All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jorge Ramirez via U-Boot <u-boot@lists.u-boot-project.org>
To: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Jorge Ramirez-Ortiz <jorge.ramirez@oss.qualcomm.com>,
	trini@konsulko.com,  jens.wiklander@linaro.org,
	ilias.apalodimas@linaro.org, bhupesh.linux@gmail.com,
	n-francis@ti.com, marek.vasut+renesas@mailbox.org,
	igor.belwon@mentallysanemainliners.org, shawn.lin@rock-chips.com,
	yoshihiro.shimoda.uh@renesas.com, alchark@gmail.com,
	tuyen.dang.xa@renesas.com, macpaul.lin@mediatek.com,
	padmarao.begari@amd.com, jstephan@baylibre.com, bb@ti.com,
	j-mcarthur@ti.com, venkyada@qti.qualcomm.com,
	hayashi.kunihiko@socionext.com, u-boot@lists.denx.de,
	sumit.garg@kernel.org
Subject: Re: [PATCH v1 2/7] ufs: add RPMB transport over SCSI SECURITY PROTOCOL
Date: Wed, 22 Jul 2026 08:10:08 +0200	[thread overview]
Message-ID: <amBewH0VMPEafAcL@trex> (raw)
In-Reply-To: <6655cb53-fe79-4163-b148-377ee35fbee8@linaro.org>

