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.


Index: sys/arch/amd64/include/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/pci_machdep.h,v
retrieving revision 1.22
diff -u -p -b -r1.22 pci_machdep.h
--- sys/arch/amd64/include/pci_machdep.h        6 Nov 2013 10:40:36 -0000       
1.22
+++ sys/arch/amd64/include/pci_machdep.h        17 Dec 2014 06:00:01 -0000
@@ -64,6 +64,7 @@ extern int pci_mcfg_min_bus, pci_mcfg_ma
 
 struct         pci_attach_args;
 
+extern uint64_t pcimem_range[2];
 extern struct extent *pciio_ex;
 extern struct extent *pcimem_ex;
 extern struct extent *pcibus_ex;
Index: sys/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 -b -r1.60 pci_machdep.c
--- sys/arch/amd64/pci/pci_machdep.c    16 Dec 2014 23:13:20 -0000      1.60
+++ sys/arch/amd64/pci/pci_machdep.c    18 Dec 2014 22:01:29 -0000
@@ -66,6 +66,7 @@
  */
 
 #include <sys/types.h>
+#include <sys/stdint.h>
 #include <sys/param.h>
 #include <sys/time.h>
 #include <sys/systm.h>
@@ -592,6 +593,7 @@ pci_intr_disestablish(pci_chipset_tag_t 
        intr_disestablish(cookie);
 }
 
+uint64_t pcimem_range[2] = {UINT64_MAX, 0};
 struct extent *pciio_ex;
 struct extent *pcimem_ex;
 struct extent *pcibus_ex;
