93 lines
2.5 KiB
C
93 lines
2.5 KiB
C
#ifndef _SYSCALLASM_H_
|
|
#define _SYSCALLASM_H_
|
|
|
|
/*
|
|
* This file defines the system calls for SPARC for the assembler.
|
|
* Anything C-ish is not allowed in this file.
|
|
* C files should include syscall.h.
|
|
*/
|
|
|
|
#include "syscall.h"
|
|
|
|
/* Some macros for writing assember syscall stubs. */
|
|
|
|
#ifdef SVR4
|
|
#define TEXT_SECTION .section ".text"
|
|
#define DATA_SECTION .section ".data"
|
|
#define ALIGN(x) .align x
|
|
#define GLOBAL(sym) .global sym
|
|
#define WORD(x) .long x
|
|
#define ASM_SYMBOL(name) name
|
|
#define ASM_PRIVATE_SYMBOL(name) _##name
|
|
#define SYSCALL_TRAP 8
|
|
#else
|
|
#define TEXT_SECTION .text
|
|
#define DATA_SECTION .data
|
|
#define ALIGN(x) .align x
|
|
#define GLOBAL(sym) .global sym
|
|
#define WORD(x) .word x
|
|
#define ASM_SYMBOL(name) _##name
|
|
#define ASM_PRIVATE_SYMBOL(name) name
|
|
#define SYSCALL_TRAP 0
|
|
#endif
|
|
|
|
#define defsyscall(name, n) \
|
|
TEXT_SECTION ; \
|
|
ALIGN (4) ; \
|
|
GLOBAL (ASM_SYMBOL (name)) ; \
|
|
ASM_SYMBOL (name): \
|
|
mov n,%g1 ; \
|
|
ta SYSCALL_TRAP ; \
|
|
bcc noerr ; \
|
|
sethi %hi (ASM_PRIVATE_SYMBOL (cerror)),%g1 ; \
|
|
or %g1,%lo (ASM_PRIVATE_SYMBOL (cerror)),%g1 ; \
|
|
jmpl %g1+%g0,%g0 ; \
|
|
nop ; \
|
|
noerr: \
|
|
jmpl %o7+8,%g0 ; \
|
|
nop
|
|
|
|
/* Support for reentrant syscalls. The "struct _reent *" arg is always the
|
|
the first one. After that we allow up to four additional args. We could
|
|
allow more, but that's all we need for now.
|
|
|
|
It may seem inefficient to have the reent arg be the first one as it means
|
|
copying all the other args into place (as opposed to making the reent arg
|
|
the last one in which case there wouldn't be any copying). I chose a clean
|
|
design over an extra four instructions in a system call. All other
|
|
reentrant functions use the first arg this way.
|
|
??? Of course this scheme breaks down if we need to support 6 or more args.
|
|
|
|
And of course the system calls aren't *really* reentrant. The intent
|
|
is to exercise the reentrancy framework rather than provide/claim
|
|
real reentrancy for this port.
|
|
*/
|
|
|
|
#define defsyscall_r(name, n) \
|
|
TEXT_SECTION ; \
|
|
ALIGN (4) ; \
|
|
GLOBAL (ASM_SYMBOL (name)) ; \
|
|
ASM_SYMBOL (name): \
|
|
mov n,%g1 ; \
|
|
mov %o0,%o5 ; \
|
|
mov %o1,%o0 ; \
|
|
mov %o2,%o1 ; \
|
|
mov %o3,%o2 ; \
|
|
mov %o4,%o3 ; \
|
|
ta SYSCALL_TRAP ; \
|
|
bcc noerr ; \
|
|
sethi %hi (ASM_PRIVATE_SYMBOL (cerror_r)),%g1 ; \
|
|
or %g1,%lo (ASM_PRIVATE_SYMBOL (cerror_r)),%g1 ; \
|
|
jmpl %g1+%g0,%g0 ; \
|
|
mov %o5,%o1 ; \
|
|
noerr: \
|
|
jmpl %o7+8,%g0 ; \
|
|
nop
|
|
|
|
#define seterrno() \
|
|
sethi %hi (ASM_PRIVATE_SYMBOL (cerror)),%g1 ; \
|
|
or %g1,%lo (ASM_PRIVATE_SYMBOL (cerror)),%g1 ; \
|
|
jmpl %g1+%g0,%g0 ; \
|
|
nop
|
|
|
|
#endif /* _SYSCALLASM_H_ */
|