#ifndef __SYSCALL_NEW_H #define __SYSCALL_NEW_H /* Copyright (C) 2005-2007 Herbert Pötzl global config options __sysc_setret ... set return value (default none) __sysc_seterr ... set error value (default errno) arch specific config __sysc_clbrs ... the clobbered syscall registers __sysc_cmd(n) ... the syscall __sysc_clobber ... clobbered registers (default: memory) __sysc_max_err ... maximum error number (default: separate) */ /* some fallback defaults */ #ifndef __sysc_setret #define __sysc_setret(v) do { } while(0) #endif #ifndef __sysc_seterr #define __sysc_seterr(e) do { errno = (e); } while(0) #endif #ifndef __sysc_cid #define __sysc_cid(N) __NR_##N #define __sc_cidvar(N) #else #define __sc_cidvar(N) __sc_scid(__cid, __sysc_cid(N)) #endif #if defined(__alpha__) /* The Alpha calling convention doesn't use the stack until after the first six arguments have been passed in registers. scnr: v0($0) args: a1($16), a2($17), a3($18), a4($19), a5($20), a6($21) sret: r0($0) serr: e0($19) (!=0, err=sret) call: callsys clob: memory */ /* ***************************************** I386 I386 I386 I386 * i386 kernel interface */ #elif defined(__i386__) /* The x86 calling convention uses stack args for all arguments, but the Linux kernel passes the first six arguments in the following registers: ebx, ecx, edx, esi, edi, ebp. scnr: id(eax) args: a1(ebx), a2(ecx), a3(edx), a4(esi), a5(edi), a6(ebp) sret: r0(eax) serr: (sret >= (unsigned)-EMAXERRNO) call: int 0x80 picr: pr(ebx) clob: memory */ #define __sysc_max_err 129 #ifndef __PIC__ #define __sysc_clbrs "eax", "ebx", "ecx", "edx", "esi", "edi" #else #define __sysc_clbrs "eax", "memory", "ecx", "edx", "esi", "edi" #endif #define __sysc_cmd(n) \ __casm(n,6,1, "movl %7,%%eax" , )\ __casm(n,5,1, "movl %6,%%edi" , )\ __casm(n,4,1, "movl %5,%%esi" , )\ __casm(n,3,1, "movl %4,%%edx" , )\ __casm(n,2,1, "movl %3,%%ecx" , )\ __pasm(n,1,1, "pushl %%ebx" , )\ __casm(n,1,1, "movl %2,%%ebx" , )\ __casm(n,6,1, "pushl %%ebp" , )\ __casm(n,6,1, "movl %%eax,%%ebp" , )\ __casm(n,0,1, "movl %1,%%eax" , )\ __casm(n,0,1, "int $0x80" , )\ __casm(n,6,1, "popl %%ebp" , )\ __pasm(n,1,1, "popl %%ebx" , )\ __casm(n,0,1, "movl %%eax,%0" , ) #else #error unknown kernel arch #endif /* implementation defaults */ #ifndef __sysc_rcon #define __sysc_rcon(n) "g" #endif #ifndef __sysc_icon #define __sysc_icon "i" #endif #ifndef __sysc_type #define __sysc_type long #endif #ifndef __sysc_clobber #define __sysc_clobber "memory" #endif /* argument list */ #define __lst_6(x,a1,a2,a3,a4,a5,a6) __lst_5(x,a1,a2,a3,a4,a5),x(6,a6) #define __lst_5(x,a1,a2,a3,a4,a5) __lst_4(x,a1,a2,a3,a4),x(5,a5) #define __lst_4(x,a1,a2,a3,a4) __lst_3(x,a1,a2,a3),x(4,a4) #define __lst_3(x,a1,a2,a3) __lst_2(x,a1,a2),x(3,a3) #define __lst_2(x,a1,a2) __lst_1(x,a1),x(2,a2) #define __lst_1(x,a1) __lst_0(x,*),x(1,a1) #define __lst_0(x,a0) /* argument selection */ #define __arg_0(...) #define __arg_1(a1,...) a1 #define __arg_2(a1,a2,...) a2 #define __arg_3(a1,a2,a3,...) a3 #define __arg_4(a1,a2,a3,a4,...) a4 #define __arg_5(a1,a2,a3,a4,a5,...) a5 #define __arg_6(a1,a2,a3,a4,a5,a6) a6 /* list reduction */ #define __red_0(...) #define __red_1(a1,...) ,a1 #define __red_2(a1,a2,...) ,a1,a2 #define __red_3(a1,a2,a3,...) ,a1,a2,a3 #define __red_4(a1,a2,a3,a4,...) ,a1,a2,a3,a4 #define __red_5(a1,a2,a3,a4,a5,...) ,a1,a2,a3,a4,a5 #define __red_6(a1,a2,a3,a4,a5,a6) ,a1,a2,a3,a4,a5,a6 /* conditional asm */ #define __casm_use(q,r,v) v __casm_use_##q##r(__casm_nl("")) #define __casm_use_10(v) #define __casm_use_11(v) v #define __casm_use_12(v) #define __casm_use_13(v) v #define __casm_use_20(v) #define __casm_use_21(v) #define __casm_use_22(v) v #define __casm_use_23(v) v #define __casm_00(v,w,r) __casm_use(1,r,v) #define __casm_01(v,w,r) __casm_use(2,r,w) #define __casm_02(v,w,r) __casm_use(2,r,w) #define __casm_03(v,w,r) __casm_use(2,r,w) #define __casm_04(v,w,r) __casm_use(2,r,w) #define __casm_05(v,w,r) __casm_use(2,r,w) #define __casm_06(v,w,r) __casm_use(2,r,w) #define __casm_10(v,w,r) __casm_use(1,r,v) #define __casm_11(v,w,r) __casm_use(1,r,v) #define __casm_12(v,w,r) __casm_use(2,r,w) #define __casm_13(v,w,r) __casm_use(2,r,w) #define __casm_14(v,w,r) __casm_use(2,r,w) #define __casm_15(v,w,r) __casm_use(2,r,w) #define __casm_16(v,w,r) __casm_use(2,r,w) #define __casm_20(v,w,r) __casm_use(1,r,v) #define __casm_21(v,w,r) __casm_use(1,r,v) #define __casm_22(v,w,r) __casm_use(1,r,v) #define __casm_23(v,w,r) __casm_use(2,r,w) #define __casm_24(v,w,r) __casm_use(2,r,w) #define __casm_25(v,w,r) __casm_use(2,r,w) #define __casm_26(v,w,r) __casm_use(2,r,w) #define __casm_30(v,w,r) __casm_use(1,r,v) #define __casm_31(v,w,r) __casm_use(1,r,v) #define __casm_32(v,w,r) __casm_use(1,r,v) #define __casm_33(v,w,r) __casm_use(1,r,v) #define __casm_34(v,w,r) __casm_use(2,r,w) #define __casm_35(v,w,r) __casm_use(2,r,w) #define __casm_36(v,w,r) __casm_use(2,r,w) #define __casm_40(v,w,r) __casm_use(1,r,v) #define __casm_41(v,w,r) __casm_use(1,r,v) #define __casm_42(v,w,r) __casm_use(1,r,v) #define __casm_43(v,w,r) __casm_use(1,r,v) #define __casm_44(v,w,r) __casm_use(1,r,v) #define __casm_45(v,w,r) __casm_use(2,r,w) #define __casm_46(v,w,r) __casm_use(2,r,w) #define __casm_50(v,w,r) __casm_use(1,r,v) #define __casm_51(v,w,r) __casm_use(1,r,v) #define __casm_52(v,w,r) __casm_use(1,r,v) #define __casm_53(v,w,r) __casm_use(1,r,v) #define __casm_54(v,w,r) __casm_use(1,r,v) #define __casm_55(v,w,r) __casm_use(1,r,v) #define __casm_56(v,w,r) __casm_use(2,r,w) #define __casm_60(v,w,r) __casm_use(1,r,v) #define __casm_61(v,w,r) __casm_use(1,r,v) #define __casm_62(v,w,r) __casm_use(1,r,v) #define __casm_63(v,w,r) __casm_use(1,r,v) #define __casm_64(v,w,r) __casm_use(1,r,v) #define __casm_65(v,w,r) __casm_use(1,r,v) #define __casm_66(v,w,r) __casm_use(1,r,v) /* special PIC handling */ #ifdef __PIC__ #define __pic(v) v #define __nopic(v) #else #define __pic(v) #define __nopic(v) v #endif #define __casm_nl(v) v "\n\t" #define __casm(n,a,r,v,w) __casm_##n##a(v,w,r) #define __pasm(n,a,r,v,w) __pic(__casm(n,a,r,v,w)) #define __nasm(n,a,r,v,w) __nopic(__casm(n,a,r,v,w)) #define __sc_list(x) x(1), x(2), x(3), x(4), x(5), x(6) #ifndef __stringify0 #define __stringify0(val) #val #endif #ifndef __stringify #define __stringify(val) __stringify0(val) #endif #define __sc_cast(v) (__sysc_type)(v) #define __sc_lval(n) __sysc_type n #define __sc_scid(n,v) __sc_lval(n) = (v) #define __sc_ival(n,v) __sysc_rcon(n)(__sc_cast(v)) #define __sc_ivals(n,...) __lst_##n(__sc_ival,__VA_ARGS__) #define __sc_cregs(n,...) __red_##n(__VA_ARGS__) #define __sc_cidval(N) __sysc_icon(__sysc_cid(N)) #ifdef __sc_complex /* complex result */ #define __sc_results __sc_lval(__ret); __sc_lval(__err) #ifndef __sysc_errc #define __sysc_errc(ret, err) (err) #endif #ifndef __sysc_retv #define __sysc_retv(type, ret, err) \ __sysc_setret(ret); \ if (__sysc_errc(ret, err)) { \ __sysc_seterr(ret); \ ret = -1; \ } \ return (type)(ret) #endif #define __sc_oregs "=g"(__ret), "=g"(__err) #define __sc_return(t) __sysc_retv(t, __ret, __err) #else /* simple result */ #define __sc_results __sc_lval(__res) #ifndef __sysc_errc #define __sysc_errc(res) \ ((unsigned __sysc_type)(res) >= \ (unsigned __sysc_type)(-(__sysc_max_err))) #endif #ifndef __sysc_retv #define __sysc_retv(type, res) \ __sysc_setret(res); \ if (__sysc_errc(res)) { \ __sysc_seterr(-res); \ res = -1; \ } \ return (type)(res) #endif #define __sc_oregs "=g"(__res) #define __sc_return(t) __sysc_retv(t, __res) #endif /* simple/complex */ /* the inline syscall */ #define __sc_asm __asm__ #define __sc_asm_vol __asm__ __volatile__ #define __sc_syscall(n,N,...) \ __sc_asm (__sysc_cmd(n) \ : __sc_oregs \ : __sc_cidval(N) __sc_ivals(n,__VA_ARGS__) \ : __sysc_clobber __sc_cregs(n,__sysc_clbrs) ) #define __sc_body(n, type, name, ...) \ { \ __sc_results;__sc_cidvar(name); \ __sc_syscall(n,name,__VA_ARGS__); \ __sc_return(type); \ } #define _syscall0(type, name) \ type name(void) \ __sc_body(0, type, name, *) #define _syscall1(type, name, type1, arg1) \ type name(type1 arg1) \ __sc_body(1, type, name, arg1) #define _syscall2(type, name, type1, arg1, type2, arg2) \ type name(type1 arg1, type2 arg2) \ __sc_body(2, type, name, arg1, arg2) #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ type name(type1 arg1, type2 arg2, type3 arg3) \ __sc_body(3, type, name, arg1, arg2, arg3) #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ type4, arg4) \ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ __sc_body(4, type, name, arg1, arg2, arg3, arg4) #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ type4, arg4, type5, arg5) \ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ __sc_body(5, type, name, arg1, arg2, arg3, arg4, arg5) #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ type4, arg4, type5, arg5, type6, arg6) \ type name(type1 arg1, type2 arg2, type3 arg3, \ type4 arg4, type5 arg5, type6 arg6) \ __sc_body(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6) #endif /* __SYSCALL_NEW_H */