matos/core/syscall.c

119 lines
3.5 KiB
C
Raw Permalink Normal View History

2021-11-08 22:31:57 +01:00
#include "syscall.h"
2021-11-06 00:13:40 +01:00
#include "keyboard.h"
2021-11-02 21:57:57 +01:00
#include "klibc.h"
2022-08-09 16:15:00 +02:00
#include "process.h"
2021-11-02 21:57:57 +01:00
#include "stdarg.h"
#include "thread.h"
2022-08-09 16:15:00 +02:00
#include "types.h"
2023-03-24 23:43:09 +01:00
#include "uaccess.h"
2022-08-09 16:15:00 +02:00
#include "uaddrspace.h"
2023-11-10 09:01:55 +01:00
#include "zero.h"
2021-11-02 21:57:57 +01:00
2021-11-08 22:31:57 +01:00
int syscallExecute(int syscallId, const struct cpu_state *userCtx)
{
2021-11-02 21:57:57 +01:00
int ret = 0;
2021-11-02 21:57:57 +01:00
switch (syscallId) {
2021-11-08 22:31:57 +01:00
case SYSCALL_ID_EXIT: {
2021-11-02 21:57:57 +01:00
uint status;
2021-11-05 23:02:23 +01:00
ret = syscallGet1arg(userCtx, &status);
2021-11-08 22:31:57 +01:00
if (ret != 0)
2021-11-02 21:57:57 +01:00
break;
threadExit();
assert(0);
break;
2021-11-08 22:31:57 +01:00
}
2023-11-11 00:07:26 +01:00
case SYSCALL_ID_HELO:
ret = printf("HELLO FROM USERSPACE\n");
2021-11-02 21:57:57 +01:00
break;
2021-11-08 22:31:57 +01:00
case SYSCALL_ID_PUTC: {
2021-11-05 23:02:23 +01:00
unsigned int c;
ret = syscallGet1arg(userCtx, &c);
putc(c);
break;
2021-11-08 22:31:57 +01:00
}
2021-11-06 00:13:40 +01:00
case SYSCALL_ID_READ:
ret = keyboardRead();
break;
case SYSCALL_ID_TEST: {
unsigned int arg1, arg2, arg3, arg4, arg5;
ret = syscallGet5args(userCtx, &arg1, &arg2, &arg3, &arg4, &arg5);
printf("Got 5args from userspace %d %d %d %d %d\n", arg1, arg2, arg3, arg4, arg5);
break;
}
2022-08-09 16:15:00 +02:00
case SYSCALL_ID_BRK:{
struct uAddrSpace *as;
uaddr_t newHeapTop;
as = processGetAddrSpace(getCurrentThread()->process);
ret = syscallGet1arg(userCtx, (unsigned int *)&newHeapTop);
if (ret != 0)
break;
threadChangeCurrentContext(uAddrSpaceGetMMUContext(as));
//TODO : what if *newHeapTop raise page fault?
ret = sysBrk(as, newHeapTop);
threadChangeCurrentContext(NULL);
break;
}
2023-03-24 23:43:09 +01:00
case SYSCALL_ID_MMAP: {
struct uAddrSpace *as;
uaddr_t uaddr;
uaddr_t uaddr_ptr;
2023-03-24 23:43:09 +01:00
size_t size;
uint32_t rights;
uint32_t flags;
uaddr_t userPath;
char path[256];
as = processGetAddrSpace(getCurrentThread()->process);
ret = syscallGet5args(userCtx, (unsigned int *)&uaddr_ptr, (unsigned int *)&size,
(unsigned int *)&rights, (unsigned int *)&flags,
(unsigned int *)&userPath);
if (ret)
break;
if (memcpyFromUser((vaddr_t)&uaddr, uaddr_ptr, sizeof(uaddr)) != sizeof(uaddr)) {
ret = -EFAULT;
break;
}
2023-03-24 23:43:09 +01:00
strzcpyFromUser((vaddr_t *)path, (uaddr_t *)userPath, sizeof(path));
printf("Trying mmap for device %s at %lu\n", path, (vaddr_t)uaddr);
if (strcmp(path, "/dev/zero") == 0) {
ret = zeroMmap(as, &uaddr, size, rights, flags);
2023-11-10 09:01:55 +01:00
}
if (!ret) {
if (memcpyToUser(uaddr_ptr, (vaddr_t)&uaddr, sizeof(uaddr)) != sizeof(uaddr)) {
ret = -EFAULT;
break;
}
}
2023-03-24 23:43:09 +01:00
break;
}
case SYSCALL_ID_MUNMAP: {
struct uAddrSpace *as;
uaddr_t uaddr;
size_t size;
ret = syscallGet2args(userCtx, (unsigned int *)&uaddr, (unsigned int *)&size);
if (ret)
break;
as = processGetAddrSpace(getCurrentThread()->process);
ret = uAddrSpaceUnmap(as, uaddr, size);
break;
}
2021-11-02 21:57:57 +01:00
default:
2021-11-08 22:31:57 +01:00
printf("Unknon syscall id %d\n", syscallId);
ret = -ENOENT;
2021-11-02 21:57:57 +01:00
}
return ret;
}