1/** 2 * \file 3 * \brief User-side system call implementation 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, 2009, 2010, ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#ifndef ARCH_X86_32_BARRELFISH_SYSCALL_H 16#define ARCH_X86_32_BARRELFISH_SYSCALL_H 17 18#include <barrelfish_kpi/syscalls.h> // for struct sysret. 19 20/* Always review the generated assembly when changing this! */ 21// XXX: noinline for now, until I figured out why GCC doesn't obey the asm 22// constraints 23static __attribute__ ((noinline)) 24struct sysret syscall(uintptr_t arg0, uintptr_t arg1, 25 uintptr_t arg2, uintptr_t arg3, 26 uintptr_t arg4, uintptr_t arg5, 27 uintptr_t arg6) 28{ 29 /* XXX: This pushes the PIC register and frame pointer. Some GCC 30 * versions disallow specifying EBP as a register variable. Since 31 * we don't know when this is the case, we currently go via memory 32 * for that variable and so the frame pointer doesn't need to be 33 * pushed here. Also, we don't need to push the PIC register while 34 * declaring this function noinline. 35 */ 36 /* __asm volatile("push %ebx"); */ 37 /* __asm volatile("push %ebp"); */ 38 39 // This order is important! 40 register uintptr_t a0 __asm("edi") = arg0; 41 register uintptr_t a1 __asm("esi") = arg1; 42 register uintptr_t a2_ret2 __asm("edx") = arg2; 43 register uintptr_t a3_ret1 __asm("eax") = arg3; 44 register uintptr_t a4 __asm("ebx") = arg4; 45 register uintptr_t a6 __asm("ecx") = arg6; 46 // register uintptr_t a5 __asm("ebp") = arg5; // Needs to be last 47 48 __asm volatile("push %%ebp \n\t" 49 "mov %[arg5], %%ebp \n\t" 50 "int $0xff \n\t" 51 "pop %%ebp \n\t" 52 /* "pop %%ebx \n\t" */ 53 : "+a" (a3_ret1), "+d" (a2_ret2), "+r" (a6) 54 : "r" (a0), "r" (a1), "r" (a4), [arg5] "m" (arg5)); 55 56 return (struct sysret){/*error*/ a3_ret1, /*value*/ a2_ret2}; 57} 58 59#define syscall7(_a, _b, _c, _d, _e, _f, _g) \ 60 syscall(_a, _b, _c, _d, _e, _f, _g) 61#define syscall6(_a, _b, _c, _d, _e, _f) \ 62 syscall7(_a, _b, _c, _d, _e, _f, 0) 63#define syscall5(_a, _b, _c, _d, _e) \ 64 syscall6(_a, _b, _c, _d, _e, 0) 65#define syscall4(_a, _b, _c, _d) \ 66 syscall5(_a, _b, _c, _d, 0) 67#define syscall3(_a, _b, _c) \ 68 syscall4(_a, _b, _c, 0) 69#define syscall2(_a, _b) \ 70 syscall3(_a, _b, 0) 71#define syscall1(_a) \ 72 syscall2(_a, 0) 73 74#endif 75