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 mov.l 4f,r8 153 mov r9,r4 154 shll2 r9 155 add r9,r8 156 mov.l @r8,r8 157 mov #0,r9 158 cmp/eq r9,r8 159 bf 3f 160 mov.l 8f,r8 ! unhandled exception 1613: 162 mov.l 5f,r10 163 jmp @r8 164 lds r10,pr 165 166interrupt_entry: 167 mov r9,r4 168 mov.l 6f,r9 169 mov.l 7f,r8 170 jmp @r8 171 lds r9,pr 172 173 .align 2 1744: .long exception_handling_table 1755: .long ret_from_exception 1766: .long ret_from_irq 1777: .long do_IRQ 1788: .long do_exception_error 179 180trap_entry: 181 /* verbose BUG trapa entry check */ 182 mov #0x3e,r8 183 cmp/ge r8,r9 184 bf/s 1f 185 add #-0x10,r9 186 add #0x10,r9 1871: 188 shll2 r9 ! TRA 189 mov #OFF_TRA,r8 190 add r15,r8 191 mov.l r9,@r8 192 mov r9,r8 193#ifdef CONFIG_TRACE_IRQFLAGS 194 mov.l 2f, r9 195 jsr @r9 196 nop 197#endif 198 sti 199 bra system_call 200 nop 201 202 .align 2 203#ifdef CONFIG_TRACE_IRQFLAGS 2042: .long trace_hardirqs_on 205#endif 206 207#if defined(CONFIG_SH_STANDARD_BIOS) 208 /* Unwind the stack and jmp to the debug entry */ 209debug_kernel_fw: 210 mov r15,r0 211 add #(22-4)*4-4,r0 212 ldc.l @r0+,gbr 213 lds.l @r0+,mach 214 lds.l @r0+,macl 215 mov r15,r0 216 mov.l @(OFF_SP,r0),r1 217 mov #OFF_SR,r2 218 mov.l @(r0,r2),r3 219 mov.l r3,@-r1 220 mov #OFF_SP,r2 221 mov.l @(r0,r2),r3 222 mov.l r3,@-r1 223 mov r15,r0 224 add #(22-4)*4-8,r0 225 mov.l 1f,r2 226 mov.l @r2,r2 227 stc sr,r3 228 mov.l r2,@r0 229 mov.l r3,@r0 230 mov.l r1,@(8,r0) 231 mov.l @r15+, r0 232 mov.l @r15+, r1 233 mov.l @r15+, r2 234 mov.l @r15+, r3 235 mov.l @r15+, r4 236 mov.l @r15+, r5 237 mov.l @r15+, r6 238 mov.l @r15+, r7 239 mov.l @r15+, r8 240 mov.l @r15+, r9 241 mov.l @r15+, r10 242 mov.l @r15+, r11 243 mov.l @r15+, r12 244 mov.l @r15+, r13 245 mov.l @r15+, r14 246 add #8,r15 247 lds.l @r15+, pr 248 rte 249 mov.l @r15+,r15 250 .align 2 2511: .long gdb_vbr_vector 252#endif /* CONFIG_SH_STANDARD_BIOS */ 253 254ENTRY(address_error_handler) 255 mov r15,r4 ! regs 256 add #4,r4 257 mov #OFF_PC,r0 258 mov.l @(r0,r15),r6 ! pc 259 mov.l 1f,r0 260 jmp @r0 261 mov #0,r5 ! writeaccess is unknown 262 .align 2 263 2641: .long do_address_error 265 266restore_all: 267 cli 268#ifdef CONFIG_TRACE_IRQFLAGS 269 mov.l 1f, r0 270 jsr @r0 271 nop 272#endif 273 mov r15,r0 274 mov.l $cpu_mode,r2 275 mov #OFF_SR,r3 276 mov.l @(r0,r3),r1 277 mov.l r1,@r2 278 shll2 r1 ! clear MD bit 279 shlr2 r1 280 mov.l @(OFF_SP,r0),r2 281 add #-8,r2 282 mov.l r2,@(OFF_SP,r0) ! point exception frame top 283 mov.l r1,@(4,r2) ! set sr 284 mov #OFF_PC,r3 285 mov.l @(r0,r3),r1 286 mov.l r1,@r2 ! set pc 287 add #4*16+4,r0 288 lds.l @r0+,pr 289 add #4,r0 ! skip sr 290 ldc.l @r0+,gbr 291 lds.l @r0+,mach 292 lds.l @r0+,macl 293 get_current_thread_info r0, r1 294 mov.l $current_thread_info,r1 295 mov.l r0,@r1 296 mov.l @r15+,r0 297 mov.l @r15+,r1 298 mov.l @r15+,r2 299 mov.l @r15+,r3 300 mov.l @r15+,r4 301 mov.l @r15+,r5 302 mov.l @r15+,r6 303 mov.l @r15+,r7 304 mov.l @r15+,r8 305 mov.l @r15+,r9 306 mov.l @r15+,r10 307 mov.l @r15+,r11 308 mov.l @r15+,r12 309 mov.l @r15+,r13 310 mov.l @r15+,r14 311 mov.l @r15,r15 312 rte 313 nop 314 315#ifdef CONFIG_TRACE_IRQFLAGS 3161: .long trace_hardirqs_off 317#endif 318$current_thread_info: 319 .long __current_thread_info 320$cpu_mode: 321 .long __cpu_mode 322 323! common exception handler 324#include "../../entry-common.S" 325 326 .data 327! cpu operation mode 328! bit30 = MD (compatible SH3/4) 329__cpu_mode: 330 .long 0x40000000 331 332 .section .bss 333__current_thread_info: 334 .long 0 335 336ENTRY(exception_handling_table) 337 .space 4*32 338