diff options
-rw-r--r-- | arch/arm/Kconfig | 21 | ||||
-rw-r--r-- | arch/arm/lib/semihosting.c | 21 | ||||
-rw-r--r-- | include/semihosting.h | 30 |
3 files changed, 72 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b2e2873448..f277929c99 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 7595dbc4a9..dbea2b06fb 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 * diff --git a/include/semihosting.h b/include/semihosting.h index 6f3c29786c..9816233c50 100644 --- a/include/semihosting.h +++ b/include/semihosting.h @@ -6,6 +6,36 @@ #ifndef _SEMIHOSTING_H #define _SEMIHOSTING_H +#if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) +/** + * semihosting_enabled() - Determine whether semihosting is supported + * + * Semihosting-based drivers should call this function before making other + * semihosting calls. + * + * Return: %true if a debugger is attached which supports semihosting, %false + * otherwise + */ +bool semihosting_enabled(void); + +/** + * disable_semihosting() - Cause semihosting_enabled() to return false + * + * If U-Boot ever receives an unhandled exception caused by a semihosting trap, + * the trap handler should call this function. + */ +void disable_semihosting(void); +#else +static inline bool semihosting_enabled(void) +{ + return CONFIG_IS_ENABLED(SEMIHOSTING); +} + +static inline void disable_semihosting(void) +{ +} +#endif + /** * enum smh_open_mode - Numeric file modes for use with smh_open() * MODE_READ: 'r' |