From: Nikita Maslo <n...@jethome.ru>

The Amlogic Meson SoC Secure Monitor implements a call to retrieve an
unique SoC ID starting from the GX Family and all new families.
But GX-family chips (e.g. GXB, GXL and newer) supports also 128-bit
chip ID. 128-bit chip ID consists 32-bit SoC version and 96-bit OTP data.

Add new subcommand "chipid" to Amlogic specific "sm" cmd to write the SoC
chip ID to memory.

Signed-off-by: Nikita Maslo <n...@jethome.ru>
Co-developed-by: Viacheslav Bocharov <ad...@lexina.in>
Signed-off-by: Viacheslav Bocharov <ad...@lexina.in>
---
 arch/arm/include/asm/arch-meson/sm.h | 12 ++++++++++-
 arch/arm/mach-meson/sm.c             | 32 +++++++++++++++++++++++++++-
 cmd/meson/sm.c                       | 22 ++++++++++++++++++-
 3 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/arch-meson/sm.h 
b/arch/arm/include/asm/arch-meson/sm.h
index 4b1d564bc48..812c5ed020a 100644
--- a/arch/arm/include/asm/arch-meson/sm.h
+++ b/arch/arm/include/asm/arch-meson/sm.h
@@ -27,9 +27,10 @@ ssize_t meson_sm_read_efuse(uintptr_t offset, void *buffer, 
size_t size);
 ssize_t meson_sm_write_efuse(uintptr_t offset, void *buffer, size_t size);
 
 #define SM_SERIAL_SIZE 12
+#define SM_CHIP_ID_SIZE        16
 
 /**
- * meson_sm_get_serial - read chip unique id into buffer
+ * meson_sm_get_serial - read chip unique serial into buffer
  *
  * @buffer: pointer to buffer
  * @size: buffer size.
@@ -37,6 +38,15 @@ ssize_t meson_sm_write_efuse(uintptr_t offset, void *buffer, 
size_t size);
  */
 int meson_sm_get_serial(void *buffer, size_t size);
 
+/**
+ * meson_sm_get_chip_id - read unique chip ID into buffer
+ *
+ * @buffer: pointer to buffer
+ * @size: buffer size.
+ * @return: zero on success or -errno on failure
+ */
+int meson_sm_get_chip_id(void *buffer, size_t size);
+
 enum {
        REBOOT_REASON_COLD = 0,
        REBOOT_REASON_NORMAL = 1,
diff --git a/arch/arm/mach-meson/sm.c b/arch/arm/mach-meson/sm.c
index 4d9f83d3b38..05d92f878d9 100644
--- a/arch/arm/mach-meson/sm.c
+++ b/arch/arm/mach-meson/sm.c
@@ -78,7 +78,6 @@ ssize_t meson_sm_write_efuse(uintptr_t offset, void *buffer, 
size_t size)
 
 #define SM_CHIP_ID_LENGTH      119
 #define SM_CHIP_ID_OFFSET      4
-#define SM_CHIP_ID_SIZE                12
 
 int meson_sm_get_serial(void *buffer, size_t size)
 {
@@ -101,6 +100,37 @@ int meson_sm_get_serial(void *buffer, size_t size)
        return 0;
 }
 
+int meson_sm_get_chip_id(void *buffer, size_t size)
+{
+       struct udevice *dev;
+       struct pt_regs regs = { 0 };
+       u8 id_buffer[SM_CHIP_ID_LENGTH];
+       int err;
+
+       dev = meson_get_sm_device();
+       if (IS_ERR(dev))
+               return PTR_ERR(dev);
+
+       regs.regs[1] = 2;
+       err = sm_call_read(dev, id_buffer, SM_CHIP_ID_LENGTH,
+                          MESON_SMC_CMD_CHIP_ID_GET, &regs);
+
+       if (err < 0) {
+               pr_err("Failed to read chipid (%d)\n", err);
+               return err;
+       }
+
+       if (((u32 *)id_buffer)[0] != 2) {
+               pr_err("Failed to read chipid: invalid chipid call version\n");
+               return -EINVAL;
+       }
+
+       memcpy(buffer, id_buffer + SM_CHIP_ID_OFFSET,
+              size > SM_CHIP_ID_LENGTH ? SM_CHIP_ID_LENGTH : size);
+
+       return 0;
+}
+
 #define AO_SEC_SD_CFG15                0xfc
 #define REBOOT_REASON_MASK     GENMASK(15, 12)
 
diff --git a/cmd/meson/sm.c b/cmd/meson/sm.c
index b69f8123ee2..21bfa58e507 100644
--- a/cmd/meson/sm.c
+++ b/cmd/meson/sm.c
@@ -33,6 +33,24 @@ static int do_sm_serial(struct cmd_tbl *cmdtp, int flag, int 
argc,
        return CMD_RET_SUCCESS;
 }
 
+static int do_sm_chip_id(struct cmd_tbl *cmdtp, int flag, int argc,
+                        char *const argv[])
+{
+       ulong address;
+       int ret;
+
+       if (argc < 2)
+               return CMD_RET_USAGE;
+
+       address = simple_strtoul(argv[1], NULL, 0);
+
+       ret = meson_sm_get_chip_id((void *)address, SM_CHIP_ID_SIZE);
+       if (ret)
+               return CMD_RET_FAILURE;
+
+       return CMD_RET_SUCCESS;
+}
+
 #define MAX_REBOOT_REASONS 14
 
 static const char *reboot_reasons[MAX_REBOOT_REASONS] = {
@@ -154,6 +172,7 @@ free_buffer:
 
 static struct cmd_tbl cmd_sm_sub[] = {
        U_BOOT_CMD_MKENT(serial, 2, 1, do_sm_serial, "", ""),
+       U_BOOT_CMD_MKENT(chipid, 2, 1, do_sm_chip_id, "", ""),
        U_BOOT_CMD_MKENT(reboot_reason, 1, 1, do_sm_reboot_reason, "", ""),
        U_BOOT_CMD_MKENT(efuseread, 4, 1, do_efuse_read, "", ""),
        U_BOOT_CMD_MKENT(efusewrite, 4, 0, do_efuse_write, "", ""),
@@ -183,7 +202,8 @@ static int do_sm(struct cmd_tbl *cmdtp, int flag, int argc,
 U_BOOT_CMD(
        sm, 5, 0, do_sm,
        "Secure Monitor Control",
-       "serial <address> - read chip unique id to memory address\n"
+       "serial <address> - read chip unique serial to memory address\n"
+       "sm chipid <address> - read unique chip id to memory address\n"
        "sm reboot_reason [name] - get reboot reason and store to environment\n"
        "sm efuseread <offset> <size> <address> - read efuse to memory 
address\n"
        "sm efusewrite <offset> <size> <address> - write into efuse from memory 
address\n"
-- 
2.48.1

Reply via email to