1/* SPDX-License-Identifier: GPL-2.0 2 * 3 * arch/sh/kernel/cpu/sh2/entry.S 4 * 5 * The SH-2 exception entry 6 * 7 * Copyright (C) 2005-2008 Yoshinori Sato 8 * Copyright (C) 2005 AXE,Inc. 9 */ 10 11#include <linux/linkage.h> 12#include <asm/asm-offsets.h> 13#include <asm/thread_info.h> 14#include <cpu/mmu_context.h> 15#include <asm/unistd.h> 16#include <asm/errno.h> 17#include <asm/page.h> 18 19/* Offsets to the stack */ 20OFF_R0 = 0 /* Return value. New ABI also arg4 */ 21OFF_R1 = 4 /* New ABI: arg5 */ 22OFF_R2 = 8 /* New ABI: arg6 */ 23OFF_R3 = 12 /* New ABI: syscall_nr */ 24OFF_R4 = 16 /* New ABI: arg0 */ 25OFF_R5 = 20 /* New ABI: arg1 */ 26OFF_R6 = 24 /* New ABI: arg2 */ 27OFF_R7 = 28 /* New ABI: arg3 */ 28OFF_SP = (15*4) 29OFF_PC = (16*4) 30OFF_SR = (16*4+2*4) 31OFF_TRA = (16*4+6*4) 32 33#include <asm/entry-macros.S> 34 35ENTRY(exception_handler) 36 ! stack 37 ! r0 <- point sp 38 ! r1 39 ! pc 40 ! sr 41 ! r0 = temporary 42 ! r1 = vector (pseudo EXPEVT / INTEVT / TRA) 43 mov.l r2,@-sp 44 mov.l r3,@-sp 45 cli 46 mov.l $cpu_mode,r2 47#ifdef CONFIG_SMP 48 mov.l $cpuid,r3 49 mov.l @r3,r3 50 mov.l @r3,r3 51 shll2 r3 52 add r3,r2 53#endif 54 mov.l @r2,r0 55 mov.l @(5*4,r15),r3 ! previous SR 56 or r0,r3 ! set MD 57 tst r0,r0 58 bf/s 1f ! previous mode check 59 mov.l r3,@(5*4,r15) ! update SR 60 ! switch to kernel mode 61 mov.l __md_bit,r0 62 mov.l r0,@r2 ! enter kernel mode 63 mov.l $current_thread_info,r2 64#ifdef CONFIG_SMP 65 mov.l $cpuid,r0 66 mov.l @r0,r0 67 mov.l @r0,r0 68 shll2 r0 69 add r0,r2 70#endif 71 mov.l @r2,r2 72 mov #(THREAD_SIZE >> 8),r0 73 shll8 r0 74 add r2,r0 75 mov r15,r2 ! r2 = user stack top 76 mov r0,r15 ! switch kernel stack 77 mov.l r1,@-r15 ! TRA 78 sts.l macl, @-r15 79 sts.l mach, @-r15 80 stc.l gbr, @-r15 81 mov.l @(5*4,r2),r0 82 mov.l r0,@-r15 ! original SR 83 sts.l pr,@-r15 84 mov.l @(4*4,r2),r0 85 mov.l r0,@-r15 ! original PC 86 mov r2,r3 87 add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame 88 mov.l r3,@-r15 ! original SP 89 mov.l r14,@-r15 90 mov.l r13,@-r15 91 mov.l r12,@-r15 92 mov.l r11,@-r15 93 mov.l r10,@-r15 94 mov.l r9,@-r15 95 mov.l r8,@-r15 96 mov.l r7,@-r15 97 mov.l r6,@-r15 98 mov.l r5,@-r15 99 mov.l r4,@-r15 100 mov r1,r9 ! save TRA 101 mov r2,r8 ! copy user -> kernel stack 102 mov.l @(0,r8),r3 103 mov.l r3,@-r15 104 mov.l @(4,r8),r2 105 mov.l r2,@-r15 106 mov.l @(12,r8),r1 107 mov.l r1,@-r15 108 mov.l @(8,r8),r0 109 bra 2f 110 mov.l r0,@-r15 1111: 112 ! in kernel exception 113 mov #(22-4-4-1)*4+4,r0 114 mov r15,r2 115 sub r0,r15 116 mov.l @r2+,r0 ! old R3 117 mov.l r0,@-r15 118 mov.l @r2+,r0 ! old R2 119 mov.l r0,@-r15 120 mov.l @(4,r2),r0 ! old R1 121 mov.l r0,@-r15 122 mov.l @r2,r0 ! old R0 123 mov.l r0,@-r15 124 add #8,r2 125 mov.l @r2+,r3 ! old PC 126 mov.l @r2+,r0 ! old SR 127 add #-4,r2 ! exception frame stub (sr) 128 mov.l r1,@-r2 ! TRA 129 sts.l macl, @-r2 130 sts.l mach, @-r2 131 stc.l gbr, @-r2 132 mov.l r0,@-r2 ! save old SR 133 sts.l pr,@-r2 134 mov.l r3,@-r2 ! save old PC 135 mov r2,r0 136 add #8*4,r0 137 mov.l r0,@-r2 ! save old SP 138 mov.l r14,@-r2 139 mov.l r13,@-r2 140 mov.l r12,@-r2 141 mov.l r11,@-r2 142 mov.l r10,@-r2 143 mov.l r9,@-r2 144 mov.l r8,@-r2 145 mov.l r7,@-r2 146 mov.l r6,@-r2 147 mov.l r5,@-r2 148 mov.l r4,@-r2 149 mov r1,r9 150 mov.l @(OFF_R0,r15),r0 151 mov.l @(OFF_R1,r15),r1 152 mov.l @(OFF_R2,r15),r2 153 mov.l @(OFF_R3,r15),r3 1542: 155 mov #64,r8 156 cmp/hs r8,r9 157 bt interrupt_entry ! vec >= 64 is interrupt 158 mov #31,r8 159 cmp/hs r8,r9 160 bt trap_entry ! 64 > vec >= 31 is trap 161#ifdef CONFIG_CPU_J2 162 mov #16,r8 163 cmp/hs r8,r9 164 bt interrupt_entry ! 31 > vec >= 16 is interrupt 165#endif 166 167 mov.l 4f,r8 168 mov r9,r4 169 shll2 r9 170 add r9,r8 171 mov.l @r8,r8 ! exception handler address 172 tst r8,r8 173 bf 3f 174 mov.l 8f,r8 ! unhandled exception 1753: 176 mov.l 5f,r10 177 jmp @r8 178 lds r10,pr 179 180interrupt_entry: 181 mov r9,r4 182 mov r15,r5 183 mov.l 6f,r9 184 mov.l 7f,r8 185 jmp @r8 186 lds r9,pr 187 188 .align 2 1894: .long exception_handling_table 1905: .long ret_from_exception 1916: .long ret_from_irq 1927: .long do_IRQ 1938: .long exception_error 194 195trap_entry: 196 mov #0x30,r8 197 cmp/ge r8,r9 ! vector 0x1f-0x2f is systemcall 198 bt 1f 199 mov #0x1f,r9 ! convert to unified SH2/3/4 trap number 2001: 201 shll2 r9 ! TRA 202 bra system_call ! jump common systemcall entry 203 mov r9,r8 204 205#if defined(CONFIG_SH_STANDARD_BIOS) 206 /* Unwind the stack and jmp to the debug entry */ 207ENTRY(sh_bios_handler) 208 mov r15,r0 209 add #(22-4)*4-4,r0 210 ldc.l @r0+,gbr 211 lds.l @r0+,mach 212 lds.l @r0+,macl 213 mov r15,r0 214 mov.l @(OFF_SP,r0),r1 215 mov #OFF_SR,r2 216 mov.l @(r0,r2),r3 217 mov.l r3,@-r1 218 mov #OFF_SP,r2 219 mov.l @(r0,r2),r3 220 mov.l r3,@-r1 221 mov r15,r0 222 add #(22-4)*4-8,r0 223 mov.l 1f,r2 224 mov.l @r2,r2 225 stc sr,r3 226 mov.l r2,@r0 227 mov.l r3,@(4,r0) 228 mov.l r1,@(8,r0) 229 mov.l @r15+, r0 230 mov.l @r15+, r1 231 mov.l @r15+, r2 232 mov.l @r15+, r3 233 mov.l @r15+, r4 234 mov.l @r15+, r5 235 mov.l @r15+, r6 236 mov.l @r15+, r7 237 mov.l @r15+, r8 238 mov.l @r15+, r9 239 mov.l @r15+, r10 240 mov.l @r15+, r11 241 mov.l @r15+, r12 242 mov.l @r15+, r13 243 mov.l @r15+, r14 244 add #8,r15 245 lds.l @r15+, pr 246 mov.l @r15+,r15 247 rte 248 nop 249 .align 2 2501: .long gdb_vbr_vector 251#endif /* CONFIG_SH_STANDARD_BIOS */ 252 253ENTRY(address_error_trap_handler) 254 mov r15,r4 ! regs 255 mov #OFF_PC,r0 256 mov.l @(r0,r15),r6 ! pc 257 mov.l 1f,r0 258 jmp @r0 259 mov #0,r5 ! writeaccess is unknown 260 261 .align 2 2621: .long do_address_error 263 264restore_all: 265 stc sr,r0 266 or #0xf0,r0 267 ldc r0,sr ! all interrupt block (same BL = 1) 268 ! restore special register 269 ! overlap exception frame 270 mov r15,r0 271 add #17*4,r0 272 lds.l @r0+,pr 273 add #4,r0 274 ldc.l @r0+,gbr 275 lds.l @r0+,mach 276 lds.l @r0+,macl 277 mov r15,r0 278 mov.l $cpu_mode,r2 279#ifdef CONFIG_SMP 280 mov.l $cpuid,r3 281 mov.l @r3,r3 282 mov.l @r3,r3 283 shll2 r3 284 add r3,r2 285#endif 286 mov #OFF_SR,r3 287 mov.l @(r0,r3),r1 288 mov.l __md_bit,r3 289 and r1,r3 ! copy MD bit 290 mov.l r3,@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 get_current_thread_info r0, r1 301 mov.l $current_thread_info,r1 302#ifdef CONFIG_SMP 303 mov.l $cpuid,r3 304 mov.l @r3,r3 305 mov.l @r3,r3 306 shll2 r3 307 add r3,r1 308#endif 309 mov.l r0,@r1 310 mov.l @r15+,r0 311 mov.l @r15+,r1 312 mov.l @r15+,r2 313 mov.l @r15+,r3 314 mov.l @r15+,r4 315 mov.l @r15+,r5 316 mov.l @r15+,r6 317 mov.l @r15+,r7 318 mov.l @r15+,r8 319 mov.l @r15+,r9 320 mov.l @r15+,r10 321 mov.l @r15+,r11 322 mov.l @r15+,r12 323 mov.l @r15+,r13 324 mov.l @r15+,r14 325 mov.l @r15,r15 326 rte 327 nop 328 329 .align 2 330__md_bit: 331 .long 0x40000000 332$current_thread_info: 333 .long __current_thread_info 334$cpu_mode: 335 .long __cpu_mode 336#ifdef CONFIG_SMP 337$cpuid: 338 .long sh2_cpuid_addr 339#endif 340 341! common exception handler 342#include "../../entry-common.S" 343 344#ifdef CONFIG_NR_CPUS 345#define NR_CPUS CONFIG_NR_CPUS 346#else 347#define NR_CPUS 1 348#endif 349 350 .data 351! cpu operation mode 352! bit30 = MD (compatible SH3/4) 353__cpu_mode: 354 .rept NR_CPUS 355 .long 0x40000000 356 .endr 357 358#ifdef CONFIG_SMP 359.global sh2_cpuid_addr 360sh2_cpuid_addr: 361 .long dummy_cpuid 362dummy_cpuid: 363 .long 0 364#endif 365 366 .section .bss 367__current_thread_info: 368 .rept NR_CPUS 369 .long 0 370 .endr 371 372ENTRY(exception_handling_table) 373 .space 4*32 374