Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
  1/*
  2 * arch/score/kernel/entry.S
  3 *
  4 * Score Processor version.
  5 *
  6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
  7 *  Chen Liqin <liqin.chen@sunplusct.com>
  8 *  Lennox Wu <lennox.wu@sunplusct.com>
  9 *
 10 * This program is free software; you can redistribute it and/or modify
 11 * it under the terms of the GNU General Public License as published by
 12 * the Free Software Foundation; either version 2 of the License, or
 13 * (at your option) any later version.
 14 *
 15 * This program is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18 * GNU General Public License for more details.
 19 *
 20 * You should have received a copy of the GNU General Public License
 21 * along with this program; if not, see the file COPYING, or write
 22 * to the Free Software Foundation, Inc.,
 23 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 24 */
 25
 26#include <linux/err.h>
 27#include <linux/init.h>
 28#include <linux/linkage.h>
 29
 30#include <asm/asmmacro.h>
 31#include <asm/thread_info.h>
 32#include <asm/unistd.h>
 33
 34/*
 35 * disable interrupts.
 36 */
 37.macro	disable_irq
 38	mfcr	r8, cr0
 39	srli	r8, r8, 1
 40	slli	r8, r8, 1
 41	mtcr	r8, cr0
 42	nop
 43	nop
 44	nop
 45	nop
 46	nop
 47.endm
 48
 49/*
 50 * enable interrupts.
 51 */
 52.macro	enable_irq
 53	mfcr	r8, cr0
 54	ori	r8, 1
 55	mtcr	r8, cr0
 56	nop
 57	nop
 58	nop
 59	nop
 60	nop
 61.endm
 62
 63__INIT
 64ENTRY(debug_exception_vector)
 65	nop!
 66	nop!
 67	nop!
 68	nop!
 69	nop!
 70	nop!
 71	nop!
 72	nop!
 73
 74ENTRY(general_exception_vector)			# should move to addr 0x200
 75	j	general_exception
 76	nop!
 77	nop!
 78	nop!
 79	nop!
 80	nop!
 81	nop!
 82
 83ENTRY(interrupt_exception_vector)		# should move to addr 0x210
 84	j	interrupt_exception
 85	nop!
 86	nop!
 87	nop!
 88	nop!
 89	nop!
 90	nop!
 91
 92	.section ".text", "ax"
 93	.align	2;
 94general_exception:
 95	mfcr	r31, cr2
 96	nop
 97	la	r30, exception_handlers
 98	andi	r31, 0x1f			# get ecr.exc_code
 99	slli	r31, r31, 2
