summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYe Li <ye.li@nxp.com>2022-09-05 13:14:00 +0800
committerYe Li <ye.li@nxp.com>2022-10-10 15:08:15 +0800
commit63d0579f39778e835bdf13da8e42fceb929f5604 (patch)
tree4dbba4ab38081eee90a53fb69c8eb86eec8457b4
parent266dddae454a9cc95f0ee08da423f63c030f9d64 (diff)
LFU-410 imx: ele_ahab: Add ahab_sec_fuse_prog command
Add ahab_sec_fuse_prog command to support burn secure fuse, for example the system ROM patch. Before running the command, user needs to sign the fuse container in format mentioned in ELE API and have loaded the container to specified address passed to ahab_sec_fuse_prog Signed-off-by: Ye Li <ye.li@nxp.com> Acked-by: Peng Fan <peng.fan@nxp.com>
-rw-r--r--arch/arm/include/asm/mach-imx/s400_api.h2
-rw-r--r--arch/arm/mach-imx/ele_ahab.c39
-rw-r--r--drivers/misc/sentinel/s400_api.c31
3 files changed, 72 insertions, 0 deletions
diff --git a/arch/arm/include/asm/mach-imx/s400_api.h b/arch/arm/include/asm/mach-imx/s400_api.h
index 539b1d16bbc..3862c5a39b8 100644
--- a/arch/arm/include/asm/mach-imx/s400_api.h
+++ b/arch/arm/include/asm/mach-imx/s400_api.h
@@ -147,4 +147,6 @@ int ahab_get_events(u32 *events, u32 *events_cnt, u32 *response);
int ahab_start_rng(void);
int ahab_generate_dek_blob(u32 key_id, u32 src_paddr, u32 dst_paddr,
u32 max_output_size);
+int ahab_write_secure_fuse(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 6daa7a96a04..192f90e6b1b 100644
--- a/arch/arm/mach-imx/ele_ahab.c
+++ b/arch/arm/mach-imx/ele_ahab.c
@@ -568,6 +568,39 @@ static int do_ahab_status(struct cmd_tbl *cmdtp, int flag, int argc,
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 = simple_strtoul(argv[1], NULL, 16);
+ 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 (ahab_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;
+}
+
+
U_BOOT_CMD(auth_cntr, CONFIG_SYS_MAXARGS, 1, do_authenticate,
"autenticate OS container via AHAB",
"addr\n"
@@ -588,3 +621,9 @@ 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"
+);
diff --git a/drivers/misc/sentinel/s400_api.c b/drivers/misc/sentinel/s400_api.c
index 8ac17890b46..baab9b2c9b0 100644
--- a/drivers/misc/sentinel/s400_api.c
+++ b/drivers/misc/sentinel/s400_api.c
@@ -561,3 +561,34 @@ int ahab_generate_dek_blob(u32 key_id, u32 src_paddr, u32 dst_paddr,
return ret;
}
+
+int ahab_write_secure_fuse(ulong signed_msg_blk, u32 *response)
+{
+ struct udevice *dev = gd->arch.s400_dev;
+ int size = sizeof(struct sentinel_msg);
+ struct sentinel_msg msg;
+ int ret;
+
+ if (!dev) {
+ printf("s400 dev is not initialized\n");
+ return -ENODEV;
+ }
+
+ msg.version = AHAB_VERSION;
+ msg.tag = AHAB_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;
+}