* [PATCHv2] drivers: tee: i2c trampoline driver
@ 2020-12-28 12:17 Jorge Ramirez-Ortiz
2020-12-29 3:32 ` Simon Glass
0 siblings, 1 reply; 3+ messages in thread
From: Jorge Ramirez-Ortiz @ 2020-12-28 12:17 UTC (permalink / raw)
To: u-boot
This commit gives the secure world access to the I2C bus so it can
communicate with I2C slaves (tipically those would be secure elements
like the NXP SE050).
Signed-off-by: Jorge Ramirez-Ortiz <jorge@foundries.io>
---
drivers/tee/optee/Makefile | 1 +
drivers/tee/optee/i2c.c | 88 ++++++++++++++++++++++++
drivers/tee/optee/optee_msg.h | 21 ++++++
drivers/tee/optee/optee_msg_supplicant.h | 5 ++
drivers/tee/optee/optee_private.h | 12 ++++
drivers/tee/optee/supplicant.c | 3 +
6 files changed, 130 insertions(+)
create mode 100644 drivers/tee/optee/i2c.c
diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
index 928d3f8002..068c6e7aa1 100644
--- a/drivers/tee/optee/Makefile
+++ b/drivers/tee/optee/Makefile
@@ -2,4 +2,5 @@
obj-y += core.o
obj-y += supplicant.o
+obj-$(CONFIG_DM_I2C) += i2c.o
obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
diff --git a/drivers/tee/optee/i2c.c b/drivers/tee/optee/i2c.c
new file mode 100644
index 0000000000..506e40850c
--- /dev/null
+++ b/drivers/tee/optee/i2c.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (c) 2020 Foundries.io Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <i2c.h>
+#include <tee.h>
+#include "optee_msg.h"
+#include "optee_private.h"
+
+static struct {
+ struct udevice *dev;
+ int chip;
+ int bus;
+} xfer;
+
+void optee_suppl_cmd_i2c_transfer(struct udevice *dev,
+ struct optee_msg_arg *arg)
+{
+ const u8 attr[] = {
+ OPTEE_MSG_ATTR_TYPE_VALUE_INPUT,
+ OPTEE_MSG_ATTR_TYPE_VALUE_INPUT,
+ OPTEE_MSG_ATTR_TYPE_RMEM_INOUT,
+ OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT,
+ };
+ struct udevice *chip_dev = NULL;
+ struct tee_shm *shm = NULL;
+ uint8_t *buf = NULL;
+ size_t len = 0;
+ int chip = -1;
+ int bus = -1;
+ int ret = -1;
+
+ if (arg->num_params != ARRAY_SIZE(attr) ||
+ arg->params[0].attr != attr[0] ||
+ arg->params[1].attr != attr[1] ||
+ arg->params[2].attr != attr[2] ||
+ arg->params[3].attr != attr[3]) {
+ arg->ret = TEE_ERROR_BAD_PARAMETERS;
+ return;
+ }
+
+ len = arg->params[2].u.rmem.size;
+ shm = (struct tee_shm *)(unsigned long)arg->params[2].u.rmem.shm_ref;
+ buf = shm->addr;
+ if (!buf || !len)
+ goto bad;
+
+ bus = (int)arg->params[0].u.value.b;
+ chip = (int)arg->params[0].u.value.c;
+
+ if (!xfer.dev || xfer.chip != chip || xfer.bus != bus) {
+ if (i2c_get_chip_for_busnum(bus, chip, 0, &chip_dev))
+ goto bad;
+
+ xfer.dev = chip_dev;
+ xfer.chip = chip;
+ xfer.bus = bus;
+ }
+
+ if (arg->params[1].u.value.a & OPTEE_MSG_RPC_CMD_I2C_FLAGS_TEN_BIT)
+ if (i2c_set_chip_flags(xfer.dev, DM_I2C_CHIP_10BIT))
+ goto bad;
+
+ switch (arg->params[0].u.value.a) {
+ case OPTEE_MSG_RPC_CMD_I2C_TRANSFER_RD:
+ ret = dm_i2c_read(xfer.dev, 0, buf, len);
+ break;
+ case OPTEE_MSG_RPC_CMD_I2C_TRANSFER_WR:
+ ret = dm_i2c_write(xfer.dev, 0, buf, len);
+ break;
+ default:
+ goto bad;
+ }
+
+ if (ret) {
+ arg->ret = TEE_ERROR_COMMUNICATION;
+ } else {
+ arg->params[3].u.value.a = len;
+ arg->ret = TEE_SUCCESS;
+ }
+
+ return;
+bad:
+ arg->ret = TEE_ERROR_BAD_PARAMETERS;
+}
diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h
index 24c60960fc..8d40ce60c2 100644
--- a/drivers/tee/optee/optee_msg.h
+++ b/drivers/tee/optee/optee_msg.h
@@ -422,4 +422,25 @@ struct optee_msg_arg {
*/
#define OPTEE_MSG_RPC_CMD_SHM_FREE 7
+/*
+ * Access a device on an i2c bus
+ *
+ * [in] param[0].u.value.a mode: RD(0), WR(1)
+ * [in] param[0].u.value.b i2c adapter
+ * [in] param[0].u.value.c i2c chip
+ *
+ * [in] param[1].u.value.a i2c control flags
+ *
+ * [in/out] memref[2] buffer to exchange the transfer data
+ * with the secure world
+ *
+ * [out] param[3].u.value.a bytes transferred by the driver
+ */
+#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER 21
+/* I2C master transfer modes */
+#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER_RD 0
+#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER_WR 1
+/* I2C master control flags */
+#define OPTEE_MSG_RPC_CMD_I2C_FLAGS_TEN_BIT BIT(0)
+
#endif /* _OPTEE_MSG_H */
diff --git a/drivers/tee/optee/optee_msg_supplicant.h b/drivers/tee/optee/optee_msg_supplicant.h
index a0fb8063c8..963cfd4782 100644
--- a/drivers/tee/optee/optee_msg_supplicant.h
+++ b/drivers/tee/optee/optee_msg_supplicant.h
@@ -147,6 +147,11 @@
#define OPTEE_MSG_RPC_CMD_SHM_ALLOC 6
#define OPTEE_MSG_RPC_CMD_SHM_FREE 7
+/*
+ * I2C bus access
+ */
+#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER 21
+
/*
* Was OPTEE_MSG_RPC_CMD_SQL_FS, which isn't supported any longer
*/
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 9442d1c176..fc19e97871 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -60,6 +60,18 @@ static inline void optee_suppl_rpmb_release(struct udevice *dev)
}
#endif
+#ifdef CONFIG_DM_I2C
+void optee_suppl_cmd_i2c_transfer(struct udevice *dev,
+ struct optee_msg_arg *arg);
+#else
+static void optee_suppl_cmd_i2c_transfer(struct udevice *dev,
+ struct optee_msg_arg *arg)
+{
+ debug("OPTEE_MSG_RPC_CMD_I2C_TRANSFER not implemented\n");
+ arg->ret = TEE_ERROR_NOT_IMPLEMENTED;
+}
+#endif
+
void *optee_alloc_and_init_page_list(void *buf, ulong len, u64 *phys_buf_ptr);
#endif /* __OPTEE_PRIVATE_H */
diff --git a/drivers/tee/optee/supplicant.c b/drivers/tee/optee/supplicant.c
index ae042b9a20..f7738983cd 100644
--- a/drivers/tee/optee/supplicant.c
+++ b/drivers/tee/optee/supplicant.c
@@ -89,6 +89,9 @@ void optee_suppl_cmd(struct udevice *dev, struct tee_shm *shm_arg,
case OPTEE_MSG_RPC_CMD_RPMB:
optee_suppl_cmd_rpmb(dev, arg);
break;
+ case OPTEE_MSG_RPC_CMD_I2C_TRANSFER:
+ optee_suppl_cmd_i2c_transfer(dev, arg);
+ break;
default:
arg->ret = TEE_ERROR_NOT_IMPLEMENTED;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCHv2] drivers: tee: i2c trampoline driver
2020-12-28 12:17 [PATCHv2] drivers: tee: i2c trampoline driver Jorge Ramirez-Ortiz
@ 2020-12-29 3:32 ` Simon Glass
0 siblings, 0 replies; 3+ messages in thread
From: Simon Glass @ 2020-12-29 3:32 UTC (permalink / raw)
To: u-boot
hI Jorge,
On Mon, 28 Dec 2020 at 05:17, Jorge Ramirez-Ortiz <jorge@foundries.io> wrote:
>
> This commit gives the secure world access to the I2C bus so it can
> communicate with I2C slaves (tipically those would be secure elements
> like the NXP SE050).
>
> Signed-off-by: Jorge Ramirez-Ortiz <jorge@foundries.io>
> ---
> drivers/tee/optee/Makefile | 1 +
> drivers/tee/optee/i2c.c | 88 ++++++++++++++++++++++++
> drivers/tee/optee/optee_msg.h | 21 ++++++
> drivers/tee/optee/optee_msg_supplicant.h | 5 ++
> drivers/tee/optee/optee_private.h | 12 ++++
> drivers/tee/optee/supplicant.c | 3 +
> 6 files changed, 130 insertions(+)
> create mode 100644 drivers/tee/optee/i2c.c
I think you missed the change log.
Also please see my comment in the original patch about a test for optee.
Regards,
Simo
n
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCHv2] drivers: tee: i2c trampoline driver
@ 2021-01-06 18:38 Jorge Ramirez-Ortiz
0 siblings, 0 replies; 3+ messages in thread
From: Jorge Ramirez-Ortiz @ 2021-01-06 18:38 UTC (permalink / raw)
To: u-boot
This commit gives the secure world access to the I2C bus so it can
communicate with I2C slaves (typically those would be secure elements
like the NXP SE050).
A similar service implementation has been merged in linux:
c05210ab ("drivers: optee: allow op-tee to access devices on the i2c
bus")
Signed-off-by: Jorge Ramirez-Ortiz <jorge@foundries.io>
---
drivers/tee/optee/Makefile | 1 +
drivers/tee/optee/i2c.c | 90 ++++++++++++++++++++++++
drivers/tee/optee/optee_msg.h | 21 ++++++
drivers/tee/optee/optee_msg_supplicant.h | 5 ++
drivers/tee/optee/optee_private.h | 17 +++++
drivers/tee/optee/supplicant.c | 3 +
6 files changed, 137 insertions(+)
create mode 100644 drivers/tee/optee/i2c.c
diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
index 928d3f8002..068c6e7aa1 100644
--- a/drivers/tee/optee/Makefile
+++ b/drivers/tee/optee/Makefile
@@ -2,4 +2,5 @@
obj-y += core.o
obj-y += supplicant.o
+obj-$(CONFIG_DM_I2C) += i2c.o
obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
diff --git a/drivers/tee/optee/i2c.c b/drivers/tee/optee/i2c.c
new file mode 100644
index 0000000000..a751e54c4c
--- /dev/null
+++ b/drivers/tee/optee/i2c.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (c) 2020 Foundries.io Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <i2c.h>
+#include <tee.h>
+#include "optee_msg.h"
+#include "optee_private.h"
+
+static int check_xfer_flags(struct udevice *chip, int tee_flags)
+{
+ int flags;
+ int ret;
+
+ ret = i2c_get_chip_flags(chip, &flags);
+ if (ret)
+ return ret;
+
+ if (tee_flags & OPTEE_MSG_RPC_CMD_I2C_FLAGS_TEN_BIT) {
+ if (!(flags & DM_I2C_CHIP_10BIT))
+ return -EINVAL;
+ } else {
+ if (flags & DM_I2C_CHIP_10BIT)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void optee_suppl_cmd_i2c_transfer(struct optee_msg_arg *arg)
+{
+ const u8 attr[] = {
+ OPTEE_MSG_ATTR_TYPE_VALUE_INPUT,
+ OPTEE_MSG_ATTR_TYPE_VALUE_INPUT,
+ OPTEE_MSG_ATTR_TYPE_RMEM_INOUT,
+ OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT,
+ };
+ struct udevice *chip_dev;
+ struct tee_shm *shm;
+ u8 *buf;
+ int ret;
+
+ if (arg->num_params != ARRAY_SIZE(attr) ||
+ arg->params[0].attr != attr[0] ||
+ arg->params[1].attr != attr[1] ||
+ arg->params[2].attr != attr[2] ||
+ arg->params[3].attr != attr[3]) {
+ goto bad;
+ }
+
+ shm = (struct tee_shm *)(unsigned long)arg->params[2].u.rmem.shm_ref;
+ buf = shm->addr;
+ if (!buf)
+ goto bad;
+
+ if (i2c_get_chip_for_busnum((int)arg->params[0].u.value.b,
+ (int)arg->params[0].u.value.c,
+ 0, &chip_dev))
+ goto bad;
+
+ if (check_xfer_flags(chip_dev, arg->params[1].u.value.a))
+ goto bad;
+
+ switch (arg->params[0].u.value.a) {
+ case OPTEE_MSG_RPC_CMD_I2C_TRANSFER_RD:
+ ret = dm_i2c_read(chip_dev, 0, buf,
+ (size_t)arg->params[2].u.rmem.size);
+ break;
+ case OPTEE_MSG_RPC_CMD_I2C_TRANSFER_WR:
+ ret = dm_i2c_write(chip_dev, 0, buf,
+ (size_t)arg->params[2].u.rmem.size);
+ break;
+ default:
+ goto bad;
+ }
+
+ if (ret) {
+ arg->ret = TEE_ERROR_COMMUNICATION;
+ } else {
+ arg->params[3].u.value.a = arg->params[2].u.rmem.size;
+ arg->ret = TEE_SUCCESS;
+ }
+
+ return;
+bad:
+ arg->ret = TEE_ERROR_BAD_PARAMETERS;
+}
diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h
index 24c60960fc..8d40ce60c2 100644
--- a/drivers/tee/optee/optee_msg.h
+++ b/drivers/tee/optee/optee_msg.h
@@ -422,4 +422,25 @@ struct optee_msg_arg {
*/
#define OPTEE_MSG_RPC_CMD_SHM_FREE 7
+/*
+ * Access a device on an i2c bus
+ *
+ * [in] param[0].u.value.a mode: RD(0), WR(1)
+ * [in] param[0].u.value.b i2c adapter
+ * [in] param[0].u.value.c i2c chip
+ *
+ * [in] param[1].u.value.a i2c control flags
+ *
+ * [in/out] memref[2] buffer to exchange the transfer data
+ * with the secure world
+ *
+ * [out] param[3].u.value.a bytes transferred by the driver
+ */
+#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER 21
+/* I2C master transfer modes */
+#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER_RD 0
+#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER_WR 1
+/* I2C master control flags */
+#define OPTEE_MSG_RPC_CMD_I2C_FLAGS_TEN_BIT BIT(0)
+
#endif /* _OPTEE_MSG_H */
diff --git a/drivers/tee/optee/optee_msg_supplicant.h b/drivers/tee/optee/optee_msg_supplicant.h
index a0fb8063c8..963cfd4782 100644
--- a/drivers/tee/optee/optee_msg_supplicant.h
+++ b/drivers/tee/optee/optee_msg_supplicant.h
@@ -147,6 +147,11 @@
#define OPTEE_MSG_RPC_CMD_SHM_ALLOC 6
#define OPTEE_MSG_RPC_CMD_SHM_FREE 7
+/*
+ * I2C bus access
+ */
+#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER 21
+
/*
* Was OPTEE_MSG_RPC_CMD_SQL_FS, which isn't supported any longer
*/
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 9442d1c176..1f07a27ee4 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -60,6 +60,23 @@ static inline void optee_suppl_rpmb_release(struct udevice *dev)
}
#endif
+#ifdef CONFIG_DM_I2C
+/**
+ * optee_suppl_cmd_i2c_transfer() - route I2C requests to an I2C chip
+ * @arg: OP-TEE message (layout specified in optee_msg.h) defining the
+ * transfer mode (read/write), adapter, chip and control flags.
+ *
+ * Handles OP-TEE requests to transfer data to the I2C chip on the I2C adapter.
+ */
+void optee_suppl_cmd_i2c_transfer(struct optee_msg_arg *arg);
+#else
+static inline void optee_suppl_cmd_i2c_transfer(struct optee_msg_arg *arg)
+{
+ debug("OPTEE_MSG_RPC_CMD_I2C_TRANSFER not implemented\n");
+ arg->ret = TEE_ERROR_NOT_IMPLEMENTED;
+}
+#endif
+
void *optee_alloc_and_init_page_list(void *buf, ulong len, u64 *phys_buf_ptr);
#endif /* __OPTEE_PRIVATE_H */
diff --git a/drivers/tee/optee/supplicant.c b/drivers/tee/optee/supplicant.c
index ae042b9a20..f9dd874b59 100644
--- a/drivers/tee/optee/supplicant.c
+++ b/drivers/tee/optee/supplicant.c
@@ -89,6 +89,9 @@ void optee_suppl_cmd(struct udevice *dev, struct tee_shm *shm_arg,
case OPTEE_MSG_RPC_CMD_RPMB:
optee_suppl_cmd_rpmb(dev, arg);
break;
+ case OPTEE_MSG_RPC_CMD_I2C_TRANSFER:
+ optee_suppl_cmd_i2c_transfer(arg);
+ break;
default:
arg->ret = TEE_ERROR_NOT_IMPLEMENTED;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-01-06 18:38 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-28 12:17 [PATCHv2] drivers: tee: i2c trampoline driver Jorge Ramirez-Ortiz
2020-12-29 3:32 ` Simon Glass
2021-01-06 18:38 Jorge Ramirez-Ortiz
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.