> Date: Wed, 30 Dec 2015 14:21:11 +0100 (CET)
> From: Mark Kettenis <[email protected]>
>
> It seems more and more server machines ship in a "64-bit"
> configuration where the BIOS assigns addresses above the 4GB mark to
> 64-bit BARs. We have a hack in arch/amd64/pci_machdep.c:pci_init_extents()
> to deal with some of these configurations:
>
> /*
> * ...
> *
> * 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.
> */
>
> I ran into a SuperMicro machine that puts stuff even higher. And
> ratherthan extending the range again, I think it is time to bite the
> bullet and trust ACPI.
>
> The diff below is a first stab. Needs a bit more polish, but before I
> spend more time on it, I'd like to get some test results. I'd like to
> see the diff tested on a wide variety of machines. Please send me old
> and new dmesg and acpidump output.
>
> Warning! A kernel with this diff might panic early on in the boot
> process, so don't play with it unless you have a way to boot your
> previous kernel.
Updated diff. Once again the ACPI standard is ambiguous and/or
violated by the hardware vendors. This should fix at least the ports
Dell r620 that naddy@ told me about.
Index: acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.297
diff -u -p -r1.297 acpi.c
--- acpi.c 23 Nov 2015 00:10:53 -0000 1.297
+++ acpi.c 30 Dec 2015 22:08:53 -0000
@@ -561,6 +561,46 @@ acpi_matchhids(struct acpi_attach_args *
return (0);
}
+int
+acpi_fill_memex(union acpi_resource *crs, void *arg)
+{
+ int type = AML_CRSTYPE(crs);
+ struct extent *ex = arg;
+ uint64_t min, max, len;
+ uint16_t flags;
+
+ switch (type) {
+ case LR_DWORD:
+ type = crs->lr_dword.type;
+ flags = crs->lr_dword.flags;
+ len = crs->lr_dword._len;
+ min = crs->lr_dword._min;
+ max = crs->lr_dword._max;
+ break;
+ case LR_QWORD:
+ type = crs->lr_qword.type;
+ flags = crs->lr_qword.flags;
+ len = crs->lr_qword._len;
+ min = crs->lr_qword._min;
+ max = crs->lr_qword._max;
+ break;
+ default:
+ return 0;
+ }
+
+ if (type != 0)
+ return 0;
+ if (len == 0)
+ return 0;
+ if (min >= max)
+ return 0;
+ if (len != max - min + 1)
+ return 0;
+
+ extent_free(ex, min, len, EX_NOWAIT);
+ return 0;
+}
+
/* Map ACPI device node to PCI */
int
acpi_getpci(struct aml_node *node, void *arg)
@@ -573,10 +613,17 @@ acpi_getpci(struct aml_node *node, void
pcitag_t tag;
uint64_t val;
uint32_t reg;
+ int64_t sta = 0;
if (!node->value || node->value->type != AML_OBJTYPE_DEVICE)
return 0;
- if (!aml_evalhid(node, &res)) {
+
+ /* Evaluate _STA to decide PCI Root node fate and walk fate */
+ if (aml_evalinteger(sc, node, "_STA", 0, NULL, &sta))
+ sta = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000;
+
+ if ((sta & (STA_PRESENT|STA_ENABLED)) == (STA_PRESENT|STA_ENABLED) &&
+ !aml_evalhid(node, &res)) {
/* Check if this is a PCI Root node */
if (_acpi_matchhids(res.v_string, pcihid)) {
aml_freevalue(&res);
@@ -603,6 +650,18 @@ acpi_getpci(struct aml_node *node, void
dnprintf(10, "found PCI root: %s %d\n",
aml_nodename(node), pci->bus);
TAILQ_INSERT_TAIL(&acpi_pcirootdevs, pci, next);
+
+ pci->memex = extent_create("pcimem", 0, -1, M_DEVBUF,
NULL, 0, EX_NOWAIT | EX_FILLED);
+ KASSERT(pci->memex != NULL);
+
+ if (aml_evalname(sc, node, "_CRS", 0, NULL, &res) == 0)
{
+ aml_parse_resource(&res, acpi_fill_memex,
pci->memex);
+ aml_freevalue(&res);
+ printf("bus %d\n", pci->bus);
+ extent_print(pci->memex);
+ if (pci->bus == 0)
+ pcimem_ex = pci->memex;
+ }
}
aml_freevalue(&res);
return 0;
@@ -833,6 +892,7 @@ acpi_pciroots_attach(struct device *dev,
1, EX_NOWAIT) != 0)
continue;
pba->pba_bus = pdev->bus;
+ pba->pba_memex = pdev->memex;
config_found(dev, pba, pr);
}
}
Index: amltypes.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/amltypes.h,v
retrieving revision 1.40
diff -u -p -r1.40 amltypes.h
--- amltypes.h 7 Sep 2012 19:19:59 -0000 1.40
+++ amltypes.h 30 Dec 2015 22:08:53 -0000
@@ -362,6 +362,8 @@ struct acpi_pci {
int _s3w;
int _s4d;
int _s4w;
+
+ struct extent *memex;
};
struct aml_node {