1*234a0538SKuninori Morimoto/* SPDX-License-Identifier: GPL-2.0 2*234a0538SKuninori Morimoto * 36e80f5e8SYoshinori Sato * arch/sh/kernel/cpu/sh2a/entry.S 46e80f5e8SYoshinori Sato * 56e80f5e8SYoshinori Sato * The SH-2A exception entry 66e80f5e8SYoshinori Sato * 76e80f5e8SYoshinori Sato * Copyright (C) 2008 Yoshinori Sato 86e80f5e8SYoshinori Sato * Based on arch/sh/kernel/cpu/sh2/entry.S 96e80f5e8SYoshinori Sato */ 106e80f5e8SYoshinori Sato 116e80f5e8SYoshinori Sato#include <linux/linkage.h> 126e80f5e8SYoshinori Sato#include <asm/asm-offsets.h> 136e80f5e8SYoshinori Sato#include <asm/thread_info.h> 14f15cbe6fSPaul Mundt#include <cpu/mmu_context.h> 156e80f5e8SYoshinori Sato#include <asm/unistd.h> 166e80f5e8SYoshinori Sato#include <asm/errno.h> 176e80f5e8SYoshinori Sato#include <asm/page.h> 186e80f5e8SYoshinori Sato 196e80f5e8SYoshinori Sato/* Offsets to the stack */ 206e80f5e8SYoshinori SatoOFF_R0 = 0 /* Return value. New ABI also arg4 */ 216e80f5e8SYoshinori SatoOFF_R1 = 4 /* New ABI: arg5 */ 226e80f5e8SYoshinori SatoOFF_R2 = 8 /* New ABI: arg6 */ 236e80f5e8SYoshinori SatoOFF_R3 = 12 /* New ABI: syscall_nr */ 246e80f5e8SYoshinori SatoOFF_R4 = 16 /* New ABI: arg0 */ 256e80f5e8SYoshinori SatoOFF_R5 = 20 /* New ABI: arg1 */ 266e80f5e8SYoshinori SatoOFF_R6 = 24 /* New ABI: arg2 */ 276e80f5e8SYoshinori SatoOFF_R7 = 28 /* New ABI: arg3 */ 286e80f5e8SYoshinori SatoOFF_SP = (15*4) 296e80f5e8SYoshinori SatoOFF_PC = (16*4) 306e80f5e8SYoshinori SatoOFF_SR = (16*4+2*4) 316e80f5e8SYoshinori SatoOFF_TRA = (16*4+6*4) 326e80f5e8SYoshinori Sato 336e80f5e8SYoshinori Sato#include <asm/entry-macros.S> 346e80f5e8SYoshinori Sato 356e80f5e8SYoshinori SatoENTRY(exception_handler) 366e80f5e8SYoshinori Sato ! stack 376e80f5e8SYoshinori Sato ! r0 <- point sp 386e80f5e8SYoshinori Sato ! r1 396e80f5e8SYoshinori Sato ! pc 406e80f5e8SYoshinori Sato ! sr 416e80f5e8SYoshinori Sato ! r0 = temporary 426e80f5e8SYoshinori Sato ! r1 = vector (pseudo EXPEVT / INTEVT / TRA) 436e80f5e8SYoshinori Sato mov.l r2,@-sp 446e80f5e8SYoshinori Sato cli 456e80f5e8SYoshinori Sato mov.l $cpu_mode,r2 466e80f5e8SYoshinori Sato bld.b #6,@(0,r2) !previus SR.MD 476e80f5e8SYoshinori Sato bst.b #6,@(4*4,r15) !set cpu mode to SR.MD 486e80f5e8SYoshinori Sato bt 1f 496e80f5e8SYoshinori Sato ! switch to kernel mode 506e80f5e8SYoshinori Sato bset.b #6,@(0,r2) !set SR.MD 516e80f5e8SYoshinori Sato mov.l $current_thread_info,r2 526e80f5e8SYoshinori Sato mov.l @r2,r2 536e80f5e8SYoshinori Sato mov #(THREAD_SIZE >> 8),r0 546e80f5e8SYoshinori Sato shll8 r0 556e80f5e8SYoshinori Sato add r2,r0 ! r0 = kernel stack tail 566e80f5e8SYoshinori Sato mov r15,r2 ! r2 = user stack top 576e80f5e8SYoshinori Sato mov r0,r15 ! switch kernel stack 586e80f5e8SYoshinori Sato mov.l r1,@-r15 ! TRA 596e80f5e8SYoshinori Sato sts.l macl, @-r15 606e80f5e8SYoshinori Sato sts.l mach, @-r15 616e80f5e8SYoshinori Sato stc.l gbr, @-r15 626e80f5e8SYoshinori Sato mov.l @(4*4,r2),r0 636e80f5e8SYoshinori Sato mov.l r0,@-r15 ! original SR 646e80f5e8SYoshinori Sato sts.l pr,@-r15 656e80f5e8SYoshinori Sato mov.l @(3*4,r2),r0 666e80f5e8SYoshinori Sato mov.l r0,@-r15 ! original PC 676e80f5e8SYoshinori Sato mov r2,r0 686e80f5e8SYoshinori Sato add #(3+2)*4,r0 ! rewind r0 - r3 + exception frame 696e80f5e8SYoshinori Sato lds r0,pr ! pr = original SP 706e80f5e8SYoshinori Sato movmu.l r3,@-r15 ! save regs 716e80f5e8SYoshinori Sato mov r2,r8 ! r8 = previus stack top 726e80f5e8SYoshinori Sato mov r1,r9 ! r9 = interrupt vector 736e80f5e8SYoshinori Sato ! restore previous stack 746e80f5e8SYoshinori Sato mov.l @r8+,r2 756e80f5e8SYoshinori Sato mov.l @r8+,r0 766e80f5e8SYoshinori Sato mov.l @r8+,r1 776e80f5e8SYoshinori Sato bra 2f 786e80f5e8SYoshinori Sato movml.l r2,@-r15 796e80f5e8SYoshinori Sato1: 806e80f5e8SYoshinori Sato ! in kernel exception 816e80f5e8SYoshinori Sato mov r15,r2 826e80f5e8SYoshinori Sato add #-((OFF_TRA + 4) - OFF_PC) + 5*4,r15 836e80f5e8SYoshinori Sato movmu.l r3,@-r15 846e80f5e8SYoshinori Sato mov r2,r8 ! r8 = previous stack top 856e80f5e8SYoshinori Sato mov r1,r9 ! r9 = interrupt vector 866e80f5e8SYoshinori Sato ! restore exception frame & regs 876e80f5e8SYoshinori Sato mov.l @r8+,r2 ! old R2 886e80f5e8SYoshinori Sato mov.l @r8+,r0 ! old R0 896e80f5e8SYoshinori Sato mov.l @r8+,r1 ! old R1 906e80f5e8SYoshinori Sato mov.l @r8+,r10 ! old PC 916e80f5e8SYoshinori Sato mov.l @r8+,r11 ! old SR 926e80f5e8SYoshinori Sato movml.l r2,@-r15 936e80f5e8SYoshinori Sato mov.l r10,@(OFF_PC,r15) 946e80f5e8SYoshinori Sato mov.l r11,@(OFF_SR,r15) 956e80f5e8SYoshinori Sato mov.l r8,@(OFF_SP,r15) ! save old sp 966e80f5e8SYoshinori Sato mov r15,r8 976e80f5e8SYoshinori Sato add #OFF_TRA + 4,r8 986e80f5e8SYoshinori Sato mov.l r9,@-r8 996e80f5e8SYoshinori Sato sts.l macl,@-r8 1006e80f5e8SYoshinori Sato sts.l mach,@-r8 1016e80f5e8SYoshinori Sato stc.l gbr,@-r8 1026e80f5e8SYoshinori Sato add #-4,r8 1036e80f5e8SYoshinori Sato sts.l pr,@-r8 1046e80f5e8SYoshinori Sato2: 1056e80f5e8SYoshinori Sato ! dispatch exception / interrupt 1066e80f5e8SYoshinori Sato mov #64,r8 1076e80f5e8SYoshinori Sato cmp/hs r8,r9 1086e80f5e8SYoshinori Sato bt interrupt_entry ! vec >= 64 is interrupt 1093623d138SRich Felker mov #31,r8 1106e80f5e8SYoshinori Sato cmp/hs r8,r9 1113623d138SRich Felker bt trap_entry ! 64 > vec >= 31 is trap 1126e80f5e8SYoshinori Sato 1136e80f5e8SYoshinori Sato mov.l 4f,r8 1146e80f5e8SYoshinori Sato mov r9,r4 1156e80f5e8SYoshinori Sato shll2 r9 1166e80f5e8SYoshinori Sato add r9,r8 1176e80f5e8SYoshinori Sato mov.l @r8,r8 ! exception handler address 1186e80f5e8SYoshinori Sato tst r8,r8 1196e80f5e8SYoshinori Sato bf 3f 1206e80f5e8SYoshinori Sato mov.l 8f,r8 ! unhandled exception 1216e80f5e8SYoshinori Sato3: 1226e80f5e8SYoshinori Sato mov.l 5f,r10 1236e80f5e8SYoshinori Sato jmp @r8 1246e80f5e8SYoshinori Sato lds r10,pr 1256e80f5e8SYoshinori Sato 1266e80f5e8SYoshinori Satointerrupt_entry: 1276e80f5e8SYoshinori Sato mov r9,r4 1286e80f5e8SYoshinori Sato mov r15,r5 1296e80f5e8SYoshinori Sato mov.l 7f,r8 1306e80f5e8SYoshinori Sato mov.l 6f,r9 1316e80f5e8SYoshinori Sato jmp @r8 1326e80f5e8SYoshinori Sato lds r9,pr 1336e80f5e8SYoshinori Sato 1346e80f5e8SYoshinori Sato .align 2 1356e80f5e8SYoshinori Sato4: .long exception_handling_table 1366e80f5e8SYoshinori Sato5: .long ret_from_exception 1376e80f5e8SYoshinori Sato6: .long ret_from_irq 1386e80f5e8SYoshinori Sato7: .long do_IRQ 1396e80f5e8SYoshinori Sato8: .long exception_error 1406e80f5e8SYoshinori Sato 1416e80f5e8SYoshinori Satotrap_entry: 1426e80f5e8SYoshinori Sato mov #0x30,r8 1433623d138SRich Felker cmp/ge r8,r9 ! vector 0x1f-0x2f is systemcall 1446e80f5e8SYoshinori Sato bt 1f 1453623d138SRich Felker mov #0x1f,r9 ! convert to unified SH2/3/4 trap number 1466e80f5e8SYoshinori Sato1: 1476e80f5e8SYoshinori Sato shll2 r9 ! TRA 1486e80f5e8SYoshinori Sato bra system_call ! jump common systemcall entry 1496e80f5e8SYoshinori Sato mov r9,r8 1506e80f5e8SYoshinori Sato 1516e80f5e8SYoshinori Sato#if defined(CONFIG_SH_STANDARD_BIOS) 1526e80f5e8SYoshinori Sato /* Unwind the stack and jmp to the debug entry */ 1536e80f5e8SYoshinori SatoENTRY(sh_bios_handler) 1546e80f5e8SYoshinori Sato mov r15,r0 1556e80f5e8SYoshinori Sato add #(22-4)*4-4,r0 1566e80f5e8SYoshinori Sato ldc.l @r0+,gbr 1576e80f5e8SYoshinori Sato lds.l @r0+,mach 1586e80f5e8SYoshinori Sato lds.l @r0+,macl 1596e80f5e8SYoshinori Sato mov r15,r0 1606e80f5e8SYoshinori Sato mov.l @(OFF_SP,r0),r1 1616e80f5e8SYoshinori Sato mov.l @(OFF_SR,r2),r3 1626e80f5e8SYoshinori Sato mov.l r3,@-r1 1636e80f5e8SYoshinori Sato mov.l @(OFF_SP,r2),r3 1646e80f5e8SYoshinori Sato mov.l r3,@-r1 1656e80f5e8SYoshinori Sato mov r15,r0 1666e80f5e8SYoshinori Sato add #(22-4)*4-8,r0 1676e80f5e8SYoshinori Sato mov.l 1f,r2 1686e80f5e8SYoshinori Sato mov.l @r2,r2 1696e80f5e8SYoshinori Sato stc sr,r3 1706e80f5e8SYoshinori Sato mov.l r2,@r0 1716e80f5e8SYoshinori Sato mov.l r3,@(4,r0) 1726e80f5e8SYoshinori Sato mov.l r1,@(8,r0) 1736e80f5e8SYoshinori Sato movml.l @r15+,r14 1746e80f5e8SYoshinori Sato add #8,r15 1756e80f5e8SYoshinori Sato lds.l @r15+, pr 1766e80f5e8SYoshinori Sato mov.l @r15+,r15 1777a90e00dSPaul Mundt rte 1787a90e00dSPaul Mundt nop 1796e80f5e8SYoshinori Sato .align 2 1806e80f5e8SYoshinori Sato1: .long gdb_vbr_vector 1816e80f5e8SYoshinori Sato#endif /* CONFIG_SH_STANDARD_BIOS */ 1826e80f5e8SYoshinori Sato 1836e80f5e8SYoshinori SatoENTRY(address_error_trap_handler) 1846e80f5e8SYoshinori Sato mov r15,r4 ! regs 1856e80f5e8SYoshinori Sato mov.l @(OFF_PC,r15),r6 ! pc 1866e80f5e8SYoshinori Sato mov.l 1f,r0 1876e80f5e8SYoshinori Sato jmp @r0 1886e80f5e8SYoshinori Sato mov #0,r5 ! writeaccess is unknown 1896e80f5e8SYoshinori Sato 1906e80f5e8SYoshinori Sato .align 2 1916e80f5e8SYoshinori Sato1: .long do_address_error 1926e80f5e8SYoshinori Sato 1936e80f5e8SYoshinori Satorestore_all: 1946e80f5e8SYoshinori Sato stc sr,r0 1956e80f5e8SYoshinori Sato or #0xf0,r0 1966e80f5e8SYoshinori Sato ldc r0,sr ! all interrupt block (same BL = 1) 1976e80f5e8SYoshinori Sato ! restore special register 1986e80f5e8SYoshinori Sato ! overlap exception frame 1996e80f5e8SYoshinori Sato mov r15,r0 2006e80f5e8SYoshinori Sato add #17*4,r0 2016e80f5e8SYoshinori Sato lds.l @r0+,pr 2026e80f5e8SYoshinori Sato add #4,r0 2036e80f5e8SYoshinori Sato ldc.l @r0+,gbr 2046e80f5e8SYoshinori Sato lds.l @r0+,mach 2056e80f5e8SYoshinori Sato lds.l @r0+,macl 2066e80f5e8SYoshinori Sato mov r15,r0 2076e80f5e8SYoshinori Sato mov.l $cpu_mode,r2 2086e80f5e8SYoshinori Sato bld.b #6,@(OFF_SR,r15) 2096e80f5e8SYoshinori Sato bst.b #6,@(0,r2) ! save CPU mode 2106e80f5e8SYoshinori Sato mov.l @(OFF_SR,r0),r1 2116e80f5e8SYoshinori Sato shll2 r1 2126e80f5e8SYoshinori Sato shlr2 r1 ! clear MD bit 2136e80f5e8SYoshinori Sato mov.l @(OFF_SP,r0),r2 2146e80f5e8SYoshinori Sato add #-8,r2 2156e80f5e8SYoshinori Sato mov.l r2,@(OFF_SP,r0) ! point exception frame top 2166e80f5e8SYoshinori Sato mov.l r1,@(4,r2) ! set sr 2176e80f5e8SYoshinori Sato mov.l @(OFF_PC,r0),r1 2186e80f5e8SYoshinori Sato mov.l r1,@r2 ! set pc 2196e80f5e8SYoshinori Sato get_current_thread_info r0, r1 2206e80f5e8SYoshinori Sato mov.l $current_thread_info,r1 2216e80f5e8SYoshinori Sato mov.l r0,@r1 2226e80f5e8SYoshinori Sato movml.l @r15+,r14 2236e80f5e8SYoshinori Sato mov.l @r15,r15 2246e80f5e8SYoshinori Sato rte 2256e80f5e8SYoshinori Sato nop 2266e80f5e8SYoshinori Sato 2276e80f5e8SYoshinori Sato .align 2 2286e80f5e8SYoshinori Sato$current_thread_info: 2296e80f5e8SYoshinori Sato .long __current_thread_info 2306e80f5e8SYoshinori Sato$cpu_mode: 2316e80f5e8SYoshinori Sato .long __cpu_mode 2326e80f5e8SYoshinori Sato 2336e80f5e8SYoshinori Sato! common exception handler 2346e80f5e8SYoshinori Sato#include "../../entry-common.S" 2356e80f5e8SYoshinori Sato 2366e80f5e8SYoshinori Sato .data 2376e80f5e8SYoshinori Sato! cpu operation mode 2386e80f5e8SYoshinori Sato! bit30 = MD (compatible SH3/4) 2396e80f5e8SYoshinori Sato__cpu_mode: 2406e80f5e8SYoshinori Sato .long 0x40000000 2416e80f5e8SYoshinori Sato 2426e80f5e8SYoshinori Sato .section .bss 2436e80f5e8SYoshinori Sato__current_thread_info: 2446e80f5e8SYoshinori Sato .long 0 2456e80f5e8SYoshinori Sato 2466e80f5e8SYoshinori SatoENTRY(exception_handling_table) 2476e80f5e8SYoshinori Sato .space 4*32 248