1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * The 'exception' command can be used for testing exception handling. 4 * 5 * Copyright (c) 2018, Heinrich Schuchardt <xypron.glpk@gmx.de> 6 */ 7 8#include <common.h> 9#include <command.h> 10#include <linux/bitops.h> 11 12static int do_undefined(struct cmd_tbl *cmdtp, int flag, int argc, 13 char *const argv[]) 14{ 15 /* 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") 19 */ 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 33static 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 64static int do_breakpoint(struct cmd_tbl *cmdtp, int flag, int argc, 65 char *const argv[]) 66{ 67 asm volatile ("brk #123\n"); 68 69 return CMD_RET_FAILURE; 70} 71 72static 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 "", ""), 77 U_BOOT_CMD_MKENT(undefined, CONFIG_SYS_MAXARGS, 1, do_undefined, 78 "", ""), 79}; 80 81static char exception_help_text[] = 82 "<ex>\n" 83 " The following exceptions are available:\n" 84 " breakpoint - breakpoint instruction exception\n" 85 " unaligned - unaligned LDAR data abort\n" 86 " undefined - undefined instruction exception\n" 87 ; 88 89#include <exception.h> 90