aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2024-05-14 00:17:03 -0400
committerIan Moffett <ian@osmora.org>2024-05-14 00:17:03 -0400
commit3980f6c5b6a637a290939ed53f00894d3aaa97b1 (patch)
treec08f9f011439ee30bf9b1113cc0b4efa9c8cd44c
parent49da408ed8c3d9903a67e0af113b38283862cb47 (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.h4
-rw-r--r--sys/kern/init_main.c6
-rw-r--r--sys/kern/kern_tty.c67
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);
+}