From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Viacheslav Bocharov Date: Tue, 31 Oct 2023 12:16:43 +0300 Subject: Add some amlogic sm functions --- arch/arm/include/asm/arch-meson/sm.h | 18 ++++ arch/arm/mach-meson/sm.c | 41 ++++++++ cmd/meson/sm.c | 49 +++++++++- drivers/sm/meson-sm.c | 1 + include/meson/sm.h | 1 + 5 files changed, 109 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/arch-meson/sm.h b/arch/arm/include/asm/arch-meson/sm.h index 111111111111..222222222222 100644 --- a/arch/arm/include/asm/arch-meson/sm.h +++ b/arch/arm/include/asm/arch-meson/sm.h @@ -26,7 +26,16 @@ 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); +/** + * meson_sm_getmax - get max size of user efuse + * @buffer: pointer to buffer + * @size: buffer size + * @return: size of user efuse or -errno on failure + */ +ssize_t meson_sm_getmax(void *buffer, size_t size); + #define SM_SERIAL_SIZE 12 +#define SM_SERIAL2_SIZE 16 /** * meson_sm_get_serial - read chip unique id into buffer @@ -37,6 +46,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_serial2 - read chip unique id (ver.2) into buffer + * + * @buffer: pointer to buffer + * @size: buffer size. + * @return: zero on success or -errno on failure + */ +int meson_sm_get_serial2(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 111111111111..222222222222 100644 --- a/arch/arm/mach-meson/sm.c +++ b/arch/arm/mach-meson/sm.c @@ -77,7 +77,26 @@ ssize_t meson_sm_write_efuse(uintptr_t offset, void *buffer, size_t size) return err; } +ssize_t meson_sm_getmax(void *buffer, size_t size) +{ + struct udevice *dev; + struct pt_regs regs = { 0 }; + int err; + + dev = meson_get_sm_device(); + if (IS_ERR(dev)) + return PTR_ERR(dev); + + err = sm_call_read(dev, buffer, size, + MESON_SMC_CMD_EFUSE_MAX, ®s); + if (err < 0) + pr_err("Failed to read max size of efuse memory (%d)\n", err); + + return err; +} + #define SM_CHIP_ID_LENGTH 119 +#define SM_CHIP_ID_LENGTH2 128 #define SM_CHIP_ID_OFFSET 4 #define SM_CHIP_ID_SIZE 12 @@ -102,6 +121,28 @@ int meson_sm_get_serial(void *buffer, size_t size) return 0; } +int meson_sm_get_serial2(void *buffer, size_t size) +{ + struct udevice *dev; + struct pt_regs regs = { 0 }; + regs.regs[1] = 2; + u8 id_buffer[SM_CHIP_ID_LENGTH2]; + int err; + + dev = meson_get_sm_device(); + if (IS_ERR(dev)) + return PTR_ERR(dev); + + 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 serial number (%d)\n", err); + + memcpy(buffer, id_buffer + SM_CHIP_ID_OFFSET, 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 111111111111..222222222222 100644 --- a/cmd/meson/sm.c +++ b/cmd/meson/sm.c @@ -33,6 +33,25 @@ static int do_sm_serial(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_SUCCESS; } +static int do_sm_serialv2(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_serial2((void *)address, SM_SERIAL2_SIZE); + if (ret) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + + #define MAX_REBOOT_REASONS 14 static const char *reboot_reasons[MAX_REBOOT_REASONS] = { @@ -152,12 +171,38 @@ free_buffer: return ret; } +static int do_efuse_getmax(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + char efusesizeprint[32]; // this covers int64 (2^64), which is 20 digits long + char *destarg = NULL; + int efusesize; + + if (argc > 1) + destarg = argv[1]; + + efusesize = meson_sm_getmax(NULL, 0); // TODO: check if this is correct + if (efusesize < 0) + return CMD_RET_FAILURE; + + snprintf(efusesizeprint, sizeof(efusesizeprint), "%d", efusesize); + if (destarg) + env_set(destarg, efusesizeprint); + else + printf("%s\n", efusesizeprint); + + return CMD_RET_SUCCESS; +} + static struct cmd_tbl cmd_sm_sub[] = { U_BOOT_CMD_MKENT(serial, 2, 1, do_sm_serial, "", ""), + U_BOOT_CMD_MKENT(serialv2, 2, 1, do_sm_serialv2, "", ""), 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, "", ""), U_BOOT_CMD_MKENT(efusedump, 3, 1, do_efuse_dump, "", ""), + U_BOOT_CMD_MKENT(getmax, 2, 1, do_efuse_getmax, "", ""), + }; static int do_sm(struct cmd_tbl *cmdtp, int flag, int argc, @@ -184,8 +229,10 @@ U_BOOT_CMD( sm, 5, 0, do_sm, "Secure Monitor Control", "serial
- read chip unique id to memory address\n" + "serialv2
- read chip unique id (ver 2) to memory address\n" "sm reboot_reason [name] - get reboot reason and store to environment\n" "sm efuseread
- read efuse to memory address\n" "sm efusewrite
- write into efuse from memory address\n" - "sm efusedump - dump efuse data range to console" + "sm efusedump - dump efuse data range to console\n" + "sm getmax [name] - get max size of user accesible efuse and store to environment\n" ); diff --git a/drivers/sm/meson-sm.c b/drivers/sm/meson-sm.c index 111111111111..222222222222 100644 --- a/drivers/sm/meson-sm.c +++ b/drivers/sm/meson-sm.c @@ -167,6 +167,7 @@ static const struct meson_sm_data meson_sm_gxbb_data = { .cmd_get_shmem_out = 0x82000021, .shmem_size = SZ_4K, .cmd = { + SET_CMD(MESON_SMC_CMD_EFUSE_MAX, 0x82000033), SET_CMD(MESON_SMC_CMD_EFUSE_READ, 0x82000030), SET_CMD(MESON_SMC_CMD_EFUSE_WRITE, 0x82000031), SET_CMD(MESON_SMC_CMD_CHIP_ID_GET, 0x82000044), diff --git a/include/meson/sm.h b/include/meson/sm.h index 111111111111..222222222222 100644 --- a/include/meson/sm.h +++ b/include/meson/sm.h @@ -9,6 +9,7 @@ #define __MESON_SM_CMD_H__ enum meson_smc_cmd { + MESON_SMC_CMD_EFUSE_MAX, /* get max size of user efuse */ MESON_SMC_CMD_EFUSE_READ, /* read efuse memory */ MESON_SMC_CMD_EFUSE_WRITE, /* write efuse memory */ MESON_SMC_CMD_CHIP_ID_GET, /* readh chip unique id */ -- Armbian