boot_vga.c (8e6d016f) boot_vga.c (29a77b73)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 17 unchanged lines hidden (view full) ---

26
27/*
28 * Miniature VGA driver for bootstrap.
29 */
30
31#include <sys/archsystm.h>
32#include <sys/vgareg.h>
33#include <sys/framebuffer.h>
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 17 unchanged lines hidden (view full) ---

26
27/*
28 * Miniature VGA driver for bootstrap.
29 */
30
31#include <sys/archsystm.h>
32#include <sys/vgareg.h>
33#include <sys/framebuffer.h>
34#include <sys/boot_console.h>
35#include "boot_console_impl.h"
34
35#include "boot_console_impl.h"
36#if defined(_BOOT)
37#include "../dboot/dboot_asm.h"
38#include "../dboot/dboot_xboot.h"
39#endif
40
41#if defined(__xpv) && defined(_BOOT)
42
43/*
44 * Device memory address
45 *
46 * In dboot under the hypervisor we don't have any memory mappings
47 * for the first meg of low memory so we can't access devices there.
48 * Intead we've mapped the device memory that we need to access into
49 * a local variable within dboot so we can access the device memory
50 * there.
51 */
52extern unsigned short *video_fb;
36
37#include "boot_console_impl.h"
38#if defined(_BOOT)
39#include "../dboot/dboot_asm.h"
40#include "../dboot/dboot_xboot.h"
41#endif
42
43#if defined(__xpv) && defined(_BOOT)
44
45/*
46 * Device memory address
47 *
48 * In dboot under the hypervisor we don't have any memory mappings
49 * for the first meg of low memory so we can't access devices there.
50 * Intead we've mapped the device memory that we need to access into
51 * a local variable within dboot so we can access the device memory
52 * there.
53 */
54extern unsigned short *video_fb;
53#define VGA_SCREEN ((unsigned short *)video_fb)
55#define VGA_SCREEN (video_fb)
54
55#else /* __xpv && _BOOT */
56
57/* Device memory address */
58#define VGA_SCREEN ((uint16_t *)(VGA_MEM_ADDR + VGA_COLOR_BASE))
59
60#endif /* __xpv && _BOOT */
61
56
57#else /* __xpv && _BOOT */
58
59/* Device memory address */
60#define VGA_SCREEN ((uint16_t *)(VGA_MEM_ADDR + VGA_COLOR_BASE))
61
62#endif /* __xpv && _BOOT */
63
64static int cons_color = CONS_COLOR;
62
63static void vga_init(void);
65
66static void vga_init(void);
64static void vga_cursor_display(void);
67static void vga_drawc(int);
68static void vga_setpos(int, int);
69static void vga_getpos(int *, int *);
70static void vga_scroll(int);
65static void vga_clear(int);
71static void vga_clear(int);
72static void vga_shiftline(int);
73static void vga_eraseline(void);
74static void vga_cursor_display(boolean_t);
75
66static void vga_set_crtc(int index, unsigned char val);
67static unsigned char vga_get_crtc(int index);
68static void vga_set_atr(int index, unsigned char val);
69static unsigned char vga_get_atr(int index);
70
76static void vga_set_crtc(int index, unsigned char val);
77static unsigned char vga_get_crtc(int index);
78static void vga_set_atr(int index, unsigned char val);
79static unsigned char vga_get_atr(int index);
80
81static int
82get_vga_color(void)
83{
84 int color;
85 uint32_t fg, bg;
86 uint8_t solaris_color_to_pc_color[16] = {
87 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
88 };
89
90 boot_get_color(&fg, &bg);
91 color = solaris_color_to_pc_color[bg] << 4;
92 color |= solaris_color_to_pc_color[fg];
93 return (color);
94}
95
71void
96void
72boot_vga_init(int cons_color)
97boot_vga_init(bcons_dev_t *bcons_dev)
73{
74 fb_info.terminal.x = VGA_TEXT_COLS;
75 fb_info.terminal.y = VGA_TEXT_ROWS;
98{
99 fb_info.terminal.x = VGA_TEXT_COLS;
100 fb_info.terminal.y = VGA_TEXT_ROWS;
101 cons_color = get_vga_color();
76
77#if defined(_BOOT)
78 /*
79 * Note that we have to enable the cursor before clearing the
80 * screen since the cursor position is dependant upon the cursor
81 * skew, which is initialized by vga_cursor_display()
82 */
83 vga_init();
84 fb_info.cursor.visible = B_FALSE;
102
103#if defined(_BOOT)
104 /*
105 * Note that we have to enable the cursor before clearing the
106 * screen since the cursor position is dependant upon the cursor
107 * skew, which is initialized by vga_cursor_display()
108 */
109 vga_init();
110 fb_info.cursor.visible = B_FALSE;
85 vga_cursor_display();
111 vga_cursor_display(B_TRUE);
86
87 /*
88 * In general we should avoid resetting the display during the boot,
89 * we may have valueable messages there, this why the "native" loader
90 * boot does pass the console state down to kernel and we do try to
91 * pick the state. However, the loader is not the only way to boot.
92 * The non-native boot loaders do not implement the smooth console.
93 * If we have no information about cursor location, we will get value
94 * (0, 0) and that means we better clear the screen.
95 */
96 if (fb_info.cursor.pos.x == 0 && fb_info.cursor.pos.y == 0)
97 vga_clear(cons_color);
98 vga_setpos(fb_info.cursor.pos.y, fb_info.cursor.pos.x);
99#endif /* _BOOT */
112
113 /*
114 * In general we should avoid resetting the display during the boot,
115 * we may have valueable messages there, this why the "native" loader
116 * boot does pass the console state down to kernel and we do try to
117 * pick the state. However, the loader is not the only way to boot.
118 * The non-native boot loaders do not implement the smooth console.
119 * If we have no information about cursor location, we will get value
120 * (0, 0) and that means we better clear the screen.
121 */
122 if (fb_info.cursor.pos.x == 0 && fb_info.cursor.pos.y == 0)
123 vga_clear(cons_color);
124 vga_setpos(fb_info.cursor.pos.y, fb_info.cursor.pos.x);
125#endif /* _BOOT */
126
127 bcons_dev->bd_putchar = vga_drawc;
128 bcons_dev->bd_eraseline = vga_eraseline;
129 bcons_dev->bd_cursor = vga_cursor_display;
130 bcons_dev->bd_setpos = vga_setpos;
131 bcons_dev->bd_shift = vga_shiftline;
100}
101
102static void
103vga_init(void)
104{
105 unsigned char val;
106
107 /* set 16bit colors */
108 val = vga_get_atr(VGA_ATR_MODE);
109 val &= ~VGA_ATR_MODE_BLINK;
110 val &= ~VGA_ATR_MODE_9WIDE;
111 vga_set_atr(VGA_ATR_MODE, val);
112}
113
114static void
132}
133
134static void
135vga_init(void)
136{
137 unsigned char val;
138
139 /* set 16bit colors */
140 val = vga_get_atr(VGA_ATR_MODE);
141 val &= ~VGA_ATR_MODE_BLINK;
142 val &= ~VGA_ATR_MODE_9WIDE;
143 vga_set_atr(VGA_ATR_MODE, val);
144}
145
146static void
115vga_cursor_display(void)
147vga_cursor_display(boolean_t visible)
116{
117 unsigned char val, msl;
118
148{
149 unsigned char val, msl;
150
151 if (fb_info.cursor.visible == visible)
152 return;
153
119 /*
120 * Figure out the maximum scan line value. We need this to set the
121 * cursor size.
122 */
123 msl = vga_get_crtc(VGA_CRTC_MAX_S_LN) & 0x1f;
124
125 /*
126 * Enable the cursor and set it's size. Preserve the upper two
127 * bits of the control register.
128 * - Bits 0-4 are the starting scan line of the cursor.
129 * Scanning is done from top-to-bottom. The top-most scan
130 * line is 0 and the bottom most scan line is the maximum scan
131 * line value.
132 * - Bit 5 is the cursor disable bit.
133 */
134 val = vga_get_crtc(VGA_CRTC_CSSL) & 0xc0;
154 /*
155 * Figure out the maximum scan line value. We need this to set the
156 * cursor size.
157 */
158 msl = vga_get_crtc(VGA_CRTC_MAX_S_LN) & 0x1f;
159
160 /*
161 * Enable the cursor and set it's size. Preserve the upper two
162 * bits of the control register.
163 * - Bits 0-4 are the starting scan line of the cursor.
164 * Scanning is done from top-to-bottom. The top-most scan
165 * line is 0 and the bottom most scan line is the maximum scan
166 * line value.
167 * - Bit 5 is the cursor disable bit.
168 */
169 val = vga_get_crtc(VGA_CRTC_CSSL) & 0xc0;
170
171 if (visible == B_FALSE)
172 val |= (1 << 5);
173
135 vga_set_crtc(VGA_CRTC_CSSL, val);
136
137 /*
138 * Continue setting the cursors size.
139 * - Bits 0-4 are the ending scan line of the cursor.
140 * Scanning is done from top-to-bottom. The top-most scan
141 * line is 0 and the bottom most scan line is the maximum scan
142 * line value.
143 * - Bits 5-6 are the cursor skew.
144 */
145 vga_set_crtc(VGA_CRTC_CESL, msl);
146}
147
174 vga_set_crtc(VGA_CRTC_CSSL, val);
175
176 /*
177 * Continue setting the cursors size.
178 * - Bits 0-4 are the ending scan line of the cursor.
179 * Scanning is done from top-to-bottom. The top-most scan
180 * line is 0 and the bottom most scan line is the maximum scan
181 * line value.
182 * - Bits 5-6 are the cursor skew.
183 */
184 vga_set_crtc(VGA_CRTC_CESL, msl);
185}
186
148
149static void
187static void
150vga_clear(int color)
188vga_eraseline_impl(int x, int y, int color)
151{
189{
152 unsigned short val;
190 unsigned short val, *buf;
153 int i;
154
191 int i;
192
193 buf = VGA_SCREEN + x + y * VGA_TEXT_COLS;
155 val = (color << 8) | ' ';
194 val = (color << 8) | ' ';
195 for (i = x; i < VGA_TEXT_COLS; i++)
196 buf[i] = val;
197}
156
198
157 for (i = 0; i < VGA_TEXT_ROWS * VGA_TEXT_COLS; i++) {
158 VGA_SCREEN[i] = val;
199static void
200vga_eraseline(void)
201{
202 int x, y;
203
204 x = fb_info.cursor.pos.x;
205 y = fb_info.cursor.pos.y;
206 vga_eraseline_impl(x, y, cons_color);
207}
208
209static void
210vga_shiftline(int chars)
211{
212 unsigned short *src, *dst;
213 int x, y, len;
214
215 x = fb_info.cursor.pos.x;
216 y = fb_info.cursor.pos.y;
217 len = VGA_TEXT_COLS - x - chars;
218 if (len <= 0)
219 return;
220
221 src = VGA_SCREEN + x + y * VGA_TEXT_COLS;
222 dst = src + chars;
223 if (dst <= src) {
224 do {
225 *dst++ = *src++;
226 } while (--len != 0);
227 } else {
228 dst += len;
229 src += len;
230 do {
231 *--dst = *--src;
232 } while (--len != 0);
159 }
160}
161
233 }
234}
235
162void
163vga_drawc(int c, int color)
236static void
237vga_clear(int color)
164{
238{
239 int i;
240
241 for (i = 0; i < VGA_TEXT_ROWS; i++)
242 vga_eraseline_impl(0, i, color);
243}
244
245static void
246vga_drawc(int c)
247{
165 int row;
166 int col;
167
168 vga_getpos(&row, &col);
248 int row;
249 int col;
250
251 vga_getpos(&row, &col);
169 VGA_SCREEN[row*VGA_TEXT_COLS + col] = (color << 8) | c;
252
253 if (c == '\n') {
254 if (row < fb_info.terminal.y - 1)
255 vga_setpos(row + 1, col);
256 else
257 vga_scroll(cons_color);
258 return;
259 }
260
261 /*
262 * VGA_SCREEN is an array of 16-bit unsigned ints, we do let
263 * the compiler to take care of truncation here.
264 */
265 VGA_SCREEN[row * VGA_TEXT_COLS + col] = (cons_color << 8) | c;
266
267 if (col < VGA_TEXT_COLS - 1)
268 vga_setpos(row, col + 1);
269 else if (row < VGA_TEXT_ROWS - 1)
270 vga_setpos(row + 1, 0);
271 else {
272 vga_setpos(row, 0);
273 vga_scroll(cons_color);
274 }
170}
171
275}
276
172void
277static void
173vga_scroll(int color)
174{
278vga_scroll(int color)
279{
175 unsigned short val;
176 int i;
177
280 int i;
281
178 val = (color << 8) | ' ';
179
180 for (i = 0; i < (VGA_TEXT_ROWS-1)*VGA_TEXT_COLS; i++) {
282 for (i = 0; i < (VGA_TEXT_ROWS - 1) * VGA_TEXT_COLS; i++) {
181 VGA_SCREEN[i] = VGA_SCREEN[i + VGA_TEXT_COLS];
182 }
283 VGA_SCREEN[i] = VGA_SCREEN[i + VGA_TEXT_COLS];
284 }
183 for (; i < VGA_TEXT_ROWS * VGA_TEXT_COLS; i++) {
184 VGA_SCREEN[i] = val;
185 }
285 vga_eraseline_impl(0, VGA_TEXT_ROWS - 1, color);
186}
187
286}
287
188void
288static void
189vga_setpos(int row, int col)
190{
191 int off;
192
289vga_setpos(int row, int col)
290{
291 int off;
292
293 if (row < 0)
294 row = 0;
295 if (row >= fb_info.terminal.y)
296 row = fb_info.terminal.y - 1;
297 if (col < 0)
298 col = 0;
299 if (col >= fb_info.terminal.x)
300 col = fb_info.terminal.x - 1;
301
193 off = row * VGA_TEXT_COLS + col;
194 vga_set_crtc(VGA_CRTC_CLAH, off >> 8);
195 vga_set_crtc(VGA_CRTC_CLAL, off & 0xff);
196
197 fb_info.cursor.pos.y = row;
198 fb_info.cursor.pos.x = col;
199}
200
302 off = row * VGA_TEXT_COLS + col;
303 vga_set_crtc(VGA_CRTC_CLAH, off >> 8);
304 vga_set_crtc(VGA_CRTC_CLAL, off & 0xff);
305
306 fb_info.cursor.pos.y = row;
307 fb_info.cursor.pos.x = col;
308}
309
201void
310static void
202vga_getpos(int *row, int *col)
203{
204 int off;
205
206 off = (vga_get_crtc(VGA_CRTC_CLAH) << 8) + vga_get_crtc(VGA_CRTC_CLAL);
207 *row = off / VGA_TEXT_COLS;
208 *col = off % VGA_TEXT_COLS;
209}

--- 40 unchanged lines hidden ---
311vga_getpos(int *row, int *col)
312{
313 int off;
314
315 off = (vga_get_crtc(VGA_CRTC_CLAH) << 8) + vga_get_crtc(VGA_CRTC_CLAL);
316 *row = off / VGA_TEXT_COLS;
317 *col = off % VGA_TEXT_COLS;
318}

--- 40 unchanged lines hidden ---