/*
    Messages.h, Copyright 11.2.97 (c) by Christian Conrad,
    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/Messages.h,v $
 	Author(s):             Christian Conrad
 	Affiliation:           ETH Zuerich, TIK
 	Version:               $Revision: 3037 $
 	Creation Date:         11.2.97
 	Last Date of Change:   $Date: 2007-06-03 23:23:51 +0200 (Son, 03 Jun 2007) $  by: $Author: sryffel $
	
*/
#ifndef __MESSAGES_H
#define __MESSAGES_H

#include "Topsy.h"
#include "types.h"
#include "Memory.h"
#include "IO.h"
#include "Configuration.h"
#include "SyscallMsg.h"


#define SELF         0         /* info about one self */
/* XXX can cause conflicts since id 1 is the loader */
#define ANY          1         /* Receiving from any thread */
#define INFINITY    -1         /* Infinite timeout when receiving message */
#define SELFPD			-1				 /* use pd of caller */

/* LR 000706 */
/* these are the low-level Send/Recv operands.  The names are adjusted from the
 * SyscallMsg.h.  This needs do be done to uniquely define these operands.
 * IF SOMEBODY CHANGES THESE VALUES, PLEASE TAKE CARE OF ALL THE OTHER STUFF.
 * IT TOOK ME ABOUT A WEEK TO DEBUG TOPSYi386 DURING BOOT-UP.
 * THESE VALUES ARE ALL DEFINED IN Topsy/SyscallMsg.h.
 */
typedef enum {SYSCALL_SEND_OP=dSYSCALL_SEND_OP, /* IMPORTANT OPERAND */
              SYSCALL_RECV_OP=dSYSCALL_RECV_OP  /* IMPORTANT OPERAND */
             } MsgOpCode;

/*
 * Message ids and errors
 */

/* flag used to specify if a massage needs a loanin or not,
	 it is not allowed to set Message ids with this bit set (negative numbers).
 */
#define MSG_NEEDS_LOANIN 0x80000000
typedef enum {
  ANYMSGTYPE,
  /* 0 */
  TM_START, TM_EXIT, TM_YIELD, TM_KILL,
  TM_STARTREPLY, TM_KILLREPLY, TM_INFO, TM_INFOREPLY,      /* thread manager */
  /* 8 */
  /* time */
  TM_GETTIME, TM_GETTIMEREPLY, TM_SETTIME, TM_SETTIMEREPLY, /* time */
  /* 12 */
  /* timer = similar to alarm() */
  TM_TIMERSET,      TM_TIMERCLEAR,      TM_TIMEREXPIRED,
  TM_TIMERSETREPLY, TM_TIMERCLEARREPLY,
  /* 17 */
  VM_ALLOC, VM_UNALLOC, VM_MOVE, VM_PROTECT,            /* memory manager */
  VM_ALLOCREPLY, VM_FREEREPLY, VM_MOVEREPLY, VM_PROTECTREPLY,
  VM_CLEANUP,
  /* 26 */
  IO_OPEN, IO_CLOSE, IO_READ, IO_WRITE,                 /* input/output */
  IO_INIT, IO_LOAD,
  IO_OPENREPLY, IO_CLOSEREPLY, IO_READREPLY,
  IO_WRITEREPLY, IO_INITREPLY, IO_LOADREPLY,
  /* 38 */
  IO_SUBSCRIBE, IO_SUBSCRIBEREPLY,
  IO_UNSUBSCRIBE, IO_UNSUBSCRIBEREPLY,
  IO_NOTIFY, IO_GETADDR, IO_GETADDRREPLY,               /* async device */

  IO_TIMER_START, IO_TIMER_STOP, IO_TIMERREPLY,         /* hw timer (option) */
  /* 48 */
  NET_INQUEUE_PT_IDLE, NET_INQUEUE_PT_BUSY,             /* network stack */
  NET_QUEUE_DATA, NET_CONFIG_REQUEST, NET_CONF_POOLREPLY,
  NET_CONF_CHAINREQ, NET_CONF_CHAINREPLY, NET_CONF_CHAINGETREPLY,
  NET_CONF_MODULEADD, NET_CONF_MODULESET, NET_CONF_MODULEGET,
  NET_CONF_TYPEGET, NET_CONF_TYPESET, NET_CONF_ADDRSET, NET_CONF_GETHWADDR,
  NET_CONF_MODULEREQ, NET_CONF_MODULEREPLY,
  NET_CONF_CHAINGETFIRST, NET_CONF_CHAINGETNEXT,
  /* 67 */

  /* arp stuff */
  NET_ARP_REQ, NET_ARP_ADD, NET_ARP_DEL, NET_ARP_REPLY,
  /* 71 */
  /* socket stuff */
  NET_CONF_PCBREQ, NET_CONF_REPLY, NET_CONF_PCBDEL,
  BIND, CONNECT, NET_SOCKET_CONNECTED, SOCK_GET_PORT,
  NET_SOCKET_PORT,
  /* 79 */
  /* Loader stuff */
  NET_TFTP_GETCMD, NET_TFTP_SIZE_REPLY,
  /* 81 */
  /* VMemory stuff */
  VM_LOOKUP, VM_ALLOC_STACK, VM_REGION_ADD_NEAR, VM_REGION_ADD_LOAN,
  VM_REPLY, VM_ATTACH_MSG_PAGE, VM_ATTACH_MSG_PAGE_REPLY,
  VM_DETACH_MSG_PAGE, VM_DETACH_MSG_PAGE_REPLY,
  VM_REGION_ADD, VM_REGION_FREE, VM_REGION_FREE_HINT, VM_REGION_FREE_ALL,
  VM_REGION_SHARE, VM_MAP_FIND_NEAR, VM_REGION_ENTER, 
  /* not yet implemented */
  VM_REGION_CHPROT, VM_REGION_RESIZE, VM_REGION_GET,
  /* 100 */
  /* Loader stuff */
  LD_LOAD, LD_REPLY,
  /* 102 */
  UNKNOWN_SYSCALL                                       /* unknown syscalls */
  /* 103 */
} MessageId;

