> Date: Fri, 19 Dec 2014 23:41:56 +1000 > From: Jonathan Matthew <jonat...@d14n.org> > > On Thu, Dec 18, 2014 at 11:14:54PM +0100, Frederic Nowak wrote: > > Hi! > > > > The diff for extracting memory ranges from ACPI was obviously not tested > > with ACPI disabled...so we definitely have to check if the values in > > pcimem_range make some sense. The diff below now uses the old values in > > case ACPI is disabled or does not return valid values. > > > > I hope this is somewhat interesting for someone else as well :) > > Please let me know if this is just noise or if there is anything else I > > am missing. > > This looks like the right direction, except I think we only really want to use > the ACPI range information to add new ranges to the existing one that covers > the 36-bit address space, rather than relying on it for everything. No point > relying on the ACPI stuff being correct if we don't need to. > > I hacked this around a bit today and ended up with the diff below. This only > deals with ranges outside the 36-bit space, so it makes no difference on most > machines, and on the r630 that needs it, it adds two ranges, > 0x0000030000000000 to 0x0000033FFFFFFFFF and 0x0000034000000000 to > 0x0000037FFFFFFFFF.
This is going in the right direction. The way I designed things though was that the acpi code would build up the complete extent purely from information provided by _CRS, and set pcimem_ex before pci_init_extents() gets called. > Index: arch/amd64/pci/pci_machdep.c > =================================================================== > RCS file: /cvs/src/sys/arch/amd64/pci/pci_machdep.c,v > retrieving revision 1.60 > diff -u -p -r1.60 pci_machdep.c > --- arch/amd64/pci/pci_machdep.c 16 Dec 2014 23:13:20 -0000 1.60 > +++ arch/amd64/pci/pci_machdep.c 19 Dec 2014 12:54:44 -0000 > @@ -90,12 +90,17 @@ > #include <dev/pci/ppbreg.h> > > #include "ioapic.h" > +#include "acpi.h" > > #if NIOAPIC > 0 > #include <machine/i82093var.h> > #include <machine/mpbiosvar.h> > #endif > > +#if NACPI > 0 > +#include <dev/acpi/acpivar.h> > +#endif > + > /* > * Memory Mapped Configuration space access. > * > @@ -622,17 +627,13 @@ pci_init_extents(void) > * here. As long as vendors continue to support > * 32-bit operating systems, we should never see BARs > * outside that region. > - * > - * Dell 13G servers have important devices outside the > - * 36-bit address space. Until we can extract the address > - * ranges from ACPI, expand the allowed range to suit. > */ > pcimem_ex = extent_create("pcimem", 0, 0xffffffffffffffffUL, > M_DEVBUF, NULL, 0, EX_NOWAIT); > if (pcimem_ex == NULL) > return; > - extent_alloc_region(pcimem_ex, 0x40000000000UL, > - 0xfffffc0000000000UL, EX_NOWAIT); > + extent_alloc_region(pcimem_ex, 0x1000000000UL, > + 0xfffffff000000000UL, EX_NOWAIT); > > for (bmp = bios_memmap; bmp->type != BIOS_MAP_END; bmp++) { > /* > @@ -657,6 +658,14 @@ pci_init_extents(void) > /* Take out the video buffer area and BIOS areas. */ > extent_alloc_region(pcimem_ex, IOM_BEGIN, IOM_SIZE, > EX_CONFLICTOK | EX_NOWAIT); > + > +#if NACPI > 0 > + /* > + * Free up any regions outside the 36-bit address space > + * specified via ACPI. > + */ > + acpi_pciroots_extents(pcimem_ex, 0x1000000000UL); > +#endif > } > > if (pcibus_ex == NULL) { > @@ -665,7 +674,6 @@ pci_init_extents(void) > } > } > > -#include "acpi.h" > #if NACPI > 0 > void acpi_pci_match(struct device *, struct pci_attach_args *); > pcireg_t acpi_pci_min_powerstate(pci_chipset_tag_t, pcitag_t); > Index: dev/acpi/acpivar.h > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v > retrieving revision 1.79 > diff -u -p -r1.79 acpivar.h > --- dev/acpi/acpivar.h 8 Dec 2014 07:12:37 -0000 1.79 > +++ dev/acpi/acpivar.h 19 Dec 2014 12:54:44 -0000 > @@ -47,6 +47,7 @@ extern u_int8_t acpi_lapic_flags[LAPIC_M > struct klist; > struct acpiec_softc; > struct acpipwrres_softc; > +struct extent; > > struct acpivideo_softc { > struct device sc_dev; > @@ -357,6 +358,7 @@ int acpi_acquire_glk(uint32_t *); > int acpi_release_glk(uint32_t *); > > void acpi_pciroots_attach(struct device *, void *, cfprint_t); > +void acpi_pciroots_extents(struct extent *, u_int64_t); > > #endif > > Index: dev/acpi/amltypes.h > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/amltypes.h,v > retrieving revision 1.40 > diff -u -p -r1.40 amltypes.h > --- dev/acpi/amltypes.h 7 Sep 2012 19:19:59 -0000 1.40 > +++ dev/acpi/amltypes.h 19 Dec 2014 12:54:44 -0000 > @@ -346,6 +346,12 @@ struct aml_value { > #define aml_pkglen(v) ((v)->length) > #define aml_pkgval(v,i) (&(v)->v_package[(i)]) > > +struct acpi_pci_range { > + SLIST_ENTRY(acpi_pci_range) next; > + uint64_t base; > + uint64_t len; > +}; > + > struct acpi_pci { > TAILQ_ENTRY(acpi_pci) next; > > @@ -362,6 +368,8 @@ struct acpi_pci { > int _s3w; > int _s4d; > int _s4w; > + > + SLIST_HEAD(, acpi_pci_range) ranges; > }; > > struct aml_node { > Index: dev/acpi/acpi.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/acpi.c,v > retrieving revision 1.277 > diff -u -p -r1.277 acpi.c > --- dev/acpi/acpi.c 9 Dec 2014 06:58:29 -0000 1.277 > +++ dev/acpi/acpi.c 19 Dec 2014 12:54:44 -0000 > @@ -384,20 +384,41 @@ TAILQ_HEAD(, acpi_pci) acpi_pcirootdevs > TAILQ_HEAD_INITIALIZER(acpi_pcirootdevs); > > int acpi_getpci(struct aml_node *node, void *arg); > -int acpi_getminbus(union acpi_resource *crs, void *arg); > +int acpi_parse_pci(union acpi_resource *crs, void *arg); > > int > -acpi_getminbus(union acpi_resource *crs, void *arg) > +acpi_parse_pci(union acpi_resource *crs, void *arg) > { > - int *bbn = arg; > + struct acpi_pci *pci = arg; > + struct acpi_pci_range *pcir; > int typ = AML_CRSTYPE(crs); > > - /* Check for embedded bus number */ > - if (typ == LR_WORD && crs->lr_word.type == 2) { > - /* If _MIN > _MAX, the resource is considered to be invalid. */ > - if (crs->lr_word._min > crs->lr_word._max) > - return -1; > - *bbn = crs->lr_word._min; > + switch (typ) { > + case LR_WORD: > + /* Check for embedded bus number */ > + if (crs->lr_word.type == 2) { > + /* > + * If _MIN > _MAX, the resource is considered to be > + * invalid. > + */ > + if (crs->lr_word._min > crs->lr_word._max) > + return -1; > + pci->bus = crs->lr_word._min; > + } > + break; > + > + case LR_QWORD: > + /* > + * We only care about ranges outside the 32-bit address space, > + * so only LR_QWORD is interesting here. > + */ > + if (crs->lr_qword.type == 0) { > + pcir = malloc(sizeof(*pcir), M_DEVBUF, M_WAITOK|M_ZERO); > + pcir->base = crs->lr_qword._min; > + pcir->len = crs->lr_qword._max - crs->lr_qword._min; > + SLIST_INSERT_HEAD(&pci->ranges, pcir, next); > + } > + break; > } > return 0; > } > @@ -455,8 +476,7 @@ acpi_getpci(struct aml_node *node, void > if (!aml_evalinteger(sc, node, "_SEG", 0, NULL, &val)) > pci->seg = val; > if (!aml_evalname(sc, node, "_CRS", 0, NULL, &res)) { > - aml_parse_resource(&res, acpi_getminbus, > - &pci->bus); > + aml_parse_resource(&res, acpi_parse_pci, pci); > dnprintf(10, "%s post-crs: %d\n", > aml_nodename(node), > pci->bus); > } > @@ -686,6 +706,21 @@ acpi_pci_notify(struct aml_node *node, i > } > > return (0); > +} > + > +void > +acpi_pciroots_extents(struct extent *memex, u_int64_t minaddr) > +{ > + struct acpi_pci *pdev; > + struct acpi_pci_range *range; > + > + TAILQ_FOREACH(pdev, &acpi_pcirootdevs, next) { > + SLIST_FOREACH(range, &pdev->ranges, next) { > + if (range->base > minaddr) { > + extent_free(memex, range->base, range->len, 0); > + } > + } > + } > } > > void