Changed magic number from 0xE5 to I_VMMPC_POSTED
[akaros.git] / kern / arch / x86 / console.c
index 5ce619c..59503ee 100644 (file)
@@ -9,6 +9,7 @@
 #include <assert.h>
 #include <stdio.h>
 #include <sys/queue.h>
+#include <arch/topology.h>
 
 #include <ros/memlayout.h>
 
@@ -49,6 +50,11 @@ static int __serial_get_char(int com, uint8_t *data)
        if (!(inb(com + COM_LSR) & COM_LSR_DATA))
                return -1;
        *data = inb(com + COM_RX);
+       /* serial input sends \r a lot, but we interpret them as \n later on.  this
+        * will help userspace too, which isn't expecting the \rs.  the right answer
+        * might involve telling userspace what sort of console this is. */
+       if (*data == '\r')
+               *data = '\n';
        return 0;
 }
 
@@ -241,32 +247,32 @@ lpt_putc(int c)
 #define MAX_SCROLL_LENGTH      20
 #define SCROLLING_CRT_SIZE     (MAX_SCROLL_LENGTH * CRT_SIZE)
 
-static spinlock_t SRACY lock = SPINLOCK_INITIALIZER_IRQSAVE;
+static spinlock_t console_lock = SPINLOCK_INITIALIZER_IRQSAVE;
 
-static unsigned SREADONLY addr_6845;
-static uint16_t *SLOCKED(&lock) COUNT(CRT_SIZE) crt_buf;
-static uint16_t SLOCKED(&lock) crt_pos;
+static unsigned addr_6845;
+static uint16_t *crt_buf;
+static uint16_t crt_pos;
 
-static uint16_t (SLOCKED(&lock) scrolling_crt_buf)[SCROLLING_CRT_SIZE];
-static uint16_t SLOCKED(&lock) scrolling_crt_pos;
-static uint8_t SLOCKED(&lock) current_crt_buf;
+static uint16_t scrolling_crt_buf[SCROLLING_CRT_SIZE];
+static uint16_t scrolling_crt_pos;
+static uint8_t current_crt_buf;
 
 void
 cga_init(void)
 {
-       volatile uint16_t SLOCKED(&lock)*COUNT(CRT_SIZE) cp;
+       volatile uint16_t *cp;
        uint16_t was;
        unsigned pos;
 
-       cp = (uint16_t *COUNT(CRT_SIZE)) TC(KERNBASE + CGA_BUF);
+       cp = (uint16_t *)(KERNBASE + CGA_BUF);
        was = *cp;
        *cp = (uint16_t) 0xA55A;
        if (*cp != 0xA55A) {
-               cp = (uint16_t *COUNT(CRT_SIZE)) TC(KERNBASE + MONO_BUF);
-               addr_6845 = SINIT(MONO_BASE);
+               cp = (uint16_t *)(KERNBASE + MONO_BUF);
+               addr_6845 = MONO_BASE;
        } else {
                *cp = was;
-               addr_6845 = SINIT(CGA_BASE);
+               addr_6845 = CGA_BASE;
        }
        
        /* Extract cursor location */
@@ -275,7 +281,7 @@ cga_init(void)
        outb(addr_6845, 15);
        pos |= inb(addr_6845 + 1);
 
-       crt_buf = (uint16_t SLOCKED(&lock)*COUNT(CRT_SIZE)) cp;
+       crt_buf = (uint16_t*)cp;
        crt_pos = pos;
        scrolling_crt_pos = 0;
        current_crt_buf = 0;
@@ -401,7 +407,7 @@ cga_putc(int c)
 
 #define E0ESC          (1<<6)
 
-static uint8_t (SREADONLY shiftcode)[256] = 
+static uint8_t shiftcode[256] = 
 {
        [0x1D] CTL,
        [0x2A] SHIFT,
@@ -411,7 +417,7 @@ static uint8_t (SREADONLY shiftcode)[256] =
        [0xB8] ALT
 };
 
-static uint8_t (SREADONLY togglecode)[256] = 
+static uint8_t togglecode[256] = 
 {
        [0x3A] CAPSLOCK,
        [0x45] NUMLOCK,
@@ -479,7 +485,7 @@ static uint8_t ctlmap[256] =
        [0xD2] KEY_INS,         [0xD3] KEY_DEL
 };
 
-static uint8_t * COUNT(256) (SREADONLY charcode)[4] = {
+static uint8_t *charcode[4] = {
        normalmap,
        shiftmap,
        ctlmap,
@@ -490,13 +496,19 @@ static uint8_t * COUNT(256) (SREADONLY charcode)[4] = {
  * Get data from the keyboard.  If we finish a character, return it.  Else 0.
  * Return -1 if no data.
  */
-static uint32_t SLOCKED(&lock) shift;
-static bool SLOCKED(&lock) crt_scrolled = FALSE;
+static uint32_t shift;
+static bool crt_scrolled = FALSE;
 
 /* TODO: i'm concerned about the (lack of) locking when scrolling the screen. */
 static int
 kbd_proc_data(void)
 {
+#ifdef CONFIG_X86_DISABLE_KEYBOARD
+       /* on some machines with usb keyboards, any keyboard input triggers SMM
+        * interference on all of the cores. */
+       return -1;
+#endif /* CONFIG_X86_DISABLE_KEYBOARD */
+
        int c;
        uint8_t data;
 
@@ -522,6 +534,9 @@ kbd_proc_data(void)
                shift |= E0ESC;
                return 0;
        } else if (data & 0x80) {
+               /* TODO: need a better check for bad key releases */
+               if (data == 0xff)
+                       return -1;
                // Key released
                data = (shift & E0ESC ? data : data & 0x7F);
                shift &= ~(shiftcode[data] | E0ESC);
@@ -634,13 +649,28 @@ int cons_get_any_char(void)
 /* output a character to all console outputs (monitor and all serials) */
 void cons_putc(int c)
 {
-       spin_lock_irqsave(&lock);
+       void logbuf(int c);
+       #ifdef CONFIG_TRACE_LOCKS
+       int8_t irq_state = 0;
+       disable_irqsave(&irq_state);
+       __spin_lock(&console_lock);
+       #else
+       spin_lock_irqsave(&console_lock);
+       #endif
+
        #ifndef CONFIG_SERIAL_IO
                serial_spam_char(c);
        #endif
        //lpt_putc(c);  /* very slow on the nehalem */
        cga_putc(c);
-       spin_unlock_irqsave(&lock);
+       logbuf(c);
+
+       #ifdef CONFIG_TRACE_LOCKS
+       __spin_unlock(&console_lock);
+       enable_irqsave(&irq_state);
+       #else
+       spin_unlock_irqsave(&console_lock);
+       #endif
 }
 
 // `High'-level console I/O.  Used by readline and cprintf.
@@ -652,7 +682,7 @@ cputchar(int c)
 }
 
 void
-cputbuf(const char*COUNT(len) buf, int len)
+cputbuf(const char*buf, int len)
 {
        int i;
        for(i = 0; i < len; i++)