Date: Fri, 15 Apr 2011 03:39:58 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 191528 for review Message-ID: <201104150339.p3F3dwmj031845@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@191528?ac=10 Change 191528 by jhb@jhb_fiver on 2011/04/15 03:39:06 More hacking. I think the host bridge resource stuff first pass is done. Still need to tackle bus number allocation in the host bridge driver and then in the PCI-PCI bridge driver. Affected files ... .. //depot/projects/pci/sys/dev/acpica/acpi_pcib_acpi.c#5 edit Differences ... ==== //depot/projects/pci/sys/dev/acpica/acpi_pcib_acpi.c#5 (text+ko) ==== @@ -91,6 +91,14 @@ device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags); +#ifdef NEW_PCIB +static int acpi_pcib_acpi_adjust_resource(device_t dev, + device_t child, int type, struct resource *r, + u_long start, u_long end); +static int acpi_pcib_acpi_release_resource(device_t dev, + device_t child, int type, int rid, + struct resource *r); +#endif static device_method_t acpi_pcib_acpi_methods[] = { /* Device interface */ @@ -159,16 +167,95 @@ } #ifdef NEW_PCIB -static void -acpi_pcib_add_producers(struct acpi_hpcib_softc *sc) +static ACPI_STATUS +acpi_pcib_producer_handler(ACPI_RESOURCE *res, void *context) { + struct acpi_hpcib_softc *sc; + UINT64 length, min, max; + int error, type; - if (pcib_host_res_init(sc->ap_dev, &sc->ap_host_res) != 0) - panic("failed to init hostb resources"); - /* - * XXX: Next use AcpiWalkResources() on _CRS calling - * pcib_host_res_manage() on each producer range. - */ + sc = context; + switch (res->Type) { + case ACPI_RESOURCE_TYPE_START_DEPENDENT: + case ACPI_RESOURCE_TYPE_END_DEPENDENT: + panic("host bridge has depenedent resources"); + case ACPI_RESOURCE_TYPE_ADDRESS16: + case ACPI_RESOURCE_TYPE_ADDRESS32: + case ACPI_RESOURCE_TYPE_ADDRESS64: + case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: + if (res->Data.Address.ProducerConsumer != ACPI_PRODUCER) + break; + switch (res->Type) { + case ACPI_RESOURCE_TYPE_ADDRESS16: + min = res->Data.Address16.Minimum; + max = res->Data.Address16.Maximum; + length = res->Data.Address16.AddressLength; + break; + case ACPI_RESOURCE_TYPE_ADDRESS32: + min = res->Data.Address32.Minimum; + max = res->Data.Address32.Maximum; + length = res->Data.Address32.AddressLength; + break; + case ACPI_RESOURCE_TYPE_ADDRESS64: + min = res->Data.Address64.Minimum; + max = res->Data.Address64.Maximum; + length = res->Data.Address64.AddressLength; + break; + case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: + min = res->Data.ExtAddress64.Minimum; + max = res->Data.ExtAddress64.Maximum; + length = res->Data.ExtAddress64.AddressLength; + break; + } + if (length == 0 || + res->Data.Address.MinAddressFixed != ACPI_ADDRESS_FIXED || + res->Data.Address.MaxAddressFixed != ACPI_ADDRESS_FIXED) + break; + KASSERT(min + length - 1 == max, ("invalid range")); + switch (res->Data.Address.ResourceType) { + case ACPI_MEMORY_RANGE: + type = SYS_RES_MEMORY; + break; + case ACPI_IO_RANGE: + type = SYS_RES_IOPORT; + break; + case ACPI_BUS_NUMBER_RANGE: + type = PCI_RES_BUS; + break; + default: + return (AE_OK); + } + + /* XXX: Not sure this is correct? */ + if (res->Data.Address.Decode != ACPI_POS_DECODE) { + device_printf(sc->ap_dev, + "Ignoring %d range (%#jx-%#jx) due to negative decode\n", + type, (uintmax_t)min, (uintmax_t)max); + break; + } +#ifdef __i386__ + if (min > ULONG_MAX) { + device_printf(sc->ap_dev, + "Ignoring %d range above 4GB (%#jx-%#jx)\n", + type, (uintmax_t)min, (uintmax_t)max); + break; + } + if (max > ULONG_MAX) { + device_printf(sc->ap_dev, + "Truncating end of range above 4GB (%#jx-%#jx)\n", + type, (uintmax_t)min, (uintmax_t)max); + max = ULONG_MAX; + } +#endif + error = pcib_host_res_manage(&sc->ap_host_res, type, min, max); + if (error) + panic("Failed to manage %d range (%#jx-%#jx): %d", type, + (uintmax_t)min, (uintmax_t)max, error); + break; + default: + break; + } + return (AE_OK); } #endif @@ -202,6 +289,20 @@ sc->ap_segment = 0; } +#ifdef NEW_PCIB + /* + * Determine which address ranges this bridge decodes and setup + * resource managers for those ranges. + */ + if (pcib_host_res_init(sc->ap_dev, &sc->ap_host_res) != 0) + panic("failed to init hostb resources"); + status = AcpiWalkResources(sc->ap_handle, "_CRS", + acpi_pcib_producer_handler, sc); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) + device_printf(sc->ap_dev, "failed to parse resources: %s\n", + AcpiFormatException(status)); +#endif + /* * Get our base bus number by evaluating _BBN. * If this doesn't work, we assume we're bus number 0. @@ -271,8 +372,10 @@ * out the Host-PCI bridges in order and that as a result the next * free bus number is our bus number. */ + if (busok) { + } else { + } #else -#endif /* * If nothing else worked, hope that ACPI at least lays out the * host-PCI bridges in order and that as a result our unit number @@ -283,6 +386,7 @@ sc->ap_bus = device_get_unit(dev); device_printf(dev, "trying bus number %d\n", sc->ap_bus); } +#endif /* If this is bus 0 on segment 0, note that it has been seen already. */ if (sc->ap_segment == 0 && sc->ap_bus == 0) @@ -423,3 +527,26 @@ return (bus_generic_alloc_resource(dev, child, type, rid, start, end, count, flags)); } + +#ifdef NEW_PCIB +int +acpi_pcib_acpi_adjust_resource(device_t dev, device_t child, int type, + struct resource *r, u_long start, u_long end) +{ + struct acpi_hpcib_softc *sc; + + sc = device_get_softc(dev); + return (pcib_host_res_adjust(&sc->ap_host_res, child, type, r, start, + end)); +} + +int +acpi_pcib_acpi_release_resource(device_t dev, device_t child, int type, int rid, + struct resource *r) +{ + struct acpi_hpcib_softc *sc; + + sc = device_get_softc(dev); + return (pcib_host_res_release(&sc->ap_host_res, child, type, rid, r)); +} +#endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104150339.p3F3dwmj031845>