// 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::handle_transaction_serviced_signal_from_PHY(SSD_Components::NVM_Transaction_Flash*)
inline void Address_Mapping_Unit_Page_Level::handle_transaction_serviced_signal_from_PHY(NVM_Transaction_Flash* transaction)
	{
		//First check if the transaction source is Mapping Module
		if (transaction->Source != Transaction_Source_Type::MAPPING) {
			return;
		}

		if (_my_instance->ideal_mapping_table){
			throw std::logic_error("There should not be any flash read/write when ideal mapping is enabled!");
		}

		if (transaction->Type == Transaction_Type::WRITE) {
			_my_instance->domains[transaction->Stream_id]->DepartingMappingEntries.erase((MVPN_type)((NVM_Transaction_Flash_WR*)transaction)->Content);
		} else {
			/*If this is a read for an MVP that is required for merging unchanged mapping enries
			* (stored on flash) with those updated entries that are evicted from CMT*/
			if (((NVM_Transaction_Flash_RD*)transaction)->RelatedWrite != NULL) {
				((NVM_Transaction_Flash_RD*)transaction)->RelatedWrite->RelatedRead = NULL;
			}

			_my_instance->ftl->TSU->Prepare_for_transaction_submit();
			MVPN_type mvpn = (MVPN_type)((NVM_Transaction_Flash_RD*)transaction)->Content;
			std::multimap<MVPN_type, LPA_type>::iterator it = _my_instance->domains[transaction->Stream_id]->ArrivingMappingEntries.find(mvpn);
			while (it != _my_instance->domains[transaction->Stream_id]->ArrivingMappingEntries.end()) {
				if ((*it).first == mvpn) {
					LPA_type lpa = (*it).second;

					//This mapping entry may arrived due to an update read request that is required for merging new and old mapping entries.
					//If that is the case, we should not insert it into CMT
					if (_my_instance->domains[transaction->Stream_id]->CMT->Is_slot_reserved_for_lpn_and_waiting(transaction->Stream_id, lpa)) {
						_my_instance->domains[transaction->Stream_id]->CMT->Insert_new_mapping_info(transaction->Stream_id, lpa,
							_my_instance->domains[transaction->Stream_id]->GlobalMappingTable[lpa].PPA,
							_my_instance->domains[transaction->Stream_id]->GlobalMappingTable[lpa].WrittenStateBitmap);
						auto it2 = _my_instance->domains[transaction->Stream_id]->Waiting_unmapped_read_transactions.find(lpa);
						while (it2 != _my_instance->domains[transaction->Stream_id]->Waiting_unmapped_read_transactions.end() &&
							(*it2).first == lpa) {
							if (_my_instance->is_lpa_locked_for_gc(transaction->Stream_id, lpa)) {
								_my_instance->manage_user_transaction_facing_barrier(it2->second);
							} else {
								if (_my_instance->translate_lpa_to_ppa(transaction->Stream_id, it2->second)) {
									_my_instance->ftl->TSU->Submit_transaction(it2->second);
								}
								else {
									_my_instance->mange_unsuccessful_translation(it2->second);
								}
							}
							_my_instance->domains[transaction->Stream_id]->Waiting_unmapped_read_transactions.erase(it2++);
						}
						it2 = _my_instance->domains[transaction->Stream_id]->Waiting_unmapped_program_transactions.find(lpa);
						while (it2 != _my_instance->domains[transaction->Stream_id]->Waiting_unmapped_program_transactions.end() &&
							(*it2).first == lpa) {
							if (_my_instance->is_lpa_locked_for_gc(transaction->Stream_id, lpa)) {
								_my_instance->manage_user_transaction_facing_barrier(it2->second);
							} else {
								if (_my_instance->translate_lpa_to_ppa(transaction->Stream_id, it2->second)) {
									_my_instance->ftl->TSU->Submit_transaction(it2->second);
									if (((NVM_Transaction_Flash_WR*)it2->second)->RelatedRead != NULL) {
										_my_instance->ftl->TSU->Submit_transaction(((NVM_Transaction_Flash_WR*)it2->second)->RelatedRead);
									}
								} else {
									_my_instance->mange_unsuccessful_translation(it2->second);
								}
							}
							_my_instance->domains[transaction->Stream_id]->Waiting_unmapped_program_transactions.erase(it2++);
						}
					}
				} else {
					break;
				}
				_my_instance->domains[transaction->Stream_id]->ArrivingMappingEntries.erase(it++);
			}
			_my_instance->ftl->TSU->Schedule();
		}
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
cmpl $0x3, 0x4(%rdi)
jne 0x2644f
movq 0x3c4b9(%rip), %rax     # 0x625d8
cmpb $0x1, 0x4c(%rax)
je 0x2645e
movq %rdi, %rbx
cmpl $0x1, 0x8(%rdi)
jne 0x2615c
movq 0xa8(%rax), %rax
movzwl (%rbx), %ecx
movl $0xb8, %edi
addq (%rax,%rcx,8), %rdi
movl 0x80(%rbx), %eax
leaq 0x8(%rsp), %rsi
movl %eax, (%rsi)
callq 0x27358
jmp 0x2644f
movq 0x88(%rbx), %rcx
testq %rcx, %rcx
je 0x26170
andq $0x0, 0x88(%rcx)
movq 0x30(%rax), %rax
movq 0x50(%rax), %rdi
callq 0x264ce
movl 0x80(%rbx), %eax
leaq 0x14(%rsp), %rsi
movl %eax, (%rsi)
movq 0x3c447(%rip), %rax     # 0x625d8
movq 0xa8(%rax), %rax
movzwl (%rbx), %ecx
movl $0x88, %r14d
movq (%rax,%rcx,8), %rdi
addq %r14, %rdi
callq 0x28390
movq %rax, %r15
movq 0x3c421(%rip), %rcx     # 0x625d8
movq 0xa8(%rcx), %rdx
movzwl (%rbx), %eax
movq (%rdx,%rax,8), %rsi
leaq 0x90(%rsi), %rdx
cmpq %rdx, %r15
je 0x26441
movl 0x20(%r15), %edx
cmpl 0x14(%rsp), %edx
jne 0x26441
movq 0x28(%r15), %rdx
movq %rdx, 0x8(%rsp)
movq 0x10(%rsi), %rdi
movzwl %ax, %esi
callq 0x20c50
movq 0x3c3d9(%rip), %rcx     # 0x625d8
movq 0xa8(%rcx), %rcx
movzwl (%rbx), %esi
testb %al, %al
je 0x2641c
movq (%rcx,%rsi,8), %rax
movq 0x8(%rsp), %rdx
movq 0x10(%rax), %rdi
movq 0x20(%rax), %rax
imulq $0x18, %rdx, %r8
movq (%rax,%r8), %rcx
movq 0x8(%rax,%r8), %r8
callq 0x20bba
movq 0x3c39d(%rip), %rax     # 0x625d8
movq 0xa8(%rax), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %rdi
addq $0x28, %rdi
leaq 0x8(%rsp), %rsi
callq 0x274f8
movq %rax, %r12
movq 0x3c377(%rip), %rdi     # 0x625d8
movq 0xa8(%rdi), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %rax
leaq 0x30(%rax), %rdx
cmpq %rdx, %r12
je 0x26320
movq 0x20(%r12), %rdx
cmpq 0x8(%rsp), %rdx
jne 0x26320
movq (%rdi), %rax
movzwl %cx, %esi
callq *0xe8(%rax)
movq 0x3c339(%rip), %rdi     # 0x625d8
testb %al, %al
je 0x262b3
movq 0x28(%r12), %rsi
movq (%rdi), %rax
callq *0xd8(%rax)
jmp 0x262e9
movzwl (%rbx), %esi
movq 0x28(%r12), %rdx
callq 0x22296
movq 0x3c311(%rip), %rdi     # 0x625d8
testb %al, %al
je 0x262df
movq 0x30(%rdi), %rax
movq 0x50(%rax), %rdi
movq 0x28(%r12), %rsi
callq 0x264ec
jmp 0x262e9
movq 0x28(%r12), %rsi
callq 0x22356
movq 0x3c2e8(%rip), %rax     # 0x625d8
movq 0xa8(%rax), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %r13
addq $0x28, %r13
movq %r12, %rdi
callq 0x7280
movq %rax, %rbp
movq %r13, %rdi
movq %r12, %rsi
callq 0x27e6c
movq %rbp, %r12
jmp 0x2625a
addq $0x58, %rax
movq %rax, %rdi
leaq 0x8(%rsp), %rsi
callq 0x274f8
movq %rax, %r12
movq 0x3c29d(%rip), %rdi     # 0x625d8
movq 0xa8(%rdi), %rcx
movzwl (%rbx), %esi
movq (%rcx,%rsi,8), %rax
addq $0x60, %rax
cmpq %rax, %r12
je 0x2641c
movq 0x20(%r12), %rdx
cmpq 0x8(%rsp), %rdx
jne 0x2641c
movq (%rdi), %rax
callq *0xe8(%rax)
movq 0x3c262(%rip), %rdi     # 0x625d8
testb %al, %al
je 0x2638a
movq 0x28(%r12), %rsi
movq (%rdi), %rax
callq *0xd8(%rax)
jmp 0x263e5
movzwl (%rbx), %esi
movq 0x28(%r12), %rdx
callq 0x22296
movq 0x3c23a(%rip), %rdi     # 0x625d8
testb %al, %al
je 0x263db
movq 0x30(%rdi), %rax
movq 0x50(%rax), %rdi
movq 0x28(%r12), %rsi
callq 0x264ec
movq 0x28(%r12), %rax
movq 0x88(%rax), %rsi
testq %rsi, %rsi
je 0x263e5
movq 0x3c20c(%rip), %rax     # 0x625d8
movq 0x30(%rax), %rax
movq 0x50(%rax), %rdi
callq 0x264ec
jmp 0x263e5
movq 0x28(%r12), %rsi
callq 0x22356
movq 0x3c1ec(%rip), %rax     # 0x625d8
movq 0xa8(%rax), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %r13
addq $0x58, %r13
movq %r12, %rdi
callq 0x7280
movq %rax, %rbp
movq %r13, %rdi
movq %r12, %rsi
callq 0x27e6c
movq %rbp, %r12
jmp 0x26334
movq (%rcx,%rsi,8), %r12
addq %r14, %r12
movq %r15, %rdi
callq 0x7280
movq %rax, %r13
movq %r12, %rdi
movq %r15, %rsi
callq 0x2754e
movq %r13, %r15
jmp 0x261b0
movq 0x30(%rcx), %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
pushq $0x10
popq %rdi
callq 0x71b0
movq %rax, %rbx
leaq 0x206e4(%rip), %rsi     # 0x46b54
movq %rax, %rdi
callq 0x74b0
movq 0x3bb41(%rip), %rsi     # 0x61fc0
movq 0x3baea(%rip), %rdx     # 0x61f70
movq %rbx, %rdi
callq 0x7590
movq %rax, %r14
movq %rbx, %rdi
callq 0x72a0
movq %r14, %rdi
callq 0x75d0
nop