Skip site navigation (1)Skip section navigation (2)
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>