diff --git a/kernel/Makefile b/kernel/Makefile index 05fc4b3..eb134e3 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -59,6 +59,7 @@ SRCFILES += $(call GRABSRC, \ rbuf \ ipc/pipe \ dev \ + randcrypto \ ) CFILES := $(call GET_CFILES, $(SRCFILES)) diff --git a/kernel/dev/dev.h b/kernel/dev/dev.h index 3cfeefe..00d93af 100644 --- a/kernel/dev/dev.h +++ b/kernel/dev/dev.h @@ -6,13 +6,16 @@ #define DEV_FNS_MAX 32 -typedef int32_t (*DevFn)(uint8_t *buffer, size_t len, void *extra); +struct Dev; -typedef struct { +typedef int32_t (*DevFn)(struct Dev *dev, uint8_t *buffer, size_t len, void *extra); + +typedef struct Dev { int _hshtbstate; char ident[0x100]; DevFn fns[DEV_FNS_MAX]; SpinLock spinlock; + void *extra; } Dev; diff --git a/kernel/dev/fbdev.c b/kernel/dev/fbdev.c index 31d6a2d..7102d87 100644 --- a/kernel/dev/fbdev.c +++ b/kernel/dev/fbdev.c @@ -10,7 +10,7 @@ #include "bootinfo/bootinfo.h" #include "errors.h" -int32_t fbdev_getinfo(uint8_t *buffer, size_t len, void *extra) { +int32_t fbdev_getinfo(struct Dev *dev, uint8_t *buffer, size_t len, void *extra) { FbDevGetInfo info = { .w = BOOT_INFO.fb->width, .h = BOOT_INFO.fb->height, diff --git a/kernel/dev/fbdev.h b/kernel/dev/fbdev.h index 9415d53..ca47708 100644 --- a/kernel/dev/fbdev.h +++ b/kernel/dev/fbdev.h @@ -1,7 +1,6 @@ #ifndef DEV_FBDEV_H_ #define DEV_FBDEV_H_ -int32_t fbdev_getinfo(uint8_t *buffer, size_t len, void *extra); void fbdev_init(void); #endif // DEV_FBDEV_H_ diff --git a/kernel/dev/ps2kbdev.c b/kernel/dev/ps2kbdev.c index 996f1bd..ed4440a 100644 --- a/kernel/dev/ps2kbdev.c +++ b/kernel/dev/ps2kbdev.c @@ -163,7 +163,7 @@ struct { Ps2kbEvConsumer *list; } PS2KB_CONSUMERS = {0}; -int32_t ps2kbdev_readch(uint8_t *buffer, size_t len, void *extra) { +int32_t ps2kbdev_readch(struct Dev *dev, uint8_t *buffer, size_t len, void *extra) { uint64_t pid = (uint64_t)buffer; Proc *consproc = NULL; spinlock_acquire(&PROCS.spinlock); @@ -201,7 +201,7 @@ int32_t ps2kbdev_readch(uint8_t *buffer, size_t len, void *extra) { #define CONSUMER_RBUF_MAX 0x400 -int32_t ps2kbdev_attchcons(uint8_t *buffer, size_t len, void *extra) { +int32_t ps2kbdev_attchcons(struct Dev *dev, uint8_t *buffer, size_t len, void *extra) { uint64_t pid = (uint64_t)buffer; spinlock_acquire(&PROCS.spinlock); Proc *proc, *proctmp; diff --git a/kernel/dev/serialdev.c b/kernel/dev/serialdev.c index 3b14636..3a77b70 100644 --- a/kernel/dev/serialdev.c +++ b/kernel/dev/serialdev.c @@ -48,23 +48,23 @@ void serial_sendb(uint8_t b) { io_out8(PORT, b); } -int32_t serialdev_sendb(uint8_t *buffer, size_t len, void *extra) { +int32_t serialdev_sendb(struct Dev *dev, uint8_t *buffer, size_t len, void *extra) { (void)len; (void)extra; serial_sendb(buffer[0]); return E_OK; } -int32_t serialdev_sendready(uint8_t *buffer, size_t len, void *extra) { +int32_t serialdev_sendready(struct Dev *dev, uint8_t *buffer, size_t len, void *extra) { (void)buffer; (void)len; (void) extra; return serial_sendready(); } -int32_t serialdev_recvb(uint8_t *buffer, size_t len, void *extra) { +int32_t serialdev_recvb(struct Dev *dev, uint8_t *buffer, size_t len, void *extra) { (void)buffer; (void)len; (void)extra; return serial_recvb(); } -int32_t serialdev_recvready(uint8_t *buffer, size_t len, void *extra) { +int32_t serialdev_recvready(struct Dev *dev, uint8_t *buffer, size_t len, void *extra) { (void)buffer; (void)len; (void)extra; return serial_recvready(); } diff --git a/kernel/dev/serialdev.h b/kernel/dev/serialdev.h index 43ee298..df838b9 100644 --- a/kernel/dev/serialdev.h +++ b/kernel/dev/serialdev.h @@ -1,10 +1,6 @@ #ifndef DEV_SERIALDEV_H_ #define DEV_SERIALDEV_H_ -int32_t serialdev_sendb(uint8_t *buffer, size_t len, void *extra); -int32_t serialdev_sendready(uint8_t *buffer, size_t len, void *extra); -int32_t serialdev_recvb(uint8_t *buffer, size_t len, void *extra); -int32_t serialdev_recvready(uint8_t *buffer, size_t len, void *extra); void serialdev_init(void); #endif // DEV_SERIALDEV_H_ diff --git a/kernel/dev/termdev.c b/kernel/dev/termdev.c index 3011815..06ca4a8 100644 --- a/kernel/dev/termdev.c +++ b/kernel/dev/termdev.c @@ -9,7 +9,7 @@ #include "hshtb.h" #include "sysdefs/devctl.h" -int32_t termdev_putch(uint8_t *buffer, size_t len, void *extra) { +int32_t termdev_putch(struct Dev *dev, uint8_t *buffer, size_t len, void *extra) { kprintf("%.*s", (int)len, (char *)buffer); return E_OK; } diff --git a/kernel/dev/termdev.h b/kernel/dev/termdev.h index e56533d..ded223f 100644 --- a/kernel/dev/termdev.h +++ b/kernel/dev/termdev.h @@ -5,7 +5,6 @@ #include #include "dev.h" -int32_t termdev_putch(uint8_t *buffer, size_t len, void *extra); void termdev_init(void); #endif // DEV_TERMDEV_H_ diff --git a/kernel/hshtb.h b/kernel/hshtb.h index cbcca3b..4c36fcf 100644 --- a/kernel/hshtb.h +++ b/kernel/hshtb.h @@ -79,7 +79,7 @@ enum { #define HSHTB_DELETE(tb, keyfield, k) \ do { \ typeof(&(tb)[0]) __e; \ - HSHTB_GET((tb), (keyfield), (k), __e); \ + HSHTB_GET((tb), keyfield, (k), __e); \ if (__e) { \ __e->_hshtbstate = HSHTB_TOMB; \ } \ diff --git a/kernel/kmain.c b/kernel/kmain.c index b1cf93a..ae4a016 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -12,6 +12,7 @@ #include "util/util.h" #include "proc/proc.h" #include "dev/dev.h" +#include "randcrypto/randcrypto.h" const char *human_size(uint64_t bytes, char *buf, size_t bufsize) { static const char *units[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB" }; @@ -62,6 +63,7 @@ void kmain(void) { hal_init(); pmm_init(); hal_vmm_init(); + randcrypto_init(); dev_init(); storedev_init(); baseimg_init(); diff --git a/kernel/randcrypto/randcrypto.c b/kernel/randcrypto/randcrypto.c new file mode 100644 index 0000000..9951ea8 --- /dev/null +++ b/kernel/randcrypto/randcrypto.c @@ -0,0 +1,6 @@ +#include "randcrypto.h" +#include "uniqid.h" + +void randcrypto_init(void) { + randcrypto_uniqid_init(); +} diff --git a/kernel/randcrypto/randcrypto.h b/kernel/randcrypto/randcrypto.h new file mode 100644 index 0000000..3ecc03e --- /dev/null +++ b/kernel/randcrypto/randcrypto.h @@ -0,0 +1,6 @@ +#ifndef RANDCRYPTO_RANDCRYPTO_H_ +#define RANDCRYPTO_RANDCRYPTO_H_ + +void randcrypto_init(void); + +#endif // RANDCRYPTO_RANDCRYPTO_H_ diff --git a/kernel/randcrypto/uniqid.c b/kernel/randcrypto/uniqid.c new file mode 100644 index 0000000..f9b6a98 --- /dev/null +++ b/kernel/randcrypto/uniqid.c @@ -0,0 +1,51 @@ +#include +#include +#include "uniqid.h" +#include "atomic.h" +#include "spinlock/spinlock.h" + +static const char *base62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static uint32_t uniqstate = 0u; +SpinLock uniqstate_spinlock; + +void randcrypto_uniqid_init(void) { + spinlock_init(&uniqstate_spinlock); +} + +uint32_t uniqmix32(uint32_t x) { + x ^= x >> 16; + x *= 0x85ebca6bU; + x ^= x >> 13; + x *= 0xc2b2ae35U; + x ^= x >> 16; + return x; +} + +void randcrypto_gen_uniqid(char *out, size_t n) { + if (!out || n == 0) { + return; + } + + spinlock_acquire(&uniqstate_spinlock); + + if (uniqstate == 0u) { + uintptr_t p = (uintptr_t)(void *)&uniqstate; + uint32_t seed = (uint32_t)(p ^ (p >> 16)); + uniqstate = seed ^ 0x9E3779B9u; + if (uniqstate == 0u) { + uniqstate = 1u; + } + } + + uniqstate += 0x9E3779B1u; + uint32_t v = uniqmix32(uniqstate); + + spinlock_release(&uniqstate_spinlock); + + for (size_t i = 0; i < n; i++) { + v = uniqmix32(v + i * 0x27d4eb2dU); + out[i] = base62[v % 62u]; + } + out[n] = '\0'; +} diff --git a/kernel/randcrypto/uniqid.h b/kernel/randcrypto/uniqid.h new file mode 100644 index 0000000..cae4384 --- /dev/null +++ b/kernel/randcrypto/uniqid.h @@ -0,0 +1,10 @@ +#ifndef RANDCRYPTO_UNIQID_H_ +#define RANDCRYPTO_UNIQID_H_ + +#include +#include + +void randcrypto_uniqid_init(void); +void randcrypto_gen_uniqid(char *out, size_t n); + +#endif // RANDCRYPTO_UNIQID_H_ diff --git a/kernel/storedev/storedev.c b/kernel/storedev/storedev.c index 57ce702..fa13a2c 100644 --- a/kernel/storedev/storedev.c +++ b/kernel/storedev/storedev.c @@ -7,6 +7,10 @@ #include "dlmalloc/malloc.h" #include "ramsd.h" #include "util/util.h" +#include "dev/dev.h" +#include "hshtb.h" +#include "hal/hal.h" +#include "randcrypto/uniqid.h" StoreDevList STOREDEV_LIST; @@ -17,6 +21,36 @@ void storedev_init(void) { LOG("storedev", "init\n"); } +void storedev_register_dev_entry(StoreDev *sd, int32_t sdtype) { + char uniq[5]; + randcrypto_gen_uniqid(uniq, 4); + + char key[20]; + hal_memset(key, 0, sizeof(key)); + if (sdtype == STOREDEV_RAMSD) { + ksprintf(key, "ramsd-%s", uniq); + } + + spinlock_acquire(&DEVTABLE.spinlock); + Dev *dev = NULL; + HSHTB_ALLOC(DEVTABLE.devs, ident, key, dev); + spinlock_release(&DEVTABLE.spinlock); + + if (dev == NULL) { + ERR("storedev", "could not register dev entry for storedev"); + return; + } + + spinlock_init(&dev->spinlock); + dev->extra = (void *)sd; +} + +void storedev_unregister_dev_entry(Dev *dev) { + spinlock_acquire(&DEVTABLE.spinlock); + HSHTB_DELETE(DEVTABLE.devs, ident, dev->ident); + spinlock_release(&DEVTABLE.spinlock); +} + StoreDev *storedev_create(int32_t sdtype, void *extra) { StoreDev *sd = dlmalloc(sizeof(*sd)); if (sd == NULL) { @@ -25,6 +59,8 @@ StoreDev *storedev_create(int32_t sdtype, void *extra) { spinlock_acquire(&STOREDEV_LIST.spinlock); + sd->_magic = STOREDEV_MAGIC; + switch (sdtype) { case STOREDEV_RAMSD: { spinlock_init(&sd->spinlock); @@ -47,6 +83,9 @@ StoreDev *storedev_create(int32_t sdtype, void *extra) { return NULL; } spinlock_release(&STOREDEV_LIST.spinlock); + + storedev_register_dev_entry(sd, sdtype); + return sd; } diff --git a/kernel/storedev/storedev.h b/kernel/storedev/storedev.h index 9c7efd0..941444e 100644 --- a/kernel/storedev/storedev.h +++ b/kernel/storedev/storedev.h @@ -6,6 +6,9 @@ #include "spinlock/spinlock.h" #include "ramsd.h" #include "compiler/attr.h" +#include "dev/dev.h" + +#define STOREDEV_MAGIC 0x50FA enum { STOREDEV_RAMSD, @@ -16,6 +19,7 @@ UNUSED static const char *storedev_strings[] = { }; typedef struct StoreDev { + uint32_t _magic; struct StoreDev *next; int32_t sdtype; @@ -43,4 +47,7 @@ void storedev_init(void); StoreDev *storedev_create(int32_t sdtype, void *extra); int32_t storedev_delete(StoreDev *sd); +void storedev_register_dev_entry(StoreDev *sd, int32_t sdtype); +void storedev_unregister_dev_entry(Dev *dev); + #endif // STOREDEV_STOREDEV_H_ diff --git a/kernel/syscall/devctl.c b/kernel/syscall/devctl.c index 8b20add..db7f208 100644 --- a/kernel/syscall/devctl.c +++ b/kernel/syscall/devctl.c @@ -107,7 +107,7 @@ int32_t SYSCALL5(sys_devctl, devh1, cmd1, buffer1, len1, extra1) { goto done; } spinlock_acquire(&dev->spinlock); - ret = dev->fns[cmd]((uint8_t *)buffer1, (size_t)len1, (void *)extra1); + ret = dev->fns[cmd](dev, (uint8_t *)buffer1, (size_t)len1, (void *)extra1); spinlock_release(&dev->spinlock); } break; }