1 // SPDX-License-Identifier: GPL-2.0+
4 * David Feng <fenghua@phytium.com.cn>
9 #include <asm/global_data.h>
10 #include <asm/ptrace.h>
12 #include <linux/compiler.h>
13 #include <efi_loader.h>
14 #include <semihosting.h>
16 DECLARE_GLOBAL_DATA_PTR;
18 int interrupt_init(void)
25 void enable_interrupts(void)
30 int disable_interrupts(void)
35 static void show_efi_loaded_images(struct pt_regs *regs)
37 efi_print_image_infos((void *)regs->elr);
40 static void dump_instr(struct pt_regs *regs)
42 u32 *addr = (u32 *)(regs->elr & ~3UL);
46 for (i = -4; i < 1; i++)
47 printf(i == 0 ? "(%08x) " : "%08x ", addr[i]);
51 void show_regs(struct pt_regs *regs)
55 if (gd->flags & GD_FLG_RELOC)
56 printf("elr: %016lx lr : %016lx (reloc)\n",
57 regs->elr - gd->reloc_off,
58 regs->regs[30] - gd->reloc_off);
59 printf("elr: %016lx lr : %016lx\n", regs->elr, regs->regs[30]);
61 for (i = 0; i < 29; i += 2)
62 printf("x%-2d: %016lx x%-2d: %016lx\n",
63 i, regs->regs[i], i+1, regs->regs[i+1]);
69 * Try to "emulate" a semihosting call in the event that we don't have a
72 static bool smh_emulate_trap(struct pt_regs *regs)
76 if (ESR_ELx_EC(regs->esr) != ESR_ELx_EC_UNKNOWN)
79 if (regs->spsr & PSR_MODE32_BIT) {
80 if (regs->spsr & PSR_AA32_T_BIT) {
81 u16 *insn = (u16 *)ALIGN_DOWN(regs->elr, 2);
83 if (*insn != SMH_T32_SVC && *insn != SMH_T32_HLT)
87 u32 *insn = (u32 *)ALIGN_DOWN(regs->elr, 4);
89 if (*insn != SMH_A32_SVC && *insn != SMH_A32_HLT)
94 u32 *insn = (u32 *)ALIGN_DOWN(regs->elr, 4);
96 if (*insn != SMH_A64_HLT)
101 /* Avoid future semihosting calls */
102 disable_semihosting();
104 /* Just pretend the call failed */
111 * do_bad_sync handles the impossible case in the Synchronous Abort vector.
113 void do_bad_sync(struct pt_regs *pt_regs)
116 printf("Bad mode in \"Synchronous Abort\" handler, esr 0x%08lx\n",
119 show_efi_loaded_images(pt_regs);
120 panic("Resetting CPU ...\n");
124 * do_bad_irq handles the impossible case in the Irq vector.
126 void do_bad_irq(struct pt_regs *pt_regs)
129 printf("Bad mode in \"Irq\" handler, esr 0x%08lx\n", pt_regs->esr);
131 show_efi_loaded_images(pt_regs);
132 panic("Resetting CPU ...\n");
136 * do_bad_fiq handles the impossible case in the Fiq vector.
138 void do_bad_fiq(struct pt_regs *pt_regs)
141 printf("Bad mode in \"Fiq\" handler, esr 0x%08lx\n", pt_regs->esr);
143 show_efi_loaded_images(pt_regs);
144 panic("Resetting CPU ...\n");
148 * do_bad_error handles the impossible case in the Error vector.
150 void do_bad_error(struct pt_regs *pt_regs)
153 printf("Bad mode in \"Error\" handler, esr 0x%08lx\n", pt_regs->esr);
155 show_efi_loaded_images(pt_regs);
156 panic("Resetting CPU ...\n");
160 * do_sync handles the Synchronous Abort exception.
162 void do_sync(struct pt_regs *pt_regs)
164 if (CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK) &&
165 smh_emulate_trap(pt_regs))
168 printf("\"Synchronous Abort\" handler, esr 0x%08lx\n", pt_regs->esr);
170 show_efi_loaded_images(pt_regs);
171 panic("Resetting CPU ...\n");
175 * do_irq handles the Irq exception.
177 void do_irq(struct pt_regs *pt_regs)
180 printf("\"Irq\" handler, esr 0x%08lx\n", pt_regs->esr);
182 show_efi_loaded_images(pt_regs);
183 panic("Resetting CPU ...\n");
187 * do_fiq handles the Fiq exception.
189 void do_fiq(struct pt_regs *pt_regs)
192 printf("\"Fiq\" handler, esr 0x%08lx\n", pt_regs->esr);
194 show_efi_loaded_images(pt_regs);
195 panic("Resetting CPU ...\n");
199 * do_error handles the Error exception.
200 * Errors are more likely to be processor specific,
201 * it is defined with weak attribute and can be redefined
202 * in processor specific code.
204 void __weak do_error(struct pt_regs *pt_regs)
207 printf("\"Error\" handler, esr 0x%08lx\n", pt_regs->esr);
209 show_efi_loaded_images(pt_regs);
210 panic("Resetting CPU ...\n");