aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorSean Anderson <sean.anderson@seco.com>2022-03-22 16:59:30 -0400
committerTom Rini <trini@konsulko.com>2022-04-01 16:56:53 -0400
commit385d69d76b4216c10083f908005983d0c62e159c (patch)
tree92bd8f763f5538def3726bacbf5b01fdd2158bcb /arch
parent6d16157426b63361d6390b3ab4b304bbe101c825 (diff)
downloadu-boot-385d69d76b4216c10083f908005983d0c62e159c.zip
u-boot-385d69d76b4216c10083f908005983d0c62e159c.tar.gz
u-boot-385d69d76b4216c10083f908005983d0c62e159c.tar.bz2
arm: smh: Add option to detect semihosting
These functions are intended to support detecting semihosting and falling back gracefully to alternative implementations. The test starts by making semihosting call. SYS_ERRNO is chosen because it should not mutate any state. If this semihosting call results in an exception (rather than being caught by the debugger), then the exception handler should call disable_semihosting() and resume execution after the call. Ideally, this would just be part of semihosting by default, and not a separate config. However, to reduce space ARM SPL doesn't include exception vectors by default. This means we can't detect if a semihosting call failed unless we enable them. To avoid forcing them to be enabled, we use a separate config option. It might also be possible to try and detect whether a debugger has enabled (by reading HDE from DSCR), but I wasn't able to figure out a way to do this from all ELs. This patch just introduces the generic code to handle detection. The next patch will implement it for arm64 (but not arm32). Signed-off-by: Sean Anderson <sean.anderson@seco.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig21
-rw-r--r--arch/arm/lib/semihosting.c21
2 files changed, 42 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b2e2873..f277929 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -414,6 +414,16 @@ config SEMIHOSTING
on the host system. If you don't have a debugger attached then trying
to do this will likely cause U-Boot to hang. Say 'n' if you are unsure.
+config SEMIHOSTING_FALLBACK
+ bool "Recover gracefully when semihosting fails"
+ depends on SEMIHOSTING && ARM64
+ default y
+ help
+ Normally, if U-Boot makes a semihosting call and no debugger is
+ attached, then it will panic due to a synchronous abort
+ exception. This config adds an exception handler which will allow
+ U-Boot to recover. Say 'y' if unsure.
+
config SPL_SEMIHOSTING
bool "Support ARM semihosting in SPL"
depends on SPL
@@ -427,6 +437,17 @@ config SPL_SEMIHOSTING
on the host system. If you don't have a debugger attached then trying
to do this will likely cause U-Boot to hang. Say 'n' if you are unsure.
+config SPL_SEMIHOSTING_FALLBACK
+ bool "Recover gracefully when semihosting fails in SPL"
+ depends on SPL_SEMIHOSTING && ARM64
+ select ARMV8_SPL_EXCEPTION_VECTORS
+ default y
+ help
+ Normally, if U-Boot makes a semihosting call and no debugger is
+ attached, then it will panic due to a synchronous abort
+ exception. This config adds an exception handler which will allow
+ U-Boot to recover. Say 'y' if unsure.
+
config SYS_THUMB_BUILD
bool "Build U-Boot using the Thumb instruction set"
depends on !ARM64
diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c
index 7595dbc..dbea2b0 100644
--- a/arch/arm/lib/semihosting.c
+++ b/arch/arm/lib/semihosting.c
@@ -20,6 +20,7 @@
#define SYSWRITE 0x05
#define SYSREAD 0x06
#define SYSREADC 0x07
+#define SYSISERROR 0x08
#define SYSSEEK 0x0A
#define SYSFLEN 0x0C
#define SYSERRNO 0x13
@@ -41,6 +42,26 @@ static noinline long smh_trap(unsigned int sysnum, void *addr)
return result;
}
+#if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK)
+static bool _semihosting_enabled = true;
+static bool try_semihosting = true;
+
+bool semihosting_enabled(void)
+{
+ if (try_semihosting) {
+ smh_trap(SYSERRNO, NULL);
+ try_semihosting = false;
+ }
+
+ return _semihosting_enabled;
+}
+
+void disable_semihosting(void)
+{
+ _semihosting_enabled = false;
+}
+#endif
+
/**
* smh_errno() - Read the host's errno
*