1 From 6a0bc3522e746025e2d9a63ab2cb5d7062c2d39c Mon Sep 17 00:00:00 2001
2 From: Patrick Delaunay <patrick.delaunay@foss.st.com>
3 Date: Mon, 6 Feb 2023 13:43:51 +0000
4 Subject: [PATCH] nvmem: stm32: add OP-TEE support for STM32MP13x
6 For boot with OP-TEE on STM32MP13, the communication with the secure
7 world no more use STMicroelectronics SMC but communication with the
8 STM32MP BSEC TA, for data access (read/write) or lock operation:
9 - all the request are sent to OP-TEE trusted application,
10 - for upper OTP with ECC protection and with word programming only
11 each OTP are permanently locked when programmed to avoid ECC error
12 on the second write operation
14 Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
15 Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
16 Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
17 Link: https://lore.kernel.org/r/20230206134356.839737-18-srinivas.kandagatla@linaro.org
18 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
20 drivers/nvmem/Kconfig | 11 +
21 drivers/nvmem/Makefile | 1 +
22 drivers/nvmem/stm32-bsec-optee-ta.c | 298 ++++++++++++++++++++++++++++
23 drivers/nvmem/stm32-bsec-optee-ta.h | 80 ++++++++
24 drivers/nvmem/stm32-romem.c | 54 ++++-
25 5 files changed, 441 insertions(+), 3 deletions(-)
26 create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.c
27 create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.h
29 --- a/drivers/nvmem/Kconfig
30 +++ b/drivers/nvmem/Kconfig
31 @@ -290,9 +290,20 @@ config NVMEM_SPRD_EFUSE
32 This driver can also be built as a module. If so, the module
33 will be called nvmem-sprd-efuse.
35 +config NVMEM_STM32_BSEC_OPTEE_TA
36 + bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver"
39 + Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE
40 + trusted application STM32MP BSEC.
42 + This library is a used by stm32-romem driver or included in the module
43 + called nvmem-stm32-romem.
45 config NVMEM_STM32_ROMEM
46 tristate "STMicroelectronics STM32 factory-programmed memory support"
47 depends on ARCH_STM32 || COMPILE_TEST
48 + imply NVMEM_STM32_BSEC_OPTEE_TA
50 Say y here to enable read-only access for STMicroelectronics STM32
51 factory-programmed memory area.
52 --- a/drivers/nvmem/Makefile
53 +++ b/drivers/nvmem/Makefile
54 @@ -61,6 +61,7 @@ obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem
55 nvmem_sprd_efuse-y := sprd-efuse.o
56 obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o
57 nvmem_stm32_romem-y := stm32-romem.o
58 +nvmem_stm32_romem-$(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) += stm32-bsec-optee-ta.o
59 obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o
60 nvmem_sunplus_ocotp-y := sunplus-ocotp.o
61 obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o
63 +++ b/drivers/nvmem/stm32-bsec-optee-ta.c
65 +// SPDX-License-Identifier: GPL-2.0-or-later
67 + * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
69 + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
72 +#include <linux/tee_drv.h>
74 +#include "stm32-bsec-optee-ta.h"
79 + * [in] value[0].a OTP start offset in byte
80 + * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock)
81 + * [out] memref[1].buffer Output buffer to store read values
82 + * [out] memref[1].size Size of OTP to be read
85 + * TEE_SUCCESS - Invoke command success
86 + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
87 + * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
89 +#define PTA_BSEC_READ_MEM 0x0
94 + * [in] value[0].a OTP start offset in byte
95 + * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock)
96 + * [in] memref[1].buffer Input buffer to read values
97 + * [in] memref[1].size Size of OTP to be written
100 + * TEE_SUCCESS - Invoke command success
101 + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
102 + * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller
104 +#define PTA_BSEC_WRITE_MEM 0x1
106 +/* value of PTA_BSEC access type = value[in] b */
107 +#define SHADOW_ACCESS 0
108 +#define FUSE_ACCESS 1
109 +#define LOCK_ACCESS 2
111 +/* Bitfield definition for LOCK status */
112 +#define LOCK_PERM BIT(30)
114 +/* OP-TEE STM32MP BSEC TA UUID */
115 +static const uuid_t stm32mp_bsec_ta_uuid =
116 + UUID_INIT(0x94cf71ad, 0x80e6, 0x40b5,
117 + 0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03);
120 + * Check whether this driver supports the BSEC TA in the TEE instance
121 + * represented by the params (ver/data) to this function.
123 +static int stm32_bsec_optee_ta_match(struct tee_ioctl_version_data *ver,
126 + /* Currently this driver only supports GP compliant, OP-TEE based TA */
127 + if ((ver->impl_id == TEE_IMPL_ID_OPTEE) &&
128 + (ver->gen_caps & TEE_GEN_CAP_GP))
134 +/* Open a session to OP-TEE for STM32MP BSEC TA */
135 +static int stm32_bsec_ta_open_session(struct tee_context *ctx, u32 *id)
137 + struct tee_ioctl_open_session_arg sess_arg;
140 + memset(&sess_arg, 0, sizeof(sess_arg));
141 + export_uuid(sess_arg.uuid, &stm32mp_bsec_ta_uuid);
142 + sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
143 + sess_arg.num_params = 0;
145 + rc = tee_client_open_session(ctx, &sess_arg, NULL);
146 + if ((rc < 0) || (sess_arg.ret != 0)) {
147 + pr_err("%s: tee_client_open_session failed err:%#x, ret:%#x\n",
148 + __func__, sess_arg.ret, rc);
152 + *id = sess_arg.session;
158 +/* close a session to OP-TEE for STM32MP BSEC TA */
159 +static void stm32_bsec_ta_close_session(void *ctx, u32 id)
161 + tee_client_close_session(ctx, id);
164 +/* stm32_bsec_optee_ta_open() - initialize the STM32MP BSEC TA */
165 +int stm32_bsec_optee_ta_open(struct tee_context **ctx)
167 + struct tee_context *tee_ctx;
171 + /* Open context with TEE driver */
172 + tee_ctx = tee_client_open_context(NULL, stm32_bsec_optee_ta_match, NULL, NULL);
173 + if (IS_ERR(tee_ctx)) {
174 + rc = PTR_ERR(tee_ctx);
176 + return -EPROBE_DEFER;
177 + pr_err("%s: tee_client_open_context failed (%d)\n", __func__, rc);
182 + /* Check STM32MP BSEC TA presence */
183 + rc = stm32_bsec_ta_open_session(tee_ctx, &session_id);
185 + tee_client_close_context(tee_ctx);
189 + stm32_bsec_ta_close_session(tee_ctx, session_id);
196 +/* stm32_bsec_optee_ta_open() - release the PTA STM32MP BSEC TA */
197 +void stm32_bsec_optee_ta_close(void *ctx)
199 + tee_client_close_context(ctx);
202 +/* stm32_bsec_optee_ta_read() - nvmem read access using PTA client driver */
203 +int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
204 + void *buf, size_t bytes)
206 + struct tee_shm *shm;
207 + struct tee_ioctl_invoke_arg arg;
208 + struct tee_param param[2];
210 + u32 start, num_bytes;
214 + ret = stm32_bsec_ta_open_session(ctx, &session_id);
218 + memset(&arg, 0, sizeof(arg));
219 + memset(¶m, 0, sizeof(param));
221 + arg.func = PTA_BSEC_READ_MEM;
222 + arg.session = session_id;
223 + arg.num_params = 2;
225 + /* align access on 32bits */
226 + start = ALIGN_DOWN(offset, 4);
227 + num_bytes = round_up(offset + bytes - start, 4);
228 + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
229 + param[0].u.value.a = start;
230 + param[0].u.value.b = SHADOW_ACCESS;
232 + shm = tee_shm_alloc_kernel_buf(ctx, num_bytes);
234 + ret = PTR_ERR(shm);
235 + goto out_tee_session;
238 + param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
239 + param[1].u.memref.shm = shm;
240 + param[1].u.memref.size = num_bytes;
242 + ret = tee_client_invoke_func(ctx, &arg, param);
243 + if (ret < 0 || arg.ret != 0) {
244 + pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n",
250 + shm_buf = tee_shm_get_va(shm, 0);
251 + if (IS_ERR(shm_buf)) {
252 + ret = PTR_ERR(shm_buf);
253 + pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
255 + /* read data from 32 bits aligned buffer */
256 + memcpy(buf, &shm_buf[offset % 4], bytes);
263 + stm32_bsec_ta_close_session(ctx, session_id);
268 +/* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */
269 +int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
270 + unsigned int offset, void *buf, size_t bytes)
271 +{ struct tee_shm *shm;
272 + struct tee_ioctl_invoke_arg arg;
273 + struct tee_param param[2];
278 + ret = stm32_bsec_ta_open_session(ctx, &session_id);
282 + /* Allow only writing complete 32-bits aligned words */
283 + if ((bytes % 4) || (offset % 4))
286 + memset(&arg, 0, sizeof(arg));
287 + memset(¶m, 0, sizeof(param));
289 + arg.func = PTA_BSEC_WRITE_MEM;
290 + arg.session = session_id;
291 + arg.num_params = 2;
293 + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
294 + param[0].u.value.a = offset;
295 + param[0].u.value.b = FUSE_ACCESS;
297 + shm = tee_shm_alloc_kernel_buf(ctx, bytes);
299 + ret = PTR_ERR(shm);
300 + goto out_tee_session;
303 + param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
304 + param[1].u.memref.shm = shm;
305 + param[1].u.memref.size = bytes;
307 + shm_buf = tee_shm_get_va(shm, 0);
308 + if (IS_ERR(shm_buf)) {
309 + ret = PTR_ERR(shm_buf);
310 + pr_err("tee_shm_get_va failed for transmit (%d)\n", ret);
313 + goto out_tee_session;
316 + memcpy(shm_buf, buf, bytes);
318 + ret = tee_client_invoke_func(ctx, &arg, param);
319 + if (ret < 0 || arg.ret != 0) {
320 + pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
324 + pr_debug("Write OTPs %d to %zu, ret=%d\n", offset / 4, (offset + bytes) / 4, ret);
326 + /* Lock the upper OTPs with ECC protection, word programming only */
327 + if (!ret && ((offset + bytes) >= (lower * 4))) {
328 + u32 start, nb_lock;
329 + u32 *lock = (u32 *)shm_buf;
333 + * don't lock the lower OTPs, no ECC protection and incremental
334 + * bit programming, a second write is allowed
336 + start = max_t(u32, offset, lower * 4);
337 + nb_lock = (offset + bytes - start) / 4;
339 + param[0].u.value.a = start;
340 + param[0].u.value.b = LOCK_ACCESS;
341 + param[1].u.memref.size = nb_lock * 4;
343 + for (i = 0; i < nb_lock; i++)
344 + lock[i] = LOCK_PERM;
346 + ret = tee_client_invoke_func(ctx, &arg, param);
347 + if (ret < 0 || arg.ret != 0) {
348 + pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret);
352 + pr_debug("Lock upper OTPs %d to %d, ret=%d\n",
353 + start / 4, start / 4 + nb_lock, ret);
359 + stm32_bsec_ta_close_session(ctx, session_id);
364 +++ b/drivers/nvmem/stm32-bsec-optee-ta.h
366 +/* SPDX-License-Identifier: GPL-2.0-or-later */
368 + * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver
370 + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
373 +#if IS_ENABLED(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA)
375 + * stm32_bsec_optee_ta_open() - initialize the STM32 BSEC TA
376 + * @ctx: the OP-TEE context on success
379 + * On success, 0. On failure, -errno.
381 +int stm32_bsec_optee_ta_open(struct tee_context **ctx);
384 + * stm32_bsec_optee_ta_close() - release the STM32 BSEC TA
385 + * @ctx: the OP-TEE context
387 + * This function used to clean the OP-TEE resources initialized in
388 + * stm32_bsec_optee_ta_open(); it can be used as callback to
389 + * devm_add_action_or_reset()
391 +void stm32_bsec_optee_ta_close(void *ctx);
394 + * stm32_bsec_optee_ta_read() - nvmem read access using TA client driver
395 + * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
396 + * @offset: nvmem offset
397 + * @buf: buffer to fill with nvem values
398 + * @bytes: number of bytes to read
401 + * On success, 0. On failure, -errno.
403 +int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
404 + void *buf, size_t bytes);
407 + * stm32_bsec_optee_ta_write() - nvmem write access using TA client driver
408 + * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open
409 + * @lower: number of lower OTP, not protected by ECC
410 + * @offset: nvmem offset
411 + * @buf: buffer with nvem values
412 + * @bytes: number of bytes to write
415 + * On success, 0. On failure, -errno.
417 +int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
418 + unsigned int offset, void *buf, size_t bytes);
422 +static inline int stm32_bsec_optee_ta_open(struct tee_context **ctx)
424 + return -EOPNOTSUPP;
427 +static inline void stm32_bsec_optee_ta_close(void *ctx)
431 +static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx,
432 + unsigned int offset, void *buf,
435 + return -EOPNOTSUPP;
438 +static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx,
439 + unsigned int lower,
440 + unsigned int offset, void *buf,
443 + return -EOPNOTSUPP;
445 +#endif /* CONFIG_NVMEM_STM32_BSEC_OPTEE_TA */
446 --- a/drivers/nvmem/stm32-romem.c
447 +++ b/drivers/nvmem/stm32-romem.c
449 #include <linux/module.h>
450 #include <linux/nvmem-provider.h>
451 #include <linux/of_device.h>
452 +#include <linux/tee_drv.h>
454 +#include "stm32-bsec-optee-ta.h"
456 /* BSEC secure service access from non-secure */
457 #define STM32_SMC_BSEC 0x82001003
459 struct stm32_romem_cfg {
465 struct stm32_romem_priv {
467 struct nvmem_config cfg;
469 + struct tee_context *ctx;
472 static int stm32_romem_read(void *context, unsigned int offset, void *buf,
473 @@ -138,12 +143,29 @@ static int stm32_bsec_write(void *contex
477 +static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf,
480 + struct stm32_romem_priv *priv = context;
482 + return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes);
485 +static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf,
488 + struct stm32_romem_priv *priv = context;
490 + return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes);
493 static int stm32_romem_probe(struct platform_device *pdev)
495 const struct stm32_romem_cfg *cfg;
496 struct device *dev = &pdev->dev;
497 struct stm32_romem_priv *priv;
498 struct resource *res;
501 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
503 @@ -173,15 +195,31 @@ static int stm32_romem_probe(struct plat
505 priv->cfg.size = cfg->size;
506 priv->lower = cfg->lower;
507 - priv->cfg.reg_read = stm32_bsec_read;
508 - priv->cfg.reg_write = stm32_bsec_write;
510 + rc = stm32_bsec_optee_ta_open(&priv->ctx);
511 + /* wait for OP-TEE client driver to be up and ready */
516 + rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx);
518 + dev_err(dev, "devm_add_action_or_reset() failed (%d)\n", rc);
521 + priv->cfg.reg_read = stm32_bsec_pta_read;
522 + priv->cfg.reg_write = stm32_bsec_pta_write;
524 + priv->cfg.reg_read = stm32_bsec_read;
525 + priv->cfg.reg_write = stm32_bsec_write;
529 return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg));
533 - * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
534 + * STM32MP15/13 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits)
535 * => 96 x 32-bits data words
536 * - Lower: 1K bits, 2:1 redundancy, incremental bit programming
537 * => 32 (x 32-bits) lower shadow registers = words 0 to 31
538 @@ -191,6 +229,13 @@ static int stm32_romem_probe(struct plat
539 static const struct stm32_romem_cfg stm32mp15_bsec_cfg = {
545 +static const struct stm32_romem_cfg stm32mp13_bsec_cfg = {
551 static const struct of_device_id stm32_romem_of_match[] = {
552 @@ -198,7 +243,10 @@ static const struct of_device_id stm32_r
553 .compatible = "st,stm32mp15-bsec",
554 .data = (void *)&stm32mp15_bsec_cfg,
556 + .compatible = "st,stm32mp13-bsec",
557 + .data = (void *)&stm32mp13_bsec_cfg,
559 + { /* sentinel */ },
561 MODULE_DEVICE_TABLE(of, stm32_romem_of_match);