#ifndef __L4__AMD64__SYSCALLS_H__
#define __L4__AMD64__SYSCALLS_H__
#include __L4_INC_ARCH(vregs.h)
#include __L4_INC_ARCH(specials.h)
#include <l4/message.h>
#include __L4_INC_ARCH(kdebug.h)
typedef struct {
L4_Word_t rax;
L4_Word_t rdx;
} __L4_Return_t;
L4_INLINE void * L4_KernelInterface (L4_Word_t *ApiVersion,
L4_Word_t *ApiFlags,
L4_Word_t *KernelId)
{
void * base_address;
__asm__ __volatile__ (
"/* L4_KernelInterface() */ \n"
" lock; nop \n"
:
"=a" (base_address),
"=c" (*ApiVersion),
"=d" (*ApiFlags),
"=S" (*KernelId)
);
return base_address;
}
typedef void (*__L4_Nop_t)(void);
typedef L4_Word_t (*__L4_ExchangeRegisters_t)( L4_Word_t, L4_Word_t, L4_Word_t,
L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t );
extern __L4_ExchangeRegisters_t __L4_ExchangeRegisters;
L4_INLINE L4_ThreadId_t L4_ExchangeRegisters (L4_ThreadId_t dest,
L4_Word_t control,
L4_Word_t sp,
L4_Word_t ip,
L4_Word_t flags,
L4_Word_t UserDefHandle,
L4_ThreadId_t pager,
L4_Word_t *old_control,
L4_Word_t *old_sp,
L4_Word_t *old_ip,
L4_Word_t *old_flags,
L4_Word_t *old_UserDefhandle,
L4_ThreadId_t *old_pager)
{
L4_ThreadId_t result;
L4_Word_t dummy;
struct {
L4_Word_t r8;
L4_Word_t r9;
L4_Word_t r10;
} args;
args.r8 = ip;
args.r9 = flags;
args.r10 = UserDefHandle;
__asm__ __volatile__ (
"/* L4_ExchangeRegisters */ \n"
"movq (%[args]), %%r8 \n"
"movq 8(%[args]), %%r9 \n"
"movq 16(%[args]), %%r10 \n"
"pushq %%rbp \n"
"pushq %[args] \n"
"callq *__L4_ExchangeRegisters \n"
"popq %[args] \n"
"popq %%rbp \n"
"movq %%r8, (%[args]) \n"
"movq %%r9, 8(%[args]) \n"
"movq %%r10, 16(%[args]) \n"
:
"=a" (result),
"=c" (dummy),
"=d" (*old_sp),
"=S" (*old_control),
"=D" (*old_pager)
:
[dest] "0" (dest),
[args] "1" (&args),
[sp] "2" (sp),
[control] "3" (control),
[pager] "4" (pager)
:
"memory", "rbx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
);
*old_ip = args.r8;
*old_flags = args.r9;
*old_UserDefhandle = args.r10;
return result;
}
typedef L4_Word_t (*__L4_ThreadControl_t)( L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t );
extern __L4_ThreadControl_t __L4_ThreadControl;
L4_INLINE L4_Word_t L4_ThreadControl (L4_ThreadId_t dest,
L4_ThreadId_t SpaceSpecifier,
L4_ThreadId_t Scheduler,
L4_ThreadId_t Pager,
void * UtcbLocation)
{
L4_Word_t result = 0;
L4_Word_t dummy = 0;
__asm__ __volatile__ (
"/* L4_ThreadControl */ \n"
"movq %%rax, %%r8 \n"
"movq %%rcx, %%r9 \n"
"pushq %%rbp \n"
"callq *__L4_ThreadControl \n"
"popq %%rbp \n"
:
"=a" (result),
"=c" (dummy),
"=d" (dummy),
"=S" (dummy),
"=D" (dummy)
:
[spacespec] "0" (SpaceSpecifier),
[utcblocation] "1" (UtcbLocation),
[scheduler] "2" (Scheduler),
[pager] "3" (Pager),
[dest] "4" (dest)
:
"memory", "rbx", "r8", "r9", "r11", "r12", "r13", "r14", "r15"
);
return result;
}
typedef L4_Clock_t (*__L4_SystemClock_t)( void );
extern __L4_SystemClock_t __L4_SystemClock;
L4_INLINE L4_Clock_t L4_SystemClock (void)
{
L4_Clock_t ret;
__asm__ __volatile__ (
"/* L4_SystemClock */ \n"
"pushq %%rbp \n"
"callq *__L4_SystemClock \n"
"popq %%rbp \n"
:
"=a" (ret.raw)
:
[dest] "0" (ret.raw)
:
"memory", "rbx", "rcx", "rdx", "rsi", "rdi",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
);
return ret;
}
typedef L4_Word_t (*__L4_ThreadSwitch_t)( L4_Word_t );
extern __L4_ThreadSwitch_t __L4_ThreadSwitch;
L4_INLINE void L4_ThreadSwitch (L4_ThreadId_t dest)
{
L4_Word_t dummy;
__asm__ __volatile__ (
"/* L4_ThreadSwitch */ \n"
"pushq %%rbp \n"
"callq *__L4_ThreadSwitch \n"
"popq %%rbp \n"
:
"=D" (dummy)
:
[dest] "0" (dest)
:
"memory", "rax", "rbx", "rcx", "rdx", "rsi",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
);
}
typedef __L4_Return_t (*__L4_Schedule_t)( L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t );
extern __L4_Schedule_t __L4_Schedule;
L4_INLINE L4_Word_t L4_Schedule (L4_ThreadId_t dest,
L4_Word_t TimeControl,
L4_Word_t ProcessorControl,
L4_Word_t prio,
L4_Word_t PreemptionControl,
L4_Word_t * old_TimeControl)
{
L4_Word_t result = 0;
L4_Word_t dummy = 0;
__asm__ __volatile__ (
"/* L4_Schedule */ \n"
"movq %%rax, %%r8 \n"
"movq %%rcx, %%r9 \n"
"pushq %%rbp \n"
"callq *__L4_Schedule \n"
"popq %%rbp \n"
:
"=a" (*old_TimeControl),
"=c" (dummy),
"=d" (dummy),
"=S" (dummy),
"=D" (dummy)
:
[procontrol] "0" (ProcessorControl),
[precontrol] "1" (PreemptionControl),
[tcontrol] "2" (TimeControl),
[prio] "3" (prio),
[dest] "4" (dest)
:
"memory", "rbx","r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
);
return result;
}
typedef L4_Word_t (*__L4_Ipc_t)( L4_Word_t, L4_Word_t, L4_Word_t );
extern __L4_Ipc_t __L4_Ipc;
L4_INLINE L4_MsgTag_t L4_Ipc (L4_ThreadId_t to,
L4_ThreadId_t FromSpecifier,
L4_Word_t Timeouts,
L4_ThreadId_t * from)
{
L4_ThreadId_t result;
L4_Word_t * utcb = __L4_X86_Utcb ();
L4_Word_t dummy;
__asm__ __volatile__ (
"/* L4_Ipc() */ \n"
"movq %[timeouts], %%r8 \n"
"movq %%rcx, %%r9 \n"
"movq 8(%[utcb]), %%rax \n"
"movq 16(%[utcb]), %%rbx \n"
"movq 24(%[utcb]), %%r10 \n"
"movq 32(%[utcb]), %%r12 \n"
"movq 40(%[utcb]), %%r13 \n"
"movq 48(%[utcb]), %%r14 \n"
"movq 56(%[utcb]), %%r15 \n"
"pushq %%rbp \n"
"callq *__L4_Ipc \n"
"popq %%rbp \n"
"movq %%r10, 24(%[utcb]) \n"
"movq %%r12, 32(%[utcb]) \n"
"movq %%r13, 40(%[utcb]) \n"
"movq %%r14, 48(%[utcb]) \n"
"movq %%r15, 56(%[utcb]) \n"
"movq %%r9, %%rcx \n"
:
"=a" (utcb[1]),
"=b" (utcb[2]),
"=c" (utcb[0]),
"=d" (dummy),
"=S" (result)
:
[to] "4" (to),
[utcb] "D" (utcb),
[from] "3" (FromSpecifier),
[utcb0] "2" (utcb[0]),
[timeouts] "r" (Timeouts)
:
"memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
);
if (! L4_IsNilThread (FromSpecifier)) {
*from = result;
}
return * (L4_MsgTag_t *) (&utcb[0]);
}
typedef L4_Word_t (*__L4_Lipc_t)( L4_Word_t, L4_Word_t, L4_Word_t );
extern __L4_Lipc_t __L4_Lipc;
L4_INLINE L4_MsgTag_t L4_Lipc (L4_ThreadId_t to,
L4_ThreadId_t FromSpecifier,
L4_Word_t Timeouts,
L4_ThreadId_t * from)
{
L4_ThreadId_t result;
L4_Word_t * utcb = __L4_X86_Utcb ();
L4_Word_t dummy;
__asm__ __volatile__ (
"/* L4_Ipc() */ \n"
"movq %[timeouts], %%r8 \n"
"movq %[utcb0], %%r9 \n"
"movq 8(%[utcb]), %%rax \n"
"movq 16(%[utcb]), %%rbx \n"
"movq 24(%[utcb]), %%r10 \n"
"movq 32(%[utcb]), %%r12 \n"
"movq 40(%[utcb]), %%r13 \n"
"movq 48(%[utcb]), %%r14 \n"
"movq 56(%[utcb]), %%r15 \n"
"pushq %%rbp \n"
"callq *__L4_Ipc \n"
"popq %%rbp \n"
"movq %%r9, %[utcb0] \n"
"movq %%r10, 24(%[utcb]) \n"
"movq %%r12, 32(%[utcb]) \n"
"movq %%r13, 40(%[utcb]) \n"
"movq %%r14, 48(%[utcb]) \n"
"movq %%r15, 56(%[utcb]) \n"
:
"=a" (utcb[1]),
"=b" (utcb[2]),
"=c" (utcb[0]),
"=d" (dummy),
"=S" (result)
:
[to] "4" (to),
[utcb] "D" (utcb),
[from] "3" (FromSpecifier),
[utcb0] "2" (utcb[0]),
[timeouts] "r" (Timeouts)
:
"memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
);
if (! L4_IsNilThread (FromSpecifier)) {
*from = result;
}
return * (L4_MsgTag_t *) (&utcb[0]);
}
typedef void (*__L4_Unmap_t)( L4_Word_t );
extern __L4_Unmap_t __L4_Unmap;
L4_INLINE void L4_Unmap (L4_Word_t control)
{
L4_Word_t * utcb = __L4_X86_Utcb ();
L4_Word_t dummy;
__asm__ __volatile__ (
"/* L4_Unmap() */ \n"
"movq %[utcb0], %%r9 \n"
"movq 24(%[utcb]), %%r10 \n"
"movq 32(%[utcb]), %%r12 \n"
"movq 40(%[utcb]), %%r13 \n"
"movq 48(%[utcb]), %%r14 \n"
"movq 56(%[utcb]), %%r15 \n"
"pushq %%rbp \n"
"callq *__L4_Unmap \n"
"popq %%rbp \n"
"movq %%r10, 24(%[utcb]) \n"
"movq %%r12, 32(%[utcb]) \n"
"movq %%r13, 40(%[utcb]) \n"
"movq %%r14, 48(%[utcb]) \n"
"movq %%r15, 56(%[utcb]) \n"
"movq %%r9, %[utcb0] \n"
:
"=a" (utcb[1]),
"=b" (utcb[2]),
"=c" (utcb[0]),
"=d" (dummy),
"=D" (utcb)
:
[utcb1] "0" (utcb[1]),
[utcb2] "1" (utcb[2]),
[utcb0] "2" (utcb[0]),
[control] "3" (control),
[utcb] "4" (utcb)
:
"memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
);
}
typedef __L4_Return_t (*__L4_SpaceControl_t)( L4_Word_t, L4_Word_t, L4_Word_t,
L4_Word_t, L4_Word_t );
extern __L4_SpaceControl_t __L4_SpaceControl;
L4_INLINE L4_Word_t L4_SpaceControl (L4_ThreadId_t SpaceSpecifier,
L4_Word_t control,
L4_Fpage_t KernelInterfacePageArea,
L4_Fpage_t UtcbArea,
L4_ThreadId_t redirector,
L4_Word_t *old_control)
{
L4_Word_t result = 0;
L4_Word_t dummy = 0;
__asm__ __volatile__ (
"/* L4_SpaceControl */ \n"
"movq %%rax, %%r8 \n"
"movq %%rcx, %%r9 \n"
"pushq %%rbp \n"
"callq *__L4_SpaceControl \n"
"popq %%rbp \n"
:
"=a" (result),
"=c" (dummy),
"=d" (*old_control),
"=S" (dummy),
"=D" (dummy)
:
[utcbarea] "0" (UtcbArea),
[redirector] "1" (redirector),
[kiparea] "2" (KernelInterfacePageArea),
[control] "3" (control),
[spacespec] "4" (SpaceSpecifier)
:
"memory", "rbx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
);
return result;
}
typedef L4_Word_t (*__L4_ProcessorControl_t)( L4_Word_t, L4_Word_t,
L4_Word_t, L4_Word_t );
extern __L4_ProcessorControl_t __L4_ProcessorControl;
L4_INLINE L4_Word_t L4_ProcessorControl (L4_Word_t ProcessorNo,
L4_Word_t InternalFrequency,
L4_Word_t ExternalFrequency,
L4_Word_t voltage)
{
L4_Word_t result;
L4_Word_t dummy;
__asm__ __volatile__ (
"/* L4_ProcessorControl */ \n"
"movq %%rax, %%r8 \n"
"pushq %%rbp \n"
"callq *__L4_ProcessorControl \n"
"popq %%rbp \n"
:
"=a" (result),
"=d" (dummy),
"=S" (dummy),
"=D" (dummy)
:
[voltage] "0" (voltage),
[exfreq] "1" (ExternalFrequency),
[intfreq] "2" (InternalFrequency),
[procno] "3" (ProcessorNo)
:
"memory", "rcx", "rbx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
);
return result;
}
typedef L4_Word_t (*__L4_MemoryControl_t)( L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t );
extern __L4_MemoryControl_t __L4_MemoryControl;
L4_INLINE L4_Word_t L4_MemoryControl (L4_Word_t control,
const L4_Word_t * attributes)
{
L4_Word_t result;
L4_Word_t dummy;
L4_Word_t * utcb = __L4_X86_Utcb ();
__asm__ __volatile__ (
"/* L4_MemoryControl */ \n"
"movq (%[attributes]), %%rcx \n"
"movq 8(%[attributes]), %%rsi \n"
"movq 16(%[attributes]), %%r8 \n"
"movq 24(%[attributes]), %%r11 \n"
"movq %[utcb0], %%r9 \n"
"movq 16(%[utcb]), %%rbx \n"
"movq 24(%[utcb]), %%r10 \n"
"movq 32(%[utcb]), %%r12 \n"
"movq 40(%[utcb]), %%r13 \n"
"movq 48(%[utcb]), %%r14 \n"
"movq 56(%[utcb]), %%r15 \n"
"pushq %%rbp \n"
"callq *__L4_MemoryControl \n"
"popq %%rbp \n"
:
"=a" (utcb[1]),
"=b" (dummy),
"=c" (utcb[0]),
"=d" (result),
"=D" (utcb)
:
[utcb1] "0" (utcb[1]),
[attributes] "1" (attributes),
[utcb0] "2" (utcb[0]),
[control] "3" (control),
[utcb] "4" (utcb)
:
"memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
);
return result;
}
#endif