// File: chenhn123[P]wdt_util_src/wdt_ct/w8755_funcs.cpp
// Function: wh_w8755_dev_program_4k_chunk_verify(WdtDevice*, ChunkInfoEx*, int)
int wh_w8755_dev_program_4k_chunk_verify(WDT_DEV* pdev, CHUNK_INFO_EX* pInputChunk, int option)
{
	int retval = 0;
	int size;
	int start_addr = 0;
	int page_size;
	int retry_count = 0;
	int is_first_page = 0;
	char*	pdata;
	UINT32	calc_checksum, read_checksum;
	CHUNK_INFO_EX	*pChunk = pInputChunk;

	printf("start 4k chunk program ...\n");
	pdev->dev_state = DS_PROGRAM;

	retval = wh_w8755_dev_send_commands(pdev, WH_CMD_ALGO_STOP, 0);
	if (!retval)
		return retval;	
	
	retval = wh_w8755_dev_send_commands(pdev, WH_CMD_FLASH_UNLOCK, 0);
	if (!retval)
		return retval;


	if (option & OPTION_ERASE_TEMP) {
		retval = wh_w8755_dev_send_commands(pdev, WH_CMD_FLASH_ERASE4K, pInputChunk->chuckInfo.temp);
		if (!retval) {
			printf("erase temp addr failed !\n");
			return 0;
		}
	}

	size = pChunk->chuckInfo.length;	
	start_addr = pChunk->chuckInfo.targetStartAddr;
	pdata =	(char*) pChunk->pData;

	if (size > WDT_PAGE_SIZE) {
		is_first_page = 1;
		size = size - WDT_PAGE_SIZE;
		start_addr = start_addr + WDT_PAGE_SIZE;
		pdata = pdata + WDT_PAGE_SIZE;
	}

	while (size) {
		if (size > (int) WDT_PAGE_SIZE)	{
			page_size = WDT_PAGE_SIZE;
			size = size - WDT_PAGE_SIZE;
		} else	{
			page_size = size;
			size = 0;
		}

		for (retry_count = 0; retry_count < RETRY_COUNT; retry_count ++) {
			retval = wh_w8755_dev_send_commands(pdev, WH_CMD_FLASH_ERASE4K, start_addr);
			if (!retval)
				continue;

			retval = wh_w8755_dev_flash_write_data(pdev, (BYTE*) pdata, start_addr, page_size);
			if (!retval)
				continue;

			calc_checksum = misr_for_bytes(0, (BYTE*) pdata, 0, page_size);
			retval = wh_w8755_dev_flash_get_checksum(pdev, &read_checksum, start_addr, page_size);

			if (read_checksum == calc_checksum)
				break;
			else
				printf("checksum failed (%d): %d <> %d\n", retry_count, read_checksum, calc_checksum);
		}

		if (retry_count == RETRY_COUNT)	{
			printf("***** retry failed *****\n");
			break;
		}

		start_addr = start_addr + page_size;
		pdata =	pdata + page_size;

		// keep the first page to write to the flash in the last loop
		if (size == 0 && is_first_page) {		
			size = WDT_PAGE_SIZE;
			start_addr = pChunk->chuckInfo.targetStartAddr;
			pdata = (char*) pChunk->pData;
			is_first_page = 0;		
		}
	}

	retval = wh_w8755_dev_send_commands(pdev, WH_CMD_FLASH_LOCK, 0);
	if (!retval)
		return retval;

	retval = wh_w8755_dev_send_commands(pdev, WH_CMD_ALGO_START, 0);
	if (!retval)
		return retval;
	
	if (retry_count == RETRY_COUNT) {
		printf("stop 4k chunk program : fail \n");
		return 0;
	}

	return 1;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl $0x0, -0x20(%rbp)
movl $0x0, -0x28(%rbp)
movl $0x0, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x50(%rbp)
leaq 0xbabd(%rip), %rdi      # 0xf6bb
movb $0x0, %al
callq 0x2050
movq -0x10(%rbp), %rax
movl $0x3, 0x278(%rax)
movq -0x10(%rbp), %rdi
movl $0x2, %esi
xorl %edx, %edx
callq 0x3100
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jne 0x3c37
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x3e9b
movq -0x10(%rbp), %rdi
movl $0x11, %esi
xorl %edx, %edx
callq 0x3100
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jne 0x3c5b
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x3e9b
movl -0x1c(%rbp), %eax
andl $0x400, %eax            # imm = 0x400
cmpl $0x0, %eax
je 0x3ca2
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movl 0x14(%rax), %edx
movl $0x13, %esi
callq 0x3100
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jne 0x3ca0
leaq 0xba4a(%rip), %rdi      # 0xf6d7
movb $0x0, %al
callq 0x2050
movl $0x0, -0x4(%rbp)
jmp 0x3e9b
jmp 0x3ca2
movq -0x50(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x24(%rbp)
movq -0x50(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x28(%rbp)
movq -0x50(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x40(%rbp)
cmpl $0x1000, -0x24(%rbp)    # imm = 0x1000
jle 0x3cf5
movl $0x1, -0x34(%rbp)
movl -0x24(%rbp), %eax
subl $0x1000, %eax           # imm = 0x1000
movl %eax, -0x24(%rbp)
movl -0x28(%rbp), %eax
addl $0x1000, %eax           # imm = 0x1000
movl %eax, -0x28(%rbp)
movq -0x40(%rbp), %rax
addq $0x1000, %rax           # imm = 0x1000
movq %rax, -0x40(%rbp)
jmp 0x3cf7
cmpl $0x0, -0x24(%rbp)
je 0x3e35
cmpl $0x1000, -0x24(%rbp)    # imm = 0x1000
jle 0x3d1e
movl $0x1000, -0x2c(%rbp)    # imm = 0x1000
movl -0x24(%rbp), %eax
subl $0x1000, %eax           # imm = 0x1000
movl %eax, -0x24(%rbp)
jmp 0x3d2b
movl -0x24(%rbp), %eax
movl %eax, -0x2c(%rbp)
movl $0x0, -0x24(%rbp)
movl $0x0, -0x30(%rbp)
cmpl $0x3, -0x30(%rbp)
jge 0x3dd3
movq -0x10(%rbp), %rdi
movl -0x28(%rbp), %edx
movl $0x13, %esi
callq 0x3100
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jne 0x3d58
jmp 0x3dc5
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rsi
movl -0x28(%rbp), %edx
movl -0x2c(%rbp), %ecx
callq 0x2fb0
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jne 0x3d76
jmp 0x3dc5
movq -0x40(%rbp), %rsi
movl -0x2c(%rbp), %ecx
xorl %edx, %edx
movl %edx, %edi
callq 0xb780
movzwl %ax, %eax
movl %eax, -0x44(%rbp)
movq -0x10(%rbp), %rdi
movl -0x28(%rbp), %edx
movl -0x2c(%rbp), %ecx
leaq -0x48(%rbp), %rsi
callq 0x3970
movl %eax, -0x20(%rbp)
movl -0x48(%rbp), %eax
cmpl -0x44(%rbp), %eax
jne 0x3dac
jmp 0x3dd3
movl -0x30(%rbp), %esi
movl -0x48(%rbp), %edx
movl -0x44(%rbp), %ecx
leaq 0xb935(%rip), %rdi      # 0xf6f1
movb $0x0, %al
callq 0x2050
jmp 0x3dc5
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x3d32
cmpl $0x3, -0x30(%rbp)
jne 0x3de9
leaq 0xb931(%rip), %rdi      # 0xf711
movb $0x0, %al
callq 0x2050
jmp 0x3e35
movl -0x28(%rbp), %eax
addl -0x2c(%rbp), %eax
movl %eax, -0x28(%rbp)
movq -0x40(%rbp), %rax
movslq -0x2c(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
cmpl $0x0, -0x24(%rbp)
jne 0x3e30
cmpl $0x0, -0x34(%rbp)
je 0x3e30
movl $0x1000, -0x24(%rbp)    # imm = 0x1000
movq -0x50(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x28(%rbp)
movq -0x50(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x40(%rbp)
movl $0x0, -0x34(%rbp)
jmp 0x3cf7
movq -0x10(%rbp), %rdi
movl $0x10, %esi
xorl %edx, %edx
callq 0x3100
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jne 0x3e56
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x3e9b
movq -0x10(%rbp), %rdi
movl $0x3, %esi
xorl %edx, %edx
callq 0x3100
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jne 0x3e77
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x3e9b
cmpl $0x3, -0x30(%rbp)
jne 0x3e94
leaq 0xb8a7(%rip), %rdi      # 0xf72b
movb $0x0, %al
callq 0x2050
movl $0x0, -0x4(%rbp)
jmp 0x3e9b
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)