summaryrefslogtreecommitdiffstats
path: root/sys/arm/arm/exception.S
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-05-17 13:53:38 +0000
committerian <ian@FreeBSD.org>2014-05-17 13:53:38 +0000
commitf51629e24e56540c52920e2b0e3fa2eddb3c8bed (patch)
tree21720b45d81bf613d158521e59271dd9e921cd76 /sys/arm/arm/exception.S
parent6341a2d92b98c830653de9c38705ec3321702a1e (diff)
downloadFreeBSD-src-f51629e24e56540c52920e2b0e3fa2eddb3c8bed.zip
FreeBSD-src-f51629e24e56540c52920e2b0e3fa2eddb3c8bed.tar.gz
MFC 262952, 262958, 262966, 262979, 262980, 262986, 262987, 262995, 262997,
263030, 263033, 263034, 263056, 263057, Remove all the redundant external declarations of exception vectors and runtime setting of the pointers that's scattered around various places. Remove all traces of support for ARM chips prior to the arm9 series. Make the default exception handler vectors point to where I thought they were already pointing: the default handlers (not a panic that says there is no default handler). Eliminate irq_dispatch.S. Move the data items it contained into arm/intr.c and the functionality it provided into arm/exception.S. Move the exception vector table (so-called "page0" data) into exception.S and eliminate vectors.S. Change the way the asm GET_CURTHREAD_PTR() macro is defined so that code using it doesn't have to have an "AST_LOCALS" macro somewhere in the file. Arrange for arm fork_trampoline() to return to userland via the standard swi_exit code in exception.S instead of having its own inline expansion of the DO_AST and PULLFRAME macros. Now that the PUSHFRAME and PULLFRAME macros are used only in the swi entry/exit code, they don't need to be macros. Except that didn't work and the whole change was reverted. Remove some unnecessary indirection and jump right to the handler functions. Use panic rather than printf to "handle" an arm26 address exception (should never happen on arm32). Remove the unreferenced DATA() macro. Remove #include <machine/asmacros.h> from files that don't need it.
Diffstat (limited to 'sys/arm/arm/exception.S')
-rw-r--r--sys/arm/arm/exception.S487
1 files changed, 354 insertions, 133 deletions
diff --git a/sys/arm/arm/exception.S b/sys/arm/arm/exception.S
index d7ef5f2..d49e20d 100644
--- a/sys/arm/arm/exception.S
+++ b/sys/arm/arm/exception.S
@@ -56,187 +56,408 @@ __FBSDID("$FreeBSD$");
.text
.align 0
-AST_LOCALS
+/*
+ * ASM macros for pushing and pulling trapframes from the stack
+ *
+ * These macros are used to handle the irqframe and trapframe structures
+ * defined above.
+ */
/*
- * reset_entry:
+ * PUSHFRAME - macro to push a trap frame on the stack in the current mode
+ * Since the current mode is used, the SVC lr field is not defined.
*
- * Handler for Reset exception.
+ * NOTE: r13 and r14 are stored separately as a work around for the
+ * SA110 rev 2 STM^ bug
*/
-ASENTRY_NP(reset_entry)
- adr r0, Lreset_panicmsg
- bl _C_LABEL(panic)
- /* NOTREACHED */
-Lreset_panicmsg:
- .asciz "Reset vector called, LR = 0x%08x"
- .balign 4
-END(reset_entry)
+#ifdef ARM_TP_ADDRESS
+#define PUSHFRAME \
+ sub sp, sp, #4; /* Align the stack */ \
+ str lr, [sp, #-4]!; /* Push the return address */ \
+ sub sp, sp, #(4*17); /* Adjust the stack pointer */ \
+ stmia sp, {r0-r12}; /* Push the user mode registers */ \
+ add r0, sp, #(4*13); /* Adjust the stack pointer */ \
+ stmia r0, {r13-r14}^; /* Push the user mode registers */ \
+ mov r0, r0; /* NOP for previous instruction */ \
+ mrs r0, spsr; /* Put the SPSR on the stack */ \
+ str r0, [sp, #-4]!; \
+ ldr r0, =ARM_RAS_START; \
+ mov r1, #0; \
+ str r1, [r0]; \
+ mov r1, #0xffffffff; \
+ str r1, [r0, #4];
+#else
+#define PUSHFRAME \
+ sub sp, sp, #4; /* Align the stack */ \
+ str lr, [sp, #-4]!; /* Push the return address */ \
+ sub sp, sp, #(4*17); /* Adjust the stack pointer */ \
+ stmia sp, {r0-r12}; /* Push the user mode registers */ \
+ add r0, sp, #(4*13); /* Adjust the stack pointer */ \
+ stmia r0, {r13-r14}^; /* Push the user mode registers */ \
+ mov r0, r0; /* NOP for previous instruction */ \
+ mrs r0, spsr; /* Put the SPSR on the stack */ \
+ str r0, [sp, #-4]!;
+#endif
/*
- * swi_entry
+ * PULLFRAME - macro to pull a trap frame from the stack in the current mode
+ * Since the current mode is used, the SVC lr field is ignored.
+ */
+
+#ifdef ARM_TP_ADDRESS
+#define PULLFRAME \
+ ldr r0, [sp], #4; /* Get the SPSR from stack */ \
+ msr spsr_fsxc, r0; \
+ ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \
+ mov r0, r0; /* NOP for previous instruction */ \
+ add sp, sp, #(4*17); /* Adjust the stack pointer */ \
+ ldr lr, [sp], #4; /* Pull the return address */ \
+ add sp, sp, #4 /* Align the stack */
+#else
+#define PULLFRAME \
+ ldr r0, [sp], #4 ; /* Get the SPSR from stack */ \
+ msr spsr_fsxc, r0; \
+ clrex; \
+ ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \
+ mov r0, r0; /* NOP for previous instruction */ \
+ add sp, sp, #(4*17); /* Adjust the stack pointer */ \
+ ldr lr, [sp], #4; /* Pull the return address */ \
+ add sp, sp, #4 /* Align the stack */
+#endif
+
+/*
+ * PUSHFRAMEINSVC - macro to push a trap frame on the stack in SVC32 mode
+ * This should only be used if the processor is not currently in SVC32
+ * mode. The processor mode is switched to SVC mode and the trap frame is
+ * stored. The SVC lr field is used to store the previous value of
+ * lr in SVC mode.
*
- * Handler for the Software Interrupt exception.
+ * NOTE: r13 and r14 are stored separately as a work around for the
+ * SA110 rev 2 STM^ bug
*/
-ASENTRY_NP(swi_entry)
- STOP_UNWINDING /* Don't unwind past here */
+#ifdef ARM_TP_ADDRESS
+#define PUSHFRAMEINSVC \
+ stmdb sp, {r0-r3}; /* Save 4 registers */ \
+ mov r0, lr; /* Save xxx32 r14 */ \
+ mov r1, sp; /* Save xxx32 sp */ \
+ mrs r3, spsr; /* Save xxx32 spsr */ \
+ mrs r2, cpsr; /* Get the CPSR */ \
+ bic r2, r2, #(PSR_MODE); /* Fix for SVC mode */ \
+ orr r2, r2, #(PSR_SVC32_MODE); \
+ msr cpsr_c, r2; /* Punch into SVC mode */ \
+ mov r2, sp; /* Save SVC sp */ \
+ bic sp, sp, #7; /* Align sp to an 8-byte addrress */ \
+ sub sp, sp, #4; /* Pad trapframe to keep alignment */ \
+ str r0, [sp, #-4]!; /* Push return address */ \
+ str lr, [sp, #-4]!; /* Push SVC lr */ \
+ str r2, [sp, #-4]!; /* Push SVC sp */ \
+ msr spsr_fsxc, r3; /* Restore correct spsr */ \
+ ldmdb r1, {r0-r3}; /* Restore 4 regs from xxx mode */ \
+ sub sp, sp, #(4*15); /* Adjust the stack pointer */ \
+ stmia sp, {r0-r12}; /* Push the user mode registers */ \
+ add r0, sp, #(4*13); /* Adjust the stack pointer */ \
+ stmia r0, {r13-r14}^; /* Push the user mode registers */ \
+ mov r0, r0; /* NOP for previous instruction */ \
+ ldr r5, =ARM_RAS_START; /* Check if there's any RAS */ \
+ ldr r4, [r5, #4]; /* reset it to point at the */ \
+ cmp r4, #0xffffffff; /* end of memory if necessary; */ \
+ movne r1, #0xffffffff; /* leave value in r4 for later */ \
+ strne r1, [r5, #4]; /* comparision against PC. */ \
+ ldr r3, [r5]; /* Retrieve global RAS_START */ \
+ cmp r3, #0; /* and reset it if non-zero. */ \
+ movne r1, #0; /* If non-zero RAS_START and */ \
+ strne r1, [r5]; /* PC was lower than RAS_END, */ \
+ ldrne r1, [r0, #16]; /* adjust the saved PC so that */ \
+ cmpne r4, r1; /* execution later resumes at */ \
+ strhi r3, [r0, #16]; /* the RAS_START location. */ \
+ mrs r0, spsr; \
+ str r0, [sp, #-4]!
+#else
+#define PUSHFRAMEINSVC \
+ stmdb sp, {r0-r3}; /* Save 4 registers */ \
+ mov r0, lr; /* Save xxx32 r14 */ \
+ mov r1, sp; /* Save xxx32 sp */ \
+ mrs r3, spsr; /* Save xxx32 spsr */ \
+ mrs r2, cpsr; /* Get the CPSR */ \
+ bic r2, r2, #(PSR_MODE); /* Fix for SVC mode */ \
+ orr r2, r2, #(PSR_SVC32_MODE); \
+ msr cpsr_c, r2; /* Punch into SVC mode */ \
+ mov r2, sp; /* Save SVC sp */ \
+ bic sp, sp, #7; /* Align sp to an 8-byte addrress */ \
+ sub sp, sp, #4; /* Pad trapframe to keep alignment */ \
+ str r0, [sp, #-4]!; /* Push return address */ \
+ str lr, [sp, #-4]!; /* Push SVC lr */ \
+ str r2, [sp, #-4]!; /* Push SVC sp */ \
+ msr spsr_fsxc, r3; /* Restore correct spsr */ \
+ ldmdb r1, {r0-r3}; /* Restore 4 regs from xxx mode */ \
+ sub sp, sp, #(4*15); /* Adjust the stack pointer */ \
+ stmia sp, {r0-r12}; /* Push the user mode registers */ \
+ add r0, sp, #(4*13); /* Adjust the stack pointer */ \
+ stmia r0, {r13-r14}^; /* Push the user mode registers */ \
+ mov r0, r0; /* NOP for previous instruction */ \
+ mrs r0, spsr; /* Put the SPSR on the stack */ \
+ str r0, [sp, #-4]!
+#endif
- PUSHFRAME
+/*
+ * PULLFRAMEFROMSVCANDEXIT - macro to pull a trap frame from the stack
+ * in SVC32 mode and restore the saved processor mode and PC.
+ * This should be used when the SVC lr register needs to be restored on
+ * exit.
+ */
- mov r0, sp /* Pass the frame to any function */
- bl _C_LABEL(swi_handler) /* It's a SWI ! */
+#ifdef ARM_TP_ADDRESS
+#define PULLFRAMEFROMSVCANDEXIT \
+ ldr r0, [sp], #4; /* Get the SPSR from stack */ \
+ msr spsr_fsxc, r0; /* restore SPSR */ \
+ ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \
+ mov r0, r0; /* NOP for previous instruction */ \
+ add sp, sp, #(4*15); /* Adjust the stack pointer */ \
+ ldmia sp, {sp, lr, pc}^ /* Restore lr and exit */
+#else
+#define PULLFRAMEFROMSVCANDEXIT \
+ ldr r0, [sp], #4; /* Get the SPSR from stack */ \
+ msr spsr_fsxc, r0; /* restore SPSR */ \
+ clrex; \
+ ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \
+ mov r0, r0; /* NOP for previous instruction */ \
+ add sp, sp, #(4*15); /* Adjust the stack pointer */ \
+ ldmia sp, {sp, lr, pc}^ /* Restore lr and exit */
+#endif
- DO_AST
- PULLFRAME
- movs pc, lr /* Exit */
+#if defined(__ARM_EABI__)
+/*
+ * Unwind hints so we can unwind past functions that use
+ * PULLFRAMEFROMSVCANDEXIT. They are run in reverse order.
+ * As the last thing we do is restore the stack pointer
+ * we can ignore the padding at the end of struct trapframe.
+ */
+#define UNWINDSVCFRAME \
+ .save {r13-r15}; /* Restore sp, lr, pc */ \
+ .pad #(2*4); /* Skip user sp and lr */ \
+ .save {r0-r12}; /* Restore r0-r12 */ \
+ .pad #(4) /* Skip spsr */
+#else
+#define UNWINDSVCFRAME
+#endif
+
+#define DO_AST \
+ ldr r0, [sp] /* Get the SPSR from stack */ ;\
+ mrs r4, cpsr /* save CPSR */ ;\
+ orr r1, r4, #(I32_bit|F32_bit) ;\
+ msr cpsr_c, r1 /* Disable interrupts */ ;\
+ and r0, r0, #(PSR_MODE) /* Returning to USR mode? */ ;\
+ teq r0, #(PSR_USR32_MODE) ;\
+ bne 2f /* Nope, get out now */ ;\
+ bic r4, r4, #(I32_bit|F32_bit) ;\
+1: GET_CURTHREAD_PTR(r5) ;\
+ ldr r1, [r5, #(TD_FLAGS)] ;\
+ and r1, r1, #(TDF_ASTPENDING|TDF_NEEDRESCHED) ;\
+ teq r1, #0x00000000 ;\
+ beq 2f /* Nope. Just bail */ ;\
+ msr cpsr_c, r4 /* Restore interrupts */ ;\
+ mov r0, sp ;\
+ bl _C_LABEL(ast) /* ast(frame) */ ;\
+ orr r0, r4, #(I32_bit|F32_bit) ;\
+ msr cpsr_c, r0 ;\
+ b 1b ;\
+2:
+
+
+/*
+ * Entry point for a Software Interrupt (SWI).
+ *
+ * The hardware switches to svc32 mode on a swi, so we're already on the
+ * right stack; just build a trapframe and call the handler.
+ */
+ASENTRY_NP(swi_entry)
+ PUSHFRAME /* Build the trapframe on the */
+ mov r0, sp /* scv32 stack, pass it to the */
+ bl _C_LABEL(swi_handler) /* swi handler. */
+ /*
+ * The fork_trampoline() code in swtch.S aranges for the MI fork_exit()
+ * to return to swi_exit here, to return to userland. The net effect is
+ * that a newly created thread appears to return from a SWI just like
+ * the parent thread that created it.
+ */
+ASENTRY_NP(swi_exit)
+ DO_AST /* Handle pending signals. */
+ PULLFRAME /* Deallocate trapframe. */
+ movs pc, lr /* Return to userland. */
+ STOP_UNWINDING /* Don't unwind into user mode. */
+END(swi_exit)
END(swi_entry)
/*
- * prefetch_abort_entry:
+ * Standard exception exit handler.
*
- * Handler for the Prefetch Abort exception.
+ * This is used to return from all exceptions except SWI. It uses DO_AST and
+ * PULLFRAMEFROMSVCANDEXIT and can only be called if the exception entry code
+ * used PUSHFRAMEINSVC.
+ *
+ * If the return is to user mode, this uses DO_AST to deliver any pending
+ * signals and/or handle TDF_NEEDRESCHED first.
+ */
+ASENTRY_NP(exception_exit)
+ DO_AST /* Handle pending signals. */
+ PULLFRAMEFROMSVCANDEXIT /* Return. */
+ UNWINDSVCFRAME /* Special unwinding for exceptions. */
+END(exception_exit)
+
+/*
+ * Entry point for a Prefetch Abort exception.
+ *
+ * The hardware switches to the abort mode stack; we switch to svc32 before
+ * calling the handler, then return directly to the original mode/stack
+ * on exit (without transitioning back through the abort mode stack).
*/
ASENTRY_NP(prefetch_abort_entry)
#ifdef __XSCALE__
nop /* Make absolutely sure any pending */
nop /* imprecise aborts have occurred. */
#endif
- sub lr, lr, #0x00000004 /* Adjust the lr */
-
- PUSHFRAMEINSVC
- ldr r1, Lprefetch_abort_handler_address
- adr lr, exception_exit
- mov r0, sp /* pass the stack pointer as r0 */
- ldr pc, [r1]
-
-Lprefetch_abort_handler_address:
- .word _C_LABEL(prefetch_abort_handler_address)
-
- .data
- .global _C_LABEL(prefetch_abort_handler_address)
-
-_C_LABEL(prefetch_abort_handler_address):
- .word abortprefetch
-
- .text
-abortprefetch:
- adr r0, abortprefetchmsg
- b _C_LABEL(panic)
-
-abortprefetchmsg:
- .asciz "abortprefetch"
- .align 0
+ sub lr, lr, #4 /* Adjust the lr. Transition to scv32 */
+ PUSHFRAMEINSVC /* mode stack, build trapframe there. */
+ adr lr, exception_exit /* Return from handler via standard */
+ mov r0, sp /* exception exit routine. Pass the */
+ b prefetch_abort_handler /* trapframe to the handler. */
END(prefetch_abort_entry)
/*
- * data_abort_entry:
+ * Entry point for a Data Abort exception.
*
- * Handler for the Data Abort exception.
+ * The hardware switches to the abort mode stack; we switch to svc32 before
+ * calling the handler, then return directly to the original mode/stack
+ * on exit (without transitioning back through the abort mode stack).
*/
ASENTRY_NP(data_abort_entry)
#ifdef __XSCALE__
nop /* Make absolutely sure any pending */
nop /* imprecise aborts have occurred. */
#endif
-
- sub lr, lr, #0x00000008 /* Adjust the lr */
- PUSHFRAMEINSVC /* Push trap frame and switch */
- /* to SVC32 mode */
- ldr r1, Ldata_abort_handler_address
- adr lr, exception_exit
- mov r0, sp /* pass the stack pointer as r0 */
- ldr pc, [r1]
-Ldata_abort_handler_address:
- .word _C_LABEL(data_abort_handler_address)
-
- .data
- .global _C_LABEL(data_abort_handler_address)
-_C_LABEL(data_abort_handler_address):
- .word abortdata
-
- .text
-abortdata:
- adr r0, abortdatamsg
- b _C_LABEL(panic)
-
-abortdatamsg:
- .asciz "abortdata"
- .align 0
+ sub lr, lr, #8 /* Adjust the lr. Transition to scv32 */
+ PUSHFRAMEINSVC /* mode stack, build trapframe there. */
+ adr lr, exception_exit /* Return from handler via standard */
+ mov r0, sp /* exception exit routine. Pass the */
+ b data_abort_handler /* trapframe to the handler. */
END(data_abort_entry)
/*
- * address_exception_entry:
+ * Entry point for an Undefined Instruction exception.
*
- * Handler for the Address Exception exception.
+ * The hardware switches to the undefined mode stack; we switch to svc32 before
+ * calling the handler, then return directly to the original mode/stack
+ * on exit (without transitioning back through the undefined mode stack).
+ */
+ASENTRY_NP(undefined_entry)
+ sub lr, lr, #4 /* Adjust the lr. Transition to scv32 */
+ PUSHFRAMEINSVC /* mode stack, build trapframe there. */
+ adr lr, exception_exit /* Return from handler via standard */
+ mov r0, sp /* exception exit routine. Pass the */
+ b undefinedinstruction /* trapframe to the handler. */
+END(undefined_entry)
+
+/*
+ * Entry point for a normal IRQ.
*
- * NOTE: This exception isn't really used on arm32. We
- * print a warning message to the console and then treat
- * it like a Data Abort.
+ * The hardware switches to the IRQ mode stack; we switch to svc32 before
+ * calling the handler, then return directly to the original mode/stack
+ * on exit (without transitioning back through the IRQ mode stack).
*/
-ASENTRY_NP(address_exception_entry)
- mrs r1, cpsr
- mrs r2, spsr
+ASENTRY_NP(irq_entry)
+ sub lr, lr, #4 /* Adjust the lr. Transition to scv32 */
+ PUSHFRAMEINSVC /* mode stack, build trapframe there. */
+ adr lr, exception_exit /* Return from handler via standard */
+ mov r0, sp /* exception exit routine. Pass the */
+ b _C_LABEL(arm_irq_handler)/* trapframe to the handler. */
+END(irq_entry)
+
+/*
+ * Entry point for an FIQ interrupt.
+ *
+ * We don't currently support FIQ handlers very much. Something can
+ * install itself in the FIQ vector using code (that may or may not work
+ * these days) in fiq.c. If nobody does that and an FIQ happens, this
+ * default handler just disables FIQs and otherwise ignores it.
+ */
+ASENTRY_NP(fiq_entry)
+ mrs r8, cpsr /* FIQ handling isn't supported, */
+ bic r8, #(F32_bit) /* just disable FIQ and return. */
+ msr cpsr_c, r8 /* The r8 we trash here is the */
+ subs pc, lr, #4 /* banked FIQ-mode r8. */
+END(fiq_entry)
+
+/*
+ * Entry point for an Address Exception exception.
+ * This is an arm26 exception that should never happen.
+ */
+ASENTRY_NP(addr_exception_entry)
mov r3, lr
- adr r0, Laddress_exception_msg
- bl _C_LABEL(printf) /* XXX CLOBBERS LR!! */
- b data_abort_entry
-Laddress_exception_msg:
+ mrs r2, spsr
+ mrs r1, cpsr
+ adr r0, Laddr_exception_msg
+ b _C_LABEL(panic)
+Laddr_exception_msg:
.asciz "Address Exception CPSR=0x%08x SPSR=0x%08x LR=0x%08x\n"
.balign 4
-END(address_exception_entry)
+END(addr_exception_entry)
/*
- * General exception exit handler
- * (Placed here to be within range of all the references to it)
- *
- * It exits straight away if not returning to USR mode.
- * This loops around delivering any pending ASTs.
- * Interrupts are disabled at suitable points to avoid ASTs
- * being posted between testing and exit to user mode.
- *
- * This function uses PULLFRAMEFROMSVCANDEXIT and DO_AST and can
- * only be called if the exception handler used PUSHFRAMEINSVC.
- *
- * For EABI, don't try to unwind any further than this. This is a
- * stopgap measure to avoid getting stuck in a loop in the unwinder,
- * which happens because we don't yet provide the proper unwind info
- * here that describes which registers are being restored.
+ * Entry point for the system Reset vector.
+ * This should never happen, so panic.
*/
-
-ASENTRY_NP(exception_exit)
- UNWINDSVCFRAME
- DO_AST
- PULLFRAMEFROMSVCANDEXIT
-END(exception_exit)
+ASENTRY_NP(reset_entry)
+ mov r1, lr
+ adr r0, Lreset_panicmsg
+ b _C_LABEL(panic)
+ /* NOTREACHED */
+Lreset_panicmsg:
+ .asciz "Reset vector called, LR = 0x%08x"
+ .balign 4
+END(reset_entry)
/*
- * undefined_entry:
- *
- * Handler for the Undefined Instruction exception.
- *
- * We indirect the undefined vector via the handler address
- * in the data area. Entry to the undefined handler must
- * look like direct entry from the vector.
+ * page0 and page0_data -- An image of the ARM vectors which is copied to
+ * the ARM vectors page (high or low) as part of CPU initialization. The
+ * code that does the copy assumes that page0_data holds one 32-bit word
+ * of data for each of the predefined ARM vectors. It also assumes that
+ * page0_data follows the vectors in page0, but other stuff can appear
+ * between the two. We currently leave room between the two for some fiq
+ * handler code to be copied in.
*/
-ASENTRY_NP(undefined_entry)
+ .global _C_LABEL(page0), _C_LABEL(page0_data)
- sub lr, lr, #0x00000004 /* Adjust the lr */
- PUSHFRAMEINSVC /* Push trap frame and switch */
- /* to SVC32 mode */
- ldr r1, Lundefined_handler_address
- adr lr, exception_exit
- mov r0, sp /* pass the stack pointer as r0 */
- ldr pc, [r1]
-END(undefined_entry)
+_C_LABEL(page0):
+ ldr pc, .Lreset_entry
+ ldr pc, .Lundefined_entry
+ ldr pc, .Lswi_entry
+ ldr pc, .Lprefetch_abort_entry
+ ldr pc, .Ldata_abort_entry
+ ldr pc, .Laddr_exception_entry
+ ldr pc, .Lirq_entry
+.fiqv: ldr pc, .Lfiq_entry
+ .space 256 /* room for some fiq handler code */
+
+_C_LABEL(page0_data):
+.Lreset_entry: .word reset_entry
+.Lundefined_entry: .word undefined_entry
+.Lswi_entry: .word swi_entry
+.Lprefetch_abort_entry: .word prefetch_abort_entry
+.Ldata_abort_entry: .word data_abort_entry
+.Laddr_exception_entry: .word addr_exception_entry
+.Lirq_entry: .word irq_entry
+.Lfiq_entry: .word fiq_entry
-ASENTRY_NP(undefinedinstruction_bounce)
- b undefinedinstruction
-END(undefinedinstruction_bounce)
+/*
+ * These items are used by the code in fiq.c to install what it calls the
+ * "null" handler. It's actually our default vector entry that just jumps
+ * to the default handler which just disables FIQs and returns.
+ */
+ .global _C_LABEL(fiq_nullhandler_code), _C_LABEL(fiq_nullhandler_size)
-Lundefined_handler_address:
- .word _C_LABEL(undefined_handler_address)
+_C_LABEL(fiq_nullhandler_code):
+ .word .fiqv
+_C_LABEL(fiq_nullhandler_size):
+ .word 4
- .data
- .global _C_LABEL(undefined_handler_address)
-_C_LABEL(undefined_handler_address):
- .word undefinedinstruction_bounce
OpenPOWER on IntegriCloud