1*8f8d81e9Sbluhm /* $OpenBSD: psp_pci.c,v 1.2 2024/11/08 17:34:22 bluhm Exp $ */ 238923a19Sbluhm 338923a19Sbluhm /* 438923a19Sbluhm * Copyright (c) 2023-2024 Hans-Joerg Hoexer <hshoexer@genua.de> 538923a19Sbluhm * Copyright (c) 2024 Alexander Bluhm <bluhm@openbsd.org> 638923a19Sbluhm * 738923a19Sbluhm * Permission to use, copy, modify, and distribute this software for any 838923a19Sbluhm * purpose with or without fee is hereby granted, provided that the above 938923a19Sbluhm * copyright notice and this permission notice appear in all copies. 1038923a19Sbluhm * 1138923a19Sbluhm * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1238923a19Sbluhm * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1338923a19Sbluhm * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1438923a19Sbluhm * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1538923a19Sbluhm * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1638923a19Sbluhm * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1738923a19Sbluhm * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1838923a19Sbluhm */ 1938923a19Sbluhm 2038923a19Sbluhm #include <sys/param.h> 2138923a19Sbluhm #include <sys/systm.h> 2238923a19Sbluhm #include <sys/device.h> 2338923a19Sbluhm 2438923a19Sbluhm #include <machine/bus.h> 2538923a19Sbluhm 2638923a19Sbluhm #include <dev/pci/pcidevs.h> 2738923a19Sbluhm #include <dev/pci/pcivar.h> 2838923a19Sbluhm 2938923a19Sbluhm #include <dev/ic/ccpvar.h> 3038923a19Sbluhm #include <dev/ic/pspvar.h> 3138923a19Sbluhm 3238923a19Sbluhm static const struct pci_matchid psp_pci_devices[] = { 3338923a19Sbluhm { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_17_CCP_1 }, 3438923a19Sbluhm { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_17_3X_CCP }, 3538923a19Sbluhm { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_19_1X_PSP }, 3638923a19Sbluhm }; 3738923a19Sbluhm 3838923a19Sbluhm int 3938923a19Sbluhm psp_pci_match(struct ccp_softc *sc, struct pci_attach_args *pa) 4038923a19Sbluhm { 4138923a19Sbluhm bus_size_t reg_capabilities; 4238923a19Sbluhm uint32_t capabilities; 4338923a19Sbluhm 4438923a19Sbluhm if (!pci_matchbyid(pa, psp_pci_devices, nitems(psp_pci_devices))) 4538923a19Sbluhm return (0); 4638923a19Sbluhm 4738923a19Sbluhm if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_17_CCP_1) 4838923a19Sbluhm reg_capabilities = PSPV1_REG_CAPABILITIES; 4938923a19Sbluhm else 5038923a19Sbluhm reg_capabilities = PSP_REG_CAPABILITIES; 5138923a19Sbluhm capabilities = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 5238923a19Sbluhm reg_capabilities); 5338923a19Sbluhm if (!ISSET(capabilities, PSP_CAP_SEV)) 5438923a19Sbluhm return (0); 5538923a19Sbluhm 5638923a19Sbluhm return (1); 5738923a19Sbluhm } 5838923a19Sbluhm 5938923a19Sbluhm void 6038923a19Sbluhm psp_pci_intr_map(struct ccp_softc *sc, struct pci_attach_args *pa) 6138923a19Sbluhm { 6238923a19Sbluhm pci_intr_handle_t ih; 6338923a19Sbluhm const char *intrstr = NULL; 6438923a19Sbluhm bus_size_t reg_inten, reg_intsts; 6538923a19Sbluhm 6638923a19Sbluhm /* clear and disable interrupts */ 6738923a19Sbluhm if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_17_CCP_1) { 6838923a19Sbluhm reg_inten = PSPV1_REG_INTEN; 6938923a19Sbluhm reg_intsts = PSPV1_REG_INTSTS; 7038923a19Sbluhm } else { 7138923a19Sbluhm reg_inten = PSP_REG_INTEN; 7238923a19Sbluhm reg_intsts = PSP_REG_INTSTS; 7338923a19Sbluhm } 7438923a19Sbluhm bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg_inten, 0); 7538923a19Sbluhm bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg_intsts, -1); 7638923a19Sbluhm 7738923a19Sbluhm if (pci_intr_map_msix(pa, 0, &ih) != 0 && 7838923a19Sbluhm pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) { 7938923a19Sbluhm printf(": couldn't map interrupt\n"); 8038923a19Sbluhm return; 8138923a19Sbluhm } 8238923a19Sbluhm 8338923a19Sbluhm intrstr = pci_intr_string(pa->pa_pc, ih); 84*8f8d81e9Sbluhm sc->sc_irqh = pci_intr_establish(pa->pa_pc, ih, IPL_BIO | IPL_MPSAFE, 85*8f8d81e9Sbluhm psp_sev_intr, sc, sc->sc_dev.dv_xname); 8638923a19Sbluhm if (sc->sc_irqh != NULL) 8738923a19Sbluhm printf(": %s", intrstr); 8838923a19Sbluhm } 8938923a19Sbluhm 9038923a19Sbluhm void 9138923a19Sbluhm psp_pci_attach(struct ccp_softc *sc, struct pci_attach_args *pa) 9238923a19Sbluhm { 9338923a19Sbluhm struct psp_attach_args arg; 9438923a19Sbluhm struct device *self = (struct device *)sc; 9538923a19Sbluhm bus_size_t reg_capabilities; 9638923a19Sbluhm 9738923a19Sbluhm memset(&arg, 0, sizeof(arg)); 9838923a19Sbluhm arg.iot = sc->sc_iot; 9938923a19Sbluhm arg.ioh = sc->sc_ioh; 10038923a19Sbluhm arg.dmat = pa->pa_dmat; 10138923a19Sbluhm switch (PCI_PRODUCT(pa->pa_id)) { 10238923a19Sbluhm case PCI_PRODUCT_AMD_17_CCP_1: 10338923a19Sbluhm arg.version = 1; 10438923a19Sbluhm reg_capabilities = PSPV1_REG_CAPABILITIES; 10538923a19Sbluhm break; 10638923a19Sbluhm case PCI_PRODUCT_AMD_17_3X_CCP: 10738923a19Sbluhm arg.version = 2; 10838923a19Sbluhm reg_capabilities = PSP_REG_CAPABILITIES; 10938923a19Sbluhm break; 11038923a19Sbluhm case PCI_PRODUCT_AMD_19_1X_PSP: 11138923a19Sbluhm arg.version = 4; 11238923a19Sbluhm reg_capabilities = PSP_REG_CAPABILITIES; 11338923a19Sbluhm break; 11438923a19Sbluhm default: 11538923a19Sbluhm reg_capabilities = PSP_REG_CAPABILITIES; 11638923a19Sbluhm break; 11738923a19Sbluhm } 11838923a19Sbluhm arg.capabilities = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 11938923a19Sbluhm reg_capabilities); 12038923a19Sbluhm 12138923a19Sbluhm sc->sc_psp = config_found_sm(self, &arg, pspprint, pspsubmatch); 12238923a19Sbluhm if (sc->sc_psp == NULL) { 12338923a19Sbluhm pci_intr_disestablish(pa->pa_pc, sc->sc_irqh); 12438923a19Sbluhm return; 12538923a19Sbluhm } 12638923a19Sbluhm } 127