Remove the old console input code; use qio
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 5 Oct 2016 16:16:41 +0000 (12:16 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 6 Oct 2016 19:41:48 +0000 (15:41 -0400)
This removes all of console.{c,h}, replacing its functionality with a
basic qio queue in devcons.

Other than using qio instead of the homebrewed rings and sems, this
also uses qiwrite directly from interrupt context.  This avoids an
excessive kernel message.

There were also a couple monitor-related commands sitting around in
console.{c.h}, which I moved to monitor files.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
13 files changed:
kern/arch/riscv/console.c
kern/arch/riscv/trap.c
kern/arch/x86/init.c
kern/drivers/dev/cons.c
kern/drivers/dev/regress.c
kern/include/console.h [deleted file]
kern/include/monitor.h
kern/include/ns.h
kern/src/Kbuild
kern/src/console.c [deleted file]
kern/src/devfs.c
kern/src/init.c
kern/src/monitor.c

index 8aabab4..1f92e1a 100644 (file)
@@ -1,5 +1,4 @@
 #include <arch/console.h>
-#include <console.h>
 #include <pmap.h>
 #include <atomic.h>
 #include <smp.h>
@@ -42,8 +41,11 @@ cputchar(int c)
 int
 getchar(void)
 {
-       char c;
-       kb_get_from_buf(&cons_buf, &c, 1);
+       char c = 'x';
+
+       #warning "implement me"
+       /* maybe do a qio read */
+
        return c;
 }
 
index ed6fa7e..125a2ca 100644 (file)
@@ -2,7 +2,6 @@
 #include <assert.h>
 #include <trap.h>
 #include <arch/console.h>
-#include <console.h>
 #include <string.h>
 #include <process.h>
 #include <syscall.h>
@@ -139,11 +138,11 @@ static void exit_halt_loop(struct hw_trapframe *hw_tf)
 
 static void handle_keypress(char c)
 {
-       /* brho: not sure if this will work on riscv or not... */
-       #define capchar2ctl(x) ((x) - '@')
-       amr_t handler = c == capchar2ctl('G') ? __run_mon : __cons_add_char;
-       send_kernel_message(core_id(), handler, (long)&cons_buf, (long)c, 0,
-                           KMSG_ROUTINE);
+       #warning "fix me"
+       /* TODO: does cons_init need to be before cons_add_char?  Also, do something
+        * with CTRL-G, Q, and B. */
+       cons_add_char(c);
+
        cons_init();
 }
 
index 60fd72b..31a796e 100644 (file)
@@ -7,7 +7,6 @@
 #include <arch/console.h>
 #include <arch/perfmon.h>
 #include <arch/init.h>
-#include <console.h>
 #include <monitor.h>
 #include <arch/usb.h>
 #include <assert.h>
@@ -50,10 +49,7 @@ static void irq_console(struct hw_trapframe *hw_tf, void *data)
                        backtrace_hwtf(hw_tf);
                        return;
        }
-       /* Do our work in an RKM, instead of interrupt context.  Note the RKM will
-        * cast 'c' to a char. */
-       send_kernel_message(core_id(), __cons_add_char, (long)&cons_buf, (long)c,
-                           0, KMSG_ROUTINE);
+       cons_add_char(c);
 }
 
 static void cons_poller(void *arg)
index be55d83..2578b49 100644 (file)
@@ -34,6 +34,8 @@ atomic_t kprintinuse = 0;             /* test and set whether /dev/kprint is open */
 int iprintscreenputs = 1;
 int keepbroken = 1;
 
+struct queue *cons_q;                  /* Akaros cons input: keyboard, serial, etc */
+
 static uint8_t logbuffer[1 << 20];
 static int index = 0;
 static struct queue *logqueue = NULL;
@@ -678,6 +680,7 @@ int consreadstr(uint32_t off, char *buf, uint32_t n, char *str)
 static void consinit(void)
 {
        kstrdup(&sysname, "nanwan");
+       cons_q = qopen(256, 0, 0, 0);
 #if 0
        todinit();
 #endif
@@ -1468,3 +1471,8 @@ void killkid(void)
        send_posix_signal(victim, SIGINT);
        proc_decref(victim);
 }
+
+void cons_add_char(char c)
+{
+       qiwrite(cons_q, &c, sizeof(char));
+}
index f52b6d4..a71434e 100644 (file)
@@ -25,7 +25,7 @@
 #include <pmap.h>
 #include <smp.h>
 #include <ip.h>
-#include <console.h>
+#include <monitor.h>
 #include <ktest.h>
 
 struct dev regressdevtab;
