Index | Thread | Search

From:
Mike Larkin <mlarkin@nested.page>
Subject:
Re: psp(4): Download firmware command 2/3
To:
tech@openbsd.org
Date:
Fri, 25 Oct 2024 09:25:43 -0700

Download raw body.

Thread
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 <hshoexer@genua.de>
> 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 */