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/m68knommu/platform | |
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/m68knommu/platform')
-rw-r--r-- | arch/m68knommu/platform/coldfire/entry.S | 30 |
1 files changed, 10 insertions, 20 deletions
diff --git a/arch/m68knommu/platform/coldfire/entry.S b/arch/m68knommu/platform/coldfire/entry.S index b9ce31966181..f90e6173ccd4 100644 --- a/arch/m68knommu/platform/coldfire/entry.S +++ b/arch/m68knommu/platform/coldfire/entry.S | |||
@@ -36,13 +36,16 @@ | |||
36 | #include <asm/asm-offsets.h> | 36 | #include <asm/asm-offsets.h> |
37 | #include <asm/entry.h> | 37 | #include <asm/entry.h> |
38 | 38 | ||
39 | #ifdef CONFIG_COLDFIRE_SW_A7 | ||
40 | /* | ||
41 | * Define software copies of the supervisor and user stack pointers. | ||
42 | */ | ||
39 | .bss | 43 | .bss |
40 | |||
41 | sw_ksp: | 44 | sw_ksp: |
42 | .long 0 | 45 | .long 0 |
43 | |||
44 | sw_usp: | 46 | sw_usp: |
45 | .long 0 | 47 | .long 0 |
48 | #endif /* CONFIG_COLDFIRE_SW_A7 */ | ||
46 | 49 | ||
47 | .text | 50 | .text |
48 | 51 | ||
@@ -52,6 +55,7 @@ sw_usp: | |||
52 | .globl ret_from_signal | 55 | .globl ret_from_signal |
53 | .globl sys_call_table | 56 | .globl sys_call_table |
54 | .globl inthandler | 57 | .globl inthandler |
58 | .globl fasthandler | ||
55 | 59 | ||
56 | enosys: | 60 | enosys: |
57 | mov.l #sys_ni_syscall,%d3 | 61 | mov.l #sys_ni_syscall,%d3 |
@@ -138,20 +142,7 @@ Luser_return: | |||
138 | jne Lwork_to_do /* still work to do */ | 142 | jne Lwork_to_do /* still work to do */ |
139 | 143 | ||
140 | Lreturn: | 144 | Lreturn: |
141 | move #0x2700,%sr /* disable intrs */ | 145 | RESTORE_USER |
142 | movel sw_usp,%a0 /* get usp */ | ||
143 | movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */ | ||
144 | movel %sp@(PT_OFF_FORMATVEC),%a0@- /* copy exception format/vector/sr */ | ||
145 | moveml %sp@,%d1-%d5/%a0-%a2 | ||
146 | lea %sp@(32),%sp /* space for 8 regs */ | ||
147 | movel %sp@+,%d0 | ||
148 | addql #4,%sp /* orig d0 */ | ||
149 | addl %sp@+,%sp /* stk adj */ | ||
150 | addql #8,%sp /* remove exception */ | ||
151 | movel %sp,sw_ksp /* save ksp */ | ||
152 | subql #8,sw_usp /* set exception */ | ||
153 | movel sw_usp,%sp /* restore usp */ | ||
154 | rte | ||
155 | 146 | ||
156 | Lwork_to_do: | 147 | Lwork_to_do: |
157 | movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ | 148 | movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ |
@@ -201,9 +192,8 @@ ENTRY(inthandler) | |||
201 | */ | 192 | */ |
202 | ENTRY(resume) | 193 | ENTRY(resume) |
203 | movel %a0, %d1 /* get prev thread in d1 */ | 194 | movel %a0, %d1 /* get prev thread in d1 */ |
204 | 195 | RDUSP | |
205 | movel sw_usp,%d0 /* save usp */ | 196 | movel %a2,%a0@(TASK_THREAD+THREAD_USP) |
206 | movel %d0,%a0@(TASK_THREAD+THREAD_USP) | ||
207 | 197 | ||
208 | SAVE_SWITCH_STACK | 198 | SAVE_SWITCH_STACK |
209 | movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */ | 199 | movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */ |
@@ -211,5 +201,5 @@ ENTRY(resume) | |||
211 | RESTORE_SWITCH_STACK | 201 | RESTORE_SWITCH_STACK |
212 | 202 | ||
213 | movel %a1@(TASK_THREAD+THREAD_USP),%a0 /* restore thread user stack */ | 203 | movel %a1@(TASK_THREAD+THREAD_USP),%a0 /* restore thread user stack */ |
214 | movel %a0, sw_usp | 204 | WRUSP |
215 | rts | 205 | rts |