Provide alternative trapframe push and pull macros from the StrongARM.

These alternative macros have a workaround for the STM^ bug in revision < 3
StrongARM CPU's that causes incorrect register saving if a cache line fill
is in progress during the STM.
This commit is contained in:
mark 1996-11-23 04:02:40 +00:00
parent 199fcfe651
commit 9c855e4d1b
4 changed files with 192 additions and 10 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: exception.S,v 1.7 1996/10/16 19:32:08 ws Exp $ */
/* $NetBSD: exception.S,v 1.8 1996/11/23 04:02:40 mark Exp $ */
/*
* Copyright (c) 1994-1996 Mark Brinicombe.
@ -54,6 +54,34 @@
* Since the current mode is used, the SVC R14 field is not defined.
*/
#ifdef CPU_SA110
#define PUSHFRAME \
str lr, [sp, #-4]!; /* Push the return address */ \
sub sp, sp, #0x00000004; /* Skip SVC R14 */ \
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_all; /* Put the SPSR on the stack */ \
str r0, [sp, #-4]!;
/*
* PULLFRAME - macro to pull a trap frame from the stack in the current mode
* Since the current mode is used, the SVC R14 field is ignored.
*/
#define PULLFRAME \
ldr r0, [sp], #0x0004; /* Get the SPSR from stack */ \
msr spsr_all, r0; \
ldmia sp, {r0-r14}^; /* Restore the registers (user mode) */ \
mov r0, r0; /* NOP for previous instruction */ \
add sp, sp, #(4*15); /* Adjust the stack pointer */ \
add sp, sp, #0x00000004; /* Skip SVC R14 */ \
ldr lr, [sp], #0x0004; /* Pull the return address */
#else
#define PUSHFRAME \
str lr, [sp, #-4]!; /* Push the return address */ \
sub sp, sp, #0x00000004; /* Skip SVC R14 */ \
@ -76,6 +104,8 @@
add sp, sp, #0x00000004; /* Skip SVC R14 */ \
ldr lr, [sp], #0x0004; /* Pull the return address */
#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
@ -84,6 +114,44 @@
* R14 in SVC mode.
*/
#ifdef CPU_SA110
#define PUSHFRAMEINSVC \
stmdb sp, {r0-r3}; /* Save 4 registers */ \
mov r0, lr; /* Save xxx32 r14 */ \
mov r1, sp; /* Save xxx32 sp */ \
mrs r3, spsr_all; /* Save xxx32 spsr */ \
mrs r2, cpsr_all; /* Get the CPSR */ \
bic r2, r2, #(PSR_MODE); /* Fix for SVC mode */ \
orr r2, r2, #(PSR_SVC32_MODE); \
msr cpsr_all, r2; /* Punch into SVC mode */ \
str r0, [sp, #-4]!; /* Push return address */ \
str lr, [sp, #-4]!; /* Push SVC r14 */ \
msr spsr_all, 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_all; /* Put the SPSR on the stack */ \
str r0, [sp, #-4]!
/*
* 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 R14 register needs to be restored on
* exit.
*/
#define PULLFRAMEFROMSVCANDEXIT \
ldr r0, [sp], #0x0004; /* Get the SPSR from stack */ \
msr spsr_all, r0; /* restore SPSR */ \
ldmia sp, {r0-r14}^; /* Restore the registers (user mode) */ \
mov r0, r0; /* NOP for previous instruction */ \
add sp, sp, #(4*15); /* Adjust the stack pointer */ \
ldmia sp!, {lr, pc}^ /* Restore lr and exit */
#else
#define PUSHFRAMEINSVC \
stmdb sp, {r0-r3}; /* Save 4 registers */ \
mov r0, lr; /* Save xxx32 r14 */ \
@ -116,6 +184,8 @@
ldmdb sp, {r0-r14}^; /* Restore the registers (user mode) */ \
mov r0, r0; /* NOP for previous instruction */ \
ldmia sp!, {lr, pc}^ /* Restore lr and exit */
#endif
sp .req r13
lr .req r14

View File

@ -1,4 +1,4 @@
/* $NetBSD: irq.S,v 1.9 1996/10/15 23:20:40 mark Exp $ */
/* $NetBSD: irq.S,v 1.10 1996/11/23 04:02:42 mark Exp $ */
/*
* Copyright (c) 1994-1996 Mark Brinicombe.
@ -55,6 +55,44 @@
* R14 in SVC mode.
*/
#ifdef CPU_SA110
#define PUSHFRAMEINSVC \
stmdb sp, {r0-r3}; /* Save 4 registers */ \
mov r0, lr; /* Save xxx32 r14 */ \
mov r1, sp; /* Save xxx32 sp */ \
mrs r3, spsr_all; /* Save xxx32 spsr */ \
mrs r2, cpsr_all; /* Get the CPSR */ \
bic r2, r2, #(PSR_MODE); /* Fix for SVC mode */ \
orr r2, r2, #(PSR_SVC32_MODE); \
msr cpsr_all, r2; /* Punch into SVC mode */ \
str r0, [sp, #-4]!; /* Push return address */ \
str lr, [sp, #-4]!; /* Push SVC r14 */ \
msr spsr_all, 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_all; /* Put the SPSR on the stack */ \
str r0, [sp, #-4]!
/*
* 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 R14 register needs to be restored on
* exit.
*/
#define PULLFRAMEFROMSVCANDEXIT \
ldr r0, [sp], #0x0004; /* Get the SPSR from stack */ \
msr spsr_all, r0; /* restore SPSR */ \
ldmia sp, {r0-r14}^; /* Restore the registers (user mode) */ \
mov r0, r0; /* NOP for previous instruction */ \
add sp, sp, #(4*15); /* Adjust the stack pointer */ \
ldmia sp!, {lr, pc}^ /* Restore lr and exit */
#else
#define PUSHFRAMEINSVC \
stmdb sp, {r0-r3}; /* Save 4 registers */ \
mov r0, lr; /* Save xxx32 r14 */ \
@ -87,6 +125,7 @@
ldmdb sp, {r0-r14}^; /* Restore the registers (usr mode) */ \
mov r0, r0; /* NOP for previous instruction */ \
ldmia sp!, {lr, pc}^ /* Restore lr and exit */
#endif
sp .req r13
lr .req r14

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.S,v 1.14 1996/10/16 19:32:18 ws Exp $ */
/* $NetBSD: locore.S,v 1.15 1996/11/23 04:02:41 mark Exp $ */
/*
* Copyright (C) 1994 Mark Brinicombe
@ -38,10 +38,38 @@
#include <machine/param.h>
#include <sys/syscall.h>
/* What size shoudl this really be ? It is only used by init_arm() */
/* What size should this really be ? It is only used by init_arm() */
#define INIT_ARM_STACK_SIZE 2048
#ifdef CPU_SA110
#define PUSHFRAME \
str lr, [sp, #-4]!; /* Push the return address */ \
sub sp, sp, #0x00000004; /* Skip SVC R14 */ \
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_all; /* Put the SPSR on the stack */ \
str r0, [sp, #-4]!;
/*
* PULLFRAME - macro to pull a trap frame from the stack in the current mode
* Since the current mode is used, the SVC R14 field is ignored.
*/
#define PULLFRAME \
ldr r0, [sp], #0x0004; /* Get the SPSR from stack */ \
msr spsr_all, r0; \
ldmia sp, {r0-r14}^; /* Restore the registers (user mode) */ \
mov r0, r0; /* NOP for previous instruction */ \
add sp, sp, #(4*15); /* Adjust the stack pointer */ \
add sp, sp, #0x00000004; /* Skip SVC R14 */ \
ldr lr, [sp], #0x0004; /* Pull the return address */
#else
#define PUSHFRAME \
str lr, [sp, #-4]!; /* Push the return address */ \
sub sp, sp, #0x00000004; /* Skip SVC R14 */ \
@ -58,6 +86,7 @@
mov r0, r0; /* NOP for previous instruction */ \
add sp, sp, #0x00000004; /* Skip SVC R14 */ \
ldr lr, [sp], #0x0004; /* Pull the return address */
#endif
/* register equates */
fp .req r11
@ -95,11 +124,16 @@ L1:
mov sp, r0
mov fp, #0x00000000 /* trace back starts here */
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #4
/* Setup an initial trap frame for start_init to use */
PUSHFRAME
mov fp, #0x00000000 /* trace back starts here */
/* mov fp, #0x00000000*/ /* trace back starts here */
mov r0, sp /* parameter to main is trap frame*/
bl _main /* Lets light the flame and start her up */
@ -538,7 +572,7 @@ ENTRY(setjmp)
.global _longjmp
ENTRY(longjmp)
ldmia r2, {r4-r14}
ldmia r0, {r4-r14}
mov r0, #0x00000001
mov r15, r14

View File

@ -1,4 +1,4 @@
/* $NetBSD: iomd_irq.S,v 1.9 1996/10/15 23:20:40 mark Exp $ */
/* $NetBSD: iomd_irq.S,v 1.10 1996/11/23 04:02:42 mark Exp $ */
/*
* Copyright (c) 1994-1996 Mark Brinicombe.
@ -55,6 +55,44 @@
* R14 in SVC mode.
*/
#ifdef CPU_SA110
#define PUSHFRAMEINSVC \
stmdb sp, {r0-r3}; /* Save 4 registers */ \
mov r0, lr; /* Save xxx32 r14 */ \
mov r1, sp; /* Save xxx32 sp */ \
mrs r3, spsr_all; /* Save xxx32 spsr */ \
mrs r2, cpsr_all; /* Get the CPSR */ \
bic r2, r2, #(PSR_MODE); /* Fix for SVC mode */ \
orr r2, r2, #(PSR_SVC32_MODE); \
msr cpsr_all, r2; /* Punch into SVC mode */ \
str r0, [sp, #-4]!; /* Push return address */ \
str lr, [sp, #-4]!; /* Push SVC r14 */ \
msr spsr_all, 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_all; /* Put the SPSR on the stack */ \
str r0, [sp, #-4]!
/*
* 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 R14 register needs to be restored on
* exit.
*/
#define PULLFRAMEFROMSVCANDEXIT \
ldr r0, [sp], #0x0004; /* Get the SPSR from stack */ \
msr spsr_all, r0; /* restore SPSR */ \
ldmia sp, {r0-r14}^; /* Restore the registers (user mode) */ \
mov r0, r0; /* NOP for previous instruction */ \
add sp, sp, #(4*15); /* Adjust the stack pointer */ \
ldmia sp!, {lr, pc}^ /* Restore lr and exit */
#else
#define PUSHFRAMEINSVC \
stmdb sp, {r0-r3}; /* Save 4 registers */ \
mov r0, lr; /* Save xxx32 r14 */ \
@ -87,6 +125,7 @@
ldmdb sp, {r0-r14}^; /* Restore the registers (usr mode) */ \
mov r0, r0; /* NOP for previous instruction */ \
ldmia sp!, {lr, pc}^ /* Restore lr and exit */
#endif
sp .req r13
lr .req r14