typedef enum {
  TM_MSGSENDOK, TM_MSGSENDFAILED, TM_MSGRECVOK, TM_MSGRECVFAILED,
  TM_STARTOK, TM_STARTFAILED, TM_KILLOK, TM_KILLFAILED,
  TM_INFOOK, TM_INFOFAILED, TM_TIMEOK, TM_TIMEFAILED,

  /* timer = similar to alarm() */
  TM_TIMERSETOK,      TM_TIMERCLEAROK,      TM_TIMEREXPIREDOK,
  TM_TIMERSETFAILED,  TM_TIMERCLEARFAILED,  TM_TIMEREXPIREDFAILED,

  VM_ALLOCOK, VM_ALLOCFAILED, VM_FREEOK, VM_FREEFAILED,
  VM_MOVEOK, VM_MOVEFAILED, VM_PROTECTOK, VM_PROTECTFAILED,
  VM_CLEANUPOK, VM_CLEANUPFAILED,

  IO_OPENOK, IO_OPENFAILED, IO_CLOSEOK, IO_CLOSEFAILED,
  IO_READOK, IO_READFAILED, IO_WRITEOK, IO_WRITEFAILED,
  IO_INITOK, IO_INITFAILED, IO_LOADOK,  IO_LOADFAILED,

  IO_SUBSCRIBEOK, IO_SUBSCRIBEFAILED,
  IO_UNSUBSCRIBEOK, IO_UNSUBSCRIBEFAILED,
  IO_SOCKPORTFAILED
} MessageError;

/* subtype for various infos on threads */
typedef enum {SPECIFIC_ID, GETFIRST, GETNEXT, THREAD_BY_NAME, GET_ID_INFO} ThreadInfoKind;

typedef enum {Info_RUNNING, Info_READY, Info_BLOCKED} ThreadInfoStatus;

/* thread structure for users */
typedef struct ThreadInfo_t
{
  ThreadId tid;
  ThreadId ptid ;
  ThreadInfoStatus status ;
  char name[MAXNAMESIZE] ;
}
ThreadInfo;


/*
 * Message structures: Threads
 */

