aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeinrich Schuchardt <xypron.glpk@gmx.de>2018-12-26 17:20:35 +0100
committerTom Rini <trini@konsulko.com>2019-04-22 12:06:39 -0400
commitdab8788a8cadaa18a44001f98fa959fc672fff4f (patch)
tree2ede1f0e809092149aaa422970fe39721ed787b0
parentc986aa624b6a0a627f029b44945b60979e25d109 (diff)
downloadu-boot-dab8788a8cadaa18a44001f98fa959fc672fff4f.zip
u-boot-dab8788a8cadaa18a44001f98fa959fc672fff4f.tar.gz
u-boot-dab8788a8cadaa18a44001f98fa959fc672fff4f.tar.bz2
cmd: add exception command
The 'exception' command allows to test exception handling. This implementation supports ARM, x86, RISC-V and the following exceptions: * 'breakpoint' - prefetch abort exception (ARM 32bit only) * 'unaligned' - data abort exception (ARM only) * 'undefined' - undefined instruction exception Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
-rw-r--r--MAINTAINERS3
-rw-r--r--cmd/Kconfig6
-rw-r--r--cmd/Makefile2
-rw-r--r--cmd/arm/Makefile7
-rw-r--r--cmd/arm/exception.c61
-rw-r--r--cmd/arm/exception64.c33
-rw-r--r--cmd/riscv/Makefile3
-rw-r--r--cmd/riscv/exception.c29
-rw-r--r--cmd/x86/Makefile1
-rw-r--r--cmd/x86/exception.c29
-rw-r--r--include/exception.h58
11 files changed, 232 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index aa4b3bc..b9cb686 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -86,6 +86,7 @@ M: Albert Aribaud <albert.u.boot@aribaud.net>
S: Maintained
T: git git://git.denx.de/u-boot-arm.git
F: arch/arm/
+F: cmd/arm/
ARM ALTERA SOCFPGA
M: Marek Vasut <marex@denx.de>
@@ -677,6 +678,7 @@ M: Rick Chen <rick@andestech.com>
S: Maintained
T: git git://git.denx.de/u-boot-riscv.git
F: arch/riscv/
+F: cmd/riscv/
F: tools/prelink-riscv.c
ROCKUSB
@@ -788,6 +790,7 @@ M: Bin Meng <bmeng.cn@gmail.com>
S: Maintained
T: git git://git.denx.de/u-boot-x86.git
F: arch/x86/
+F: cmd/x86/
XTENSA
M: Max Filippov <jcmvbkbc@gmail.com>
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 2bdbfcb..5d1999e 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1433,6 +1433,12 @@ config CMD_EFIDEBUG
particularly for managing boot parameters as well as examining
various EFI status for debugging.
+config CMD_EXCEPTION
+ bool "exception - raise exception"
+ depends on ARM || RISCV || X86
+ help
+ Enable the 'exception' command which allows to raise an exception.
+
config CMD_LED
bool "led"
depends on LED
diff --git a/cmd/Makefile b/cmd/Makefile
index 6b1c6b0..7864fcf 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -173,6 +173,8 @@ obj-$(CONFIG_CMD_BLOB) += blob.o
# Android Verified Boot 2.0
obj-$(CONFIG_CMD_AVB) += avb.o
+obj-$(CONFIG_ARM) += arm/
+obj-$(CONFIG_RISCV) += riscv/
obj-$(CONFIG_X86) += x86/
obj-$(CONFIG_ARCH_MVEBU) += mvebu/
diff --git a/cmd/arm/Makefile b/cmd/arm/Makefile
new file mode 100644
index 0000000..94367dc
--- /dev/null
+++ b/cmd/arm/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+ifdef CONFIG_ARM64
+obj-$(CONFIG_CMD_EXCEPTION) += exception64.o
+else
+obj-$(CONFIG_CMD_EXCEPTION) += exception.o
+endif
diff --git a/cmd/arm/exception.c b/cmd/arm/exception.c
new file mode 100644
index 0000000..33bc759
--- /dev/null
+++ b/cmd/arm/exception.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * The 'exception' command can be used for testing exception handling.
+ *
+ * Copyright (c) 2018, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ */
+
+#include <common.h>
+#include <command.h>
+
+static int do_unaligned(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ /*
+ * The LDRD instruction requires the data source to be four byte aligned
+ * even if strict alignment fault checking is disabled in the system
+ * control register.
+ */
+ asm volatile (
+ "MOV r5, sp\n"
+ "ADD r5, #1\n"
+ "LDRD r6, r7, [r5]\n");
+ return CMD_RET_FAILURE;
+}
+
+static int do_breakpoint(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ asm volatile ("BKPT #123\n");
+ return CMD_RET_FAILURE;
+}
+
+static int do_undefined(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ /*
+ * 0xe7f...f. is undefined in ARM mode
+ * 0xde.. is undefined in Thumb mode
+ */
+ asm volatile (".word 0xe7f7defb\n");
+ return CMD_RET_FAILURE;
+}
+
+static cmd_tbl_t cmd_sub[] = {
+ U_BOOT_CMD_MKENT(breakpoint, CONFIG_SYS_MAXARGS, 1, do_breakpoint,
+ "", ""),
+ U_BOOT_CMD_MKENT(unaligned, CONFIG_SYS_MAXARGS, 1, do_unaligned,
+ "", ""),
+ U_BOOT_CMD_MKENT(undefined, CONFIG_SYS_MAXARGS, 1, do_undefined,
+ "", ""),
+};
+
+static char exception_help_text[] =
+ "<ex>\n"
+ " The following exceptions are available:\n"
+ " breakpoint - prefetch abort\n"
+ " unaligned - data abort\n"
+ " undefined - undefined instruction\n"
+ ;
+
+#include <exception.h>
diff --git a/cmd/arm/exception64.c b/cmd/arm/exception64.c
new file mode 100644
index 0000000..a363818
--- /dev/null
+++ b/cmd/arm/exception64.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * The 'exception' command can be used for testing exception handling.
+ *
+ * Copyright (c) 2018, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ */
+
+#include <common.h>
+#include <command.h>
+
+static int do_undefined(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ /*
+ * 0xe7f...f. is undefined in ARM mode
+ * 0xde.. is undefined in Thumb mode
+ */
+ asm volatile (".word 0xe7f7defb\n");
+ return CMD_RET_FAILURE;
+}
+
+static cmd_tbl_t cmd_sub[] = {
+ U_BOOT_CMD_MKENT(undefined, CONFIG_SYS_MAXARGS, 1, do_undefined,
+ "", ""),
+};
+
+static char exception_help_text[] =
+ "<ex>\n"
+ " The following exceptions are available:\n"
+ " undefined - undefined instruction\n"
+ ;
+
+#include <exception.h>
diff --git a/cmd/riscv/Makefile b/cmd/riscv/Makefile
new file mode 100644
index 0000000..24df023
--- /dev/null
+++ b/cmd/riscv/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-$(CONFIG_CMD_EXCEPTION) += exception.o
diff --git a/cmd/riscv/exception.c b/cmd/riscv/exception.c
new file mode 100644
index 0000000..547fb7d
--- /dev/null
+++ b/cmd/riscv/exception.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * The 'exception' command can be used for testing exception handling.
+ *
+ * Copyright (c) 2018, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ */
+
+#include <common.h>
+#include <command.h>
+
+static int do_undefined(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ asm volatile (".word 0xffffffff\n");
+ return CMD_RET_FAILURE;
+}
+
+static cmd_tbl_t cmd_sub[] = {
+ U_BOOT_CMD_MKENT(undefined, CONFIG_SYS_MAXARGS, 1, do_undefined,
+ "", ""),
+};
+
+static char exception_help_text[] =
+ "<ex>\n"
+ " The following exceptions are available:\n"
+ " undefined - undefined instruction\n"
+ ;
+
+#include <exception.h>
diff --git a/cmd/x86/Makefile b/cmd/x86/Makefile
index bcc6d06..7071614 100644
--- a/cmd/x86/Makefile
+++ b/cmd/x86/Makefile
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: GPL-2.0+
obj-y += mtrr.o
+obj-$(CONFIG_CMD_EXCEPTION) += exception.o
obj-$(CONFIG_HAVE_FSP) += fsp.o
diff --git a/cmd/x86/exception.c b/cmd/x86/exception.c
new file mode 100644
index 0000000..ade1e2e
--- /dev/null
+++ b/cmd/x86/exception.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * The 'exception' command can be used for testing exception handling.
+ *
+ * Copyright (c) 2018, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ */
+
+#include <common.h>
+#include <command.h>
+
+static int do_undefined(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ asm volatile (".word 0xffff\n");
+ return CMD_RET_FAILURE;
+}
+
+static cmd_tbl_t cmd_sub[] = {
+ U_BOOT_CMD_MKENT(undefined, CONFIG_SYS_MAXARGS, 1, do_undefined,
+ "", ""),
+};
+
+static char exception_help_text[] =
+ "<ex>\n"
+ " The following exceptions are available:\n"
+ " undefined - undefined instruction\n"
+ ;
+
+#include <exception.h>
diff --git a/include/exception.h b/include/exception.h
new file mode 100644
index 0000000..fc02490
--- /dev/null
+++ b/include/exception.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * The 'exception' command can be used for testing exception handling.
+ *
+ * Copyright (c) 2018, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ */
+
+static int do_exception(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ cmd_tbl_t *cp;
+
+ if (argc != 2)
+ return CMD_RET_USAGE;
+
+ /* drop sub-command parameter */
+ argc--;
+ argv++;
+
+ cp = find_cmd_tbl(argv[0], cmd_sub, ARRAY_SIZE(cmd_sub));
+
+ if (cp)
+ return cp->cmd(cmdtp, flag, argc, argv);
+
+ return CMD_RET_USAGE;
+}
+
+static int exception_complete(int argc, char * const argv[], char last_char,
+ int maxv, char *cmdv[])
+{
+ int len = 0;
+ int i = 0;
+ cmd_tbl_t *cmdtp;
+
+ switch (argc) {
+ case 1:
+ break;
+ case 2:
+ len = strlen(argv[1]);
+ break;
+ default:
+ return 0;
+ }
+ for (cmdtp = cmd_sub; cmdtp != cmd_sub + ARRAY_SIZE(cmd_sub); cmdtp++) {
+ if (i >= maxv - 1)
+ return i;
+ if (!strncmp(argv[1], cmdtp->name, len))
+ cmdv[i++] = cmdtp->name;
+ }
+ cmdv[i] = NULL;
+ return i;
+}
+
+U_BOOT_CMD_COMPLETE(
+ exception, 2, 0, do_exception,
+ "Forces an exception to occur",
+ exception_help_text, exception_complete
+);