1#include <minix/ipcconst.h>
2#include <machine/asm.h>
3
4/* Redefine _ENTRY to put the following function in the section
5 * ".usermapped_glo". */
6#undef _ENTRY
7#define _ENTRY(x) \
8	_ALIGN_TEXT; .globl x; .type x,@function; x:
9
10.section .usermapped_glo, "wax", @progbits
11
12/**========================================================================* */
13/*                           IPC assembly routines			  * */
14/**========================================================================* */
15/* all message passing routines save ebx, but destroy eax and ecx. */
16
17#define IPCFUNC(name,SETARGS,VEC,POSTTRAP)			 \
18ENTRY(usermapped_ ## name ## _softint)					;\
19	push	%ebp							;\
20	movl	%esp, %ebp						;\
21	push	%ebx							;\
22	SETARGS								;\
23	int	$VEC	/* trap to the kernel */			;\
24	mov	%ebx, %ecx	/* save %ebx */				;\
25	POSTTRAP							;\
26	pop	%ebx							;\
27	pop	%ebp							;\
28	ret								;\
29ENTRY(usermapped_ ## name ## _sysenter)					;\
30	push	%ebp							;\
31	movl	%esp, %ebp						;\
32	push	%ebp							;\
33	push	%edx							;\
34	push	%ebx							;\
35	push	%esi							;\
36	push	%edi							;\
37	movl	%esp, %esi	/* kernel uses %esi for restored %esp */;\
38	movl	$0f, %edx	/* kernel uses %edx for restored %eip */;\
39	movl	$VEC, %edi	/* %edi to distinguish ipc/kerncall */	;\
40	/* !!! There is a dependency of proc_stacktrace()		;\
41	 * on this stack layout; it needs to find %ebp on it.		;\
42	 */								;\
43	SETARGS			/* call-specific register setup */	;\
44	sysenter		/* disappear into kernel */		;\
450:									;\
46	mov	%ebx, %ecx	/* return w. state mangled; save %ebx */;\
47	pop	%edi							;\
48	pop	%esi							;\
49	pop	%ebx							;\
50	pop	%edx							;\
51	pop	%ebp							;\
52	POSTTRAP							;\
53	pop	%ebp							;\
54	ret								;\
55ENTRY(usermapped_ ## name ## _syscall)					;\
56	push	%ebp							;\
57	movl	%esp, %ebp						;\
58	push	%ebp							;\
59	push	%edx							;\
60	push	%ebx							;\
61	push	%esi							;\
62	push	%edi							;\
63	movl	$VEC, %edi	/* %edi to distinguish ipc/kerncall */	;\
64	/* !!! There is a dependency of proc_stacktrace()		;\
65	 * on this stack layout; it needs to find %ebp on it.		;\
66	 */								;\
67	SETARGS			/* call-specific register setup */	;\
68	movl	%ecx, %edx	/* %ecx is clobbered by SYSCALL */	;\
69	syscall			/* disappear into kernel */		;\
70	mov	%ebx, %ecx	/* return w. state mangled; save %ebx */;\
71	pop	%edi							;\
72	pop	%esi							;\
73	pop	%ebx							;\
74	pop	%edx							;\
75	pop	%ebp							;\
76	POSTTRAP							;\
77	pop	%ebp							;\
78	ret
79
80#define IPCARGS(opcode)							\
81	movl	8(%ebp), %eax	/* eax = dest-src */			;\
82	movl	12(%ebp), %ebx	/* ebx = message pointer */		;\
83	movl	$opcode, %ecx						;\
84
85#define SENDA_ARGS		\
86	movl	12(%ebp), %eax	/* eax = count */			;\
87	movl	8(%ebp), %ebx	/* ebx = table */			;\
88	movl	$SENDA, %ecx						;\
89
90#define GETSTATUS							\
91	push	%eax							;\
92	movl    16(%ebp), %eax      /* ecx = saved %ebx */		;\
93	movl	%ecx,  (%eax)						;\
94	pop	%eax
95
96#define KERNARGS mov 8(%ebp), %eax
97
98IPCFUNC(send,IPCARGS(SEND),IPCVEC_UM,)
99IPCFUNC(receive,IPCARGS(RECEIVE),IPCVEC_UM,GETSTATUS)
100IPCFUNC(sendrec,IPCARGS(SENDREC),IPCVEC_UM,)
101IPCFUNC(sendnb,IPCARGS(SENDNB),IPCVEC_UM,)
102IPCFUNC(notify,IPCARGS(NOTIFY),IPCVEC_UM,)
103IPCFUNC(senda,SENDA_ARGS,IPCVEC_UM,)
104IPCFUNC(do_kernel_call,KERNARGS,KERVEC_UM,)
105
106.data
107LABEL(usermapped_offset)
108.space 4
109