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, ®s); + + 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