diff options
author | Marcel Apfelbaum <marcel@redhat.com> | 2015-06-02 14:23:11 +0300 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2015-06-03 18:19:18 +0200 |
commit | 0f6dd8e1d514b8c24689499ed72ea89fd0d967f3 (patch) | |
tree | 0be64b828df070b4f646f39fa6c64de0e56d074f /hw/i386 | |
parent | 0e79e51a7dcbd4fde5738d713b60f0fb0321f1af (diff) |
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 <marcel@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Diffstat (limited to 'hw/i386')
-rw-r--r-- | hw/i386/acpi-build.c | 87 |
1 files 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); + } } } |