Date: Wed, 4 May 2011 21:51:50 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 192618 for review Message-ID: <201105042151.p44Lpoxo020934@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@192618?ac=10 Change 192618 by jhb@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105042151.p44Lpoxo020934>
