diff options
-rw-r--r-- | sys/dev/ic/psp.c | 71 | ||||
-rw-r--r-- | sys/dev/ic/pspvar.h | 17 | ||||
-rw-r--r-- | sys/dev/pci/ccp_pci.c | 65 | ||||
-rw-r--r-- | sys/dev/pci/files.pci | 3 | ||||
-rw-r--r-- | sys/dev/pci/psp_pci.c | 126 |
5 files changed, 206 insertions, 76 deletions
diff --git a/sys/dev/ic/psp.c b/sys/dev/ic/psp.c index 95babb7d3db..e3eda5c96a8 100644 --- a/sys/dev/ic/psp.c +++ b/sys/dev/ic/psp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: psp.c,v 1.5 2024/10/04 16:58:26 bluhm Exp $ */ +/* $OpenBSD: psp.c,v 1.6 2024/10/24 18:52:59 bluhm Exp $ */ /* * Copyright (c) 2023, 2024 Hans-Joerg Hoexer <hshoexer@genua.de> @@ -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 device *self, void *aux) 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 device *self, void *aux) 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 device *self, void *aux) 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 *status, int poll) 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 *status, int poll) 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, uint64_t paddr) 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); diff --git a/sys/dev/ic/pspvar.h b/sys/dev/ic/pspvar.h index a1d7c83849e..c3bad155aca 100644 --- a/sys/dev/ic/pspvar.h +++ b/sys/dev/ic/pspvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pspvar.h,v 1.2 2024/09/04 07:45:08 jsg Exp $ */ +/* $OpenBSD: pspvar.h,v 1.3 2024/10/24 18:52:59 bluhm Exp $ */ /* * Copyright (c) 2023, 2024 Hans-Joerg Hoexer <hshoexer@genua.de> @@ -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 */ 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; + } +} |