diff options
| author | Yoshinori Sato <ysato@users.sourceforge.jp> | 2008-07-09 12:20:03 -0400 |
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2008-07-28 05:10:34 -0400 |
| commit | 6e80f5e8c4c685eb7bc34c3916e3d986b03f9981 (patch) | |
| tree | 3c8768bdb748ba6b1bc923d798b1a8e3b91df4eb /arch/sh/kernel/cpu/sh2 | |
| parent | cafd63b0076b78bc8f114abbeb724c7e5f5bfe5d (diff) | |
sh2(A) exception handler update
This patch is
By sh2
- Remove duplicate code
- Reduce stack usage
- Cleanup and little optimize
By sh2a
- Add missing handler(256 to 511)
- Use sh2a instructions handler
Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/cpu/sh2')
| -rw-r--r-- | arch/sh/kernel/cpu/sh2/entry.S | 133 | ||||
| -rw-r--r-- | arch/sh/kernel/cpu/sh2/ex.S | 15 |
2 files changed, 59 insertions, 89 deletions
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S index 0fc89069d8c..ee894e5a45e 100644 --- a/arch/sh/kernel/cpu/sh2/entry.S +++ b/arch/sh/kernel/cpu/sh2/entry.S | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * The SH-2 exception entry | 4 | * The SH-2 exception entry |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2005,2006 Yoshinori Sato | 6 | * Copyright (C) 2005-2008 Yoshinori Sato |
| 7 | * Copyright (C) 2005 AXE,Inc. | 7 | * Copyright (C) 2005 AXE,Inc. |
| 8 | * | 8 | * |
| 9 | * This file is subject to the terms and conditions of the GNU General Public | 9 | * This file is subject to the terms and conditions of the GNU General Public |
| @@ -36,43 +36,41 @@ OFF_TRA = (16*4+6*4) | |||
| 36 | #include <asm/entry-macros.S> | 36 | #include <asm/entry-macros.S> |
| 37 | 37 | ||
| 38 | ENTRY(exception_handler) | 38 | ENTRY(exception_handler) |
| 39 | ! already saved r0/r1 | 39 | ! stack |
| 40 | ! r0 <- point sp | ||
| 41 | ! r1 | ||
| 42 | ! pc | ||
| 43 | ! sr | ||
| 44 | ! r0 = temporary | ||
| 45 | ! r1 = vector (pseudo EXPEVT / INTEVT / TRA) | ||
| 40 | mov.l r2,@-sp | 46 | mov.l r2,@-sp |
| 41 | mov.l r3,@-sp | 47 | mov.l r3,@-sp |
| 42 | mov r0,r1 | ||
| 43 | cli | 48 | cli |
| 44 | mov.l $cpu_mode,r2 | 49 | mov.l $cpu_mode,r2 |
| 45 | mov.l @r2,r0 | 50 | mov.l @r2,r0 |
| 46 | mov.l @(5*4,r15),r3 ! previous SR | 51 | mov.l @(5*4,r15),r3 ! previous SR |
| 47 | shll2 r3 ! set "S" flag | 52 | or r0,r3 ! set MD |
| 48 | rotl r0 ! T <- "S" flag | 53 | tst r0,r0 |
| 49 | rotl r0 ! "S" flag is LSB | 54 | bf/s 1f ! previous mode check |
| 50 | rotcr r3 ! T -> r3:b30 | 55 | mov.l r3,@(5*4,r15) ! update SR |
| 51 | shlr r3 | ||
| 52 | shlr r0 | ||
| 53 | bt/s 1f | ||
| 54 | mov.l r3,@(5*4,r15) ! copy cpu mode to SR | ||
| 55 | ! switch to kernel mode | 56 | ! switch to kernel mode |
| 56 | mov #1,r0 | 57 | mov.l __md_bit,r0 |
| 57 | rotr r0 | ||
| 58 | rotr r0 | ||
| 59 | mov.l r0,@r2 ! enter kernel mode | 58 | mov.l r0,@r2 ! enter kernel mode |
| 60 | mov.l $current_thread_info,r2 | 59 | mov.l $current_thread_info,r2 |
| 61 | mov.l @r2,r2 | 60 | mov.l @r2,r2 |
| 62 | mov #0x20,r0 | 61 | mov #(THREAD_SIZE >> 8),r0 |
| 63 | shll8 r0 | 62 | shll8 r0 |
| 64 | add r2,r0 | 63 | add r2,r0 |
| 65 | mov r15,r2 ! r2 = user stack top | 64 | mov r15,r2 ! r2 = user stack top |
| 66 | mov r0,r15 ! switch kernel stack | 65 | mov r0,r15 ! switch kernel stack |
| 67 | add #-4,r15 ! dummy | ||
| 68 | mov.l r1,@-r15 ! TRA | 66 | mov.l r1,@-r15 ! TRA |
| 69 | sts.l macl, @-r15 | 67 | sts.l macl, @-r15 |
| 70 | sts.l mach, @-r15 | 68 | sts.l mach, @-r15 |
| 71 | stc.l gbr, @-r15 | 69 | stc.l gbr, @-r15 |
| 72 | mov.l @(4*4,r2),r0 | 70 | mov.l @(5*4,r2),r0 |
| 73 | mov.l @(5*4,r2),r1 | 71 | mov.l r0,@-r15 ! original SR |
| 74 | mov.l r1,@-r15 ! original SR | ||
| 75 | sts.l pr,@-r15 | 72 | sts.l pr,@-r15 |
| 73 | mov.l @(4*4,r2),r0 | ||
| 76 | mov.l r0,@-r15 ! original PC | 74 | mov.l r0,@-r15 ! original PC |
| 77 | mov r2,r3 | 75 | mov r2,r3 |
| 78 | add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame | 76 | add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame |
| @@ -88,14 +86,15 @@ ENTRY(exception_handler) | |||
| 88 | mov.l r6,@-r15 | 86 | mov.l r6,@-r15 |
| 89 | mov.l r5,@-r15 | 87 | mov.l r5,@-r15 |
| 90 | mov.l r4,@-r15 | 88 | mov.l r4,@-r15 |
| 89 | mov r1,r9 ! save TRA | ||
| 91 | mov r2,r8 ! copy user -> kernel stack | 90 | mov r2,r8 ! copy user -> kernel stack |
| 92 | mov.l @r8+,r3 | 91 | mov.l @(0,r8),r3 |
| 93 | mov.l r3,@-r15 | 92 | mov.l r3,@-r15 |
| 94 | mov.l @r8+,r2 | 93 | mov.l @(4,r8),r2 |
| 95 | mov.l r2,@-r15 | 94 | mov.l r2,@-r15 |
| 96 | mov.l @r8+,r1 | 95 | mov.l @(12,r8),r1 |
| 97 | mov.l r1,@-r15 | 96 | mov.l r1,@-r15 |
| 98 | mov.l @r8+,r0 | 97 | mov.l @(8,r8),r0 |
| 99 | bra 2f | 98 | bra 2f |
| 100 | mov.l r0,@-r15 | 99 | mov.l r0,@-r15 |
| 101 | 1: | 100 | 1: |
| @@ -107,10 +106,11 @@ ENTRY(exception_handler) | |||
| 107 | mov.l r0,@-r15 | 106 | mov.l r0,@-r15 |
| 108 | mov.l @r2+,r0 ! old R2 | 107 | mov.l @r2+,r0 ! old R2 |
| 109 | mov.l r0,@-r15 | 108 | mov.l r0,@-r15 |
| 110 | mov.l @r2+,r0 ! old R1 | 109 | mov.l @(4,r2),r0 ! old R1 |
| 111 | mov.l r0,@-r15 | ||
| 112 | mov.l @r2+,r0 ! old R0 | ||
| 113 | mov.l r0,@-r15 | 110 | mov.l r0,@-r15 |
| 111 | mov.l @r2,r0 ! old R0 | ||
| 112 | mov.l r0,@-r15 | ||
| 113 | add #8,r2 | ||
| 114 | mov.l @r2+,r3 ! old PC | 114 | mov.l @r2+,r3 ! old PC |
| 115 | mov.l @r2+,r0 ! old SR | 115 | mov.l @r2+,r0 ! old SR |
| 116 | add #-4,r2 ! exception frame stub (sr) | 116 | add #-4,r2 ! exception frame stub (sr) |
| @@ -135,14 +135,12 @@ ENTRY(exception_handler) | |||
| 135 | mov.l r6,@-r2 | 135 | mov.l r6,@-r2 |
| 136 | mov.l r5,@-r2 | 136 | mov.l r5,@-r2 |
| 137 | mov.l r4,@-r2 | 137 | mov.l r4,@-r2 |
| 138 | mov r1,r9 | ||
| 138 | mov.l @(OFF_R0,r15),r0 | 139 | mov.l @(OFF_R0,r15),r0 |
| 139 | mov.l @(OFF_R1,r15),r1 | 140 | mov.l @(OFF_R1,r15),r1 |
| 140 | mov.l @(OFF_R2,r15),r2 | 141 | mov.l @(OFF_R2,r15),r2 |
| 141 | mov.l @(OFF_R3,r15),r3 | 142 | mov.l @(OFF_R3,r15),r3 |
| 142 | 2: | 143 | 2: |
| 143 | mov #OFF_TRA,r8 | ||
| 144 | add r15,r8 | ||
| 145 | mov.l @r8,r9 | ||
| 146 | mov #64,r8 | 144 | mov #64,r8 |
| 147 | cmp/hs r8,r9 | 145 | cmp/hs r8,r9 |
| 148 | bt interrupt_entry ! vec >= 64 is interrupt | 146 | bt interrupt_entry ! vec >= 64 is interrupt |
| @@ -150,26 +148,14 @@ ENTRY(exception_handler) | |||
| 150 | cmp/hs r8,r9 | 148 | cmp/hs r8,r9 |
| 151 | bt trap_entry ! 64 > vec >= 32 is trap | 149 | bt trap_entry ! 64 > vec >= 32 is trap |
| 152 | 150 | ||
| 153 | #if defined(CONFIG_SH_FPU) | ||
| 154 | mov #13,r8 | ||
| 155 | cmp/eq r8,r9 | ||
| 156 | bt 10f ! fpu | ||
| 157 | nop | ||
| 158 | #endif | ||
| 159 | |||
| 160 | mov.l 4f,r8 | 151 | mov.l 4f,r8 |
| 161 | mov r9,r4 | 152 | mov r9,r4 |
| 162 | shll2 r9 | 153 | shll2 r9 |
| 163 | add r9,r8 | 154 | add r9,r8 |
| 164 | mov.l @r8,r8 | 155 | mov.l @r8,r8 ! exception handler address |
| 165 | mov #0,r9 | 156 | tst r8,r8 |
| 166 | cmp/eq r9,r8 | ||
| 167 | bf 3f | 157 | bf 3f |
| 168 | mov.l 8f,r8 ! unhandled exception | 158 | mov.l 8f,r8 ! unhandled exception |
| 169 | #if defined(CONFIG_SH_FPU) | ||
| 170 | 10: | ||
| 171 | mov.l 9f, r8 ! unhandled exception | ||
| 172 | #endif | ||
| 173 | 3: | 159 | 3: |
| 174 | mov.l 5f,r10 | 160 | mov.l 5f,r10 |
| 175 | jmp @r8 | 161 | jmp @r8 |
| @@ -188,10 +174,7 @@ interrupt_entry: | |||
| 188 | 5: .long ret_from_exception | 174 | 5: .long ret_from_exception |
| 189 | 6: .long ret_from_irq | 175 | 6: .long ret_from_irq |
| 190 | 7: .long do_IRQ | 176 | 7: .long do_IRQ |
| 191 | 8: .long do_exception_error | 177 | 8: .long exception_error |
| 192 | #ifdef CONFIG_SH_FPU | ||
| 193 | 9: .long fpu_error_trap_handler | ||
| 194 | #endif | ||
| 195 | 178 | ||
| 196 | trap_entry: | 179 | trap_entry: |
| 197 | mov #0x30,r8 | 180 | mov #0x30,r8 |
| @@ -200,24 +183,9 @@ trap_entry: | |||
| 200 | add #-0x10,r9 ! convert SH2 to SH3/4 ABI | 183 | add #-0x10,r9 ! convert SH2 to SH3/4 ABI |
| 201 | 1: | 184 | 1: |
| 202 | shll2 r9 ! TRA | 185 | shll2 r9 ! TRA |
| 203 | mov #OFF_TRA,r8 | 186 | bra system_call ! jump common systemcall entry |
| 204 | add r15,r8 | 187 | mov r9,r8 |
| 205 | mov.l r9,@r8 | ||
| 206 | mov r9,r8 | ||
| 207 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
| 208 | mov.l 2f, r9 | ||
| 209 | jsr @r9 | ||
| 210 | nop | ||
| 211 | #endif | ||
| 212 | sti | ||
| 213 | bra system_call | ||
| 214 | nop | ||
| 215 | 188 | ||
| 216 | .align 2 | ||
| 217 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
| 218 | 2: .long trace_hardirqs_on | ||
| 219 | #endif | ||
| 220 | |||
| 221 | #if defined(CONFIG_SH_STANDARD_BIOS) | 189 | #if defined(CONFIG_SH_STANDARD_BIOS) |
| 222 | /* Unwind the stack and jmp to the debug entry */ | 190 | /* Unwind the stack and jmp to the debug entry */ |
| 223 | ENTRY(sh_bios_handler) | 191 | ENTRY(sh_bios_handler) |
| @@ -240,7 +208,7 @@ ENTRY(sh_bios_handler) | |||
| 240 | mov.l @r2,r2 | 208 | mov.l @r2,r2 |
| 241 | stc sr,r3 | 209 | stc sr,r3 |
| 242 | mov.l r2,@r0 | 210 | mov.l r2,@r0 |
| 243 | mov.l r3,@r0 | 211 | mov.l r3,@(4,r0) |
| 244 | mov.l r1,@(8,r0) | 212 | mov.l r1,@(8,r0) |
| 245 | mov.l @r15+, r0 | 213 | mov.l @r15+, r0 |
| 246 | mov.l @r15+, r1 | 214 | mov.l @r15+, r1 |
| @@ -272,22 +240,30 @@ ENTRY(address_error_trap_handler) | |||
| 272 | mov.l 1f,r0 | 240 | mov.l 1f,r0 |
| 273 | jmp @r0 | 241 | jmp @r0 |
| 274 | mov #0,r5 ! writeaccess is unknown | 242 | mov #0,r5 ! writeaccess is unknown |
| 275 | .align 2 | ||
| 276 | 243 | ||
| 244 | .align 2 | ||
| 277 | 1: .long do_address_error | 245 | 1: .long do_address_error |
| 278 | 246 | ||
| 279 | restore_all: | 247 | restore_all: |
| 280 | cli | 248 | stc sr,r0 |
| 281 | #ifdef CONFIG_TRACE_IRQFLAGS | 249 | or #0xf0,r0 |
| 282 | mov.l 1f, r0 | 250 | ldc r0,sr ! all interrupt block (same BL = 1) |
| 283 | jsr @r0 | 251 | ! restore special register |
| 284 | nop | 252 | ! overlap exception frame |
| 285 | #endif | 253 | mov r15,r0 |
| 254 | add #17*4,r0 | ||
| 255 | lds.l @r0+,pr | ||
| 256 | add #4,r0 | ||
| 257 | ldc.l @r0+,gbr | ||
| 258 | lds.l @r0+,mach | ||
| 259 | lds.l @r0+,macl | ||
| 286 | mov r15,r0 | 260 | mov r15,r0 |
| 287 | mov.l $cpu_mode,r2 | 261 | mov.l $cpu_mode,r2 |
| 288 | mov #OFF_SR,r3 | 262 | mov #OFF_SR,r3 |
| 289 | mov.l @(r0,r3),r1 | 263 | mov.l @(r0,r3),r1 |
| 290 | mov.l r1,@r2 | 264 | mov.l __md_bit,r3 |
| 265 | and r1,r3 ! copy MD bit | ||
| 266 | mov.l r3,@r2 | ||
| 291 | shll2 r1 ! clear MD bit | 267 | shll2 r1 ! clear MD bit |
| 292 | shlr2 r1 | 268 | shlr2 r1 |
| 293 | mov.l @(OFF_SP,r0),r2 | 269 | mov.l @(OFF_SP,r0),r2 |
| @@ -297,12 +273,6 @@ restore_all: | |||
| 297 | mov #OFF_PC,r3 | 273 | mov #OFF_PC,r3 |
| 298 | mov.l @(r0,r3),r1 | 274 | mov.l @(r0,r3),r1 |
| 299 | mov.l r1,@r2 ! set pc | 275 | mov.l r1,@r2 ! set pc |
| 300 | add #4*16+4,r0 | ||
| 301 | lds.l @r0+,pr | ||
| 302 | add #4,r0 ! skip sr | ||
| 303 | ldc.l @r0+,gbr | ||
| 304 | lds.l @r0+,mach | ||
| 305 | lds.l @r0+,macl | ||
| 306 | get_current_thread_info r0, r1 | 276 | get_current_thread_info r0, r1 |
| 307 | mov.l $current_thread_info,r1 | 277 | mov.l $current_thread_info,r1 |
| 308 | mov.l r0,@r1 | 278 | mov.l r0,@r1 |
| @@ -326,9 +296,8 @@ restore_all: | |||
| 326 | nop | 296 | nop |
| 327 | 297 | ||
| 328 | .align 2 | 298 | .align 2 |
| 329 | #ifdef CONFIG_TRACE_IRQFLAGS | 299 | __md_bit: |
| 330 | 1: .long trace_hardirqs_off | 300 | .long 0x40000000 |
| 331 | #endif | ||
| 332 | $current_thread_info: | 301 | $current_thread_info: |
| 333 | .long __current_thread_info | 302 | .long __current_thread_info |
| 334 | $cpu_mode: | 303 | $cpu_mode: |
diff --git a/arch/sh/kernel/cpu/sh2/ex.S b/arch/sh/kernel/cpu/sh2/ex.S index 6d285af7846..85b0bf81fc1 100644 --- a/arch/sh/kernel/cpu/sh2/ex.S +++ b/arch/sh/kernel/cpu/sh2/ex.S | |||
| @@ -18,16 +18,17 @@ | |||
| 18 | exception_entry: | 18 | exception_entry: |
| 19 | no = 0 | 19 | no = 0 |
| 20 | .rept 256 | 20 | .rept 256 |
| 21 | mov.l r0,@-sp | 21 | mov.l r1,@-sp |
| 22 | mov #no,r0 | ||
| 23 | bra exception_trampoline | 22 | bra exception_trampoline |
| 24 | and #0xff,r0 | 23 | mov #no,r1 |
| 25 | no = no + 1 | 24 | no = no + 1 |
| 26 | .endr | 25 | .endr |
| 27 | exception_trampoline: | 26 | exception_trampoline: |
| 28 | mov.l r1,@-sp | 27 | mov.l r0,@-sp |
| 29 | mov.l $exception_handler,r1 | 28 | mov.l $exception_handler,r0 |
| 30 | jmp @r1 | 29 | extu.b r1,r1 |
| 30 | jmp @r0 | ||
| 31 | extu.w r1,r1 | ||
| 31 | 32 | ||
| 32 | .align 2 | 33 | .align 2 |
| 33 | $exception_entry: | 34 | $exception_entry: |
| @@ -41,6 +42,6 @@ $exception_handler: | |||
| 41 | ENTRY(vbr_base) | 42 | ENTRY(vbr_base) |
| 42 | vector = 0 | 43 | vector = 0 |
| 43 | .rept 256 | 44 | .rept 256 |
| 44 | .long exception_entry + vector * 8 | 45 | .long exception_entry + vector * 6 |
| 45 | vector = vector + 1 | 46 | vector = vector + 1 |
| 46 | .endr | 47 | .endr |
