Define a TOM(top of memory) register to report the base of PCI memory, so that qemu should update MMIO by reading this register value. With the combination of qemu upstream, this should be a fix for PCI MMIO hole configuration. Upstream qemu set 0xe0000000 as TOM, but guest bios may set MMIO to 0x80000000~0xe0000000. Signed-off-by: Xudong Hao <xudong.hao@intel.com> Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com> --- tools/firmware/hvmloader/pci.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tools/firmware/hvmloader/pci.c b/tools/firmware/hvmloader/pci.c index c7c87a7..a70e1d1 100644 --- a/tools/firmware/hvmloader/pci.c +++ b/tools/firmware/hvmloader/pci.c @@ -34,6 +34,29 @@ unsigned long pci_mem_end = PCI_MEM_END; enum virtual_vga virtual_vga = VGA_none; unsigned long igd_opregion_pgbase = 0; +#define PCI_CLASS_BRIDGE_HOST 0x0600 +#define PCI_VENDOR_ID_INTEL 0x8086 +#define PCI_DEVICE_ID_INTEL_82441 0x1237 +#define I440FX_PCI_HOLE_BASE 0xb0 + +static void pci_adjust_pci_hole(uint32_t pci_hole_start) +{ + uint16_t class, vendor_id, device_id; + if (pci_hole_start == 0xf0000000) + return; + + /* Check whether it is I440FX */ + class = pci_readw(0, PCI_CLASS_DEVICE); + vendor_id = pci_readw(0, PCI_VENDOR_ID); + device_id = pci_readw(0, PCI_DEVICE_ID); + + if (class != PCI_CLASS_BRIDGE_HOST || + vendor_id != PCI_VENDOR_ID_INTEL || + device_id != PCI_DEVICE_ID_INTEL_82441) + return; + pci_writel(0, I440FX_PCI_HOLE_BASE, pci_hole_start); + +} void pci_setup(void) { uint8_t is_64bar, using_64bar, bar64_relocate = 0; @@ -236,6 +259,7 @@ void pci_setup(void) BUG(); hvm_info->high_mem_pgend += nr_pages; } + pci_adjust_pci_hole(hvm_info->low_mem_pgend << PAGE_SHIFT); high_mem_resource.base = ((uint64_t)hvm_info->high_mem_pgend) << PAGE_SHIFT; high_mem_resource.max = 1ull << cpu_phys_addr(); -- 1.7.12.1