// File: /workspace/github_c_makefile_star2_O0/intel[P]pf-bb-config/bb_acc_vfio.c
// Function: vfio_device_open
int vfio_device_open(void *dev)
{
	int   ret, groupid;
	int   vfio_container_fd, vfio_group_fd, vfio_dev_fd;
	char  path[PATH_MAX];

	hw_device *hwd = (hw_device *)dev;
	char *pci_addr = hwd->pci_address;

	struct vfio_group_status group_status = {
		.argsz = sizeof(group_status)
	};

	struct vfio_device_info device_info = {
		.argsz = sizeof(device_info)
	};

	struct vfio_iommu_type1_dma_map dma_map = {
		.argsz = sizeof(dma_map)
	};

	LOG(DEBUG, "PCI device: %s", pci_addr);

	if (!hwd->vfio_mode) {
		LOG(WARN, "not opened in vfio mode");
		return -1;
	}

	if (hwd->vfio_dev_fd) {
		LOG(DEBUG, "VFIO device already opened");
		return 0;
	}

	vfio_container_fd = open("/dev/vfio/vfio", O_RDWR);
	if (vfio_container_fd < 0) {
		LOG(ERR, "Failed to open /dev/vfio/vfio, %d (%s)",
				vfio_container_fd, strerror(errno));
		goto error0;
	}

	groupid = vfio_get_device_groupid(pci_addr);
	if (groupid == -1) {
		LOG(ERR, "Failed to get groupid");
		goto error1;
	}
	LOG(DEBUG, "VFIO: Using PCI device [%s] in group %d",
			pci_addr, groupid);

	snprintf(path, sizeof(path), "/dev/vfio/%d", groupid);
	vfio_group_fd = open(path, O_RDWR);
	if (vfio_group_fd < 0) {
		LOG(ERR, "Failed to open %s, %d (%s)",
				path, vfio_group_fd, strerror(errno));
		LOG(ERR, "Device [%s] not bind to vfio-pci driver",
				pci_addr);
		goto error1;
	}

	ret = ioctl(vfio_group_fd, VFIO_GROUP_GET_STATUS, &group_status);
	if (ret) {
		LOG(ERR, "ioctl(VFIO_GROUP_GET_STATUS) failed");
		goto error2;
	}

	if (!(group_status.flags & VFIO_GROUP_FLAGS_VIABLE)) {
		LOG(ERR, "Group not viable, are all devices attached to vfio?");
		goto error2;
	}

	/* NOTE: set container ioctl will attach the vfio_group_fd
	* to vfio_container_fd, will not override the vfio_conatiner_fd
	*/
	ret = ioctl(vfio_group_fd, VFIO_GROUP_SET_CONTAINER,
			&vfio_container_fd);
	if (ret) {
		LOG(ERR, "Failed to set group container");
		goto error2;
	}

	ret = ioctl(vfio_container_fd,
			VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
	if (ret) {
		LOG(ERR, "Failed to set IOMMU");
		goto error2;
	}

	if (hwd->info_ring_total_size) {
		/* Allocate some space and setup a DMA mapping */
		dma_map.vaddr = (uint64_t)mmap(0, hwd->info_ring_total_size,
				PROT_READ | PROT_WRITE,
				MAP_SHARED | MAP_ANONYMOUS, 0, 0);
		if (dma_map.vaddr == (uint64_t)MAP_FAILED) {
			LOG(ERR, "DMA mapping failed");
			goto error2;
		}
		dma_map.size = hwd->info_ring_total_size;
		dma_map.iova = dma_map.vaddr;
		dma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;

		ret = ioctl(vfio_container_fd, VFIO_IOMMU_MAP_DMA, &dma_map);
		if (ret) {
			LOG(ERR, "Failed to set IOMMU_MAP_DMA");
			goto error2;
		}
		hwd->iommu_map_dma_vaddr = (void *)(dma_map.vaddr);
		hwd->iommu_map_dma_size  = hwd->info_ring_total_size;
		LOG(DEBUG, "VFIO selected IOVA mode 'VA'");
	}

	vfio_dev_fd = ioctl(vfio_group_fd,
			VFIO_GROUP_GET_DEVICE_FD, pci_addr);
	if (vfio_dev_fd < 0) {
		LOG(ERR, "Failed to get device %s", pci_addr);
		goto error2;
	}

	close(vfio_container_fd);
	close(vfio_group_fd);
	hwd->vfio_dev_fd = vfio_dev_fd;

	LOG(DEBUG, "Done, vfio_dev_fd: %d", vfio_dev_fd);
	return 0;

error2:
	close(vfio_group_fd);
error1:
	close(vfio_container_fd);
error0:
	return -1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x10d0, %rsp           # imm = 0x10D0
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1038(%rbp)
movq -0x1038(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x1040(%rbp)
movq 0x6c2d(%rip), %rax      # 0x262a0
movq %rax, -0x1048(%rbp)
movq 0x6c27(%rip), %rax      # 0x262a8
movq %rax, -0x105c(%rbp)
movq 0x6c21(%rip), %rax      # 0x262b0
movq %rax, -0x1054(%rbp)
movl 0x6c1c(%rip), %eax      # 0x262b8
movl %eax, -0x104c(%rbp)
movq 0x6c27(%rip), %rax      # 0x262d0
movq %rax, -0x1080(%rbp)
movq 0x6c21(%rip), %rax      # 0x262d8
movq %rax, -0x1078(%rbp)
movq 0x6c1b(%rip), %rax      # 0x262e0
movq %rax, -0x1070(%rbp)
movq 0x6c15(%rip), %rax      # 0x262e8
movq %rax, -0x1068(%rbp)
callq 0x20230
movq %rax, %rcx
leaq 0x1c1e7(%rip), %rax     # 0x3b8d0
movq 0x18(%rax), %r8
movq -0x1040(%rbp), %rax
movl $0x3, %edi
xorl %esi, %esi
leaq 0x64d9(%rip), %rdx      # 0x25bdb
leaq 0x64ee(%rip), %r9       # 0x25bf7
movq %rax, (%rsp)
movb $0x0, %al
callq 0x216e0
movq -0x1038(%rbp), %rax
cmpl $0x0, 0xbc(%rax)
jne 0x1f758
callq 0x20230
movq %rax, %rcx
leaq 0x1c19d(%rip), %rax     # 0x3b8d0
movq 0x8(%rax), %r8
movl $0x1, %edi
xorl %esi, %esi
leaq 0x64c3(%rip), %rdx      # 0x25c08
movb $0x0, %al
callq 0x216e0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1fc9c
movq -0x1038(%rbp), %rax
cmpl $0x0, 0xc0(%rax)
je 0x1f7a3
callq 0x20230
movq %rax, %rcx
leaq 0x1c159(%rip), %rax     # 0x3b8d0
movq 0x18(%rax), %r8
movl $0x3, %edi
xorl %esi, %esi
leaq 0x649e(%rip), %rdx      # 0x25c27
leaq 0x6467(%rip), %r9       # 0x25bf7
movb $0x0, %al
callq 0x216e0
movl $0x0, -0x4(%rbp)
jmp 0x1fc9c
leaq 0x64a5(%rip), %rdi      # 0x25c4f
movl $0x2, %esi
movb $0x0, %al
callq 0xd300
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
jge 0x1f821
callq 0x20230
movq %rax, -0x1098(%rbp)
leaq 0x1c0fe(%rip), %rax     # 0x3b8d0
movq (%rax), %rax
movq %rax, -0x1090(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x1084(%rbp)
callq 0xd060
movl (%rax), %edi
callq 0xd410
movq -0x1098(%rbp), %rcx
movq -0x1090(%rbp), %r8
movl -0x1084(%rbp), %r9d
xorl %esi, %esi
leaq 0x644f(%rip), %rdx      # 0x25c5e
movl %esi, %edi
movq %rax, (%rsp)
movb $0x0, %al
callq 0x216e0
jmp 0x1fc95
movq -0x1040(%rbp), %rdi
callq 0x1fcb0
movl %eax, -0x18(%rbp)
cmpl $-0x1, -0x18(%rbp)
jne 0x1f85f
callq 0x20230
movq %rax, %rcx
leaq 0x1c08b(%rip), %rax     # 0x3b8d0
movq (%rax), %r8
xorl %esi, %esi
leaq 0x643b(%rip), %rdx      # 0x25c8c
movl %esi, %edi
movb $0x0, %al
callq 0x216e0
jmp 0x1fc8d
callq 0x20230
movq %rax, %rcx
leaq 0x1c062(%rip), %rax     # 0x3b8d0
movq 0x18(%rax), %r8
movq -0x1040(%rbp), %r10
movl -0x18(%rbp), %eax
movl $0x3, %edi
xorl %esi, %esi
leaq 0x641f(%rip), %rdx      # 0x25ca9
leaq 0x6366(%rip), %r9       # 0x25bf7
movq %r10, (%rsp)
movl %eax, 0x8(%rsp)
movb $0x0, %al
callq 0x216e0
leaq -0x1030(%rbp), %rdi
movl -0x18(%rbp), %ecx
movl $0x1000, %esi           # imm = 0x1000
leaq 0x6428(%rip), %rdx      # 0x25cde
movb $0x0, %al
callq 0xd160
leaq -0x1030(%rbp), %rdi
movl $0x2, %esi
movb $0x0, %al
callq 0xd300
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jge 0x1f984
callq 0x20230
movq %rax, -0x10b8(%rbp)
leaq 0x1bfe0(%rip), %rax     # 0x3b8d0
movq (%rax), %rax
movq %rax, -0x10b0(%rbp)
leaq -0x1030(%rbp), %rax
movq %rax, -0x10a8(%rbp)
movl -0x20(%rbp), %eax
movl %eax, -0x109c(%rbp)
callq 0xd060
movl (%rax), %edi
callq 0xd410
movq -0x10b8(%rbp), %rcx
movq -0x10b0(%rbp), %r8
movq -0x10a8(%rbp), %r9
movl -0x109c(%rbp), %r10d
xorl %esi, %esi
leaq 0x63a9(%rip), %rdx      # 0x25ceb
movl %esi, %edi
movl %r10d, (%rsp)
movq %rax, 0x8(%rsp)
movb $0x0, %al
callq 0x216e0
callq 0x20230
movq %rax, %rcx
leaq 0x1bf6d(%rip), %rax     # 0x3b8d0
movq (%rax), %r8
movq -0x1040(%rbp), %r9
xorl %esi, %esi
leaq 0x6397(%rip), %rdx      # 0x25d0d
movl %esi, %edi
movb $0x0, %al
callq 0x216e0
jmp 0x1fc8d
movl -0x20(%rbp), %edi
movl $0x3b67, %esi           # imm = 0x3B67
leaq -0x1048(%rbp), %rdx
movb $0x0, %al
callq 0xd180
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x1f9cc
callq 0x20230
movq %rax, %rcx
leaq 0x1bf1e(%rip), %rax     # 0x3b8d0
movq (%rax), %r8
xorl %esi, %esi
leaq 0x637e(%rip), %rdx      # 0x25d3c
movl %esi, %edi
movb $0x0, %al
callq 0x216e0
jmp 0x1fc85
movl -0x1044(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x1fa03
callq 0x20230
movq %rax, %rcx
leaq 0x1bee7(%rip), %rax     # 0x3b8d0
movq (%rax), %r8
xorl %esi, %esi
leaq 0x6372(%rip), %rdx      # 0x25d67
movl %esi, %edi
movb $0x0, %al
callq 0x216e0
jmp 0x1fc85
movl -0x20(%rbp), %edi
movl $0x3b68, %esi           # imm = 0x3B68
leaq -0x1c(%rbp), %rdx
movb $0x0, %al
callq 0xd180
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x1fa48
callq 0x20230
movq %rax, %rcx
leaq 0x1bea2(%rip), %rax     # 0x3b8d0
movq (%rax), %r8
xorl %esi, %esi
leaq 0x6368(%rip), %rdx      # 0x25da2
movl %esi, %edi
movb $0x0, %al
callq 0x216e0
jmp 0x1fc85
movl -0x1c(%rbp), %edi
movl $0x3b66, %esi           # imm = 0x3B66
movl $0x1, %edx
movb $0x0, %al
callq 0xd180
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x1fa8e
callq 0x20230
movq %rax, %rcx
leaq 0x1be5c(%rip), %rax     # 0x3b8d0
movq (%rax), %r8
xorl %esi, %esi
leaq 0x6347(%rip), %rdx      # 0x25dc7
movl %esi, %edi
movb $0x0, %al
callq 0x216e0
jmp 0x1fc85
movq -0x1038(%rbp), %rax
cmpq $0x0, 0xa0(%rax)
je 0x1fbdb
movq -0x1038(%rbp), %rax
movq 0xa0(%rax), %rsi
xorl %eax, %eax
movl %eax, %r9d
movl $0x3, %edx
movl $0x21, %ecx
xorl %r8d, %r8d
movq %r9, %rdi
callq 0xd100
movq %rax, -0x1078(%rbp)
cmpq $-0x1, -0x1078(%rbp)
jne 0x1fb05
callq 0x20230
movq %rax, %rcx
leaq 0x1bde5(%rip), %rax     # 0x3b8d0
movq (%rax), %r8
xorl %esi, %esi
leaq 0x62eb(%rip), %rdx      # 0x25de2
movl %esi, %edi
movb $0x0, %al
callq 0x216e0
jmp 0x1fc85
movq -0x1038(%rbp), %rax
movq 0xa0(%rax), %rax
movq %rax, -0x1068(%rbp)
movq -0x1078(%rbp), %rax
movq %rax, -0x1070(%rbp)
movl $0x3, -0x107c(%rbp)
movl -0x1c(%rbp), %edi
movl $0x3b71, %esi           # imm = 0x3B71
leaq -0x1080(%rbp), %rdx
movb $0x0, %al
callq 0xd180
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x1fb7a
callq 0x20230
movq %rax, %rcx
leaq 0x1bd70(%rip), %rax     # 0x3b8d0
movq (%rax), %r8
xorl %esi, %esi
leaq 0x6290(%rip), %rdx      # 0x25dfc
movl %esi, %edi
movb $0x0, %al
callq 0x216e0
jmp 0x1fc85
movq -0x1078(%rbp), %rcx
movq -0x1038(%rbp), %rax
movq %rcx, 0xd0(%rax)
movq -0x1038(%rbp), %rax
movq 0xa0(%rax), %rax
movl %eax, %ecx
movq -0x1038(%rbp), %rax
movl %ecx, 0xd8(%rax)
callq 0x20230
movq %rax, %rcx
leaq 0x1bd15(%rip), %rax     # 0x3b8d0
movq 0x18(%rax), %r8
movl $0x3, %edi
xorl %esi, %esi
leaq 0x6252(%rip), %rdx      # 0x25e1f
leaq 0x6023(%rip), %r9       # 0x25bf7
movb $0x0, %al
callq 0x216e0
movl -0x20(%rbp), %edi
movq -0x1040(%rbp), %rdx
movl $0x3b6a, %esi           # imm = 0x3B6A
movb $0x0, %al
callq 0xd180
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jge 0x1fc27
callq 0x20230
movq %rax, %rcx
leaq 0x1bcc7(%rip), %rax     # 0x3b8d0
movq (%rax), %r8
movq -0x1040(%rbp), %r9
xorl %esi, %esi
leaq 0x622d(%rip), %rdx      # 0x25e49
movl %esi, %edi
movb $0x0, %al
callq 0x216e0
jmp 0x1fc85
movl -0x1c(%rbp), %edi
callq 0xd190
movl -0x20(%rbp), %edi
callq 0xd190
movl -0x24(%rbp), %ecx
movq -0x1038(%rbp), %rax
movl %ecx, 0xc0(%rax)
callq 0x20230
movq %rax, %rcx
leaq 0x1bc7a(%rip), %rax     # 0x3b8d0
movq 0x18(%rax), %r8
movl -0x24(%rbp), %eax
movl $0x3, %edi
xorl %esi, %esi
leaq 0x61fd(%rip), %rdx      # 0x25e68
leaq 0x5f85(%rip), %r9       # 0x25bf7
movl %eax, (%rsp)
movb $0x0, %al
callq 0x216e0
movl $0x0, -0x4(%rbp)
jmp 0x1fc9c
movl -0x20(%rbp), %edi
callq 0xd190
movl -0x1c(%rbp), %edi
callq 0xd190
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl -0x4(%rbp), %eax
addq $0x10d0, %rsp           # imm = 0x10D0
popq %rbp
retq
nopl (%rax,%rax)