summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2020-06-10 16:31:27 +0000
committerkettenis <kettenis@openbsd.org>2020-06-10 16:31:27 +0000
commit1f76319b3a51492f9c330ef3b49dba56499b046d (patch)
tree3cbdfc809d4c4180c75058e9dba231db218cbd85
parentAdd MSI support calls. (diff)
downloadwireguard-openbsd-1f76319b3a51492f9c330ef3b49dba56499b046d.tar.xz
wireguard-openbsd-1f76319b3a51492f9c330ef3b49dba56499b046d.zip
A bit of MSI support code; we need to distinguish between 32-bit and 64-bit
MSIs on powerpc64.
-rw-r--r--sys/arch/powerpc64/dev/pci_machdep.c11
-rw-r--r--sys/arch/powerpc64/dev/phb.c42
-rw-r--r--sys/arch/powerpc64/include/pci_machdep.h7
3 files changed, 47 insertions, 13 deletions
diff --git a/sys/arch/powerpc64/dev/pci_machdep.c b/sys/arch/powerpc64/dev/pci_machdep.c
index f1d3c4b1286..f28fab763e1 100644
--- a/sys/arch/powerpc64/dev/pci_machdep.c
+++ b/sys/arch/powerpc64/dev/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_machdep.c,v 1.1 2020/06/07 16:14:47 kettenis Exp $ */
+/* $OpenBSD: pci_machdep.c,v 1.2 2020/06/10 16:31:27 kettenis Exp $ */
/*
* Copyright (c) 2019 Mark Kettenis <kettenis@openbsd.org>
@@ -45,8 +45,6 @@ pci_msi_enable(pci_chipset_tag_t pc, pcitag_t tag,
pci_conf_write(pc, tag, off, reg | PCI_MSI_MC_MSIE);
}
-#ifdef notyet
-
int
pci_msix_table_map(pci_chipset_tag_t pc, pcitag_t tag,
bus_space_tag_t memt, bus_space_handle_t *memh)
@@ -118,21 +116,20 @@ pci_msix_enable(pci_chipset_tag_t pc, pcitag_t tag, bus_space_tag_t memt,
pci_conf_write(pc, tag, off, reg | PCI_MSIX_MC_MSIXE);
}
-#endif
-
int
_pci_intr_map_msi(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
{
pci_chipset_tag_t pc = pa->pa_pc;
pcitag_t tag = pa->pa_tag;
+ pcireg_t reg;
if ((pa->pa_flags & PCI_FLAGS_MSI_ENABLED) == 0 ||
- pci_get_capability(pc, tag, PCI_CAP_MSI, NULL, NULL) == 0)
+ pci_get_capability(pc, tag, PCI_CAP_MSI, NULL, &reg) == 0)
return -1;
ihp->ih_pc = pa->pa_pc;
ihp->ih_tag = pa->pa_tag;
- ihp->ih_type = PCI_MSI;
+ ihp->ih_type = (reg & PCI_MSI_MC_C64) ? PCI_MSI64 : PCI_MSI32;
return 0;
}
diff --git a/sys/arch/powerpc64/dev/phb.c b/sys/arch/powerpc64/dev/phb.c
index e9f91920972..da7353d3545 100644
--- a/sys/arch/powerpc64/dev/phb.c
+++ b/sys/arch/powerpc64/dev/phb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: phb.c,v 1.3 2020/06/08 19:06:47 kettenis Exp $ */
+/* $OpenBSD: phb.c,v 1.4 2020/06/10 16:31:27 kettenis Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
*
@@ -420,7 +420,8 @@ const char *
phb_intr_string(void *v, pci_intr_handle_t ih)
{
switch (ih.ih_type) {
- case PCI_MSI:
+ case PCI_MSI32:
+ case PCI_MSI64:
return "msi";
case PCI_MSIX:
return "msix";
@@ -433,7 +434,42 @@ void *
phb_intr_establish(void *v, pci_intr_handle_t ih, int level,
int (*func)(void *), void *arg, char *name)
{
- return NULL;
+ struct phb_softc *sc = v;
+ void *cookie;
+
+ KASSERT(ih.ih_type != PCI_NONE);
+
+ if (ih.ih_type != PCI_INTX) {
+ uint32_t addr32, data;
+ uint64_t addr;
+ uint32_t xive;
+ int64_t error;
+
+ /* XXX Allocate a real interrupt vector. */
+ xive = 0;
+
+ if (ih.ih_type == PCI_MSI32) {
+ error = opal_get_msi_32(sc->sc_phb_id, 0, xive,
+ 1, &addr32, &data);
+ addr = addr32;
+ } else {
+ error = opal_get_msi_64(sc->sc_phb_id, 0, xive,
+ 1, &addr, &data);
+ }
+ if (error != OPAL_SUCCESS)
+ return NULL;
+
+ /* XXX Allocate a real cookie. */
+ cookie = sc;
+
+ if (ih.ih_type == PCI_MSIX) {
+ pci_msix_enable(ih.ih_pc, ih.ih_tag,
+ sc->sc_iot, ih.ih_intrpin, addr, data);
+ } else
+ pci_msi_enable(ih.ih_pc, ih.ih_tag, addr, data);
+ }
+
+ return cookie;
}
void
diff --git a/sys/arch/powerpc64/include/pci_machdep.h b/sys/arch/powerpc64/include/pci_machdep.h
index f97e3ae5ef9..3e551ae589a 100644
--- a/sys/arch/powerpc64/include/pci_machdep.h
+++ b/sys/arch/powerpc64/include/pci_machdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_machdep.h,v 1.1 2020/06/07 16:14:47 kettenis Exp $ */
+/* $OpenBSD: pci_machdep.h,v 1.2 2020/06/10 16:31:27 kettenis Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -32,8 +32,9 @@ typedef uint64_t pcitag_t;
/* Supported interrupt types. */
#define PCI_NONE 0
#define PCI_INTX 1
-#define PCI_MSI 2
-#define PCI_MSIX 3
+#define PCI_MSI32 2
+#define PCI_MSI64 3
+#define PCI_MSIX 4
typedef struct {
pci_chipset_tag_t ih_pc;