diff options
author | Greg Ungerer <gerg@uclinux.org> | 2010-11-03 23:53:26 -0400 |
---|---|---|
committer | Greg Ungerer <gerg@uclinux.org> | 2011-01-05 00:19:18 -0500 |
commit | 1c83af5f9d7e15a091f11394ad5916a7dcf1a99e (patch) | |
tree | aa41743fb552319bb53959a7df228233d4f04ba2 /arch/m68k/include/asm/entry_no.h | |
parent | 0762346034a3e94f9c3a5fe8d7c4bcaffbc1cd53 (diff) |
m68knommu: use user stack pointer hardware on some ColdFire cores
The more modern ColdFire parts (even if based on older version cores)
have separate user and supervisor stack pointers (a7 register).
Modify the ColdFire CPU setup and exception code to enable and use
this on parts that have it.
Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Diffstat (limited to 'arch/m68k/include/asm/entry_no.h')
-rw-r--r-- | arch/m68k/include/asm/entry_no.h | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/arch/m68k/include/asm/entry_no.h b/arch/m68k/include/asm/entry_no.h index 26be277394f9..627d69bacc58 100644 --- a/arch/m68k/include/asm/entry_no.h +++ b/arch/m68k/include/asm/entry_no.h | |||
@@ -42,12 +42,16 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #ifdef CONFIG_COLDFIRE | 44 | #ifdef CONFIG_COLDFIRE |
45 | #ifdef CONFIG_COLDFIRE_SW_A7 | ||
45 | /* | 46 | /* |
46 | * This is made a little more tricky on the ColdFire. There is no | 47 | * This is made a little more tricky on older ColdFires. There is no |
47 | * separate kernel and user stack pointers. Need to artificially | 48 | * separate supervisor and user stack pointers. Need to artificially |
48 | * construct a usp in software... When doing this we need to disable | 49 | * construct a usp in software... When doing this we need to disable |
49 | * interrupts, otherwise bad things could happen. | 50 | * interrupts, otherwise bad things will happen. |
50 | */ | 51 | */ |
52 | .globl sw_usp | ||
53 | .globl sw_ksp | ||
54 | |||
51 | .macro SAVE_ALL | 55 | .macro SAVE_ALL |
52 | move #0x2700,%sr /* disable intrs */ | 56 | move #0x2700,%sr /* disable intrs */ |
53 | btst #5,%sp@(2) /* from user? */ | 57 | btst #5,%sp@(2) /* from user? */ |
@@ -74,9 +78,7 @@ | |||
74 | 7: | 78 | 7: |
75 | .endm | 79 | .endm |
76 | 80 | ||
77 | .macro RESTORE_ALL | 81 | .macro RESTORE_USER |
78 | btst #5,%sp@(PT_SR) /* going user? */ | ||
79 | bnes 8f /* no, skip */ | ||
80 | move #0x2700,%sr /* disable intrs */ | 82 | move #0x2700,%sr /* disable intrs */ |
81 | movel sw_usp,%a0 /* get usp */ | 83 | movel sw_usp,%a0 /* get usp */ |
82 | movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */ | 84 | movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */ |
@@ -91,19 +93,22 @@ | |||
91 | subql #8,sw_usp /* set exception */ | 93 | subql #8,sw_usp /* set exception */ |
92 | movel sw_usp,%sp /* restore usp */ | 94 | movel sw_usp,%sp /* restore usp */ |
93 | rte | 95 | rte |
94 | 8: | ||
95 | moveml %sp@,%d1-%d5/%a0-%a2 | ||
96 | lea %sp@(32),%sp /* space for 8 regs */ | ||
97 | movel %sp@+,%d0 | ||
98 | addql #4,%sp /* orig d0 */ | ||
99 | addl %sp@+,%sp /* stkadj */ | ||
100 | rte | ||
101 | .endm | 96 | .endm |
102 | 97 | ||
98 | .macro RDUSP | ||
99 | movel sw_usp,%a2 | ||
100 | .endm | ||
101 | |||
102 | .macro WRUSP | ||
103 | movel %a0,sw_usp | ||
104 | .endm | ||
105 | |||
106 | #else /* !CONFIG_COLDFIRE_SW_A7 */ | ||
103 | /* | 107 | /* |
104 | * Quick exception save, use current stack only. | 108 | * Modern ColdFire parts have separate supervisor and user stack |
109 | * pointers. Simple load and restore macros for this case. | ||
105 | */ | 110 | */ |
106 | .macro SAVE_LOCAL | 111 | .macro SAVE_ALL |
107 | move #0x2700,%sr /* disable intrs */ | 112 | move #0x2700,%sr /* disable intrs */ |
108 | clrl %sp@- /* stkadj */ | 113 | clrl %sp@- /* stkadj */ |
109 | movel %d0,%sp@- /* orig d0 */ | 114 | movel %d0,%sp@- /* orig d0 */ |
@@ -112,7 +117,7 @@ | |||
112 | moveml %d1-%d5/%a0-%a2,%sp@ | 117 | moveml %d1-%d5/%a0-%a2,%sp@ |
113 | .endm | 118 | .endm |
114 | 119 | ||
115 | .macro RESTORE_LOCAL | 120 | .macro RESTORE_USER |
116 | moveml %sp@,%d1-%d5/%a0-%a2 | 121 | moveml %sp@,%d1-%d5/%a0-%a2 |
117 | lea %sp@(32),%sp /* space for 8 regs */ | 122 | lea %sp@(32),%sp /* space for 8 regs */ |
118 | movel %sp@+,%d0 | 123 | movel %sp@+,%d0 |
@@ -121,6 +126,18 @@ | |||
121 | rte | 126 | rte |
122 | .endm | 127 | .endm |
123 | 128 | ||
129 | .macro RDUSP | ||
130 | /*move %usp,%a2*/ | ||
131 | .word 0x4e6a | ||
132 | .endm | ||
133 | |||
134 | .macro WRUSP | ||
135 | /*move %a0,%usp*/ | ||
136 | .word 0x4e60 | ||
137 | .endm | ||
138 | |||
139 | #endif /* !CONFIG_COLDFIRE_SW_A7 */ | ||
140 | |||
124 | .macro SAVE_SWITCH_STACK | 141 | .macro SAVE_SWITCH_STACK |
125 | lea %sp@(-24),%sp /* 6 regs */ | 142 | lea %sp@(-24),%sp /* 6 regs */ |
126 | moveml %a3-%a6/%d6-%d7,%sp@ | 143 | moveml %a3-%a6/%d6-%d7,%sp@ |
@@ -131,14 +148,6 @@ | |||
131 | lea %sp@(24),%sp /* 6 regs */ | 148 | lea %sp@(24),%sp /* 6 regs */ |
132 | .endm | 149 | .endm |
133 | 150 | ||
134 | /* | ||
135 | * Software copy of the user and kernel stack pointers... Ugh... | ||
136 | * Need these to get around ColdFire not having separate kernel | ||
137 | * and user stack pointers. | ||
138 | */ | ||
139 | .globl sw_usp | ||
140 | .globl sw_ksp | ||
141 | |||
142 | #else /* !CONFIG_COLDFIRE */ | 151 | #else /* !CONFIG_COLDFIRE */ |
143 | 152 | ||
144 | /* | 153 | /* |
@@ -167,6 +176,6 @@ | |||
167 | moveml %sp@+,%a3-%a6/%d6-%d7 | 176 | moveml %sp@+,%a3-%a6/%d6-%d7 |
168 | .endm | 177 | .endm |
169 | 178 | ||
170 | #endif /* !CONFIG_COLDFIRE */ | 179 | #endif /* !COLDFIRE_SW_A7 */ |
171 | #endif /* __ASSEMBLY__ */ | 180 | #endif /* __ASSEMBLY__ */ |
172 | #endif /* __M68KNOMMU_ENTRY_H */ | 181 | #endif /* __M68KNOMMU_ENTRY_H */ |