imx: ele_api: support program secure fuse and return lifecycle
authorPeng Fan <peng.fan@nxp.com>
Thu, 15 Jun 2023 10:09:08 +0000 (18:09 +0800)
committerStefano Babic <sbabic@denx.de>
Thu, 13 Jul 2023 09:29:40 +0000 (11:29 +0200)
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
arch/arm/mach-imx/ele_ahab.c
drivers/misc/imx_ele/ele_api.c

index 120da08..477cfe7 100644 (file)
@@ -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
index 5f23486..785b0d6 100644 (file)
@@ -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"
+);
index 5660571..0ca0a94 100644 (file)
@@ -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;
+}