From 0f6dd8e1d514b8c24689499ed72ea89fd0d967f3 Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Tue, 2 Jun 2015 14:23:11 +0300 Subject: [PATCH] apci: fix PXB behaviour if used with unsupported BIOS PXB does not work with unsupported bioses, but should not interfere with normal OS operation. We don't ship them anymore, but it's reasonable to keep the work-around until we update the bios in qemu. Fix this by not adding PXB mem/IO chunks to _CRS if they weren't configured by BIOS. Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Acked-by: Laszlo Ersek --- hw/i386/acpi-build.c | 87 +++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 45c36a88bd..db32fd1526 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -786,6 +786,14 @@ static Aml *build_crs(PCIHostState *host, range_base = r->addr; range_limit = r->addr + r->size - 1; + /* + * Work-around for old bioses + * that do not support multiple root buses + */ + if (!range_base || range_base > range_limit) { + continue; + } + if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { aml_append(crs, aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED, @@ -819,45 +827,66 @@ static Aml *build_crs(PCIHostState *host, range_base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO); range_limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO); - aml_append(crs, - aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED, - AML_POS_DECODE, AML_ENTIRE_RANGE, - 0, - range_base, - range_limit, - 0, - range_limit - range_base + 1)); - crs_range_insert(io_ranges, range_base, range_limit); + + /* + * Work-around for old bioses + * that do not support multiple root buses + */ + if (range_base || range_base > range_limit) { + aml_append(crs, + aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED, + AML_POS_DECODE, AML_ENTIRE_RANGE, + 0, + range_base, + range_limit, + 0, + range_limit - range_base + 1)); + crs_range_insert(io_ranges, range_base, range_limit); + } range_base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY); range_limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY); - aml_append(crs, - aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, - AML_MAX_FIXED, AML_NON_CACHEABLE, - AML_READ_WRITE, - 0, - range_base, - range_limit, - 0, - range_limit - range_base + 1)); - crs_range_insert(mem_ranges, range_base, range_limit); + + /* + * Work-around for old bioses + * that do not support multiple root buses + */ + if (range_base || range_base > range_limit) { + aml_append(crs, + aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, + AML_MAX_FIXED, AML_NON_CACHEABLE, + AML_READ_WRITE, + 0, + range_base, + range_limit, + 0, + range_limit - range_base + 1)); + crs_range_insert(mem_ranges, range_base, range_limit); + } range_base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH); range_limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH); - aml_append(crs, - aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, - AML_MAX_FIXED, AML_NON_CACHEABLE, - AML_READ_WRITE, - 0, - range_base, - range_limit, - 0, - range_limit - range_base + 1)); - crs_range_insert(mem_ranges, range_base, range_limit); + + /* + * Work-around for old bioses + * that do not support multiple root buses + */ + if (range_base || range_base > range_limit) { + aml_append(crs, + aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, + AML_MAX_FIXED, AML_NON_CACHEABLE, + AML_READ_WRITE, + 0, + range_base, + range_limit, + 0, + range_limit - range_base + 1)); + crs_range_insert(mem_ranges, range_base, range_limit); + } } } -- GitLab