#include <cpu_func.h>
#include <efi_loader.h>
#include <irq_func.h>
+#include <semihosting.h>
#include <asm/global_data.h>
#include <asm/proc-armv/ptrace.h>
#include <asm/ptrace.h>
regs->ARM_pc = pc | (regs->ARM_pc & PCMASK);
}
+/*
+ * Try to "emulate" a semihosting call in the event that we don't have a
+ * debugger attached.
+ */
+static bool smh_emulate_trap(struct pt_regs *regs)
+{
+ if (regs->ARM_cpsr & T_BIT) {
+ u16 *insn = (u16 *)(regs->ARM_pc - 2);
+
+ if (*insn != SMH_T32_SVC)
+ return false;
+ } else {
+ u32 *insn = (u32 *)(regs->ARM_pc - 4);
+
+ if (*insn != SMH_A32_SVC)
+ return false;
+ }
+
+ /* Avoid future semihosting calls */
+ disable_semihosting();
+
+ /* Just pretend the call failed */
+ regs->ARM_r0 = -1;
+ return true;
+}
+
void do_undefined_instruction (struct pt_regs *pt_regs)
{
efi_restore_gd();
void do_software_interrupt (struct pt_regs *pt_regs)
{
+ if (CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) &&
+ smh_emulate_trap(pt_regs))
+ return;
+
efi_restore_gd();
printf ("software interrupt\n");
fixup_pc(pt_regs, -4);
get_bad_stack_swi
bad_save_user_regs
bl do_software_interrupt
+#if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK)
+ ldmia sp, {r0 - lr}^ @ Calling r0 - lr
+ mov r0, r0
+ ldr lr, [sp, #S_PC] @ Get PC
+ add sp, sp, #S_FRAME_SIZE
+ movs pc, lr @ return & move spsr_svc into cpsr
+#endif
.align 5
prefetch_abort:
config SEMIHOSTING_FALLBACK
bool "Recover gracefully when semihosting fails"
- depends on SEMIHOSTING && (ARM64 || RISCV)
+ depends on SEMIHOSTING
default y
help
Normally, if U-Boot makes a semihosting call and no debugger is
config SPL_SEMIHOSTING_FALLBACK
bool "Recover gracefully when semihosting fails in SPL"
- depends on SPL_SEMIHOSTING && (ARM64 || RISCV)
+ depends on SPL_SEMIHOSTING
select ARMV8_SPL_EXCEPTION_VECTORS if ARM64
default y
help