/* removed in new message passing system (push & pop is used instead)
 *
typedef struct TMStartMsg_t { 	     // Message to create a thread
    ThreadMainFunction fctnAddress;
    ThreadArg parameter;
    char *name;
} TMStartMsg;
*/

typedef struct TMStartReplyMsg_t
{   /* Message to create a thread (reply) */
  ThreadId newId;
  MessageError errorCode;
}
TMStartReplyMsg;

typedef struct TMKillMsg_t
{ 	     /* Message to kill a thread */
  ThreadId id;
}
TMKillMsg;

typedef struct TMKillReplyMsg_t
{    /* Message to kill a thread (reply) */
  MessageError errorCode;
}
TMKillReplyMsg;

typedef struct TMExitMsg_t
{ 	     /* Message to "exit" a thread */
  ThreadId id;
}
TMExitMsg;

typedef struct TMGetInfoMsg_t
{      // Message to get info about threads
  ThreadId about;
  ThreadInfoKind kind;
}
TMGetInfoMsg;

/* removed in new message passing system (push & pop is used instead)
 *
typedef struct TMGetInfoReplyMsg_t { 
    MessageError errorCode;
    long int info[2];
} TMGetInfoReplyMsg;
*/

typedef struct TMTimeMsg_t
{         /* Message to get/set real time */
  MessageError errorCode;
  unsigned long int seconds;
  unsigned long int microSeconds;
}
TMTimeMsg;


#ifdef WITH_TIMER_QUEUE
typedef struct TMTimerSetMsg_t
{
  unsigned long deltaTicks;
}
TMTimerSetMsg;

typedef struct TMTimerSetReplyMsg_t
{
  MessageError errorCode;
  unsigned long timerId;
}
TMTimerSetReplyMsg;

typedef struct TMTimerExpiredMsg_t
{
  unsigned long timerId;
}
TMTimerExpiredMsg;

typedef struct TMTimerClearMsg_t
{
  unsigned long timerId;
}
TMTimerClearMsg;

typedef struct TMTimerClearReplyMsg_t
{
  MessageError errorCode;
}
TMTimerClearReplyMsg;
#endif

/*
 * Message structures: Memory
 */
// Some of these messages would have to be adapted to the new
// messaguing systemn, however since the new messaging system
// is only available/usefull with the new MM this stuff here
// will not be changed and be removed later
typedef struct VMAllocMsg_t
{        /* Message to get virtual memory */
  unsigned long int size;
}
VMAllocMsg;

typedef struct VMAllocReplyMsg_t
{   /* Message to get virtual memory (reply) */
  MessageError errorCode;
  Address address;
}
VMAllocReplyMsg;

typedef struct VMFreeMsg_t
{         /* Message to free virtual memory */
  Address address;
}
VMFreeMsg;

typedef struct VMFreeReplyMsg_t
{    /* Message to free virtual memory (reply) */
  MessageError errorCode;
}
VMFreeReplyMsg;

typedef struct VMMoveMsg_t
{         /* Message to move memory region */
  Address address;
  ThreadId newOwner;
}
VMMoveMsg;

typedef struct VMMoveReplyMsg_t
{    /* Message to move memory region (reply) */
  MessageError errorCode;
  Address address;
}
VMMoveReplyMsg;

typedef struct VMProtectMsg_t
{      /* Message to protect memory region */
  Address startAddress;
  unsigned long int size;
  ProtectionMode pmode;
}
VMProtectMsg;

typedef struct VMProtectReplyMsg_t
{ /* protect memory region (reply) */
  MessageError errorCode;
}
VMProtectReplyMsg;

typedef struct VMCleanupMsg_t
{      /* cleanup memory regions for thread */
  ThreadId threadId;
}
VMCleanupMsg;


/*
 * Message structures: IO
 */
typedef struct IOOpenMsg_t
{
  long int deviceMajor;
  long int deviceMinor;
}
IOOpenMsg;

typedef struct IOOpenReplyMsg_t
{
  MessageError errorCode;
  long int deviceThreadId;
}
IOOpenReplyMsg;

typedef struct IOCloseMsg_t
{
  long int deviceThreadId;
}
IOCloseMsg;

