root/arch/sh/kernel/cpu/sh2a/entry.S

/* [<][>][^][v][top][bottom][index][help] */
   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 */
  20 OFF_R0  =  0            /* Return value. New ABI also arg4 */
  21 OFF_R1  =  4            /* New ABI: arg5 */
  22 OFF_R2  =  8            /* New ABI: arg6 */
  23 OFF_R3  =  12           /* New ABI: syscall_nr */
  24 OFF_R4  =  16           /* New ABI: arg0 */
  25 OFF_R5  =  20           /* New ABI: arg1 */
  26 OFF_R6  =  24           /* New ABI: arg2 */
  27 OFF_R7  =  28           /* New ABI: arg3 */
  28 OFF_SP  =  (15*4)
  29 OFF_PC  =  (16*4)
  30 OFF_SR  =  (16*4+2*4)
  31 OFF_TRA =  (16*4+6*4)
  32 
  33 #include <asm/entry-macros.S>
  34 
  35 ENTRY(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
  79 1:
  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
 104 2:
 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
 121 3:
 122         mov.l   5f,r10
 123         jmp     @r8
 124          lds    r10,pr
 125 
 126 interrupt_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
 135 4:      .long   exception_handling_table
 136 5:      .long   ret_from_exception
 137 6:      .long   ret_from_irq
 138 7:      .long   do_IRQ
 139 8:      .long   exception_error
 140 
 141 trap_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
 146 1:      
 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 */
 153 ENTRY(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
 180 1:      .long   gdb_vbr_vector
 181 #endif /* CONFIG_SH_STANDARD_BIOS */
 182 
 183 ENTRY(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
 191 1:      .long   do_address_error
 192 
 193 restore_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 
 246 ENTRY(exception_handling_table)
 247         .space  4*32

/* [<][>][^][v][top][bottom][index][help] */