@@ -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(