// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %edx, %r14d
movq %rsi, %r15
movq %rdi, %rbx
leaq 0x8184(%rip), %rdi      # 0xb77d
callq 0x2270
movl $0x3, 0x278(%rbx)
xorl %ebp, %ebp
movq %rbx, %rdi
movl $0x2, %esi
xorl %edx, %edx
callq 0x2d98
testl %eax, %eax
je 0x37dd
xorl %ebp, %ebp
movq %rbx, %rdi
xorl %esi, %esi
callq 0x30b0
testl %eax, %eax
je 0x37dd
btl $0xa, %r14d
jae 0x3655
movl 0x14(%r15), %edx
movq %rbx, %rdi
movl $0x13, %esi
callq 0x2d98
testl %eax, %eax
je 0x37cf
movl (%r15), %ebp
movl 0x4(%r15), %edx
movq %r15, 0x10(%rsp)
movq 0x18(%r15), %r15
cmpl $0x1001, %edx           # imm = 0x1001
jl 0x3687
addl $0xfffff000, %edx       # imm = 0xFFFFF000
addl $0x1000, %ebp           # imm = 0x1000
addq $0x1000, %r15           # imm = 0x1000
movl $0x1, %esi
jmp 0x3691
xorl %esi, %esi
testl %edx, %edx
je 0x37ee
movl $0x1000, %ecx           # imm = 0x1000
xorl %edi, %edi
movl %esi, 0x4(%rsp)
movl %edx, %r13d
leal -0x1000(%r13), %eax
cmpl $0x1001, %edx           # imm = 0x1001
cmovll %edi, %eax
movl %eax, 0x8(%rsp)
cmpl %ecx, %edx
cmovgel %ecx, %r13d
xorl %r14d, %r14d
movq %rbx, %rdi
movl $0x13, %esi
movl %ebp, %edx
callq 0x2d98
testl %eax, %eax
je 0x3725
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %edx
movl %r13d, %ecx
callq 0x2cb6
testl %eax, %eax
je 0x3725
xorl %edi, %edi
movq %r15, %rsi
xorl %edx, %edx
movl %r13d, %ecx
callq 0x88e6
movzwl %ax, %r12d
movq %rbx, %rdi
leaq 0xc(%rsp), %rsi
movl %ebp, %edx
movl %r13d, %ecx
callq 0x33f7
movl 0xc(%rsp), %edx
cmpl %r12d, %edx
je 0x3730
leaq 0x7f56(%rip), %rdi      # 0xb66e
movl %r14d, %esi
movl %r12d, %ecx
xorl %eax, %eax
callq 0x2050
incl %r14d
cmpl $0x3, %r14d
jne 0x36bc
jmp 0x377f
movl 0x8(%rsp), %edx
testl %edx, %edx
sete %al
movl 0x4(%rsp), %esi
testl %esi, %esi
setne %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x375d
movq 0x10(%rsp), %rax
movl (%rax), %ebp
movq 0x18(%rax), %r15
xorl %esi, %esi
movl $0x1000, %edx           # imm = 0x1000
jmp 0x3766
addl %r13d, %ebp
movslq %r13d, %rax
addq %rax, %r15
movl $0x1000, %ecx           # imm = 0x1000
xorl %edi, %edi
testl %edx, %edx
jne 0x3698
cmpl $0x3, %r14d
setne %r14b
jmp 0x378e
leaq 0x802b(%rip), %rdi      # 0xb7b1
callq 0x2270
xorl %r14d, %r14d
xorl %ebp, %ebp
movq %rbx, %rdi
movl $0x10, %esi
xorl %edx, %edx
callq 0x2d98
testl %eax, %eax
je 0x37dd
movq %rbx, %rdi
movl $0x3, %esi
xorl %edx, %edx
callq 0x2d98
xorl %ebp, %ebp
testl %eax, %eax
setne %al
sete %cl
orb %r14b, %cl
je 0x37c6
movb %al, %bpl
jmp 0x37dd
leaq 0x7ffd(%rip), %rdi      # 0xb7ca
jmp 0x37d6
leaq 0x7fc2(%rip), %rdi      # 0xb798
callq 0x2270
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movb $0x1, %r14b
jmp 0x378e