From: Hans-Jörg Höxer Subject: psp(4): Download firmware command 2/3 To: Date: Fri, 25 Oct 2024 15:50:15 +0200 Hi, this implements the download firmware command. Take care, HJ. ------------------------------------------------------------------- commit eec4dc462c8ba317902623b7ac11e4dd9f598969 Author: Hans-Joerg Hoexer Date: Mon Oct 21 14:26:48 2024 +0200 psp(4): Download firmware command Implement the download firmware command. Will be used by automatic firmware loading. diff --git a/sys/dev/ic/psp.c b/sys/dev/ic/psp.c index eebae8bab57..92459c9e06f 100644 --- a/sys/dev/ic/psp.c +++ b/sys/dev/ic/psp.c @@ -603,6 +603,55 @@ psp_deactivate(struct psp_softc *sc, struct psp_deactivate *udeact) return (0); } +int +psp_downloadfirmware(struct psp_softc *sc, struct psp_downloadfirmware *udlfw) +{ + struct psp_downloadfirmware *dlfw; + bus_dmamap_t map; + bus_dma_segment_t seg; + caddr_t kva; + int nsegs; + int ret; + + dlfw = (struct psp_downloadfirmware *)sc->sc_cmd_kva; + bzero(dlfw, sizeof(*dlfw)); + + ret = ENOMEM; + if (bus_dmamap_create(sc->sc_dmat, udlfw->fw_len, 1, udlfw->fw_len, 0, + BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT, &map) != 0) + return (ret); + if (bus_dmamem_alloc(sc->sc_dmat, udlfw->fw_len, 0, 0, &seg, 1, + &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO) != 0 || nsegs != 1) + goto fail_0; + if (bus_dmamem_map(sc->sc_dmat, &seg, nsegs, udlfw->fw_len, &kva, + BUS_DMA_WAITOK) != 0) + goto fail_1; + if (bus_dmamap_load(sc->sc_dmat, map, kva, udlfw->fw_len, NULL, + BUS_DMA_WAITOK) != 0) + goto fail_2; + + bcopy((void *)udlfw->fw_paddr, kva, udlfw->fw_len); + + dlfw->fw_paddr = map->dm_segs[0].ds_addr; + dlfw->fw_len = map->dm_segs[0].ds_len; + + ret = ccp_docmd(sc, PSP_CMD_DOWNLOADFIRMWARE, + sc->sc_cmd_map->dm_segs[0].ds_addr); + + if (ret != 0) + ret = EIO; + + bus_dmamap_unload(sc->sc_dmat, map); +fail_2: + bus_dmamem_unmap(sc->sc_dmat, kva, udlfw->fw_len); +fail_1: + bus_dmamem_free(sc->sc_dmat, &seg, 1); +fail_0: + bus_dmamap_destroy(sc->sc_dmat, map); + + return (ret); +} + int psp_guest_shutdown(struct psp_softc *sc, struct psp_guest_shutdown *ugshutdown) { diff --git a/sys/dev/ic/pspvar.h b/sys/dev/ic/pspvar.h index e7c776ea0cf..888b5d95daa 100644 --- a/sys/dev/ic/pspvar.h +++ b/sys/dev/ic/pspvar.h @@ -78,6 +78,7 @@ #define PSP_CMD_INIT 0x1 #define PSP_CMD_PLATFORMSTATUS 0x4 #define PSP_CMD_DF_FLUSH 0xa +#define PSP_CMD_DOWNLOADFIRMWARE 0xb #define PSP_CMD_DECOMMISSION 0x20 #define PSP_CMD_ACTIVATE 0x21 #define PSP_CMD_DEACTIVATE 0x22 @@ -214,6 +215,11 @@ struct psp_init { uint32_t tmr_length; } __packed; +struct psp_downloadfirmware { + /* Input parameters for PSP_CMD_DOWNLOADFIRMWARE */ + uint64_t fw_paddr; + uint32_t fw_len; +} __packed; struct psp_guest_shutdown { /* Input parameter for PSP_CMD_GUEST_SHUTDOWN */