// File: narges64[P]SIMBA/ftl.cpp
// Function: update_physical_page(ssd_info*, int, int)
STATE update_physical_page(ssd_info * ssd, const int ppn, const int lpn){
	local * location = new local(0,0,0);
	find_location(ssd, ppn, location);

	int c = location->channel;
	int l = location->lun;
	int p = location->plane;
	int b = location->block;
	int pg = location->page;

	blk_info * block = ssd->channel_head[c]->lun_head[l]->plane_head[p]->blk_head[b];

	if (lpn != -1) {
		if (block->last_write_page > pg) {
			cout << "update physical page, writing backward " << block->last_write_page  << "  "  << pg<< endl;
			return FAIL;
		}
		ssd->channel_head[c]->lun_head[l]->plane_head[p]->blk_head[b]->page_head[pg]->lpn=lpn;
		ssd->channel_head[c]->lun_head[l]->plane_head[p]->blk_head[b]->page_head[pg]->valid_state=true;

		ssd->channel_head[c]->lun_head[l]->plane_head[p]->free_page--;
		ssd->stats->flash_prog_count++;
		ssd->channel_head[c]->program_count++;
		ssd->channel_head[c]->lun_head[l]->program_count++;
		ssd->channel_head[c]->lun_head[l]->plane_head[p]->program_count++;
	}else {

		if (block->page_head[pg]->lpn == -1 || block->page_head[pg]->valid_state == false) {
			cout << "invalidating has problem, the page is already invalid or free " << endl;
			return FAIL;
		}

		block->page_head[pg]->lpn=-1;
		if (block->page_head[pg]->valid_state){
			block->invalid_page_num++;
		}
		block->page_head[pg]->valid_state=false;
		ssd->channel_head[c]->lun_head[l]->plane_head[p]->invalid_page++;

	}
	delete location;
	return SUCCESS;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movl $0x18, %edi
callq 0x2130
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x50(%rbp)
xorl %ecx, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x8b20
jmp 0x7db3
movq -0x50(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movq -0x20(%rbp), %rdx
callq 0x5c70
movq -0x20(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x30(%rbp)
movq -0x20(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x34(%rbp)
movq -0x20(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0x38(%rbp)
movq -0x20(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x3c(%rbp)
movq -0x20(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
movslq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movslq -0x34(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
movslq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x20(%rax), %rax
movslq -0x3c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x48(%rbp)
cmpl $-0x1, -0x18(%rbp)
je 0x8022
movq -0x48(%rbp), %rax
movl 0x10(%rax), %eax
cmpl -0x40(%rbp), %eax
jle 0x7ec2
movq 0xc17d(%rip), %rdi      # 0x13fd0
leaq 0x7813(%rip), %rsi      # 0xf66d
callq 0x2110
movq %rax, %rdi
movq -0x48(%rbp), %rax
movl 0x10(%rax), %esi
callq 0x2220
movq %rax, %rdi
leaq 0x75de(%rip), %rsi      # 0xf456
callq 0x2110
movq %rax, %rdi
movl -0x40(%rbp), %esi
callq 0x2220
movq %rax, %rdi
movq 0xc12e(%rip), %rsi      # 0x13fc0
callq 0x2150
movl $0x0, -0x4(%rbp)
jmp 0x8130
movq -0x50(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
movl $0x18, %esi
callq 0x2140
jmp 0x8139
movl -0x18(%rbp), %ecx
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
movslq -0x30(%rbp), %rdx
movq (%rax,%rdx,8), %rax
movq 0x50(%rax), %rax
movslq -0x34(%rbp), %rdx
movq (%rax,%rdx,8), %rax
movq (%rax), %rax
movslq -0x38(%rbp), %rdx
movq (%rax,%rdx,8), %rax
movq 0x20(%rax), %rax
movslq -0x3c(%rbp), %rdx
movq (%rax,%rdx,8), %rax
movq 0x20(%rax), %rax
movslq -0x40(%rbp), %rdx
movq (%rax,%rdx,8), %rax
movl %ecx, 0x4(%rax)
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
movslq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movslq -0x34(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
movslq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x20(%rax), %rax
movslq -0x3c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x20(%rax), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb $0x1, (%rax)
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
movslq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movslq -0x34(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
movslq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rcx
addq $-0x1, %rcx
movq %rcx, (%rax)
movq -0x10(%rbp), %rax
movq 0x98(%rax), %rax
movq 0x88(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x88(%rax)
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
movslq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x10(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x10(%rax)
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
movslq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movslq -0x34(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl 0xc(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xc(%rax)
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
movslq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movslq -0x34(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
movslq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x40(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x40(%rax)
jmp 0x8104
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpl $-0x1, 0x4(%rax)
je 0x8054
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x8082
movq 0xbf75(%rip), %rdi      # 0x13fd0
leaq 0x7633(%rip), %rsi      # 0xf695
callq 0x2110
movq %rax, %rdi
movq 0xbf4f(%rip), %rsi      # 0x13fc0
callq 0x2150
movl $0x0, -0x4(%rbp)
jmp 0x8130
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl $0xffffffff, 0x4(%rax)  # imm = 0xFFFFFFFF
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
testb $0x1, (%rax)
je 0x80bb
movq -0x48(%rbp), %rax
movl 0x8(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x8(%rax)
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb $0x0, (%rax)
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
movslq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movslq -0x34(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
movslq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x8(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
movq %rax, -0x58(%rbp)
cmpq $0x0, %rax
je 0x8129
movq -0x58(%rbp), %rdi
callq 0x8b50
movq -0x58(%rbp), %rdi
movl $0x18, %esi
callq 0x2140
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
movq -0x28(%rbp), %rdi
callq 0x2230
nopw %cs:(%rax,%rax)