linux/arch/sh/kernel/cpu/sh2/entry.S
<<
>>
Prefs
   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