From 3980f6c5b6a637a290939ed53f00894d3aaa97b1 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Tue, 14 May 2024 00:17:03 -0400 Subject: kernel: tty: Add tty_attach() This commit adds a new routine called tty_attach(). This routine allows a TTY to be registered with the system and have a device file associated with it. Signed-off-by: Ian Moffett --- sys/include/sys/tty.h | 4 +++ sys/kern/init_main.c | 6 +++++ sys/kern/kern_tty.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/sys/include/sys/tty.h b/sys/include/sys/tty.h index 2700abc..4a2c9ec 100644 --- a/sys/include/sys/tty.h +++ b/sys/include/sys/tty.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #define TTY_RING_SIZE 32 @@ -44,14 +45,17 @@ struct tty_ring { }; struct tty { + dev_t id; struct vcons_screen *scr; /* Console screen */ struct tty_ring ring; /* Input ring */ struct spinlock rlock; /* Ring lock */ struct termios termios; /* Termios structure */ + struct device *dev; /* Device pointer */ }; extern struct tty g_root_tty; +dev_t tty_attach(struct tty *tty); int tty_putc(struct tty *tty, int c); ssize_t tty_flush(struct tty *tty); diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index c78d401..5a0a64b 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -76,6 +77,7 @@ void main(void) { struct cpu_info *ci; + int status; __TRY_CALL(pre_init); syslog_init(); @@ -93,6 +95,10 @@ main(void) vfs_init(); + /* Attach the root TTY */ + if ((status = tty_attach(&g_root_tty)) < 0) + kprintf("Failed to attach root TTY (got %d)\n", status); + DRIVERS_INIT(); sched_init(); diff --git a/sys/kern/kern_tty.c b/sys/kern/kern_tty.c index 146ace0..39b94f7 100644 --- a/sys/kern/kern_tty.c +++ b/sys/kern/kern_tty.c @@ -31,7 +31,10 @@ #include #include #include +#include +#include +static dev_t tty_major = 0; struct tty g_root_tty = { .scr = &g_syslog_screen, .ring = { @@ -40,6 +43,14 @@ struct tty g_root_tty = { } }; +static inline dev_t +tty_alloc_id(void) +{ + static dev_t id = 1; + + return id++; +} + /* * Flushes the TTY ring buffer. * @@ -70,6 +81,33 @@ __tty_flush(struct tty *tty) return count; } +/* + * Device structure routine for reading a + * TTY device file. + */ +static int +tty_dev_read(struct device *dev, struct sio_txn *sio) +{ + struct tty_ring *ring = &g_root_tty.ring; + size_t len; + + spinlock_acquire(&g_root_tty.rlock); + len = (ring->enq_index - ring->deq_index); + + /* + * Transfer data from the TTY ring with SIO and + * flush it. + * + * TODO: As of now we are just reading the root + * TTY, add support for multiple TTYs. + */ + memcpy(sio->buf, ring->data, len); + __tty_flush(&g_root_tty); + + spinlock_release(&g_root_tty.rlock); + return len; +} + /* * Serialized wrapper over __tty_flush() */ @@ -106,3 +144,32 @@ tty_putc(struct tty *tty, int c) spinlock_release(&tty->rlock); return 0; } + +dev_t +tty_attach(struct tty *tty) +{ + int tmp; + char devname[128]; + struct device *dev = device_alloc(); + + if (dev == NULL) + return -ENOMEM; + + /* + * Allocate a major for the driver if we don't + * have one yet. + */ + if (tty_major == 0) + tty_major = device_alloc_major(); + + /* Now try to create the device */ + tty->id = tty_alloc_id(); + if ((tmp = device_create(dev, tty_major, tty->id)) < 0) + return tmp; + + dev->read = tty_dev_read; + dev->blocksize = 1; + + snprintf(devname, sizeof(devname), "tty%d", tty->id); + return devfs_add_dev(devname, dev); +} -- cgit v1.2.3