/** * Write to PCI config space. * @param bdf 16-bit bus/device/function ID of target. * @param address Config space access address. * @param value Value to be written. * @param size Access size (1, 2 or 4 bytes). * * @see pci_read_config */ void pci_write_config(u16 bdf, u16 address, u32 value, unsigned int size) { void *mmcfg_addr = pci_get_device_mmcfg_base(bdf) + address; if (!pci_space || PCI_BUS(bdf) > end_bus) return arch_pci_write_config(bdf, address, value, size); if (size == 1) mmio_write8(mmcfg_addr, value); else if (size == 2) mmio_write16(mmcfg_addr, value); else mmio_write32(mmcfg_addr, value); }
/** * Handler for OUT 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_out_handler(struct registers *guest_regs, struct pci_device *device, u16 address, unsigned int size) { u32 reg_data = get_rax_reg(guest_regs, size); enum pci_access access; access = pci_cfg_write_moderate(device, address, size, reg_data); if (access == PCI_ACCESS_REJECT) return -1; if (access == PCI_ACCESS_PERFORM) arch_pci_write_config(device->info->bdf, address, reg_data, size); return 1; }