> 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

Reply via email to