On 21/07/26 09:46:55, neil.armstrong@linaro.org wrote:
> Hi,
> On 7/20/26 10:51, Jorge Ramirez-Ortiz wrote:
> > Add a UFS RPMB transport that moves fully-formed JEDEC RPMB frames to and
> > from the RPMB Well-Known LUN using SCSI SECURITY PROTOCOL IN/OUT commands,
> > exposed through ufs_rpmb_route_frames() for the OP-TEE RPMB supplicant and
> > guarded by CONFIG_SUPPORT_UFS_RPMB.
> > 
> > Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez@oss.qualcomm.com>
> > ---
> >   drivers/ufs/Kconfig      |  13 ++++
> >   drivers/ufs/Makefile     |   1 +
> >   drivers/ufs/ufs-rpmb.c   | 146 +++++++++++++++++++++++++++++++++++++++
> >   drivers/ufs/ufs-uclass.c |   6 ++
> >   drivers/ufs/ufs.h        |  13 ++++
> >   include/ufs.h            |   8 +++
> >   6 files changed, 187 insertions(+)
> >   create mode 100644 drivers/ufs/ufs-rpmb.c
> > 
> > diff --git a/drivers/ufs/Kconfig b/drivers/ufs/Kconfig
> > index 49472933de3..d39fcda42dc 100644
> > --- a/drivers/ufs/Kconfig
> > +++ b/drivers/ufs/Kconfig
> > @@ -92,4 +92,17 @@ config UFS_TI_J721E
> >   	  This selects the glue layer driver for Cadence controller
> >   	  present on TI's J721E devices.
> > +config SUPPORT_UFS_RPMB
> > +	bool "Enable UFS RPMB (Replay Protected Memory Block) support"
> > +	depends on UFS && OPTEE && !SUPPORT_EMMC_RPMB
> > +	select BLAKE2
> > +	help
> > +	  Route OP-TEE RPMB requests to the UFS RPMB Well-Known LUN using
> > +	  SCSI SECURITY PROTOCOL IN/OUT commands. Required for OP-TEE secure
> > +	  storage (CFG_RPMB_FS) on UFS-based platforms that have no eMMC.
> > +	  BLAKE2 is used to derive the fixed-length RPMB CID that matches the
> > +	  Linux kernel UFS device_id ABI. The OP-TEE supplicant handles a
> > +	  single RPMB transport, so this is mutually exclusive with the eMMC
> > +	  RPMB supplicant (SUPPORT_EMMC_RPMB).
> > +
> >   endmenu
> > diff --git a/drivers/ufs/Makefile b/drivers/ufs/Makefile
> > index e7f3c1d30c4..d60440ca119 100644
> > --- a/drivers/ufs/Makefile
> > +++ b/drivers/ufs/Makefile
> > @@ -13,3 +13,4 @@ obj-$(CONFIG_UFS_RENESAS) += ufs-renesas.o
> >   obj-$(CONFIG_UFS_RENESAS_GEN5) += ufs-renesas-rcar-gen5.o
> >   obj-$(CONFIG_UFS_ROCKCHIP) += ufs-rockchip.o
> >   obj-$(CONFIG_UFS_TI_J721E) += ti-j721e-ufs.o
> > +obj-$(CONFIG_SUPPORT_UFS_RPMB) += ufs-rpmb.o
> > diff --git a/drivers/ufs/ufs-rpmb.c b/drivers/ufs/ufs-rpmb.c
> > new file mode 100644
> > index 00000000000..636ccb6e74f
> > --- /dev/null
> > +++ b/drivers/ufs/ufs-rpmb.c
> > @@ -0,0 +1,146 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +#include <dm.h>
> > +#include <log.h>
> > +#include <scsi.h>
> > +#include <ufs.h>
> > +#include <linux/errno.h>
> > +#include <linux/string.h>
> > +#include "ufs.h"
> > +
> > +#define RPMB_REQ_KEY		1
> > +#define RPMB_REQ_WCOUNTER	2
> > +#define RPMB_REQ_WRITE_DATA	3
> > +#define RPMB_REQ_READ_DATA	4
> > +#define RPMB_REQ_STATUS		5
> > +
> > +#define RPMB_FRAME_REQ_OFFSET	510
> > +
> > +static u16 rpmb_frame_request(const void *frame)
> > +{
> > +	const u8 *p = frame;
> > +
> > +	return ((u16)p[RPMB_FRAME_REQ_OFFSET] << 8) |
> > +		p[RPMB_FRAME_REQ_OFFSET + 1];
> > +}
> > +
> > +static int ufs_rpmb_secprot(struct udevice *scsi_dev, unsigned int region,
> > +			    u8 opcode, void *buf, unsigned int nframes,
> > +			    enum dma_data_direction dir)
> > +{
> > +	struct scsi_cmd pccb;
> > +	u32 len = nframes * RPMB_FRAME_SIZE;
> > +	u16 spsp = (region << 8) | UFS_RPMB_SEC_PROTOCOL_ID;
> > +
> > +	memset(&pccb, 0, sizeof(pccb));
> > +	pccb.lun = UFS_UPIU_RPMB_WLUN;
> > +	pccb.cmd[0] = opcode;
> > +	pccb.cmd[1] = SEC_PROTOCOL_UFS;
> > +	pccb.cmd[2] = (spsp >> 8) & 0xff;
> > +	pccb.cmd[3] = spsp & 0xff;
> > +	pccb.cmd[4] = 0;
> > +	pccb.cmd[5] = 0;
> > +	pccb.cmd[6] = (len >> 24) & 0xff;
> > +	pccb.cmd[7] = (len >> 16) & 0xff;
> > +	pccb.cmd[8] = (len >> 8) & 0xff;
> > +	pccb.cmd[9] = len & 0xff;
> > +	pccb.cmd[10] = 0;
> > +	pccb.cmd[11] = 0;
> > +	pccb.cmdlen = 12;
> > +	pccb.pdata = buf;
> > +	pccb.datalen = len;
> > +	pccb.dma_dir = dir;
> > +
> > +	return scsi_exec(scsi_dev, &pccb);
> > +}
> > +
> > +static int ufs_rpmb_send(struct udevice *scsi_dev, unsigned int region,
> > +			 void *frames, unsigned int nframes)
> > +{
> > +	return ufs_rpmb_secprot(scsi_dev, region, SECURITY_PROTOCOL_OUT,
> > +				frames, nframes, DMA_TO_DEVICE);
> > +}
> > +
> > +static int ufs_rpmb_recv(struct udevice *scsi_dev, unsigned int region,
> > +			 void *frames, unsigned int nframes)
> > +{
> > +	return ufs_rpmb_secprot(scsi_dev, region, SECURITY_PROTOCOL_IN,
> > +				frames, nframes, DMA_FROM_DEVICE);
> > +}
> > +
> > +int ufs_rpmb_route_frames(struct udevice *scsi_dev, unsigned int region,
> > +			  void *req, unsigned long reqlen, void *rsp,
> > +			  unsigned long rsplen)
> > +{
> > +	unsigned int n_req = reqlen / RPMB_FRAME_SIZE;
> > +	unsigned int n_rsp = rsplen / RPMB_FRAME_SIZE;
> > +	u16 request;
> > +	int ret;
> > +
> > +	if (!scsi_dev || reqlen % RPMB_FRAME_SIZE ||
> > +	    rsplen % RPMB_FRAME_SIZE || !n_req)
> > +		return -EINVAL;
> > +
> > +	request = rpmb_frame_request(req);
> > +
> > +	switch (request) {
> > +	case RPMB_REQ_KEY:
> > +	case RPMB_REQ_WRITE_DATA: {
> > +		u8 status_frame[RPMB_FRAME_SIZE];
> > +
> > +		ret = ufs_rpmb_send(scsi_dev, region, req, n_req);
> > +		if (ret)
> > +			return ret;
> > +
> > +		memset(status_frame, 0, sizeof(status_frame));
> > +		status_frame[RPMB_FRAME_REQ_OFFSET] = RPMB_REQ_STATUS >> 8;
> > +		status_frame[RPMB_FRAME_REQ_OFFSET + 1] = RPMB_REQ_STATUS & 0xff;
> > +		ret = ufs_rpmb_send(scsi_dev, region, status_frame, 1);
> > +		if (ret)
> > +			return ret;
> > +
> > +		if (n_rsp < 1)
> > +			return -EINVAL;
> > +		return ufs_rpmb_recv(scsi_dev, region, rsp, 1);
> > +	}
> > +	case RPMB_REQ_WCOUNTER:
> > +	case RPMB_REQ_READ_DATA:
> > +		ret = ufs_rpmb_send(scsi_dev, region, req, 1);
> > +		if (ret)
> > +			return ret;
> > +		if (n_rsp < 1)
> > +			return -EINVAL;
> > +		return ufs_rpmb_recv(scsi_dev, region, rsp, n_rsp);
> > +	default:
> > +		debug("ufs-rpmb: unsupported request 0x%x\n", request);
> > +		return -EINVAL;
> > +	}
> > +}
> > +
> > +struct udevice *ufs_rpmb_get_scsi_dev(int dev_id)
> > +{
> > +	struct udevice *scsi_dev;
> > +	int ret;
> > +
> > +	ret = uclass_get_device(UCLASS_SCSI, dev_id, &scsi_dev);
> > +	if (ret) {
> > +		debug("ufs-rpmb: no SCSI device for dev_id %d: %d\n",
> > +		      dev_id, ret);
> > +		return NULL;
> > +	}
> > +	return scsi_dev;
> > +}
> 
> This is a wrapper on uclass_get_device(), why not using uclass_get_device()
> from the caller code ?