diff --git a/kern/include/console.h b/kern/include/console.h
deleted file mode 100644 (file)
index 5f26839..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (c) 2012 The Regents of the University of California
- * Barret Rhoden <brho@cs.berkeley.edu>
- * See LICENSE for details.
- *
- * Console (Keyboard/serial/whatever) related functions. */
-
-#pragma once
-
-#include <atomic.h>
-#include <kthread.h>
-#include <trap.h>
-
-#define KB_BUF_SIZE 256        /* Make sure this is a power of 2 */
-
-/* Ring buffer for keyboard/character devices.  Might make a more generic
- * version in the future (allowing both sides to block, etc).  Adding will drop
- * any overflow, and getting will block til the full amount is read. */
-struct kb_buffer {
-       unsigned int prod_idx;
-       unsigned int cons_idx;
-       spinlock_t                                                      buf_lock;
-       struct semaphore                                        buf_sem;
-       char                                                            buf[KB_BUF_SIZE];
-};
-extern struct kb_buffer cons_buf;      /* kernel's console buffer */
-
-void kb_buf_init(struct kb_buffer *kb);
-/* These are not irq-safe.  and get will block. */
-void kb_add_to_buf(struct kb_buffer *kb, char c);
-void kb_get_from_buf(struct kb_buffer *kb, char *dst, size_t cnt);
-
-/* Kernel messages associated with the console.  Arch-specific interrupt
- * handlers need to call these.  For add char, a0 = &cons_buf and a1 = the char
- * you read.  Call __run_mon on your 'magic' input.  */
-void __cons_add_char(uint32_t srcid, long a0, long a1, long a2);
-void __run_mon(uint32_t srcid, long a0, long a1, long a2);
-
-/* function to run one command. */
-int onecmd(int argc, char *argv[], struct hw_trapframe *hw_tf);
index 94c8f0d..0235980 100644 (file)
@@ -8,6 +8,8 @@
 // (NULL if none).
 void monitor(struct hw_trapframe *hw_tf);
 void emit_monitor_backtrace(int type, void *tf);
+int onecmd(int argc, char *argv[], struct hw_trapframe *hw_tf);
+void __run_mon(uint32_t srcid, long a0, long a1, long a2);
 
 // Functions implementing monitor commands.
 int mon_help(int argc, char **argv, struct hw_trapframe *hw_tf);
index 5ccd0de..9e44780 100644 (file)
@@ -682,6 +682,7 @@ void cnameclose(struct cname *);
 struct block *concatblock(struct block *);
 struct block *linearizeblock(struct block *b);
 void confinit(void);
+void cons_add_char(char c);
 void copen(struct chan *);
 struct block *copyblock(struct block *b, int mem_flags);
 int cread(struct chan *, uint8_t * unused_uint8_p_t, int unused_int, int64_t);
index ada8815..07b6f24 100644 (file)
@@ -29,7 +29,6 @@ obj-y                                         += build_info.o
 obj-y                                          += ceq.o
 obj-y                                          += colored_caches.o
 obj-y                                          += completion.o
-obj-y                                          += console.o
 obj-y                                          += coreprov.o
 obj-y                                          += ctype.o
 obj-y                                          += devfs.o
