PERFORCE change 191528 for review
John Baldwin
jhb at FreeBSD.org
Fri Apr 15 03:39:58 UTC 2011
http://p4web.freebsd.org/@@191528?ac=10
Change 191528 by jhb at 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
More information about the p4-projects
mailing list