ok.

> 
> > +
> > +int ufs_rpmb_read_geometry(struct udevice *scsi_dev, u8 *rpmb_rw_size)
> > +{
> > +	struct ufs_hba *hba = dev_get_uclass_priv(scsi_dev->parent);
> > +	u8 desc[QUERY_DESC_GEOMETRY_DEF_SIZE];
> > +	int ret;
> > +
> > +	ret = ufshcd_read_descriptor(hba, QUERY_DESC_IDN_GEOMETRY, 0,
> > +				     desc, sizeof(desc));
> > +	if (ret)
> > +		return ret;
> > +
> > +	*rpmb_rw_size = desc[GEOMETRY_DESC_RPMB_RW_SIZE];
> > +	return 0;
> > +}
> > diff --git a/drivers/ufs/ufs-uclass.c b/drivers/ufs/ufs-uclass.c
> > index 4d10e0b11fe..962b6093762 100644
> > --- a/drivers/ufs/ufs-uclass.c
> > +++ b/drivers/ufs/ufs-uclass.c
> > @@ -1712,6 +1712,12 @@ static inline int ufshcd_read_desc(struct ufs_hba *hba, enum desc_idn desc_id,
> >   	return ufshcd_read_desc_param(hba, desc_id, desc_index, 0, buf, size);
> >   }
> > +int ufshcd_read_descriptor(struct ufs_hba *hba, enum desc_idn desc_id,
> > +			   int desc_index, u8 *buf, u8 size)
> > +{
> > +	return ufshcd_read_desc_param(hba, desc_id, desc_index, 0, buf, size);
> 
> Why you don't expose & use ufshcd_read_desc_param() directly ?

sure

> 
> > +}
> > +
> >   static int ufshcd_read_device_desc(struct ufs_hba *hba, u8 *buf, u32 size)
> >   {
> >   	return ufshcd_read_desc(hba, QUERY_DESC_IDN_DEVICE, 0, buf, size);
> > diff --git a/drivers/ufs/ufs.h b/drivers/ufs/ufs.h
> > index 0f6c93fbce7..e66d2c5f533 100644
> > --- a/drivers/ufs/ufs.h
> > +++ b/drivers/ufs/ufs.h
> > @@ -10,6 +10,16 @@
> >   struct udevice;
> >   #define UFS_CDB_SIZE	16
> > +
> > +#define UFS_UPIU_RPMB_WLUN		0xC4
> > +#define RPMB_FRAME_SIZE			512
> 
> Can this be declared in a common rpbm header ?
> 
> > +
> > +#define SECURITY_PROTOCOL_IN		0xA2
> > +#define SECURITY_PROTOCOL_OUT		0xB5
> 
> Those are SCSI indentifiers, move the, to sci headers.
> 
> > +#define SEC_PROTOCOL_UFS		0xEC
> > +#define UFS_RPMB_SEC_PROTOCOL_ID	0x01
> 
> Those are not UFS internal identifiers, move them to the ufs-rpmb code like Linux.

ok, let me fix all this issues on v2

  reply	other threads:[~2026-07-22  6:10 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-20  8:51 [PATCH v1 0/7] ufs: rpmb: route OP-TEE RPMB secure storage over UFS Jorge Ramirez-Ortiz
2026-07-20  8:51 ` [PATCH v1 1/7] ufs: decode string descriptors as UTF-16 big-endian Jorge Ramirez-Ortiz
2026-07-21  7:32   ` Neil Armstrong (Linaro) via U-Boot
2026-07-21 14:56     ` Jorge Ramirez via U-Boot
2026-07-20  8:51 ` [PATCH v1 2/7] ufs: add RPMB transport over SCSI SECURITY PROTOCOL Jorge Ramirez-Ortiz
2026-07-21  7:46   ` Neil Armstrong (Linaro) via U-Boot
2026-07-22  6:10     ` Jorge Ramirez via U-Boot [this message]
2026-07-20  8:51 ` [PATCH v1 3/7] ufs: rpmb: derive the per-region RPMB CID and size for OP-TEE Jorge Ramirez-Ortiz
2026-07-21  7:51   ` Neil Armstrong (Linaro) via U-Boot
2026-07-20  8:51 ` [PATCH v1 4/7] ufs: rpmb: retry SECURITY PROTOCOL on power-on UNIT ATTENTION Jorge Ramirez-Ortiz
2026-07-21  7:52   ` Neil Armstrong (Linaro) via U-Boot
2026-07-22  6:10     ` Jorge Ramirez via U-Boot
2026-07-20  8:51 ` [PATCH v1 5/7] ufs: rpmb: bounce unaligned frames through a DMA-aligned buffer Jorge Ramirez-Ortiz
2026-07-21  7:53   ` Neil Armstrong (Linaro) via U-Boot
2026-07-22  6:11     ` Jorge Ramirez via U-Boot
2026-07-20  8:51 ` [PATCH v1 6/7] optee: rename rpmb.c to rpmb_legacy.c Jorge Ramirez-Ortiz
2026-07-20  8:51 ` [PATCH v1 7/7] optee: implement the RPMB subsystem interface for UFS Jorge Ramirez-Ortiz
2026-07-21  7:34   ` Neil Armstrong (Linaro) via U-Boot
2026-07-21 14:55     ` Jorge Ramirez via U-Boot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=amBewH0VMPEafAcL@trex \
    --to=u-boot@lists.u-boot-project.org \
    --cc=alchark@gmail.com \
    --cc=bb@ti.com \
    --cc=bhupesh.linux@gmail.com \
    --cc=hayashi.kunihiko@socionext.com \
    --cc=igor.belwon@mentallysanemainliners.org \
    --cc=ilias.apalodimas@linaro.org \
    --cc=j-mcarthur@ti.com \
    --cc=jens.wiklander@linaro.org \
    --cc=jorge.ramirez@oss.qualcomm.com \
    --cc=jstephan@baylibre.com \
    --cc=macpaul.lin@mediatek.com \
    --cc=marek.vasut+renesas@mailbox.org \
    --cc=n-francis@ti.com \
    --cc=neil.armstrong@linaro.org \
    --cc=padmarao.begari@amd.com \
    --cc=shawn.lin@rock-chips.com \
    --cc=sumit.garg@kernel.org \
    --cc=trini@konsulko.com \
    --cc=tuyen.dang.xa@renesas.com \
    --cc=u-boot@lists.denx.de \
    --cc=venkyada@qti.qualcomm.com \
    --cc=yoshihiro.shimoda.uh@renesas.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.