diff --git a/kern/src/console.c b/kern/src/console.c
deleted file mode 100644 (file)
index 080f2f9..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Copyright (c) 2012 The Regents of the University of California
- * Barret Rhoden <brho@cs.berkeley.edu>
- * See LICENSE for details.
- *
- * Console (Keyboard/serial/whatever) related functions. */
-
-#include <console.h>
-#include <ros/ring_buffer.h>
-#include <monitor.h>
-#include <stdio.h>
-
-struct kb_buffer cons_buf;
-
-void kb_buf_init(struct kb_buffer *kb)
-{
-       kb->prod_idx = 0;
-       kb->cons_idx = 0;
-       spinlock_init(&kb->buf_lock);
-       sem_init(&kb->buf_sem, 0);
-       /* no need to memset the buffer - we only read something that is written */
-}
-
-/* Producers don't block - their input is dropped.  Should be rare for now; if
- * it happens, it's probably a bug. */
-void kb_add_to_buf(struct kb_buffer *kb, char c)
-{
-       /* make sure we're a power of 2 */
-       static_assert(KB_BUF_SIZE == __RD32(KB_BUF_SIZE));
-       bool was_empty = FALSE;
-       spin_lock(&kb->buf_lock);
-       if (!__ring_full(KB_BUF_SIZE, kb->prod_idx, kb->cons_idx)) {
-               if (__ring_empty(kb->prod_idx, kb->cons_idx))
-                       was_empty = TRUE;
-               kb->buf[kb->prod_idx % KB_BUF_SIZE] = c;        // compiler should shift
-               kb->prod_idx++;
-       } else {
-               /* else drop the char */
-               printk("[kernel] KB buffer overflowed %c\n", c);
-       }
-       spin_unlock(&kb->buf_lock);
-       /* up the sem when it goes from empty->non_empty.   rule for syncing with
-        * blockers: if there are any items in the buffer, either the sem is upped,
-        * or there is an active consumer.  consumers immediately down (to become an
-        * active consumer). */
-       if (was_empty)
-               sem_up(&kb->buf_sem);
-       /* also note that multiple readers on the console/serial are going to fight
-        * for input and it is going to get interleaved - broader issue */
-}
-
-/* Will read cnt chars from the KB buf into dst.  Will block until complete. */
-void kb_get_from_buf(struct kb_buffer *kb, char *dst, size_t cnt)
-{
-       unsigned int dst_idx = 0; /* aka, amt copied so far */
-       bool need_an_up = FALSE;
-
-       /* so long as we still need items, we'll sleep til there is activity, then
-        * grab everything we can til the kb buf is empty (or we're done).  If we
-        * didn't empty the buf, we'll need to up the sem later. */
-       while (dst_idx < cnt) {
-               /* this will return immediately if some data is already there, o/w we
-                * block til there is some activity */
-               sem_down(&kb->buf_sem);
-               spin_lock(&kb->buf_lock);
-               /* under the current scheme, we should only have one active consumer at
-                * a time, so if we woke up, the ring must not be empty. */
-               assert(!__ring_empty(kb->prod_idx, kb->cons_idx));
-               while (!__ring_empty(kb->prod_idx, kb->cons_idx)) {
-                       if (dst_idx == cnt) {
-                               /* we're done, and it's not empty yet */
-                               need_an_up = TRUE;
-                               break;
-                       }
-                       dst[dst_idx] = kb->buf[kb->cons_idx % KB_BUF_SIZE];
-                       kb->cons_idx++;
-                       dst_idx++;
-               }
-               spin_unlock(&kb->buf_lock);
-       }
-       /* Remember: if the buf is non empty, there is either an active consumer or
-        * the sem is upped. */
-       if (need_an_up)
-               sem_up(&kb->buf_sem);
-}
-
-/* Kernel messages associated with the console.  Arch-specific interrupt
- * handlers need to call these.  For add char, a0 = &cons_buf and a1 = the char
- * you read.  Call __run_mon on your 'magic' input.  */
-void __cons_add_char(uint32_t srcid, long a0, long a1, long a2)
-{
-       kb_add_to_buf((struct kb_buffer*)a0, (char)a1);
-}
-
-void __run_mon(uint32_t srcid, long a0, long a1, long a2)
-{
-       monitor(0);
-}
index fde7351..e6edaee 100644 (file)
@@ -14,7 +14,7 @@
 #include <smp.h>
 #include <umem.h>
 #include <kmalloc.h>
-#include <console.h>
+#include <ns.h>
 
 /* These structs are declared again and initialized farther down */
 struct file_operations dev_f_op_stdin;
@@ -81,17 +81,11 @@ ssize_t dev_stdin_read(struct file *file, char *buf, size_t count,
                        off64_t *offset)
 {
        char c;
-       extern struct kb_buffer cons_buf;
+       extern struct queue *cons_q;
 
        if (!count)
                return 0;
-       kb_get_from_buf(&cons_buf, &c, 1);
-       /* TODO UMEM */
-       if (current)
-               memcpy_to_user_errno(current, buf, &c, 1);
-       else
-               memcpy(buf, &c, 1);
-       return 1;
+       return qread(cons_q, buf, count);
 }
 
 ssize_t dev_stdout_write(struct file *file, const char *buf, size_t count,
index 9ab93fc..e1a8185 100644 (file)
@@ -41,7 +41,6 @@
 #include <blockdev.h>
 #include <ext2fs.h>
 #include <kthread.h>
-#include <console.h>
 #include <linker_func.h>
 #include <ip.h>
 #include <acpi.h>
@@ -159,7 +158,6 @@ void kernel_init(multiboot_info_t *mboot_info)
        vfs_init();
        devfs_init();
        time_init();
-       kb_buf_init(&cons_buf);
        arch_init();
        block_init();
        enable_irq();
index 218b872..9d78646 100644 (file)
@@ -4,7 +4,6 @@
 #include <arch/arch.h>
 #include <stab.h>
 #include <smp.h>
-#include <console.h>
 #include <arch/console.h>
 
 #include <stdio.h>
@@ -854,6 +853,11 @@ int onecmd(int argc, char *argv[], struct hw_trapframe *hw_tf) {
        return -1;
 }
 
+void __run_mon(uint32_t srcid, long a0, long a1, long a2)
+{
+       monitor(0);
+}
+
 static int runcmd(char *real_buf, struct hw_trapframe *hw_tf) {
        char * buf = real_buf;
        int argc;