aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2021-01-13 19:51:40 +0100
committerMarvin Borner2021-01-13 19:51:40 +0100
commit91abed9333241731d0cd877beba4e2d4675989c8 (patch)
tree09a5e509afda809d56db88ec720c78864312620e
parent9ac1eda2988b6c7472a24817f4fd623de28a33f5 (diff)
VFS ready function and read yielding
-rw-r--r--kernel/drivers/ide.c1
-rw-r--r--kernel/drivers/keyboard.c34
-rw-r--r--kernel/features/fs.c67
-rw-r--r--kernel/features/proc.c8
-rw-r--r--kernel/features/syscall.c7
-rw-r--r--kernel/inc/fs.h4
-rw-r--r--libc/inc/sys.h2
7 files changed, 111 insertions, 12 deletions
diff --git a/kernel/drivers/ide.c b/kernel/drivers/ide.c
index f3d0f6e..5a51cb8 100644
--- a/kernel/drivers/ide.c
+++ b/kernel/drivers/ide.c
@@ -147,6 +147,7 @@ void ata_probe(void)
struct vfs *vfs = malloc(sizeof(*vfs));
vfs->type = VFS_EXT2;
vfs->read = ext2_read;
+ vfs->ready = ext2_ready;
vfs->stat = ext2_stat;
dev->vfs = vfs;
vfs_mount(dev, "/");
diff --git a/kernel/drivers/keyboard.c b/kernel/drivers/keyboard.c
index 7f3247f..6936c22 100644
--- a/kernel/drivers/keyboard.c
+++ b/kernel/drivers/keyboard.c
@@ -2,12 +2,17 @@
#include <cpu.h>
#include <def.h>
+#include <fs.h>
#include <interrupts.h>
#include <mem.h>
#include <print.h>
+#include <proc.h>
+#include <stack.h>
+#include <str.h>
#include <sys.h>
static struct event_keyboard *event = NULL;
+static struct stack *queue = NULL;
static int state = 0;
static int merged = 0;
@@ -33,10 +38,13 @@ void keyboard_handler()
event->magic = KEYBOARD_MAGIC;
event->press = (scancode & 0x80) == 0;
event->scancode = event->press ? scancode : scancode & ~0x80;
- //event_trigger(EVENT_KEYBOARD, event);
+ stack_push_bot(queue, event);
state = 0;
merged = 0;
+
+ // TODO: Only enable waiting procs
+ proc_current()->state = PROC_RUNNING;
}
void keyboard_acknowledge(void)
@@ -52,8 +60,32 @@ void keyboard_rate(void)
outb(0x60, 0x0); // Rate{00000} Delay{00} 0
}
+u32 keyboard_read(void *buf, u32 offset, u32 count, struct device *dev)
+{
+ (void)dev;
+ if (stack_empty(queue))
+ return 0;
+
+ struct event *e = stack_pop(queue);
+ memcpy(buf, (u8 *)e + offset, count);
+ return count;
+}
+
+u32 keyboard_ready()
+{
+ return !stack_empty(queue);
+}
+
void keyboard_install(void)
{
//keyboard_rate(); TODO: Fix keyboard rate?
irq_install_handler(1, keyboard_handler);
+
+ queue = stack_new();
+ struct device *dev = malloc(sizeof(*dev));
+ dev->name = strdup("kbd");
+ dev->type = DEV_CHAR;
+ dev->read = keyboard_read;
+ dev->ready = keyboard_ready;
+ device_add(dev);
}
diff --git a/kernel/features/fs.c b/kernel/features/fs.c
index 13ed0c2..45e744c 100644
--- a/kernel/features/fs.c
+++ b/kernel/features/fs.c
@@ -154,9 +154,32 @@ u32 vfs_write(const char *path, void *buf, u32 offset, u32 count)
u32 vfs_stat(const char *path, struct stat *buf)
{
- struct device *dev = vfs_find_dev(path);
- assert(dev && dev->vfs && dev->vfs->stat);
- return dev->vfs->stat(path, buf, dev);
+ while (*path == ' ')
+ path++;
+
+ struct mount_info *m = vfs_find_mount_info(path);
+ assert(m && m->dev && m->dev->vfs && m->dev->vfs->stat);
+
+ u32 len = strlen(m->path);
+ if (len > 1)
+ path += len;
+
+ return m->dev->vfs->stat(path, buf, m->dev);
+}
+
+u32 vfs_ready(const char *path)
+{
+ while (*path == ' ')
+ path++;
+
+ struct mount_info *m = vfs_find_mount_info(path);
+ assert(m && m->dev && m->dev->vfs && m->dev->vfs->ready);
+
+ u32 len = strlen(m->path);
+ if (len > 1)
+ path += len;
+
+ return m->dev->vfs->ready(path, m->dev);
}
void vfs_install(void)
@@ -176,7 +199,7 @@ void device_add(struct device *dev)
list_add(devices, dev);
}
-struct device *device_get(u32 id)
+struct device *device_get_by_id(u32 id)
{
struct node *iterator = devices->head;
while (iterator) {
@@ -187,11 +210,33 @@ struct device *device_get(u32 id)
return NULL;
}
+struct device *device_get_by_name(const char *name)
+{
+ struct node *iterator = devices->head;
+ while (iterator) {
+ if (!strcmp(((struct device *)iterator->data)->name, name))
+ return iterator->data;
+ iterator = iterator->next;
+ }
+ return NULL;
+}
+
u32 devfs_read(const char *path, void *buf, u32 offset, u32 count, struct device *dev)
{
- assert(dev && dev->read);
- printf("%s - off: %d, cnt: %d, buf: %x, dev %x\n", path, offset, count, buf, dev);
- return dev->read(buf, offset, count, dev);
+ struct device *target = device_get_by_name(path + 1);
+ if (!target || !target->read)
+ return 0;
+ return target->read(buf, offset, count, dev);
+}
+
+u32 devfs_ready(const char *path, struct device *dev)
+{
+ (void)dev;
+
+ struct device *target = device_get_by_name(path + 1);
+ if (!target || !target->ready)
+ return 0;
+ return target->ready();
}
void device_install(void)
@@ -201,6 +246,7 @@ void device_install(void)
struct vfs *vfs = malloc(sizeof(*vfs));
vfs->type = VFS_DEVFS;
vfs->read = devfs_read;
+ vfs->ready = devfs_ready;
struct device *dev = malloc(sizeof(*dev));
dev->name = "dev";
dev->type = DEV_CHAR;
@@ -406,3 +452,10 @@ u32 ext2_stat(const char *path, struct stat *buf, struct device *dev)
return 0;
}
+
+u32 ext2_ready(const char *path, struct device *dev)
+{
+ (void)path;
+ (void)dev;
+ return 1;
+}
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index 79bc6c8..8fbb4c5 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -44,8 +44,12 @@ void scheduler(struct regs *regs)
} else if (((struct proc *)proc_list->head->data)->state == PROC_RUNNING) {
current = proc_list->head;
} else {
- print("TODO: All processes are sleeping!\n"); // TODO!
- /* loop(); */
+ /* sti(); */
+ /* hlt(); */
+ /* cli(); */
+ //print("TODO: All processes are sleeping!\n"); // TODO!
+ //loop();
+ return;
}
memcpy(regs, &((struct proc *)current->data)->regs, sizeof(struct regs));
diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c
index dbb7033..c5570c3 100644
--- a/kernel/features/syscall.c
+++ b/kernel/features/syscall.c
@@ -37,7 +37,12 @@ void syscall_handler(struct regs *r)
break;
}
case SYS_READ: {
- r->eax = (u32)vfs_read((char *)r->ebx, (void *)r->ecx, r->edx, r->esi);
+ if (vfs_ready((char *)r->ebx)) {
+ r->eax = (u32)vfs_read((char *)r->ebx, (void *)r->ecx, r->edx, r->esi);
+ } else {
+ proc_current()->state = PROC_SLEEPING;
+ scheduler(r);
+ }
break;
}
case SYS_WRITE: {
diff --git a/kernel/inc/fs.h b/kernel/inc/fs.h
index ff14361..1b2b073 100644
--- a/kernel/inc/fs.h
+++ b/kernel/inc/fs.h
@@ -20,6 +20,7 @@ struct device {
void *data;
u32 (*read)(void *buf, u32 offset, u32 count, struct device *dev);
u32 (*write)(void *buf, u32 offset, u32 count, struct device *dev);
+ u32 (*ready)();
};
void device_install(void);
@@ -38,6 +39,7 @@ struct vfs {
u32 (*read)(const char *path, void *buf, u32 offset, u32 count, struct device *dev);
u32 (*write)(const char *path, void *buf, u32 offset, u32 count, struct device *dev);
u32 (*stat)(const char *path, struct stat *buf, struct device *dev);
+ u32 (*ready)(const char *path, struct device *dev);
};
struct mount_info {
@@ -53,6 +55,7 @@ u32 vfs_mount(struct device *dev, const char *path);
u32 vfs_read(const char *path, void *buf, u32 offset, u32 count);
u32 vfs_write(const char *path, void *buf, u32 offset, u32 count);
u32 vfs_stat(const char *path, struct stat *buf);
+u32 vfs_ready(const char *path);
/**
* EXT2
@@ -147,5 +150,6 @@ struct ext2_file {
u32 ext2_read(const char *path, void *buf, u32 offset, u32 count, struct device *dev);
u32 ext2_stat(const char *path, struct stat *buf, struct device *dev);
+u32 ext2_ready(const char *path, struct device *dev);
#endif
diff --git a/libc/inc/sys.h b/libc/inc/sys.h
index e345ce8..14f83dd 100644
--- a/libc/inc/sys.h
+++ b/libc/inc/sys.h
@@ -96,7 +96,7 @@ static inline u32 getpid()
return buf;
}
-// Hacky, one-digit solution - TODO!
+// Hacky one-digit solution - TODO!
#include <mem.h>
#include <str.h>
static inline u32 pidof(const char *name)