1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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"
);
|