Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[linux-2.6-microblaze.git] / arch / csky / kernel / entry.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3
4 #include <linux/linkage.h>
5 #include <abi/entry.h>
6 #include <abi/pgtable-bits.h>
7 #include <asm/errno.h>
8 #include <asm/setup.h>
9 #include <asm/unistd.h>
10 #include <asm/asm-offsets.h>
11 #include <linux/threads.h>
12 #include <asm/setup.h>
13 #include <asm/page.h>
14 #include <asm/thread_info.h>
15
16 .macro  zero_fp
17 #ifdef CONFIG_STACKTRACE
18         movi    r8, 0
19 #endif
20 .endm
21
22 .macro  context_tracking
23 #ifdef CONFIG_CONTEXT_TRACKING
24         mfcr    a0, epsr
25         btsti   a0, 31
26         bt      1f
27         jbsr    context_tracking_user_exit
28         ldw     a0, (sp, LSAVE_A0)
29         ldw     a1, (sp, LSAVE_A1)
30         ldw     a2, (sp, LSAVE_A2)
31         ldw     a3, (sp, LSAVE_A3)
32 #if defined(__CSKYABIV1__)
33         ldw     r6, (sp, LSAVE_A4)
34         ldw     r7, (sp, LSAVE_A5)
35 #endif
36 1:
37 #endif
38 .endm
39
40 .text
41 ENTRY(csky_pagefault)
42         SAVE_ALL 0
43         zero_fp
44         context_tracking
45         psrset  ee
46         mov     a0, sp
47         jbsr    do_page_fault
48         jmpi    ret_from_exception
49
50 ENTRY(csky_systemcall)
51         SAVE_ALL TRAP0_SIZE
52         zero_fp
53         context_tracking
54         psrset  ee, ie
55
56         lrw     r9, __NR_syscalls
57         cmphs   syscallid, r9           /* Check nr of syscall */
58         bt      1f
59
60         lrw     r9, sys_call_table
61         ixw     r9, syscallid
62         ldw     syscallid, (r9)
63         cmpnei  syscallid, 0
64         bf      ret_from_exception
65
66         mov     r9, sp
67         bmaski  r10, THREAD_SHIFT
68         andn    r9, r10
69         ldw     r10, (r9, TINFO_FLAGS)
70         lrw     r9, _TIF_SYSCALL_WORK
71         and     r10, r9
72         cmpnei  r10, 0
73         bt      csky_syscall_trace
74 #if defined(__CSKYABIV2__)
75         subi    sp, 8
76         stw     r5, (sp, 0x4)
77         stw     r4, (sp, 0x0)
78         jsr     syscallid                      /* Do system call */
79         addi    sp, 8
80 #else
81         jsr     syscallid
82 #endif
83         stw     a0, (sp, LSAVE_A0)      /* Save return value */
84 1:
85 #ifdef CONFIG_DEBUG_RSEQ
86         mov     a0, sp
87         jbsr    rseq_syscall
88 #endif
89         jmpi    ret_from_exception
90
91 csky_syscall_trace:
92         mov     a0, sp                  /* sp = pt_regs pointer */
93         jbsr    syscall_trace_enter
94         cmpnei  a0, 0
95         bt      1f
96         /* Prepare args before do system call */
97         ldw     a0, (sp, LSAVE_A0)
98         ldw     a1, (sp, LSAVE_A1)
99         ldw     a2, (sp, LSAVE_A2)
100         ldw     a3, (sp, LSAVE_A3)
101 #if defined(__CSKYABIV2__)
102         subi    sp, 8
103         ldw     r9, (sp, LSAVE_A4)
104         stw     r9, (sp, 0x0)
105         ldw     r9, (sp, LSAVE_A5)
106         stw     r9, (sp, 0x4)
107         jsr     syscallid                     /* Do system call */
108         addi    sp, 8
109 #else
110         ldw     r6, (sp, LSAVE_A4)
111         ldw     r7, (sp, LSAVE_A5)
112         jsr     syscallid                     /* Do system call */
113 #endif
114         stw     a0, (sp, LSAVE_A0)      /* Save return value */
115
116 1:
117 #ifdef CONFIG_DEBUG_RSEQ
118         mov     a0, sp
119         jbsr    rseq_syscall
120 #endif
121         mov     a0, sp                  /* right now, sp --> pt_regs */
122         jbsr    syscall_trace_exit
123         br      ret_from_exception
124
125 ENTRY(ret_from_kernel_thread)
126         jbsr    schedule_tail
127         mov     a0, r10
128         jsr     r9
129         jbsr    ret_from_exception
130
131 ENTRY(ret_from_fork)
132         jbsr    schedule_tail
133         mov     r9, sp
134         bmaski  r10, THREAD_SHIFT
135         andn    r9, r10
136         ldw     r10, (r9, TINFO_FLAGS)
137         lrw     r9, _TIF_SYSCALL_WORK
138         and     r10, r9
139         cmpnei  r10, 0
140         bf      ret_from_exception
141         mov     a0, sp                  /* sp = pt_regs pointer */
142         jbsr    syscall_trace_exit
143
144 ret_from_exception:
145         psrclr  ie
146         ld      r9, (sp, LSAVE_PSR)
147         btsti   r9, 31
148
149         bt      1f
150         /*
151          * Load address of current->thread_info, Then get address of task_struct
152          * Get task_needreshed in task_struct
153          */
154         mov     r9, sp
155         bmaski  r10, THREAD_SHIFT
156         andn    r9, r10
157
158         ldw     r10, (r9, TINFO_FLAGS)
159         lrw     r9, _TIF_WORK_MASK
160         and     r10, r9
161         cmpnei  r10, 0
162         bt      exit_work
163 #ifdef CONFIG_CONTEXT_TRACKING
164         jbsr    context_tracking_user_enter
165 #endif
166 1:
167 #ifdef CONFIG_PREEMPTION
168         mov     r9, sp
169         bmaski  r10, THREAD_SHIFT
170         andn    r9, r10
171
172         ldw     r10, (r9, TINFO_PREEMPT)
173         cmpnei  r10, 0
174         bt      2f
175         jbsr    preempt_schedule_irq    /* irq en/disable is done inside */
176 2:
177 #endif
178
179 #ifdef CONFIG_TRACE_IRQFLAGS
180         ld      r10, (sp, LSAVE_PSR)
181         btsti   r10, 6
182         bf      2f
183         jbsr    trace_hardirqs_on
184 2:
185 #endif
186         RESTORE_ALL
187
188 exit_work:
189         lrw     r9, ret_from_exception
190         mov     lr, r9
191
192         btsti   r10, TIF_NEED_RESCHED
193         bt      work_resched
194
195         psrset  ie
196         mov     a0, sp
197         mov     a1, r10
198         jmpi    do_notify_resume
199
200 work_resched:
201         jmpi    schedule
202
203 ENTRY(csky_trap)
204         SAVE_ALL 0
205         zero_fp
206         context_tracking
207         psrset  ee
208         mov     a0, sp                 /* Push Stack pointer arg */
209         jbsr    trap_c                 /* Call C-level trap handler */
210         jmpi    ret_from_exception
211
212 /*
213  * Prototype from libc for abiv1:
214  * register unsigned int __result asm("a0");
215  * asm( "trap 3" :"=r"(__result)::);
216  */
217 ENTRY(csky_get_tls)
218         USPTOKSP
219
220         RD_MEH  a0
221         WR_MEH  a0
222
223         /* increase epc for continue */
224         mfcr    a0, epc
225         addi    a0, TRAP0_SIZE
226         mtcr    a0, epc
227
228         /* get current task thread_info with kernel 8K stack */
229         bmaski  a0, THREAD_SHIFT
230         not     a0
231         subi    sp, 1
232         and     a0, sp
233         addi    sp, 1
234
235         /* get tls */
236         ldw     a0, (a0, TINFO_TP_VALUE)
237
238         KSPTOUSP
239         rte
240
241 ENTRY(csky_irq)
242         SAVE_ALL 0
243         zero_fp
244         context_tracking
245         psrset  ee
246
247 #ifdef CONFIG_TRACE_IRQFLAGS
248         jbsr    trace_hardirqs_off
249 #endif
250
251
252         mov     a0, sp
253         jbsr    csky_do_IRQ
254
255         jmpi    ret_from_exception
256
257 /*
258  * a0 =  prev task_struct *
259  * a1 =  next task_struct *
260  * a0 =  return next
261  */
262 ENTRY(__switch_to)
263         lrw     a3, TASK_THREAD
264         addu    a3, a0
265
266         SAVE_SWITCH_STACK
267
268         stw     sp, (a3, THREAD_KSP)
269
270         /* Set up next process to run */
271         lrw     a3, TASK_THREAD
272         addu    a3, a1
273
274         ldw     sp, (a3, THREAD_KSP)    /* Set next kernel sp */
275
276 #if  defined(__CSKYABIV2__)
277         addi    a3, a1, TASK_THREAD_INFO
278         ldw     tls, (a3, TINFO_TP_VALUE)
279 #endif
280
281         RESTORE_SWITCH_STACK
282
283         rts
284 ENDPROC(__switch_to)