linux/arch/nds32/kernel/ex-entry.S
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (C) 2005-2017 Andes Technology Corporation
   3
   4#include <linux/linkage.h>
   5#include <asm/memory.h>
   6#include <asm/nds32.h>
   7#include <asm/errno.h>
   8#include <asm/asm-offsets.h>
   9#include <asm/page.h>
  10#include <asm/fpu.h>
  11
  12#ifdef CONFIG_HWZOL
  13        .macro push_zol
  14        mfusr   $r14, $LB
  15        mfusr   $r15, $LE
  16        mfusr   $r16, $LC
  17        .endm
  18#endif
  19        .macro  skip_save_fucop_ctl
  20#if defined(CONFIG_FPU)
  21skip_fucop_ctl:
  22        smw.adm $p0, [$sp], $p0, #0x1
  23        j fucop_ctl_done
  24#endif
  25        .endm
  26
  27        .macro  save_user_regs
  28#if defined(CONFIG_FPU)
  29        sethi   $p0, hi20(has_fpu)
  30        lbsi    $p0, [$p0+lo12(has_fpu)]
  31        beqz    $p0, skip_fucop_ctl
  32        mfsr    $p0, $FUCOP_CTL
  33        smw.adm $p0, [$sp], $p0, #0x1
  34        bclr    $p0, $p0, #FUCOP_CTL_offCP0EN
  35        mtsr    $p0, $FUCOP_CTL
  36fucop_ctl_done:
  37        /* move $SP to the bottom of pt_regs */
  38        addi    $sp, $sp, -FUCOP_CTL_OFFSET
  39#else
  40        smw.adm $sp, [$sp], $sp, #0x1
  41        /* move $SP to the bottom of pt_regs */
  42        addi    $sp, $sp, -OSP_OFFSET
  43#endif
  44
  45        /* push $r0 ~ $r25 */
  46        smw.bim $r0, [$sp], $r25
  47        /* push $fp, $gp, $lp */
  48        smw.bim $sp, [$sp], $sp, #0xe
  49
  50        mfsr    $r12, $SP_USR
  51        mfsr    $r13, $IPC
  52#ifdef CONFIG_HWZOL
  53        push_zol
  54#endif
  55        movi    $r17, -1
  56        move    $r18, $r0
  57        mfsr    $r19, $PSW
  58        mfsr    $r20, $IPSW
  59        mfsr    $r21, $P_IPSW
  60        mfsr    $r22, $P_IPC
  61        mfsr    $r23, $P_P0
  62        mfsr    $r24, $P_P1
  63        smw.bim $r12, [$sp], $r24, #0
  64        addi    $sp, $sp, -FUCOP_CTL_OFFSET
  65
  66        /* Initialize kernel space $fp */
  67        andi    $p0, $r20, #PSW_mskPOM
  68        movi    $p1, #0x0
  69        cmovz   $fp, $p1, $p0
  70
  71        andi    $r16, $r19, #PSW_mskINTL
  72        slti    $r17, $r16, #4
  73        bnez    $r17, 1f
  74        addi    $r17, $r19, #-2
  75        mtsr    $r17, $PSW
  76        isb
  771:
  78        /* If it was superuser mode, we don't need to update $r25 */
  79        bnez    $p0, 2f
  80        la      $p0, __entry_task
  81        lw      $r25, [$p0]
  822:
  83        .endm
  84
  85        .text
  86
  87/*
  88 * Exception Vector
  89 */
  90exception_handlers:
  91        .long   unhandled_exceptions    !Reset/NMI
  92        .long   unhandled_exceptions    !TLB fill
  93        .long   do_page_fault           !PTE not present
  94        .long   do_dispatch_tlb_misc    !TLB misc
  95        .long   unhandled_exceptions    !TLB VLPT
  96        .long   unhandled_exceptions    !Machine Error
  97        .long   do_debug_trap           !Debug related
  98        .long   do_dispatch_general     !General exception
  99        .long   eh_syscall              !Syscall
 100        .long   asm_do_IRQ              !IRQ
 101
 102        skip_save_fucop_ctl
 103common_exception_handler:
 104        save_user_regs
 105        mfsr    $p0, $ITYPE
 106        andi    $p0, $p0, #ITYPE_mskVECTOR
 107        srli    $p0, $p0, #ITYPE_offVECTOR
 108        andi    $p1, $p0, #NDS32_VECTOR_mskNONEXCEPTION
 109        bnez    $p1, 1f
 110        sethi   $lp, hi20(ret_from_exception)
 111        ori     $lp, $lp, lo12(ret_from_exception)
 112        sethi   $p1, hi20(exception_handlers)
 113        ori     $p1, $p1, lo12(exception_handlers)
 114        lw      $p1, [$p1+$p0<<2]
 115        move    $r0, $p0
 116        mfsr    $r1, $EVA
 117        mfsr    $r2, $ITYPE
 118        move    $r3, $sp
 119        mfsr    $r4, $OIPC
 120        /* enable gie if it is enabled in IPSW. */
 121        mfsr    $r21, $PSW
 122        andi    $r20, $r20, #PSW_mskGIE /* r20 is $IPSW*/
 123        or      $r21, $r21, $r20
 124        mtsr    $r21, $PSW
 125        dsb
 126        jr      $p1
 127        /* syscall */
 1281:
 129        addi    $p1, $p0, #-NDS32_VECTOR_offEXCEPTION
 130        bnez    $p1, 2f
 131        sethi   $lp, hi20(ret_from_exception)
 132        ori     $lp, $lp, lo12(ret_from_exception)
 133        sethi   $p1, hi20(exception_handlers)
 134        ori     $p1, $p1, lo12(exception_handlers)
 135        lwi     $p1, [$p1+#NDS32_VECTOR_offEXCEPTION<<2]
 136        jr      $p1
 137
 138        /* interrupt */
 1392:
 140#ifdef CONFIG_TRACE_IRQFLAGS
 141        jal     __trace_hardirqs_off
 142#endif
 143        move    $r0, $sp
 144        sethi   $lp, hi20(ret_from_intr)
 145        ori     $lp, $lp, lo12(ret_from_intr)
 146        sethi   $p0, hi20(exception_handlers)
 147        ori     $p0, $p0, lo12(exception_handlers)
 148        lwi     $p0, [$p0+#NDS32_VECTOR_offINTERRUPT<<2]
 149        jr      $p0
 150
 151        .macro  EXCEPTION_VECTOR_DEBUG
 152        .align 4
 153        mfsr     $p0, $EDM_CTL
 154        andi     $p0, $p0, EDM_CTL_mskV3_EDM_MODE
 155        tnez     $p0, SWID_RAISE_INTERRUPT_LEVEL
 156        .endm
 157
 158        .macro  EXCEPTION_VECTOR
 159        .align 4
 160        sethi    $p0, hi20(common_exception_handler)
 161        ori      $p0, $p0, lo12(common_exception_handler)
 162        jral.ton $p0, $p0
 163        .endm
 164
 165        .section        ".text.init", #alloc, #execinstr
 166        .global exception_vector
 167exception_vector:
 168.rept 6
 169        EXCEPTION_VECTOR
 170.endr
 171        EXCEPTION_VECTOR_DEBUG
 172.rept 121
 173        EXCEPTION_VECTOR
 174.endr
 175        .align 4
 176        .global exception_vector_end
 177exception_vector_end:
 178