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

/* [<][>][^][v][top][bottom][index][help] */
   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 */
  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         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
 111 1:
 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
 154 2:
 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
 175 3:
 176         mov.l   5f,r10
 177         jmp     @r8
 178          lds    r10,pr
 179 
 180 interrupt_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
 189 4:      .long   exception_handling_table
 190 5:      .long   ret_from_exception
 191 6:      .long   ret_from_irq
 192 7:      .long   do_IRQ
 193 8:      .long   exception_error
 194 
 195 trap_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
 200 1:      
 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 */
 207 ENTRY(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
 250 1:      .long   gdb_vbr_vector
 251 #endif /* CONFIG_SH_STANDARD_BIOS */
 252 
 253 ENTRY(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
 262 1:      .long   do_address_error
 263 
 264 restore_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
 360 sh2_cpuid_addr:
 361         .long   dummy_cpuid
 362 dummy_cpuid:
 363         .long   0
 364 #endif
 365                 
 366         .section        .bss
 367 __current_thread_info:
 368         .rept   NR_CPUS
 369         .long   0
 370         .endr
 371 
 372 ENTRY(exception_handling_table)
 373         .space  4*32

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