8e02c5dec558a9dc43cb1b456410e975dc483147
[tpg/acess2.git] / Kernel / syscalls.c
1 /*
2  * AcessOS Microkernel Version
3  * syscalls.c
4  */
5 #define DEBUG   0
6
7 #include <common.h>
8 #include <syscalls.h>
9 #include <proc.h>
10 #include <errno.h>
11
12 // === IMPORTS ===
13 extern int      Proc_Clone(Uint *Err, Uint Flags);
14 extern Uint     Proc_SendMessage(Uint *Err, Uint Dest, Uint Length, void *Data);
15 extern int      Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer);
16 extern int      Proc_Execve(char *File, char **ArgV, char **EnvP);
17 extern Uint     Binary_Load(char *file, Uint *entryPoint);
18 extern int      VFS_FInfo(int FD, void *Dest, int MaxACLs);
19
20 // === CODE ===
21 void SyscallHandler(tSyscallRegs *Regs)
22 {
23         Uint64  ret = 0;
24         Uint    err = 0;
25         #if DEBUG
26         ENTER("iThread iNum", gCurrentThread->TID, Regs->Num);
27         if(Regs->Num < NUM_SYSCALLS)
28                 LOG("Syscall %s", cSYSCALL_NAMES[Regs->Num]);
29         LOG("Arg1: 0x%x, Arg2: 0x%x, Arg3: 0x%x", Regs->Arg1, Regs->Arg2, Regs->Arg3);
30         #endif
31         switch(Regs->Num)
32         {
33         // -- Exit the current thread
34         case SYS_EXIT:  Proc_Exit();    break;
35         
36         // -- Put the current thread to sleep
37         case SYS_SLEEP: Proc_Sleep();   Log(" SyscallHandler: %i is alive", gCurrentThread->TID);       break;
38         
39         // -- Yield current timeslice
40         case SYS_YIELD: Proc_Yield();   break;
41         
42         // -- Clone the current thread
43         case SYS_CLONE:
44                 // Call clone system call
45                 ret = Proc_Clone(&err, Regs->Arg1);
46                 // Change user stack if requested
47                 if(ret == 0 && Regs->Arg2)
48                         Regs->StackPointer = Regs->Arg2;
49                 break;
50         
51         // -- Send a signal
52         case SYS_KILL:
53                 err = -ENOSYS;
54                 ret = -1;
55                 break;
56         
57         case SYS_GETPHYS:
58                 ret = MM_GetPhysAddr(Regs->Arg1);
59                 break;
60         // -- Map an address
61         case SYS_MAP:   MM_Map(Regs->Arg1, Regs->Arg2); break;
62         // -- Allocate an address
63         case SYS_ALLOCATE:      ret = MM_Allocate(Regs->Arg1);  break;
64         // -- Unmap an address
65         case SYS_UNMAP:         MM_Deallocate(Regs->Arg1);      break;
66         
67         // -- Get Thread/Process IDs
68         case SYS_GETTID:        ret = gCurrentThread->TID;      break;
69         case SYS_GETPID:        ret = gCurrentThread->TGID;     break;
70         // -- Get User/Group IDs
71         case SYS_GETUID:        ret = gCurrentThread->UID;      break;
72         case SYS_GETGID:        ret = gCurrentThread->GID;      break;
73         
74         // -- Send Message
75         case SYS_SENDMSG:
76                 ret = Proc_SendMessage(&err, Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3);
77                 break;
78         // -- Check for messages
79         case SYS_GETMSG:
80                 ret = Proc_GetMessage(&err, (Uint*)Regs->Arg1, (void*)Regs->Arg2);
81                 break;
82         
83         // -- Set the thread's name
84         case SYS_SETNAME:
85                 // Sanity Check
86                 if(!Regs->Arg1) {       ret = -1;       err = -EINVAL;  break;  }
87                 // Lock Process
88                 LOCK( &gCurrentThread->IsLocked );
89                 // Free old name
90                 if(gCurrentThread->ThreadName && (Uint)gCurrentThread->ThreadName > 0xE0800000)
91                         free(gCurrentThread->ThreadName);
92                 // Change name
93                 gCurrentThread->ThreadName = malloc( strlen( (char*)Regs->Arg1 ) + 1 );
94                 strcpy(gCurrentThread->ThreadName, (char*)Regs->Arg1);
95                 // Unlock
96                 RELEASE( &gCurrentThread->IsLocked );
97                 break;
98         
99         // ---
100         // Binary Control
101         // ---
102         case SYS_EXECVE:
103                 ret = Proc_Execve((char*)Regs->Arg1, (char**)Regs->Arg2, (char**)Regs->Arg3);
104                 break;
105         case SYS_LOADBIN:
106                 ret = Binary_Load((char*)Regs->Arg1, (Uint*)Regs->Arg2);
107                 break;
108         
109         // ---
110         // Virtual Filesystem
111         // ---
112         case SYS_OPEN:
113                 ret = VFS_Open((char*)Regs->Arg1, Regs->Arg2 | VFS_OPENFLAG_USER);
114                 break;
115         
116         case SYS_CLOSE:
117                 VFS_Close( Regs->Arg1 );
118                 break;
119         
120         case SYS_WRITE:
121                 #if BITS < 64
122                 VFS_Write( Regs->Arg1, Regs->Arg2|((Uint64)Regs->Arg3<<32), (void*)Regs->Arg4 );
123                 #else
124                 VFS_Write( Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3 );
125                 #endif
126                 break;
127         
128         case SYS_READ:
129                 #if BITS < 64
130                 VFS_Read( Regs->Arg1, Regs->Arg2|((Uint64)Regs->Arg3<<32), (void*)Regs->Arg4 );
131                 #else
132                 VFS_Read( Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3 );
133                 #endif
134                 break;
135         
136         case SYS_FINFO:
137                 ret = VFS_FInfo( Regs->Arg1, (void*)Regs->Arg2, Regs->Arg3 );
138                 break;
139         
140         // -- Debug
141         case SYS_DEBUG:
142                 Log((char*)Regs->Arg1,
143                         Regs->Arg2, Regs->Arg3, Regs->Arg4, Regs->Arg5, Regs->Arg6);
144                 break;
145         
146         // -- Default (Return Error)
147         default:
148                 Warning("SyscallHandler: Unknown System Call %i", Regs->Num);
149                 if(Regs->Num < NUM_SYSCALLS)
150                         Warning(" Syscall '%s'", cSYSCALL_NAMES[Regs->Num]);
151                 err = -ENOSYS;
152                 ret = -1;
153                 break;
154         }
155         #if BITS < 64
156         Regs->Return = ret&0xFFFFFFFF;
157         Regs->RetHi = ret >> 32;
158         #else
159         Regs->Return = ret;
160         #endif
161         Regs->Error = err;
162         #if DEBUG
163         LOG("SyscallHandler: err = %i", err);
164         LEAVE('x', ret);
165         #endif
166 }
167

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