typedef struct IOCloseReplyMsg_t
{
  MessageError errorCode;
}
IOCloseReplyMsg;

/* removed in new message passing system (push & pop is used instead)
 *
typedef struct IOLoadMsg_t {
    long int deviceMajor;
	Address deviceDesc; // IODevice not declared here -> generic pointer
} IOLoadMsg;
*/

typedef struct IOLoadReplyMsg_t
{
  MessageError errorCode;
  long int deviceMinor;
}
IOLoadReplyMsg;

/* has been adapted to new msg system (buffer is passed in reply enveloppe)
 */
typedef struct IOReadMsg_t
{
  unsigned long int size;
}
IOReadMsg;

typedef struct IOReadReplyMsg_t
{
  MessageError errorCode;
  unsigned long int bytesRead;
}
IOReadReplyMsg;

/* has been adapted to new msg system (buffer is passed in msg enveloppe)
 */
typedef struct IOWriteMsg_t
{
  unsigned long int size;
}
IOWriteMsg;

typedef struct IOWriteReplyMsg_t
{
  MessageError errorCode;
  unsigned long int bytesWritten;
}
IOWriteReplyMsg;

typedef struct IOInitReplyMsg_t
{
  MessageError errorCode;
}
IOInitReplyMsg;

typedef struct
{ /* Message for hw-timer */
  int period;
}
IOTimerMsg;

typedef struct IOSubscribeMsg_t
{  /* async device */
}
IOSubscribeMsg;

typedef struct IOSubscribeReplyMsg_t
{  /* async device */
  MessageError errorCode;
}
IOSubscribeReplyMsg;

typedef struct IOUnSubscribeMsg_t
{  /* async device */
}
IOUnSubscribeMsg;

typedef struct IOUnSubscribeReplyMsg_t
{  /* async device */
  MessageError errorCode;
}
IOUnSubscribeReplyMsg;

typedef struct IONotifyMsg_t
{  /* async device */
  long int deviceNumber;
  unsigned long int length;
}
IONotifyMsg;

typedef struct IOGetAddrReplyMsg_t
{  /* async device */
  unsigned char addr[12];           /* Ethernet: first 6 bytes */
}
IOGetAddrReplyMsg;

/*
 * Message structures: networkStack
 */
// there's a lot of waork to be done, making all this work
// with the new MM and messaging system...
typedef struct NETQueueMsg_t
{
  Address		netData;
  Address		netMeta;
  ThreadId	netId;
}
NETQueueMsg;

typedef struct NETChainGetMsg_t
{
  long id;
  long errno;
  long pad;
}
NETChainGetMsg;

typedef struct NETSocketReqMsg_t
{
  unsigned short domain;
  unsigned short type;
  unsigned short protocol;
  short pad[3];
}
NETSocketReqMsg;

typedef struct NETSocketAllocated_t
{
  long errno;
  unsigned short socket;
  short pad[3];
}
NETSocketAllocated;

typedef struct NETSocketPortReply_t
{
  unsigned short port;
  MessageError errorCode;
}
NETSocketPortReply;

typedef struct NETARPReplyMsg_t
{
  unsigned char* ha;
  int ha_len;
  int status;
}
NETARPReplyMsg;

typedef struct NETARPReqMsg_t
{
  unsigned char* pa;
  int pa_len;
  short proto;
  unsigned short device;
}
NETARPReqMsg;

typedef struct NETARPAddMsg_t
{
  unsigned char *pa;
  unsigned char *ha;
  short proto;
  unsigned short device;
}
NETARPAddMsg;

typedef struct NETConfigureChainRequest_t
{
  unsigned short	chainKey;
  long	id;
}
NETConfigureChainRequest;

typedef struct NETConfigureChainReply
{
  Address		chain;
  long		len;
}
NETConfigureChainReply;

typedef struct NETConfigureModuleAdd_t
{
  Address moduleRegistry;
  int copyFlag;
}
NETConfigureModuleAdd;

typedef struct NETConfigureModuleConf_t
{
  long id;
  Address attrVec;
  unsigned long len;
}
NETConfigureModuleConf;

