xref: /netbsd-src/sys/arch/m68k/m68k/reenter_syscall.s (revision 1069d0becae52e4df2a294b6eead8a42a463109f)
1/*	$NetBSD: reenter_syscall.s,v 1.7 2021/02/23 16:54:17 tsutsui Exp $	*/
2
3/*
4 * Written by ITOH Yasufumi.
5 * Public domain.
6 */
7
8#include <m68k/asm.h>
9#include "assym.h"
10
11/*
12 * void reenter_syscall(struct frame *fp, int stkadj)
13 *					__attribute__((__noreturn__));
14 *
15 * Move stack frame by stkadj bytes and re-enter syscall().
16 *
17 * XXX This is a kludge.
18 */
19
20ENTRY_NOPROFILE(reenter_syscall)
21	addql	#4,%sp			| pop PC
22	movel	(%sp)+,%a0		| current frame addr
23	movel	(%sp),%d1		| stkadj
24
25| The m68k frame (struct trapframe) format:
26|	16:l	d0-d7/a0-a6/usp
27|	1:w	(pad)
28|	1:w	stkadj
29|	1:w	sr
30|	1:l	pc
31|	1:w	format/vector
32
33	moveal	%a0,%a1
34	subal	%d1,%a1			| new frame address
35	moveal	%a1,%sp			| set SP
36
37	| copy down frame (16*4 + 2 + 2 + 2 + 4 + 2 = 76 bytes = 19 longs)
38	moveq	#19-1,%d0
39.Lcpfr:	movel	(%a0)+,(%a1)+
40	dbra	%d0,.Lcpfr
41
42	movew	%d1,FR_ADJ(%sp)		| set stack adjust count
43	movel	(%sp),-(%sp)		| push syscall no (original d0 value)
44	jbsr	_C_LABEL(syscall)	| re-enter syscall()
45	addql	#4,%sp			| pop syscall no
46#ifdef DEBUG
47	tstw	FR_ADJ(%sp)		| stack adjust must be zero
48	jeq	.Ladjzero
49	PANIC("reenter_syscall")
50.Ladjzero:
51#endif
52	moveal	FR_SP(%sp),%a0		| grab and restore
53	movel	%a0,%usp		|   user SP
54	movw	FR_ADJ(%sp),%d0		| need to adjust stack?
55	jne	.Ladjstk		| yes, go to it
56	moveml	(%sp)+,#0x7FFF		| restore user registers
57	addql	#8,%sp			| pop SP and stack adjust
58	jra	_ASM_LABEL(rei)		| rte
59.Ladjstk:
60	lea	FR_HW(%sp),%a1		| pointer to HW frame
61	addql	#8,%a1			| source pointer
62	movl	%a1,%a0			| source
63	addw	%d0,%a0			|  + hole size = dest pointer
64	movl	-(%a1),-(%a0)		| copy
65	movl	-(%a1),-(%a0)		|  8 bytes
66	movl	%a0,FR_SP(%sp)		| new SSP
67	moveml	(%sp)+,#0x7FFF		| restore user register
68	movl	(%sp),%sp		| and do real RTE
69	jra	_ASM_LABEL(rei)		| rte
70