/** * Read from PCI config space. * @param bdf 16-bit bus/device/function ID of target. * @param address Config space access address. * @param size Access size (1, 2 or 4 bytes). * * @return Read value. * * @see pci_write_config */ u32 pci_read_config(u16 bdf, u16 address, unsigned int size) { void *mmcfg_addr = pci_get_device_mmcfg_base(bdf) + address; if (!pci_space || PCI_BUS(bdf) > end_bus) return arch_pci_read_config(bdf, address, size); if (size == 1) return mmio_read8(mmcfg_addr); else if (size == 2) return mmio_read16(mmcfg_addr); else return mmio_read32(mmcfg_addr); }
/** * Handler for IN accesses to data port. * @param guest_regs Guest register set. * @param device Structure describing PCI device. * @param address Config space access address. * @param size Access size (1, 2 or 4 bytes). * * @return 1 if handled successfully, -1 on access error. * * @private */ static int data_port_in_handler(struct registers *guest_regs, struct pci_device *device, u16 address, unsigned int size) { u32 reg_data; if (pci_cfg_read_moderate(device, address, size, ®_data) == PCI_ACCESS_PERFORM) reg_data = arch_pci_read_config(device->info->bdf, address, size); set_rax_reg(guest_regs, reg_data, size); return 1; }