typedef struct NETConfigureTypeConf_t
{
  long type;
  Address attrVec;
  unsigned long len;
}
NETConfigureTypeConf;

typedef struct NETSocketConnectBind_t
{
  Address attrVec;
  unsigned long len;
  unsigned short protocol;
  unsigned short domain;
}
NETSocketConnectBind;

typedef struct NETConfigureAddressSet_t
{
  unsigned short deviceNr;
  unsigned short index;
  Address attrVec;
  unsigned long len;
}
NETConfigureAddressSet;

typedef struct NETConfigureHWAddressGet_t
{
  unsigned short deviceNr;
  unsigned short pad;
  Address attrVec;
  unsigned long *len;
}
NETConfigureHWAddressGet;

typedef struct NETConfigureModuleRequest_t
{
  long request;
  ThreadId id;
}
NETConfigureModuleRequest;

typedef union NETConfigureMsg_u {
  NETSocketReqMsg SocketReq;
  NETSocketAllocated SocketAllocated;
  NETConfigureChainRequest ChainReq;
  NETConfigureChainReply ChainReply;
  NETConfigureModuleAdd ModuleAdd;
  NETConfigureModuleConf ModuleConf;
  NETConfigureTypeConf TypeConf;
  NETConfigureAddressSet AddrSet;
  NETConfigureModuleRequest ModuleReq;
  NETConfigureHWAddressGet HWAddrGet;
} NETConfigureMsg;

typedef struct NETConfigureReplyMsg_t
{
  long errno;
  long pad0, pad1;
}
NETConfigureReplyMsg;

typedef struct NETTftpGetCmd_t
{
  address_t		buff;
  char*				file;
}
NETTftpGetCmd;

typedef struct NETTftpSizeReply_t
{
  long				size;
}
NETTftpSizeReply;


/*
 * Message structures: VMemory
 */

/* must not be adapted to new msg
 */
typedef struct VMemoryRegionLookupMsg_t
{
  ThreadId		pdId;
  address_t		badVAddr;
  long				type;
}
VMemoryRegionLookupMsg;

/* must not be adapted to new msg
 */
typedef struct VMemoryRegionAllocStackMsg_t
{
  ThreadId		pdId;
  address_t		hintaddr;
  size_t			size;
}
VMemoryRegionAllocStackMsg;

typedef struct VMemoryRegionFreeHintMsg_t
{
  ThreadId		pdId;
  address_t		hintaddr;
}
VMemoryRegionFreeHintMsg;

typedef struct VMemoryRegionFreeAllMsg_t
{
  ThreadId		pdId;
}
VMemoryRegionFreeAllMsg;

/* XXX must be adapted to new msg but is not yet used...
 */
typedef struct VMemoryRegionGetMsg_t
{
  ThreadId		pdId;
  address_t		hint;
  address_t		regPtr;
}
VMemoryRegionGetMsg;

/* XXX might have be adapted to new msg but is not yet used...
 */
typedef struct VMemoryRegionChProtMsg_t
{
  long XXX;
}
VMemoryRegionChProtMsg;

/* XXX must be adapted to new msg but is not yet used...
 */
typedef struct VMemoryRegionResizeMsg_t
{
  ThreadId		pdId;
  address_t		regPtr;
}
VMemoryRegionResizeMsg;

/* XXX might have be adapted to new msg but is not yet used...
 */
typedef struct VMemoryRegionShareMsg_t
{
  long XXX;
}
VMemoryRegionShareMsg;

/* must not be adapted to new msg since ptr is not yet used in
 * a way which needs copying of associated data
 */
typedef struct VMemoryReplyMsg_t
{
  long			err;
  address_t	ptr1;
  address_t	ptr2;
}
VMemoryReplyMsg;

/* must not be adapted to new msg since ptr is not used in
 * a way which needs copying of associated data
 */
typedef struct VMemoryMsgPage_t
{
  uint32			flags;
  address_t		pageAddr;
  long				error;
}
VMemoryMsgPage;


/*
 * Message structures: Loader
 */

/* removed in new message passing system (push & pop is used instead)
 *
typedef struct LDLoadMsg_t {
	char		*fileName;
	int			permission;
	int			priority;
} LDLoadMsg;
*/

