Lots of work on the AcessNative kernel
[tpg/acess2.git] / AcessNative / acesskernel_src / syscalls.c
1 /*
2  * Acess2 Native Kernel
3  * - Acess kernel emulation on another OS using SDL and UDP
4  *
5  * Syscall Server
6  */
7 #include <acess.h>
8 #include "../syscalls.h"
9
10 // === TYPES ===
11 typedef int     (*tSyscallHandler)(const char *Format, void *Args);
12
13 // === MACROS ===
14 #define SYSCALL3(_name, _call, _fmtstr, _t1, _t2, _t3) int _name(const char *fmt,void*args){\
15         _t1 a1;_t2 a2;_t3 a3;\
16         if(strcmp(fmt,_fmtstr)!=0)return 0;\
17         a1 = *(_t1*)args;args+=sizeof(_t1);\
18         a2 = *(_t2*)args;args+=sizeof(_t2);\
19         a3 = *(_t3*)args;args+=sizeof(_t3);\
20         return _call(a1,a2,a3);\
21 }
22
23 #define SYSCALL2(_name, _call, _fmtstr, _t1, _t2) int _name(const char *fmt,void*args){\
24         _t1 a1;_t2 a2;\
25         if(strcmp(fmt,_fmtstr)!=0)return 0;\
26         a1 = *(_t1*)args;args+=sizeof(_t1);\
27         a2 = *(_t2*)args;args+=sizeof(_t2);\
28         return _call(a1,a2);\
29 }
30
31 #define SYSCALL1V(_name, _call, _fmtstr, _t1) int _name(const char *fmt, void*args){\
32         _t1 a1;\
33         if(strcmp(fmt,_fmtstr)!=0)return 0;\
34         a1 = *(_t1*)args;args+=sizeof(_t1);\
35         _call(a1);\
36         return 0;\
37 }
38
39 // === CODE ===
40 int Syscall_Null(const char *Format, void *Args)
41 {
42         return 0;
43 }
44
45 SYSCALL2(Syscall_Open, VFS_Open, "di", const char *, int);
46 SYSCALL1V(Syscall_Close, VFS_Close, "i", int);
47 SYSCALL3(Syscall_Read, VFS_Read, "iid", int, int, void *);
48 SYSCALL3(Syscall_Write, VFS_Write, "iid", int, int, const void *);
49
50
51 const tSyscallHandler   caSyscalls[] = {
52         Syscall_Null,
53         Syscall_Open,
54         Syscall_Close,
55         Syscall_Read,
56         Syscall_Write
57 };
58 const int       ciNumSyscalls = sizeof(caSyscalls)/sizeof(caSyscalls[0]);
59 /**
60  * \brief Recieve a syscall structure from the server code
61  */
62 tRequestHeader *SyscallRecieve(tRequestHeader *Request)
63 {
64         char    formatString[Request->NParams+1];
65         char    *inData = (char*)&Request->Params[Request->NParams+Request->NReturn];
66          int    argListLen = 0;
67          int    i, retVal;
68         
69         if( Request->CallID > ciNumSyscalls ) {
70                 return NULL;
71         }
72         
73         // Get size of argument list
74         for( i = 0; i < Request->NParams; i ++ )
75         {
76                 switch(Request->Params[i].Type)
77                 {
78                 case ARG_TYPE_VOID:
79                         formatString[i] = '-';
80                         break;
81                 case ARG_TYPE_INT32:
82                         formatString[i] = 'i';
83                         argListLen += sizeof(Uint32);
84                         break;
85                 case ARG_TYPE_INT64:
86                         formatString[i] = 'I';
87                         argListLen += sizeof(Uint64);
88                         break;
89                 case ARG_TYPE_DATA:
90                         formatString[i] = 'd';
91                         argListLen += sizeof(void*);
92                         break;
93                 default:
94                         return NULL;    // ERROR!
95                 }
96         }
97         
98         {
99                 char    argListData[argListLen];
100                 argListLen = 0;
101                 // Build argument list
102                 for( i = 0; i < Request->NParams; i ++ )
103                 {
104                         switch(Request->Params[i].Type)
105                         {
106                         case ARG_TYPE_VOID:
107                                 break;
108                         case ARG_TYPE_INT32:
109                                 *(Uint32*)&argListData[argListLen] = *(Uint32*)inData;
110                                 argListLen += sizeof(Uint32);
111                                 inData += sizeof(Uint32);
112                                 break;
113                         case ARG_TYPE_INT64:
114                                 *(Uint64*)&argListData[argListLen] = *(Uint64*)inData;
115                                 argListLen += sizeof(Uint64);
116                                 inData += sizeof(Uint64);
117                                 break;
118                         case ARG_TYPE_DATA:
119                         case ARG_TYPE_STRING:
120                                 *(void**)&argListData[argListLen] = *(void**)inData;
121                                 argListLen += sizeof(void*);
122                                 inData += sizeof(void*);
123                                 break;
124                         }
125                 }
126                 
127                 retVal = caSyscalls[Request->CallID](formatString, argListData);
128         }
129         
130         return NULL;
131 }

UCC git Repository :: git.ucc.asn.au