diff options
author | Ian Moffett <ian@osmora.org> | 2024-05-14 00:17:03 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-05-14 00:17:03 -0400 |
commit | 3980f6c5b6a637a290939ed53f00894d3aaa97b1 (patch) | |
tree | c08f9f011439ee30bf9b1113cc0b4efa9c8cd44c | |
parent | 49da408ed8c3d9903a67e0af113b38283862cb47 (diff) |
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 <ian@osmora.org>
-rw-r--r-- | sys/include/sys/tty.h | 4 | ||||
-rw-r--r-- | sys/kern/init_main.c | 6 | ||||
-rw-r--r-- | sys/kern/kern_tty.c | 67 |
3 files changed, 77 insertions, 0 deletions
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 <sys/types.h> #include <sys/termios.h> #include <sys/spinlock.h> +#include <sys/device.h> #include <dev/vcons/vcons.h> #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 <sys/machdep.h> #include <sys/timer.h> #include <sys/sched.h> +#include <sys/tty.h> #include <sys/vfs.h> #include <sys/driver.h> #include <machine/cpu_mp.h> @@ -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 <sys/cdefs.h> #include <sys/errno.h> #include <sys/syslog.h> +#include <fs/devfs.h> +#include <string.h> +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. * @@ -71,6 +82,33 @@ __tty_flush(struct tty *tty) } /* + * 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() */ ssize_t @@ -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); +} |