9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 742dda6b47d1621e44c450831d017d80dae060a9
parent 7e254b64801e42ff89392a157f1f1a822099ce1c
Author: Roberto E. Vargas Caballero <roberto.vargas@midokura.com>
Date:   Sat, 26 Nov 2022 11:21:12 +0100

os9: Add open() syscall

Open was added as a syscall as a proof of concept
where we can begin to test the full syscall path.

Diffstat:
Minclude/os9/os9.h | 13++++++++++++-
Msrc/os9/Makefile | 1+
Msrc/os9/arch/arm64/trap.c | 38+++++++++++++++++++++++++++++++++++---
Msrc/os9/dev/dev.c | 47-----------------------------------------------
Msrc/os9/dev/dev.h | 1-
Msrc/os9/dlang.c | 6+++---
Msrc/os9/sys.c | 6+++---
Asrc/os9/syscall.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 140 insertions(+), 58 deletions(-)

diff --git a/include/os9/os9.h b/include/os9/os9.h @@ -101,6 +101,11 @@ enum map_attr { MD = 1 << 3, }; +enum sysnumbers { + SYSOPEN, + NR_SYSCALLS, +}; + struct ref { mutex_t m; int cnt; @@ -193,6 +198,11 @@ struct rendez { Task *task; }; +struct syscall { + int nargs; + int (*fn)(int, ...); +}; + /** * @entry: Entry point for the task. * @prio: @@ -343,7 +353,7 @@ extern void idle(void); /* dev functions */ extern void idev(void); -extern Chan *chanopen(char *name, int mode); +extern Chan *namec(char *, int mode); extern int chanwrite(Chan *c, void *buf, int n); extern int chanread(Chan *c, void *buf, int n); extern int chanclose(Chan *c); @@ -359,6 +369,7 @@ extern Chan *console; extern Mach mach; extern char buffertab[NR_BUFFERS][PAGESIZE]; extern char bufto[], buffrom[]; +extern struct syscall systab[]; /* per cpu globals */ extern Task *proc; diff --git a/src/os9/Makefile b/src/os9/Makefile @@ -14,6 +14,7 @@ OBJS =\ map.o\ proc.o\ ref.o\ + syscall.o\ sys.o\ dev/builtin.o\ diff --git a/src/os9/arch/arm64/trap.c b/src/os9/arch/arm64/trap.c @@ -8,8 +8,30 @@ #include "arch.h" static void -svc(int numsvc) +syscall(Context *ctx) { + int nsys, r; + struct syscall *sys; + uintmax_t arg1, arg2, arg3, arg4; + + nsys = ctx->r[X0]; + if (nsys < 0 || nsys >= NR_SYSCALLS) { + kprint("trap: %llu: invalid syscall %d number\n", + ctx->r[X29], nsys); + seterrno(EINVAL); + return; + } + + arg1 = ctx->r[X1]; + arg2 = ctx->r[X2]; + arg3 = ctx->r[X3]; + arg4 = ctx->r[X4]; + + sys = systab[n]; + if (!sys->fn) + panic("null syscall entry"); + r = (*fn)(sys->narg, arg1, arg2, arg3, arg4); + setret(r); } void @@ -17,7 +39,7 @@ trap(Context *ctx) { enum ecvals ec; const char *msg; - int numsvc; + int numsvc, nsyscall; ec = (ctx->r[ESR] >> 26) & 0x3f; @@ -29,7 +51,17 @@ trap(Context *ctx) } numsvc = ctx->r[ESR] & 0xff; + if (numsvc == 0) { + syscall(ctx); + } else { + kprint("trap: %llu: invalid svc %d number\n", + ctx->r[X29], numsvc); + seterror(EINVAL); + setret(-1); + } + + ctx->r[X0] = proc->ret; + ctx->r[X1] = proc->errno; - svc(numsvc); swtch(ctx); } diff --git a/src/os9/dev/dev.c b/src/os9/dev/dev.c @@ -202,22 +202,6 @@ err: return NULL; } -static int -validmode(int mode) -{ - if ((mode & O_READ) && (mode & (O_WRITE | O_RDWR))) - goto err; - if ((mode & O_WRITE) && (mode & (O_READ | O_RDWR))) - goto err; - if ((mode & O_RDWR) && (mode & (O_READ | O_WRITE))) - goto err; - return 1; - -err: - seterror(EINVAL); - return 0; -} - static char * next(char *s, char *elem) { @@ -492,37 +476,6 @@ devgen(Chan *c, Dirtab *tab, int ntab, int n, Dir *dir) return 1; } -Chan * -chanopen(char *fname, int mode) -{ - if (!validmode(mode)) - return NULL; - return namec(fname, mode); -} - -int -open(char *fname, int mode) -{ - int fd; - Chan *c, **bp; - Fdset *fds = proc->fds; - - if ((c = chanopen(fname, mode)) == NULL) - return -1; - - lock(&fds->m); - for (bp = fds->fdset; bp < &fds->fdset[NR_CHANS]; ++bp) { - if (*bp == c) - break; - } - fd = (bp == &fds->fdset[NR_CHANS]) ? -1 : (bp - fds->fdset); - unlock(&fds->m); - - if (fd == -1) - panic("corrupted channel"); - return fd; -} - int chanclose(Chan *c) { diff --git a/src/os9/dev/dev.h b/src/os9/dev/dev.h @@ -40,7 +40,6 @@ struct attr { }; extern int sameqid(Qid q1, Qid qid2); -extern Chan *namec(char *name, int mode); extern Chan *clone(Chan *c, Chan *nc); extern Chan *attach(int id, int dev); extern int buf2chan(Chan *c, diff --git a/src/os9/dlang.c b/src/os9/dlang.c @@ -89,7 +89,7 @@ do_read(const struct cmd *cmd, struct args *args) Chan *c; char buf[100], *bp; - if ((c = chanopen(args->argv[1], O_READ)) == NULL) + if ((c = namec(args->argv[1], O_READ)) == NULL) goto err; ch = -1; @@ -123,7 +123,7 @@ do_ls(const struct cmd *cmd, struct args *args) Dir dentry; unsigned char buf[DIRLEN]; - if ((c = chanopen(args->argv[1], O_READ)) == NULL) + if ((c = namec(args->argv[1], O_READ)) == NULL) goto err; while ((n = chanread(c, buf, DIRLEN)) > 0) { @@ -149,7 +149,7 @@ do_write(const struct cmd *cmd, struct args *args) Chan *c; char *s, buffer[LINELEN]; - if ((c = chanopen(args->argv[1], O_WRITE)) == NULL) + if ((c = namec(args->argv[1], O_WRITE)) == NULL) goto err; offset = 0; diff --git a/src/os9/sys.c b/src/os9/sys.c @@ -12,7 +12,7 @@ Chan *console; static void icons(void) { - if ((console = chanopen("#c/raw", O_RDWR)) == NULL) + if ((console = namec("#c/raw", O_RDWR)) == NULL) panic("icons:#c/raw open"); } @@ -29,7 +29,7 @@ writeline(char *line) *p++ = '\0'; data = p; - if ((c = chanopen(file, O_WRITE)) < 0) + if ((c = namec(file, O_WRITE)) < 0) panic("writeline:open"); if (chanwrite(c, data, strlen(data)) < 0) panic("writeline:write"); @@ -78,7 +78,7 @@ iconf(void) NULL }, *bp; - if ((c = chanopen("/blobs/conf", O_READ)) == NULL) { + if ((c = namec("/blobs/conf", O_READ)) == NULL) { kprint("missed kernel namespace configuration\n"); return; } diff --git a/src/os9/syscall.c b/src/os9/syscall.c @@ -0,0 +1,86 @@ +#include <os9/os9.h> + +#include <stdarg.h> +#include <errno.h> + +#include "version.h" + + +static int +validmode(int mode) +{ + if ((mode & O_READ) && (mode & (O_WRITE | O_RDWR))) + goto err; + if ((mode & O_WRITE) && (mode & (O_READ | O_RDWR))) + goto err; + if ((mode & O_RDWR) && (mode & (O_READ | O_WRITE))) + goto err; + if (mode == 0) + goto err; + return 1; + +err: + seterror(EINVAL); + return 0; +} + +static int +newfd(Chan *c, int mode) +{ + int fd; + Chan **bp; + Fdset *fds = proc->fds; + + lock(&fds->m); + for (bp = fds->fdset; bp < &fds->fdset[NR_CHANS]; ++bp) { + if (*bp == c) + break; + } + if (bp == &fds->fdset[NR_CHANS]) { + seterror(EMFILE); + unlock(&fds->m); + return -1; + } + + fd = bp - fds->fdset; + fds->fdset[fd] = c; + unlock(&fds->m); + + return fd; +} + +static int +validaddr(void *addr, int len, int write) +{ + /* TODO */ + return 1; +} + +static int +sysopen(int nargs, ...) +{ + char *fname; + int mode, flags, fd; + va_list va; + Chan *c; + + va_start(va, nargs); + fname = (char *) va_arg(va, uintptr_t); + mode = va_arg(va, uintptr_t); + flags = va_arg(va, uintptr_t); + va_end(va); + + if (!validmode(mode)) + return -1; + if (!validaddr(fname, 1, 0)) + return -1; + if ((c = namec(fname, mode)) == NULL) + return -1; + if ((fd = newfd(c, mode)) < 0) + return -1; + return fd; +} + +struct syscall systab[] = { + [SYSOPEN] = 3, sysopen, +};