mirror of
https://github.com/armbian/build.git
synced 2025-08-19 05:21:09 +02:00
219 lines
6.5 KiB
Diff
219 lines
6.5 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Viacheslav Bocharov <adeep@lexina.in>
|
|
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 <address> - read chip unique id to memory address\n"
|
|
+ "serialv2 <address> - read chip unique id (ver 2) 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"
|
|
- "sm efusedump <offset> <size> - dump efuse data range to console"
|
|
+ "sm efusedump <offset> <size> - 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
|
|
|