hypervisor/dm/vpci/pci_pt.c
void init_vdev_pt(struct pci_vdev *vdev)
{
	enum pci_bar_type type;
	uint32_t idx;
	struct pci_vbar *vbar;
	uint16_t pci_command;
	uint32_t size32, offset, lo, hi = 0U;
	union pci_bdf pbdf;
	uint64_t mask;

	vdev->nr_bars = vdev->pdev->nr_bars;
	pbdf.value = vdev->pdev->bdf.value;

	for (idx = 0U; idx < vdev->nr_bars; idx++) {
		vbar = &vdev->vbars[idx];
		offset = pci_bar_offset(idx);
		lo = pci_pdev_read_cfg(pbdf, offset, 4U);

		type = pci_get_bar_type(lo);
		if (type == PCIBAR_NONE) {
			continue;
		}
		mask = (type == PCIBAR_IO_SPACE) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK;
		vbar->base_hpa = (uint64_t)lo & mask;

		if (type == PCIBAR_MEM64) {
			hi = pci_pdev_read_cfg(pbdf, offset + 4U, 4U);
			vbar->base_hpa |= ((uint64_t)hi << 32U);
		}

		if (vbar->base_hpa != 0UL) {
			pci_pdev_write_cfg(pbdf, offset, 4U, ~0U);
			size32 = pci_pdev_read_cfg(pbdf, offset, 4U);
			pci_pdev_write_cfg(pbdf, offset, 4U, lo);

			vbar->type = type;
			vbar->mask = size32 & mask;
			vbar->fixed = lo & (~mask);
			vbar->size = (uint64_t)size32 & mask;

			if (is_prelaunched_vm(vdev->vpci->vm)) {
				lo = (uint32_t)vdev->pci_dev_config->vbar_base[idx];
			}

			if (type == PCIBAR_MEM64) {
				idx++;
				offset = pci_bar_offset(idx);
				pci_pdev_write_cfg(pbdf, offset, 4U, ~0U);
				size32 = pci_pdev_read_cfg(pbdf, offset, 4U);
				pci_pdev_write_cfg(pbdf, offset, 4U, hi);

				vbar->size |= ((uint64_t)size32 << 32U);
				vbar->size = vbar->size & ~(vbar->size - 1UL);
				vbar->size = round_page_up(vbar->size);

				vbar = &vdev->vbars[idx];
				vbar->mask = size32;
				vbar->type = PCIBAR_MEM64HI;

				if (is_prelaunched_vm(vdev->vpci->vm)) {
					hi = (uint32_t)(vdev->pci_dev_config->vbar_base[idx - 1U] >> 32U);
				}
				pci_vdev_write_bar(vdev, idx - 1U, lo);
				pci_vdev_write_bar(vdev, idx, hi);
			} else {
				vbar->size = vbar->size & ~(vbar->size - 1UL);
				if (type == PCIBAR_MEM32) {
					vbar->size = round_page_up(vbar->size);
				}
				pci_vdev_write_bar(vdev, idx, lo);
			}
		}
	}

	if (is_prelaunched_vm(vdev->vpci->vm)) {
		pci_command = (uint16_t)pci_pdev_read_cfg(vdev->pdev->bdf, PCIR_COMMAND, 2U);

		/* Disable INTX */
		pci_command |= 0x400U;
		pci_pdev_write_cfg(vdev->pdev->bdf, PCIR_COMMAND, 2U, pci_command);
	}
}
/**
 * PCI base address register (bar) virtualization:
 *
 * Virtualize the PCI bars (up to 6 bars at byte offset 0x10~0x24 for type 0 PCI device,
 * 2 bars at byte offset 0x10-0x14 for type 1 PCI device) of the PCI configuration space
 * header.
 *
 * pbar: bar for the physical PCI device (pci_pdev), the value of pbar (hpa) is assigned
 * by platform firmware during boot. It is assumed a valid hpa is always assigned to a
 * mmio pbar, hypervisor shall not change the value of a pbar.
 *
 * vbar: for each pci_pdev, it has a virtual PCI device (pci_vdev) counterpart. pci_vdev
 * virtualizes all the bars (called vbars). a vbar can be initialized by hypervisor by
 * assigning a gpa to it; if vbar has a value of 0 (unassigned), guest may assign
 * and program a gpa to it. The guest only sees the vbars, it will not see and can
 * never change the pbars.
 *
 * Hypervisor traps guest changes to the mmio vbar (gpa) to establish ept mapping
 * between vbar(gpa) and pbar(hpa). pbar should always align on 4K boundary.
 *
 * @pre vdev != NULL
 * @pre vdev->vpci != NULL
 * @pre vdev->vpci->vm != NULL
 * @pre vdev->pdev != NULL
 */
