Skip to content

Commit e7588d8

Browse files
Andre-ARMtrini
authored andcommitted
cmd: exception: arm64: fix undefined, add faults
The arm64 version of the exception command was just defining the undefined exception, but actually copied the AArch32 instruction. Replace that with an encoding that is guaranteed to be and stay undefined. Also add instructions to trigger unaligned access faults and a breakpoint. This brings ARM64 on par with ARM(32) for the exception command. Signed-off-by: Andre Przywara <[email protected]>
1 parent f861ffa commit e7588d8

File tree

1 file changed

+60
-4
lines changed

1 file changed

+60
-4
lines changed

cmd/arm/exception64.c

+60-4
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,83 @@
77

88
#include <common.h>
99
#include <command.h>
10+
#include <linux/bitops.h>
1011

1112
static int do_undefined(struct cmd_tbl *cmdtp, int flag, int argc,
1213
char *const argv[])
1314
{
1415
/*
15-
* 0xe7f...f. is undefined in ARM mode
16-
* 0xde.. is undefined in Thumb mode
16+
* Instructions starting with the upper 16 bits all 0 are permanently
17+
* undefined. The lower 16 bits can be used for some kind of immediate.
18+
* --- ARMv8 ARM (ARM DDI 0487G.a C6.2.339: "UDF")
1719
*/
18-
asm volatile (".word 0xe7f7defb\n");
20+
asm volatile (".word 0x00001234\n");
21+
22+
return CMD_RET_FAILURE;
23+
}
24+
25+
/*
26+
* The ID_AA64MMFR2_EL1 register name is only know to binutils for ARMv8.2
27+
* and later architecture revisions. However the register is valid regardless
28+
* of binutils architecture support or the core the code is running on, so
29+
* just use the generic encoding.
30+
*/
31+
#define ID_AA64MMFR2_EL1 "S3_0_C0_C7_2"
32+
33+
static int do_unaligned(struct cmd_tbl *cmdtp, int flag, int argc,
34+
char *const argv[])
35+
{
36+
uint64_t reg;
37+
38+
/*
39+
* The unaligned LDAR access below is only guaranteed to generate an
40+
* alignment fault on cores not implementing FEAT_LSE2. To avoid false
41+
* negatives, check this condition before we exectute LDAR.
42+
*/
43+
asm ("mrs %0, "ID_AA64MMFR2_EL1"\n" : "=r" (reg));
44+
if (reg & GENMASK(35, 32)) {
45+
printf("unaligned access check only supported on pre-v8.4 cores\n");
46+
return CMD_RET_FAILURE;
47+
}
48+
49+
/*
50+
* The load acquire instruction requires the data source to be
51+
* naturally aligned, and will fault even if strict alignment fault
52+
* checking is disabled (but only without FEAT_LSE2).
53+
* --- ARMv8 ARM (ARM DDI 0487G.a B2.5.2: "Alignment of data accesses")
54+
*/
55+
asm volatile (
56+
"mov x1, sp\n\t"
57+
"orr x1, x1, #3\n\t"
58+
"ldar x0, [x1]\n"
59+
::: "x0", "x1" );
60+
61+
return CMD_RET_FAILURE;
62+
}
63+
64+
static int do_breakpoint(struct cmd_tbl *cmdtp, int flag, int argc,
65+
char *const argv[])
66+
{
67+
asm volatile ("brk #123\n");
68+
1969
return CMD_RET_FAILURE;
2070
}
2171

2272
static struct cmd_tbl cmd_sub[] = {
73+
U_BOOT_CMD_MKENT(breakpoint, CONFIG_SYS_MAXARGS, 1, do_breakpoint,
74+
"", ""),
75+
U_BOOT_CMD_MKENT(unaligned, CONFIG_SYS_MAXARGS, 1, do_unaligned,
76+
"", ""),
2377
U_BOOT_CMD_MKENT(undefined, CONFIG_SYS_MAXARGS, 1, do_undefined,
2478
"", ""),
2579
};
2680

2781
static char exception_help_text[] =
2882
"<ex>\n"
2983
" The following exceptions are available:\n"
30-
" undefined - undefined instruction\n"
84+
" breakpoint - breakpoint instruction exception\n"
85+
" unaligned - unaligned LDAR data abort\n"
86+
" undefined - undefined instruction exception\n"
3187
;
3288

3389
#include <exception.h>

0 commit comments

Comments
 (0)