linux/arch/h8300/kernel/entry.S
<<
>>
Prefs
   1/* -*- mode: asm -*-
   2 *
   3 *  linux/arch/h8300/platform/h8300h/entry.S
   4 *
   5 *  Yoshinori Sato <ysato@users.sourceforge.jp>
   6 *  David McCullough <davidm@snapgear.com>
   7 *
   8 */
   9
  10/*
  11 *  entry.S
  12 *  include exception/interrupt gateway
  13 *          system call entry
  14 */
  15
  16#include <linux/sys.h>
  17#include <asm/unistd.h>
  18#include <asm/setup.h>
  19#include <asm/segment.h>
  20#include <asm/linkage.h>
  21#include <asm/asm-offsets.h>
  22#include <asm/thread_info.h>
  23#include <asm/errno.h>
  24
  25#if defined(CONFIG_CPU_H8300H)
  26#define USERRET 8
  27INTERRUPTS = 64
  28        .h8300h
  29        .macro  SHLL2 reg
  30        shll.l  \reg
  31        shll.l  \reg
  32        .endm
  33        .macro  SHLR2 reg
  34        shlr.l  \reg
  35        shlr.l  \reg
  36        .endm
  37        .macro  SAVEREGS
  38        mov.l   er0,@-sp
  39        mov.l   er1,@-sp
  40        mov.l   er2,@-sp
  41        mov.l   er3,@-sp
  42        .endm
  43        .macro  RESTOREREGS
  44        mov.l   @sp+,er3
  45        mov.l   @sp+,er2
  46        .endm
  47        .macro  SAVEEXR
  48        .endm
  49        .macro  RESTOREEXR
  50        .endm
  51#endif
  52#if defined(CONFIG_CPU_H8S)
  53#define USERRET 10
  54#define USEREXR 8
  55INTERRUPTS = 128
  56        .h8300s
  57        .macro  SHLL2 reg
  58        shll.l  #2,\reg
  59        .endm
  60        .macro  SHLR2 reg
  61        shlr.l  #2,\reg
  62        .endm
  63        .macro  SAVEREGS
  64        stm.l   er0-er3,@-sp
  65        .endm
  66        .macro  RESTOREREGS
  67        ldm.l   @sp+,er2-er3
  68        .endm
  69        .macro  SAVEEXR
  70        mov.w   @(USEREXR:16,er0),r1
  71        mov.w   r1,@(LEXR-LER3:16,sp)           /* copy EXR */
  72        .endm
  73        .macro  RESTOREEXR
  74        mov.w   @(LEXR-LER1:16,sp),r1           /* restore EXR */
  75        mov.b   r1l,r1h
  76        mov.w   r1,@(USEREXR:16,er0)
  77        .endm
  78#endif
  79
  80
  81/* CPU context save/restore macros. */
  82
  83        .macro  SAVE_ALL
  84        mov.l   er0,@-sp
  85        stc     ccr,r0l                         /* check kernel mode */
  86        btst    #4,r0l
  87        bne     5f
  88
  89        /* user mode */
  90        mov.l   sp,@SYMBOL_NAME(sw_usp)
  91        mov.l   @sp,er0                         /* restore saved er0 */
  92        orc     #0x10,ccr                       /* switch kernel stack */
  93        mov.l   @SYMBOL_NAME(sw_ksp),sp
  94        sub.l   #(LRET-LORIG),sp                /* allocate LORIG - LRET */
  95        SAVEREGS
  96        mov.l   @SYMBOL_NAME(sw_usp),er0
  97        mov.l   @(USERRET:16,er0),er1           /* copy the RET addr */
  98        mov.l   er1,@(LRET-LER3:16,sp)
  99        SAVEEXR
 100
 101        mov.l   @(LORIG-LER3:16,sp),er0
 102        mov.l   er0,@(LER0-LER3:16,sp)          /* copy ER0 */
 103        mov.w   e1,r1                           /* e1 highbyte = ccr */
 104        and     #0xef,r1h                       /* mask mode? flag */
 105        bra     6f
 1065:
 107        /* kernel mode */
 108        mov.l   @sp,er0                         /* restore saved er0 */
 109        subs    #2,sp                           /* set dummy ccr */
 110        SAVEREGS
 111        mov.w   @(LRET-LER3:16,sp),r1           /* copy old ccr */
 1126:
 113        mov.b   r1h,r1l
 114        mov.b   #0,r1h
 115        mov.w   r1,@(LCCR-LER3:16,sp)           /* set ccr */
 116        mov.l   er6,@-sp                        /* syscall arg #6 */
 117        mov.l   er5,@-sp                        /* syscall arg #5 */
 118        mov.l   er4,@-sp                        /* syscall arg #4 */
 119        .endm                                   /* r1 = ccr */
 120
 121        .macro  RESTORE_ALL
 122        mov.l   @sp+,er4
 123        mov.l   @sp+,er5
 124        mov.l   @sp+,er6
 125        RESTOREREGS
 126        mov.w   @(LCCR-LER1:16,sp),r0           /* check kernel mode */
 127        btst    #4,r0l
 128        bne     7f
 129
 130        orc     #0x80,ccr
 131        mov.l   @SYMBOL_NAME(sw_usp),er0
 132        mov.l   @(LER0-LER1:16,sp),er1          /* restore ER0 */
 133        mov.l   er1,@er0
 134        RESTOREEXR
 135        mov.w   @(LCCR-LER1:16,sp),r1           /* restore the RET addr */
 136        mov.b   r1l,r1h
 137        mov.b   @(LRET+1-LER1:16,sp),r1l
 138        mov.w   r1,e1
 139        mov.w   @(LRET+2-LER1:16,sp),r1
 140        mov.l   er1,@(USERRET:16,er0)
 141
 142        mov.l   @sp+,er1
 143        add.l   #(LRET-LER1),sp                 /* remove LORIG - LRET */
 144        mov.l   sp,@SYMBOL_NAME(sw_ksp)
 145        andc    #0xef,ccr                       /* switch to user mode */
 146        mov.l   er0,sp
 147        bra     8f
 1487:
 149        mov.l   @sp+,er1
 150        adds    #4,sp
 151        adds    #2,sp
 1528:
 153        mov.l   @sp+,er0
 154        adds    #4,sp                           /* remove the sw created LVEC */
 155        rte
 156        .endm
 157
 158.globl SYMBOL_NAME(system_call)
 159.globl SYMBOL_NAME(ret_from_exception)
 160.globl SYMBOL_NAME(ret_from_fork)
 161.globl SYMBOL_NAME(ret_from_interrupt)
 162.globl SYMBOL_NAME(interrupt_redirect_table)
 163.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
 164.globl SYMBOL_NAME(resume)
 165.globl SYMBOL_NAME(interrupt_entry)
 166.globl SYMBOL_NAME(trace_break)
 167
 168#if defined(CONFIG_ROMKERNEL)
 169        .section .int_redirect,"ax"
 170SYMBOL_NAME_LABEL(interrupt_redirect_table)
 171#if defined(CONFIG_CPU_H8300H)
 172        .rept   7
 173        .long   0
 174        .endr
 175#endif
 176#if defined(CONFIG_CPU_H8S)
 177        .rept   5
 178        .long   0
 179        .endr
 180        jmp     @SYMBOL_NAME(trace_break)
 181        .long   0
 182#endif
 183
 184        jsr     @SYMBOL_NAME(interrupt_entry)   /* NMI */
 185        jmp     @SYMBOL_NAME(system_call)       /* TRAPA #0 (System call) */
 186        .long   0
 187        .long   0
 188        jmp     @SYMBOL_NAME(trace_break)       /* TRAPA #3 (breakpoint) */
 189        .rept   INTERRUPTS-12
 190        jsr     @SYMBOL_NAME(interrupt_entry)
 191        .endr
 192#endif
 193#if defined(CONFIG_RAMKERNEL)
 194.globl SYMBOL_NAME(interrupt_redirect_table)
 195        .section .bss
 196SYMBOL_NAME_LABEL(interrupt_redirect_table)
 197        .space  4
 198#endif
 199
 200        .section .text
 201        .align  2
 202SYMBOL_NAME_LABEL(interrupt_entry)
 203        SAVE_ALL
 204        mov.l   sp,er0
 205        add.l   #LVEC,er0
 206        btst    #4,r1l
 207        bne     1f
 208        /* user LVEC */
 209        mov.l   @SYMBOL_NAME(sw_usp),er0
 210        adds    #4,er0
 2111:
 212        mov.l   @er0,er0                        /* LVEC address */
 213#if defined(CONFIG_ROMKERNEL)
 214        sub.l   #SYMBOL_NAME(interrupt_redirect_table),er0
 215#endif
 216#if defined(CONFIG_RAMKERNEL)
 217        mov.l   @SYMBOL_NAME(interrupt_redirect_table),er1
 218        sub.l   er1,er0
 219#endif
 220        SHLR2   er0
 221        dec.l   #1,er0
 222        mov.l   sp,er1
 223        subs    #4,er1                          /* adjust ret_pc */
 224        jsr     @SYMBOL_NAME(do_IRQ)
 225        jmp     @SYMBOL_NAME(ret_from_interrupt)
 226
 227SYMBOL_NAME_LABEL(system_call)
 228        subs    #4,sp                           /* dummy LVEC */
 229        SAVE_ALL
 230        andc    #0x7f,ccr
 231        mov.l   er0,er4
 232
 233        /* save top of frame */
 234        mov.l   sp,er0
 235        jsr     @SYMBOL_NAME(set_esp0)
 236        mov.l   sp,er2
 237        and.w   #0xe000,r2
 238        mov.b   @((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
 239        btst    #(TIF_SYSCALL_TRACE & 7),r2l
 240        beq     1f
 241        jsr     @SYMBOL_NAME(do_syscall_trace)
 2421:
 243        cmp.l   #NR_syscalls,er4
 244        bcc     badsys
 245        SHLL2   er4
 246        mov.l   #SYMBOL_NAME(sys_call_table),er0
 247        add.l   er4,er0
 248        mov.l   @er0,er4
 249        beq     SYMBOL_NAME(ret_from_exception):16
 250        mov.l   @(LER1:16,sp),er0
 251        mov.l   @(LER2:16,sp),er1
 252        mov.l   @(LER3:16,sp),er2
 253        jsr     @er4
 254        mov.l   er0,@(LER0:16,sp)               /* save the return value */
 255        mov.l   sp,er2
 256        and.w   #0xe000,r2
 257        mov.b   @((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
 258        btst    #(TIF_SYSCALL_TRACE & 7),r2l
 259        beq     2f
 260        jsr     @SYMBOL_NAME(do_syscall_trace)
 2612:
 262#if defined(CONFIG_SYSCALL_PRINT)
 263        jsr     @SYMBOL_NAME(syscall_print)
 264#endif
 265        orc     #0x80,ccr
 266        bra     resume_userspace
 267
 268badsys:
 269        mov.l   #-ENOSYS,er0
 270        mov.l   er0,@(LER0:16,sp)
 271        bra     resume_userspace
 272
 273#if !defined(CONFIG_PREEMPT)
 274#define resume_kernel restore_all
 275#endif
 276
 277SYMBOL_NAME_LABEL(ret_from_exception)
 278#if defined(CONFIG_PREEMPT)
 279        orc     #0x80,ccr
 280#endif
 281SYMBOL_NAME_LABEL(ret_from_interrupt)
 282        mov.b   @(LCCR+1:16,sp),r0l
 283        btst    #4,r0l
 284        bne     resume_kernel:8         /* return from kernel */
 285resume_userspace:
 286        andc    #0x7f,ccr
 287        mov.l   sp,er4
 288        and.w   #0xe000,r4              /* er4 <- current thread info */
 289        mov.l   @(TI_FLAGS:16,er4),er1
 290        and.l   #_TIF_WORK_MASK,er1
 291        beq     restore_all:8
 292work_pending:
 293        btst    #TIF_NEED_RESCHED,r1l
 294        bne     work_resched:8
 295        /* work notifysig */
 296        mov.l   sp,er0
 297        subs    #4,er0                  /* er0: pt_regs */
 298        jsr     @SYMBOL_NAME(do_notify_resume)
 299        bra     restore_all:8
 300work_resched:
 301        mov.l   sp,er0
 302        jsr     @SYMBOL_NAME(set_esp0)
 303        jsr     @SYMBOL_NAME(schedule)
 304        bra     resume_userspace:8
 305restore_all:
 306        RESTORE_ALL                     /* Does RTE */
 307
 308#if defined(CONFIG_PREEMPT)
 309resume_kernel:
 310        mov.l   @(TI_PRE_COUNT:16,er4),er0
 311        bne     restore_all:8
 312need_resched:
 313        mov.l   @(TI_FLAGS:16,er4),er0
 314        btst    #TIF_NEED_RESCHED,r0l
 315        beq     restore_all:8
 316        mov.b   @(LCCR+1:16,sp),r0l     /* Interrupt Enabled? */
 317        bmi     restore_all:8
 318        mov.l   #PREEMPT_ACTIVE,er0
 319        mov.l   er0,@(TI_PRE_COUNT:16,er4)
 320        andc    #0x7f,ccr
 321        mov.l   sp,er0
 322        jsr     @SYMBOL_NAME(set_esp0)
 323        jsr     @SYMBOL_NAME(schedule)
 324        orc     #0x80,ccr
 325        bra     need_resched:8
 326#endif
 327
 328SYMBOL_NAME_LABEL(ret_from_fork)
 329        mov.l   er2,er0
 330        jsr     @SYMBOL_NAME(schedule_tail)
 331        jmp     @SYMBOL_NAME(ret_from_exception)
 332
 333SYMBOL_NAME_LABEL(resume)
 334        /*
 335         * Beware - when entering resume, offset of tss is in d1,
 336         * prev (the current task) is in a0, next (the new task)
 337         * is in a1 and d2.b is non-zero if the mm structure is
 338         * shared between the tasks, so don't change these
 339         * registers until their contents are no longer needed.
 340         */
 341
 342        /* save sr */
 343        sub.w   r3,r3
 344        stc     ccr,r3l
 345        mov.w   r3,@(THREAD_CCR+2:16,er0)
 346
 347        /* disable interrupts */
 348        orc     #0x80,ccr
 349        mov.l   @SYMBOL_NAME(sw_usp),er3
 350        mov.l   er3,@(THREAD_USP:16,er0)
 351        mov.l   sp,@(THREAD_KSP:16,er0)
 352
 353        /* Skip address space switching if they are the same. */
 354        /* FIXME: what did we hack out of here, this does nothing! */
 355
 356        mov.l   @(THREAD_USP:16,er1),er0
 357        mov.l   er0,@SYMBOL_NAME(sw_usp)
 358        mov.l   @(THREAD_KSP:16,er1),sp
 359
 360        /* restore status register */
 361        mov.w   @(THREAD_CCR+2:16,er1),r3
 362
 363        ldc     r3l,ccr
 364        rts
 365
 366SYMBOL_NAME_LABEL(trace_break)
 367        subs    #4,sp
 368        SAVE_ALL
 369        sub.l   er1,er1
 370        dec.l   #1,er1
 371        mov.l   er1,@(LORIG,sp)
 372        mov.l   sp,er0
 373        jsr     @SYMBOL_NAME(set_esp0)
 374        mov.l   @SYMBOL_NAME(sw_usp),er0
 375        mov.l   @er0,er1
 376        mov.w   @(-2:16,er1),r2
 377        cmp.w   #0x5730,r2
 378        beq     1f
 379        subs    #2,er1
 380        mov.l   er1,@er0
 3811:
 382        and.w   #0xff,e1
 383        mov.l   er1,er0
 384        jsr     @SYMBOL_NAME(trace_trap)
 385        jmp     @SYMBOL_NAME(ret_from_exception)
 386
 387        .section        .bss
 388SYMBOL_NAME_LABEL(sw_ksp)
 389        .space  4
 390SYMBOL_NAME_LABEL(sw_usp)
 391        .space  4
 392
 393        .end
 394