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