diff options
author | Marvin Borner | 2021-04-25 13:43:14 +0200 |
---|---|---|
committer | Marvin Borner | 2021-04-25 13:43:14 +0200 |
commit | f2b4acb2fe6a366288b19843e0d2678b8590bdf4 (patch) | |
tree | 1eb869f237908ec0b2516c00f940c6562c5cc5bd /kernel/features | |
parent | cd46cefdd74b9ad0b225706f4d4b5864e87d97d6 (diff) |
Chu chuu, using the bus for everything now!
Well, I know: bus != train. But I like trains. So I don't care.
Go away!
Diffstat (limited to 'kernel/features')
-rw-r--r-- | kernel/features/bus.c | 52 | ||||
-rw-r--r-- | kernel/features/io.c | 22 | ||||
-rw-r--r-- | kernel/features/logger.c | 42 | ||||
-rw-r--r-- | kernel/features/proc.c | 57 | ||||
-rw-r--r-- | kernel/features/syscall.c | 5 |
5 files changed, 112 insertions, 66 deletions
diff --git a/kernel/features/bus.c b/kernel/features/bus.c index f8a561c..4a09fc0 100644 --- a/kernel/features/bus.c +++ b/kernel/features/bus.c @@ -19,6 +19,7 @@ struct bus_conn { u32 bus; // Bus name hash u32 conn; + u32 pid; // Client pid struct stack *in; // Queue of bus owner struct stack *out; // Queue of other client }; @@ -85,6 +86,7 @@ static void bus_add_conn(u32 hash, u32 conn) { struct bus_conn *bus_conn = zalloc(sizeof(*bus_conn)); bus_conn->bus = hash; + bus_conn->pid = proc_current()->pid; bus_conn->conn = conn; bus_conn->in = stack_new(); bus_conn->out = stack_new(); @@ -113,7 +115,7 @@ static res bus_register(const char *name) return EOK; } -static res bus_connect(const char *bus, u32 *conn) +static res bus_connect_bus(const char *bus, u32 *conn) { if (!memory_readable(bus) || !memory_writable(conn)) return -EFAULT; @@ -137,7 +139,25 @@ static res bus_connect(const char *bus, u32 *conn) return EOK; } -static res bus_send(u32 conn, void *buf, u32 count) +static res bus_connect_conn(u32 conn) +{ + struct bus_conn *bus_conn = bus_find_conn(conn); + if (!bus_conn) + return -ENOENT; + + struct bus *bus = bus_find_bus(bus_conn->bus); + if (!bus) + return -ENOENT; + + if (bus_conn->pid != proc_current()->pid && bus->pid != proc_current()->pid) + return -EACCES; + + proc_current()->bus_conn = conn; + + return EOK; +} + +static res bus_send(u32 conn, const void *buf, u32 count) { if (!count) return EOK; @@ -160,10 +180,13 @@ static res bus_send(u32 conn, void *buf, u32 count) msg->conn = conn; msg->size = count; - if (bus->pid == proc_current()->pid) - stack_push_bot(bus_conn->in, msg); - else + if (bus->pid == proc_current()->pid) { stack_push_bot(bus_conn->out, msg); + io_unblock_pid(bus_conn->pid); + } else { + stack_push_bot(bus_conn->in, msg); + io_unblock_pid(bus->pid); + } return count; } @@ -176,16 +199,20 @@ static res bus_conn_receive(struct bus_conn *bus_conn, void *buf, u32 offset, u3 struct bus_message *msg = NULL; if (bus->pid == proc_current()->pid) - msg = stack_pop(bus_conn->out); + msg = stack_pop(bus_conn->in); else msg = stack_pop(bus_conn->out); if (!msg) return -EIO; - memcpy_user(buf, (u8 *)msg->data + offset, MIN(count, msg->size)); + struct bus_header h = { .conn = bus_conn->conn }; + memcpy_user(buf, &h, sizeof(h)); + memcpy_user((u8 *)buf + sizeof(h), (u8 *)msg->data + offset, MIN(count, msg->size)); + free(msg->data); free(msg); + return MIN(count, msg->size); } @@ -230,8 +257,11 @@ static res bus_control(u32 request, void *arg1, void *arg2, void *arg3) UNUSED(arg3); switch (request) { - case IOCTL_BUS_CONNECT: { - return bus_connect(arg1, arg2); + case IOCTL_BUS_CONNECT_BUS: { + return bus_connect_bus(arg1, arg2); + } + case IOCTL_BUS_CONNECT_CONN: { + return bus_connect_conn((u32)arg1); } case IOCTL_BUS_REGISTER: { return bus_register(arg1); @@ -242,7 +272,7 @@ static res bus_control(u32 request, void *arg1, void *arg2, void *arg3) } } -static res bus_write(void *buf, u32 offset, u32 count) +static res bus_write(const void *buf, u32 offset, u32 count) { if (offset) return -EINVAL; @@ -263,7 +293,7 @@ static res bus_conn_ready(struct bus_conn *bus_conn) u8 ready = 0; if (bus->pid == proc_current()->pid) - ready = !stack_empty(bus_conn->out); + ready = !stack_empty(bus_conn->in); else ready = !stack_empty(bus_conn->out); diff --git a/kernel/features/io.c b/kernel/features/io.c index c48eb62..fbae5cf 100644 --- a/kernel/features/io.c +++ b/kernel/features/io.c @@ -8,6 +8,7 @@ #include <interrupts.h> #include <io.h> #include <list.h> +#include <logger.h> #include <mem.h> #include <mm.h> #include <proc.h> @@ -117,7 +118,7 @@ res io_control(enum io_type io, u32 request, void *arg1, void *arg2, void *arg3) return dev->control(request, arg1, arg2, arg3); } -res io_write(enum io_type io, void *buf, u32 offset, u32 count) +res io_write(enum io_type io, const void *buf, u32 offset, u32 count) { if (!memory_readable(buf)) return -EFAULT; @@ -182,6 +183,24 @@ void io_unblock(enum io_type io) } } +void io_unblock_pid(u32 pid) +{ + for (u32 io = IO_MIN; io < IO_MAX; io++) { + struct node *iterator = io_listeners[io]->head; + while (iterator) { + struct io_listener *listener = iterator->data; + struct proc *proc = listener->proc; + proc_state(proc, PROC_RUNNING); + struct node *next = iterator->next; + if (proc->pid == pid) { + list_remove(io_listeners[io], iterator); + free(listener); + } + iterator = next; + } + } +} + CLEAR void io_install(struct boot_info *boot) { for (u32 i = 0; i < IO_MAX; i++) @@ -200,6 +219,7 @@ CLEAR void io_install(struct boot_info *boot) } timer_install(); + logger_install(); fb_install(boot->vid); bus_install(); } diff --git a/kernel/features/logger.c b/kernel/features/logger.c new file mode 100644 index 0000000..7db9a82 --- /dev/null +++ b/kernel/features/logger.c @@ -0,0 +1,42 @@ +// MIT License, Copyright (c) 2021 Marvin Borner + +#include <cpu.h> +#include <def.h> +#include <errno.h> +#include <io.h> +#include <logger.h> +#include <mem.h> +#include <print.h> +#include <serial.h> + +static res logger_write(const void *buf, u32 offset, u32 count) +{ + if (offset) + return -EINVAL; + + if (!count) + return EOK; + + print_prefix(); + + u32 i; + stac(); + for (i = 0; i < count; i++) { + if (!((const u8 *)buf)[i]) + break; + + serial_put(((const u8 *)buf)[i]); + } + clac(); + + serial_print("\x1B[0m"); + + return i; +} + +void logger_install(void) +{ + struct io_dev *dev = zalloc(sizeof(*dev)); + dev->write = logger_write; + io_add(IO_LOGGER, dev); +} diff --git a/kernel/features/proc.c b/kernel/features/proc.c index cada97d..4cf4005 100644 --- a/kernel/features/proc.c +++ b/kernel/features/proc.c @@ -251,21 +251,6 @@ static const char *procfs_parse_path(const char **path, u32 *pid) return *path; } -static enum stream_defaults procfs_stream(const char *path) -{ - if (!memcmp_user(path, "in", 3)) { - return STREAM_IN; - } else if (!memcmp_user(path, "out", 4)) { - return STREAM_OUT; - } else if (!memcmp_user(path, "err", 4)) { - return STREAM_ERR; - } else if (!memcmp_user(path, "log", 4)) { - return STREAM_LOG; - } else { - return STREAM_UNKNOWN; - } -} - struct procfs_message { u8 *data; u32 size; @@ -273,39 +258,12 @@ struct procfs_message { static res procfs_write(const char *path, void *buf, u32 offset, u32 count, struct vfs_dev *dev) { + UNUSED(path); + UNUSED(buf); UNUSED(offset); + UNUSED(count); UNUSED(dev); - u32 pid = 0; - procfs_parse_path(&path, &pid); - if (pid) { - struct proc *p = proc_from_pid(pid); - stac(); - if (!p || path[0] != '/') { - clac(); - return -ENOENT; - } - clac(); - - path++; - if (!memcmp_user(path, "io/", 3)) { - path += 3; - enum stream_defaults id = procfs_stream(path); - if (id == STREAM_UNKNOWN) - return -ENOENT; - - // Put proc log/err messages to serial console for debugging - if (id == STREAM_LOG || id == STREAM_ERR) - print_app(id, p->name, (char *)buf); - - struct stream *stream = &p->streams[id]; - assert(stream->offset_write + count < STREAM_MAX_SIZE); // TODO: Resize - memcpy_user((char *)(stream->data + stream->offset_write), buf, count); - stream->offset_write += count; - return count; - } - } - return -ENOENT; } @@ -338,15 +296,6 @@ static res procfs_read(const char *path, void *buf, u32 offset, u32 count, struc const char *status = p->state == PROC_RUNNING ? "running" : "sleeping"; memcpy_user(buf, status + offset, count); return count; - } else if (!memcmp_user(path, "io/", 3)) { - path += 3; - enum stream_defaults id = procfs_stream(path); - if (id == STREAM_UNKNOWN) - return -ENOENT; - struct stream *stream = &p->streams[id]; - memcpy_user(buf, stream->data + stream->offset_read, count); - stream->offset_read += count; - return count; } } diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c index 94ea778..23c8d37 100644 --- a/kernel/features/syscall.c +++ b/kernel/features/syscall.c @@ -132,6 +132,11 @@ static void syscall_handler(struct regs *r) break; } + case SYS_MIN: + case SYS_MAX: + r->eax = -EINVAL; + break; + // TODO: Reimplement network functions using VFS default: { r->eax = -EINVAL; |