summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-03-10 22:52:32 +0000
committerian <ian@FreeBSD.org>2014-03-10 22:52:32 +0000
commit77aa58f7b4e861ae31bcc0429e9f3568617f95a2 (patch)
tree2ad72bbf027ee3f0363aac728e519d436341e376 /sys/arm
parentab22d4f391ac7c4c8395ac6a05ab747f91d52d2f (diff)
downloadFreeBSD-src-77aa58f7b4e861ae31bcc0429e9f3568617f95a2.zip
FreeBSD-src-77aa58f7b4e861ae31bcc0429e9f3568617f95a2.tar.gz
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. That means that now all references to the PUSH/PULLFRAME and DO_AST macros are localized to exception.S, so move the macros themselves into there and remove them from asmacros.h
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/arm/exception.S225
-rw-r--r--sys/arm/arm/swtch.S18
-rw-r--r--sys/arm/include/asmacros.h208
3 files changed, 228 insertions, 223 deletions
diff --git a/sys/arm/arm/exception.S b/sys/arm/arm/exception.S
index cb537cc..ec2c33b 100644
--- a/sys/arm/arm/exception.S
+++ b/sys/arm/arm/exception.S
@@ -57,6 +57,216 @@ __FBSDID("$FreeBSD$");
.align 0
/*
+ * ASM macros for pushing and pulling trapframes from the stack
+ *
+ * These macros are used to handle the irqframe and trapframe structures
+ * defined above.
+ */
+
+/*
+ * 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.
+ *
+ * NOTE: r13 and r14 are stored separately as a work around for the
+ * SA110 rev 2 STM^ bug
+ */
+#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
+
+/*
+ * 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], #0x0004; /* 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], #0x0004; /* Pull the return address */ \
+ add sp, sp, #4 /* Align the stack */
+#else
+#define PULLFRAME \
+ ldr r0, [sp], #0x0004; /* 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], #0x0004; /* 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.
+ *
+ * NOTE: r13 and r14 are stored separately as a work around for the
+ * SA110 rev 2 STM^ bug
+ */
+#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
+
+/*
+ * 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.
+ */
+
+#ifdef ARM_TP_ADDRESS
+#define PULLFRAMEFROMSVCANDEXIT \
+ ldr r0, [sp], #0x0004; /* 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], #0x0004; /* 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
+
+#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:
+
+
+
+
+/*
* reset_entry:
*
* Handler for Reset exception.
@@ -76,16 +286,27 @@ END(reset_entry)
* Handler for the Software Interrupt exception.
*/
ASENTRY_NP(swi_entry)
- STOP_UNWINDING /* Don't unwind past here */
+ STOP_UNWINDING /* Don't unwind into user mode. */
PUSHFRAME
mov r0, sp /* Pass the frame to any function */
bl _C_LABEL(swi_handler) /* It's a SWI ! */
- DO_AST
+ /*
+ * 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 /* Deliver signals. */
+
PULLFRAME
movs pc, lr /* Exit */
+
+END(swi_exit)
END(swi_entry)
/*
diff --git a/sys/arm/arm/swtch.S b/sys/arm/arm/swtch.S
index be9b5c4..610d575 100644
--- a/sys/arm/arm/swtch.S
+++ b/sys/arm/arm/swtch.S
@@ -486,20 +486,12 @@ ENTRY(savectx)
END(savectx)
ENTRY(fork_trampoline)
- STOP_UNWINDING /* Can't unwind beyond the thread enty point */
- mov r1, r5
+ STOP_UNWINDING /* EABI: Don't unwind beyond the thread enty point. */
+ mov fp, #0 /* OABI: Stack traceback via fp stops here. */
mov r2, sp
+ mov r1, r5
mov r0, r4
- mov fp, #0
- bl _C_LABEL(fork_exit)
- /* Kill irq"s */
- mrs r0, cpsr
- orr r0, r0, #(I32_bit|F32_bit)
- msr cpsr_c, r0
- DO_AST
- PULLFRAME
-
- movs pc, lr /* Exit */
-
+ ldr lr, =swi_exit /* Go finish forking, then return */
+ b _C_LABEL(fork_exit) /* to userland via swi_exit code. */
END(fork_trampoline)
diff --git a/sys/arm/include/asmacros.h b/sys/arm/include/asmacros.h
index b849582..469de50 100644
--- a/sys/arm/include/asmacros.h
+++ b/sys/arm/include/asmacros.h
@@ -47,190 +47,6 @@
#ifdef LOCORE
#include "opt_global.h"
-/*
- * ASM macros for pushing and pulling trapframes from the stack
- *
- * These macros are used to handle the irqframe and trapframe structures
- * defined above.
- */
-
-/*
- * 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.
- *
- * NOTE: r13 and r14 are stored separately as a work around for the
- * SA110 rev 2 STM^ bug
- */
-#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
-
-/*
- * 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], #0x0004; /* 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], #0x0004; /* Pull the return address */ \
- add sp, sp, #4 /* Align the stack */
-#else
-#define PULLFRAME \
- ldr r0, [sp], #0x0004; /* 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], #0x0004; /* 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.
- *
- * NOTE: r13 and r14 are stored separately as a work around for the
- * SA110 rev 2 STM^ bug
- */
-#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
-
-/*
- * 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.
- */
-
-#ifdef ARM_TP_ADDRESS
-#define PULLFRAMEFROMSVCANDEXIT \
- ldr r0, [sp], #0x0004; /* 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], #0x0004; /* 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
-#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 DATA(name) \
.data ; \
_ALIGN_DATA ; \
@@ -239,38 +55,14 @@
name:
#ifdef _ARM_ARCH_6
-#define AST_LOCALS
#define GET_CURTHREAD_PTR(tmp) \
mrc p15, 0, tmp, c13, c0, 4
#else
-#define AST_LOCALS
#define GET_CURTHREAD_PTR(tmp) \
ldr tmp, =_C_LABEL(__pcpu);\
ldr tmp, [tmp, #PC_CURTHREAD]
#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:
-
#endif /* LOCORE */
#endif /* _KERNEL */
OpenPOWER on IntegriCloud