diff mbox series

[11/30] imx: ele_api: support program secure fuse and return lifecycle

Message ID 20230602064607.17222-12-peng.fan@oss.nxp.com
State Superseded
Delegated to: Stefano Babic
Headers show
Series imx: misc update and fix | expand

Commit Message

Peng Fan (OSS) June 2, 2023, 6:45 a.m. UTC
From: Peng Fan <peng.fan@nxp.com>

Add two ELE API: ele_return_lifecycle_update and ele_write_secure_fuse
Add two cmd: ahab_return_lifecycle and ahab_sec_fuse_prog

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/include/asm/mach-imx/ele_api.h |  2 +
 arch/arm/mach-imx/ele_ahab.c            | 74 +++++++++++++++++++++++++
 drivers/misc/imx_ele/ele_api.c          | 64 ++++++++++++++++++++-
 3 files changed, 139 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/arch/arm/include/asm/mach-imx/ele_api.h b/arch/arm/include/asm/mach-imx/ele_api.h
index 120da0854e4..477cfe73ab0 100644
--- a/arch/arm/include/asm/mach-imx/ele_api.h
+++ b/arch/arm/include/asm/mach-imx/ele_api.h
@@ -146,5 +146,7 @@  int ele_dump_buffer(u32 *buffer, u32 buffer_length);
 int ele_get_info(struct ele_get_info_data *info, u32 *response);
 int ele_get_fw_status(u32 *status, u32 *response);
 int ele_release_m33_trout(void);
+int ele_write_secure_fuse(ulong signed_msg_blk, u32 *response);
+int ele_return_lifecycle_update(ulong signed_msg_blk, u32 *response);
 
 #endif
diff --git a/arch/arm/mach-imx/ele_ahab.c b/arch/arm/mach-imx/ele_ahab.c
index 5f23486304c..785b0d6ec3c 100644
--- a/arch/arm/mach-imx/ele_ahab.c
+++ b/arch/arm/mach-imx/ele_ahab.c
@@ -563,6 +563,68 @@  static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc, char *const
 	return 0;
 }
 
+static int do_sec_fuse_prog(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+	ulong addr;
+	u32 header, response;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	addr = hextoul(argv[1], NULL);
+	header = *(u32 *)addr;
+
+	if ((header & 0xff0000ff) != 0x89000000) {
+		printf("Wrong Signed message block format, header 0x%x\n", header);
+		return CMD_RET_FAILURE;
+	}
+
+	header = (header & 0xffff00) >> 8;
+
+	printf("Signed Message block at 0x%lx, size 0x%x\n", addr, header);
+	flush_dcache_range(addr, addr + header - 1);
+
+	if (ele_write_secure_fuse(addr, &response)) {
+		printf("Program secure fuse failed, response 0x%x\n", response);
+		return CMD_RET_FAILURE;
+	}
+
+	printf("Program secure fuse completed, response 0x%x\n", response);
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_ahab_return_lifecycle(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+	ulong addr;
+	u32 header, response;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	addr = hextoul(argv[1], NULL);
+	header = *(u32 *)addr;
+
+	if ((header & 0xff0000ff) != 0x89000000) {
+		printf("Wrong Signed message block format, header 0x%x\n", header);
+		return CMD_RET_FAILURE;
+	}
+
+	header = (header & 0xffff00) >> 8;
+
+	printf("Signed Message block at 0x%lx, size 0x%x\n", addr, header);
+	flush_dcache_range(addr, addr + header - 1);
+
+	if (ele_return_lifecycle_update(addr, &response)) {
+		printf("Return lifecycle failed, response 0x%x\n", response);
+		return CMD_RET_FAILURE;
+	}
+
+	printf("Return lifecycle completed, response 0x%x\n", response);
+
+	return CMD_RET_SUCCESS;
+}
+
 U_BOOT_CMD(auth_cntr, CONFIG_SYS_MAXARGS, 1, do_authenticate,
 	   "autenticate OS container via AHAB",
 	   "addr\n"
@@ -583,3 +645,15 @@  U_BOOT_CMD(ahab_status, CONFIG_SYS_MAXARGS, 1, do_ahab_status,
 	   "display AHAB lifecycle only",
 	   ""
 );
+
+U_BOOT_CMD(ahab_sec_fuse_prog, CONFIG_SYS_MAXARGS, 1, do_sec_fuse_prog,
+	   "Program secure fuse via signed message block",
+	   "addr\n"
+	   "addr - Signed message block for secure fuse\n"
+);
+
+U_BOOT_CMD(ahab_return_lifecycle, CONFIG_SYS_MAXARGS, 1, do_ahab_return_lifecycle,
+	   "Return lifecycle to OEM field return via signed message block",
+	   "addr\n"
+	   "addr - Return lifecycle message block signed by OEM SRK\n"
+);
diff --git a/drivers/misc/imx_ele/ele_api.c b/drivers/misc/imx_ele/ele_api.c
index 56605714f44..0ca0a94f08c 100644
--- a/drivers/misc/imx_ele/ele_api.c
+++ b/drivers/misc/imx_ele/ele_api.c
@@ -1,6 +1,6 @@ 
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright 2020 NXP
+ * Copyright 2020, 2023 NXP
  *
  */
 
@@ -490,3 +490,65 @@  int ele_get_events(u32 *events, u32 *events_cnt, u32 *response)
 
 	return ret;
 }
+
+int ele_write_secure_fuse(ulong signed_msg_blk, u32 *response)
+{
+	struct udevice *dev = gd->arch.ele_dev;
+	int size = sizeof(struct ele_msg);
+	struct ele_msg msg;
+	int ret;
+
+	if (!dev) {
+		printf("ele dev is not initialized\n");
+		return -ENODEV;
+	}
+
+	msg.version = ELE_VERSION;
+	msg.tag = ELE_CMD_TAG;
+	msg.size = 3;
+	msg.command = ELE_WRITE_SECURE_FUSE_REQ;
+
+	msg.data[0] = upper_32_bits(signed_msg_blk);
+	msg.data[1] = lower_32_bits(signed_msg_blk);
+
+	ret = misc_call(dev, false, &msg, size, &msg, size);
+	if (ret)
+		printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n",
+		       __func__, ret, msg.data[0], msg.data[1]);
+
+	if (response)
+		*response = msg.data[0];
+
+	return ret;
+}
+
+int ele_return_lifecycle_update(ulong signed_msg_blk, u32 *response)
+{
+	struct udevice *dev = gd->arch.ele_dev;
+	int size = sizeof(struct ele_msg);
+	struct ele_msg msg;
+	int ret;
+
+	if (!dev) {
+		printf("ele dev is not initialized\n");
+		return -ENODEV;
+	}
+
+	msg.version = ELE_VERSION;
+	msg.tag = ELE_CMD_TAG;
+	msg.size = 3;
+	msg.command = ELE_RET_LIFECYCLE_UP_REQ;
+
+	msg.data[0] = upper_32_bits(signed_msg_blk);
+	msg.data[1] = lower_32_bits(signed_msg_blk);
+
+	ret = misc_call(dev, false, &msg, size, &msg, size);
+	if (ret)
+		printf("Error: %s: ret %d, response 0x%x, failed fuse row index %u\n",
+		       __func__, ret, msg.data[0], msg.data[1]);
+
+	if (response)
+		*response = msg.data[0];
+
+	return ret;
+}