// File: goodix[P]gdix_hid_firmware_update/gtx9/gtx9_update.cpp
// Function: GTx9Update::fw_update(unsigned int)
int GTx9Update::fw_update(unsigned int firmware_flag)
{
	struct firmware_summary *fw_info =
		(struct firmware_summary *)image->GetFirmwareSummary();
	struct fw_subsys_info *fw_x;
	struct fw_subsys_info subsys_cfg;
	int i;
	int ret;
	uint8_t buf[1];
	int minorVer;
	int majorVer;
	uint8_t cfgVer;
	uint8_t temp_buf[CFG_MAX_SIZE] = {0};

	gdix_info("IN\n");
	/* flash config */
	if (image->HasConfig()) {
		memcpy(temp_buf,
			   image->GetFirmwareData() + image->GetFirmwareSize() + 64,
			   image->GetConfigSize());

		subsys_cfg.data = temp_buf;
		subsys_cfg.size = CFG_MAX_SIZE;
		subsys_cfg.flash_addr = 0x40000;
		subsys_cfg.type = 4;
		ret = flashSubSystem(&subsys_cfg);
		if (ret < 0) {
			gdix_err("failed flash config with ISP\n");
			return ret;
		}
		gdix_info("success flash config with ISP\n");
		usleep(20000);
	}

	for (i = 1; i < fw_info->subsys_num; i++) {
		fw_x = &fw_info->subsys[i];
		if (fw_x->type == (uint8_t)firmware_flag) {
			gdix_info("skip type[%02X] subsystem[%d]\n", fw_x->type, i);
			continue;
		}
		ret = flashSubSystem(fw_x);
		if (ret < 0) {
			gdix_err("-------- Failed flash subsystem %d --------\n", i);
			return ret;
		}
		gdix_info("-------- Success flash subsystem %d --------\n", i);
	}

	/* reset IC */
	gdix_info("Reset IC\n");
	buf[0] = 1;
	ret = dev->SendCmd(0x13, buf, 1);
	if (ret < 0) {
		gdix_err("Failed reset IC\n");
		return ret;
	}
	usleep(100000);

	/* compare version */
	dev->SetBasicProperties();
	majorVer = image->GetFirmwareVersionMajor();
	minorVer = image->GetFirmwareVersionMinor();
	if (image->HasConfig() == false) {
		cfgVer = (uint8_t)dev->GetFirmwareVersionMinor();
		minorVer &= 0xffffff00;
		minorVer |= cfgVer;
	}

	if ((dev->GetFirmwareVersionMajor() != majorVer) ||
		(dev->GetFirmwareVersionMinor() != minorVer)) {
		gdix_err("update failed\n");
		gdix_info("Current version:%d.%d\n", dev->GetFirmwareVersionMajor(),
				  dev->GetFirmwareVersionMinor());
		gdix_info("Firmware version:%d.%d\n", majorVer, minorVer);
		return -1;
	}

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1090, %rsp           # imm = 0x1090
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1068(%rbp)
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x70(%rax)
movq %rax, -0x20(%rbp)
leaq -0x1060(%rbp), %rdi
xorl %esi, %esi
movl $0x1000, %edx           # imm = 0x1000
callq 0x50a0
leaq 0xdf44(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1837e
movq 0xdc57(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
leaq 0x7e44(%rip), %rsi      # 0x201af
leaq 0x6e8a(%rip), %rdx      # 0x1f1fc
movl $0xfe, %ecx
movb $0x0, %al
callq 0x5190
jmp 0x18380
movq -0x1068(%rbp), %rax
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x98(%rax)
testb $0x1, %al
jne 0x1839d
jmp 0x184cd
movq -0x1068(%rbp), %rax
leaq -0x1060(%rbp), %rcx
movq %rcx, -0x1078(%rbp)
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x38(%rax)
movq %rax, %rcx
movq -0x1068(%rbp), %rax
movq %rcx, -0x1080(%rbp)
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq -0x1080(%rbp), %rcx
movl %eax, %edx
movq -0x1068(%rbp), %rax
movl %edx, %edx
addq %rdx, %rcx
addq $0x40, %rcx
movq %rcx, -0x1070(%rbp)
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0xa0(%rax)
movq -0x1078(%rbp), %rdi
movq -0x1070(%rbp), %rsi
movslq %eax, %rdx
callq 0x50b0
movq -0x1068(%rbp), %rdi
leaq -0x1060(%rbp), %rax
movq %rax, -0x30(%rbp)
movl $0x1000, -0x3c(%rbp)    # imm = 0x1000
movl $0x40000, -0x38(%rbp)   # imm = 0x40000
movb $0x4, -0x40(%rbp)
leaq -0x40(%rbp), %rsi
callq 0x17f60
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x48(%rbp)
jge 0x1848f
jmp 0x18452
leaq 0xde40(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x18482
movq 0xdb73(%rip), %rax      # 0x25fd8
movq (%rax), %rdi
leaq 0x7fcc(%rip), %rsi      # 0x2043b
leaq 0x6d86(%rip), %rdx      # 0x1f1fc
movl $0x10b, %ecx            # imm = 0x10B
movb $0x0, %al
callq 0x5190
jmp 0x18484
movl -0x48(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x1884e
jmp 0x18491
leaq 0xde01(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x184c1
movq 0xdb14(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
leaq 0x7fbc(%rip), %rsi      # 0x2046a
leaq 0x6d47(%rip), %rdx      # 0x1f1fc
movl $0x10e, %ecx            # imm = 0x10E
movb $0x0, %al
callq 0x5190
jmp 0x184c3
movl $0x4e20, %edi           # imm = 0x4E20
callq 0x5180
movl $0x1, -0x44(%rbp)
movl -0x44(%rbp), %eax
movq -0x20(%rbp), %rcx
movzbl 0x1d(%rcx), %ecx
cmpl %ecx, %eax
jge 0x185f8
movq -0x20(%rbp), %rax
addq $0x2a, %rax
movslq -0x44(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
movl -0x14(%rbp), %ecx
movzbl %cl, %ecx
cmpl %ecx, %eax
jne 0x18554
jmp 0x18511
leaq 0xdd81(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1854d
movq 0xda94(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
movq -0x28(%rbp), %rax
movzbl (%rax), %r8d
movl -0x44(%rbp), %r9d
leaq 0x7f60(%rip), %rsi      # 0x2049a
leaq 0x6cbb(%rip), %rdx      # 0x1f1fc
movl $0x115, %ecx            # imm = 0x115
movb $0x0, %al
callq 0x5190
jmp 0x1854f
jmp 0x185ea
movq -0x1068(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x17f60
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x48(%rbp)
jge 0x185b0
jmp 0x1856f
leaq 0xdd23(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x185a3
movq 0xda56(%rip), %rax      # 0x25fd8
movq (%rax), %rdi
movl -0x44(%rbp), %r8d
leaq 0x7f3a(%rip), %rsi      # 0x204ca
leaq 0x6c65(%rip), %rdx      # 0x1f1fc
movl $0x11a, %ecx            # imm = 0x11A
movb $0x0, %al
callq 0x5190
jmp 0x185a5
movl -0x48(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x1884e
jmp 0x185b2
leaq 0xdce0(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x185e6
movq 0xd9f3(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
movl -0x44(%rbp), %r8d
leaq 0x7f35(%rip), %rsi      # 0x20508
leaq 0x6c22(%rip), %rdx      # 0x1f1fc
movl $0x11d, %ecx            # imm = 0x11D
movb $0x0, %al
callq 0x5190
jmp 0x185e8
jmp 0x185ea
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x184d4
jmp 0x185fa
leaq 0xdc98(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1862a
movq 0xd9ab(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
leaq 0x7f30(%rip), %rsi      # 0x20547
leaq 0x6bde(%rip), %rdx      # 0x1f1fc
movl $0x121, %ecx            # imm = 0x121
movb $0x0, %al
callq 0x5190
jmp 0x1862c
movq -0x1068(%rbp), %rax
movb $0x1, -0x49(%rbp)
movq 0x8(%rax), %rdi
leaq -0x49(%rbp), %rdx
movq (%rdi), %rax
movl $0x13, %esi
movl $0x1, %ecx
callq *0x48(%rax)
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x48(%rbp)
jge 0x18697
jmp 0x1865a
leaq 0xdc38(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1868a
movq 0xd96b(%rip), %rax      # 0x25fd8
movq (%rax), %rdi
leaq 0x7eeb(%rip), %rsi      # 0x20562
leaq 0x6b7e(%rip), %rdx      # 0x1f1fc
movl $0x125, %ecx            # imm = 0x125
movb $0x0, %al
callq 0x5190
jmp 0x1868c
movl -0x48(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x1884e
movl $0x186a0, %edi          # imm = 0x186A0
callq 0x5180
movq -0x1068(%rbp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0xa0(%rax)
movq -0x1068(%rbp), %rax
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x28(%rax)
movl %eax, %ecx
movq -0x1068(%rbp), %rax
movl %ecx, -0x54(%rbp)
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x30(%rax)
movl %eax, %ecx
movq -0x1068(%rbp), %rax
movl %ecx, -0x50(%rbp)
movq 0x10(%rax), %rdi
movq (%rdi), %rax
callq *0x98(%rax)
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x18728
movq -0x1068(%rbp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x68(%rax)
movb %al, -0x55(%rbp)
movl -0x50(%rbp), %eax
andl $0xffffff00, %eax       # imm = 0xFFFFFF00
movl %eax, -0x50(%rbp)
movzbl -0x55(%rbp), %eax
orl -0x50(%rbp), %eax
movl %eax, -0x50(%rbp)
movq -0x1068(%rbp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x60(%rax)
cmpl -0x54(%rbp), %eax
jne 0x18758
movq -0x1068(%rbp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x68(%rax)
cmpl -0x50(%rbp), %eax
je 0x18847
jmp 0x1875a
leaq 0xdb38(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1878a
movq 0xd86b(%rip), %rax      # 0x25fd8
movq (%rax), %rdi
leaq 0x7e0d(%rip), %rsi      # 0x20584
leaq 0x6a7e(%rip), %rdx      # 0x1f1fc
movl $0x136, %ecx            # imm = 0x136
movb $0x0, %al
callq 0x5190
jmp 0x1878c
jmp 0x1878e
leaq 0xdb04(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x18800
movq -0x1068(%rbp), %rax
movq 0xd810(%rip), %rcx      # 0x25fb8
movq (%rcx), %rcx
movq %rcx, -0x1090(%rbp)
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x60(%rax)
movl %eax, %ecx
movq -0x1068(%rbp), %rax
movl %ecx, -0x1084(%rbp)
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x68(%rax)
movq -0x1090(%rbp), %rdi
movl -0x1084(%rbp), %r8d
movl %eax, %r9d
leaq 0x794c(%rip), %rsi      # 0x20139
leaq 0x6a08(%rip), %rdx      # 0x1f1fc
movl $0x138, %ecx            # imm = 0x138
movb $0x0, %al
callq 0x5190
jmp 0x18802
jmp 0x18804
leaq 0xda8e(%rip), %rax      # 0x26299
testb $0x1, (%rax)
je 0x1883c
movq 0xd7a1(%rip), %rax      # 0x25fb8
movq (%rax), %rdi
movl -0x54(%rbp), %r8d
movl -0x50(%rbp), %r9d
leaq 0x7938(%rip), %rsi      # 0x20161
leaq 0x69cc(%rip), %rdx      # 0x1f1fc
movl $0x139, %ecx            # imm = 0x139
movb $0x0, %al
callq 0x5190
jmp 0x1883e
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1884e
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x1090, %rsp           # imm = 0x1090
popq %rbp
retq
nopw (%rax,%rax)