// File: KinderRiven[P]rdma_demo/server.cc
// Function: open_device(rdma_context_t*)
static void open_device(rdma_context_t* context)
{
    /* ------------------------------------------- */
    printf("----------- Open Device -----------\n");
    int _res;
    int _num_dev = 0;
    struct ibv_device* _dev = NULL;
    struct ibv_device** _dev_list = NULL;

    /* ------------------------------------------- */
    // 获得RDMA列表
    _dev_list = ibv_get_device_list(&_num_dev);
    if (_num_dev == 0) {
        printf("|--ibv_get_device_list failed.\n");
        exit(1);
    }
    printf("|--ibv_get_device_list ok.[%d]\n", _num_dev);

    /* ------------------------------------------- */
    // 打开RDMA设备
    _dev = _dev_list[0];
    context->ctx = ibv_open_device(_dev);
    if (context->ctx == NULL) {
        printf("|--ibv_open_device failed.\n");
        exit(1);
    }
    printf("|--ibv_open_device ok [%s].\n", ibv_get_device_name(_dev));

    /* ------------------------------------------- */
    _res = ibv_query_port(context->ctx, 1, &context->port_attr);
    if (_res) {
        printf("|--ibv_query_port failed.\n");
        exit(1);
    }
    printf("|--ibv_query_port ok.\n");
    printf("|----[lid:%d]\n", context->port_attr.lid);

    /* ------------------------------------------- */
    // port is 1 | idx is 2
    // use show_gids to show all info
    _res = ibv_query_gid(context->ctx, 1, 2, &context->gid);
    if (_res) {
        printf("|--ibv_query_gid failed.\n");
        exit(1);
    }
    printf("|--ibv_query_gid ok.\n");
    printf("|----");
    for (int i = 0; i < 16; i++) {
        printf("%02x", context->gid.raw[i]);
        if (i & 1) {
            printf(":");
        }
    }
    printf("\n");
    printf("|----");
    // for (int i = 0; i < 16; i++) {
    //     context->gid.raw[i] = g_gids[i];
    //     printf("%02x", context->gid.raw[i]);
    //     if (i & 1) {
    //         printf(":");
    //     }
    // }
    // printf("\n");

    /* ------------------------------------------- */
    _res = ibv_query_device(context->ctx, &context->dev_attr);
    if (_res) {
        printf("|--ibv_query_device failed.\n");
        exit(1);
    }
    printf("|--ibv_query_device ok.\n");
    printf("|----[VERSION:%d]\n", context->dev_attr.hw_ver);
    printf("|----[MAX_NUM_CQ:%d][MAX_CQE:%d]\n", context->dev_attr.max_cq, context->dev_attr.max_cqe);
    printf("|----[MAX_QP_WR:%d]\n", context->dev_attr.max_qp_wr);
    printf("|----[MAX_NUM_MR:%dMB][MR_SIZE:%lluGB]\n", context->dev_attr.max_mr / (1024 * 1024), context->dev_attr.max_mr_size / (1024UL * 1024 * 1024));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
leaq 0x15e8(%rip), %rdi      # 0x305b
movb $0x0, %al
callq 0x1050
movl $0x0, -0x10(%rbp)
movq $0x0, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
leaq -0x10(%rbp), %rdi
callq 0x11a0
movq %rax, -0x20(%rbp)
cmpl $0x0, -0x10(%rbp)
jne 0x1abc
leaq 0x15d5(%rip), %rdi      # 0x3080
movb $0x0, %al
callq 0x1050
movl $0x1, %edi
callq 0x1150
movl -0x10(%rbp), %esi
leaq 0x15da(%rip), %rdi      # 0x30a0
movb $0x0, %al
callq 0x1050
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
callq 0x1110
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x1b0f
leaq 0x15c2(%rip), %rdi      # 0x30c0
movb $0x0, %al
callq 0x1050
movl $0x1, %edi
callq 0x1150
movq -0x18(%rbp), %rdi
callq 0x10d0
movq %rax, %rsi
leaq 0x15ba(%rip), %rdi      # 0x30dc
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x8(%rbp), %rdx
addq $0x430, %rdx            # imm = 0x430
movl $0x1, %esi
callq 0x20c0
movl %eax, -0xc(%rbp)
cmpl $0x0, -0xc(%rbp)
je 0x1b67
leaq 0x15a3(%rip), %rdi      # 0x30f9
movb $0x0, %al
callq 0x1050
movl $0x1, %edi
callq 0x1150
leaq 0x15a6(%rip), %rdi      # 0x3114
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movzwl 0x452(%rax), %esi
leaq 0x15a4(%rip), %rdi      # 0x312b
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x8(%rbp), %rcx
addq $0x560, %rcx            # imm = 0x560
movl $0x1, %esi
movl $0x2, %edx
callq 0x1140
movl %eax, -0xc(%rbp)
cmpl $0x0, -0xc(%rbp)
je 0x1bd1
leaq 0x157a(%rip), %rdi      # 0x313a
movb $0x0, %al
callq 0x1050
movl $0x1, %edi
callq 0x1150
leaq 0x157c(%rip), %rdi      # 0x3154
movb $0x0, %al
callq 0x1050
leaq 0x1584(%rip), %rdi      # 0x316a
movb $0x0, %al
callq 0x1050
movl $0x0, -0x24(%rbp)
cmpl $0x10, -0x24(%rbp)
jge 0x1c3e
movq -0x8(%rbp), %rax
movslq -0x24(%rbp), %rcx
movzbl 0x560(%rax,%rcx), %esi
leaq 0x155f(%rip), %rdi      # 0x3170
movb $0x0, %al
callq 0x1050
movl -0x24(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x1c31
leaq 0x1876(%rip), %rdi      # 0x34a0
movb $0x0, %al
callq 0x1050
jmp 0x1c33
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x1bf4
leaq 0x1439(%rip), %rdi      # 0x307e
movb $0x0, %al
callq 0x1050
leaq 0x1517(%rip), %rdi      # 0x316a
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x8(%rbp), %rsi
addq $0x468, %rsi            # imm = 0x468
callq 0x11c0
movl %eax, -0xc(%rbp)
cmpl $0x0, -0xc(%rbp)
je 0x1c93
leaq 0x14f3(%rip), %rdi      # 0x3175
movb $0x0, %al
callq 0x1050
movl $0x1, %edi
callq 0x1150
leaq 0x14f8(%rip), %rdi      # 0x3192
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movl 0x4d0(%rax), %esi
leaq 0x14f9(%rip), %rdi      # 0x31ab
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movl 0x4e8(%rax), %esi
movq -0x8(%rbp), %rax
movl 0x4ec(%rax), %edx
leaq 0x14ea(%rip), %rdi      # 0x31be
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movl 0x4d8(%rax), %esi
leaq 0x14f4(%rip), %rdi      # 0x31e0
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movl 0x4f0(%rax), %eax
movl $0x100000, %ecx         # imm = 0x100000
cltd
idivl %ecx
movl %eax, %esi
movq -0x8(%rbp), %rax
movq 0x4b8(%rax), %rdx
shrq $0x1e, %rdx
leaq 0x14d8(%rip), %rdi      # 0x31f5
movb $0x0, %al
callq 0x1050
addq $0x30, %rsp
popq %rbp
retq
nopw (%rax,%rax)