summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Tomsich <philipp.tomsich@theobroma-systems.com>2017-02-16 12:56:18 +0100
committerPhilipp Tomsich <philipp.tomsich@theobroma-systems.com>2017-03-09 01:40:23 +0100
commite1a93744c44ec66bb7d333acaaf0413d8cee2af8 (patch)
tree0c52531d8a419037a846ac3147a9ee315caed380
parent5a03643bb7baee556fa3c1fb971c67b834e83d2d (diff)
[do not upstream] axp/smc commands for Klaus
-rw-r--r--cmd/Makefile3
-rw-r--r--cmd/smc.c116
2 files changed, 119 insertions, 0 deletions
diff --git a/cmd/Makefile b/cmd/Makefile
index f13bb8c11e..29bdde0797 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -165,6 +165,9 @@ obj-$(CONFIG_CMD_BLOB) += blob.o
# core command
obj-y += nvedit.o
+# secure monitor call (for calling into the ARM Trusted Firmware)
+obj-y += smc.o
+
obj-$(CONFIG_ARCH_MVEBU) += mvebu/
filechk_data_gz = (echo "static const char data_gz[] ="; cat $< | scripts/bin2c; echo ";")
diff --git a/cmd/smc.c b/cmd/smc.c
new file mode 100644
index 0000000000..22f1cecb62
--- /dev/null
+++ b/cmd/smc.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2000-2009
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cli.h>
+#include <asm-offsets.h>
+#include <asm/system.h>
+
+#define ARM_STD_SVC_VERSION 0x8400ff03
+
+void atf_get_version(uint64_t* major, uint64_t* minor)
+{
+ struct pt_regs regs;
+
+ regs.regs[0] = ARM_STD_SVC_VERSION;
+
+ smc_call(&regs);
+
+ *major = regs.regs[0];
+ *minor = regs.regs[1];
+}
+
+#define SUNXI_SVC_BASE 0x83000000
+#define SUNXI_SVC_UID (SUNXI_SVC_BASE + 0xffff)
+#define SUNXI_SVC_GET_CPUCLOCK (SUNXI_SVC_BASE + 0)
+#define SUNXI_SVC_SET_CPUCLOCK (SUNXI_SVC_BASE + 1)
+#define SUNXI_SVC_AXP_READ_REG (SUNXI_SVC_BASE + 2)
+#define SUNXI_SVC_AXP_WRITE_REG (SUNXI_SVC_BASE + 3)
+
+int atf_sunxi_axp_read_reg(uint8_t address)
+{
+ struct pt_regs regs;
+
+ regs.regs[0] = SUNXI_SVC_AXP_READ_REG;
+ regs.regs[1] = address;
+
+ smc_call(&regs);
+
+ return regs.regs[0];
+}
+
+int atf_sunxi_axp_write_reg(uint8_t address, uint8_t value)
+{
+ struct pt_regs regs;
+
+ regs.regs[0] = SUNXI_SVC_AXP_WRITE_REG;
+ regs.regs[1] = address;
+ regs.regs[2] = value;
+
+ smc_call(&regs);
+
+ return regs.regs[0];
+}
+
+static int do_smc_axp(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+{
+ int reg, val;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ if (argc < 3) {
+ reg = simple_strtoul(argv[1], NULL, 16);
+ printf ("axp reg %x reads %x\n", reg, atf_sunxi_axp_read_reg(reg));
+ return 0;
+ } else {
+ reg = simple_strtoul(argv[1], NULL, 16);
+ val = simple_strtoul(argv[2], NULL, 16);
+ printf("axp reg %x write %x returns %d\n",
+ reg, val, atf_sunxi_axp_write_reg(reg, val));
+ }
+ return 0;
+}
+
+static int do_smc_version(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+{
+ uint64_t major, minor;
+ atf_get_version(&major, &minor);
+ printf("ATF version: %ld.%ld\n", major, minor);
+ return 0;
+}
+
+static cmd_tbl_t cmd_smc_sub[] = {
+ U_BOOT_CMD_MKENT(version, 0, 1, do_smc_version, "", ""),
+ U_BOOT_CMD_MKENT(axp, 2, 1, do_smc_axp, "", ""),
+};
+
+static int do_smc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ cmd_tbl_t *c;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ /* Strip off leading 'smc' command argument */
+ argc--;
+ argv++;
+
+ c = find_cmd_tbl(argv[0], &cmd_smc_sub[0], ARRAY_SIZE(cmd_smc_sub));
+ if (c)
+ return c->cmd(cmdtp, flag, argc, argv);
+
+ return CMD_RET_USAGE;
+}
+
+U_BOOT_CMD(
+ smc, 4, 1, do_smc,
+ "Secure monitor call (TSD test infrastructure)",
+ "version - show the ATF version\n"
+ "smc axp reg [value] - read/write a register in the AXP803\n"
+);