diff options
author | Philipp Tomsich <philipp.tomsich@theobroma-systems.com> | 2017-02-16 12:56:18 +0100 |
---|---|---|
committer | Philipp Tomsich <philipp.tomsich@theobroma-systems.com> | 2017-03-09 01:40:23 +0100 |
commit | e1a93744c44ec66bb7d333acaaf0413d8cee2af8 (patch) | |
tree | 0c52531d8a419037a846ac3147a9ee315caed380 | |
parent | 5a03643bb7baee556fa3c1fb971c67b834e83d2d (diff) |
[do not upstream] axp/smc commands for Klaus
-rw-r--r-- | cmd/Makefile | 3 | ||||
-rw-r--r-- | cmd/smc.c | 116 |
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(®s); + + *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(®s); + + 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(®s); + + 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" +); |