1/* SPDX-License-Identifier: GPL-2.0 2 * 3 * arch/sh/kernel/cpu/sh2a/entry.S 4 * 5 * The SH-2A exception entry 6 * 7 * Copyright (C) 2008 Yoshinori Sato 8 * Based on arch/sh/kernel/cpu/sh2/entry.S 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 cli 45 mov.l $cpu_mode,r2 46 bld.b #6,@(0,r2) !previus SR.MD 47 bst.b #6,@(4*4,r15) !set cpu mode to SR.MD 48 bt 1f 49 ! switch to kernel mode 50 bset.b #6,@(0,r2) !set SR.MD 51 mov.l $current_thread_info,r2 52 mov.l @r2,r2 53 mov #(THREAD_SIZE >> 8),r0 54 shll8 r0 55 add r2,r0 ! r0 = kernel stack tail 56 mov r15,r2 ! r2 = user stack top 57 mov r0,r15 ! switch kernel stack 58 mov.l r1,@-r15 ! TRA 59 sts.l macl, @-r15 60 sts.l mach, @-r15 61 stc.l gbr, @-r15 62 mov.l @(4*4,r2),r0 63 mov.l r0,@-r15 ! original SR 64 sts.l pr,@-r15 65 mov.l @(3*4,r2),r0 66 mov.l r0,@-r15 ! original PC 67 mov r2,r0 68 add #(3+2)*4,r0 ! rewind r0 - r3 + exception frame 69 lds r0,pr ! pr = original SP 70 movmu.l r3,@-r15 ! save regs 71 mov r2,r8 ! r8 = previus stack top 72 mov r1,r9 ! r9 = interrupt vector 73 ! restore previous stack 74 mov.l @r8+,r2 75 mov.l @r8+,r0 76 mov.l @r8+,r1 77 bra 2f 78 movml.l r2,@-r15 791: 80 ! in kernel exception 81 mov r15,r2 82 add #-((OFF_TRA + 4) - OFF_PC) + 5*4,r15 83 movmu.l r3,@-r15 84 mov r2,r8 ! r8 = previous stack top 85 mov r1,r9 ! r9 = interrupt vector 86 ! restore exception frame & regs 87 mov.l @r8+,r2 ! old R2 88 mov.l @r8+,r0 ! old R0 89 mov.l @r8+,r1 ! old R1 90 mov.l @r8+,r10 ! old PC 91 mov.l @r8+,r11 ! old SR 92 movml.l r2,@-r15 93 mov.l r10,@(OFF_PC,r15) 94 mov.l r11,@(OFF_SR,r15) 95 mov.l r8,@(OFF_SP,r15) ! save old sp 96 mov r15,r8 97 add #OFF_TRA + 4,r8 98 mov.l r9,@-r8 99 sts.l macl,@-r8 100 sts.l mach,@-r8 101 stc.l gbr,@-r8 102 add #-4,r8 103 sts.l pr,@-r8 1042: 105 ! dispatch exception / interrupt 106 mov #64,r8 107 cmp/hs r8,r9 108 bt interrupt_entry ! vec >= 64 is interrupt 109 mov #31,r8 110 cmp/hs r8,r9 111 bt trap_entry ! 64 > vec >= 31 is trap 112 113 mov.l 4f,r8 114 mov r9,r4 115 shll2 r9 116 add r9,r8 117 mov.l @r8,r8 ! exception handler address 118 tst r8,r8 119 bf 3f 120 mov.l 8f,r8 ! unhandled exception 1213: 122 mov.l 5f,r10 123 jmp @r8 124 lds r10,pr 125 126interrupt_entry: 127 mov r9,r4 128 mov r15,r5 129 mov.l 7f,r8 130 mov.l 6f,r9 131 jmp @r8 132 lds r9,pr 133 134 .align 2 1354: .long exception_handling_table 1365: .long ret_from_exception 1376: .long ret_from_irq 1387: .long do_IRQ 1398: .long exception_error 140 141trap_entry: 142 mov #0x30,r8 143 cmp/ge r8,r9 ! vector 0x1f-0x2f is systemcall 144 bt 1f 145 mov #0x1f,r9 ! convert to unified SH2/3/4 trap number 1461: 147 shll2 r9 ! TRA 148 bra system_call ! jump common systemcall entry 149 mov r9,r8 150 151#if defined(CONFIG_SH_STANDARD_BIOS) 152 /* Unwind the stack and jmp to the debug entry */ 153ENTRY(sh_bios_handler) 154 mov r15,r0 155 add #(22-4)*4-4,r0 156 ldc.l @r0+,gbr 157 lds.l @r0+,mach 158 lds.l @r0+,macl 159 mov r15,r0 160 mov.l @(OFF_SP,r0),r1 161 mov.l @(OFF_SR,r2),r3 162 mov.l r3,@-r1 163 mov.l @(OFF_SP,r2),r3 164 mov.l r3,@-r1 165 mov r15,r0 166 add #(22-4)*4-8,r0 167 mov.l 1f,r2 168 mov.l @r2,r2 169 stc sr,r3 170 mov.l r2,@r0 171 mov.l r3,@(4,r0) 172 mov.l r1,@(8,r0) 173 movml.l @r15+,r14 174 add #8,r15 175 lds.l @r15+, pr 176 mov.l @r15+,r15 177 rte 178 nop 179 .align 2 1801: .long gdb_vbr_vector 181#endif /* CONFIG_SH_STANDARD_BIOS */ 182 183ENTRY(address_error_trap_handler) 184 mov r15,r4 ! regs 185 mov.l @(OFF_PC,r15),r6 ! pc 186 mov.l 1f,r0 187 jmp @r0 188 mov #0,r5 ! writeaccess is unknown 189 190 .align 2 1911: .long do_address_error 192 193restore_all: 194 stc sr,r0 195 or #0xf0,r0 196 ldc r0,sr ! all interrupt block (same BL = 1) 197 ! restore special register 198 ! overlap exception frame 199 mov r15,r0 200 add #17*4,r0 201 lds.l @r0+,pr 202 add #4,r0 203 ldc.l @r0+,gbr 204 lds.l @r0+,mach 205 lds.l @r0+,macl 206 mov r15,r0 207 mov.l $cpu_mode,r2 208 bld.b #6,@(OFF_SR,r15) 209 bst.b #6,@(0,r2) ! save CPU mode 210 mov.l @(OFF_SR,r0),r1 211 shll2 r1 212 shlr2 r1 ! clear MD bit 213 mov.l @(OFF_SP,r0),r2 214 add #-8,r2 215 mov.l r2,@(OFF_SP,r0) ! point exception frame top 216 mov.l r1,@(4,r2) ! set sr 217 mov.l @(OFF_PC,r0),r1 218 mov.l r1,@r2 ! set pc 219 get_current_thread_info r0, r1 220 mov.l $current_thread_info,r1 221 mov.l r0,@r1 222 movml.l @r15+,r14 223 mov.l @r15,r15 224 rte 225 nop 226 227 .align 2 228$current_thread_info: 229 .long __current_thread_info 230$cpu_mode: 231 .long __cpu_mode 232 233! common exception handler 234#include "../../entry-common.S" 235 236 .data 237! cpu operation mode 238! bit30 = MD (compatible SH3/4) 239__cpu_mode: 240 .long 0x40000000 241 242 .section .bss 243__current_thread_info: 244 .long 0 245 246ENTRY(exception_handling_table) 247 .space 4*32 248