Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
Re: AMD SEV psp version 1 attach
To:
Mark Kettenis <mark.kettenis@xs4all.nl>
Cc:
tech@openbsd.org, hshoexer@genua.de
Date:
Tue, 22 Oct 2024 13:24:49 +0200

Download raw body.

Thread
On Mon, Oct 21, 2024 at 02:22:14PM +0200, Alexander Bluhm wrote:
> As hshoexer@ has tested it I added version 4 PCI Id.

One PCI_PRODUCT_AMD_19_1X_PSP was missing.  New diff.

ok?

bluhm

Index: dev/ic/psp.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/dev/ic/psp.c,v
diff -u -p -r1.5 psp.c
--- dev/ic/psp.c	4 Oct 2024 16:58:26 -0000	1.5
+++ dev/ic/psp.c	22 Oct 2024 09:49:22 -0000
@@ -37,7 +37,12 @@ struct psp_softc {
 	bus_space_handle_t	sc_ioh;
 
 	bus_dma_tag_t		sc_dmat;
-	uint32_t		sc_capabilities;
+
+	bus_size_t		sc_reg_inten;
+	bus_size_t		sc_reg_intsts;
+	bus_size_t		sc_reg_cmdresp;
+	bus_size_t		sc_reg_addrlo;
+	bus_size_t		sc_reg_addrhi;
 
 	bus_dmamap_t		sc_cmd_map;
 	bus_dma_segment_t	sc_cmd_seg;
@@ -74,8 +79,8 @@ psp_sev_intr(void *arg)
 	struct psp_softc *sc = (struct psp_softc *)csc->sc_psp;
 	uint32_t status;
 
-	status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, PSP_REG_INTSTS);
-	bus_space_write_4(sc->sc_iot, sc->sc_ioh, PSP_REG_INTSTS, status);
+	status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_intsts);
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_intsts, status);
 
 	if (!(status & PSP_CMDRESP_COMPLETE))
 		return (0);
@@ -101,10 +106,25 @@ psp_attach(struct device *parent, struct
 	size_t				size;
 	int				nsegs;
 
+	printf(":");
 	sc->sc_iot = arg->iot;
 	sc->sc_ioh = arg->ioh;
 	sc->sc_dmat = arg->dmat;
-	sc->sc_capabilities = arg->capabilities;
+	if (arg->version == 1) {
+		sc->sc_reg_inten = PSPV1_REG_INTEN;
+		sc->sc_reg_intsts = PSPV1_REG_INTSTS;
+		sc->sc_reg_cmdresp = PSPV1_REG_CMDRESP;
+		sc->sc_reg_addrlo = PSPV1_REG_ADDRLO;
+		sc->sc_reg_addrhi = PSPV1_REG_ADDRHI;
+	} else {
+		sc->sc_reg_inten = PSP_REG_INTEN;
+		sc->sc_reg_intsts = PSP_REG_INTSTS;
+		sc->sc_reg_cmdresp = PSP_REG_CMDRESP;
+		sc->sc_reg_addrlo = PSP_REG_ADDRLO;
+		sc->sc_reg_addrhi = PSP_REG_ADDRHI;
+	}
+	if (arg->version)
+		printf(" vers %d,", arg->version);
 
 	rw_init(&sc->sc_lock, "psp_lock");
 
@@ -127,8 +147,16 @@ psp_attach(struct device *parent, struct
 	    size, NULL, BUS_DMA_WAITOK) != 0)
 		goto fail_2;
 
-	if (psp_get_pstatus(sc, &pst) || pst.state != 0)
+	if (psp_get_pstatus(sc, &pst)) {
+		printf(" platform status");
 		goto fail_3;
+	}
+	if (pst.state != PSP_PSTATE_UNINIT) {
+		printf(" uninitialized state");
+		goto fail_3;
+	}
+	printf(" api %u.%u, build %u,",
+	    pst.api_major, pst.api_minor, pst.cfges_build >> 24);
 
 	/*
          * create and map Trusted Memory Region (TMR); size 1 Mbyte,
@@ -156,15 +184,20 @@ psp_attach(struct device *parent, struct
 	init.enable_es = 1;
 	init.tmr_length = PSP_TMR_SIZE;
 	init.tmr_paddr = sc->sc_tmr_map->dm_segs[0].ds_addr;
-	if (psp_init(sc, &init))
+	if (psp_init(sc, &init)) {
+		printf(" init");
 		goto fail_7;
+	}
 
-	printf(": SEV");
+	printf(" SEV");
 
 	psp_get_pstatus(sc, &pst);
-	if ((pst.state == 1) && (pst.cfges_build & 0x1))
+	if ((pst.state == PSP_PSTATE_INIT) && (pst.cfges_build & 0x1))
 		printf(", SEV-ES");
 
+        /* enable interrupts */
+        bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_inten, -1);
+
 	printf("\n");
 
 	return;
