1/* 2 * arch/sh/kernel/cpu/sh2/entry.S 3 * 4 * The SH-2 exception entry 5 * 6 * Copyright (C) 2005,2006 Yoshinori Sato 7 * Copyright (C) 2005 AXE,Inc. 8 * 9 * This file is subject to the terms and conditions of the GNU General Public 10 * License. See the file "COPYING" in the main directory of this archive 11 * for more details. 12 */ 13 14#include <linux/linkage.h> 15#include <asm/asm-offsets.h> 16#include <asm/thread_info.h> 17#include <asm/cpu/mmu_context.h> 18#include <asm/unistd.h> 19#include <asm/errno.h> 20#include <asm/page.h> 21 22/* Offsets to the stack */ 23OFF_R0 = 0 /* Return value. New ABI also arg4 */ 24OFF_R1 = 4 /* New ABI: arg5 */ 25OFF_R2 = 8 /* New ABI: arg6 */ 26OFF_R3 = 12 /* New ABI: syscall_nr */ 27OFF_R4 = 16 /* New ABI: arg0 */ 28OFF_R5 = 20 /* New ABI: arg1 */ 29OFF_R6 = 24 /* New ABI: arg2 */ 30OFF_R7 = 28 /* New ABI: arg3 */ 31OFF_SP = (15*4) 32OFF_PC = (16*4) 33OFF_SR = (16*4+2*4) 34OFF_TRA = (16*4+6*4) 35 36#include <asm/entry-macros.S> 37 38ENTRY(exception_handler) 39 ! already saved r0/r1 40 mov.l r2,@-sp 41 mov.l r3,@-sp 42 mov r0,r1 43 cli 44 mov.l $cpu_mode,r2 45 mov.l @r2,r0 46 mov.l @(5*4,r15),r3 ! previous SR 47 shll2 r3 ! set "S" flag 48 rotl r0 ! T <- "S" flag 49 rotl r0 ! "S" flag is LSB 50 rotcr r3 ! T -> r3:b30 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 mov #1,r0 57 rotr r0 58 rotr r0 59 mov.l r0,@r2 ! enter kernel mode 60 mov.l $current_thread_info,r2 61 mov.l @r2,r2 62 mov #0x20,r0 63 shll8 r0 64 add r2,r0 65 mov r15,r2 ! r2 = user stack top 66 mov r0,r15 ! switch kernel stack 67 add #-4,r15 ! dummy 68 mov.l r1,@-r15 ! TRA 69 sts.l macl, @-r15 70 sts.l mach, @-r15 71 stc.l gbr, @-r15 72 mov.l @(4*4,r2),r0 73 mov.l @(5*4,r2),r1 74 mov.l r1,@-r15 ! original SR 75 sts.l pr,@-r15 76 mov.l r0,@-r15 ! original PC 77 mov r2,r3 78 add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame 79 mov.l r3,@-r15 ! original SP 80 mov.l r14,@-r15 81 mov.l r13,@-r15 82 mov.l r12,@-r15 83 mov.l r11,@-r15 84 mov.l r10,@-r15 85 mov.l r9,@-r15 86 mov.l r8,@-r15 87 mov.l r7,@-r15 88 mov.l r6,@-r15 89 mov.l r5,@-r15 90 mov.l r4,@-r15 91 mov r2,r8 ! copy user -> kernel stack 92 mov.l @r8+,r3 93 mov.l r3,@-r15 94 mov.l @r8+,r2 95 mov.l r2,@-r15 96 mov.l @r8+,r1 97 mov.l r1,@-r15 98 mov.l @r8+,r0 99 bra 2f 100 mov.l r0,@-r15 1011: 102 ! in kernel exception 103 mov #(22-4-4-1)*4+4,r0 104 mov r15,r2 105 sub r0,r15 106 mov.l @r2+,r0 ! old R3 107 mov.l r0,@-r15 108 mov.l @r2+,r0 ! old R2 109 mov.l r0,@-r15 110 mov.l @r2+,r0 ! old R1 111 mov.l r0,@-r15 112 mov.l @r2+,r0 ! old R0 113 mov.l r0,@-r15 114 mov.l @r2+,r3 ! old PC 115 mov.l @r2+,r0 ! old SR 116 add #-4,r2 ! exception frame stub (sr) 117 mov.l r1,@-r2 ! TRA 118 sts.l macl, @-r2 119 sts.l mach, @-r2 120 stc.l gbr, @-r2 121 mov.l r0,@-r2 ! save old SR 122 sts.l pr,@-r2 123 mov.l r3,@-r2 ! save old PC 124 mov r2,r0 125 add #8*4,r0 126 mov.l r0,@-r2 ! save old SP 127 mov.l r14,@-r2 128 mov.l r13,@-r2 129 mov.l r12,@-r2 130 mov.l r11,@-r2 131 mov.l r10,@-r2 132 mov.l r9,@-r2 133 mov.l r8,@-r2 134 mov.l r7,@-r2 135 mov.l r6,@-r2 136 mov.l r5,@-r2 137 mov.l r4,@-r2 138 mov.l @(OFF_R0,r15),r0 139 mov.l @(OFF_R1,r15),r1 140 mov.l @(OFF_R2,r15),r2 141 mov.l @(OFF_R3,r15),r3 1422: 143 mov #OFF_TRA,r8 144 add r15,r8 145 mov.l @r8,r9 146 mov #64,r8 147 cmp/hs r8,r9 148 bt interrupt_entry ! vec >= 64 is interrupt 149 mov #32,r8 150 cmp/hs r8,r9 151 bt trap_entry ! 64 > vec >= 32 is trap 152 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 161 mov r9,r4 162 shll2 r9 163 add r9,r8 164 mov.l @r8,r8 165 mov #0,r9 166 cmp/eq r9,r8 167 bf 3f 168 mov.l 8f,r8 ! unhandled exception 169#if defined(CONFIG_SH_FPU) 17010: 171 mov.l 9f, r8 ! unhandled exception 172#endif 1733: 174 mov.l 5f,r10 175 jmp @r8 176 lds r10,pr 177 178interrupt_entry: 179 mov r9,r4 180 mov r15,r5 181 mov.l 6f,r9 182 mov.l 7f,r8 183 jmp @r8 184 lds r9,pr 185 186 .align 2 1874: .long exception_handling_table 1885: .long ret_from_exception 1896: .long ret_from_irq 1907: .long do_IRQ 1918: .long do_exception_error 192#ifdef CONFIG_SH_FPU 1939: .long fpu_error_trap_handler 194#endif 195 196trap_entry: 197 mov #0x30,r8 198 cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall 199 bt 1f 200 add #-0x10,r9 ! convert SH2 to SH3/4 ABI 2011: 202 shll2 r9 ! TRA 203 mov #OFF_TRA,r8 204 add r15,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 216 .align 2 217#ifdef CONFIG_TRACE_IRQFLAGS 2182: .long trace_hardirqs_on 219#endif 220 221#if defined(CONFIG_SH_STANDARD_BIOS) 222 /* Unwind the stack and jmp to the debug entry */ 223ENTRY(sh_bios_handler) 224 mov r15,r0 225 add #(22-4)*4-4,r0 226 ldc.l @r0+,gbr 227 lds.l @r0+,mach 228 lds.l @r0+,macl 229 mov r15,r0 230 mov.l @(OFF_SP,r0),r1 231 mov #OFF_SR,r2 232 mov.l @(r0,r2),r3 233 mov.l r3,@-r1 234 mov #OFF_SP,r2 235 mov.l @(r0,r2),r3 236 mov.l r3,@-r1 237 mov r15,r0 238 add #(22-4)*4-8,r0 239 mov.l 1f,r2 240 mov.l @r2,r2 241 stc sr,r3 242 mov.l r2,@r0 243 mov.l r3,@r0 244 mov.l r1,@(8,r0) 245 mov.l @r15+, r0 246 mov.l @r15+, r1 247 mov.l @r15+, r2 248 mov.l @r15+, r3 249 mov.l @r15+, r4 250 mov.l @r15+, r5 251 mov.l @r15+, r6 252 mov.l @r15+, r7 253 mov.l @r15+, r8 254 mov.l @r15+, r9 255 mov.l @r15+, r10 256 mov.l @r15+, r11 257 mov.l @r15+, r12 258 mov.l @r15+, r13 259 mov.l @r15+, r14 260 add #8,r15 261 lds.l @r15+, pr 262 rte 263 mov.l @r15+,r15 264 .align 2 2651: .long gdb_vbr_vector 266#endif /* CONFIG_SH_STANDARD_BIOS */ 267 268ENTRY(address_error_trap_handler) 269 mov r15,r4 ! regs 270 mov #OFF_PC,r0 271 mov.l @(r0,r15),r6 ! pc 272 mov.l 1f,r0 273 jmp @r0 274 mov #0,r5 ! writeaccess is unknown 275 .align 2 276 2771: .long do_address_error 278 279restore_all: 280 cli 281#ifdef CONFIG_TRACE_IRQFLAGS 282 mov.l 1f, r0 283 jsr @r0 284 nop 285#endif 286 mov r15,r0 287 mov.l $cpu_mode,r2 288 mov #OFF_SR,r3 289 mov.l @(r0,r3),r1 290 mov.l r1,@r2 291 shll2 r1 ! clear MD bit 292 shlr2 r1 293 mov.l @(OFF_SP,r0),r2 294 add #-8,r2 295 mov.l r2,@(OFF_SP,r0) ! point exception frame top 296 mov.l r1,@(4,r2) ! set sr 297 mov #OFF_PC,r3 298 mov.l @(r0,r3),r1 299 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 307 mov.l $current_thread_info,r1 308 mov.l r0,@r1 309 mov.l @r15+,r0 310 mov.l @r15+,r1 311 mov.l @r15+,r2 312 mov.l @r15+,r3 313 mov.l @r15+,r4 314 mov.l @r15+,r5 315 mov.l @r15+,r6 316 mov.l @r15+,r7 317 mov.l @r15+,r8 318 mov.l @r15+,r9 319 mov.l @r15+,r10 320 mov.l @r15+,r11 321 mov.l @r15+,r12 322 mov.l @r15+,r13 323 mov.l @r15+,r14 324 mov.l @r15,r15 325 rte 326 nop 327 328 .align 2 329#ifdef CONFIG_TRACE_IRQFLAGS 3301: .long trace_hardirqs_off 331#endif 332$current_thread_info: 333 .long __current_thread_info 334$cpu_mode: 335 .long __cpu_mode 336 337! common exception handler 338#include "../../entry-common.S" 339 340 .data 341! cpu operation mode 342! bit30 = MD (compatible SH3/4) 343__cpu_mode: 344 .long 0x40000000 345 346 .section .bss 347__current_thread_info: 348 .long 0 349 350ENTRY(exception_handling_table) 351 .space 4*32 352