xref: /openbmc/linux/arch/csky/kernel/entry.S (revision a1515ec7)
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
361:
37#endif
38.endm
39
40.text
41ENTRY(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
50ENTRY(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 */
841:
85#ifdef CONFIG_DEBUG_RSEQ
86	mov	a0, sp
87	jbsr	rseq_syscall
88#endif
89	jmpi    ret_from_exception
90
91csky_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
1161:
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
125ENTRY(ret_from_kernel_thread)
126	jbsr	schedule_tail
127	mov	a0, r10
128	jsr	r9
129	jbsr	ret_from_exception
130
131ENTRY(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
144ret_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
1661:
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 */
1762:
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
1842:
185#endif
186	RESTORE_ALL
187
188exit_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
200work_resched:
201	jmpi	schedule
202
203ENTRY(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 */
217ENTRY(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
241ENTRY(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 */
262ENTRY(__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
284ENDPROC(__switch_to)
285