@@ -186,7 +219,7 @@ fail_1:
 fail_0:
 	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmd_map);
 
-	printf("\n");
+	printf(" failed\n");
 
 	return;
 }
@@ -199,9 +232,9 @@ ccp_wait(struct psp_softc *sc, uint32_t 
 
 	if (poll) {
 		count = 0;
-		while (count++ < 100) {
+		while (count++ < 400) {
 			cmdword = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
-			    PSP_REG_CMDRESP);
+			    sc->sc_reg_cmdresp);
 			if (cmdword & PSP_CMDRESP_RESPONSE)
 				goto done;
 			delay(5000);
@@ -214,12 +247,10 @@ ccp_wait(struct psp_softc *sc, uint32_t 
 	if (tsleep_nsec(sc, PWAIT, "psp", SEC_TO_NSEC(2)) == EWOULDBLOCK)
 		return (1);
 
+	cmdword = bus_space_read_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_cmdresp);
 done:
-	if (status) {
-		*status = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
-		    PSP_REG_CMDRESP);
-	}
-
+	if (status != NULL)
+		*status = cmdword;
 	return (0);
 }
 
@@ -234,9 +265,9 @@ ccp_docmd(struct psp_softc *sc, int cmd,
 	if (!cold)
 		cmdword |= PSP_CMDRESP_IOC;
 
-	bus_space_write_4(sc->sc_iot, sc->sc_ioh, PSP_REG_ADDRLO, plo);
-	bus_space_write_4(sc->sc_iot, sc->sc_ioh, PSP_REG_ADDRHI, phi);
-	bus_space_write_4(sc->sc_iot, sc->sc_ioh, PSP_REG_CMDRESP, cmdword);
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_addrlo, plo);
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_addrhi, phi);
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_cmdresp, cmdword);
 
 	if (ccp_wait(sc, &status, cold))
 		return (1);
Index: dev/ic/pspvar.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/dev/ic/pspvar.h,v
diff -u -p -r1.2 pspvar.h
--- dev/ic/pspvar.h	4 Sep 2024 07:45:08 -0000	1.2
+++ dev/ic/pspvar.h	22 Oct 2024 09:49:22 -0000
@@ -19,6 +19,13 @@
 #include <sys/ioctl.h>
 
 /* AMD 17h */
+#define PSPV1_REG_INTEN		0x10610
+#define PSPV1_REG_INTSTS	0x10614
+#define PSPV1_REG_CMDRESP	0x10580
+#define PSPV1_REG_ADDRLO	0x105e0
+#define PSPV1_REG_ADDRHI	0x105e4
+#define PSPV1_REG_CAPABILITIES	0x105fc
+
 #define PSP_REG_INTEN		0x10690
 #define PSP_REG_INTSTS		0x10694
 #define PSP_REG_CMDRESP		0x10980
@@ -252,10 +259,18 @@ struct psp_attach_args {
 
 	bus_dma_tag_t		dmat;
 	uint32_t		capabilities;
+	int			version;
 };
 
 int pspsubmatch(struct device *, void *, void *);
 int pspprint(void *aux, const char *pnp);
 int psp_sev_intr(void *);
+
+struct ccp_softc;
+struct pci_attach_args;
+
+int psp_pci_match(struct ccp_softc *, struct pci_attach_args *);
+void psp_pci_intr_map(struct ccp_softc *, struct pci_attach_args *);
+void psp_pci_attach(struct ccp_softc *, struct pci_attach_args *);
 
 #endif	/* _KERNEL */
Index: dev/pci/ccp_pci.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pci/ccp_pci.c,v
diff -u -p -r1.13 ccp_pci.c
--- dev/pci/ccp_pci.c	4 Sep 2024 07:45:08 -0000	1.13
+++ dev/pci/ccp_pci.c	22 Oct 2024 09:49:22 -0000
@@ -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, st
 	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, st
 		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
 }
Index: dev/pci/files.pci
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/dev/pci/files.pci,v
diff -u -p -r1.366 files.pci
--- dev/pci/files.pci	14 Aug 2024 14:40:46 -0000	1.366
+++ dev/pci/files.pci	22 Oct 2024 09:49:22 -0000
@@ -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
Index: dev/pci/psp_pci.c
===================================================================
RCS file: dev/pci/psp_pci.c
diff -N dev/pci/psp_pci.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ dev/pci/psp_pci.c	22 Oct 2024 09:50:05 -0000
@@ -0,0 +1,126 @@
+/*	$OpenBSD$	*/
+
+/*
+ * 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;
+	}
+}