PERFORCE change 192618 for review

John Baldwin jhb at FreeBSD.org
Wed May 4 21:51:51 UTC 2011


http://p4web.freebsd.org/@@192618?ac=10

Change 192618 by jhb at jhb_jhbbsd on 2011/05/04 21:51:01

	Add support for RF_PREFETCHABLE memory ranges in hostb decoding.

Affected files ...

.. //depot/projects/pci/sys/dev/acpica/acpi_pcib_acpi.c#16 edit
.. //depot/projects/pci/sys/dev/pci/pci_domain.c#8 edit
.. //depot/projects/pci/sys/dev/pci/pcib_private.h#15 edit
.. //depot/projects/pci/sys/sys/bus.h#5 edit

Differences ...

==== //depot/projects/pci/sys/dev/acpica/acpi_pcib_acpi.c#16 (text+ko) ====

@@ -158,6 +158,7 @@
 {
 	struct acpi_hpcib_softc *sc;
 	UINT64 length, min, max;
+	u_int flags;
 	int error, type;
 
 	sc = context;
@@ -175,6 +176,7 @@
 		case ACPI_RESOURCE_TYPE_ADDRESS16:
 			min = res->Data.Address16.Minimum;
 			max = res->Data.Address16.Maximum;
+			flags = res->Data.Address16.
 			length = res->Data.Address16.AddressLength;
 			break;
 		case ACPI_RESOURCE_TYPE_ADDRESS32:
@@ -201,9 +203,20 @@
 		    res->Data.Address.MaxAddressFixed != ACPI_ADDRESS_FIXED)
 			break;
 		KASSERT(min + length - 1 == max, ("invalid range"));
+		flags = 0;
 		switch (res->Data.Address.ResourceType) {
 		case ACPI_MEMORY_RANGE:
 			type = SYS_RES_MEMORY;
+			if (res->Type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64) {
+				if (res->Data.Address.Info.Mem.Caching ==
+				    ACPI_PREFETCHABLE_MEMORY)
+					flags |= RF_PREFETCHABLE;
+			} else {
+				/*
+				 * XXX: Parse prefetch flag out of
+				 * TypeSpecific.
+				 */
+			}
 			break;
 		case ACPI_IO_RANGE:
 			type = SYS_RES_IOPORT;
@@ -238,7 +251,8 @@
 			max = ULONG_MAX;
 		}
 #endif
-		error = pcib_host_res_decodes(&sc->ap_host_res, type, min, max);
+		error = pcib_host_res_decodes(&sc->ap_host_res, type, min, max,
+		    flags);
 		if (error)
 			panic("Failed to manage %d range (%#jx-%#jx): %d", type,
 			    (uintmax_t)min, (uintmax_t)max, error);

==== //depot/projects/pci/sys/dev/pci/pci_domain.c#8 (text+ko) ====

@@ -136,13 +136,23 @@
 
 int
 pcib_host_res_decodes(struct pcib_host_resources *hr, int type, u_long start,
-    u_long end)
+    u_long end, u_int flags)
 {
+	struct resource_list_entry *rle;
+	int rid;
 
 	if (bootverbose)
-		device_printf(hr->hr_pcib, "decoding %d range %#lx-%#lx\n",
-		    type, start, end);
-	resource_list_add_next(&hr->hr_rl, type, start, end, end - start + 1);
+		device_printf(hr->hr_pcib, "decoding %d %srange %#lx-%#lx\n",
+		    flags & RF_PREFETCHABLE ? "prefetchable ": "", type, start,
+		    end);
+	rid = resource_list_add_next(&hr->hr_rl, type, start, end,
+	    end - start + 1);
+	if (flags & RF_PREFETCHABLE) {
+		KASSERT(type == SYS_RES_MEMORY,
+		    ("only memory is prefetchable"));
+		rle = resource_list_find(&hr->hr_rl, type, rid);
+		rle->flags = RLE_PREFETCH;
+	}
 	return (0);
 }
 
@@ -154,6 +164,10 @@
 	struct resource *r;
 	u_long new_start, new_end;
 
+	if (flags & RF_PREFETCHABLE)
+		KASSERT(type == SYS_RES_MEMORY,
+		    ("only memory is prefetchable"));
+
 	rle = resource_list_find(&hr->hr_rl, type, 0);
 	if (rle == NULL) {
 		/*
@@ -163,11 +177,15 @@
 		return (bus_generic_alloc_resource(hr->hr_pcib, dev, type, rid,
 		    start, end, count, flags));
 	}
-		   
+
+restart:
 	/* Try to allocate from each decoded range. */
 	for (; rle != NULL; rle = STAILQ_NEXT(rle, link)) {
 		if (rle->type != type)
 			continue;
+		if (((flags & RF_PREFETCHABLE) != 0) !=
+		    ((rle->flags & RLE_PREFETCH) != 0))
+			continue;
 		new_start = ulmax(start, rle->start);
 		new_end = ulmin(end, rle->end);
 		if (new_start > new_end ||
@@ -186,5 +204,13 @@
 		}
 	}
 
+	/*
+	 * If we failed to find a prefetch range for a memory
+	 * resource, try again without prefetch.
+	 */
+	if (flags & RF_PREFETCHABLE) {
+		flags &= ~RF_PREFETCHABLE;
+		goto restart;
+	}
 	return (NULL);
 }

==== //depot/projects/pci/sys/dev/pci/pcib_private.h#15 (text+ko) ====

@@ -109,7 +109,7 @@
 int		pcib_host_res_free(device_t pcib,
 		    struct pcib_host_resources *hr);
 int		pcib_host_res_decodes(struct pcib_host_resources *hr, int type,
-		    u_long start, u_long end);
+		    u_long start, u_long end, u_int flags);
 struct resource *pcib_host_res_alloc(struct pcib_host_resources *hr,
 		    device_t dev, int type, int *rid, u_long start, u_long end,
 		    u_long count, u_int flags);

==== //depot/projects/pci/sys/sys/bus.h#5 (text+ko) ====

@@ -247,6 +247,7 @@
 
 #define	RLE_RESERVED		0x0001	/* Reserved by the parent bus. */
 #define	RLE_ALLOCATED		0x0002	/* Reserved resource is allocated. */
+#define	RLE_PREFETCH		0x0004	/* Resource is a prefetch range. */
 
 void	resource_list_init(struct resource_list *rl);
 void	resource_list_free(struct resource_list *rl);


More information about the p4-projects mailing list