Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / drivers / console / vga.c
diff --git a/kitten/drivers/console/vga.c b/kitten/drivers/console/vga.c
new file mode 100644 (file)
index 0000000..55e8253
--- /dev/null
@@ -0,0 +1,144 @@
+#include <lwk/driver.h>
+#include <lwk/console.h>
+#include <lwk/string.h>
+
+/** Base address of the VGA frame buffer. */
+static volatile uint8_t * const vga_fb = (uint8_t *) 0xffffffff800b8000ul;
+
+/** Current cursor row coordinate. */
+static int row = 0;
+
+/** Current cursor column coordinate. */
+static int col = 0;
+
+/** Number of rows on the screen. */
+static int nrows = 25;
+
+/** Number of columns on the screen. */
+static int ncols = 80;
+
+/** Set when vga console has been initialized. */
+static int initialized = 0;
+
+/** Calculates the offset in the vga_fb corresponding to (row, col). */
+static inline int cursor(int row, int col)
+{
+       return (row * ncols * 2) + col * 2;
+}
+
+/**
+ * Scrolls everything on the screen up by one row.
+ */ 
+static void vga_scroll(void)
+{
+       int i;
+
+       // Move all existing lines up by one
+       memmove(
+               (void *) vga_fb,
+               (void *) (vga_fb + cursor(1, 0)),
+               (nrows - 1) * ncols * sizeof(uint16_t)
+       );
+
+       // Blank the new line at the bottom of the screen
+       for (i = 0; i < ncols; i++)
+               vga_fb[cursor(nrows-1, i)] = ' ';
+}
+
+/**
+ * Moves cursor to the next line.
+ */ 
+static void vga_newline(void)
+{
+       row = row + 1;
+       col = 0;
+
+       if (row == nrows) {
+               row = nrows - 1;
+               vga_scroll();
+       }
+}
+
+/**
+ * Sets the VGA font color.
+ */
+static void vga_set_font_color(uint8_t color)
+{
+       int i, j;
+       for (i = 0; i < nrows; i++)
+               for (j = 0; j < ncols; j++)
+                       vga_fb[cursor(i, j) + 1] = color;
+}
+
+/**
+ * Prints a single character to the screen.
+ */
+static void vga_putc(unsigned char c)
+{
+       // Print the character
+       vga_fb[cursor(row, col)] = c;
+
+       // Move cursor
+       if (++col == ncols)
+               vga_newline();
+}
+
+/**
+ * Writes a string to the screen at the current cursor location.
+ */
+static void vga_write(struct console *con, const char *str)
+{
+       unsigned char c;
+
+       while ((c = *str++) != '\0') {
+               switch (c) {
+                       case '\n':
+                               vga_newline();
+                               break;
+
+                       case '\t':
+                               /* Emulate a TAB */
+                               vga_putc(' ');
+                               while ((col % 8) != 0)
+                                       vga_putc(' ');
+                               break;
+
+                       default: 
+                               vga_putc(c);
+               }
+       }
+}
+
+/**
+ * VGA console device.
+ */
+static struct console vga_console = {
+       .name  = "VGA Console",
+       .write = vga_write
+};
+
+/**
+ * Initializes and registers the VGA console driver.
+ */
+void vga_console_init(void)
+{
+       if (initialized) {
+               printk(KERN_ERR "VGA console already initialized.\n");
+               return;
+       }
+
+       vga_set_font_color(0x0F /* White */);
+       console_register(&vga_console);
+       initialized = 1;
+}
+
+driver_init(vga_console_init);
+
+/**
+ * Sets the row on the screen to start printing at.
+ * This is used to avoid overwriting BIOS/boot messages.
+ * At least on x86-64, this is set automatically as part
+ * of the bootstrap process.
+ */
+driver_param(row, int);
+