3 #include "../../Usermode/include/acess/sys.h"
11 #include "../syscalls.h"
18 const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const char *ArgTypes, va_list *Args)
22 int direction = 0; // 0: Invalid, 1: Out, 2: In, 3: Out
27 while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++;
28 if( *ArgTypes == '\0' ) return ArgTypes;
33 default: // Defaults to output
34 case '>': direction = 1; break;
35 case '<': direction = 2; break;
36 case '?': direction = 3; break;
41 while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++;
42 if( *ArgTypes == '\0' ) return ArgTypes;
50 if( direction != 1 ) {
51 fprintf(stderr, "ReadEntry: Recieving an integer is not defined\n");
55 val32 = va_arg(*Args, uint32_t);
56 printf("val32 = 0x%x\n", val32);
58 Dest->Type = ARG_TYPE_INT32;
59 Dest->Length = sizeof(uint32_t);
63 *(uint32_t*)DataDest = val32;
68 if( direction != 1 ) {
69 fprintf(stderr, "ReadEntry: Recieving an integer is not defined\n");
73 val64 = va_arg(*Args, uint64_t);
74 printf("val64 = 0x%llx\n", val64);
76 Dest->Type = ARG_TYPE_INT64;
77 Dest->Length = sizeof(uint64_t);
80 *(uint64_t*)DataDest = val64;
84 // Input string makes no sense!
85 if( direction != 1 ) {
86 fprintf(stderr, "ReadEntry: Recieving a string is not defined\n");
90 str = va_arg(*Args, char*);
91 printf("str = %p '%s'\n", str, str);
93 Dest->Type = ARG_TYPE_STRING;
94 Dest->Length = strlen(str) + 1;
99 memcpy(DataDest, str, Dest->Length);
102 // Data (special handling)
104 len = va_arg(*Args, int);
105 str = va_arg(*Args, char*);
107 printf("len = %i, str = %p\n", len, str);
109 // Save the pointer for later
110 if( PtrDest ) *PtrDest = str;
112 // Create parameter block
113 Dest->Type = ARG_TYPE_DATA;
117 Dest->Flags |= ARG_FLAG_RETURN;
123 memcpy(DataDest, str, len);
126 Dest->Flags |= ARG_FLAG_ZEROED;
140 * Whitespace is ignored
141 * >i: Input Integer (32-bits)
142 * >I: Input Long Integer (64-bits)
144 * >d: Input Buffer (Preceded by valid size)
145 * <I: Output long integer
146 * <d: Output Buffer (Preceded by valid size)
147 * ?d: Bi-directional buffer (Preceded by valid size), buffer contents
150 uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
153 int paramCount, dataLength;
154 int retCount = 1, retLength = sizeof(uint64_t);
155 void **retPtrs; // Pointers to return buffers
163 va_start(args, ArgTypes);
169 tRequestValue tmpVal;
171 str = ReadEntry(&tmpVal, NULL, NULL, str, &args);
173 fprintf(stderr, "syscalls.c: ReadEntry failed (SyscallID = %i)\n", SyscallID);
177 if( !(tmpVal.Flags & ARG_FLAG_ZEROED) )
178 dataLength += tmpVal.Length;
180 if( tmpVal.Flags & ARG_FLAG_RETURN ) {
181 retLength += tmpVal.Length;
187 dataLength += sizeof(tRequestHeader) + paramCount*sizeof(tRequestValue);
188 retLength += sizeof(tRequestHeader) + retCount*sizeof(tRequestValue);
191 retPtrs = malloc( sizeof(void*) * (retCount+1) );
192 if( dataLength > retLength)
193 req = malloc( dataLength );
195 req = malloc( retLength );
196 req->ClientID = 0; //< Filled later
197 req->CallID = SyscallID;
198 req->NParams = paramCount;
199 dataPtr = &req->Params[paramCount];
201 // Fill `output` and `input`
202 va_start(args, ArgTypes);
204 // - re-zero so they can be used as indicies
209 str = ReadEntry(&req->Params[paramCount], dataPtr, &retPtrs[retCount], str, &args);
212 if( !(req->Params[paramCount].Flags & ARG_FLAG_ZEROED) )
213 dataPtr += req->Params[paramCount].Length;
214 if( req->Params[paramCount].Flags & ARG_FLAG_RETURN )
221 // Send syscall request
222 if( SendRequest(req, dataLength) < 0 ) {
223 fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID);
227 // Parse return value
228 dataPtr = &req->Params[req->NParams];
230 if( req->NParams > 1 )
232 switch(req->Params[0].Type)
235 retValue = *(uint64_t*)dataPtr;
236 dataPtr += req->Params[0].Length;
239 retValue = *(uint32_t*)dataPtr;
240 dataPtr += req->Params[0].Length;
245 // Write changes to buffers
246 va_start(args, ArgTypes);
247 for( i = 1; i < req->NParams; i ++ )
249 memcpy( retPtrs[i-1], dataPtr, req->Params[i].Length );
250 dataPtr += req->Params[i].Length;
260 int open(const char *Path, int Flags) {
261 return _Syscall(SYS_OPEN, ">s >i", Path, Flags);
265 _Syscall(SYS_CLOSE, ">i", FD);
268 int reopen(int FD, const char *Path, int Flags) {
269 return _Syscall(SYS_REOPEN, ">i >s >i", FD, Path, Flags);
272 size_t read(int FD, size_t Bytes, void *Dest) {
273 return _Syscall(SYS_READ, "<i >i >i <d", FD, Bytes, Bytes, Dest);
276 size_t write(int FD, size_t Bytes, void *Src) {
277 return _Syscall(SYS_WRITE, ">i >i >d", FD, Bytes, Bytes, Src);
280 int seek(int FD, int64_t Ofs, int Dir) {
281 return _Syscall(SYS_SEEK, ">i >I >i", FD, Ofs, Dir);
284 uint64_t tell(int FD) {
285 return _Syscall(SYS_TELL, ">i", FD);
288 int ioctl(int fd, int id, void *data) {
289 // NOTE: 1024 byte size is a hack
290 return _Syscall(SYS_IOCTL, ">i >i ?d", fd, id, 1024, data);
292 int finfo(int fd, t_sysFInfo *info, int maxacls) {
293 return _Syscall(SYS_FINFO, ">i <d >i",
295 sizeof(t_sysFInfo)+maxacls*sizeof(t_sysACL), info,
299 int readdir(int fd, char *dest) {
300 return _Syscall(SYS_READDIR, ">i <d", fd, 256, dest);
303 int _SysOpenChild(int fd, char *name, int flags) {
304 return _Syscall(SYS_OPENCHILD, ">i >s >i", fd, name, flags);
307 int _SysGetACL(int fd, t_sysACL *dest) {
308 return _Syscall(SYS_GETACL, "<i >i <d", fd, sizeof(t_sysACL), dest);
311 int _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
312 return _Syscall(SYS_MOUNT, ">s >s >s >s", Device, Directory, Type, Options);
317 int _SysSetFaultHandler(int (*Handler)(int)) {
321 // --- Memory Management ---
322 uint64_t _SysAllocate(uint vaddr)
324 if( AllocateMemory(vaddr, 0x1000) == -1 ) // Allocate a page
326 return vaddr; // Just ignore the need for paddrs :)
330 // === Symbol List ===
331 #define DEFSYM(name) {#name, name}
332 const tSym caBuiltinSymbols[] = {
345 DEFSYM(_SysOpenChild),
349 DEFSYM(_SysAllocate),
351 {"_SysSetFaultHandler", _SysSetFaultHandler}
354 const int ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]);