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