From: Mike Larkin Subject: Re: psp(4): Download firmware command 2/3 To: tech@openbsd.org Date: Fri, 25 Oct 2024 09:25:43 -0700 On Fri, Oct 25, 2024 at 03:50:15PM +0200, Hans-Jörg Höxer wrote: > Hi, > > this implements the download firmware command. > ok mlarkin > 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 */