summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/arch/i386/driver/ps2.c40
-rw-r--r--src/kernel/arch/i386/driver/ps2.h4
-rw-r--r--src/kernel/handle.h3
-rw-r--r--src/kernel/proc.c19
-rw-r--r--src/kernel/proc.h2
-rw-r--r--src/kernel/vfs/mount.c22
-rw-r--r--src/kernel/vfs/request.h1
-rw-r--r--src/kernel/vfs/root.c9
8 files changed, 78 insertions, 22 deletions
diff --git a/src/kernel/arch/i386/driver/ps2.c b/src/kernel/arch/i386/driver/ps2.c
index 4b7eae4..6ee24e2 100644
--- a/src/kernel/arch/i386/driver/ps2.c
+++ b/src/kernel/arch/i386/driver/ps2.c
@@ -1,20 +1,60 @@
#include <kernel/arch/i386/driver/ps2.h>
#include <kernel/arch/i386/interrupts/irq.h>
+#include <kernel/mem/virt.h>
+#include <kernel/panic.h>
#include <shared/container/ring.h>
#include <shared/mem.h>
+
#define BACKLOG_CAPACITY 64
static volatile uint8_t backlog_buf[BACKLOG_CAPACITY];
static volatile ring_t backlog = {(void*)backlog_buf, BACKLOG_CAPACITY, 0, 0};
+static struct vfs_request *blocked_on = NULL;
+
bool ps2_ready(void) {
return ring_size((void*)&backlog) > 0;
}
void ps2_recv(uint8_t s) {
ring_put1b((void*)&backlog, s);
+ if (blocked_on) {
+ vfs_ps2_accept(blocked_on);
+ blocked_on = NULL;
+ }
}
size_t ps2_read(uint8_t *buf, size_t len) {
return ring_get((void*)&backlog, buf, len);
}
+
+int vfs_ps2_accept(struct vfs_request *req) {
+ static uint8_t buf[32]; // pretty damn stupid
+ int ret;
+ switch (req->type) {
+ case VFSOP_OPEN:
+ // allows opening /ps2/anything, TODO don't
+ return vfsreq_finish(req, 0); // fake file handle, whatever
+ case VFSOP_READ:
+ if (ps2_ready()) {
+ // TODO FUKKEN MESS
+ if (req->caller) {
+ // clamp between 0, sizeof buf
+ ret = req->output.len;
+ if (ret > sizeof buf) ret = sizeof buf;
+ if (ret < 0) ret = 0;
+
+ ret = ps2_read(buf, ret);
+ virt_cpy_to(req->caller->pages, req->output.buf, buf, ret);
+ } else ret = -1;
+ return vfsreq_finish(req, ret);
+ } else {
+ blocked_on = req;
+ return -1;
+ }
+ default:
+ return vfsreq_finish(req, -1);
+ }
+}
+
+bool vfs_ps2_ready(struct vfs_backend *self) { return blocked_on == NULL; }
diff --git a/src/kernel/arch/i386/driver/ps2.h b/src/kernel/arch/i386/driver/ps2.h
index 712b157..1bbc2f1 100644
--- a/src/kernel/arch/i386/driver/ps2.h
+++ b/src/kernel/arch/i386/driver/ps2.h
@@ -1,4 +1,5 @@
#pragma once
+#include <kernel/vfs/request.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
@@ -6,3 +7,6 @@
bool ps2_ready(void);
void ps2_recv(uint8_t scancode);
size_t ps2_read(uint8_t *buf, size_t max_len);
+
+int vfs_ps2_accept(struct vfs_request *);
+bool vfs_ps2_ready(struct vfs_backend *);
diff --git a/src/kernel/handle.h b/src/kernel/handle.h
index 3b75894..b90ab60 100644
--- a/src/kernel/handle.h
+++ b/src/kernel/handle.h
@@ -3,9 +3,6 @@
#include <shared/types.h>
#include <stddef.h>
-// TODO make accessible only from proc.c
-#define HANDLE_MAX 16
-
enum handle_type {
HANDLE_INVALID = 0,
HANDLE_FILE,
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 7c41eb2..ed317ec 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -125,22 +125,23 @@ static _Noreturn void process_switch(struct process *proc) {
/** If there are any processes waiting for IRQs, wait with them. Otherwise, shut down */
static _Noreturn void process_idle(void) {
+ // this mess is temporary
+
struct process *procs[16];
size_t len = process_find_multiple(PS_WAITS4IRQ, procs, 16);
if (len == 0) shutdown();
- for (;;) {
- for (size_t i = 0; i < len; i++) {
- if (procs[i]->waits4irq.ready()) {
- /* if this is entered during the first iteration, it indicates a
- * kernel bug. this should be logged. TODO? */
- procs[i]->waits4irq.callback(procs[i]);
- process_switch_any();
- }
+ cpu_pause();
+ for (size_t i = 0; i < len; i++) {
+ if (procs[i]->waits4irq.ready()) {
+ /* if this is entered during the first iteration, it indicates a
+ * kernel bug. this should be logged. TODO? */
+ procs[i]->waits4irq.callback(procs[i]);
}
- cpu_pause();
}
+
+ process_switch_any();
}
_Noreturn void process_switch_any(void) {
diff --git a/src/kernel/proc.h b/src/kernel/proc.h
index 3102ac7..a6a8609 100644
--- a/src/kernel/proc.h
+++ b/src/kernel/proc.h
@@ -6,6 +6,8 @@
#include <shared/syscalls.h>
#include <stdbool.h>
+#define HANDLE_MAX 16
+
enum process_state {
PS_RUNNING,
PS_DEAD, // return message wasn't collected
diff --git a/src/kernel/vfs/mount.c b/src/kernel/vfs/mount.c
index a6c5970..232e702 100644
--- a/src/kernel/vfs/mount.c
+++ b/src/kernel/vfs/mount.c
@@ -4,6 +4,8 @@
#include <kernel/vfs/root.h>
#include <shared/mem.h>
+#include <kernel/arch/i386/driver/ps2.h>
+
struct vfs_mount *vfs_mount_seed(void) {
struct vfs_mount *mount = kmalloc(sizeof *mount);
struct vfs_backend *backend = kmalloc(sizeof *backend);
@@ -19,7 +21,25 @@ struct vfs_mount *vfs_mount_seed(void) {
.backend = backend,
.refs = 1, // never to be freed
};
- return mount;
+
+ // what a mess.
+ // TODO register funcs
+ struct vfs_mount *ps2 = kmalloc(sizeof *ps2);
+ backend = kmalloc(sizeof *backend);
+ backend->is_user = false;
+ backend->potential_handlers = 1;
+ backend->refcount = 1;
+ backend->kern.ready = vfs_ps2_ready;
+ backend->kern.accept = vfs_ps2_accept;
+ *ps2 = (struct vfs_mount){
+ .prev = mount,
+ .prefix = "/ps2",
+ .prefix_len = 4,
+ .backend = backend,
+ .refs = 1,
+ };
+
+ return ps2;
}
struct vfs_mount *vfs_mount_resolve(
diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h
index e62f28f..b4624fa 100644
--- a/src/kernel/vfs/request.h
+++ b/src/kernel/vfs/request.h
@@ -1,4 +1,5 @@
#pragma once
+#include <kernel/proc.h>
#include <shared/flags.h>
#include <shared/types.h>
#include <stdbool.h>
diff --git a/src/kernel/vfs/root.c b/src/kernel/vfs/root.c
index 701d4e6..0c58d86 100644
--- a/src/kernel/vfs/root.c
+++ b/src/kernel/vfs/root.c
@@ -15,7 +15,6 @@ enum {
HANDLE_ROOT,
HANDLE_VGA,
HANDLE_COM1,
- HANDLE_PS2,
HANDLE_ATA_ROOT,
HANDLE_ATA,
_SKIP = HANDLE_ATA + 4,
@@ -72,7 +71,6 @@ static int handle(struct vfs_request *req, bool *ready) {
if (exacteq(req, "/")) return HANDLE_ROOT;
if (exacteq(req, "/vga")) return HANDLE_VGA;
if (exacteq(req, "/com1")) return HANDLE_COM1;
- if (exacteq(req, "/ps2")) return HANDLE_PS2;
if (exacteq(req, "/ata/")) return HANDLE_ATA_ROOT;
if (exacteq(req, "/ata/0"))
@@ -113,13 +111,6 @@ static int handle(struct vfs_request *req, bool *ready) {
virt_cpy_to(req->caller->pages, req->output.buf, buf, len);
return len;
}
- case HANDLE_PS2: {
- if (wait_setup(req, ready, ps2_ready)) return -1;
- uint8_t buf[16];
- size_t len = ps2_read(buf, min(req->output.len, sizeof buf));
- virt_cpy_to(req->caller->pages, req->output.buf, buf, len);
- return len;
- }
case HANDLE_ATA_ROOT: {
// TODO offset
char list[8] = {};