// File: /workspace/github_cpp_makefile_star2_O2/CMU-SAFARI[P]MQSim/src/ssd/Address_Mapping_Unit_Page_Level.cpp
// Function: SSD_Components::Address_Mapping_Unit_Page_Level::generate_flash_writeback_request_for_mapping_data(unsigned short, unsigned long)
void Address_Mapping_Unit_Page_Level::generate_flash_writeback_request_for_mapping_data(const stream_id_type stream_id, const LPA_type lpn)
	{
		MVPN_type mvpn = get_MVPN(lpn, stream_id);
		if (is_mvpn_locked_for_gc(stream_id, mvpn)) {
			manage_mapping_transaction_facing_barrier(stream_id, mvpn, false);
			domains[stream_id]->DepartingMappingEntries.insert(get_MVPN(lpn, stream_id));
		} else {
			ftl->TSU->Prepare_for_transaction_submit();

			//Writing back all dirty CMT entries that fall into the same translation virtual page (MVPN)
			unsigned int read_size = 0;
			page_status_type readSectorsBitmap = 0;
			LPA_type startLPN = get_start_LPN_in_MVP(mvpn);
			LPA_type endLPN = get_end_LPN_in_MVP(mvpn);
			for (LPA_type lpn_itr = startLPN; lpn_itr <= endLPN; lpn_itr++) {
				if (domains[stream_id]->CMT->Exists(stream_id, lpn_itr)) {
					if (domains[stream_id]->CMT->Is_dirty(stream_id, lpn_itr)) {
						domains[stream_id]->CMT->Make_clean(stream_id, lpn_itr);
						domains[stream_id]->GlobalMappingTable[lpn_itr].PPA = domains[stream_id]->CMT->Retrieve_ppa(stream_id, lpn_itr);
					} else {
						page_status_type bitlocation = (((page_status_type)0x1) << (((lpn_itr - startLPN) * GTD_entry_size) / SECTOR_SIZE_IN_BYTE));
						if ((readSectorsBitmap & bitlocation) == 0) {
							readSectorsBitmap |= bitlocation;
							read_size += SECTOR_SIZE_IN_BYTE;
						}
					}
				}
			}

			//Read the unchaged mapping entries from flash to merge them with updated parts of MVPN
			NVM_Transaction_Flash_RD* readTR = NULL;
			MPPN_type mppn = domains[stream_id]->GlobalTranslationDirectory[mvpn].MPPN;
			if (mppn != NO_MPPN) {
				readTR = new NVM_Transaction_Flash_RD(Transaction_Source_Type::MAPPING, stream_id, read_size,
					mvpn, mppn, NULL, mvpn, NULL, readSectorsBitmap, CurrentTimeStamp);
				Convert_ppa_to_address(mppn, readTR->Address);
				block_manager->Read_transaction_issued(readTR->Address);//Inform block_manager as soon as the transaction's target address is determined
				domains[stream_id]->ArrivingMappingEntries.insert(std::pair<MVPN_type, LPA_type>(mvpn, lpn));
				ftl->TSU->Submit_transaction(readTR);
			}

			NVM_Transaction_Flash_WR* writeTR = new NVM_Transaction_Flash_WR(Transaction_Source_Type::MAPPING, stream_id, SECTOR_SIZE_IN_BYTE * sector_no_per_page,
				mvpn, mppn, NULL, mvpn, readTR, (((page_status_type)0x1) << sector_no_per_page) - 1, CurrentTimeStamp);
			allocate_plane_for_translation_write(writeTR);
			allocate_page_in_plane_for_translation_write(writeTR, mvpn, false);
			domains[stream_id]->DepartingMappingEntries.insert(get_MVPN(lpn, stream_id));
			ftl->TSU->Submit_transaction(writeTR);

			Stats::Total_flash_reads_for_mapping++;
			Stats::Total_flash_writes_for_mapping++;
			Stats::Total_flash_reads_for_mapping_per_stream[stream_id]++;
			Stats::Total_flash_writes_for_mapping_per_stream[stream_id]++;

			ftl->TSU->Schedule();
		}
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdx, %r15
movl %esi, %ebp
movq %rdi, %rbx
movl 0xc0(%rdi), %ecx
movq %rdx, %rax
xorl %edx, %edx
divq %rcx
movq %rax, %r12
movq (%rdi), %rax
movl %r12d, %edx
callq *0xf0(%rax)
testb %al, %al
je 0x24ee6
movq (%rbx), %rax
movzwl %bp, %r14d
movq %rbx, %rdi
movl %r14d, %esi
movl %r12d, %edx
xorl %ecx, %ecx
callq *0xe0(%rax)
movq 0xa8(%rbx), %rax
movl $0xb8, %edi
addq (%rax,%r14,8), %rdi
movl 0xc0(%rbx), %ecx
movq %r15, %rax
xorl %edx, %edx
divq %rcx
leaq 0x28(%rsp), %rsi
movl %eax, (%rsi)
callq 0x28544
jmp 0x251e5
movq %r15, 0x20(%rsp)
movq 0x30(%rbx), %rax
movq 0x50(%rax), %rdi
callq 0x264ce
movl 0xc0(%rbx), %eax
leal 0x1(%r12), %r13d
imull %eax, %r13d
movl %eax, %r14d
movq %r12, 0x10(%rsp)
imull %r12d, %r14d
decl %r13d
movzwl %bp, %r12d
xorl %r15d, %r15d
xorl %ebp, %ebp
movq $0x0, 0x8(%rsp)
movq %r13, 0x18(%rsp)
movq 0xa8(%rbx), %rax
movq (%rax,%r12,8), %rax
cmpq %r13, %r14
ja 0x25019
movq 0x10(%rax), %rdi
movl %r12d, %esi
movq %r14, %rdx
callq 0x264a2
testb %al, %al
je 0x2500e
movq 0xa8(%rbx), %rax
movq (%rax,%r12,8), %rax
movq 0x10(%rax), %rdi
movl %r12d, %esi
movq %r14, %rdx
callq 0x20e12
testb %al, %al
je 0x24fd6
movq 0xa8(%rbx), %rax
movq %rbp, %r13
leal (,%r12,8), %ebp
movq (%rax,%rbp), %rax
movq 0x10(%rax), %rdi
movl %r12d, %esi
movq %r14, %rdx
callq 0x20e82
movq 0xa8(%rbx), %rax
movq (%rax,%rbp), %rax
movq 0x10(%rax), %rdi
movl %r12d, %esi
movq %r14, %rdx
callq 0x20a46
movq 0xa8(%rbx), %rcx
movq (%rcx,%rbp), %rcx
movq %r13, %rbp
movq 0x18(%rsp), %r13
movq 0x20(%rcx), %rcx
imulq $0x18, %r14, %rdx
movq %rax, (%rcx,%rdx)
jmp 0x2500e
movl 0xb4(%rbx), %ecx
imull %r15d, %ecx
shrl $0x9, %ecx
pushq $0x1
popq %rax
shlq %cl, %rax
movq 0x8(%rsp), %rsi
leal 0x200(%rsi), %edx
btq %rcx, %rbp
movl $0x0, %ecx
cmovbq %rcx, %rax
cmovbl %esi, %edx
orq %rax, %rbp
movl %edx, %eax
movq %rax, 0x8(%rsp)
incq %r14
incq %r15
jmp 0x24f2d
movq (%rax), %rax
movl 0x10(%rsp), %r13d
movq %r13, %rcx
shlq $0x4, %rcx
movl (%rax,%rcx), %r15d
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpq %rax, %r15
movq %r15, 0x18(%rsp)
je 0x250e8
movl $0xa0, %edi
callq 0x7370
movq %rax, %r14
callq 0x1f784
movq %rax, %rdi
callq 0x1fafc
subq $0x8, %rsp
pushq $0x3
popq %rsi
movq %r14, %rdi
movl %r12d, %edx
movq 0x10(%rsp), %rcx
movq %r13, %r8
movq %r15, %r9
pushq %rax
pushq %rbp
pushq $0x0
pushq %r13
pushq $0x0
callq 0x3a134
addq $0x30, %rsp
movq %r14, %rbp
addq $0x38, %r14
movq (%rbx), %rax
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq *0x88(%rax)
movq 0x40(%rbx), %rdi
movq %r14, %rsi
callq 0x31b8a
movq 0xa8(%rbx), %rax
movl $0x88, %edi
addq (%rax,%r12,8), %rdi
leaq 0x28(%rsp), %rsi
movq 0x10(%rsp), %rax
movl %eax, (%rsi)
movq 0x20(%rsp), %rax
movq %rax, 0x8(%rsi)
callq 0x283e2
movq 0x30(%rbx), %rax
movq 0x50(%rax), %rdi
movq %rbp, 0x8(%rsp)
movq %rbp, %rsi
callq 0x264ec
jmp 0x250f1
movq $0x0, 0x8(%rsp)
movl $0xb0, %edi
callq 0x7370
movq %rax, %rbp
movl 0x7c(%rbx), %r14d
pushq $-0x1
popq %r15
movl %r14d, %ecx
shlq %cl, %r15
callq 0x1f784
movq %rax, %rdi
callq 0x1fafc
shll $0x9, %r14d
notq %r15
subq $0x8, %rsp
pushq $0x3
popq %rsi
movq %rbp, %rdi
movl %r12d, %edx
movl %r14d, %ecx
movq %r13, %r8
movq 0x20(%rsp), %r9
pushq %rax
pushq %r15
pushq 0x20(%rsp)
pushq %r13
pushq $0x0
callq 0x3a2c6
addq $0x30, %rsp
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x2278e
movq %rbx, %rdi
movq %rbp, %rsi
movq 0x10(%rsp), %rdx
xorl %ecx, %ecx
callq 0x21d5e
movq 0xa8(%rbx), %rax
leal (,%r12,8), %r14d
movl $0xb8, %edi
addq (%rax,%r14), %rdi
movl 0xc0(%rbx), %ecx
movq 0x20(%rsp), %rax
xorl %edx, %edx
divq %rcx
leaq 0x28(%rsp), %rsi
movl %eax, (%rsi)
callq 0x28544
movq 0x30(%rbx), %rax
movq 0x50(%rax), %rdi
movq %rbp, %rsi
callq 0x264ec
leaq 0x3d53c(%rip), %rax     # 0x626f0
incq (%rax)
leaq 0x3d53a(%rip), %rax     # 0x626f8
incq (%rax)
leaq 0x3d538(%rip), %rax     # 0x62700
incq (%rax,%r14)
leaq 0x3dd2d(%rip), %rax     # 0x62f00
incq (%rax,%r14)
movq 0x30(%rbx), %rax
movq 0x50(%rax), %rdi
movq (%rdi), %rax
callq *0x30(%rax)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq %r14, %rdi
jmp 0x25202
movq %rax, %rbx
movq %rbp, %rdi
callq 0x7340
movq %rbx, %rdi
callq 0x75d0
nop