WIP FPC-III support
[linux/fpc-iii.git] / arch / csky / kernel / entry.S
blob5a5cabd076e1664bafa95848e6dc197a8f50d16b
1 /* SPDX-License-Identifier: GPL-2.0 */
2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
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>
16 #define PTE_INDX_MSK    0xffc
17 #define PTE_INDX_SHIFT  10
18 #define _PGDIR_SHIFT    22
20 .macro  zero_fp
21 #ifdef CONFIG_STACKTRACE
22         movi    r8, 0
23 #endif
24 .endm
26 .macro  context_tracking
27 #ifdef CONFIG_CONTEXT_TRACKING
28         mfcr    a0, epsr
29         btsti   a0, 31
30         bt      1f
31         jbsr    context_tracking_user_exit
32         ldw     a0, (sp, LSAVE_A0)
33         ldw     a1, (sp, LSAVE_A1)
34         ldw     a2, (sp, LSAVE_A2)
35         ldw     a3, (sp, LSAVE_A3)
36 #if defined(__CSKYABIV1__)
37         ldw     r6, (sp, LSAVE_A4)
38         ldw     r7, (sp, LSAVE_A5)
39 #endif
41 #endif
42 .endm
44 .macro tlbop_begin name, val0, val1, val2
45 ENTRY(csky_\name)
46         mtcr    a3, ss2
47         mtcr    r6, ss3
48         mtcr    a2, ss4
50         RD_PGDR r6
51         RD_MEH  a3
52 #ifdef CONFIG_CPU_HAS_TLBI
53         tlbi.vaas a3
54         sync.is
56         btsti   a3, 31
57         bf      1f
58         RD_PGDR_K r6
60 #else
61         bgeni   a2, 31
62         WR_MCIR a2
63         bgeni   a2, 25
64         WR_MCIR a2
65 #endif
66         bclri   r6, 0
67         lrw     a2, va_pa_offset
68         ld.w    a2, (a2, 0)
69         subu    r6, a2
70         bseti   r6, 31
72         mov     a2, a3
73         lsri    a2, _PGDIR_SHIFT
74         lsli    a2, 2
75         addu    r6, a2
76         ldw     r6, (r6)
78         lrw     a2, va_pa_offset
79         ld.w    a2, (a2, 0)
80         subu    r6, a2
81         bseti   r6, 31
83         lsri    a3, PTE_INDX_SHIFT
84         lrw     a2, PTE_INDX_MSK
85         and     a3, a2
86         addu    r6, a3
87         ldw     a3, (r6)
89         movi    a2, (_PAGE_PRESENT | \val0)
90         and     a3, a2
91         cmpne   a3, a2
92         bt      \name
94         /* First read/write the page, just update the flags */
95         ldw     a3, (r6)
96         bgeni   a2, PAGE_VALID_BIT
97         bseti   a2, PAGE_ACCESSED_BIT
98         bseti   a2, \val1
99         bseti   a2, \val2
100         or      a3, a2
101         stw     a3, (r6)
103         /* Some cpu tlb-hardrefill bypass the cache */
104 #ifdef CONFIG_CPU_NEED_TLBSYNC
105         movi    a2, 0x22
106         bseti   a2, 6
107         mtcr    r6, cr22
108         mtcr    a2, cr17
109         sync
110 #endif
112         mfcr    a3, ss2
113         mfcr    r6, ss3
114         mfcr    a2, ss4
115         rte
116 \name:
117         mfcr    a3, ss2
118         mfcr    r6, ss3
119         mfcr    a2, ss4
120         SAVE_ALL 0
121 .endm
122 .macro tlbop_end is_write
123         zero_fp
124         context_tracking
125         RD_MEH  a2
126         psrset  ee, ie
127         mov     a0, sp
128         movi    a1, \is_write
129         jbsr    do_page_fault
130         jmpi    ret_from_exception
131 .endm
133 .text
135 tlbop_begin tlbinvalidl, _PAGE_READ, PAGE_VALID_BIT, PAGE_ACCESSED_BIT
136 tlbop_end 0
138 tlbop_begin tlbinvalids, _PAGE_WRITE, PAGE_DIRTY_BIT, PAGE_MODIFIED_BIT
139 tlbop_end 1
141 tlbop_begin tlbmodified, _PAGE_WRITE, PAGE_DIRTY_BIT, PAGE_MODIFIED_BIT
142 #ifndef CONFIG_CPU_HAS_LDSTEX
143 jbsr csky_cmpxchg_fixup
144 #endif
145 tlbop_end 1
147 ENTRY(csky_systemcall)
148         SAVE_ALL TRAP0_SIZE
149         zero_fp
150         context_tracking
151         psrset  ee, ie
153         lrw     r9, __NR_syscalls
154         cmphs   syscallid, r9           /* Check nr of syscall */
155         bt      1f
157         lrw     r9, sys_call_table
158         ixw     r9, syscallid
159         ldw     syscallid, (r9)
160         cmpnei  syscallid, 0
161         bf      ret_from_exception
163         mov     r9, sp
164         bmaski  r10, THREAD_SHIFT
165         andn    r9, r10
166         ldw     r10, (r9, TINFO_FLAGS)
167         lrw     r9, _TIF_SYSCALL_WORK
168         and     r10, r9
169         cmpnei  r10, 0
170         bt      csky_syscall_trace
171 #if defined(__CSKYABIV2__)
172         subi    sp, 8
173         stw     r5, (sp, 0x4)
174         stw     r4, (sp, 0x0)
175         jsr     syscallid                      /* Do system call */
176         addi    sp, 8
177 #else
178         jsr     syscallid
179 #endif
180         stw     a0, (sp, LSAVE_A0)      /* Save return value */
182 #ifdef CONFIG_DEBUG_RSEQ
183         mov     a0, sp
184         jbsr    rseq_syscall
185 #endif
186         jmpi    ret_from_exception
188 csky_syscall_trace:
189         mov     a0, sp                  /* sp = pt_regs pointer */
190         jbsr    syscall_trace_enter
191         cmpnei  a0, 0
192         bt      1f
193         /* Prepare args before do system call */
194         ldw     a0, (sp, LSAVE_A0)
195         ldw     a1, (sp, LSAVE_A1)
196         ldw     a2, (sp, LSAVE_A2)
197         ldw     a3, (sp, LSAVE_A3)
198 #if defined(__CSKYABIV2__)
199         subi    sp, 8
200         ldw     r9, (sp, LSAVE_A4)
201         stw     r9, (sp, 0x0)
202         ldw     r9, (sp, LSAVE_A5)
203         stw     r9, (sp, 0x4)
204         jsr     syscallid                     /* Do system call */
205         addi    sp, 8
206 #else
207         ldw     r6, (sp, LSAVE_A4)
208         ldw     r7, (sp, LSAVE_A5)
209         jsr     syscallid                     /* Do system call */
210 #endif
211         stw     a0, (sp, LSAVE_A0)      /* Save return value */
214 #ifdef CONFIG_DEBUG_RSEQ
215         mov     a0, sp
216         jbsr    rseq_syscall
217 #endif
218         mov     a0, sp                  /* right now, sp --> pt_regs */
219         jbsr    syscall_trace_exit
220         br      ret_from_exception
222 ENTRY(ret_from_kernel_thread)
223         jbsr    schedule_tail
224         mov     a0, r10
225         jsr     r9
226         jbsr    ret_from_exception
228 ENTRY(ret_from_fork)
229         jbsr    schedule_tail
230         mov     r9, sp
231         bmaski  r10, THREAD_SHIFT
232         andn    r9, r10
233         ldw     r10, (r9, TINFO_FLAGS)
234         lrw     r9, _TIF_SYSCALL_WORK
235         and     r10, r9
236         cmpnei  r10, 0
237         bf      ret_from_exception
238         mov     a0, sp                  /* sp = pt_regs pointer */
239         jbsr    syscall_trace_exit
241 ret_from_exception:
242         psrclr  ie
243         ld      r9, (sp, LSAVE_PSR)
244         btsti   r9, 31
246         bt      1f
247         /*
248          * Load address of current->thread_info, Then get address of task_struct
249          * Get task_needreshed in task_struct
250          */
251         mov     r9, sp
252         bmaski  r10, THREAD_SHIFT
253         andn    r9, r10
255         ldw     r10, (r9, TINFO_FLAGS)
256         lrw     r9, _TIF_WORK_MASK
257         and     r10, r9
258         cmpnei  r10, 0
259         bt      exit_work
260 #ifdef CONFIG_CONTEXT_TRACKING
261         jbsr    context_tracking_user_enter
262 #endif
264 #ifdef CONFIG_PREEMPTION
265         mov     r9, sp
266         bmaski  r10, THREAD_SHIFT
267         andn    r9, r10
269         ldw     r10, (r9, TINFO_PREEMPT)
270         cmpnei  r10, 0
271         bt      2f
272         jbsr    preempt_schedule_irq    /* irq en/disable is done inside */
274 #endif
276 #ifdef CONFIG_TRACE_IRQFLAGS
277         ld      r10, (sp, LSAVE_PSR)
278         btsti   r10, 6
279         bf      2f
280         jbsr    trace_hardirqs_on
282 #endif
283         RESTORE_ALL
285 exit_work:
286         lrw     r9, ret_from_exception
287         mov     lr, r9
289         btsti   r10, TIF_NEED_RESCHED
290         bt      work_resched
292         psrset  ie
293         mov     a0, sp
294         mov     a1, r10
295         jmpi    do_notify_resume
297 work_resched:
298         jmpi    schedule
300 ENTRY(csky_trap)
301         SAVE_ALL 0
302         zero_fp
303         context_tracking
304         psrset  ee
305         mov     a0, sp                 /* Push Stack pointer arg */
306         jbsr    trap_c                 /* Call C-level trap handler */
307         jmpi    ret_from_exception
310  * Prototype from libc for abiv1:
311  * register unsigned int __result asm("a0");
312  * asm( "trap 3" :"=r"(__result)::);
313  */
314 ENTRY(csky_get_tls)
315         USPTOKSP
317         /* increase epc for continue */
318         mfcr    a0, epc
319         addi    a0, TRAP0_SIZE
320         mtcr    a0, epc
322         /* get current task thread_info with kernel 8K stack */
323         bmaski  a0, THREAD_SHIFT
324         not     a0
325         subi    sp, 1
326         and     a0, sp
327         addi    sp, 1
329         /* get tls */
330         ldw     a0, (a0, TINFO_TP_VALUE)
332         KSPTOUSP
333         rte
335 ENTRY(csky_irq)
336         SAVE_ALL 0
337         zero_fp
338         context_tracking
339         psrset  ee
341 #ifdef CONFIG_TRACE_IRQFLAGS
342         jbsr    trace_hardirqs_off
343 #endif
346         mov     a0, sp
347         jbsr    csky_do_IRQ
349         jmpi    ret_from_exception
352  * a0 =  prev task_struct *
353  * a1 =  next task_struct *
354  * a0 =  return next
355  */
356 ENTRY(__switch_to)
357         lrw     a3, TASK_THREAD
358         addu    a3, a0
360         SAVE_SWITCH_STACK
362         stw     sp, (a3, THREAD_KSP)
364         /* Set up next process to run */
365         lrw     a3, TASK_THREAD
366         addu    a3, a1
368         ldw     sp, (a3, THREAD_KSP)    /* Set next kernel sp */
370 #if  defined(__CSKYABIV2__)
371         addi    a3, a1, TASK_THREAD_INFO
372         ldw     tls, (a3, TINFO_TP_VALUE)
373 #endif
375         RESTORE_SWITCH_STACK
377         rts
378 ENDPROC(__switch_to)