// 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_read_request_for_mapping_data(unsigned short, unsigned long)
void Address_Mapping_Unit_Page_Level::generate_flash_read_request_for_mapping_data(const stream_id_type stream_id, const LPA_type lpn)
	{
		MVPN_type mvpn = get_MVPN(lpn, stream_id);

		if (mvpn >= domains[stream_id]->Total_translation_pages_no) {
			PRINT_ERROR("Out of range virtual translation page number!")
		}

		domains[stream_id]->ArrivingMappingEntries.insert(std::pair<MVPN_type, LPA_type>(mvpn, lpn));

		if (is_mvpn_locked_for_gc(stream_id, mvpn)) {
			manage_mapping_transaction_facing_barrier(stream_id, mvpn, true);
		} else {
			ftl->TSU->Prepare_for_transaction_submit();

			PPA_type ppn = domains[stream_id]->GlobalTranslationDirectory[mvpn].MPPN;

			if (ppn == NO_MPPN){
				PRINT_ERROR("Reading an invalid physical flash page address in function generate_flash_read_request_for_mapping_data!")
			}

			NVM_Transaction_Flash_RD* readTR = new NVM_Transaction_Flash_RD(Transaction_Source_Type::MAPPING, stream_id,
					SECTOR_SIZE_IN_BYTE, NO_LPA, NO_PPA, NULL, mvpn, ((page_status_type)0x1) << sector_no_per_page, CurrentTimeStamp);
			Convert_ppa_to_address(ppn, readTR->Address);
			block_manager->Read_transaction_issued(readTR->Address);//Inform block_manager as soon as the transaction's target address is determined
			readTR->PPA = ppn;
			ftl->TSU->Submit_transaction(readTR);

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

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

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %rcx
movl %esi, %ebp
movq %rdi, %rbx
movl 0xc0(%rdi), %esi
movq %rdx, %rax
xorl %edx, %edx
divq %rsi
movq %rax, %r14
movq 0xa8(%rdi), %rax
movl %ebp, %r13d
movq (%rax,%r13,8), %rdi
cmpl %r14d, 0x268(%rdi)
jbe 0x25fa6
addq $0x88, %rdi
leaq 0x8(%rsp), %rsi
movl %r14d, (%rsi)
movq %rcx, 0x8(%rsi)
callq 0x283e2
movq (%rbx), %rax
movzwl %bp, %ebp
movq %rbx, %rdi
movl %ebp, %esi
movl %r14d, %edx
callq *0xf0(%rax)
testb %al, %al
je 0x25eb9
movq (%rbx), %rax
pushq $0x1
popq %rcx
movq %rbx, %rdi
movl %ebp, %esi
movl %r14d, %edx
callq *0xe0(%rax)
jmp 0x25f97
movq 0x30(%rbx), %rax
movq 0x50(%rax), %rdi
callq 0x264ce
movq 0xa8(%rbx), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %rax
movl %r14d, %ecx
movq %rcx, (%rsp)
shlq $0x4, %rcx
movl (%rax,%rcx), %r14d
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpq %rax, %r14
je 0x25fc5
movl $0xa0, %edi
callq 0x7370
movq %rax, %r15
movb 0x7c(%rbx), %cl
pushq $0x1
popq %r12
shlq %cl, %r12
callq 0x1f784
movq %rax, %rdi
callq 0x1fafc
pushq $0x3
popq %rsi
pushq $-0x1
popq %r8
movq %r15, %rdi
movl %ebp, %edx
movl $0x200, %ecx            # imm = 0x200
movq %r8, %r9
pushq %rax
pushq %r12
pushq 0x10(%rsp)
pushq $0x0
callq 0x3a21a
addq $0x20, %rsp
movq %r15, %r12
addq $0x38, %r12
movq (%rbx), %rax
movq %rbx, %rdi
movq %r14, %rsi
movq %r12, %rdx
callq *0x88(%rax)
movq 0x40(%rbx), %rdi
movq %r12, %rsi
callq 0x31b8a
movq %r14, 0x60(%r15)
movq 0x30(%rbx), %rax
movq 0x50(%rax), %rdi
movq %r15, %rsi
callq 0x264ec
leaq 0x3c775(%rip), %rax     # 0x626f0
incq (%rax)
leaq 0x3c77b(%rip), %rax     # 0x62700
incq (%rax,%r13,8)
movq 0x30(%rbx), %rax
movq 0x50(%rax), %rdi
movq (%rdi), %rax
callq *0x30(%rax)
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x3c043(%rip), %rbx     # 0x61ff0
leaq 0x1e5d4(%rip), %rsi     # 0x44588
movq %rbx, %rdi
callq 0x7360
leaq 0x20afa(%rip), %rsi     # 0x46abd
jmp 0x25fe2
movq 0x3c024(%rip), %rbx     # 0x61ff0
leaq 0x1e5b5(%rip), %rsi     # 0x44588
movq %rbx, %rdi
callq 0x7360
leaq 0x20b09(%rip), %rsi     # 0x46aeb
movq %rbx, %rdi
callq 0x7360
movq %rax, %rdi
callq 0x71a0
movq 0x3bfd7(%rip), %rdi     # 0x61fd0
callq 0x73d0
pushq $0x1
popq %rdi
callq 0x73e0
movq %rax, %rbx
movq %r15, %rdi
callq 0x7340
movq %rbx, %rdi
callq 0x75d0
nop