@@ -618,31 +620,32 @@ pci_init_extents(void)
 
        if (pcimem_ex == NULL) {
                /*
-                * Cover the 36-bit address space addressable by PAE
-                * 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.
+                * Cover the address space extracted from
+                * ACPI. Fallback to fixed ranges in case ACPI is
+                * disabled or reporting an invalid address range.
                 */
+               if(pcimem_range[0] >= pcimem_range[1]) {
+                       pcimem_range[0] = 0;
+                       pcimem_range[1] = 0x40000000000UL;
+               }
+
                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, pcimem_range[1] + 1,
+                   (0xffffffffffffffffUL - pcimem_range[1]), EX_NOWAIT);
 
                for (bmp = bios_memmap; bmp->type != BIOS_MAP_END; bmp++) {
                        /*
-                        * Ignore address space beyond 4G.
+                        * Ignore address space beyond fixed/extracted
+                        * address range.
                         */
-                       if (bmp->addr >= 0x100000000ULL)
+                       if (bmp->addr > pcimem_range[1])
                                continue;
                        size = bmp->size;
-                       if (bmp->addr + size >= 0x100000000ULL)
-                               size = 0x100000000ULL - bmp->addr;
+                       if (bmp->addr + size > pcimem_range[1])
+                               size = pcimem_range[1] - bmp->addr + 1;
 
                        /* Ignore zero-sized regions. */
                        if (size == 0)
Index: sys/dev/acpi/acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.277
diff -u -p -b -r1.277 acpi.c
--- sys/dev/acpi/acpi.c 9 Dec 2014 06:58:29 -0000       1.277
+++ sys/dev/acpi/acpi.c 17 Dec 2014 05:59:36 -0000
@@ -385,0 +385,0 @@ TAILQ_HEAD(, acpi_pci) acpi_pcirootdevs

 int acpi_getpci(struct aml_node *node, void *arg);
 int acpi_getminbus(union acpi_resource *crs, void *arg);
+int acpi_getmemrange(union acpi_resource *crs, void *arg);
+
+int
+acpi_getmemrange(union acpi_resource *crs, void *arg)
+{
+       int typ = AML_CRSTYPE(crs);
+       uint64_t *range = arg;  /* size 2 */
+       uint64_t min, max;
+
+       switch(typ) {
+       case LR_24BIT:
+               min = crs->lr_m24._min;
+               max = crs->lr_m24._max;
+               break;
+       case LR_32BIT:
+       case LR_32BITFIXED:
+               min = crs->lr_m32._min;
+               max = crs->lr_m32._max;
+               break;
+       case LR_WORD:
+               min = crs->lr_word._min;
+               max = crs->lr_word._max;
+               break;
+       case LR_DWORD:
+               min = crs->lr_dword._min;
+               max = crs->lr_dword._max;
+               break;
+       case LR_QWORD:
+               min = crs->lr_qword._min;
+               max = crs->lr_qword._max;
+               break;
+       default:
+               return 0;
+       }
+
+       if(min >= max)
+               return 0;
+
+       if(min < range[0])
+               range[0] = min;
+
+       if(max > range[1])
+               range[1] = max;
+
+       return 0;
+}

 int
 acpi_getminbus(union acpi_resource *crs, void *arg)
@@ -457,8 +505,14 @@ acpi_getpci(struct aml_node *node, void
                        if (!aml_evalname(sc, node, "_CRS", 0, NULL, &res)) {
                                aml_parse_resource(&res, acpi_getminbus,
                                    &pci->bus);
-                               dnprintf(10, "%s post-crs: %d\n", 
aml_nodename(node),
+                               dnprintf(10, "%s post-crs bus: %d\n", 
aml_nodename(node),
                                    pci->bus);
+#if defined(__amd64__)
+                               aml_parse_resource(&res, acpi_getmemrange,
+                                   pcimem_range);
+                               dnprintf(10, "%s post-crs range: 
0x%llx/0x%llx\n",
aml_nodename(node),
+                                   pcimem_range[0], pcimem_range[1]);
+#endif
                        }
                        if (!aml_evalinteger(sc, node, "_BBN", 0, NULL, &val)) {
                                dnprintf(10, "%s post-bbn: %d, %lld\n", 
aml_nodename(node),


Cheers,
Frederic


> Frederic Nowak <f...@mailbox.org> hat am 17. Dezember 2014 um 08:22
> geschrieben:
> 
> 
> Hi!
> 
> The below diff extracts the memory range information from ACPI. It
> looks
> up all the memory ranges in _CRS and calculates minimal and maximal
> values for pci_machdep.c.
> 
> I tested this on two amd64 machines and see no difference in pcidump.
> 
> Do you think we need to keep the old method in case the ACPI on some
> machines does not report correct memory ranges? A simple check would
> be
> to test if pcimem_range[0] < pcimem_range[1]...
> 
> 
> Index: sys/arch/amd64/include/pci_machdep.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/include/pci_machdep.h,v
> retrieving revision 1.22
> diff -u -p -b -r1.22 pci_machdep.h
> --- sys/arch/amd64/include/pci_machdep.h      6 Nov 2013 10:40:36 -0000
> 1.22
> +++ sys/arch/amd64/include/pci_machdep.h      17 Dec 2014 06:00:01 -0000
> @@ -64,6 +64,7 @@ extern int pci_mcfg_min_bus, pci_mcfg_ma
>  
>  struct               pci_attach_args;
>  
> +extern uint64_t pcimem_range[2];
>  extern struct extent *pciio_ex;
>  extern struct extent *pcimem_ex;
>  extern struct extent *pcibus_ex;
> Index: sys/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 -b -r1.60 pci_machdep.c
> --- sys/arch/amd64/pci/pci_machdep.c  16 Dec 2014 23:13:20 -0000      1.60
> +++ sys/arch/amd64/pci/pci_machdep.c  17 Dec 2014 07:16:47 -0000
> @@ -66,6 +66,7 @@
>   */
>  
>  #include <sys/types.h>
> +#include <sys/stdint.h>
>  #include <sys/param.h>
>  #include <sys/time.h>
>  #include <sys/systm.h>
> @@ -592,6 +593,7 @@ pci_intr_disestablish(pci_chipset_tag_t 
>       intr_disestablish(cookie);
>  }
>  
> +uint64_t pcimem_range[2] = {UINT64_MAX, 0};
>  struct extent *pciio_ex;
>  struct extent *pcimem_ex;
>  struct extent *pcibus_ex;
> @@ -618,31 +620,25 @@ pci_init_extents(void)
>  
>       if (pcimem_ex == NULL) {
>               /*
> -              * Cover the 36-bit address space addressable by PAE
> -              * 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.
> +              * Cover the address space extracted from ACPI.
>                */
>               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, pcimem_range[1] + 1,
> +                 (0xffffffffffffffffUL - pcimem_range[1]), EX_NOWAIT);
>  
>               for (bmp = bios_memmap; bmp->type != BIOS_MAP_END; bmp++) {
>                       /*
> -                      * Ignore address space beyond 4G.
> +                      * Ignore address space beyond address range
> +                      * extracted from ACPI.
>                        */
> -                     if (bmp->addr >= 0x100000000ULL)
> +                     if (bmp->addr > pcimem_range[1])
>                               continue;
>                       size = bmp->size;
> -                     if (bmp->addr + size >= 0x100000000ULL)
> -                             size = 0x100000000ULL - bmp->addr;
> +                     if (bmp->addr + size > pcimem_range[1])
> +                             size = pcimem_range[1] - bmp->addr + 1;
>  
>                       /* Ignore zero-sized regions. */
>                       if (size == 0)
> Index: sys/dev/acpi/acpi.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
> retrieving revision 1.277
> diff -u -p -b -r1.277 acpi.c
> --- sys/dev/acpi/acpi.c       9 Dec 2014 06:58:29 -0000       1.277
> +++ sys/dev/acpi/acpi.c       17 Dec 2014 05:59:36 -0000
> @@ -385,0 +385,0 @@ TAILQ_HEAD(, acpi_pci) acpi_pcirootdevs
> 
>  int acpi_getpci(struct aml_node *node, void *arg);
>  int acpi_getminbus(union acpi_resource *crs, void *arg);
> +int acpi_getmemrange(union acpi_resource *crs, void *arg);
> +
> +int
> +acpi_getmemrange(union acpi_resource *crs, void *arg)
> +{
> +     int typ = AML_CRSTYPE(crs);
> +     uint64_t *range = arg;  /* size 2 */
> +     uint64_t min, max;
> +
> +     switch(typ) {
> +     case LR_24BIT:
> +             min = crs->lr_m24._min;
> +             max = crs->lr_m24._max;
> +             break;
> +     case LR_32BIT:
> +     case LR_32BITFIXED:
> +             min = crs->lr_m32._min;
> +             max = crs->lr_m32._max;
> +             break;
> +     case LR_WORD:
> +             min = crs->lr_word._min;
> +             max = crs->lr_word._max;
> +             break;
> +     case LR_DWORD:
> +             min = crs->lr_dword._min;
> +             max = crs->lr_dword._max;
> +             break;
> +     case LR_QWORD:
> +             min = crs->lr_qword._min;
> +             max = crs->lr_qword._max;
> +             break;
> +     default:
> +             return 0;
> +     }
> +
> +     if(min >= max)
> +             return 0;
> +
> +     if(min < range[0])
> +             range[0] = min;
> +
> +     if(max > range[1])
> +             range[1] = max;
> +
> +     return 0;
> +}
> 
>  int
>  acpi_getminbus(union acpi_resource *crs, void *arg)
> @@ -457,8 +505,14 @@ acpi_getpci(struct aml_node *node, void
>                       if (!aml_evalname(sc, node, "_CRS", 0, NULL, &res)) {
>                               aml_parse_resource(&res, acpi_getminbus,
>                                   &pci->bus);
> -                             dnprintf(10, "%s post-crs: %d\n", 
> aml_nodename(node),
> +                             dnprintf(10, "%s post-crs bus: %d\n", 
> aml_nodename(node),
>                                   pci->bus);
> +#if defined(__amd64__)
> +                             aml_parse_resource(&res, acpi_getmemrange,
> +                                 pcimem_range);
> +                             dnprintf(10, "%s post-crs range: 
> 0x%llx/0x%llx\n",
> aml_nodename(node),
> +                                 pcimem_range[0], pcimem_range[1]);
> +#endif
>                       }
>                       if (!aml_evalinteger(sc, node, "_BBN", 0, NULL, &val)) {
>                               dnprintf(10, "%s post-bbn: %d, %lld\n", 
> aml_nodename(node),
> 
> 
> Cheers,
> Frederic
> 
> > Jonathan Matthew <jonat...@d14n.org> hat am 16. Dezember 2014 um
> > 06:16
> > geschrieben:
> > 
> > 
> > On Sun, Dec 14, 2014 at 06:22:37PM +0100, Hrvoje Popovski wrote:
> > > Hi all,
> > > 
> > > I have got two new Dell R630 and have current on them from Sun Dec
> > > 14 15:07:17. Installation went great and very fast.
> > > The problem is that I see around 11k interrupts on acpi0. First I
> > > thought that problem is similar to this thread
> > > http://marc.info/?l=openbsd-misc&m=140551906923931&w=2
> > > 
> > > But if in dell bios system profile settings is set to performance
> > > or
> > > to DAPC there are always interrupts on acpi0.
> > > In links bellow you can find acpidump and dmesg from performance
> > > and
> > > DAPC settings in dell bios.
> > 
> > We just got some r630s too, so I spent some time last week figuring
> > out what's
> > going on here.  Something in the AML wants to talk to the intel MEI
> > device.
> > Normally this works, but on the new generation of dell machines
> > (we've
> > seen it
> > on r630s and r730s), it's been moved outside the pci memory range we
> > currently
> > allow on amd64.  You can see this in your dmesgs:
> > 
> > 0:22:0: mem address conflict 0x33ffff03000/0x10
> > 0:22:1: mem address conflict 0x33ffff02000/0x10
> > 
> > The interrupt will keep triggering until it manages to talk to the
> > device,
> > which will never happen.
> > 
> > kettenis@ says we can get the pci memory range information we need
> > to
> > deal with
> > this from acpi.  Until that happens, expanding the allowed pci
> > memory
> > range
> > makes things work properly.
> > 
> > ok?
> > 
> > 
> > Index: pci_machdep.c
> > ===================================================================
> > RCS file: /cvs/src/sys/arch/amd64/pci/pci_machdep.c,v
> > retrieving revision 1.59
> > diff -u -p -u -p -r1.59 pci_machdep.c
> > --- pci_machdep.c   19 Apr 2014 11:53:42 -0000      1.59
> > +++ pci_machdep.c   16 Dec 2014 04:21:53 -0000
> > @@ -622,13 +622,17 @@ 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, 0x1000000000UL,
> > -               0xfffffff000000000UL, EX_NOWAIT);
> > +           extent_alloc_region(pcimem_ex, 0x40000000000UL,
> > +               0xfffffc0000000000UL, EX_NOWAIT);
> >  
> >             for (bmp = bios_memmap; bmp->type != BIOS_MAP_END; bmp++) {
> >                     /*

Reply via email to