summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordzwdz2022-04-07 21:13:00 +0200
committerdzwdz2022-04-07 21:13:00 +0200
commitda2bbef4e4f586ecf13cd5ffe9a62df3114a3483 (patch)
treec65b48e250f803938c82239a0919b8a92ee0b826 /src
parentdf2c9dbc694fb4718fc4905b9af3331dbf73bfb2 (diff)
kernel: add a /com1 device
Diffstat (limited to 'src')
-rw-r--r--src/kernel/arch/i386/driver/serial.c (renamed from src/kernel/arch/i386/tty/serial.c)15
-rw-r--r--src/kernel/arch/i386/driver/serial.h9
-rw-r--r--src/kernel/arch/i386/tty/serial.h7
-rw-r--r--src/kernel/arch/i386/tty/tty.c12
-rw-r--r--src/kernel/vfs/root.c25
5 files changed, 49 insertions, 19 deletions
diff --git a/src/kernel/arch/i386/tty/serial.c b/src/kernel/arch/i386/driver/serial.c
index 054f956..d2c34e7 100644
--- a/src/kernel/arch/i386/tty/serial.c
+++ b/src/kernel/arch/i386/driver/serial.c
@@ -1,5 +1,6 @@
+#include <kernel/arch/i386/driver/serial.h>
+#include <kernel/arch/i386/interrupts/irq.h>
#include <kernel/arch/i386/port_io.h>
-#include <kernel/arch/i386/tty/serial.h>
#include <kernel/panic.h>
#include <stdint.h>
@@ -40,6 +41,18 @@ bool serial_poll_read(char *c) {
return true;
}
+size_t serial_read(char *buf, size_t len) {
+ irq_interrupt_flag(true);
+ for (size_t i = 0; i < len; i++) {
+ for (;;) {
+ if (serial_poll_read(&buf[i])) break;
+ asm("hlt" ::: "memory");
+ }
+ }
+ irq_interrupt_flag(false);
+ return len;
+}
+
void serial_write(const char *buf, size_t len) {
for (size_t i = 0; i < len; i++)
serial_putchar(buf[i]);
diff --git a/src/kernel/arch/i386/driver/serial.h b/src/kernel/arch/i386/driver/serial.h
new file mode 100644
index 0000000..be738d1
--- /dev/null
+++ b/src/kernel/arch/i386/driver/serial.h
@@ -0,0 +1,9 @@
+#pragma once
+#include <stdbool.h>
+#include <stddef.h>
+
+void serial_init(void);
+size_t serial_read(char *buf, size_t len);
+void serial_write(const char *buf, size_t len);
+
+bool serial_poll_read(char *c);
diff --git a/src/kernel/arch/i386/tty/serial.h b/src/kernel/arch/i386/tty/serial.h
deleted file mode 100644
index 808f1aa..0000000
--- a/src/kernel/arch/i386/tty/serial.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-#include <stdbool.h>
-#include <stddef.h>
-
-bool serial_poll_read(char *c);
-void serial_write(const char *buf, size_t len);
-void serial_init(void);
diff --git a/src/kernel/arch/i386/tty/tty.c b/src/kernel/arch/i386/tty/tty.c
index ebe0fd3..ab15aba 100644
--- a/src/kernel/arch/i386/tty/tty.c
+++ b/src/kernel/arch/i386/tty/tty.c
@@ -1,5 +1,4 @@
-#include <kernel/arch/i386/interrupts/irq.h>
-#include <kernel/arch/i386/tty/serial.h>
+#include <kernel/arch/i386/driver/serial.h>
#include <kernel/arch/i386/tty/vga.h>
#include <kernel/arch/io.h>
@@ -13,14 +12,7 @@ void tty_init(void) {
}
void tty_read(char *buf, size_t len) {
- irq_interrupt_flag(true);
- for (size_t i = 0; i < len; i++) {
- for (;;) {
- if (serial_poll_read(&buf[i])) break;
- asm("hlt" ::: "memory");
- }
- }
- irq_interrupt_flag(false);
+ serial_read(buf, len);
}
void tty_write(const char *buf, size_t len) {
diff --git a/src/kernel/vfs/root.c b/src/kernel/vfs/root.c
index 8904c4b..b8b41fc 100644
--- a/src/kernel/vfs/root.c
+++ b/src/kernel/vfs/root.c
@@ -1,5 +1,6 @@
#include <kernel/arch/i386/ata.h>
#include <kernel/arch/i386/driver/ps2.h>
+#include <kernel/arch/i386/driver/serial.h>
#include <kernel/mem/virt.h>
#include <kernel/panic.h>
#include <kernel/proc.h>
@@ -13,6 +14,7 @@ enum {
HANDLE_ROOT,
HANDLE_TTY,
HANDLE_VGA,
+ HANDLE_COM1,
HANDLE_PS2,
HANDLE_ATA_ROOT,
HANDLE_ATA,
@@ -61,6 +63,7 @@ int vfs_root_handler(struct vfs_request *req) {
if (exacteq(req, "/tty")) return HANDLE_TTY;
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;
@@ -79,7 +82,12 @@ int vfs_root_handler(struct vfs_request *req) {
switch (req->id) {
case HANDLE_ROOT: {
// TODO document directory read format
- const char src[] = "tty\0vga\0ata/";
+ const char src[] =
+ "tty\0"
+ "vga\0"
+ "com1\0"
+ "ps2\0"
+ "ata/";
if (req->output.len < 0) return 0; // is this needed? TODO make that a size_t or something
int len = min((size_t) req->output.len, sizeof(src));
virt_cpy_to(req->caller->pages, req->output.buf, src, len);
@@ -100,6 +108,12 @@ int vfs_root_handler(struct vfs_request *req) {
vga + req->offset, req->output.len);
return req->output.len;
}
+ case HANDLE_COM1: {
+ char buf[16];
+ size_t len = serial_read(buf, sizeof buf);
+ virt_cpy_to(req->caller->pages, req->output.buf, buf, len);
+ return len;
+ }
case HANDLE_PS2: {
uint8_t buf[16];
size_t len = ps2_read(buf, sizeof buf);
@@ -151,7 +165,16 @@ int vfs_root_handler(struct vfs_request *req) {
req->input.buf, req->input.len);
return req->input.len;
}
+ case HANDLE_COM1: {
+ struct virt_iter iter;
+ virt_iter_new(&iter, req->input.buf, req->input.len,
+ req->caller->pages, true, false);
+ while (virt_iter_next(&iter))
+ serial_write(iter.frag, iter.frag_len);
+ return iter.prior;
+ }
case HANDLE_ATA_ROOT: return -1;
+ // TODO don't panic on ps2 reads
default: panic_invalid_state();
}