X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=linux-user%2Fsyscall.c;h=753a47cd2d8a19db414e029f5cbab865a24d0f60;hb=70a194b930797263bd6cb962d7f09596a07b4fef;hp=cd3fdf553567b9c2178996d216c1c04d254f5b3d;hpb=f2674e31e0b79a8e30335438f274b846d084a383;p=qemu diff --git a/linux-user/syscall.c b/linux-user/syscall.c index cd3fdf5..753a47c 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -68,6 +68,129 @@ #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2]) #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2]) + +#if defined(__powerpc__) +#undef __syscall_nr +#undef __sc_loadargs_0 +#undef __sc_loadargs_1 +#undef __sc_loadargs_2 +#undef __sc_loadargs_3 +#undef __sc_loadargs_4 +#undef __sc_loadargs_5 +#undef __sc_asm_input_0 +#undef __sc_asm_input_1 +#undef __sc_asm_input_2 +#undef __sc_asm_input_3 +#undef __sc_asm_input_4 +#undef __sc_asm_input_5 +#undef _syscall0 +#undef _syscall1 +#undef _syscall2 +#undef _syscall3 +#undef _syscall4 +#undef _syscall5 + +/* need to redefine syscalls as Linux kernel defines are incorrect for + the clobber list */ +/* On powerpc a system call basically clobbers the same registers like a + * function call, with the exception of LR (which is needed for the + * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal + * an error return status). + */ + +#define __syscall_nr(nr, type, name, args...) \ + unsigned long __sc_ret, __sc_err; \ + { \ + register unsigned long __sc_0 __asm__ ("r0"); \ + register unsigned long __sc_3 __asm__ ("r3"); \ + register unsigned long __sc_4 __asm__ ("r4"); \ + register unsigned long __sc_5 __asm__ ("r5"); \ + register unsigned long __sc_6 __asm__ ("r6"); \ + register unsigned long __sc_7 __asm__ ("r7"); \ + \ + __sc_loadargs_##nr(name, args); \ + __asm__ __volatile__ \ + ("sc \n\t" \ + "mfcr %0 " \ + : "=&r" (__sc_0), \ + "=&r" (__sc_3), "=&r" (__sc_4), \ + "=&r" (__sc_5), "=&r" (__sc_6), \ + "=&r" (__sc_7) \ + : __sc_asm_input_##nr \ + : "cr0", "ctr", "memory", \ + "r8", "r9", "r10","r11", "r12"); \ + __sc_ret = __sc_3; \ + __sc_err = __sc_0; \ + } \ + if (__sc_err & 0x10000000) \ + { \ + errno = __sc_ret; \ + __sc_ret = -1; \ + } \ + return (type) __sc_ret + +#define __sc_loadargs_0(name, dummy...) \ + __sc_0 = __NR_##name +#define __sc_loadargs_1(name, arg1) \ + __sc_loadargs_0(name); \ + __sc_3 = (unsigned long) (arg1) +#define __sc_loadargs_2(name, arg1, arg2) \ + __sc_loadargs_1(name, arg1); \ + __sc_4 = (unsigned long) (arg2) +#define __sc_loadargs_3(name, arg1, arg2, arg3) \ + __sc_loadargs_2(name, arg1, arg2); \ + __sc_5 = (unsigned long) (arg3) +#define __sc_loadargs_4(name, arg1, arg2, arg3, arg4) \ + __sc_loadargs_3(name, arg1, arg2, arg3); \ + __sc_6 = (unsigned long) (arg4) +#define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5) \ + __sc_loadargs_4(name, arg1, arg2, arg3, arg4); \ + __sc_7 = (unsigned long) (arg5) + +#define __sc_asm_input_0 "0" (__sc_0) +#define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3) +#define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4) +#define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5) +#define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6) +#define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7) + +#define _syscall0(type,name) \ +type name(void) \ +{ \ + __syscall_nr(0, type, name); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ + __syscall_nr(1, type, name, arg1); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1, type2 arg2) \ +{ \ + __syscall_nr(2, type, name, arg1, arg2); \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1, type2 arg2, type3 arg3) \ +{ \ + __syscall_nr(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) \ +{ \ + __syscall_nr(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) \ +{ \ + __syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5); \ +} +#endif + #define __NR_sys_uname __NR_uname #define __NR_sys_getcwd1 __NR_getcwd #define __NR_sys_statfs __NR_statfs @@ -210,6 +333,21 @@ static inline void host_to_target_fds(target_long *target_fds, #endif } +#if defined(__alpha__) +#define HOST_HZ 1024 +#else +#define HOST_HZ 100 +#endif + +static inline long host_to_target_clock_t(long ticks) +{ +#if HOST_HZ == TARGET_HZ + return ticks; +#else + return ((int64_t)ticks * TARGET_HZ) / HOST_HZ; +#endif +} + static inline void host_to_target_rusage(struct target_rusage *target_rusage, const struct rusage *rusage) { @@ -1423,11 +1561,13 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, struct tms tms; ret = get_errno(times(&tms)); if (tmsp) { - tmsp->tms_utime = tswapl(tms.tms_utime); - tmsp->tms_stime = tswapl(tms.tms_stime); - tmsp->tms_cutime = tswapl(tms.tms_cutime); - tmsp->tms_cstime = tswapl(tms.tms_cstime); + tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime)); + tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime)); + tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime)); + tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime)); } + if (!is_error(ret)) + ret = host_to_target_clock_t(ret); } break; case TARGET_NR_prof: @@ -1791,8 +1931,8 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, goto unimplemented; case TARGET_NR_readdir: goto unimplemented; -#ifdef TARGET_I386 case TARGET_NR_mmap: +#if defined(TARGET_I386) || defined(TARGET_ARM) { uint32_t v1, v2, v3, v4, v5, v6, *vptr; vptr = (uint32_t *)arg1; @@ -1806,13 +1946,14 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, target_to_host_bitmask(v4, mmap_flags_tbl), v5, v6)); } - break; -#endif -#ifdef TARGET_I386 - case TARGET_NR_mmap2: #else - case TARGET_NR_mmap: + ret = get_errno(target_mmap(arg1, arg2, arg3, + target_to_host_bitmask(arg4, mmap_flags_tbl), + arg5, + arg6)); #endif + break; + case TARGET_NR_mmap2: ret = get_errno(target_mmap(arg1, arg2, arg3, target_to_host_bitmask(arg4, mmap_flags_tbl), arg5,