// File: CMU-SAFARI[P]MQSim/src/ssd/Address_Mapping_Unit_Page_Level.cpp
// Function: SSD_Components::Address_Mapping_Unit_Page_Level::Set_barrier_for_accessing_physical_block(NVM::FlashMemory::Physical_Page_Address const&)
inline void Address_Mapping_Unit_Page_Level::Set_barrier_for_accessing_physical_block(const NVM::FlashMemory::Physical_Page_Address& block_address)
	{
		//The LPAs are actually not known until they are read one-by-one from flash storage. But, to reduce MQSim's complexity, we assume that LPAs are stored in DRAM and thus no read from flash storage is needed.
		Block_Pool_Slot_Type* block = &(block_manager->plane_manager[block_address.ChannelID][block_address.ChipID][block_address.DieID][block_address.PlaneID].Blocks[block_address.BlockID]);
		NVM::FlashMemory::Physical_Page_Address addr(block_address);
		for (flash_page_ID_type pageID = 0; pageID < block->Current_page_write_index; pageID++) {
			if (block_manager->Is_page_valid(block, pageID)) {
				addr.PageID = pageID;
				if (block->Holds_mapping_data) {
					MVPN_type mpvn = (MVPN_type)flash_controller->Get_metadata(addr.ChannelID, addr.ChipID, addr.DieID, addr.PlaneID, addr.BlockID, addr.PageID);
					if (domains[block->Stream_id]->GlobalTranslationDirectory[mpvn].MPPN != Convert_address_to_ppa(addr)) {
						PRINT_ERROR("Inconsistency in the global translation directory when locking an MPVN!")
						Set_barrier_for_accessing_mvpn(block->Stream_id, mpvn);
					}
				} else {
					LPA_type lpa = flash_controller->Get_metadata(addr.ChannelID, addr.ChipID, addr.DieID, addr.PlaneID, addr.BlockID, addr.PageID);
					LPA_type ppa = domains[block->Stream_id]->GlobalMappingTable[lpa].PPA;
					if (domains[block->Stream_id]->CMT->Exists(block->Stream_id, lpa)) {
						ppa = domains[block->Stream_id]->CMT->Retrieve_ppa(block->Stream_id, lpa);
					}
					if (ppa != Convert_address_to_ppa(addr)) {
						PRINT_ERROR("Inconsistency in the global mapping table when locking an LPA!")
					}
					Set_barrier_for_accessing_lpa(block->Stream_id, lpa);
				}
			}
		}
	}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x40(%rax), %rax
