diff --git a/kernel/dev/fbdev.c b/kernel/dev/fbdev.c index aafbdb0..7c1e4da 100644 --- a/kernel/dev/fbdev.c +++ b/kernel/dev/fbdev.c @@ -2,7 +2,7 @@ #include #include "fbdev.h" #include "dev.h" -#include "sysdefs/devctl.h" +#include "sysdefs/dev.h" #include "hshtb.h" #include "spinlock/spinlock.h" #include "util/util.h" diff --git a/kernel/dev/ps2kbdev.c b/kernel/dev/ps2kbdev.c index 6511df0..6366baa 100644 --- a/kernel/dev/ps2kbdev.c +++ b/kernel/dev/ps2kbdev.c @@ -8,7 +8,7 @@ #include "dlmalloc/malloc.h" #include "util/util.h" #include "hshtb.h" -#include "sysdefs/devctl.h" +#include "sysdefs/dev.h" #include "proc/proc.h" #define KB_CTL_STATUS 0x64 diff --git a/kernel/dev/serialdev.c b/kernel/dev/serialdev.c index d6f9680..136abce 100644 --- a/kernel/dev/serialdev.c +++ b/kernel/dev/serialdev.c @@ -5,7 +5,7 @@ #include "errors.h" #include "util/util.h" #include "hshtb.h" -#include "sysdefs/devctl.h" +#include "sysdefs/dev.h" #include "kprintf.h" #include "hal/hal.h" diff --git a/kernel/dev/termdev.c b/kernel/dev/termdev.c index 6b5be37..af761e8 100644 --- a/kernel/dev/termdev.c +++ b/kernel/dev/termdev.c @@ -7,7 +7,7 @@ #include "errors.h" #include "util/util.h" #include "hshtb.h" -#include "sysdefs/devctl.h" +#include "sysdefs/dev.h" int32_t termdev_putch(struct Dev *dev, uint8_t *buffer, size_t len, void *extra) { (void)dev; (void)extra; diff --git a/kernel/syscall/dev.c b/kernel/syscall/dev.c new file mode 100644 index 0000000..cf39918 --- /dev/null +++ b/kernel/syscall/dev.c @@ -0,0 +1,135 @@ +#include +#include +#include "kprintf.h" +#include "syscall.h" +#include "errors.h" +#include "spinlock/spinlock.h" +#include "proc/proc.h" +#include "sysdefs/dev.h" +#include "util/util.h" +#include "hshtb.h" +#include "dev/dev.h" + +int32_t SYSCALL2(sys_dev_gethandle, dev1, devname1) { + uint64_t *devh = (uint64_t *)dev1; + int32_t ret = E_OK; + + spinlock_acquire(&PROCS.spinlock); + Proc *proc = PROCS.current; + spinlock_release(&PROCS.spinlock); + + char *ident = (char *)devname1; + if (ident == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + + spinlock_acquire(&DEVTABLE.spinlock); + Dev *founddev; + HSHTB_GET(DEVTABLE.devs, ident, ident, founddev); + spinlock_release(&DEVTABLE.spinlock); + + if (founddev == NULL) { + ret = E_NOENTRY; + goto done; + } + + bool found = false; + for (size_t i = 0; i < PROC_DEVHANDLES_MAX; i++) { + if (proc->devs[i] == NULL) { + found = true; + proc->devs[i] = founddev; + *devh = i; + break; + } + } + + if (!found) { + ret = E_NOMEMORY; + goto done; + } + +done: + return ret; +} + +int32_t SYSCALL0(sys_dev_listsize) { + int32_t ret = E_OK; + + size_t n = 0; + spinlock_acquire(&DEVTABLE.spinlock); + for (size_t i = 0; i < LEN(DEVTABLE.devs); i++) { + if (DEVTABLE.devs[i]._hshtbstate == HSHTB_TAKEN) { + n++; + } + } + spinlock_release(&DEVTABLE.spinlock); + ret = n; + + return ret; +} + +int32_t SYSCALL2(sys_dev_stat, devstat1, idx1) { + int32_t ret = E_OK; + + DevStat *devstat = (DevStat *)devstat1; + size_t idx = (size_t)idx1; + + if (devstat == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + + devstat->present = false; + + spinlock_acquire(&DEVTABLE.spinlock); + for (size_t i = 0; i < LEN(DEVTABLE.devs); i++) { + if (i == idx && DEVTABLE.devs[i]._hshtbstate == HSHTB_TAKEN) { + Dev *dev = &DEVTABLE.devs[i]; + hal_memcpy(devstat->name, dev->ident, sizeof(dev->ident)); + for (size_t j = 0; j < DEV_FNS_MAX; j++) { + if (dev->fns[j] != NULL) { + devstat->nfns++; + } + } + devstat->present = true; + break; + } + } + spinlock_release(&DEVTABLE.spinlock); + +done: + return ret; +} + +int32_t SYSCALL5(sys_dev_cmd, dev1, cmd1, argbuf1, len1, extra1) { + uint64_t *devh = (uint64_t *)dev1; + uint64_t cmd = cmd1; + int32_t ret = E_OK; + + spinlock_acquire(&PROCS.spinlock); + Proc *proc = PROCS.current; + spinlock_release(&PROCS.spinlock); + + if (devh == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + + if (cmd >= DEV_FNS_MAX) { + ret = E_INVALIDARGUMENT; + goto done; + } + + Dev *dev = proc->devs[*devh]; + if (dev == NULL) { + ret = E_NOENTRY; + goto done; + } + spinlock_acquire(&dev->spinlock); + ret = dev->fns[cmd](dev, (uint8_t *)argbuf1, (size_t)len1, (void *)extra1); + spinlock_release(&dev->spinlock); + +done: + return ret; +} diff --git a/kernel/syscall/dev.h b/kernel/syscall/dev.h new file mode 100644 index 0000000..07abd16 --- /dev/null +++ b/kernel/syscall/dev.h @@ -0,0 +1,13 @@ +#ifndef SYSCALL_DEV_H_ +#define SYSCALL_DEV_H_ + +#include +#include +#include "syscall.h" + +int32_t SYSCALL2(sys_dev_gethandle, dev1, devname1); +int32_t SYSCALL0(sys_dev_listsize); +int32_t SYSCALL2(sys_dev_stat, devstat1, idx1); +int32_t SYSCALL5(sys_dev_cmd, dev1, cmd1, argbuf1, len1, extra1); + +#endif // SYSCALL_DEV_H_ diff --git a/kernel/syscall/devctl.c b/kernel/syscall/devctl.c deleted file mode 100644 index db7f208..0000000 --- a/kernel/syscall/devctl.c +++ /dev/null @@ -1,117 +0,0 @@ -#include -#include -#include "kprintf.h" -#include "syscall.h" -#include "errors.h" -#include "spinlock/spinlock.h" -#include "proc/proc.h" -#include "sysdefs/devctl.h" -#include "util/util.h" -#include "hshtb.h" -#include "dev/dev.h" - -int32_t SYSCALL5(sys_devctl, devh1, cmd1, buffer1, len1, extra1) { - uint64_t *devh = (uint64_t *)devh1; - uint64_t cmd = cmd1; - int32_t ret = E_OK; - - spinlock_acquire(&PROCS.spinlock); - Proc *proc = PROCS.current; - spinlock_release(&PROCS.spinlock); - - switch (cmd) { - case DEVCTL_GET_HANDLE: { - char *ident = (char *)buffer1; - if (ident == NULL) { - ret = E_INVALIDARGUMENT; - goto done; - } - - spinlock_acquire(&DEVTABLE.spinlock); - Dev *founddev; - HSHTB_GET(DEVTABLE.devs, ident, ident, founddev); - spinlock_release(&DEVTABLE.spinlock); - - if (founddev == NULL) { - ret = E_NOENTRY; - goto done; - } - - bool found = false; - for (size_t i = 0; i < PROC_DEVHANDLES_MAX; i++) { - if (proc->devs[i] == NULL) { - found = true; - proc->devs[i] = founddev; - *devh = i; - break; - } - } - - if (!found) { - ret = E_NOMEMORY; - goto done; - } - } break; - case DEVCTL_DEVLS_SZ: { - size_t n = 0; - spinlock_acquire(&DEVTABLE.spinlock); - for (size_t i = 0; i < LEN(DEVTABLE.devs); i++) { - if (DEVTABLE.devs[i]._hshtbstate == HSHTB_TAKEN) { - n++; - } - } - spinlock_release(&DEVTABLE.spinlock); - ret = n; - } break; - case DEVCTL_DEVLS_STAT: { - DevStat *devstat = (DevStat *)buffer1; - size_t idx = (size_t)len1; - - if (devstat == NULL) { - ret = E_INVALIDARGUMENT; - goto done; - } - - devstat->present = false; - - spinlock_acquire(&DEVTABLE.spinlock); - for (size_t i = 0; i < LEN(DEVTABLE.devs); i++) { - if (i == idx && DEVTABLE.devs[i]._hshtbstate == HSHTB_TAKEN) { - Dev *dev = &DEVTABLE.devs[i]; - hal_memcpy(devstat->name, dev->ident, sizeof(dev->ident)); - for (size_t j = 0; j < DEV_FNS_MAX; j++) { - if (dev->fns[j] != NULL) { - devstat->nfns++; - } - } - devstat->present = true; - break; - } - } - spinlock_release(&DEVTABLE.spinlock); - } break; - default: { - if (devh == NULL) { - ret = E_INVALIDARGUMENT; - goto done; - } - - if (cmd >= DEV_FNS_MAX) { - ret = E_INVALIDARGUMENT; - goto done; - } - - Dev *dev = proc->devs[*devh]; - if (dev == NULL) { - ret = E_NOENTRY; - goto done; - } - spinlock_acquire(&dev->spinlock); - ret = dev->fns[cmd](dev, (uint8_t *)buffer1, (size_t)len1, (void *)extra1); - spinlock_release(&dev->spinlock); - } break; - } - -done: - return ret; -} diff --git a/kernel/syscall/devctl.h b/kernel/syscall/devctl.h deleted file mode 100644 index 2df1e91..0000000 --- a/kernel/syscall/devctl.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef SYSCALL_DEVCTL_H_ -#define SYSCALL_DEVCTL_H_ - -#include -#include "syscall.h" -#include "dev/dev.h" - -int32_t SYSCALL5(sys_devctl, devh1, cmd1, buffer1, len1, extra1); - -#endif // SYSCALL_DEVCTL_H_ diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index d4e12b4..77e4f31 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -6,11 +6,11 @@ #include "ipcpipe.h" #include "mman.h" #include "sched.h" -#include "devctl.h" #include "randcrypto.h" #include "vfs.h" #include "proc.h" #include "fs.h" +#include "dev.h" int32_t SYSCALL1(sys_debugprint, string) { char *p = (char *)string; @@ -23,7 +23,6 @@ SyscallFn SYSCALL_TABLE[SYSCALLS_MAX] = { [SYS_MMAN_MAP] = &sys_mman_map, [SYS_MMAN_UNMAP] = &sys_mman_unmap, [SYS_SCHEDRELEASE] = &sys_schedrelease, - [SYS_DEVCTL] = &sys_devctl, [SYS_RAND] = &sys_rand, [SYS_VFSMOUNT] = &sys_vfsmount, [SYS_VFSUNMOUNT] = &sys_vfsunmount, @@ -48,4 +47,8 @@ SyscallFn SYSCALL_TABLE[SYSCALLS_MAX] = { [SYS_FS_STAT] = &sys_fs_stat, [SYS_FS_FETCHDIRENT] = &sys_fs_fetchdirent, [SYS_FS_MKDIR] = &sys_fs_mkdir, + [SYS_DEV_GETHANDLE] = &sys_dev_gethandle, + [SYS_DEV_LISTSIZE] = &sys_dev_listsize, + [SYS_DEV_STAT] = &sys_dev_stat, + [SYS_DEV_CMD] = &sys_dev_cmd, }; diff --git a/kernel/syscall/vfs.c b/kernel/syscall/vfs.c index 09e9150..5bdb426 100644 --- a/kernel/syscall/vfs.c +++ b/kernel/syscall/vfs.c @@ -5,7 +5,7 @@ #include "syscall.h" #include "vfs.h" #include "errors.h" -#include "sysdefs/devctl.h" +#include "sysdefs/dev.h" #include "vfs/vfs.h" #include "spinlock/spinlock.h" #include "dev/dev.h" diff --git a/share/sysdefs/devctl.h b/share/sysdefs/dev.h similarity index 67% rename from share/sysdefs/devctl.h rename to share/sysdefs/dev.h index f579d4f..7351098 100644 --- a/share/sysdefs/devctl.h +++ b/share/sysdefs/dev.h @@ -1,9 +1,5 @@ -#ifndef SHARE_SYSDEFS_DEVCTL_H_ -#define SHARE_SYSDEFS_DEVCTL_H_ - -#define DEVCTL_GET_HANDLE 100 -#define DEVCTL_DEVLS_SZ 101 -#define DEVCTL_DEVLS_STAT 102 +#ifndef SHARE_SYSDEFS_DEV_H_ +#define SHARE_SYSDEFS_DEV_H_ #define DEV_TERMDEV_PUTCH 0 @@ -17,8 +13,6 @@ #define DEV_FBDEV_GETINFO 0 -#if !defined(__ASSEMBLER__) - typedef uint64_t Dev_t; typedef struct { @@ -33,6 +27,4 @@ typedef struct { size_t nfns; } DevStat; -#endif - -#endif // SHARE_SYSDEFS_DEVCTL_H_ +#endif // SHARE_SYSDEFS_DEV_H_ diff --git a/share/sysdefs/syscall.h b/share/sysdefs/syscall.h index a7bee19..7b7e936 100644 --- a/share/sysdefs/syscall.h +++ b/share/sysdefs/syscall.h @@ -6,7 +6,6 @@ #define SYS_MMAN_MAP 5 #define SYS_MMAN_UNMAP 6 #define SYS_SCHEDRELEASE 7 -#define SYS_DEVCTL 8 #define SYS_RAND 9 #define SYS_VFSMOUNT 10 #define SYS_VFSUNMOUNT 11 @@ -31,6 +30,10 @@ #define SYS_FS_WRITE 30 #define SYS_FS_FETCHDIRENT 31 #define SYS_FS_MKDIR 32 +#define SYS_DEV_GETHANDLE 33 +#define SYS_DEV_LISTSIZE 34 +#define SYS_DEV_STAT 35 +#define SYS_DEV_CMD 36 #endif // SHARE_HDRS_SYSCALL_H_ diff --git a/ulib/system/system.c b/ulib/system/system.c index 0610d3b..e739d8e 100644 --- a/ulib/system/system.c +++ b/ulib/system/system.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include void debugprint(const char *string) { @@ -23,10 +23,6 @@ int32_t schedrelease(void) { return syscall(SYS_SCHEDRELEASE, 0, 0, 0, 0, 0, 0); } -int32_t devctl(Dev_t *devh, uint64_t cmd, uint8_t *buffer, size_t len, uint64_t extra) { - return syscall(SYS_DEVCTL, (uint64_t)devh, cmd, (uint64_t)buffer, (uint64_t)len, (uint64_t)extra, 0); -} - int32_t rand(void) { return syscall(SYS_RAND, 0, 0, 0, 0, 0, 0); } @@ -122,3 +118,19 @@ int32_t fs_fetchdirent(char *path, FsDirent *direntbuf, size_t idx) { int32_t fs_mkdir(char *path) { return syscall(SYS_FS_MKDIR, (uint64_t)path, 0, 0, 0, 0, 0); } + +int32_t dev_gethandle(Dev_t *dev, char *name) { + return syscall(SYS_DEV_GETHANDLE, (uint64_t)dev, (uint64_t)name, 0, 0, 0, 0); +} + +int32_t dev_listsize(void) { + return syscall(SYS_DEV_LISTSIZE, 0, 0, 0, 0, 0, 0); +} + +int32_t dev_stat(DevStat *devstatbuf, size_t idx) { + return syscall(SYS_DEV_STAT, (uint64_t)devstatbuf, (uint64_t)idx, 0, 0, 0, 0); +} + +int32_t dev_cmd(Dev_t *dev, uint64_t cmd, void *buf, size_t len, void *extra) { + return syscall(SYS_DEV_CMD, (uint64_t)dev, (uint64_t)cmd, (uint64_t)buf, (uint64_t)len, (uint64_t)extra, 0); +} diff --git a/ulib/system/system.h b/ulib/system/system.h index aa328e5..f0e2a9b 100644 --- a/ulib/system/system.h +++ b/ulib/system/system.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -12,7 +12,6 @@ void debugprint(const char *string); int32_t mman_map(uint8_t *addr, size_t size, uint64_t prot, uint64_t flags, uint8_t **out); int32_t mman_unmap(uint8_t *addr); int32_t schedrelease(void); -int32_t devctl(Dev_t *devh, uint64_t cmd, uint8_t *buffer, size_t len, uint64_t extra); int32_t rand(void); int32_t vfsmount(char *mountpoint, char *fstype, Dev_t *dev, bool format); int32_t vfsunmount(char *mountpoint); @@ -37,5 +36,9 @@ int32_t fs_read(int32_t fsh, uint8_t *const buffer, size_t len, size_t off); int32_t fs_stat(char *path, FsStat *statbuf); int32_t fs_fetchdirent(char *path, FsDirent *direntbuf, size_t idx); int32_t fs_mkdir(char *path); +int32_t dev_gethandle(Dev_t *dev, char *name); +int32_t dev_listsize(void); +int32_t dev_stat(DevStat *devstatbuf, size_t idx); +int32_t dev_cmd(Dev_t *dev, uint64_t cmd, void *buf, size_t len, void *extra); #endif // ULIB_SYSTEM_SYSTEM_H_ diff --git a/ulib/ulib.h b/ulib/ulib.h index 1199d11..d51cef7 100644 --- a/ulib/ulib.h +++ b/ulib/ulib.h @@ -21,6 +21,7 @@ #include #include +#include #include #include #include diff --git a/user/dev/ls.c b/user/dev/ls.c index 9471134..9bc2a7e 100644 --- a/user/dev/ls.c +++ b/user/dev/ls.c @@ -3,14 +3,14 @@ #include void dev_ls(void) { - size_t ndevs = devctl(NULL, DEVCTL_DEVLS_SZ, NULL, 0, 0); + size_t ndevs = dev_listsize(); uprintf("TOTAL: %zu\n", ndevs); uprintf("%-20s %-10s\n", "DEVICE", "FUNCTIONS"); for (size_t i = 0; i < 0x100; i++) { DevStat devstat; ZERO(&devstat); - devctl(NULL, DEVCTL_DEVLS_STAT, (uint8_t *)&devstat, i, 0); + dev_stat(&devstat, i); if (!devstat.present) continue; diff --git a/user/fs/mount.c b/user/fs/mount.c index 778b5b6..4952248 100644 --- a/user/fs/mount.c +++ b/user/fs/mount.c @@ -40,7 +40,7 @@ void fs_mount(void) { } Dev_t dev; - ret = devctl(&dev, DEVCTL_GET_HANDLE, (uint8_t *)FS_MOUNT_CONFIG.devname, 0, 0); + ret = dev_gethandle(&dev, FS_MOUNT_CONFIG.devname); if (ret != E_OK) { uprintf("fs: device %s not found\n", FS_MOUNT_CONFIG.devname); return; diff --git a/user/init/main.c b/user/init/main.c index 021ed2b..20e8b14 100644 --- a/user/init/main.c +++ b/user/init/main.c @@ -6,7 +6,7 @@ Dev_t ps2kbdev; Dev_t termdev; void tb_runinitscript(void) { - devctl(&termdev, DEVCTL_GET_HANDLE, (uint8_t *)"termdev", 0, 0); + dev_gethandle(&termdev, "termdev"); char *tbargs[] = { "-m", "runfile", "-f", "base:/scripts/init.tb" }; int32_t tb = proc_spawn("base:/bin/tb", tbargs, ARRLEN(tbargs)); @@ -20,7 +20,7 @@ void tb_runinitscript(void) { string_memset(buf, 0, sizeof(buf)); r = ipc_piperead(tb, 0, (uint8_t *const)buf, sizeof(buf)-1); if (r > 0) { - devctl(&termdev, DEV_TERMDEV_PUTCH, (uint8_t *)buf, string_len(buf), 0); + dev_cmd(&termdev, DEV_TERMDEV_PUTCH, buf, string_len(buf), NULL); } else { schedrelease(); } @@ -29,8 +29,8 @@ void tb_runinitscript(void) { void main(void) { PID = proc_getpid(); - devctl(&ps2kbdev, DEVCTL_GET_HANDLE, (uint8_t *)"ps2kbdev", 0, 0); - devctl(&ps2kbdev, DEV_PS2KBDEV_ATTCHCONS, (uint8_t *)PID, 0, 0); + dev_gethandle(&ps2kbdev, "ps2kbdev"); + dev_cmd(&ps2kbdev, DEV_PS2KBDEV_ATTCHCONS, (void *)PID, 0, NULL); tb_runinitscript(); diff --git a/user/tb/interp.c b/user/tb/interp.c index 0f90d36..ccafc5c 100644 --- a/user/tb/interp.c +++ b/user/tb/interp.c @@ -217,7 +217,7 @@ bool interp_runstring(char *string, InterpResult **res, bool logcmds, bool inter while(proc_pollstate(app) != 4) { if (interactive) { - int32_t key = devctl(&ps2kbdev, DEV_PS2KBDEV_READCH, (uint8_t *)PID, 0, 0); + int32_t key = dev_cmd(&ps2kbdev, DEV_PS2KBDEV_READCH, (void *)PID, 0, NULL); if (key > 0 && (uint8_t)key == C('S')) { proc_kill(app); goto cleanup; diff --git a/user/tb/main.c b/user/tb/main.c index eec0afb..48098ff 100644 --- a/user/tb/main.c +++ b/user/tb/main.c @@ -102,7 +102,7 @@ void do_mode_interactive(void) { uint8_t b = 0; for (;;) { - int32_t key = devctl(&ps2kbdev, DEV_PS2KBDEV_READCH, (uint8_t *)PID, 0, 0); + int32_t key = dev_cmd(&ps2kbdev, DEV_PS2KBDEV_READCH, (void *)PID, 0, NULL); if (key > 0) { b = (uint8_t)key; switch (b) { @@ -151,8 +151,8 @@ void main(void) { do_file("base:/scripts/rc.tb"); if (CONFIG.mode == MODE_INTERACTIVE) { - devctl(&ps2kbdev, DEVCTL_GET_HANDLE, (uint8_t *)"ps2kbdev", 0, 0); - devctl(&ps2kbdev, DEV_PS2KBDEV_ATTCHCONS, (uint8_t *)PID, 0, 0); + dev_gethandle(&ps2kbdev, "ps2kbdev"); + dev_cmd(&ps2kbdev, DEV_PS2KBDEV_ATTCHCONS, (void *)PID, 0, NULL); do_mode_interactive(); } else if (CONFIG.mode == MODE_RUNFILE) { if (CONFIG.filepath == NULL) {