#ifndef __L4__X86__SYSCALLS_H__
#define __L4__X86__SYSCALLS_H__
#include __L4_INC_ARCH(vregs.h)
#include __L4_INC_ARCH(specials.h)
#include <l4/message.h>
#if defined(__pic__)
# define __L4_SAVE_REGS " pushl %%ebx; pushl %%ebp\n"
# define __L4_RESTORE_REGS " popl %%ebp; popl %%ebx\n"
# define __L4_CLOBBER_REGS "cc"
#else
# define __L4_SAVE_REGS " pushl %%ebp \n"
# define __L4_RESTORE_REGS " popl %%ebp \n"
# define __L4_CLOBBER_REGS "ebx", "cc"
#endif
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;
}
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;
struct {
L4_Word_t ebp;
L4_Word_t edi;
L4_Word_t ebx;
L4_Word_t esi;
} in;
in.ebp = pager.raw;
in.ebx = UserDefHandle;
in.esi = ip;
in.edi = flags;
__asm__ __volatile__ (
"/* L4_ExchangeRegisters() */ \n"
__L4_SAVE_REGS
" pushl %%esi \n"
" movl (%%esi), %%ebp \n"
" movl 4(%%esi), %%edi \n"
" movl 8(%%esi), %%ebx \n"
" movl 12(%%esi), %%esi \n"
" call __L4_ExchangeRegisters \n"
" xchgl %%esi, (%%esp) \n"
" movl %%edi, 4(%%esi) \n"
" movl %%ebx, 8(%%esi) \n"
" movl %%ebp, (%%esi) \n"
" popl %%esi \n"
__L4_RESTORE_REGS
:
"=a" (result), "=c" (*old_control), "=d" (*old_sp), "=S" (*old_ip)
:
"a" (dest.raw), "c" (control), "d" (sp), "S" (&in)
:
"edi", "memory", __L4_CLOBBER_REGS);
old_pager->raw = in.ebp;
*old_flags = in.edi;
*old_UserDefhandle = in.ebx;
return result;
}
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;
L4_Word_t dummy;
__asm__ __volatile__ (
"/* L4_ThreadControl() */ \n"
__L4_SAVE_REGS
" call __L4_ThreadControl \n"
__L4_RESTORE_REGS
:
"=a" (result),
"=c" (dummy),
"=d" (dummy),
"=S" (dummy),
"=D" (dummy)
:
"0" (dest),
"1" (Pager),
"2" (Scheduler),
"3" (SpaceSpecifier),
"4" (UtcbLocation)
:
__L4_CLOBBER_REGS);
return result;
}
L4_INLINE L4_Clock_t L4_SystemClock (void)
{
L4_Clock_t result;
__asm__ __volatile__ (
"/* L4_SystemClock() */ \n"
" call __L4_SystemClock \n"
:
"=A" (result.raw)
:
:
"ecx", "esi", "edi");
return result;
}
L4_INLINE void L4_ThreadSwitch (L4_ThreadId_t dest)
{
__asm__ __volatile__ (
"/* L4_ThreadSwitch() */ \n"
" call __L4_ThreadSwitch \n"
:
:
"a" (dest)
);
}
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;
L4_Word_t dummy;
__asm__ __volatile__ (
"/* L4_Schedule() */ \n"
__L4_SAVE_REGS
" call __L4_Schedule \n"
__L4_RESTORE_REGS
:
"=a" (result),
"=c" (dummy),
"=d" (*old_TimeControl),
"=S" (dummy),
"=D" (dummy)
:
"0" (dest),
"1" (prio),
"2" (TimeControl),
"3" (ProcessorControl),
"4" (PreemptionControl)
:
__L4_CLOBBER_REGS);
return result;
}
L4_INLINE L4_MsgTag_t L4_Ipc (L4_ThreadId_t to,
L4_ThreadId_t FromSpecifier,
L4_Word_t Timeouts,
L4_ThreadId_t * from)
{
L4_MsgTag_t mr0;
L4_Word_t mr1, mr2;
L4_ThreadId_t result;
L4_Word_t * utcb = __L4_X86_Utcb ();
#if defined(__pic__)
__asm__ __volatile__ (
"/* L4_Ipc() */ \n"
__L4_SAVE_REGS
" call __L4_Ipc \n"
" movl %%ebp, %%ecx \n"
" movl %%ebx, %%edx \n"
__L4_RESTORE_REGS
:
"=S" (mr0),
"=a" (result),
"=d" (mr1),
"=c" (mr2)
:
"S" (utcb[0]),
"a" (to.raw),
"D" (utcb),
"c" (Timeouts),
"d" (FromSpecifier)
);
#else
L4_Word_t dummy;
__asm__ __volatile__ (
"/* L4_Ipc() */ \n"
__L4_SAVE_REGS
" call __L4_Ipc \n"
" movl %%ebp, %%ecx \n"
__L4_RESTORE_REGS
:
"=S" (mr0),
"=a" (result),
"=b" (mr1),
"=c" (mr2),
"=d" (dummy)
:
"S" (utcb[0]),
"a" (to.raw),
"D" (utcb),
"c" (Timeouts),
"d" (FromSpecifier)
);
#endif
if (! L4_IsNilThread (FromSpecifier)) {
*from = result;
utcb[1] = mr1;
utcb[2] = mr2;
}
return mr0;
}
L4_INLINE L4_MsgTag_t L4_Lipc (L4_ThreadId_t to,
L4_ThreadId_t FromSpecifier,
L4_Word_t Timeouts,
L4_ThreadId_t * from)
{
L4_MsgTag_t mr0;
L4_Word_t mr1, mr2;
L4_ThreadId_t result;
L4_Word_t * utcb = __L4_X86_Utcb ();
#if defined(__pic__)
__asm__ __volatile__ (
"/* L4_Lipc() */ \n"
__L4_SAVE_REGS
" call __L4_Lipc \n"
" movl %%ebp, %%ecx \n"
" movl %%ebx, %%edx \n"
__L4_RESTORE_REGS
:
"=S" (mr0),
"=a" (result),
"=d" (mr1),
"=c" (mr2)
:
"S" (utcb[0]),
"a" (to.raw),
"D" (utcb),
"c" (Timeouts),
"d" (FromSpecifier)
);
#else
L4_Word_t dummy;
__asm__ __volatile__ (
"/* L4_Lipc() */ \n"
__L4_SAVE_REGS
" call __L4_Lipc \n"
" movl %%ebp, %%ecx \n"
__L4_RESTORE_REGS
:
"=S" (mr0),
"=a" (result),
"=b" (mr1),
"=c" (mr2),
"=d" (dummy)
:
"S" (utcb[0]),
"a" (to.raw),
"D" (utcb),
"c" (Timeouts),
"d" (FromSpecifier)
);
#endif
if (! L4_IsNilThread (FromSpecifier)) {
*from = result;
utcb[1] = mr1;
utcb[2] = mr2;
}
return mr0;
}
L4_INLINE void L4_Unmap (L4_Word_t control)
{
L4_Word_t dummy;
L4_Word_t * utcb = __L4_X86_Utcb ();
__asm__ __volatile__ (
"/* L4_Unmap() */ \n"
__L4_SAVE_REGS
" call __L4_Unmap \n"
__L4_RESTORE_REGS
:
"=S" (utcb[0]),
"=D" (dummy),
"=a" (dummy)
:
"0" (utcb[0]),
"1" (utcb),
"2" (control)
:
"ecx", "edx", __L4_CLOBBER_REGS);
}
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, dummy;
__asm__ __volatile__ (
"/* L4_SpaceControl() */ \n"
__L4_SAVE_REGS
" call __L4_SpaceControl \n"
__L4_RESTORE_REGS
:
"=a" (result),
"=c" (*old_control),
"=d" (dummy),
"=S" (dummy),
"=D" (dummy)
:
"0" (SpaceSpecifier),
"1" (control),
"2" (KernelInterfacePageArea),
"3" (UtcbArea),
"4" (redirector)
:
__L4_CLOBBER_REGS);
return result;
}
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, dummy;
__asm__ __volatile__ (
"/* L4_ProcessorControl() */ \n"
__L4_SAVE_REGS
" call __L4_ProcessorControl \n"
__L4_RESTORE_REGS
:
"=a" (result),
"=c" (dummy),
"=d" (dummy),
"=S" (dummy),
"=D" (dummy)
:
"0" (ProcessorNo),
"1" (InternalFrequency),
"2" (ExternalFrequency),
"3" (voltage)
:
__L4_CLOBBER_REGS);
return result;
}
L4_INLINE L4_Word_t L4_MemoryControl (L4_Word_t control,
const L4_Word_t * attributes)
{
L4_Word_t result, dummy;
L4_Word_t * utcb = __L4_X86_Utcb ();
__asm__ __volatile__ (
"/* L4_MemoryControl() */ \n"
__L4_SAVE_REGS
" movl 12(%6), %%ebp \n"
" movl 8(%6), %%ebx \n"
" movl 4(%6), %%edx \n"
" movl (%6), %%ecx \n"
" call __L4_MemoryControl \n"
__L4_RESTORE_REGS
:
"=a" (result),
"=c" (dummy),
"=d" (dummy),
"=S" (dummy),
"=D" (dummy)
:
"0" (control),
"1" (attributes),
"3" (utcb[0]),
"4" (utcb)
:
__L4_CLOBBER_REGS);
return result;
}
#endif