. add cpufeature detection of both . use it for both ipc and kernelcall traps, using a register for call number . SYSENTER/SYSCALL does not save any context, therefore userland has to save it . to accomodate multiple kernel entry/exit types, the entry type is recorded in the process struct. hitherto all types were interrupt (soft int, exception, hard int); now SYSENTER/SYSCALL is new, with the difference that context is not fully restored from proc struct when running the process again. this can't be done as some information is missing. . complication: cases in which the kernel has to fully change process context (i.e. sigreturn). in that case the exit type is changed from SYSENTER/SYSEXIT to soft-int (i.e. iret) and context is fully restored from the proc struct. this does mean the PC and SP must change, as the sysenter/sysexit userland code will otherwise try to restore its own context. this is true in the sigreturn case. . override all usage by setting libc_ipc=1
		
			
				
	
	
		
			95 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
#include <minix/ipcconst.h>
 | 
						|
#include <machine/asm.h>
 | 
						|
 | 
						|
/**========================================================================* */
 | 
						|
/*                           IPC assembly routines			  * */
 | 
						|
/**========================================================================* */
 | 
						|
/* all message passing routines save ebx, but destroy eax and ecx. */
 | 
						|
 | 
						|
#define IPCFUNC(name,SETARGS,VEC,POSTTRAP)			 \
 | 
						|
ENTRY(usermapped_ ## name ## _softint)					;\
 | 
						|
	push	%ebp							;\
 | 
						|
	movl	%esp, %ebp						;\
 | 
						|
	push	%ebx							;\
 | 
						|
	SETARGS								;\
 | 
						|
	int	$VEC	/* trap to the kernel */			;\
 | 
						|
	mov	%ebx, %ecx	/* save %ebx */				;\
 | 
						|
	POSTTRAP							;\
 | 
						|
	pop	%ebx							;\
 | 
						|
	pop	%ebp							;\
 | 
						|
	ret								;\
 | 
						|
ENTRY(usermapped_ ## name ## _sysenter)					;\
 | 
						|
	push	%ebp							;\
 | 
						|
	movl	%esp, %ebp						;\
 | 
						|
	push	%ebp							;\
 | 
						|
	push	%edx							;\
 | 
						|
	push	%ebx							;\
 | 
						|
	push	%esi							;\
 | 
						|
	push	%edi							;\
 | 
						|
	movl	%esp, %esi	/* kernel uses %esi for restored %esp */;\
 | 
						|
	movl	$0f, %edx	/* kernel uses %edx for restored %eip */;\
 | 
						|
	movl	$VEC, %edi	/* %edi to distinguish ipc/kerncall */	;\
 | 
						|
	SETARGS			/* call-specific register setup */	;\
 | 
						|
	sysenter		/* disappear into kernel */		;\
 | 
						|
0:									;\
 | 
						|
	mov	%ebx, %ecx	/* return w. state mangled; save %ebx */;\
 | 
						|
	pop	%edi							;\
 | 
						|
	pop	%esi							;\
 | 
						|
	pop	%ebx							;\
 | 
						|
	pop	%edx							;\
 | 
						|
	pop	%ebp							;\
 | 
						|
	POSTTRAP							;\
 | 
						|
	pop	%ebp							;\
 | 
						|
	ret								;\
 | 
						|
ENTRY(usermapped_ ## name ## _syscall)					;\
 | 
						|
	push	%ebp							;\
 | 
						|
	movl	%esp, %ebp						;\
 | 
						|
	push	%ebp							;\
 | 
						|
	push	%edx							;\
 | 
						|
	push	%ebx							;\
 | 
						|
	push	%esi							;\
 | 
						|
	push	%edi							;\
 | 
						|
	movl	$VEC, %edi	/* %edi to distinguish ipc/kerncall */	;\
 | 
						|
	SETARGS			/* call-specific register setup */	;\
 | 
						|
	movl	%ecx, %edx	/* %ecx is clobbered by SYSCALL */	;\
 | 
						|
	syscall			/* disappear into kernel */		;\
 | 
						|
	mov	%ebx, %ecx	/* return w. state mangled; save %ebx */;\
 | 
						|
	pop	%edi							;\
 | 
						|
	pop	%esi							;\
 | 
						|
	pop	%ebx							;\
 | 
						|
	pop	%edx							;\
 | 
						|
	pop	%ebp							;\
 | 
						|
	POSTTRAP							;\
 | 
						|
	pop	%ebp							;\
 | 
						|
	ret
 | 
						|
 | 
						|
#define IPCARGS(opcode)							\
 | 
						|
	movl	8(%ebp), %eax	/* eax = dest-src */			;\
 | 
						|
	movl	12(%ebp), %ebx	/* ebx = message pointer */		;\
 | 
						|
	movl	$opcode, %ecx						;\
 | 
						|
 | 
						|
#define SENDA_ARGS		\
 | 
						|
	movl	12(%ebp), %eax	/* eax = count */			;\
 | 
						|
	movl	8(%ebp), %ebx	/* ebx = table */			;\
 | 
						|
	movl	$SENDA, %ecx						;\
 | 
						|
 | 
						|
#define GETSTATUS							\
 | 
						|
	push	%eax							;\
 | 
						|
	movl    16(%ebp), %eax      /* ecx = saved %ebx */		;\
 | 
						|
	movl	%ecx,  (%eax)						;\
 | 
						|
	pop	%eax
 | 
						|
 | 
						|
#define KERNARGS mov 8(%ebp), %eax
 | 
						|
 | 
						|
IPCFUNC(send,IPCARGS(SEND),IPCVEC_UM,)
 | 
						|
IPCFUNC(receive,IPCARGS(RECEIVE),IPCVEC_UM,GETSTATUS)
 | 
						|
IPCFUNC(sendrec,IPCARGS(SENDREC),IPCVEC_UM,)
 | 
						|
IPCFUNC(sendnb,IPCARGS(SENDNB),IPCVEC_UM,)
 | 
						|
IPCFUNC(notify,IPCARGS(NOTIFY),IPCVEC_UM,)
 | 
						|
IPCFUNC(senda,SENDA_ARGS,IPCVEC_UM,)
 | 
						|
IPCFUNC(do_kernel_call,KERNARGS,KERVEC_UM,)
 | 
						|
 | 
						|
.data
 | 
						|
LABEL(usermapped_offset)
 | 
						|
.space 4
 |