linux/arch/sh/kernel/cpu/sh2/entry.S
<<
>>
Prefs
   1/*
   2 * arch/sh/kernel/cpu/sh2/entry.S
   3 *
   4 * The SH-2 exception entry
   5 *
   6 * Copyright (C) 2005-2008 Yoshinori Sato
   7 * Copyright (C) 2005  AXE,Inc.
   8 *
   9 * This file is subject to the terms and conditions of the GNU General Public
  10 * License.  See the file "COPYING" in the main directory of this archive
  11 * for more details.
  12 */
  13
  14#include <linux/linkage.h>
  15#include <asm/asm-offsets.h>
  16#include <asm/thread_info.h>
  17#include <cpu/mmu_context.h>
  18#include <asm/unistd.h>
  19#include <asm/errno.h>
  20#include <asm/page.h>
  21        
  22/* Offsets to the stack */
  23OFF_R0  =  0            /* Return value. New ABI also arg4 */
  24OFF_R1  =  4            /* New ABI: arg5 */
  25OFF_R2  =  8            /* New ABI: arg6 */
  26OFF_R3  =  12           /* New ABI: syscall_nr */
  27OFF_R4  =  16           /* New ABI: arg0 */
  28OFF_R5  =  20           /* New ABI: arg1 */
  29OFF_R6  =  24           /* New ABI: arg2 */
  30OFF_R7  =  28           /* New ABI: arg3 */
  31OFF_SP  =  (15*4)
  32OFF_PC  =  (16*4)
  33OFF_SR  =  (16*4+2*4)
  34OFF_TRA =  (16*4+6*4)
  35
  36#include <asm/entry-macros.S>
  37
  38ENTRY(exception_handler)
  39        ! stack
  40        ! r0 <- point sp
  41        ! r1
  42        ! pc
  43        ! sr
  44        ! r0 = temporary
  45        ! r1 = vector (pseudo EXPEVT / INTEVT / TRA)
  46        mov.l   r2,@-sp
  47        mov.l   r3,@-sp
  48        cli
  49        mov.l   $cpu_mode,r2
  50#ifdef CONFIG_SMP
  51        mov.l   $cpuid,r3
  52        mov.l   @r3,r3
  53        mov.l   @r3,r3
  54        shll2   r3
  55        add     r3,r2
  56#endif
  57        mov.l   @r2,r0
  58        mov.l   @(5*4,r15),r3   ! previous SR
  59        or      r0,r3           ! set MD
  60        tst     r0,r0
  61        bf/s    1f              ! previous mode check
  62         mov.l  r3,@(5*4,r15)   ! update SR
  63        ! switch to kernel mode
  64        mov.l   __md_bit,r0
  65        mov.l   r0,@r2          ! enter kernel mode
  66        mov.l   $current_thread_info,r2
  67#ifdef CONFIG_SMP
  68        mov.l   $cpuid,r0
  69        mov.l   @r0,r0
  70        mov.l   @r0,r0
  71        shll2   r0
  72        add     r0,r2
  73#endif
  74        mov.l   @r2,r2
  75        mov     #(THREAD_SIZE >> 8),r0
  76        shll8   r0
  77        add     r2,r0
  78        mov     r15,r2          ! r2 = user stack top
  79        mov     r0,r15          ! switch kernel stack
  80        mov.l   r1,@-r15        ! TRA
  81        sts.l   macl, @-r15
  82        sts.l   mach, @-r15
  83        stc.l   gbr, @-r15
  84        mov.l   @(5*4,r2),r0
  85        mov.l   r0,@-r15        ! original SR
  86        sts.l   pr,@-r15
  87        mov.l   @(4*4,r2),r0
  88        mov.l   r0,@-r15        ! original PC
  89        mov     r2,r3
  90        add     #(4+2)*4,r3     ! rewind r0 - r3 + exception frame
  91        mov.l   r3,@-r15        ! original SP
  92        mov.l   r14,@-r15
  93        mov.l   r13,@-r15
  94        mov.l   r12,@-r15
  95        mov.l   r11,@-r15
  96        mov.l   r10,@-r15
  97        mov.l   r9,@-r15
  98        mov.l   r8,@-r15
  99        mov.l   r7,@-r15
 100        mov.l   r6,@-r15
 101        mov.l   r5,@-r15
 102        mov.l   r4,@-r15
 103        mov     r1,r9           ! save TRA
 104        mov     r2,r8           ! copy user -> kernel stack
 105        mov.l   @(0,r8),r3
 106        mov.l   r3,@-r15
 107        mov.l   @(4,r8),r2
 108        mov.l   r2,@-r15
 109        mov.l   @(12,r8),r1
 110        mov.l   r1,@-r15
 111        mov.l   @(8,r8),r0
 112        bra     2f
 113         mov.l  r0,@-r15
 1141:
 115        ! in kernel exception
 116        mov     #(22-4-4-1)*4+4,r0
 117        mov     r15,r2
 118        sub     r0,r15
 119        mov.l   @r2+,r0         ! old R3
 120        mov.l   r0,@-r15        
 121        mov.l   @r2+,r0         ! old R2
 122        mov.l   r0,@-r15        
 123        mov.l   @(4,r2),r0      ! old R1
 124        mov.l   r0,@-r15        
 125        mov.l   @r2,r0          ! old R0
 126        mov.l   r0,@-r15
 127        add     #8,r2
 128        mov.l   @r2+,r3         ! old PC
 129        mov.l   @r2+,r0         ! old SR
 130        add     #-4,r2          ! exception frame stub (sr)
 131        mov.l   r1,@-r2         ! TRA
 132        sts.l   macl, @-r2
 133        sts.l   mach, @-r2
 134        stc.l   gbr, @-r2
 135        mov.l   r0,@-r2         ! save old SR
 136        sts.l   pr,@-r2
 137        mov.l   r3,@-r2         ! save old PC
 138        mov     r2,r0
 139        add     #8*4,r0
 140        mov.l   r0,@-r2         ! save old SP
 141        mov.l   r14,@-r2
 142        mov.l   r13,@-r2
 143        mov.l   r12,@-r2
 144        mov.l   r11,@-r2
 145        mov.l   r10,@-r2
 146        mov.l   r9,@-r2
 147        mov.l   r8,@-r2
 148        mov.l   r7,@-r2
 149        mov.l   r6,@-r2
 150        mov.l   r5,@-r2
 151        mov.l   r4,@-r2
 152        mov     r1,r9
 153        mov.l   @(OFF_R0,r15),r0
 154        mov.l   @(OFF_R1,r15),r1
 155        mov.l   @(OFF_R2,r15),r2
 156        mov.l   @(OFF_R3,r15),r3
 1572:
 158        mov     #64,r8
 159        cmp/hs  r8,r9
 160        bt      interrupt_entry ! vec >= 64 is interrupt
 161        mov     #31,r8
 162        cmp/hs  r8,r9
 163        bt      trap_entry      ! 64 > vec >= 31  is trap
 164#ifdef CONFIG_CPU_J2
 165        mov     #16,r8
 166        cmp/hs  r8,r9
 167        bt      interrupt_entry ! 31 > vec >= 16 is interrupt
 168#endif
 169
 170        mov.l   4f,r8
 171        mov     r9,r4
 172        shll2   r9
 173        add     r9,r8
 174        mov.l   @r8,r8          ! exception handler address
 175        tst     r8,r8
 176        bf      3f
 177        mov.l   8f,r8           ! unhandled exception
 1783:
 179        mov.l   5f,r10
 180        jmp     @r8
 181         lds    r10,pr
 182
 183interrupt_entry:
 184        mov     r9,r4
 185        mov     r15,r5
 186        mov.l   6f,r9
 187        mov.l   7f,r8
 188        jmp     @r8
 189         lds    r9,pr
 190
 191        .align  2
 1924:      .long   exception_handling_table
 1935:      .long   ret_from_exception
 1946:      .long   ret_from_irq
 1957:      .long   do_IRQ
 1968:      .long   exception_error
 197
 198trap_entry:
 199        mov     #0x30,r8
 200        cmp/ge  r8,r9           ! vector 0x1f-0x2f is systemcall
 201        bt      1f
 202        mov     #0x1f,r9        ! convert to unified SH2/3/4 trap number
 2031:      
 204        shll2   r9                      ! TRA
 205        bra     system_call     ! jump common systemcall entry
 206         mov    r9,r8
 207        
 208#if defined(CONFIG_SH_STANDARD_BIOS)
 209        /* Unwind the stack and jmp to the debug entry */
 210ENTRY(sh_bios_handler)
 211        mov     r15,r0
 212        add     #(22-4)*4-4,r0
 213        ldc.l   @r0+,gbr
 214        lds.l   @r0+,mach
 215        lds.l   @r0+,macl
 216        mov     r15,r0
 217        mov.l   @(OFF_SP,r0),r1
 218        mov     #OFF_SR,r2
 219        mov.l   @(r0,r2),r3
 220        mov.l   r3,@-r1
 221        mov     #OFF_SP,r2
 222        mov.l   @(r0,r2),r3
 223        mov.l   r3,@-r1
 224        mov     r15,r0
 225        add     #(22-4)*4-8,r0
 226        mov.l   1f,r2
 227        mov.l   @r2,r2
 228        stc     sr,r3
 229        mov.l   r2,@r0
 230        mov.l   r3,@(4,r0)
 231        mov.l   r1,@(8,r0)      
 232        mov.l   @r15+, r0
 233        mov.l   @r15+, r1
 234        mov.l   @r15+, r2
 235        mov.l   @r15+, r3
 236        mov.l   @r15+, r4
 237        mov.l   @r15+, r5
 238        mov.l   @r15+, r6
 239        mov.l   @r15+, r7
 240        mov.l   @r15+, r8
 241        mov.l   @r15+, r9
 242        mov.l   @r15+, r10
 243        mov.l   @r15+, r11
 244        mov.l   @r15+, r12
 245        mov.l   @r15+, r13
 246        mov.l   @r15+, r14
 247        add     #8,r15
 248        lds.l   @r15+, pr
 249        mov.l   @r15+,r15
 250        rte
 251         nop
 252        .align  2
 2531:      .long   gdb_vbr_vector
 254#endif /* CONFIG_SH_STANDARD_BIOS */
 255
 256ENTRY(address_error_trap_handler)
 257        mov     r15,r4                          ! regs
 258        mov     #OFF_PC,r0
 259        mov.l   @(r0,r15),r6                    ! pc
 260        mov.l   1f,r0
 261        jmp     @r0
 262         mov    #0,r5                           ! writeaccess is unknown
 263
 264        .align  2
 2651:      .long   do_address_error
 266
 267restore_all:
 268        stc     sr,r0
 269        or      #0xf0,r0
 270        ldc     r0,sr                           ! all interrupt block (same BL = 1)
 271        ! restore special register
 272        ! overlap exception frame
 273        mov     r15,r0
 274        add     #17*4,r0
 275        lds.l   @r0+,pr
 276        add     #4,r0
 277        ldc.l   @r0+,gbr
 278        lds.l   @r0+,mach
 279        lds.l   @r0+,macl
 280        mov     r15,r0
 281        mov.l   $cpu_mode,r2
 282#ifdef CONFIG_SMP
 283        mov.l   $cpuid,r3
 284        mov.l   @r3,r3
 285        mov.l   @r3,r3
 286        shll2   r3
 287        add     r3,r2
 288#endif
 289        mov     #OFF_SR,r3
 290        mov.l   @(r0,r3),r1
 291        mov.l   __md_bit,r3
 292        and     r1,r3                           ! copy MD bit
 293        mov.l   r3,@r2
 294        shll2   r1                              ! clear MD bit
 295        shlr2   r1
 296        mov.l   @(OFF_SP,r0),r2
 297        add     #-8,r2
 298        mov.l   r2,@(OFF_SP,r0)                 ! point exception frame top
 299        mov.l   r1,@(4,r2)                      ! set sr
 300        mov     #OFF_PC,r3
 301        mov.l   @(r0,r3),r1
 302        mov.l   r1,@r2                          ! set pc
 303        get_current_thread_info r0, r1
 304        mov.l   $current_thread_info,r1
 305#ifdef CONFIG_SMP
 306        mov.l   $cpuid,r3
 307        mov.l   @r3,r3
 308        mov.l   @r3,r3
 309        shll2   r3
 310        add     r3,r1
 311#endif
 312        mov.l   r0,@r1
 313        mov.l   @r15+,r0
 314        mov.l   @r15+,r1
 315        mov.l   @r15+,r2
 316        mov.l   @r15+,r3
 317        mov.l   @r15+,r4
 318        mov.l   @r15+,r5
 319        mov.l   @r15+,r6
 320        mov.l   @r15+,r7
 321        mov.l   @r15+,r8
 322        mov.l   @r15+,r9
 323        mov.l   @r15+,r10
 324        mov.l   @r15+,r11
 325        mov.l   @r15+,r12
 326        mov.l   @r15+,r13
 327        mov.l   @r15+,r14
 328        mov.l   @r15,r15
 329        rte
 330         nop
 331
 332        .align 2
 333__md_bit:
 334        .long   0x40000000
 335$current_thread_info:
 336        .long   __current_thread_info
 337$cpu_mode:      
 338        .long   __cpu_mode
 339#ifdef CONFIG_SMP
 340$cpuid:
 341        .long sh2_cpuid_addr
 342#endif
 343                
 344! common exception handler
 345#include "../../entry-common.S"
 346
 347#ifdef CONFIG_NR_CPUS
 348#define NR_CPUS CONFIG_NR_CPUS
 349#else
 350#define NR_CPUS 1
 351#endif
 352        
 353        .data
 354! cpu operation mode 
 355! bit30 = MD (compatible SH3/4)
 356__cpu_mode:
 357        .rept   NR_CPUS
 358        .long   0x40000000
 359        .endr
 360
 361#ifdef CONFIG_SMP
 362.global sh2_cpuid_addr
 363sh2_cpuid_addr:
 364        .long   dummy_cpuid
 365dummy_cpuid:
 366        .long   0
 367#endif
 368                
 369        .section        .bss
 370__current_thread_info:
 371        .rept   NR_CPUS
 372        .long   0
 373        .endr
 374
 375ENTRY(exception_handling_table)
 376        .space  4*32
 377