summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2019-08-28 22:39:09 +0000
committerkettenis <kettenis@openbsd.org>2019-08-28 22:39:09 +0000
commit9a33df95e47f32536bea8cf06ab92d6e9378a78e (patch)
tree135b587a53c099799ad60e8c735faf992f25a6c9
parentFix white spaces and wrap long lines. (diff)
downloadwireguard-openbsd-9a33df95e47f32536bea8cf06ab92d6e9378a78e.tar.xz
wireguard-openbsd-9a33df95e47f32536bea8cf06ab92d6e9378a78e.zip
Use ACPI information to attach PCI busses like we do on arm64. There are a
few additional quirks though, and attaching the PCI busses is delayed to replicate the existing code more closely. That may be changed in the future. Also tweak how we handle MSI support and respect to ACPI flag that says we shouldn't attempt to use MSIs. Some fallout is expected. ok patrick@
-rw-r--r--sys/arch/amd64/amd64/mainbus.c6
-rw-r--r--sys/arch/amd64/conf/GENERIC3
-rw-r--r--sys/arch/amd64/conf/RAMDISK4
-rw-r--r--sys/arch/amd64/conf/RAMDISK_CD4
-rw-r--r--sys/arch/amd64/conf/files.amd644
-rw-r--r--sys/arch/amd64/pci/acpipci.c180
-rw-r--r--sys/arch/amd64/pci/pci_machdep.c21
-rw-r--r--sys/dev/acpi/acpi.c3
-rw-r--r--sys/dev/acpi/acpireg.h3
-rw-r--r--sys/dev/acpi/acpivar.h3
10 files changed, 196 insertions, 35 deletions
diff --git a/sys/arch/amd64/amd64/mainbus.c b/sys/arch/amd64/amd64/mainbus.c
index 6d2080ee2b1..af1ba119e3a 100644
--- a/sys/arch/amd64/amd64/mainbus.c
+++ b/sys/arch/amd64/amd64/mainbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mainbus.c,v 1.47 2019/05/17 19:07:15 guenther Exp $ */
+/* $OpenBSD: mainbus.c,v 1.48 2019/08/28 22:39:09 kettenis Exp $ */
/* $NetBSD: mainbus.c,v 1.1 2003/04/26 18:39:29 fvdl Exp $ */
/*
@@ -231,6 +231,9 @@ mainbus_attach(struct device *parent, struct device *self, void *aux)
#endif
#if NPCI > 0
+#if NACPI > 0
+ if (!acpi_haspci)
+#endif
{
pci_init_extents();
@@ -244,6 +247,7 @@ mainbus_attach(struct device *parent, struct device *self, void *aux)
mba.mba_pba.pba_busex = pcibus_ex;
mba.mba_pba.pba_domain = pci_ndomains++;
mba.mba_pba.pba_bus = 0;
+ mba.mba_pba.pba_flags = PCI_FLAGS_MSI_ENABLED;
config_found(self, &mba.mba_pba, mainbus_print);
#if NACPI > 0
acpi_pciroots_attach(self, &mba.mba_pba, mainbus_print);
diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC
index 563c9f855de..068a2bb2ec5 100644
--- a/sys/arch/amd64/conf/GENERIC
+++ b/sys/arch/amd64/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.476 2019/08/14 00:08:46 jsg Exp $
+# $OpenBSD: GENERIC,v 1.477 2019/08/28 22:39:09 kettenis Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -48,6 +48,7 @@ acpicmos* at acpi?
acpidock* at acpi?
acpiec* at acpi?
acpipci* at acpi?
+pci* at acpipci?
acpiprt* at acpi?
acpisbs* at acpi?
acpitz* at acpi?
diff --git a/sys/arch/amd64/conf/RAMDISK b/sys/arch/amd64/conf/RAMDISK
index bbc452fe4cc..5eec537843b 100644
--- a/sys/arch/amd64/conf/RAMDISK
+++ b/sys/arch/amd64/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.71 2018/03/27 21:11:16 kettenis Exp $
+# $OpenBSD: RAMDISK,v 1.72 2019/08/28 22:39:09 kettenis Exp $
machine amd64
maxusers 4
@@ -31,6 +31,8 @@ acpi0 at bios?
#acpicpu* at acpi?
acpicmos* at acpi?
acpiec* at acpi?
+acpipci* at acpi?
+pci* at acpipci?
acpiprt* at acpi?
acpimadt0 at acpi?
#acpitz* at acpi?
diff --git a/sys/arch/amd64/conf/RAMDISK_CD b/sys/arch/amd64/conf/RAMDISK_CD
index 96b15483567..2583a8f0e9f 100644
--- a/sys/arch/amd64/conf/RAMDISK_CD
+++ b/sys/arch/amd64/conf/RAMDISK_CD
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK_CD,v 1.181 2019/06/24 21:33:27 kettenis Exp $
+# $OpenBSD: RAMDISK_CD,v 1.182 2019/08/28 22:39:09 kettenis Exp $
machine amd64
maxusers 4
@@ -39,6 +39,8 @@ acpi0 at bios?
#acpicpu* at acpi?
acpicmos* at acpi?
acpiec* at acpi?
+acpipci* at acpi?
+pci* at acpipci?
acpiprt* at acpi?
acpimadt0 at acpi?
#acpitz* at acpi?
diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64
index 15e7d6bf137..b1c7f5d52b8 100644
--- a/sys/arch/amd64/conf/files.amd64
+++ b/sys/arch/amd64/conf/files.amd64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.amd64,v 1.102 2019/05/17 19:07:16 guenther Exp $
+# $OpenBSD: files.amd64,v 1.103 2019/08/28 22:39:09 kettenis Exp $
maxpartitions 16
maxusers 2 16 128
@@ -237,7 +237,7 @@ attach acpi at bios
file arch/amd64/amd64/acpi_machdep.c acpi
file arch/amd64/amd64/acpi_wakecode.S acpi & !small_kernel
-device acpipci
+device acpipci: pcibus
attach acpipci at acpi
file arch/amd64/pci/acpipci.c acpipci
diff --git a/sys/arch/amd64/pci/acpipci.c b/sys/arch/amd64/pci/acpipci.c
index 4bc996b2c13..0161b28df81 100644
--- a/sys/arch/amd64/pci/acpipci.c
+++ b/sys/arch/amd64/pci/acpipci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpipci.c,v 1.1 2018/10/26 20:26:19 kettenis Exp $ */
+/* $OpenBSD: acpipci.c,v 1.2 2019/08/28 22:39:09 kettenis Exp $ */
/*
* Copyright (c) 2018 Mark Kettenis
*
@@ -53,6 +53,19 @@ struct acpipci_softc {
struct device sc_dev;
struct acpi_softc *sc_acpi;
struct aml_node *sc_node;
+
+ bus_space_tag_t sc_iot;
+ bus_space_tag_t sc_memt;
+ bus_dma_tag_t sc_dmat;
+
+ struct extent *sc_busex;
+ struct extent *sc_memex;
+ struct extent *sc_ioex;
+ char sc_busex_name[32];
+ char sc_ioex_name[32];
+ char sc_memex_name[32];
+ int sc_bus;
+ uint32_t sc_seg;
};
int acpipci_match(struct device *, void *, void *);
@@ -72,6 +85,11 @@ const char *acpipci_hids[] = {
NULL
};
+void acpipci_attach_deferred(struct device *);
+int acpipci_print(void *, const char *);
+int acpipci_parse_resources(int, union acpi_resource *, void *);
+void acpipci_osc(struct acpipci_softc *);
+
int
acpipci_match(struct device *parent, void *match, void *aux)
{
@@ -86,15 +104,163 @@ acpipci_attach(struct device *parent, struct device *self, void *aux)
{
struct acpi_attach_args *aaa = aux;
struct acpipci_softc *sc = (struct acpipci_softc *)self;
- struct aml_value args[4];
struct aml_value res;
- static uint8_t uuid[16] = ACPI_PCI_UUID;
- uint32_t buf[3];
+ uint64_t bbn = 0;
+ uint64_t seg = 0;
sc->sc_acpi = (struct acpi_softc *)parent;
sc->sc_node = aaa->aaa_node;
printf(" %s", sc->sc_node->name);
+ if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) {
+ printf(": can't find resources\n");
+ return;
+ }
+
+ aml_evalinteger(sc->sc_acpi, sc->sc_node, "_BBN", 0, NULL, &bbn);
+ sc->sc_bus = bbn;
+
+ aml_evalinteger(sc->sc_acpi, sc->sc_node, "_SEG", 0, NULL, &seg);
+ sc->sc_seg = seg;
+
+ /* Create extents for our address spaces. */
+ snprintf(sc->sc_busex_name, sizeof(sc->sc_busex_name),
+ "%s pcibus", sc->sc_dev.dv_xname);
+ snprintf(sc->sc_ioex_name, sizeof(sc->sc_ioex_name),
+ "%s pciio", sc->sc_dev.dv_xname);
+ snprintf(sc->sc_memex_name, sizeof(sc->sc_memex_name),
+ "%s pcimem", sc->sc_dev.dv_xname);
+ sc->sc_busex = extent_create(sc->sc_busex_name, 0, 255,
+ M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
+ sc->sc_ioex = extent_create(sc->sc_ioex_name, 0, 0xffffffff,
+ M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
+ sc->sc_memex = extent_create(sc->sc_memex_name, 0, (u_long)-1,
+ M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
+
+ aml_parse_resource(&res, acpipci_parse_resources, sc);
+
+ acpipci_osc(sc);
+
+ printf("\n");
+
+ acpi_haspci = 1;
+
+ sc->sc_iot = aaa->aaa_iot;
+ sc->sc_memt = aaa->aaa_memt;
+ sc->sc_dmat = aaa->aaa_dmat;
+
+ config_defer(self, acpipci_attach_deferred);
+}
+
+void
+acpipci_attach_deferred(struct device *self)
+{
+ struct acpipci_softc *sc = (struct acpipci_softc *)self;
+ struct pcibus_attach_args pba;
+
+ memset(&pba, 0, sizeof(pba));
+ pba.pba_busname = "pci";
+ pba.pba_iot = sc->sc_iot;
+ pba.pba_memt = sc->sc_memt;
+ pba.pba_dmat = sc->sc_dmat;
+ pba.pba_busex = sc->sc_busex;
+ pba.pba_ioex = sc->sc_ioex;
+ pba.pba_memex = sc->sc_memex;
+ pba.pba_pmemex = sc->sc_memex;
+ pba.pba_domain = pci_ndomains++;
+ pba.pba_bus = sc->sc_bus;
+
+ /* Enable MSI in ACPI 2.0 and above, unless we're told not to. */
+ if (sc->sc_acpi->sc_fadt->hdr.revision >= 2 &&
+ (sc->sc_acpi->sc_fadt->iapc_boot_arch & FADT_NO_MSI) == 0)
+ pba.pba_flags |= PCI_FLAGS_MSI_ENABLED;
+
+ config_found(self, &pba, acpipci_print);
+}
+
+int
+acpipci_print(void *aux, const char *pnp)
+{
+ struct pcibus_attach_args *pba = aux;
+
+ if (pnp)
+ printf("%s at %s", pba->pba_busname, pnp);
+ printf(" bus %d", pba->pba_bus);
+ return (UNCONF);
+}
+
+int
+acpipci_parse_resources(int crsidx, union acpi_resource *crs, void *arg)
+{
+ struct acpipci_softc *sc = arg;
+ int type = AML_CRSTYPE(crs);
+ int restype, tflags = 0;
+ u_long min, len = 0, tra = 0;
+
+ switch (type) {
+ case LR_WORD:
+ restype = crs->lr_word.type;
+ tflags = crs->lr_word.tflags;
+ min = crs->lr_word._min;
+ len = crs->lr_word._len;
+ tra = crs->lr_word._tra;
+ break;
+ case LR_DWORD:
+ restype = crs->lr_dword.type;
+ tflags = crs->lr_dword.tflags;
+ min = crs->lr_dword._min;
+ len = crs->lr_dword._len;
+ tra = crs->lr_dword._tra;
+ break;
+ case LR_QWORD:
+ restype = crs->lr_qword.type;
+ tflags = crs->lr_qword.tflags;
+ min = crs->lr_qword._min;
+ len = crs->lr_qword._len;
+ tra = crs->lr_qword._tra;
+ break;
+ case LR_MEM32FIXED:
+ /*
+ * Coreboot on the PC Engines apu2 incorrectly uses a
+ * Memory32Fixed resource descriptor to describe mmio
+ * address space forwarded to the PCI bus.
+ */
+ restype = LR_TYPE_MEMORY;
+ min = crs->lr_m32fixed._bas;
+ len = crs->lr_m32fixed._len;
+ break;
+ }
+
+ if (len == 0)
+ return 0;
+
+ switch (restype) {
+ case LR_TYPE_MEMORY:
+ if (tflags & LR_MEMORY_TTP)
+ return 0;
+ extent_free(sc->sc_memex, min, len, EX_WAITOK | EX_CONFLICTOK);
+ break;
+ case LR_TYPE_IO:
+ if (tflags & LR_IO_TTP)
+ return 0;
+ extent_free(sc->sc_ioex, min, len, EX_WAITOK | EX_CONFLICTOK);
+ break;
+ case LR_TYPE_BUS:
+ extent_free(sc->sc_busex, min, len, EX_WAITOK);
+ break;
+ }
+
+ return 0;
+}
+
+void
+acpipci_osc(struct acpipci_softc *sc)
+{
+ struct aml_value args[4];
+ struct aml_value res;
+ static uint8_t uuid[16] = ACPI_PCI_UUID;
+ uint32_t buf[3];
+
memset(args, 0, sizeof(args));
args[0].type = AML_OBJTYPE_BUFFER;
args[0].v_buffer = uuid;
@@ -112,10 +278,8 @@ acpipci_attach(struct device *parent, struct device *self, void *aux)
buf[1] = ACPI_PCI_PCIE_CONFIG | ACPI_PCI_MSI;
buf[2] = ACPI_PCI_PCIE_HOTPLUG;
- if (aml_evalname(sc->sc_acpi, sc->sc_node, "_OSC", 4, args, &res)) {
- printf(": _OSC failed\n");
+ if (aml_evalname(sc->sc_acpi, sc->sc_node, "_OSC", 4, args, &res))
return;
- }
if (res.type == AML_OBJTYPE_BUFFER) {
size_t len = res.length;
@@ -128,6 +292,4 @@ acpipci_attach(struct device *parent, struct device *self, void *aux)
len -= 4;
}
}
-
- printf("\n");
}
diff --git a/sys/arch/amd64/pci/pci_machdep.c b/sys/arch/amd64/pci/pci_machdep.c
index 27e78c7cfa4..d207ab54c65 100644
--- a/sys/arch/amd64/pci/pci_machdep.c
+++ b/sys/arch/amd64/pci/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_machdep.c,v 1.71 2019/06/25 16:46:32 kettenis Exp $ */
+/* $OpenBSD: pci_machdep.c,v 1.72 2019/08/28 22:39:09 kettenis Exp $ */
/* $NetBSD: pci_machdep.c,v 1.3 2003/05/07 21:33:58 fvdl Exp $ */
/*-
@@ -189,24 +189,11 @@ pci_attach_hook(struct device *parent, struct device *self,
switch (PCI_VENDOR(id)) {
case PCI_VENDOR_INTEL:
- /*
- * In the wonderful world of virtualization you can
- * have the latest 64-bit AMD multicore CPU behind a
- * prehistoric Intel host bridge. Give them what they
- * deserve.
- */
- switch (PCI_PRODUCT(id)) {
- case PCI_PRODUCT_INTEL_82441FX: /* QEMU */
- case PCI_PRODUCT_INTEL_82443BX: /* VMWare */
- break;
- default:
- pba->pba_flags |= PCI_FLAGS_MSI_ENABLED;
- break;
- }
- break;
case PCI_VENDOR_NVIDIA:
case PCI_VENDOR_AMD:
- pba->pba_flags |= PCI_FLAGS_MSI_ENABLED;
+ break;
+ default:
+ pba->pba_flags &= ~PCI_FLAGS_MSI_ENABLED;
break;
}
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index 620c5fab27e..fcded825bb5 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.372 2019/08/27 22:39:53 deraadt Exp $ */
+/* $OpenBSD: acpi.c,v 1.373 2019/08/28 22:39:09 kettenis Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -71,6 +71,7 @@ int acpi_debug = 16;
int acpi_poll_enabled;
int acpi_hasprocfvs;
+int acpi_haspci;
#define ACPIEN_RETRIES 15
diff --git a/sys/dev/acpi/acpireg.h b/sys/dev/acpi/acpireg.h
index 4e92d113e73..bfbb73ce212 100644
--- a/sys/dev/acpi/acpireg.h
+++ b/sys/dev/acpi/acpireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpireg.h,v 1.44 2019/06/10 14:38:06 kettenis Exp $ */
+/* $OpenBSD: acpireg.h,v 1.45 2019/08/28 22:39:09 kettenis Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
@@ -150,6 +150,7 @@ struct acpi_fadt {
#define FADT_LEGACY_DEVICES 0x0001 /* Legacy devices supported */
#define FADT_i8042 0x0002 /* Keyboard controller present */
#define FADT_NO_VGA 0x0004 /* Do not probe VGA */
+#define FADT_NO_MSI 0x0008 /* Do not enable MSI */
uint8_t reserved1;
uint32_t flags;
#define FADT_WBINVD 0x00000001
diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h
index 0fe5aeb9659..860362acc39 100644
--- a/sys/dev/acpi/acpivar.h
+++ b/sys/dev/acpi/acpivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpivar.h,v 1.103 2019/08/27 22:39:53 deraadt Exp $ */
+/* $OpenBSD: acpivar.h,v 1.104 2019/08/28 22:39:09 kettenis Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
@@ -43,6 +43,7 @@ extern int acpi_debug;
#endif
extern int acpi_hasprocfvs;
+extern int acpi_haspci;
struct klist;
struct acpiec_softc;