Linux 5.7.6
[linux/fpc-iii.git] / arch / nds32 / kernel / ex-entry.S
blob107d98a1d1b851758c7d1b764008bece438e0a99
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2005-2017 Andes Technology Corporation
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>
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)
21 skip_fucop_ctl:
22         smw.adm $p0, [$sp], $p0, #0x1
23         j fucop_ctl_done
24 #endif
25         .endm
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
36 fucop_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
45         /* push $r0 ~ $r25 */
46         smw.bim $r0, [$sp], $r25
47         /* push $fp, $gp, $lp */
48         smw.bim $sp, [$sp], $sp, #0xe
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
66         /* Initialize kernel space $fp */
67         andi    $p0, $r20, #PSW_mskPOM
68         movi    $p1, #0x0
69         cmovz   $fp, $p1, $p0
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
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]
83         .endm
85         .text
88  * Exception Vector
89  */
90 exception_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
102         skip_save_fucop_ctl
103 common_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 */
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
138         /* interrupt */
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
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
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
165         .section        ".text.init", #alloc, #execinstr
166         .global exception_vector
167 exception_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
177 exception_vector_end: