From: Lukas Funke <lukas.fu...@weidmueller.com>

Add subcommands to read/write eFuses using u-boot. The subcommands
through the 'zynqmp' command.

Example:

=> zynqmp efuse_read 0xc 0xc
00000000: 85 36 b1 3c 34 f2 3b 01 00 00 00 40              .f.<D.:....@

Signed-off-by: Lukas Funke <lukas.fu...@weidmueller.com>
---

 board/xilinx/zynqmp/cmds.c | 101 +++++++++++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)

diff --git a/board/xilinx/zynqmp/cmds.c b/board/xilinx/zynqmp/cmds.c
index bf39c5472ea..e8d70ffecd6 100644
--- a/board/xilinx/zynqmp/cmds.c
+++ b/board/xilinx/zynqmp/cmds.c
@@ -16,6 +16,9 @@
 #include <asm/arch/sys_proto.h>
 #include <asm/io.h>
 #include <mach/zynqmp_aes.h>
+#include <misc.h>
+#include <hexdump.h>
+#include <dm.h>
 
 static int do_zynqmp_verify_secure(struct cmd_tbl *cmdtp, int flag, int argc,
                                   char *const argv[])
@@ -340,6 +343,99 @@ static int do_zynqmp_sha3(struct cmd_tbl *cmdtp, int flag,
        return CMD_RET_SUCCESS;
 }
 
+static int do_zynqmp_efuse_read(struct cmd_tbl *cmdtp, int flag,
+                               int argc, char * const argv[])
+{
+       struct udevice *dev;
+       u32 offset, len;
+       u8 buf[32];
+       int ret;
+
+       if (!CONFIG_IS_ENABLED(ZYNQMP_EFUSE)) {
+               printf("Failed: not supported\n");
+               return CMD_RET_FAILURE;
+       }
+
+       if (argc > cmdtp->maxargs || argc < (cmdtp->maxargs - 1))
+               return CMD_RET_USAGE;
+
+       memset(buf, 0, sizeof(buf));
+
+       offset = hextoul(argv[2], NULL);
+       len = hextoul(argv[3], NULL);
+
+       if (len > sizeof(buf)) {
+               printf("Failed: length exceeds buffer size");
+               return CMD_RET_FAILURE;
+       }
+
+       ret = uclass_get_device_by_driver(UCLASS_MISC,
+                                         DM_DRIVER_GET(zynqmp_efuse), &dev);
+       if (ret) {
+               printf("Failed to initialize zynqmp_efuse: %d\n", ret);
+               return CMD_RET_FAILURE;
+       }
+
+       ret = misc_read(dev, offset, (void *)buf, len);
+       if (ret) {
+               printf("Failed: cannot read efuse at 0x%x, errocode %d\n",
+                      offset, ret);
+               return CMD_RET_FAILURE;
+       }
+
+       if (CONFIG_IS_ENABLED(HEXDUMP))
+               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len);
+
+       return CMD_RET_SUCCESS;
+}
+
+static int do_zynqmp_efuse_write(struct cmd_tbl *cmdtp, int flag,
+                                int argc, char * const argv[])
+{
+       struct udevice *dev;
+       u64 value;
+       u32 offset, len;
+       u8 buf[sizeof(u64)];
+       int ret;
+
+       if (!CONFIG_IS_ENABLED(ZYNQMP_EFUSE)) {
+               printf("Failed: not supported\n");
+               return CMD_RET_FAILURE;
+       }
+
+       if (argc > cmdtp->maxargs || argc < (cmdtp->maxargs - 1))
+               return CMD_RET_USAGE;
+
+       memset(buf, 0, sizeof(buf));
+
+       offset = hextoul(argv[2], NULL);
+       len = hextoul(argv[3], NULL);
+
+       if (len <= sizeof(u64)) {
+               value = hextoul(argv[4], NULL);
+               memcpy(buf, &value, sizeof(value));
+       } else {
+               printf("Cannot write more than %zu byte to efuse\n", 
sizeof(u64));
+               return CMD_RET_FAILURE;
+       }
+
+       ret = uclass_get_device_by_driver(UCLASS_MISC,
+                                         DM_DRIVER_GET(zynqmp_efuse), &dev);
+       if (ret) {
+               printf("Failed to initialize zynqmp_efuse: %d\n", ret);
+               return CMD_RET_FAILURE;
+       }
+
+       ret = misc_write(dev, offset, (void *)buf, sizeof(buf));
+       if (ret) {
+               printf("Failed: cannot read efuse at 0x%x, errocode 0x%x\n",
+                      offset, ret);
+               return CMD_RET_FAILURE;
+       }
+
+       return CMD_RET_SUCCESS;
+}
+
 static struct cmd_tbl cmd_zynqmp_sub[] = {
        U_BOOT_CMD_MKENT(secure, 5, 0, do_zynqmp_verify_secure, "", ""),
        U_BOOT_CMD_MKENT(pmufw, 4, 0, do_zynqmp_pmufw, "", ""),
@@ -348,6 +444,8 @@ static struct cmd_tbl cmd_zynqmp_sub[] = {
        U_BOOT_CMD_MKENT(aes, 9, 0, do_zynqmp_aes, "", ""),
        U_BOOT_CMD_MKENT(rsa, 7, 0, do_zynqmp_rsa, "", ""),
        U_BOOT_CMD_MKENT(sha3, 5, 0, do_zynqmp_sha3, "", ""),
+       U_BOOT_CMD_MKENT(efuse_read, 4, 0, do_zynqmp_efuse_read, "", ""),
+       U_BOOT_CMD_MKENT(efuse_write, 5, 0, do_zynqmp_efuse_write, "", ""),
 #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
        U_BOOT_CMD_MKENT(tcminit, 3, 0, do_zynqmp_tcm_init, "", ""),
 #endif
@@ -422,6 +520,9 @@ U_BOOT_LONGHELP(zynqmp,
        "       48 bytes hash value into srcaddr\n"
        "       Optional key_addr can be specified for saving sha3 hash value\n"
        "       Note: srcaddr/srclen should not be 0\n"
+       "zynqmp efuse_read offset len - read efuse at given offset\n"
+       "zynqmp efuse_write offset len value - write value of length <len>\n"
+       "                      to efuse at given offset\n"
        );
 
 U_BOOT_CMD(
-- 
2.30.2

Reply via email to