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
1 #include <lwk/driver.h>
2 #include <lwk/console.h>
3 #include <lwk/string.h>
4
5 /** Base address of the VGA frame buffer. */
6 static volatile uint8_t * const vga_fb = (uint8_t *) 0xffffffff800b8000ul;
7
8 /** Current cursor row coordinate. */
9 static int row = 0;
10
11 /** Current cursor column coordinate. */
12 static int col = 0;
13
14 /** Number of rows on the screen. */
15 static int nrows = 25;
16
17 /** Number of columns on the screen. */
18 static int ncols = 80;
19
20 /** Set when vga console has been initialized. */
21 static int initialized = 0;
22
23 /** Calculates the offset in the vga_fb corresponding to (row, col). */
24 static inline int cursor(int row, int col)
25 {
26         return (row * ncols * 2) + col * 2;
27 }
28
29 /**
30  * Scrolls everything on the screen up by one row.
31  */ 
32 static void vga_scroll(void)
33 {
34         int i;
35
36         // Move all existing lines up by one
37         memmove(
38                 (void *) vga_fb,
39                 (void *) (vga_fb + cursor(1, 0)),
40                 (nrows - 1) * ncols * sizeof(uint16_t)
41         );
42
43         // Blank the new line at the bottom of the screen
44         for (i = 0; i < ncols; i++)
45                 vga_fb[cursor(nrows-1, i)] = ' ';
46 }
47
48 /**
49  * Moves cursor to the next line.
50  */ 
51 static void vga_newline(void)
52 {
53         row = row + 1;
54         col = 0;
55
56         if (row == nrows) {
57                 row = nrows - 1;
58                 vga_scroll();
59         }
60 }
61
62 /**
63  * Sets the VGA font color.
64  */
65 static void vga_set_font_color(uint8_t color)
66 {
67         int i, j;
68         for (i = 0; i < nrows; i++)
69                 for (j = 0; j < ncols; j++)
70                         vga_fb[cursor(i, j) + 1] = color;
71 }
72
73 /**
74  * Prints a single character to the screen.
75  */
76 static void vga_putc(unsigned char c)
77 {
78         // Print the character
79         vga_fb[cursor(row, col)] = c;
80
81         // Move cursor
82         if (++col == ncols)
83                 vga_newline();
84 }
85
86 /**
87  * Writes a string to the screen at the current cursor location.
88  */
89 static void vga_write(struct console *con, const char *str)
90 {
91         unsigned char c;
92
93         while ((c = *str++) != '\0') {
94                 switch (c) {
95                         case '\n':
96                                 vga_newline();
97                                 break;
98
99                         case '\t':
100                                 /* Emulate a TAB */
101                                 vga_putc(' ');
102                                 while ((col % 8) != 0)
103                                         vga_putc(' ');
104                                 break;
105
106                         default: 
107                                 vga_putc(c);
108                 }
109         }
110 }
111
112 /**
113  * VGA console device.
114  */
115 static struct console vga_console = {
116         .name  = "VGA Console",
117         .write = vga_write
118 };
119
120 /**
121  * Initializes and registers the VGA console driver.
122  */
123 void vga_console_init(void)
124 {
125         if (initialized) {
126                 printk(KERN_ERR "VGA console already initialized.\n");
127                 return;
128         }
129
130         vga_set_font_color(0x0F /* White */);
131         console_register(&vga_console);
132         initialized = 1;
133 }
134
135 driver_init(vga_console_init);
136
137 /**
138  * Sets the row on the screen to start printing at.
139  * This is used to avoid overwriting BIOS/boot messages.
140  * At least on x86-64, this is set automatically as part
141  * of the bootstrap process.
142  */
143 driver_param(row, int);
144