PCI base address register (bar) virtualization:
Virtualize the PCI bars (up to 6 bars at byte offset 0x10~0x24 for type 0 PCI device,
2 bars at byte offset 0x10-0x14 for type 1 PCI device) of the PCI configuration space
header.

bar for the physical PCI device (pci_pdev), the value of pbar (hpa) is assigned
by platform firmware during boot. It is assumed a valid hpa is always assigned to a
mmio pbar, hypervisor shall not change the value of a pbar.

for each pci_pdev, it has a virtual PCI device (pci_vdev) counterpart. pci_vdev
virtualizes all the bars (called vbars). a vbar can be initialized by hypervisor by
assigning a gpa to it; if vbar has a value of 0 (unassigned), guest may assign
and program a gpa to it. The guest only sees the vbars, it will not see and can
never change the pbars.

Hypervisor traps guest changes to the mmio vbar (gpa) to establish ept mapping
between vbar(gpa) and pbar(hpa). pbar should always align on 4K boundary.


PCI base address register ( bar ) virtualization : Virtualize the PCI bars ( up to 6 bars at byte offset 0x10~0x24 for type 0 PCI device 2 bars at byte offset 0x10 - 0x14 for type 1 PCI device ) of the PCI configuration space header . bar for the physical PCI device ( pci_pdev ) the value of pbar ( hpa ) is assigned by platform firmware during boot . It is assumed a valid hpa is always assigned to a mmio pbar hypervisor shall not change the value of a pbar . for each pci_pdev it has a virtual PCI device ( pci_vdev ) counterpart . pci_vdev virtualizes all the bars ( called vbars ) . a vbar can be initialized by hypervisor by assigning a gpa to it ; if vbar has a value of 0 ( unassigned ) guest may assign and program a gpa to it . The guest only sees the vbars it will not see and can never change the pbars . Hypervisor traps guest changes to the mmio vbar ( gpa ) to establish ept mapping between vbar ( gpa ) and pbar ( hpa ) . pbar should always align on 4K boundary .
void init_vdev_pt(struct pci_vdev *vdev)
{
	enum pci_bar_type type;
	uint32_t idx;
	struct pci_vbar *vbar;
	uint16_t pci_command;
	uint32_t size32, offset, lo, hi = 0U;
	union pci_bdf pbdf;
	uint64_t mask;
	vdev->nr_bars = vdev->pdev->nr_bars;
	pbdf.value = vdev->pdev->bdf.value;
	for (idx = 0U; idx < vdev->nr_bars; idx++) {
		vbar = &vdev->vbars[idx];
		offset = pci_bar_offset(idx);
		lo = pci_pdev_read_cfg(pbdf, offset, 4U);
		type = pci_get_bar_type(lo);
		if (type == PCIBAR_NONE) {
			continue;
		}
		mask = (type == PCIBAR_IO_SPACE) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK;
		vbar->base_hpa = (uint64_t)lo & mask;
		if (type == PCIBAR_MEM64) {
			hi = pci_pdev_read_cfg(pbdf, offset + 4U, 4U);
			vbar->base_hpa |= ((uint64_t)hi << 32U);
		}
		if (vbar->base_hpa != 0UL) {
			pci_pdev_write_cfg(pbdf, offset, 4U, ~0U);
			size32 = pci_pdev_read_cfg(pbdf, offset, 4U);
			pci_pdev_write_cfg(pbdf, offset, 4U, lo);
			vbar->type = type;
			vbar->mask = size32 & mask;
			vbar->fixed = lo & (~mask);
			vbar->size = (uint64_t)size32 & mask;
			if (is_prelaunched_vm(vdev->vpci->vm)) {
				lo = (uint32_t)vdev->pci_dev_config->vbar_base[idx];
			}
			if (type == PCIBAR_MEM64) {
				idx++;
				offset = pci_bar_offset(idx);
				pci_pdev_write_cfg(pbdf, offset, 4U, ~0U);
				size32 = pci_pdev_read_cfg(pbdf, offset, 4U);
				pci_pdev_write_cfg(pbdf, offset, 4U, hi);
				vbar->size |= ((uint64_t)size32 << 32U);
				vbar->size = vbar->size & ~(vbar->size - 1UL);
				vbar->size = round_page_up(vbar->size);
				vbar = &vdev->vbars[idx];
				vbar->mask = size32;
				vbar->type = PCIBAR_MEM64HI;
				if (is_prelaunched_vm(vdev->vpci->vm)) {
					hi = (uint32_t)(vdev->pci_dev_config->vbar_base[idx - 1U] >> 32U);
				}
				pci_vdev_write_bar(vdev, idx - 1U, lo);
				pci_vdev_write_bar(vdev, idx, hi);
			} else {
				vbar->size = vbar->size & ~(vbar->size - 1UL);
				if (type == PCIBAR_MEM32) {
					vbar->size = round_page_up(vbar->size);
				}
				pci_vdev_write_bar(vdev, idx, lo);
			}
		}
	}
	if (is_prelaunched_vm(vdev->vpci->vm)) {
		pci_command = (uint16_t)pci_pdev_read_cfg(vdev->pdev->bdf, PCIR_COMMAND, 2U);
		pci_command |= 0x400U;
		pci_pdev_write_cfg(vdev->pdev->bdf, PCIR_COMMAND, 2U, pci_command);
	}
}
void init_vdev_pt ( struct pci_vdev * vdev ) { enum pci_bar_type type ; uint32_t idx ; struct pci_vbar * vbar ; uint16_t pci_command ; uint32_t size32 , offset , lo , hi = 0U ; union pci_bdf pbdf ; uint64_t mask ; vdev -> nr_bars = vdev -> pdev -> nr_bars ; pbdf . value = vdev -> pdev -> bdf . value ; for ( idx = 0U ; idx < vdev -> nr_bars ; idx ++ ) { vbar = & vdev -> vbars [ idx ] ; offset = pci_bar_offset ( idx ) ; lo = pci_pdev_read_cfg ( pbdf , offset , 4U ) ; type = pci_get_bar_type ( lo ) ; if ( type == PCIBAR_NONE ) { continue ; } mask = ( type == PCIBAR_IO_SPACE ) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK ; vbar -> base_hpa = ( uint64_t ) lo & mask ; if ( type == PCIBAR_MEM64 ) { hi = pci_pdev_read_cfg ( pbdf , offset + 4U , 4U ) ; vbar -> base_hpa |= ( ( uint64_t ) hi << 32U ) ; } if ( vbar -> base_hpa != 0UL ) { pci_pdev_write_cfg ( pbdf , offset , 4U , ~ 0U ) ; size32 = pci_pdev_read_cfg ( pbdf , offset , 4U ) ; pci_pdev_write_cfg ( pbdf , offset , 4U , lo ) ; vbar -> type = type ; vbar -> mask = size32 & mask ; vbar -> fixed = lo & ( ~ mask ) ; vbar -> size = ( uint64_t ) size32 & mask ; if ( is_prelaunched_vm ( vdev -> vpci -> vm ) ) { lo = ( uint32_t ) vdev -> pci_dev_config -> vbar_base [ idx ] ; } if ( type == PCIBAR_MEM64 ) { idx ++ ; offset = pci_bar_offset ( idx ) ; pci_pdev_write_cfg ( pbdf , offset , 4U , ~ 0U ) ; size32 = pci_pdev_read_cfg ( pbdf , offset , 4U ) ; pci_pdev_write_cfg ( pbdf , offset , 4U , hi ) ; vbar -> size |= ( ( uint64_t ) size32 << 32U ) ; vbar -> size = vbar -> size & ~ ( vbar -> size - 1UL ) ; vbar -> size = round_page_up ( vbar -> size ) ; vbar = & vdev -> vbars [ idx ] ; vbar -> mask = size32 ; vbar -> type = PCIBAR_MEM64HI ; if ( is_prelaunched_vm ( vdev -> vpci -> vm ) ) { hi = ( uint32_t ) ( vdev -> pci_dev_config -> vbar_base [ idx - 1U ] >> 32U ) ; } pci_vdev_write_bar ( vdev , idx - 1U , lo ) ; pci_vdev_write_bar ( vdev , idx , hi ) ; } else { vbar -> size = vbar -> size & ~ ( vbar -> size - 1UL ) ; if ( type == PCIBAR_MEM32 ) { vbar -> size = round_page_up ( vbar -> size ) ; } pci_vdev_write_bar ( vdev , idx , lo ) ; } } } if ( is_prelaunched_vm ( vdev -> vpci -> vm ) ) { pci_command = ( uint16_t ) pci_pdev_read_cfg ( vdev -> pdev -> bdf , PCIR_COMMAND , 2U ) ; pci_command |= 0x400U ; pci_pdev_write_cfg ( vdev -> pdev -> bdf , PCIR_COMMAND , 2U , pci_command ) ; } }
PCI base address register (bar) virtualization:
 Virtualize the PCI bars (up to 6 bars at byte offset 0x10~0x24 for type 0 PCI device,
 2 bars at byte offset 0x10-0x14 for type 1 PCI device) of the PCI configuration space
 header.
PCI base address register ( bar ) virtualization : Virtualize the PCI bars ( up to 6 bars at byte offset 0x10~0x24 for type 0 PCI device 2 bars at byte offset 0x10 - 0x14 for type 1 PCI device ) of the PCI configuration space header .
/* Disable INTX */