summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2024-10-24 18:53:00 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2024-10-24 18:53:00 +0000
commit74efed2a7ff980788efff6b3b5993762e7a78215 (patch)
tree122826ea8c34527a24858772effc3bbcdd14dd91 /sys/dev/pci
parent9cd2590ca23be81c1d41f53830d293a19657ac78 (diff)
Attach psp(4) version 1.
Some AMD CPUs come with an older platform security processor. It is detectet by PCI Id and has different register offsets. Move the dynamic register offsets into psp_softc. The PCI attach code is now in a separate psp_pci.c file and detects the version of the psp along with the ccp. The attach code is more verbose to display where problems might occur. Now the ccp_wait() has 2 seconds timeout, both for polling and interrupt. Also prevent a useless bus_space_read_4(). OK hshoexer@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/ccp_pci.c65
-rw-r--r--sys/dev/pci/files.pci3
-rw-r--r--sys/dev/pci/psp_pci.c126
3 files changed, 139 insertions, 55 deletions
diff --git a/sys/dev/pci/ccp_pci.c b/sys/dev/pci/ccp_pci.c
index 8e1168689f4..49991d12563 100644
--- a/sys/dev/pci/ccp_pci.c
+++ b/sys/dev/pci/ccp_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ccp_pci.c,v 1.13 2024/09/04 07:45:08 jsg Exp $ */
+/* $OpenBSD: ccp_pci.c,v 1.14 2024/10/24 18:52:59 bluhm Exp $ */
/*
* Copyright (c) 2018 David Gwynne <dlg@openbsd.org>
@@ -36,9 +36,6 @@
int ccp_pci_match(struct device *, void *, void *);
void ccp_pci_attach(struct device *, struct device *, void *);
-void ccp_pci_intr_map(struct ccp_softc *, struct pci_attach_args *);
-void ccp_pci_psp_attach(struct ccp_softc *, struct pci_attach_args *);
-
const struct cfattach ccp_pci_ca = {
sizeof(struct ccp_softc),
ccp_pci_match,
@@ -67,6 +64,9 @@ ccp_pci_attach(struct device *parent, struct device *self, void *aux)
struct ccp_softc *sc = (struct ccp_softc *)self;
struct pci_attach_args *pa = aux;
pcireg_t memtype;
+#if NPSP > 0
+ int psp_matched;
+#endif
memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, CCP_PCI_BAR);
if (PCI_MAPREG_TYPE(memtype) != PCI_MAPREG_TYPE_MEM) {
@@ -80,59 +80,16 @@ ccp_pci_attach(struct device *parent, struct device *self, void *aux)
return;
}
- ccp_pci_intr_map(sc, pa);
-
- ccp_attach(sc);
-
- ccp_pci_psp_attach(sc, pa);
-}
-
-void
-ccp_pci_intr_map(struct ccp_softc *sc, struct pci_attach_args *pa)
-{
#if NPSP > 0
- pci_intr_handle_t ih;
- const char *intrstr = NULL;
-
- /* clear and disable interrupts */
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, PSP_REG_INTEN, 0);
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, PSP_REG_INTSTS, -1);
-
- if (pci_intr_map_msix(pa, 0, &ih) != 0 &&
- pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) {
- printf(": couldn't map interrupt\n");
- return;
- }
-
- intrstr = pci_intr_string(pa->pa_pc, ih);
- sc->sc_irqh = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, psp_sev_intr,
- sc, sc->sc_dev.dv_xname);
- if (sc->sc_irqh != NULL)
- printf(": %s", intrstr);
+ psp_matched = psp_pci_match(sc, aux);
+ if (psp_matched)
+ psp_pci_intr_map(sc, pa);
#endif
-}
-void
-ccp_pci_psp_attach(struct ccp_softc *sc, struct pci_attach_args *pa)
-{
-#if NPSP > 0
- struct psp_attach_args arg;
- struct device *self = (struct device *)sc;
-
- memset(&arg, 0, sizeof(arg));
- arg.iot = sc->sc_iot;
- arg.ioh = sc->sc_ioh;
- arg.dmat = pa->pa_dmat;
- arg.capabilities = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
- PSP_REG_CAPABILITIES);
-
- sc->sc_psp = config_found_sm(self, &arg, pspprint, pspsubmatch);
- if (sc->sc_psp == NULL) {
- pci_intr_disestablish(pa->pa_pc, sc->sc_irqh);
- return;
- }
+ ccp_attach(sc);
- /* enable interrupts */
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, PSP_REG_INTEN, -1);
+#if NPSP > 0
+ if (psp_matched)
+ psp_pci_attach(sc, pa);
#endif
}
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci
index 76cecece306..42c5d61f7f5 100644
--- a/sys/dev/pci/files.pci
+++ b/sys/dev/pci/files.pci
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pci,v 1.366 2024/08/14 14:40:46 patrick Exp $
+# $OpenBSD: files.pci,v 1.367 2024/10/24 18:52:59 bluhm Exp $
# $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $
#
# Config file and device description for machine-independent PCI code.
@@ -830,6 +830,7 @@ file dev/pci/if_bwfm_pci.c bwfm_pci
# AMD Cryptographic Co-processor
attach ccp at pci with ccp_pci
file dev/pci/ccp_pci.c ccp_pci
+file dev/pci/psp_pci.c psp
# Broadcom NetXtreme-C/E
device bnxt: ether, ifnet, ifmedia, intrmap, stoeplitz
diff --git a/sys/dev/pci/psp_pci.c b/sys/dev/pci/psp_pci.c
new file mode 100644
index 00000000000..e1356ceeb8a
--- /dev/null
+++ b/sys/dev/pci/psp_pci.c
@@ -0,0 +1,126 @@
+/* $OpenBSD: psp_pci.c,v 1.1 2024/10/24 18:52:59 bluhm Exp $ */
+
+/*
+ * Copyright (c) 2023-2024 Hans-Joerg Hoexer <hshoexer@genua.de>
+ * Copyright (c) 2024 Alexander Bluhm <bluhm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pcivar.h>
+
+#include <dev/ic/ccpvar.h>
+#include <dev/ic/pspvar.h>
+
+static const struct pci_matchid psp_pci_devices[] = {
+ { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_17_CCP_1 },
+ { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_17_3X_CCP },
+ { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_19_1X_PSP },
+};
+
+int
+psp_pci_match(struct ccp_softc *sc, struct pci_attach_args *pa)
+{
+ bus_size_t reg_capabilities;
+ uint32_t capabilities;
+
+ if (!pci_matchbyid(pa, psp_pci_devices, nitems(psp_pci_devices)))
+ return (0);
+
+ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_17_CCP_1)
+ reg_capabilities = PSPV1_REG_CAPABILITIES;
+ else
+ reg_capabilities = PSP_REG_CAPABILITIES;
+ capabilities = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+ reg_capabilities);
+ if (!ISSET(capabilities, PSP_CAP_SEV))
+ return (0);
+
+ return (1);
+}
+
+void
+psp_pci_intr_map(struct ccp_softc *sc, struct pci_attach_args *pa)
+{
+ pci_intr_handle_t ih;
+ const char *intrstr = NULL;
+ bus_size_t reg_inten, reg_intsts;
+
+ /* clear and disable interrupts */
+ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_17_CCP_1) {
+ reg_inten = PSPV1_REG_INTEN;
+ reg_intsts = PSPV1_REG_INTSTS;
+ } else {
+ reg_inten = PSP_REG_INTEN;
+ reg_intsts = PSP_REG_INTSTS;
+ }
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg_inten, 0);
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg_intsts, -1);
+
+ if (pci_intr_map_msix(pa, 0, &ih) != 0 &&
+ pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) {
+ printf(": couldn't map interrupt\n");
+ return;
+ }
+
+ intrstr = pci_intr_string(pa->pa_pc, ih);
+ sc->sc_irqh = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, psp_sev_intr,
+ sc, sc->sc_dev.dv_xname);
+ if (sc->sc_irqh != NULL)
+ printf(": %s", intrstr);
+}
+
+void
+psp_pci_attach(struct ccp_softc *sc, struct pci_attach_args *pa)
+{
+ struct psp_attach_args arg;
+ struct device *self = (struct device *)sc;
+ bus_size_t reg_capabilities;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.iot = sc->sc_iot;
+ arg.ioh = sc->sc_ioh;
+ arg.dmat = pa->pa_dmat;
+ switch (PCI_PRODUCT(pa->pa_id)) {
+ case PCI_PRODUCT_AMD_17_CCP_1:
+ arg.version = 1;
+ reg_capabilities = PSPV1_REG_CAPABILITIES;
+ break;
+ case PCI_PRODUCT_AMD_17_3X_CCP:
+ arg.version = 2;
+ reg_capabilities = PSP_REG_CAPABILITIES;
+ break;
+ case PCI_PRODUCT_AMD_19_1X_PSP:
+ arg.version = 4;
+ reg_capabilities = PSP_REG_CAPABILITIES;
+ break;
+ default:
+ reg_capabilities = PSP_REG_CAPABILITIES;
+ break;
+ }
+ arg.capabilities = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+ reg_capabilities);
+
+ sc->sc_psp = config_found_sm(self, &arg, pspprint, pspsubmatch);
+ if (sc->sc_psp == NULL) {
+ pci_intr_disestablish(pa->pa_pc, sc->sc_irqh);
+ return;
+ }
+}