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