typedef struct LDReplyMsg_t
{
  long      err;
}
LDReplyMsg;


/*
 * Message structures: Generic messages
 */
typedef struct SyscallReply_t
{
  MessageError errorCode;
}
SyscallReply;

/* XXX must be adapted to new msg but can wait
 */
typedef struct UserMessage_t
{
  void* p1;
  void* p2;
  void* p3;
}
UserMessage;

typedef struct PushPopMsg_t
{
  uint32	num_args;
  uint32	push_pos;
  uint32	pop_pos;
}
PushPopMsg;



typedef union SpecMsg_u {            /* Union type of all possible messages */
  UserMessage userMsg;

  PushPopMsg pushpop;

  TMStartReplyMsg tmStartReply;
  TMKillMsg tmKill;
  TMKillReplyMsg tmKillReply;
  TMGetInfoMsg tmInfo;
  TMTimeMsg tmTime;
#ifdef WITH_TIMER_QUEUE

  TMTimerSetMsg         tmTimerSet;
  TMTimerSetReplyMsg    tmTimerSetReply;
  TMTimerClearMsg       tmTimerClear;
  TMTimerClearReplyMsg  tmTimerClearReply;
  TMTimerExpiredMsg     tmTimerExpired;
#endif


  VMAllocMsg vmAlloc;
  VMAllocReplyMsg vmAllocReply;
  VMFreeMsg vmFree;
  VMFreeReplyMsg vmFreeReply;
  VMMoveMsg vmMove;
  VMMoveReplyMsg vmMoveReply;
  VMProtectMsg vmProtect;
  VMProtectReplyMsg vmProtectReply;
  VMCleanupMsg vmCleanup;

  IOOpenMsg ioOpen;
  IOOpenReplyMsg ioOpenReply;
  IOCloseMsg	ioClose;
  IOCloseReplyMsg ioCloseReply;
  IOLoadReplyMsg ioLoadReply;
  IOReadMsg ioRead;
  IOReadReplyMsg ioReadReply;
  IOWriteMsg ioWrite;
  IOWriteReplyMsg ioWriteReply;
  IOInitReplyMsg ioInitReply;
  IOTimerMsg ioTimer;

  IOSubscribeMsg ioSubscribe;
  IOSubscribeReplyMsg ioSubscribeReply;
  IOUnSubscribeMsg ioUnSubscribe;
  IOUnSubscribeReplyMsg ioUnSubscribeReply;
  IONotifyMsg ioNotify;
  IOGetAddrReplyMsg ioGetAddrReply;

  NETQueueMsg netqMsg;
  NETChainGetMsg netChainGet;
  NETARPReqMsg netARPReq;
  NETARPReplyMsg netARPReply;
  NETARPAddMsg netARPAdd;

  NETConfigureMsg netConf;
  NETConfigureReplyMsg netConfReply;

  NETSocketConnectBind netSockBindConnect;

  NETSocketPortReply netSockPort;

  NETTftpGetCmd netTftpGet;
  NETTftpSizeReply netTftpSize;

  VMemoryRegionLookupMsg vm_lookup;
  VMemoryRegionAllocStackMsg vm_alloc_stack;
  VMemoryRegionGetMsg vm_get;
  VMemoryRegionFreeHintMsg vm_free_hint;
  VMemoryRegionFreeAllMsg vm_free_all;
  VMemoryRegionChProtMsg vm_chprot;
  VMemoryRegionResizeMsg vm_resize;
  VMemoryRegionShareMsg vm_share;
  VMemoryReplyMsg vm_reply;
  VMemoryMsgPage vm_msg_page;

  LDReplyMsg ld_reply;

  SyscallReply syscallReply;
} SpecMessage;

typedef struct Message_t
{		/* Main message structure */
  ThreadId		from;					/* Sender of the message (must be 1st elemnt in struct) */
  MessageId		id;						/* Type of the message (must be 2nd elemnt in struct) */
  ThreadId		to;						/* Sender of the message */
  address_t		enveloppe;		/* address of the envelope page */
  SpecMessage	msg;					/* Specific message contents */
}
Message;


#endif
