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

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