100	add	r30, r30, r31
101	lw	r30, [r30]
102	br	r30
103
104interrupt_exception:
105	SAVE_ALL
106	mfcr	r4, cr2
107	nop
108	lw	r16, [r28, TI_REGS]
109	sw	r0, [r28, TI_REGS]
110	la	r3, ret_from_irq
111	srli	r4, r4, 18			# get ecr.ip[7:2], interrupt No.
112	mv	r5, r0
113	j	do_IRQ
114
115ENTRY(handle_nmi)				# NMI #1
116	SAVE_ALL
117	mv	r4, r0
118	la	r8, nmi_exception_handler
119	brl	r8
120	j	restore_all
121
122ENTRY(handle_adelinsn)				# AdEL-instruction #2
123	SAVE_ALL
124	mfcr	r8, cr6
125	nop
126	nop
127	sw	r8, [r0, PT_EMA]
128	mv	r4, r0
129	la	r8, do_adelinsn
130	brl	r8
131	mv	r4, r0
132	j	ret_from_exception
133	nop
134
135ENTRY(handle_ibe)				# BusEL-instruction #5
136	SAVE_ALL
137	mv	r4, r0
138	la	r8, do_be
139	brl	r8
140	mv	r4, r0
141	j	ret_from_exception
142	nop
143
144ENTRY(handle_pel)				# P-EL #6
145	SAVE_ALL
146	mv	r4, r0
147	la	r8, do_pel
148	brl	r8
149	mv	r4, r0
150	j	ret_from_exception
151	nop
152
153ENTRY(handle_ccu)				# CCU #8
154	SAVE_ALL
155	mv	r4, r0
156	la	r8, do_ccu
157	brl	r8
158	mv	r4, r0
159	j	ret_from_exception
160	nop
161
162ENTRY(handle_ri)				# RI #9
163	SAVE_ALL
164	mv	r4, r0
165	la	r8, do_ri
166	brl	r8
167	mv	r4, r0
168	j	ret_from_exception
169	nop
170
171ENTRY(handle_tr)				# Trap #10
172	SAVE_ALL
173	mv	r4, r0
174	la	r8, do_tr
175	brl	r8
176	mv	r4, r0
177	j	ret_from_exception
178	nop
179
180ENTRY(handle_adedata)				# AdES-instruction #12
181	SAVE_ALL
182	mfcr	r8, cr6
183	nop
184	nop
185	sw	r8, [r0, PT_EMA]
186	mv	r4, r0
187	la	r8, do_adedata
188	brl	r8
189	mv	r4, r0
190	j	ret_from_exception
191	nop
192
193ENTRY(handle_cee)				# CeE #16
194	SAVE_ALL
195	mv	r4, r0
196	la	r8, do_cee
197	brl	r8
198	mv	r4, r0
199	j	ret_from_exception
200	nop
201
202ENTRY(handle_cpe)				# CpE #17
203	SAVE_ALL
204	mv	r4, r0
205	la	r8, do_cpe
206	brl	r8
207	mv	r4, r0
208	j	ret_from_exception
209	nop
210
211ENTRY(handle_dbe)				# BusEL-data #18
212	SAVE_ALL
213	mv	r4, r0
214	la	r8, do_be
215	brl	r8
216	mv	r4, r0
217	j	ret_from_exception
218	nop
219
220ENTRY(handle_reserved)				# others
221	SAVE_ALL
222	mv	r4, r0
223	la	r8, do_reserved
224	brl	r8
225	mv	r4, r0
226	j	ret_from_exception
227	nop
228
229#ifndef CONFIG_PREEMPT
230#define resume_kernel	restore_all
231#else
232#define __ret_from_irq	ret_from_exception
233#endif
234
235	.align	2
236#ifndef CONFIG_PREEMPT
237ENTRY(ret_from_exception)
238	disable_irq			# preempt stop
239	nop
240	j	__ret_from_irq
241	nop
242#endif
243
244ENTRY(ret_from_irq)
245	sw	r16, [r28, TI_REGS]
246
247ENTRY(__ret_from_irq)
248	lw	r8, [r0, PT_PSR]	# returning to kernel mode?
249	andri.c	r8, r8, KU_USER
250	beq	resume_kernel
251
252resume_userspace:
253	disable_irq
254	lw	r6, [r28, TI_FLAGS]	# current->work
255	li	r8, _TIF_WORK_MASK
256	and.c	r8, r8, r6		# ignoring syscall_trace
257	bne	work_pending
258	nop
259	j	restore_all
260	nop
261
262#ifdef CONFIG_PREEMPT
263resume_kernel:
264	disable_irq
265	lw	r8, [r28, TI_PRE_COUNT]
266	cmpz.c	r8
267	bne	r8, restore_all
268need_resched:
269	lw	r8, [r28, TI_FLAGS]
270	andri.c	r9, r8, _TIF_NEED_RESCHED
271	beq	restore_all
272	lw	r8, [r28, PT_PSR]		# Interrupts off?
273	andri.c	r8, r8, 1
274	beq	restore_all
275	bl	preempt_schedule_irq
276	nop
277	j	need_resched
278	nop
279#endif
280
281ENTRY(ret_from_fork)
282	bl	schedule_tail			# r4=struct task_struct *prev
283
284ENTRY(syscall_exit)
285	nop
286	disable_irq
287	lw	r6, [r28, TI_FLAGS]		# current->work
288	li	r8, _TIF_WORK_MASK
289	and.c	r8, r6, r8
290	bne	syscall_exit_work
291
292ENTRY(restore_all)					# restore full frame
293	RESTORE_ALL_AND_RET
294
295work_pending:
296	andri.c	r8, r6, _TIF_NEED_RESCHED # r6 is preloaded with TI_FLAGS
297	beq	work_notifysig
298work_resched:
299	bl	schedule
300	nop
301	disable_irq
302	lw	r6, [r28, TI_FLAGS]
303	li	r8, _TIF_WORK_MASK
304	and.c	r8, r6, r8	# is there any work to be done
305				# other than syscall tracing?
306	beq	restore_all
307	andri.c	r8, r6, _TIF_NEED_RESCHED
308	bne	work_resched
309
310work_notifysig:
311	mv	r4, r0
312	li	r5, 0
313	bl	do_notify_resume	# r6 already loaded
314	nop
315	j	resume_userspace
316	nop
317
318ENTRY(syscall_exit_work)
319	li	r8, _TIF_SYSCALL_TRACE
320	and.c	r8, r8, r6		# r6 is preloaded with TI_FLAGS
321	beq	work_pending		# trace bit set?
322	nop
323	enable_irq
324	mv	r4, r0
325	li	r5, 1
326	bl	do_syscall_trace
327	nop
328	b	resume_userspace
329	nop
330
331.macro	save_context	reg
332	sw	r12, [\reg, THREAD_REG12];
333	sw	r13, [\reg, THREAD_REG13];
334	sw	r14, [\reg, THREAD_REG14];
335	sw	r15, [\reg, THREAD_REG15];
336	sw	r16, [\reg, THREAD_REG16];
337	sw	r17, [\reg, THREAD_REG17];
338	sw	r18, [\reg, THREAD_REG18];
339	sw	r19, [\reg, THREAD_REG19];
340	sw	r20, [\reg, THREAD_REG20];
341	sw	r21, [\reg, THREAD_REG21];
342	sw	r29, [\reg, THREAD_REG29];
343	sw	r2, [\reg, THREAD_REG2];
344	sw	r0, [\reg, THREAD_REG0]
345.endm
346
347.macro	restore_context	reg
348	lw	r12, [\reg, THREAD_REG12];
349	lw	r13, [\reg, THREAD_REG13];
350	lw	r14, [\reg, THREAD_REG14];
351	lw	r15, [\reg, THREAD_REG15];
352	lw	r16, [\reg, THREAD_REG16];
353	lw	r17, [\reg, THREAD_REG17];
354	lw	r18, [\reg, THREAD_REG18];
355	lw	r19, [\reg, THREAD_REG19];
356	lw	r20, [\reg, THREAD_REG20];
357	lw	r21, [\reg, THREAD_REG21];
358	lw	r29, [\reg, THREAD_REG29];
359	lw	r0, [\reg, THREAD_REG0];
360	lw	r2, [\reg, THREAD_REG2];
361	lw	r3, [\reg, THREAD_REG3]
362.endm
363
364/*
365 * task_struct *resume(task_struct *prev, task_struct *next,
366 *			struct thread_info *next_ti)
367 */
368ENTRY(resume)
369	mfcr	r9, cr0
370	nop
371	nop
372	sw	r9, [r4, THREAD_PSR]
373	save_context	r4
374	sw	r3, [r4, THREAD_REG3]
375
376	mv	r28, r6
377	restore_context	r5
378	mv	r8, r6
379	addi	r8, KERNEL_STACK_SIZE
380	subi	r8, 32
381	la 	r9, kernelsp;
382	sw 	r8, [r9];
383
384	mfcr	r9, cr0
385	ldis	r7, 0x00ff
386	nop
387	and	r9, r9, r7
388	lw	r6, [r5, THREAD_PSR]
389	not	r7, r7
390	and	r6, r6, r7
391	or	r6, r6, r9
392	mtcr	r6, cr0
393	nop; nop; nop; nop; nop
394	br	r3
395
396ENTRY(handle_sys)
397	SAVE_ALL
398	sw	r8, [r0, 16]		# argument 5 from user r8
399	sw	r9, [r0, 20]		# argument 6 from user r9
400	enable_irq
401
402	sw	r4, [r0, PT_ORIG_R4]	#for restart syscall
403	sw	r7, [r0, PT_ORIG_R7]	#for restart syscall
404	sw	r27, [r0, PT_IS_SYSCALL] # it from syscall
405
406	lw	r9, [r0, PT_EPC]	# skip syscall on return
407	addi	r9, 4
408	sw	r9, [r0, PT_EPC]
409
410	cmpi.c	r27, __NR_syscalls 	# check syscall number
411	bgtu	illegal_syscall
412
413	slli	r8, r27, 2		# get syscall routine
414	la	r11, sys_call_table
415	add	r11, r11, r8
416	lw	r10, [r11]		# get syscall entry
417
418	cmpz.c	r10
419	beq	illegal_syscall
420
421	lw	r8, [r28, TI_FLAGS]
422	li	r9, _TIF_SYSCALL_TRACE
423	and.c	r8, r8, r9
424	bne	syscall_trace_entry
425
426	brl	r10			# Do The Real system call
427
428	cmpi.c	r4, 0
429	blt	1f
430	ldi	r8, 0
431	sw	r8, [r0, PT_R7]
432	b 2f
4331:
434	cmpi.c	r4, -MAX_ERRNO - 1
435	ble	2f
436	ldi	r8, 0x1;
437	sw	r8, [r0, PT_R7]
438	neg	r4, r4
4392:
440	sw	r4, [r0, PT_R4]		# save result
441
442syscall_return:
443	disable_irq
444	lw	r6, [r28, TI_FLAGS]	# current->work
445	li	r8, _TIF_WORK_MASK
446	and.c	r8, r6, r8
447	bne	syscall_return_work
448	j	restore_all
449
450syscall_return_work:
451	j	syscall_exit_work
452
453syscall_trace_entry:
454	mv	r16, r10
455	mv	r4, r0
456	li	r5, 0
457	bl	do_syscall_trace
458
459	mv	r8, r16
460	lw	r4, [r0, PT_R4]		# Restore argument registers
461	lw	r5, [r0, PT_R5]
462	lw	r6, [r0, PT_R6]
463	lw	r7, [r0, PT_R7]
464	brl	r8
465
466	li	r8, -MAX_ERRNO - 1
467	sw	r8, [r0, PT_R7]		# set error flag
468
469	neg	r4, r4			# error
470	sw	r4, [r0, PT_R0]		# set flag for syscall
471					# restarting
4721:	sw	r4, [r0, PT_R2]		# result
473	j	syscall_exit
474
475illegal_syscall:
476	ldi	r4, -ENOSYS		# error
477	sw	r4, [r0, PT_ORIG_R4]
478	sw	r4, [r0, PT_R4]
479	ldi	r9, 1			# set error flag
480	sw	r9, [r0, PT_R7]
481	j	syscall_return
482
483ENTRY(sys_execve)
484	mv	r4, r0
485	la	r8, score_execve
486	br	r8
487
488ENTRY(sys_clone)
489	mv	r4, r0
490	la	r8, score_clone
491	br	r8
492
493ENTRY(sys_rt_sigreturn)
494	mv	r4, r0
495	la	r8, score_rt_sigreturn
496	br	r8
497
498ENTRY(sys_sigaltstack)
499	mv	r4, r0
500	la	r8, score_sigaltstack
501	br	r8
502
503#ifdef __ARCH_WANT_SYSCALL_DEPRECATED
504ENTRY(sys_fork)
505	mv	r4, r0
506	la	r8, score_fork
507	br	r8
508
509ENTRY(sys_vfork)
510	mv	r4, r0
511	la	r8, score_vfork
512	br	r8
513#endif /* __ARCH_WANT_SYSCALL_DEPRECATED */
514