Mercurial > illumos > illumos-gate
changeset 2950:449abdd74783
6354996 pci_boot.c incorrectly accounts for system resources in PCI configuration
author | myers |
---|---|
date | Fri, 20 Oct 2006 07:29:03 -0700 |
parents | 5581081d0989 |
children | 8e5048c1f58e |
files | usr/src/uts/i86pc/io/acpica/acpi_enum.c usr/src/uts/i86pc/io/pci/pci_boot.c |
diffstat | 2 files changed, 75 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/i86pc/io/acpica/acpi_enum.c Fri Oct 20 07:07:59 2006 -0700 +++ b/usr/src/uts/i86pc/io/acpica/acpi_enum.c Fri Oct 20 07:29:03 2006 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -279,8 +278,9 @@ addr16.Maximum, addr16.AddressLength); } - if (addr16.ResourceType != ACPI_MEMORY_RANGE && - addr16.ResourceType != ACPI_IO_RANGE) { + if (addr16.ProducerConsumer == ACPI_PRODUCER || + (addr16.ResourceType != ACPI_MEMORY_RANGE && + addr16.ResourceType != ACPI_IO_RANGE)) { return; } if (addr16.AddressLength > 0) { @@ -330,8 +330,9 @@ addr32.Maximum, addr32.AddressLength); } - if (addr32.ResourceType != ACPI_MEMORY_RANGE && - addr32.ResourceType != ACPI_IO_RANGE) { + if (addr32.ProducerConsumer == ACPI_PRODUCER || + (addr32.ResourceType != ACPI_MEMORY_RANGE && + addr32.ResourceType != ACPI_IO_RANGE)) { return; } if (addr32.AddressLength > 0) { @@ -391,8 +392,9 @@ addr64.Maximum, addr64.AddressLength); } - if (addr64.ResourceType != ACPI_MEMORY_RANGE && - addr64.ResourceType != ACPI_IO_RANGE) { + if (addr64.ProducerConsumer == ACPI_PRODUCER || + (addr64.ResourceType != ACPI_MEMORY_RANGE && + addr64.ResourceType != ACPI_IO_RANGE)) { return; } if (addr64.AddressLength > 0) {
--- a/usr/src/uts/i86pc/io/pci/pci_boot.c Fri Oct 20 07:07:59 2006 -0700 +++ b/usr/src/uts/i86pc/io/pci/pci_boot.c Fri Oct 20 07:29:03 2006 -0700 @@ -356,6 +356,62 @@ } } +static void +remove_resource_range(struct memlist **list, int *ranges, int range_count) +{ + struct range { + uint32_t base; + uint32_t len; + }; + int index; + + ASSERT(*list != NULL); + + for (index = 0; index < range_count; index++) { + (void) memlist_remove(list, + (uint64_t)((struct range *)ranges)[index].base, + (uint64_t)((struct range *)ranges)[index].len); + } +} + +static void +remove_used_resources() +{ + dev_info_t *used; + int *narray; + uint_t ncount; + int status; + int bus; + + used = ddi_find_devinfo("used-resources", -1, 0); + if (used == NULL) { + printf("pci_boot did not find used-resources\n"); + return; + } + + status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, used, + DDI_PROP_DONTPASS, "io-space", &narray, &ncount); + if (status == DDI_PROP_SUCCESS) { + for (bus = 0; bus <= pci_bios_nbus; bus++) + if (pci_bus_res[bus].io_ports != NULL) + remove_resource_range( + &pci_bus_res[bus].io_ports, + narray, ncount / 2); + ddi_prop_free(narray); + } + + status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, used, + DDI_PROP_DONTPASS, "device-memory", &narray, &ncount); + if (status == DDI_PROP_SUCCESS) { + for (bus = 0; bus <= pci_bios_nbus; bus++) + if (pci_bus_res[bus].mem_space != NULL) + remove_resource_range( + &pci_bus_res[bus].mem_space, + narray, ncount / 2); + ddi_prop_free(narray); + } +} + void pci_reprogram(void) { @@ -386,6 +442,9 @@ ddi_prop_free(onoff); } + /* remove used-resources from PCI resource maps */ + remove_used_resources(); + for (i = 0; i <= pci_bios_nbus; i++) { /* configure devices not configured by bios */ if (pci_reconfig) @@ -435,14 +494,15 @@ /* * Special treatment of bus 0: * If no resource from MPSPEC/HRT, copy pcimem from boot - * and make io space the entire range. There is no difference - * between prefetchable memory or not. + * and make I/O space the entire range starting at 0x100. There + * is no difference between prefetchable memory or not. */ if (pci_bus_res[0].mem_space == NULL) pci_bus_res[0].mem_space = memlist_dup(bootops->boot_mem->pcimem); + /* Exclude 0x00 to 0xff of the I/O space, used by all PCs */ if (pci_bus_res[0].io_ports == NULL) - memlist_insert(&pci_bus_res[0].io_ports, 0, 0x10000); + memlist_insert(&pci_bus_res[0].io_ports, 0x100, 0xff00); } /*