1*47d11326SKuninori Morimoto/* SPDX-License-Identifier: GPL-2.0 2*47d11326SKuninori Morimoto * 3de398406SYoshinori Sato * arch/sh/kernel/cpu/sh2/entry.S 4de398406SYoshinori Sato * 5de398406SYoshinori Sato * The SH-2 exception entry 6de398406SYoshinori Sato * 76e80f5e8SYoshinori Sato * Copyright (C) 2005-2008 Yoshinori Sato 8de398406SYoshinori Sato * Copyright (C) 2005 AXE,Inc. 9de398406SYoshinori Sato */ 10de398406SYoshinori Sato 11de398406SYoshinori Sato#include <linux/linkage.h> 12de398406SYoshinori Sato#include <asm/asm-offsets.h> 13de398406SYoshinori Sato#include <asm/thread_info.h> 14f15cbe6fSPaul Mundt#include <cpu/mmu_context.h> 15de398406SYoshinori Sato#include <asm/unistd.h> 16de398406SYoshinori Sato#include <asm/errno.h> 17de398406SYoshinori Sato#include <asm/page.h> 18de398406SYoshinori Sato 19de398406SYoshinori Sato/* Offsets to the stack */ 20de398406SYoshinori SatoOFF_R0 = 0 /* Return value. New ABI also arg4 */ 21de398406SYoshinori SatoOFF_R1 = 4 /* New ABI: arg5 */ 22de398406SYoshinori SatoOFF_R2 = 8 /* New ABI: arg6 */ 23de398406SYoshinori SatoOFF_R3 = 12 /* New ABI: syscall_nr */ 24de398406SYoshinori SatoOFF_R4 = 16 /* New ABI: arg0 */ 25de398406SYoshinori SatoOFF_R5 = 20 /* New ABI: arg1 */ 26de398406SYoshinori SatoOFF_R6 = 24 /* New ABI: arg2 */ 27de398406SYoshinori SatoOFF_R7 = 28 /* New ABI: arg3 */ 28de398406SYoshinori SatoOFF_SP = (15*4) 29de398406SYoshinori SatoOFF_PC = (16*4) 30de398406SYoshinori SatoOFF_SR = (16*4+2*4) 31de398406SYoshinori SatoOFF_TRA = (16*4+6*4) 32de398406SYoshinori Sato 33de398406SYoshinori Sato#include <asm/entry-macros.S> 34de398406SYoshinori Sato 35de398406SYoshinori 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) 43de398406SYoshinori Sato mov.l r2,@-sp 44de398406SYoshinori Sato mov.l r3,@-sp 45de398406SYoshinori Sato cli 46de398406SYoshinori Sato mov.l $cpu_mode,r2 474b6ef05bSRich Felker#ifdef CONFIG_SMP 484b6ef05bSRich Felker mov.l $cpuid,r3 494b6ef05bSRich Felker mov.l @r3,r3 504b6ef05bSRich Felker mov.l @r3,r3 514b6ef05bSRich Felker shll2 r3 524b6ef05bSRich Felker add r3,r2 534b6ef05bSRich Felker#endif 54de398406SYoshinori Sato mov.l @r2,r0 55de398406SYoshinori Sato mov.l @(5*4,r15),r3 ! previous SR 566e80f5e8SYoshinori Sato or r0,r3 ! set MD 576e80f5e8SYoshinori Sato tst r0,r0 586e80f5e8SYoshinori Sato bf/s 1f ! previous mode check 596e80f5e8SYoshinori Sato mov.l r3,@(5*4,r15) ! update SR 60de398406SYoshinori Sato ! switch to kernel mode 616e80f5e8SYoshinori Sato mov.l __md_bit,r0 62de398406SYoshinori Sato mov.l r0,@r2 ! enter kernel mode 63de398406SYoshinori Sato mov.l $current_thread_info,r2 644b6ef05bSRich Felker#ifdef CONFIG_SMP 654b6ef05bSRich Felker mov.l $cpuid,r0 664b6ef05bSRich Felker mov.l @r0,r0 674b6ef05bSRich Felker mov.l @r0,r0 684b6ef05bSRich Felker shll2 r0 694b6ef05bSRich Felker add r0,r2 704b6ef05bSRich Felker#endif 71de398406SYoshinori Sato mov.l @r2,r2 726e80f5e8SYoshinori Sato mov #(THREAD_SIZE >> 8),r0 73de398406SYoshinori Sato shll8 r0 74de398406SYoshinori Sato add r2,r0 75de398406SYoshinori Sato mov r15,r2 ! r2 = user stack top 76de398406SYoshinori Sato mov r0,r15 ! switch kernel stack 77de398406SYoshinori Sato mov.l r1,@-r15 ! TRA 78de398406SYoshinori Sato sts.l macl, @-r15 79de398406SYoshinori Sato sts.l mach, @-r15 80de398406SYoshinori Sato stc.l gbr, @-r15 816e80f5e8SYoshinori Sato mov.l @(5*4,r2),r0 826e80f5e8SYoshinori Sato mov.l r0,@-r15 ! original SR 83de398406SYoshinori Sato sts.l pr,@-r15 846e80f5e8SYoshinori Sato mov.l @(4*4,r2),r0 85de398406SYoshinori Sato mov.l r0,@-r15 ! original PC 86de398406SYoshinori Sato mov r2,r3 87de398406SYoshinori Sato add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame 88de398406SYoshinori Sato mov.l r3,@-r15 ! original SP 89de398406SYoshinori Sato mov.l r14,@-r15 90de398406SYoshinori Sato mov.l r13,@-r15 91de398406SYoshinori Sato mov.l r12,@-r15 92de398406SYoshinori Sato mov.l r11,@-r15 93de398406SYoshinori Sato mov.l r10,@-r15 94de398406SYoshinori Sato mov.l r9,@-r15 95de398406SYoshinori Sato mov.l r8,@-r15 96de398406SYoshinori Sato mov.l r7,@-r15 97de398406SYoshinori Sato mov.l r6,@-r15 98de398406SYoshinori Sato mov.l r5,@-r15 99de398406SYoshinori Sato mov.l r4,@-r15 1006e80f5e8SYoshinori Sato mov r1,r9 ! save TRA 101de398406SYoshinori Sato mov r2,r8 ! copy user -> kernel stack 1026e80f5e8SYoshinori Sato mov.l @(0,r8),r3 103de398406SYoshinori Sato mov.l r3,@-r15 1046e80f5e8SYoshinori Sato mov.l @(4,r8),r2 105de398406SYoshinori Sato mov.l r2,@-r15 1066e80f5e8SYoshinori Sato mov.l @(12,r8),r1 107de398406SYoshinori Sato mov.l r1,@-r15 1086e80f5e8SYoshinori Sato mov.l @(8,r8),r0 109de398406SYoshinori Sato bra 2f 110de398406SYoshinori Sato mov.l r0,@-r15 111de398406SYoshinori Sato1: 112de398406SYoshinori Sato ! in kernel exception 113de398406SYoshinori Sato mov #(22-4-4-1)*4+4,r0 114de398406SYoshinori Sato mov r15,r2 115de398406SYoshinori Sato sub r0,r15 116de398406SYoshinori Sato mov.l @r2+,r0 ! old R3 117de398406SYoshinori Sato mov.l r0,@-r15 118de398406SYoshinori Sato mov.l @r2+,r0 ! old R2 119de398406SYoshinori Sato mov.l r0,@-r15 1206e80f5e8SYoshinori Sato mov.l @(4,r2),r0 ! old R1 121de398406SYoshinori Sato mov.l r0,@-r15 1226e80f5e8SYoshinori Sato mov.l @r2,r0 ! old R0 123de398406SYoshinori Sato mov.l r0,@-r15 1246e80f5e8SYoshinori Sato add #8,r2 125de398406SYoshinori Sato mov.l @r2+,r3 ! old PC 126de398406SYoshinori Sato mov.l @r2+,r0 ! old SR 127de398406SYoshinori Sato add #-4,r2 ! exception frame stub (sr) 128de398406SYoshinori Sato mov.l r1,@-r2 ! TRA 129de398406SYoshinori Sato sts.l macl, @-r2 130de398406SYoshinori Sato sts.l mach, @-r2 131de398406SYoshinori Sato stc.l gbr, @-r2 132de398406SYoshinori Sato mov.l r0,@-r2 ! save old SR 133de398406SYoshinori Sato sts.l pr,@-r2 134de398406SYoshinori Sato mov.l r3,@-r2 ! save old PC 135de398406SYoshinori Sato mov r2,r0 136de398406SYoshinori Sato add #8*4,r0 137de398406SYoshinori Sato mov.l r0,@-r2 ! save old SP 138de398406SYoshinori Sato mov.l r14,@-r2 139de398406SYoshinori Sato mov.l r13,@-r2 140de398406SYoshinori Sato mov.l r12,@-r2 141de398406SYoshinori Sato mov.l r11,@-r2 142de398406SYoshinori Sato mov.l r10,@-r2 143de398406SYoshinori Sato mov.l r9,@-r2 144de398406SYoshinori Sato mov.l r8,@-r2 145de398406SYoshinori Sato mov.l r7,@-r2 146de398406SYoshinori Sato mov.l r6,@-r2 147de398406SYoshinori Sato mov.l r5,@-r2 148de398406SYoshinori Sato mov.l r4,@-r2 1496e80f5e8SYoshinori Sato mov r1,r9 150de398406SYoshinori Sato mov.l @(OFF_R0,r15),r0 151de398406SYoshinori Sato mov.l @(OFF_R1,r15),r1 152de398406SYoshinori Sato mov.l @(OFF_R2,r15),r2 153de398406SYoshinori Sato mov.l @(OFF_R3,r15),r3 154de398406SYoshinori Sato2: 155de398406SYoshinori Sato mov #64,r8 156de398406SYoshinori Sato cmp/hs r8,r9 157de398406SYoshinori Sato bt interrupt_entry ! vec >= 64 is interrupt 1583623d138SRich Felker mov #31,r8 159de398406SYoshinori Sato cmp/hs r8,r9 1603623d138SRich Felker bt trap_entry ! 64 > vec >= 31 is trap 1615a846abaSRich Felker#ifdef CONFIG_CPU_J2 1625a846abaSRich Felker mov #16,r8 1635a846abaSRich Felker cmp/hs r8,r9 1645a846abaSRich Felker bt interrupt_entry ! 31 > vec >= 16 is interrupt 1655a846abaSRich Felker#endif 16674d99a5eSPaul Mundt 167de398406SYoshinori Sato mov.l 4f,r8 168de398406SYoshinori Sato mov r9,r4 169de398406SYoshinori Sato shll2 r9 170de398406SYoshinori Sato add r9,r8 1716e80f5e8SYoshinori Sato mov.l @r8,r8 ! exception handler address 1726e80f5e8SYoshinori Sato tst r8,r8 173de398406SYoshinori Sato bf 3f 174de398406SYoshinori Sato mov.l 8f,r8 ! unhandled exception 175de398406SYoshinori Sato3: 176de398406SYoshinori Sato mov.l 5f,r10 177de398406SYoshinori Sato jmp @r8 178de398406SYoshinori Sato lds r10,pr 179de398406SYoshinori Sato 180de398406SYoshinori Satointerrupt_entry: 181de398406SYoshinori Sato mov r9,r4 1823afb209aSPaul Mundt mov r15,r5 183de398406SYoshinori Sato mov.l 6f,r9 184de398406SYoshinori Sato mov.l 7f,r8 185de398406SYoshinori Sato jmp @r8 186de398406SYoshinori Sato lds r9,pr 187de398406SYoshinori Sato 188de398406SYoshinori Sato .align 2 189de398406SYoshinori Sato4: .long exception_handling_table 190de398406SYoshinori Sato5: .long ret_from_exception 191de398406SYoshinori Sato6: .long ret_from_irq 192de398406SYoshinori Sato7: .long do_IRQ 1936e80f5e8SYoshinori Sato8: .long exception_error 194de398406SYoshinori Sato 195de398406SYoshinori Satotrap_entry: 1964aa362bbSYoshinori Sato mov #0x30,r8 1973623d138SRich Felker cmp/ge r8,r9 ! vector 0x1f-0x2f is systemcall 1984aa362bbSYoshinori Sato bt 1f 1993623d138SRich Felker mov #0x1f,r9 ! convert to unified SH2/3/4 trap number 200e9cfc147SYoshinori Sato1: 201de398406SYoshinori Sato shll2 r9 ! TRA 2026e80f5e8SYoshinori Sato bra system_call ! jump common systemcall entry 203de398406SYoshinori Sato mov r9,r8 204de398406SYoshinori Sato 205de398406SYoshinori Sato#if defined(CONFIG_SH_STANDARD_BIOS) 206de398406SYoshinori Sato /* Unwind the stack and jmp to the debug entry */ 207f413d0d9SPaul MundtENTRY(sh_bios_handler) 208de398406SYoshinori Sato mov r15,r0 209de398406SYoshinori Sato add #(22-4)*4-4,r0 210de398406SYoshinori Sato ldc.l @r0+,gbr 211de398406SYoshinori Sato lds.l @r0+,mach 212de398406SYoshinori Sato lds.l @r0+,macl 213de398406SYoshinori Sato mov r15,r0 214de398406SYoshinori Sato mov.l @(OFF_SP,r0),r1 215de398406SYoshinori Sato mov #OFF_SR,r2 216de398406SYoshinori Sato mov.l @(r0,r2),r3 217de398406SYoshinori Sato mov.l r3,@-r1 218de398406SYoshinori Sato mov #OFF_SP,r2 219de398406SYoshinori Sato mov.l @(r0,r2),r3 220de398406SYoshinori Sato mov.l r3,@-r1 221de398406SYoshinori Sato mov r15,r0 222de398406SYoshinori Sato add #(22-4)*4-8,r0 223de398406SYoshinori Sato mov.l 1f,r2 224de398406SYoshinori Sato mov.l @r2,r2 225de398406SYoshinori Sato stc sr,r3 226de398406SYoshinori Sato mov.l r2,@r0 2276e80f5e8SYoshinori Sato mov.l r3,@(4,r0) 228de398406SYoshinori Sato mov.l r1,@(8,r0) 229de398406SYoshinori Sato mov.l @r15+, r0 230de398406SYoshinori Sato mov.l @r15+, r1 231de398406SYoshinori Sato mov.l @r15+, r2 232de398406SYoshinori Sato mov.l @r15+, r3 233de398406SYoshinori Sato mov.l @r15+, r4 234de398406SYoshinori Sato mov.l @r15+, r5 235de398406SYoshinori Sato mov.l @r15+, r6 236de398406SYoshinori Sato mov.l @r15+, r7 237de398406SYoshinori Sato mov.l @r15+, r8 238de398406SYoshinori Sato mov.l @r15+, r9 239de398406SYoshinori Sato mov.l @r15+, r10 240de398406SYoshinori Sato mov.l @r15+, r11 241de398406SYoshinori Sato mov.l @r15+, r12 242de398406SYoshinori Sato mov.l @r15+, r13 243de398406SYoshinori Sato mov.l @r15+, r14 244de398406SYoshinori Sato add #8,r15 245de398406SYoshinori Sato lds.l @r15+, pr 246de398406SYoshinori Sato mov.l @r15+,r15 2477a90e00dSPaul Mundt rte 2487a90e00dSPaul Mundt nop 249de398406SYoshinori Sato .align 2 250de398406SYoshinori Sato1: .long gdb_vbr_vector 251de398406SYoshinori Sato#endif /* CONFIG_SH_STANDARD_BIOS */ 252de398406SYoshinori Sato 2535a4f7c66SPaul MundtENTRY(address_error_trap_handler) 254de398406SYoshinori Sato mov r15,r4 ! regs 255de398406SYoshinori Sato mov #OFF_PC,r0 256de398406SYoshinori Sato mov.l @(r0,r15),r6 ! pc 257de398406SYoshinori Sato mov.l 1f,r0 258de398406SYoshinori Sato jmp @r0 259de398406SYoshinori Sato mov #0,r5 ! writeaccess is unknown 260de398406SYoshinori Sato 2616e80f5e8SYoshinori Sato .align 2 262de398406SYoshinori Sato1: .long do_address_error 263de398406SYoshinori Sato 264de398406SYoshinori Satorestore_all: 2656e80f5e8SYoshinori Sato stc sr,r0 2666e80f5e8SYoshinori Sato or #0xf0,r0 2676e80f5e8SYoshinori Sato ldc r0,sr ! all interrupt block (same BL = 1) 2686e80f5e8SYoshinori Sato ! restore special register 2696e80f5e8SYoshinori Sato ! overlap exception frame 2706e80f5e8SYoshinori Sato mov r15,r0 2716e80f5e8SYoshinori Sato add #17*4,r0 2726e80f5e8SYoshinori Sato lds.l @r0+,pr 2736e80f5e8SYoshinori Sato add #4,r0 2746e80f5e8SYoshinori Sato ldc.l @r0+,gbr 2756e80f5e8SYoshinori Sato lds.l @r0+,mach 2766e80f5e8SYoshinori Sato lds.l @r0+,macl 277de398406SYoshinori Sato mov r15,r0 278de398406SYoshinori Sato mov.l $cpu_mode,r2 2794b6ef05bSRich Felker#ifdef CONFIG_SMP 2804b6ef05bSRich Felker mov.l $cpuid,r3 2814b6ef05bSRich Felker mov.l @r3,r3 2824b6ef05bSRich Felker mov.l @r3,r3 2834b6ef05bSRich Felker shll2 r3 2844b6ef05bSRich Felker add r3,r2 2854b6ef05bSRich Felker#endif 286de398406SYoshinori Sato mov #OFF_SR,r3 287de398406SYoshinori Sato mov.l @(r0,r3),r1 2886e80f5e8SYoshinori Sato mov.l __md_bit,r3 2896e80f5e8SYoshinori Sato and r1,r3 ! copy MD bit 2906e80f5e8SYoshinori Sato mov.l r3,@r2 291de398406SYoshinori Sato shll2 r1 ! clear MD bit 292de398406SYoshinori Sato shlr2 r1 293de398406SYoshinori Sato mov.l @(OFF_SP,r0),r2 294de398406SYoshinori Sato add #-8,r2 295de398406SYoshinori Sato mov.l r2,@(OFF_SP,r0) ! point exception frame top 296de398406SYoshinori Sato mov.l r1,@(4,r2) ! set sr 297de398406SYoshinori Sato mov #OFF_PC,r3 298de398406SYoshinori Sato mov.l @(r0,r3),r1 299de398406SYoshinori Sato mov.l r1,@r2 ! set pc 300de398406SYoshinori Sato get_current_thread_info r0, r1 301de398406SYoshinori Sato mov.l $current_thread_info,r1 3024b6ef05bSRich Felker#ifdef CONFIG_SMP 3034b6ef05bSRich Felker mov.l $cpuid,r3 3044b6ef05bSRich Felker mov.l @r3,r3 3054b6ef05bSRich Felker mov.l @r3,r3 3064b6ef05bSRich Felker shll2 r3 3074b6ef05bSRich Felker add r3,r1 3084b6ef05bSRich Felker#endif 309de398406SYoshinori Sato mov.l r0,@r1 310de398406SYoshinori Sato mov.l @r15+,r0 311de398406SYoshinori Sato mov.l @r15+,r1 312de398406SYoshinori Sato mov.l @r15+,r2 313de398406SYoshinori Sato mov.l @r15+,r3 314de398406SYoshinori Sato mov.l @r15+,r4 315de398406SYoshinori Sato mov.l @r15+,r5 316de398406SYoshinori Sato mov.l @r15+,r6 317de398406SYoshinori Sato mov.l @r15+,r7 318de398406SYoshinori Sato mov.l @r15+,r8 319de398406SYoshinori Sato mov.l @r15+,r9 320de398406SYoshinori Sato mov.l @r15+,r10 321de398406SYoshinori Sato mov.l @r15+,r11 322de398406SYoshinori Sato mov.l @r15+,r12 323de398406SYoshinori Sato mov.l @r15+,r13 324de398406SYoshinori Sato mov.l @r15+,r14 325de398406SYoshinori Sato mov.l @r15,r15 326de398406SYoshinori Sato rte 327de398406SYoshinori Sato nop 328de398406SYoshinori Sato 3299f9a5de4SPaul Mundt .align 2 3306e80f5e8SYoshinori Sato__md_bit: 3316e80f5e8SYoshinori Sato .long 0x40000000 332de398406SYoshinori Sato$current_thread_info: 333de398406SYoshinori Sato .long __current_thread_info 334de398406SYoshinori Sato$cpu_mode: 335de398406SYoshinori Sato .long __cpu_mode 3364b6ef05bSRich Felker#ifdef CONFIG_SMP 3374b6ef05bSRich Felker$cpuid: 3384b6ef05bSRich Felker .long sh2_cpuid_addr 3394b6ef05bSRich Felker#endif 340de398406SYoshinori Sato 341de398406SYoshinori Sato! common exception handler 342de398406SYoshinori Sato#include "../../entry-common.S" 343de398406SYoshinori Sato 3444b6ef05bSRich Felker#ifdef CONFIG_NR_CPUS 3454b6ef05bSRich Felker#define NR_CPUS CONFIG_NR_CPUS 3464b6ef05bSRich Felker#else 3474b6ef05bSRich Felker#define NR_CPUS 1 3484b6ef05bSRich Felker#endif 3494b6ef05bSRich Felker 350de398406SYoshinori Sato .data 351de398406SYoshinori Sato! cpu operation mode 352de398406SYoshinori Sato! bit30 = MD (compatible SH3/4) 353de398406SYoshinori Sato__cpu_mode: 3544b6ef05bSRich Felker .rept NR_CPUS 355de398406SYoshinori Sato .long 0x40000000 3564b6ef05bSRich Felker .endr 3574b6ef05bSRich Felker 3584b6ef05bSRich Felker#ifdef CONFIG_SMP 3594b6ef05bSRich Felker.global sh2_cpuid_addr 3604b6ef05bSRich Felkersh2_cpuid_addr: 3614b6ef05bSRich Felker .long dummy_cpuid 3624b6ef05bSRich Felkerdummy_cpuid: 3634b6ef05bSRich Felker .long 0 3644b6ef05bSRich Felker#endif 365de398406SYoshinori Sato 366de398406SYoshinori Sato .section .bss 367de398406SYoshinori Sato__current_thread_info: 3684b6ef05bSRich Felker .rept NR_CPUS 369de398406SYoshinori Sato .long 0 3704b6ef05bSRich Felker .endr 371de398406SYoshinori Sato 372de398406SYoshinori SatoENTRY(exception_handling_table) 373de398406SYoshinori Sato .space 4*32 374