movq 0x8(%rax), %rax
movq 0x58(%rsp), %rcx
movl (%rcx), %ecx
movq (%rax,%rcx,8), %rax
movq 0x58(%rsp), %rcx
movl 0x4(%rcx), %ecx
movq (%rax,%rcx,8), %rax
movq 0x58(%rsp), %rcx
movl 0x8(%rcx), %ecx
movq (%rax,%rcx,8), %rax
movq 0x58(%rsp), %rcx
movl 0xc(%rcx), %ecx
imulq $0xe0, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movq 0x58(%rsp), %rcx
movl 0x10(%rcx), %ecx
shlq $0x6, %rcx
addq %rcx, %rax
movq %rax, 0x50(%rsp)
movq 0x58(%rsp), %rsi
leaq 0x38(%rsp), %rdi
callq 0x5e380
movl $0x0, 0x34(%rsp)
movl 0x34(%rsp), %eax
movq 0x50(%rsp), %rcx
cmpl 0x4(%rcx), %eax
jae 0x5ae60
movq 0x18(%rsp), %rax
movq 0x40(%rax), %rdi
movq 0x50(%rsp), %rsi
movl 0x34(%rsp), %edx
callq 0x7cfa0
testb $0x1, %al
jne 0x5ac06
jmp 0x5ae4e
movl 0x34(%rsp), %eax
movl %eax, 0x4c(%rsp)
movq 0x50(%rsp), %rax
testb $0x1, 0x22(%rax)
je 0x5ace8
movq 0x18(%rsp), %rax
movq 0x38(%rax), %rdi
movl 0x38(%rsp), %esi
movl 0x3c(%rsp), %edx
movl 0x40(%rsp), %ecx
movl 0x44(%rsp), %r8d
movl 0x48(%rsp), %r9d
movl 0x4c(%rsp), %r10d
movq (%rdi), %rax
movl %r10d, (%rsp)
callq *0x38(%rax)
movq 0x18(%rsp), %rdi
movl %eax, 0x30(%rsp)
movq 0xa8(%rdi), %rax
movq 0x50(%rsp), %rcx
movzwl 0x20(%rcx), %ecx
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
movl 0x30(%rsp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movl (%rax), %eax
movq %rax, 0x10(%rsp)
movq (%rdi), %rax
leaq 0x38(%rsp), %rsi
callq *0x90(%rax)
movq %rax, %rcx
movq 0x10(%rsp), %rax
cmpq %rcx, %rax
je 0x5ace3
movq 0x7f351(%rip), %rdi     # 0xd9ff0
leaq 0x4fc42(%rip), %rsi     # 0xaa8e8
callq 0x8440
movq 0x7f33e(%rip), %rdi     # 0xd9ff0
leaq 0x52083(%rip), %rsi     # 0xacd3c
callq 0x8440
movq %rax, %rdi
movq 0x7f290(%rip), %rsi     # 0xd9f58
callq 0x8480
movq 0x7f2fc(%rip), %rdi     # 0xd9fd0
callq 0x84f0
movl $0x1, %edi
callq 0x8500
jmp 0x5ae4c
movq 0x18(%rsp), %rax
movq 0x38(%rax), %rdi
movl 0x38(%rsp), %esi
movl 0x3c(%rsp), %edx
movl 0x40(%rsp), %ecx
movl 0x44(%rsp), %r8d
movl 0x48(%rsp), %r9d
movl 0x4c(%rsp), %r10d
movq (%rdi), %rax
movl %r10d, (%rsp)
callq *0x38(%rax)
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x28(%rsp)
movq 0xa8(%rax), %rcx
movq 0x50(%rsp), %rdx
movzwl 0x20(%rdx), %edx
movq (%rcx,%rdx,8), %rcx
movq 0x20(%rcx), %rcx
imulq $0x18, 0x28(%rsp), %rdx
addq %rdx, %rcx
movq (%rcx), %rcx
movq %rcx, 0x20(%rsp)
movq 0xa8(%rax), %rax
movq 0x50(%rsp), %rcx
movzwl 0x20(%rcx), %ecx
movq (%rax,%rcx,8), %rax
movq 0x10(%rax), %rdi
movq 0x50(%rsp), %rax
movw 0x20(%rax), %ax
movq 0x28(%rsp), %rdx
movzwl %ax, %esi
callq 0x59760
testb $0x1, %al
jne 0x5ad80
jmp 0x5adb8
movq 0x18(%rsp), %rax
movq 0xa8(%rax), %rax
movq 0x50(%rsp), %rcx
movzwl 0x20(%rcx), %ecx
movq (%rax,%rcx,8), %rax
movq 0x10(%rax), %rdi
movq 0x50(%rsp), %rax
movw 0x20(%rax), %ax
movq 0x28(%rsp), %rdx
movzwl %ax, %esi
callq 0x4a3f0
movq %rax, 0x20(%rsp)
movq 0x18(%rsp), %rdi
movq 0x20(%rsp), %rax
movq %rax, 0x8(%rsp)
movq (%rdi), %rax
leaq 0x38(%rsp), %rsi
callq *0x90(%rax)
movq %rax, %rcx
movq 0x8(%rsp), %rax
cmpq %rcx, %rax
je 0x5ae2d
movq 0x7f207(%rip), %rdi     # 0xd9ff0
leaq 0x4faf8(%rip), %rsi     # 0xaa8e8
callq 0x8440
movq 0x7f1f4(%rip), %rdi     # 0xd9ff0
leaq 0x51f81(%rip), %rsi     # 0xacd84
callq 0x8440
movq %rax, %rdi
movq 0x7f146(%rip), %rsi     # 0xd9f58
callq 0x8480
movq 0x7f1b2(%rip), %rdi     # 0xd9fd0
callq 0x84f0
movl $0x1, %edi
callq 0x8500
movq 0x18(%rsp), %rdi
movq 0x50(%rsp), %rax
movw 0x20(%rax), %cx
movq 0x28(%rsp), %rdx
movq (%rdi), %rax
movzwl %cx, %esi
callq *0xa0(%rax)
jmp 0x5ae4e
jmp 0x5ae50
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
jmp 0x5abd4
addq $0x68, %rsp
retq
nopw %cs:(%rax,%rax)
nop