1/* 2 * arch/sh/kernel/cpu/sh2/entry.S 3 * 4 * The SH-2 exception entry 5 * 6 * Copyright (C) 2005-2008 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 <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 ! stack 40 ! r0 <- point sp 41 ! r1 42 ! pc 43 ! sr 44 ! r0 = temporary 45 ! r1 = vector (pseudo EXPEVT / INTEVT / TRA) 46 mov.l r2,@-sp 47 mov.l r3,@-sp 48 cli 49 mov.l $cpu_mode,r2 50 mov.l @r2,r0 51 mov.l @(5*4,r15),r3 ! previous SR 52 or r0,r3 ! set MD 53 tst r0,r0 54 bf/s 1f ! previous mode check 55 mov.l r3,@(5*4,r15) ! update SR 56 ! switch to kernel mode 57 mov.l __md_bit,r0 58 mov.l r0,@r2 ! enter kernel mode 59 mov.l $current_thread_info,r2 60 mov.l @r2,r2 61 mov #(THREAD_SIZE >> 8),r0 62 shll8 r0 63 add r2,r0 64 mov r15,r2 ! r2 = user stack top 65 mov r0,r15 ! switch kernel stack 66 mov.l r1,@-r15 ! TRA 67 sts.l macl, @-r15 68 sts.l mach, @-r15 69 stc.l gbr, @-r15 70 mov.l @(5*4,r2),r0 71 mov.l r0,@-r15 ! original SR 72 sts.l pr,@-r15 73 mov.l @(4*4,r2),r0 74 mov.l r0,@-r15 ! original PC 75 mov r2,r3 76 add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame 77 mov.l r3,@-r15 ! original SP 78 mov.l r14,@-r15 79 mov.l r13,@-r15 80 mov.l r12,@-r15 81 mov.l r11,@-r15 82 mov.l r10,@-r15 83 mov.l r9,@-r15 84 mov.l r8,@-r15 85 mov.l r7,@-r15 86 mov.l r6,@-r15 87 mov.l r5,@-r15 88 mov.l r4,@-r15 89 mov r1,r9 ! save TRA 90 mov r2,r8 ! copy user -> kernel stack 91 mov.l @(0,r8),r3 92 mov.l r3,@-r15 93 mov.l @(4,r8),r2 94 mov.l r2,@-r15 95 mov.l @(12,r8),r1 96 mov.l r1,@-r15 97 mov.l @(8,r8),r0 98 bra 2f 99 mov.l r0,@-r15 1001: 101 ! in kernel exception 102 mov #(22-4-4-1)*4+4,r0 103 mov r15,r2 104 sub r0,r15 105 mov.l @r2+,r0 ! old R3 106 mov.l r0,@-r15 107 mov.l @r2+,r0 ! old R2 108 mov.l r0,@-r15 109 mov.l @(4,r2),r0 ! old R1 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 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 r1,r9 139 mov.l @(OFF_R0,r15),r0 140 mov.l @(OFF_R1,r15),r1 141 mov.l @(OFF_R2,r15),r2 142 mov.l @(OFF_R3,r15),r3 1432: 144 mov #64,r8 145 cmp/hs r8,r9 146 bt interrupt_entry ! vec >= 64 is interrupt 147 mov #32,r8 148 cmp/hs r8,r9 149 bt trap_entry ! 64 > vec >= 32 is trap 150 151 mov.l 4f,r8 152 mov r9,r4 153 shll2 r9 154 add r9,r8 155 mov.l @r8,r8 ! exception handler address 156 tst r8,r8 157 bf 3f 158 mov.l 8f,r8 ! unhandled exception 1593: 160 mov.l 5f,r10 161 jmp @r8 162 lds r10,pr 163 164interrupt_entry: 165 mov r9,r4 166 mov r15,r5 167 mov.l 6f,r9 168 mov.l 7f,r8 169 jmp @r8 170 lds r9,pr 171 172 .align 2 1734: .long exception_handling_table 1745: .long ret_from_exception 1756: .long ret_from_irq 1767: .long do_IRQ 1778: .long exception_error 178 179trap_entry: 180 mov #0x30,r8 181 cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall 182 bt 1f 183 add #-0x10,r9 ! convert SH2 to SH3/4 ABI 1841: 185 shll2 r9 ! TRA 186 bra system_call ! jump common systemcall entry 187 mov r9,r8 188 189#if defined(CONFIG_SH_STANDARD_BIOS) 190 /* Unwind the stack and jmp to the debug entry */ 191ENTRY(sh_bios_handler) 192 mov r15,r0 193 add #(22-4)*4-4,r0 194 ldc.l @r0+,gbr 195 lds.l @r0+,mach 196 lds.l @r0+,macl 197 mov r15,r0 198 mov.l @(OFF_SP,r0),r1 199 mov #OFF_SR,r2 200 mov.l @(r0,r2),r3 201 mov.l r3,@-r1 202 mov #OFF_SP,r2 203 mov.l @(r0,r2),r3 204 mov.l r3,@-r1 205 mov r15,r0 206 add #(22-4)*4-8,r0 207 mov.l 1f,r2 208 mov.l @r2,r2 209 stc sr,r3 210 mov.l r2,@r0 211 mov.l r3,@(4,r0) 212 mov.l r1,@(8,r0) 213 mov.l @r15+, r0 214 mov.l @r15+, r1 215 mov.l @r15+, r2 216 mov.l @r15+, r3 217 mov.l @r15+, r4 218 mov.l @r15+, r5 219 mov.l @r15+, r6 220 mov.l @r15+, r7 221 mov.l @r15+, r8 222 mov.l @r15+, r9 223 mov.l @r15+, r10 224 mov.l @r15+, r11 225 mov.l @r15+, r12 226 mov.l @r15+, r13 227 mov.l @r15+, r14 228 add #8,r15 229 lds.l @r15+, pr 230 rte 231 mov.l @r15+,r15 232 .align 2 2331: .long gdb_vbr_vector 234#endif /* CONFIG_SH_STANDARD_BIOS */ 235 236ENTRY(address_error_trap_handler) 237 mov r15,r4 ! regs 238 mov #OFF_PC,r0 239 mov.l @(r0,r15),r6 ! pc 240 mov.l 1f,r0 241 jmp @r0 242 mov #0,r5 ! writeaccess is unknown 243 244 .align 2 2451: .long do_address_error 246 247restore_all: 248 stc sr,r0 249 or #0xf0,r0 250 ldc r0,sr ! all interrupt block (same BL = 1) 251 ! restore special register 252 ! overlap exception frame 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 260 mov r15,r0 261 mov.l $cpu_mode,r2 262 mov #OFF_SR,r3 263 mov.l @(r0,r3),r1 264 mov.l __md_bit,r3 265 and r1,r3 ! copy MD bit 266 mov.l r3,@r2 267 shll2 r1 ! clear MD bit 268 shlr2 r1 269 mov.l @(OFF_SP,r0),r2 270 add #-8,r2 271 mov.l r2,@(OFF_SP,r0) ! point exception frame top 272 mov.l r1,@(4,r2) ! set sr 273 mov #OFF_PC,r3 274 mov.l @(r0,r3),r1 275 mov.l r1,@r2 ! set pc 276 get_current_thread_info r0, r1 277 mov.l $current_thread_info,r1 278 mov.l r0,@r1 279 mov.l @r15+,r0 280 mov.l @r15+,r1 281 mov.l @r15+,r2 282 mov.l @r15+,r3 283 mov.l @r15+,r4 284 mov.l @r15+,r5 285 mov.l @r15+,r6 286 mov.l @r15+,r7 287 mov.l @r15+,r8 288 mov.l @r15+,r9 289 mov.l @r15+,r10 290 mov.l @r15+,r11 291 mov.l @r15+,r12 292 mov.l @r15+,r13 293 mov.l @r15+,r14 294 mov.l @r15,r15 295 rte 296 nop 297 298 .align 2 299__md_bit: 300 .long 0x40000000 301$current_thread_info: 302 .long __current_thread_info 303$cpu_mode: 304 .long __cpu_mode 305 306! common exception handler 307#include "../../entry-common.S" 308 309 .data 310! cpu operation mode 311! bit30 = MD (compatible SH3/4) 312__cpu_mode: 313 .long 0x40000000 314 315 .section .bss 316__current_thread_info: 317 .long 0 318 319ENTRY(exception_handling_table) 320 .space 4*32 321