1 /* SPDX-License-Identifier: GPL-2.0 */
2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
4 #include <linux/linkage.h>
6 #include <abi/pgtable-bits.h>
9 #include <asm/unistd.h>
10 #include <asm/asm-offsets.h>
11 #include <linux/threads.h>
12 #include <asm/setup.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 tlbop_begin name, val0, val1, val2
28 #ifdef CONFIG_CPU_HAS_TLBI
57 lsri a3, PTE_INDX_SHIFT
63 movi a2, (_PAGE_PRESENT | \val0)
68 /* First read/write the page, just update the flags */
70 bgeni a2, PAGE_VALID_BIT
71 bseti a2, PAGE_ACCESSED_BIT
77 /* Some cpu tlb-hardrefill bypass the cache */
78 #ifdef CONFIG_CPU_NEED_TLBSYNC
96 .macro tlbop_end is_write
102 movi r11_sig, 0 /* r11 = 0, Not a syscall. */
103 jmpi ret_from_exception
108 tlbop_begin tlbinvalidl, _PAGE_READ, PAGE_VALID_BIT, PAGE_ACCESSED_BIT
111 tlbop_begin tlbinvalids, _PAGE_WRITE, PAGE_DIRTY_BIT, PAGE_MODIFIED_BIT
114 tlbop_begin tlbmodified, _PAGE_WRITE, PAGE_DIRTY_BIT, PAGE_MODIFIED_BIT
115 #ifndef CONFIG_CPU_HAS_LDSTEX
116 jbsr csky_cmpxchg_fixup
120 ENTRY(csky_systemcall)
121 SAVE_ALL EPC_INCREASE
125 lrw r11, __NR_syscalls
126 cmphs syscallid, r11 /* Check nr of syscall */
127 bt ret_from_exception
129 lrw r13, sys_call_table
133 bf ret_from_exception
136 bmaski r10, THREAD_SHIFT
138 ldw r8, (r9, TINFO_FLAGS)
139 btsti r8, TIF_SYSCALL_TRACE
141 #if defined(__CSKYABIV2__)
145 jsr r11 /* Do system call */
150 stw a0, (sp, LSAVE_A0) /* Save return value */
151 jmpi ret_from_exception
154 movi a0, 0 /* enter system call */
155 mov a1, sp /* sp = pt_regs pointer */
157 /* Prepare args before do system call */
158 ldw a0, (sp, LSAVE_A0)
159 ldw a1, (sp, LSAVE_A1)
160 ldw a2, (sp, LSAVE_A2)
161 ldw a3, (sp, LSAVE_A3)
162 #if defined(__CSKYABIV2__)
167 ldw r6, (sp, LSAVE_A4)
168 ldw r7, (sp, LSAVE_A5)
170 jsr r11 /* Do system call */
171 #if defined(__CSKYABIV2__)
174 stw a0, (sp, LSAVE_A0) /* Save return value */
176 movi a0, 1 /* leave system call */
177 mov a1, sp /* right now, sp --> pt_regs */
179 br ret_from_exception
181 ENTRY(ret_from_kernel_thread)
185 jbsr ret_from_exception
190 bmaski r10, THREAD_SHIFT
192 ldw r8, (r9, TINFO_FLAGS)
194 btsti r8, TIF_SYSCALL_TRACE
197 mov a1, sp /* sp = pt_regs pointer */
200 jbsr ret_from_exception
203 ld syscallid, (sp, LSAVE_PSR)
208 * Load address of current->thread_info, Then get address of task_struct
209 * Get task_needreshed in task_struct
212 bmaski r10, THREAD_SHIFT
216 ldw r8, (r9, TINFO_FLAGS)
217 andi r8, (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED)
223 btsti r8, TIF_NEED_RESCHED
225 /* If thread_info->flag is empty, RESTORE_ALL */
230 mov a2, r11_sig /* syscall? */
231 btsti r8, TIF_SIGPENDING /* delivering a signal? */
232 /* prevent further restarts(set r11 = 0) */
234 jbsr do_notify_resume /* do signals */
238 lrw syscallid, ret_from_exception
239 mov r15, syscallid /* Return address in link */
242 ENTRY(sys_rt_sigreturn)
249 movi r11_sig, 0 /* r11 = 0, Not a syscall. */
250 mov a0, sp /* Push Stack pointer arg */
251 jbsr trap_c /* Call C-level trap handler */
252 jmpi ret_from_exception
255 * Prototype from libc for abiv1:
256 * register unsigned int __result asm("a0");
257 * asm( "trap 3" :"=r"(__result)::);
262 /* increase epc for continue */
267 /* get current task thread_info with kernel 8K stack */
268 bmaski a0, THREAD_SHIFT
275 ldw a0, (a0, TINFO_TP_VALUE)
283 movi r11_sig, 0 /* r11 = 0, Not a syscall. */
285 #ifdef CONFIG_PREEMPT
286 mov r9, sp /* Get current stack pointer */
287 bmaski r10, THREAD_SHIFT
288 andn r9, r10 /* Get thread_info */
291 * Get task_struct->stack.preempt_count for current,
294 ldw r8, (r9, TINFO_PREEMPT)
296 stw r8, (r9, TINFO_PREEMPT)
302 #ifdef CONFIG_PREEMPT
304 stw r8, (r9, TINFO_PREEMPT)
307 ldw r8, (r9, TINFO_FLAGS)
308 btsti r8, TIF_NEED_RESCHED
311 jbsr preempt_schedule_irq /* irq en/disable is done inside */
312 ldw r7, (r9, TINFO_FLAGS) /* get new tasks TI_FLAGS */
313 btsti r7, TIF_NEED_RESCHED
317 jmpi ret_from_exception
320 * a0 = prev task_struct *
321 * a1 = next task_struct *
328 mfcr a2, psr /* Save PSR value */
329 stw a2, (a3, THREAD_SR) /* Save PSR in task struct */
330 bclri a2, 6 /* Disable interrupts */
335 stw sp, (a3, THREAD_KSP)
337 /* Set up next process to run */
341 ldw sp, (a3, THREAD_KSP) /* Set next kernel sp */
343 ldw a2, (a3, THREAD_SR) /* Set next PSR */
346 #if defined(__CSKYABIV2__)
347 addi r7, a1, TASK_THREAD_INFO
348 ldw tls, (r7, TINFO_TP_VALUE)