/*
  Syscall.h, Copyright  (c) by Eckart Zitzler, Christian Conrad, George Fankhauser,
  Swiss Federal Institute of Technology,
  Computer Engineering and Networks Laboratory.
 
  TOPSY -- A Teachable Operating System.
           Implementation of a tiny and simple
           micro kernel for teaching purposes.
 
  For further information, please visit http://www.tik.ee.ethz.ch/~topsy
 
  This software is provided under the terms of the GNU General Public Licence.
 
  A full copy of the GNU GPL is provided in the file COPYING found in the 
  development root of Topsy.
*/
/*
  File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/Topsy/Syscall.h,v $
  Author(s):             Eckart Zitzler, Christian Conrad, George Fankhauser
  Affiliation:           ETH Zuerich, TIK
  Version:               $Revision: 2922 $
  Creation Date:         
  Last Date of Change:   $Date: 2007-03-19 17:48:52 +0100 (Mon, 19 Mär 2007) $      by: $Author: baderma $
*/

#ifndef _SYSCALL_H_
#define _SYSCALL_H_

#include "Topsy.h"
#include "Messages.h"
#include "Memory.h"
#include "Threads.h"
#include "IO.h"

#define SYSCALL_ERROR  MessageError

/* Syscall interface */
SYSCALL_ERROR genericSyscall(ThreadId to, Message* message, Message* reply);

#if 0
/* old memory management */

SYSCALL_ERROR  vmAlloc(Address *addressPtr, unsigned long int  size);
SYSCALL_ERROR  vmFree(Address address);
SYSCALL_ERROR  vmMove(Address *addressPtr, ThreadId newOwner);
SYSCALL_ERROR  vmProtect(Address  startAdr, unsigned long int  size,
                        ProtectionMode  pmode);
SYSCALL_ERROR  vmCleanup(ThreadId threadId);
#endif

/* new virtual memory management */

int vmAllocateStack(ThreadId pdId, address_t *baseaddr,
                    address_t hintaddr, size_t size, address_t *sharedbase);
int vmFreeHint(ThreadId pdId, address_t hintaddr);
int vmFreeAll(ThreadId pdId);

/* thread management */

SYSCALL_ERROR tmMsgSend( ThreadId to, Message *msg);
SYSCALL_ERROR tmMsgRecv( ThreadId* from,
                        MessageId msgId,
                        Message* msg,
                        int timeOut);
SYSCALL_ERROR tmStart( ThreadId* id,
                      ThreadMainFunction mainFunction,
                      ThreadArg parameter,
                      char *name);
SYSCALL_ERROR tmKill(ThreadId id);
void tmExit(void);
void tmYield(void);
/* the famous info msg */
SYSCALL_ERROR tmGetInfo(ThreadId about, ThreadId* tid, ThreadId* ptid);
SYSCALL_ERROR tmGetFirst(ThreadInfo* info);
SYSCALL_ERROR tmGetNext(ThreadInfo* info);
SYSCALL_ERROR tmGetIDInfo(ThreadId about, ThreadInfo* info);
/* timing stuff */
SYSCALL_ERROR tmGetTime(unsigned long* seconds, unsigned long* microSeconds);
SYSCALL_ERROR tmSetTime(unsigned long seconds, unsigned long microSeconds);

/* timer SysCalls: important, the expiredMsg-Buffer must remain intact until a
 * timer is either fired or cancelled, AND REMOVED AFTERWARDS BY THE CALLER!
 * The expiredMsg is the only parameter to be explained: it will be the 
 * TMTimerExpiredMsg being sent back when the timer goes off, and has to be
 * defined here to make sure we have the possibility to run several threads awaiting
 * a timer in parallel.
 */
SYSCALL_ERROR tmSetTimer(unsigned long ticks,
                        unsigned long *timerId);
SYSCALL_ERROR tmClearTimer(unsigned long timerId);
SYSCALL_ERROR tmAwaitTimer(unsigned long *timerId);


/* io interface */

SYSCALL_ERROR ioLoad(unsigned short major, Address dev, unsigned short *minor);
SYSCALL_ERROR ioOpen(unsigned short major, unsigned short minor , ThreadId* id);
SYSCALL_ERROR ioClose(ThreadId id);
SYSCALL_ERROR ioRead(ThreadId id, char* buffer, unsigned long int* nOfBytes);
SYSCALL_ERROR ioWrite(ThreadId id, char* buffer, unsigned long int* nOfBytes);
SYSCALL_ERROR ioInit(ThreadId id);
SYSCALL_ERROR ioSubscribe(ThreadId id, ThreadId from);
SYSCALL_ERROR ioUnSubscribe(ThreadId id, ThreadId from);
void ioGetAddr(ThreadId id, char *addr, int len);
SYSCALL_ERROR ioSockGetPort(ThreadId id, unsigned short *port);

/* function prototypes for the new push / pop message interface */
SYSCALL_ERROR attachEnvMsg(Message* msg, uint32 flags);
SYSCALL_ERROR detachEnvMsg(Message* msg);
int initEnvMsg(Message* msg);
inline int pushEnvMsg(Message* msg, address_t data, size_t len);
int pushEnvMsg_8(Message* msg, uint8 data);
int pushEnvMsg_16(Message* msg, uint16 data);
int pushEnvMsg_32(Message* msg, uint32 data);
inline size_t popEnvMsg(Message* msg, address_t* addr);
size_t popEnvMsg_8(Message* msg, uint8* retVal);
size_t popEnvMsg_16(Message* msg, uint16* retVal);
size_t popEnvMsg_32(Message* msg, uint32* retVal);
/* Macros used for the message system */
#define WORDROUND(x)		( ( (x) + 3) & 0xFFFFFFFC )
#define CLEAR_MSGENV(x)	(x).enveloppe = NULL


#endif
