// File: /workspace/github_c_makefile_star2_O0/orempel[P]multiboot_tool/mpmboot.c
// Function: mpm_open
static int mpm_open(struct multiboot *mboot)
{
    struct mpm_privdata *mpm = (struct mpm_privdata *)mboot->privdata;

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

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

    if (mpm_open_device(mpm) < 0)
    {
        return -1;
    }

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

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

    char version[16 +1];
    if (mpm_read_version(mpm, (uint8_t *)version, sizeof(version) -1))
    {
        fprintf(stderr, "failed to get bootloader version\n");
        mpm_close(mboot);
        return -1;
    }

    version[16] = '\0';

    uint8_t chipinfo[8];
    if (mpm_read_chipinfo(mpm, chipinfo, sizeof(chipinfo)))
    {
        fprintf(stderr, "failed to get bootloader version\n");
        mpm_close(mboot);
        return -1;
    }

    const char *chipname = chipinfo_get_avr_name(chipinfo);

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

    printf("device         : %-16s (address: 0x%02X)\n",
           mpm->device, mpm->address);

    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",
           mpm->flashsize, mpm->flashsize, mpm->flashpage);

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

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movzbl 0x10(%rax), %eax
cmpl $0x0, %eax
jne 0x7819
movq 0x87fc(%rip), %rax      # 0xfff8
movq (%rax), %rdi
leaq 0x4587(%rip), %rsi      # 0xbd8d
movb $0x0, %al
callq 0x2160
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7a06
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x7847
movq 0x87ce(%rip), %rax      # 0xfff8
movq (%rax), %rdi
leaq 0x3b71(%rip), %rsi      # 0xb3a5
movb $0x0, %al
callq 0x2160
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7a06
movq -0x18(%rbp), %rdi
callq 0x8020
cmpl $0x0, %eax
jge 0x7861
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7a06
movq -0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x8130
cmpl $0x0, %eax
je 0x789e
movq 0x8780(%rip), %rax      # 0xfff8
movq (%rax), %rdi
leaq 0x4576(%rip), %rsi      # 0xbdf8
movb $0x0, %al
callq 0x2160
movq -0x10(%rbp), %rdi
callq 0x7a10
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7a06
movl $0x186a0, %edi          # imm = 0x186A0
callq 0x2280
movq -0x18(%rbp), %rdi
leaq -0x30(%rbp), %rsi
movl $0x10, %edx
callq 0x81c0
cmpl $0x0, %eax
je 0x78ec
movq 0x8732(%rip), %rax      # 0xfff8
movq (%rax), %rdi
leaq 0x4574(%rip), %rsi      # 0xbe44
movb $0x0, %al
callq 0x2160
movq -0x10(%rbp), %rdi
callq 0x7a10
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7a06
movb $0x0, -0x20(%rbp)
movq -0x18(%rbp), %rdi
leaq -0x38(%rbp), %rsi
movl $0x8, %edx
callq 0x8290
cmpl $0x0, %eax
je 0x7934
movq 0x86ea(%rip), %rax      # 0xfff8
movq (%rax), %rdi
leaq 0x452c(%rip), %rsi      # 0xbe44
movb $0x0, %al
callq 0x2160
movq -0x10(%rbp), %rdi
callq 0x7a10
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7a06
leaq -0x38(%rbp), %rdi
callq 0x3700
movq %rax, -0x40(%rbp)
movb -0x35(%rbp), %cl
movq -0x18(%rbp), %rax
movb %cl, 0x14(%rax)
movzbl -0x34(%rbp), %eax
shll $0x8, %eax
movzbl -0x33(%rbp), %ecx
addl %ecx, %eax
movw %ax, %cx
movq -0x18(%rbp), %rax
movw %cx, 0x12(%rax)
movzbl -0x32(%rbp), %eax
shll $0x8, %eax
movzbl -0x31(%rbp), %ecx
addl %ecx, %eax
movw %ax, %cx
movq -0x18(%rbp), %rax
movw %cx, 0x16(%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rsi
movq -0x18(%rbp), %rax
movzbl 0x10(%rax), %edx
leaq 0x49f2(%rip), %rdi      # 0xc383
movb $0x0, %al
callq 0x20d0
leaq -0x30(%rbp), %rsi
movzbl -0x38(%rbp), %edx
movzbl -0x37(%rbp), %ecx
movzbl -0x36(%rbp), %r8d
movq -0x40(%rbp), %r9
leaq 0x44d5(%rip), %rdi      # 0xbe89
movb $0x0, %al
callq 0x20d0
movq -0x18(%rbp), %rax
movzwl 0x12(%rax), %esi
movq -0x18(%rbp), %rax
movzwl 0x12(%rax), %edx
movq -0x18(%rbp), %rax
movzbl 0x14(%rax), %ecx
leaq 0x44e9(%rip), %rdi      # 0xbec3
movb $0x0, %al
callq 0x20d0
movq -0x18(%rbp), %rax
movzwl 0x16(%rax), %esi
movq -0x18(%rbp), %rax
movzwl 0x16(%rax), %edx
leaq 0x3ab8(%rip), %rdi      # 0xb4b0
movb $0x0, %al
callq 0x20d0
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nop