// File: /workspace/github_c_makefile_star2_O0/orempel[P]multiboot_tool/funkboot.c
// Function: funk_open
static int funk_open(struct multiboot *mboot)
{
    struct funk_privdata *funk = (struct funk_privdata *)mboot->privdata;

    if (funk->address == 0)
    {
        fprintf(stderr, "abort: no address given\n");
        return -1;
    }

    if (funk->device == NULL)
    {
        fprintf(stderr, "abort: no device given\n");
        return -1;
    }

    if (funk_open_device(funk) < 0)
    {
        return -1;
    }

    printf("funkbridge dev : %-16s\n", funk->device);

    char bridge_version[20];
    if (funk_bridge_version(funk, (uint8_t *)bridge_version, sizeof(bridge_version)))
    {
        fprintf(stderr, "failed to get funkbridge version\n");
        funk_close(mboot);
        return -1;
    }

    printf("funkbridge ver : %-16s\n", bridge_version);

    if (funk_switch_application(funk, BOOTTYPE_BOOTLOADER))
    {
        fprintf(stderr, "failed to switch to bootloader (invalid address?)\n");
        funk_close(mboot);
        return -1;
    }

    printf("address        : 0x%02X\n", funk->address);

    /* wait for watchdog and startup time */
    usleep(100000);

    char version[20];
    if (funk_read_version(funk, (uint8_t *)version, sizeof(version)))
    {
        fprintf(stderr, "failed to get bootloader version\n");
        funk_close(mboot);
        return -1;
    }

    uint8_t chipinfo[8];
    if (funk_read_chipinfo(funk, chipinfo, sizeof(chipinfo)))
    {
        fprintf(stderr, "failed to get bootloader chipinfo\n");
        funk_close(mboot);
        return -1;
    }

    const char *chipname = chipinfo_get_avr_name(chipinfo);

    funk->flashpage  = chipinfo[3];
    funk->flashsize  = (chipinfo[4] << 8) + chipinfo[5];
    funk->eepromsize = (chipinfo[6] << 8) + chipinfo[7];

    printf("version        : %-16s (sig: 0x%02x 0x%02x 0x%02x => %s)\n",
           version, chipinfo[0], chipinfo[1], chipinfo[2], chipname);

    printf("flash size     : 0x%04x / %5d   (0x%02x bytes/page)\n",
           funk->flashsize, funk->flashsize, funk->flashpage);

    printf("eeprom size    : 0x%04x / %5d\n",
           funk->eepromsize, funk->eepromsize);

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
cmpl $0x0, 0x10(%rax)
jne 0x5e16
movq 0xa1ff(%rip), %rax      # 0xfff8
movq (%rax), %rdi
leaq 0x5f8a(%rip), %rsi      # 0xbd8d
movb $0x0, %al
callq 0x2160
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x6056
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x5e44
movq 0xa1d1(%rip), %rax      # 0xfff8
movq (%rax), %rdi
leaq 0x5574(%rip), %rsi      # 0xb3a5
movb $0x0, %al
callq 0x2160
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x6056
movq -0x18(%rbp), %rdi
callq 0x6650
cmpl $0x0, %eax
jge 0x5e5e
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x6056
movq -0x18(%rbp), %rax
movq (%rax), %rsi
leaq 0x5f3a(%rip), %rdi      # 0xbda6
movb $0x0, %al
callq 0x20d0
movq -0x18(%rbp), %rdi
leaq -0x30(%rbp), %rsi
movl $0x14, %edx
callq 0x6760
cmpl $0x0, %eax
je 0x5eb7
movq 0xa167(%rip), %rax      # 0xfff8
movq (%rax), %rdi
leaq 0x5f23(%rip), %rsi      # 0xbdbe
movb $0x0, %al
callq 0x2160
movq -0x10(%rbp), %rdi
callq 0x6060
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x6056
leaq -0x30(%rbp), %rsi
leaq 0x5f1e(%rip), %rdi      # 0xbde0
movb $0x0, %al
callq 0x20d0
movq -0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x6800
cmpl $0x0, %eax
je 0x5f06
movq 0xa118(%rip), %rax      # 0xfff8
movq (%rax), %rdi
leaq 0x5f0e(%rip), %rsi      # 0xbdf8
movb $0x0, %al
callq 0x2160
movq -0x10(%rbp), %rdi
callq 0x6060
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x6056
movq -0x18(%rbp), %rax
movl 0x10(%rax), %esi
leaq 0x5f17(%rip), %rdi      # 0xbe2b
movb $0x0, %al
callq 0x20d0
movl $0x186a0, %edi          # imm = 0x186A0
callq 0x2280
movq -0x18(%rbp), %rdi
leaq -0x50(%rbp), %rsi
movl $0x14, %edx
callq 0x6900
cmpl $0x0, %eax
je 0x5f69
movq 0xa0b5(%rip), %rax      # 0xfff8
movq (%rax), %rdi
leaq 0x5ef7(%rip), %rsi      # 0xbe44
movb $0x0, %al
callq 0x2160
movq -0x10(%rbp), %rdi
callq 0x6060
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x6056
movq -0x18(%rbp), %rdi
leaq -0x58(%rbp), %rsi
movl $0x8, %edx
callq 0x6a60
cmpl $0x0, %eax
je 0x5fad
movq 0xa071(%rip), %rax      # 0xfff8
movq (%rax), %rdi
leaq 0x5ed5(%rip), %rsi      # 0xbe66
movb $0x0, %al
callq 0x2160
movq -0x10(%rbp), %rdi
callq 0x6060
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x6056
leaq -0x58(%rbp), %rdi
callq 0x3700
movq %rax, -0x60(%rbp)
movzbl -0x55(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x20(%rax)
movzbl -0x54(%rbp), %ecx
shll $0x8, %ecx
movzbl -0x53(%rbp), %eax
addl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x1c(%rax)
movzbl -0x52(%rbp), %ecx
shll $0x8, %ecx
movzbl -0x51(%rbp), %eax
addl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x24(%rax)
leaq -0x50(%rbp), %rsi
movzbl -0x58(%rbp), %edx
movzbl -0x57(%rbp), %ecx
movzbl -0x56(%rbp), %r8d
movq -0x60(%rbp), %r9
leaq 0x5e80(%rip), %rdi      # 0xbe89
movb $0x0, %al
callq 0x20d0
movq -0x18(%rbp), %rax
movl 0x1c(%rax), %esi
movq -0x18(%rbp), %rax
movl 0x1c(%rax), %edx
movq -0x18(%rbp), %rax
movl 0x20(%rax), %ecx
leaq 0x5e97(%rip), %rdi      # 0xbec3
movb $0x0, %al
callq 0x20d0
movq -0x18(%rbp), %rax
movl 0x24(%rax), %esi
movq -0x18(%rbp), %rax
movl 0x24(%rax), %edx
leaq 0x5468(%rip), %rdi      # 0xb4b0
movb $0x0, %al
callq 0x20d0
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
nop