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 <[email protected]> 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 <[email protected]> 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++) {
> > /*
> >
>