aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/console
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/console')
-rw-r--r--drivers/video/console/Kconfig24
-rw-r--r--drivers/video/console/fonts.c2
-rw-r--r--drivers/video/console/newport_con.c4
-rw-r--r--drivers/video/console/vgacon.c271
4 files changed, 247 insertions, 54 deletions
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 6ee449858a5c..4444bef68fba 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -26,6 +26,30 @@ config VGA_CONSOLE
26# fi 26# fi
27# fi 27# fi
28 28
29config VGACON_SOFT_SCROLLBACK
30 bool "Enable Scrollback Buffer in System RAM"
31 depends on VGA_CONSOLE
32 default n
33 help
34 The scrollback buffer of the standard VGA console is located in
35 the VGA RAM. The size of this RAM is fixed and is quite small.
36 If you require a larger scrollback buffer, this can be placed in
37 System RAM which is dynamically allocated during intialization.
38 Placing the scrollback buffer in System RAM will slightly slow
39 down the console.
40
41 If you want this feature, say 'Y' here and enter the amount of
42 RAM to allocate for this buffer. If unsure, say 'N'.
43
44config VGACON_SOFT_SCROLLBACK_SIZE
45 int "Scrollback Buffer Size (in KB)"
46 depends on VGACON_SOFT_SCROLLBACK
47 default "64"
48 help
49 Enter the amount of System RAM to allocate for the scrollback
50 buffer. Each 64KB will give you approximately 16 80x25
51 screenfuls of scrollback buffer
52
29config VIDEO_SELECT 53config VIDEO_SELECT
30 bool "Video mode selection support" 54 bool "Video mode selection support"
31 depends on X86 && VGA_CONSOLE 55 depends on X86 && VGA_CONSOLE
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
index 4fd07d9eca03..0cc1bfda76a6 100644
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -66,7 +66,7 @@ static const struct font_desc *fonts[] = {
66#endif 66#endif
67}; 67};
68 68
69#define num_fonts (sizeof(fonts)/sizeof(*fonts)) 69#define num_fonts ARRAY_SIZE(fonts)
70 70
71#ifdef NO_FONTS 71#ifdef NO_FONTS
72#error No fonts configured. 72#error No fonts configured.
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index 762c7a593141..e99fe30e568c 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -149,7 +149,7 @@ static inline void newport_clear_lines(int ystart, int yend, int ci)
149 newport_clear_screen(0, ystart, 1280 + 63, yend, ci); 149 newport_clear_screen(0, ystart, 1280 + 63, yend, ci);
150} 150}
151 151
152void newport_reset(void) 152static void newport_reset(void)
153{ 153{
154 unsigned short treg; 154 unsigned short treg;
155 int i; 155 int i;
@@ -193,7 +193,7 @@ void newport_reset(void)
193 * calculate the actual screen size by reading 193 * calculate the actual screen size by reading
194 * the video timing out of the VC2 194 * the video timing out of the VC2
195 */ 195 */
196void newport_get_screensize(void) 196static void newport_get_screensize(void)
197{ 197{
198 int i, cols; 198 int i, cols;
199 unsigned short ventry, treg; 199 unsigned short ventry, treg;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 5a86978537d2..d5a04b68c4d4 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -93,7 +93,6 @@ static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
93static void vgacon_invert_region(struct vc_data *c, u16 * p, int count); 93static void vgacon_invert_region(struct vc_data *c, u16 * p, int count);
94static unsigned long vgacon_uni_pagedir[2]; 94static unsigned long vgacon_uni_pagedir[2];
95 95
96
97/* Description of the hardware situation */ 96/* Description of the hardware situation */
98static unsigned long vga_vram_base; /* Base of video memory */ 97static unsigned long vga_vram_base; /* Base of video memory */
99static unsigned long vga_vram_end; /* End of video memory */ 98static unsigned long vga_vram_end; /* End of video memory */
@@ -161,6 +160,201 @@ static inline void write_vga(unsigned char reg, unsigned int val)
161 spin_unlock_irqrestore(&vga_lock, flags); 160 spin_unlock_irqrestore(&vga_lock, flags);
162} 161}
163 162
163static inline void vga_set_mem_top(struct vc_data *c)
164{
165 write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2);
166}
167
168#ifdef CONFIG_VGACON_SOFT_SCROLLBACK
169#include <linux/bootmem.h>
170/* software scrollback */
171static void *vgacon_scrollback;
172static int vgacon_scrollback_tail;
173static int vgacon_scrollback_size;
174static int vgacon_scrollback_rows;
175static int vgacon_scrollback_cnt;
176static int vgacon_scrollback_cur;
177static int vgacon_scrollback_save;
178static int vgacon_scrollback_restore;
179
180static void vgacon_scrollback_init(int pitch)
181{
182 int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
183
184 if (vgacon_scrollback) {
185 vgacon_scrollback_cnt = 0;
186 vgacon_scrollback_tail = 0;
187 vgacon_scrollback_cur = 0;
188 vgacon_scrollback_rows = rows - 1;
189 vgacon_scrollback_size = rows * pitch;
190 }
191}
192
193static void __init vgacon_scrollback_startup(void)
194{
195 vgacon_scrollback = alloc_bootmem(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE
196 * 1024);
197 vgacon_scrollback_init(vga_video_num_columns * 2);
198}
199
200static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
201{
202 void *p;
203
204 if (!vgacon_scrollback_size || c->vc_num != fg_console)
205 return;
206
207 p = (void *) (c->vc_origin + t * c->vc_size_row);
208
209 while (count--) {
210 scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail,
211 p, c->vc_size_row);
212 vgacon_scrollback_cnt++;
213 p += c->vc_size_row;
214 vgacon_scrollback_tail += c->vc_size_row;
215
216 if (vgacon_scrollback_tail >= vgacon_scrollback_size)
217 vgacon_scrollback_tail = 0;
218
219 if (vgacon_scrollback_cnt > vgacon_scrollback_rows)
220 vgacon_scrollback_cnt = vgacon_scrollback_rows;
221
222 vgacon_scrollback_cur = vgacon_scrollback_cnt;
223 }
224}
225
226static void vgacon_restore_screen(struct vc_data *c)
227{
228 vgacon_scrollback_save = 0;
229
230 if (!vga_is_gfx && !vgacon_scrollback_restore) {
231 scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
232 c->vc_screenbuf_size > vga_vram_size ?
233 vga_vram_size : c->vc_screenbuf_size);
234 vgacon_scrollback_restore = 1;
235 vgacon_scrollback_cur = vgacon_scrollback_cnt;
236 }
237}
238
239static int vgacon_scrolldelta(struct vc_data *c, int lines)
240{
241 int start, end, count, soff, diff;
242 void *d, *s;
243
244 if (!lines) {
245 c->vc_visible_origin = c->vc_origin;
246 vga_set_mem_top(c);
247 return 1;
248 }
249
250 if (!vgacon_scrollback)
251 return 1;
252
253 if (!vgacon_scrollback_save) {
254 vgacon_cursor(c, CM_ERASE);
255 vgacon_save_screen(c);
256 vgacon_scrollback_save = 1;
257 }
258
259 vgacon_scrollback_restore = 0;
260 start = vgacon_scrollback_cur + lines;
261 end = start + abs(lines);
262
263 if (start < 0)
264 start = 0;
265
266 if (start > vgacon_scrollback_cnt)
267 start = vgacon_scrollback_cnt;
268
269 if (end < 0)
270 end = 0;
271
272 if (end > vgacon_scrollback_cnt)
273 end = vgacon_scrollback_cnt;
274
275 vgacon_scrollback_cur = start;
276 count = end - start;
277 soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) *
278 c->vc_size_row);
279 soff -= count * c->vc_size_row;
280
281 if (soff < 0)
282 soff += vgacon_scrollback_size;
283
284 count = vgacon_scrollback_cnt - start;
285
286 if (count > c->vc_rows)
287 count = c->vc_rows;
288
289 diff = c->vc_rows - count;
290
291 d = (void *) c->vc_origin;
292 s = (void *) c->vc_screenbuf;
293
294 while (count--) {
295 scr_memcpyw(d, vgacon_scrollback + soff, c->vc_size_row);
296 d += c->vc_size_row;
297 soff += c->vc_size_row;
298
299 if (soff >= vgacon_scrollback_size)
300 soff = 0;
301 }
302
303 if (diff == c->vc_rows) {
304 vgacon_cursor(c, CM_MOVE);
305 } else {
306 while (diff--) {
307 scr_memcpyw(d, s, c->vc_size_row);
308 d += c->vc_size_row;
309 s += c->vc_size_row;
310 }
311 }
312
313 return 1;
314}
315#else
316#define vgacon_scrollback_startup(...) do { } while (0)
317#define vgacon_scrollback_init(...) do { } while (0)
318#define vgacon_scrollback_update(...) do { } while (0)
319
320static void vgacon_restore_screen(struct vc_data *c)
321{
322 if (c->vc_origin != c->vc_visible_origin)
323 vgacon_scrolldelta(c, 0);
324}
325
326static int vgacon_scrolldelta(struct vc_data *c, int lines)
327{
328 if (!lines) /* Turn scrollback off */
329 c->vc_visible_origin = c->vc_origin;
330 else {
331 int margin = c->vc_size_row * 4;
332 int ul, we, p, st;
333
334 if (vga_rolled_over >
335 (c->vc_scr_end - vga_vram_base) + margin) {
336 ul = c->vc_scr_end - vga_vram_base;
337 we = vga_rolled_over + c->vc_size_row;
338 } else {
339 ul = 0;
340 we = vga_vram_size;
341 }
342 p = (c->vc_visible_origin - vga_vram_base - ul + we) % we +
343 lines * c->vc_size_row;
344 st = (c->vc_origin - vga_vram_base - ul + we) % we;
345 if (st < 2 * margin)
346 margin = 0;
347 if (p < margin)
348 p = 0;
349 if (p > st - margin)
350 p = st;
351 c->vc_visible_origin = vga_vram_base + (p + ul) % we;
352 }
353 vga_set_mem_top(c);
354 return 1;
355}
356#endif /* CONFIG_VGACON_SOFT_SCROLLBACK */
357
164static const char __init *vgacon_startup(void) 358static const char __init *vgacon_startup(void)
165{ 359{
166 const char *display_desc = NULL; 360 const char *display_desc = NULL;
@@ -330,7 +524,7 @@ static const char __init *vgacon_startup(void)
330 524
331 vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH; 525 vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH;
332 vgacon_yres = vga_scan_lines; 526 vgacon_yres = vga_scan_lines;
333 527 vgacon_scrollback_startup();
334 return display_desc; 528 return display_desc;
335} 529}
336 530
@@ -357,11 +551,6 @@ static void vgacon_init(struct vc_data *c, int init)
357 con_set_default_unimap(c); 551 con_set_default_unimap(c);
358} 552}
359 553
360static inline void vga_set_mem_top(struct vc_data *c)
361{
362 write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2);
363}
364
365static void vgacon_deinit(struct vc_data *c) 554static void vgacon_deinit(struct vc_data *c)
366{ 555{
367 /* When closing the last console, reset video origin */ 556 /* When closing the last console, reset video origin */
@@ -433,29 +622,37 @@ static void vgacon_set_cursor_size(int xpos, int from, int to)
433 cursor_size_lastto = to; 622 cursor_size_lastto = to;
434 623
435 spin_lock_irqsave(&vga_lock, flags); 624 spin_lock_irqsave(&vga_lock, flags);
436 outb_p(0x0a, vga_video_port_reg); /* Cursor start */ 625 if (vga_video_type >= VIDEO_TYPE_VGAC) {
437 curs = inb_p(vga_video_port_val); 626 outb_p(VGA_CRTC_CURSOR_START, vga_video_port_reg);
438 outb_p(0x0b, vga_video_port_reg); /* Cursor end */ 627 curs = inb_p(vga_video_port_val);
439 cure = inb_p(vga_video_port_val); 628 outb_p(VGA_CRTC_CURSOR_END, vga_video_port_reg);
629 cure = inb_p(vga_video_port_val);
630 } else {
631 curs = 0;
632 cure = 0;
633 }
440 634
441 curs = (curs & 0xc0) | from; 635 curs = (curs & 0xc0) | from;
442 cure = (cure & 0xe0) | to; 636 cure = (cure & 0xe0) | to;
443 637
444 outb_p(0x0a, vga_video_port_reg); /* Cursor start */ 638 outb_p(VGA_CRTC_CURSOR_START, vga_video_port_reg);
445 outb_p(curs, vga_video_port_val); 639 outb_p(curs, vga_video_port_val);
446 outb_p(0x0b, vga_video_port_reg); /* Cursor end */ 640 outb_p(VGA_CRTC_CURSOR_END, vga_video_port_reg);
447 outb_p(cure, vga_video_port_val); 641 outb_p(cure, vga_video_port_val);
448 spin_unlock_irqrestore(&vga_lock, flags); 642 spin_unlock_irqrestore(&vga_lock, flags);
449} 643}
450 644
451static void vgacon_cursor(struct vc_data *c, int mode) 645static void vgacon_cursor(struct vc_data *c, int mode)
452{ 646{
453 if (c->vc_origin != c->vc_visible_origin) 647 vgacon_restore_screen(c);
454 vgacon_scrolldelta(c, 0); 648
455 switch (mode) { 649 switch (mode) {
456 case CM_ERASE: 650 case CM_ERASE:
457 write_vga(14, (c->vc_pos - vga_vram_base) / 2); 651 write_vga(14, (c->vc_pos - vga_vram_base) / 2);
458 vgacon_set_cursor_size(c->vc_x, 31, 30); 652 if (vga_video_type >= VIDEO_TYPE_VGAC)
653 vgacon_set_cursor_size(c->vc_x, 31, 30);
654 else
655 vgacon_set_cursor_size(c->vc_x, 31, 31);
459 break; 656 break;
460 657
461 case CM_MOVE: 658 case CM_MOVE:
@@ -493,7 +690,10 @@ static void vgacon_cursor(struct vc_data *c, int mode)
493 10 ? 1 : 2)); 690 10 ? 1 : 2));
494 break; 691 break;
495 case CUR_NONE: 692 case CUR_NONE:
496 vgacon_set_cursor_size(c->vc_x, 31, 30); 693 if (vga_video_type >= VIDEO_TYPE_VGAC)
694 vgacon_set_cursor_size(c->vc_x, 31, 30);
695 else
696 vgacon_set_cursor_size(c->vc_x, 31, 31);
497 break; 697 break;
498 default: 698 default:
499 vgacon_set_cursor_size(c->vc_x, 1, 699 vgacon_set_cursor_size(c->vc_x, 1,
@@ -595,6 +795,7 @@ static int vgacon_switch(struct vc_data *c)
595 vgacon_doresize(c, c->vc_cols, c->vc_rows); 795 vgacon_doresize(c, c->vc_cols, c->vc_rows);
596 } 796 }
597 797
798 vgacon_scrollback_init(c->vc_size_row);
598 return 0; /* Redrawing not needed */ 799 return 0; /* Redrawing not needed */
599} 800}
600 801
@@ -1062,37 +1263,6 @@ static int vgacon_resize(struct vc_data *c, unsigned int width,
1062 return 0; 1263 return 0;
1063} 1264}
1064 1265
1065static int vgacon_scrolldelta(struct vc_data *c, int lines)
1066{
1067 if (!lines) /* Turn scrollback off */
1068 c->vc_visible_origin = c->vc_origin;
1069 else {
1070 int margin = c->vc_size_row * 4;
1071 int ul, we, p, st;
1072
1073 if (vga_rolled_over >
1074 (c->vc_scr_end - vga_vram_base) + margin) {
1075 ul = c->vc_scr_end - vga_vram_base;
1076 we = vga_rolled_over + c->vc_size_row;
1077 } else {
1078 ul = 0;
1079 we = vga_vram_size;
1080 }
1081 p = (c->vc_visible_origin - vga_vram_base - ul + we) % we +
1082 lines * c->vc_size_row;
1083 st = (c->vc_origin - vga_vram_base - ul + we) % we;
1084 if (st < 2 * margin)
1085 margin = 0;
1086 if (p < margin)
1087 p = 0;
1088 if (p > st - margin)
1089 p = st;
1090 c->vc_visible_origin = vga_vram_base + (p + ul) % we;
1091 }
1092 vga_set_mem_top(c);
1093 return 1;
1094}
1095
1096static int vgacon_set_origin(struct vc_data *c) 1266static int vgacon_set_origin(struct vc_data *c)
1097{ 1267{
1098 if (vga_is_gfx || /* We don't play origin tricks in graphic modes */ 1268 if (vga_is_gfx || /* We don't play origin tricks in graphic modes */
@@ -1135,15 +1305,14 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
1135 if (t || b != c->vc_rows || vga_is_gfx) 1305 if (t || b != c->vc_rows || vga_is_gfx)
1136 return 0; 1306 return 0;
1137 1307
1138 if (c->vc_origin != c->vc_visible_origin)
1139 vgacon_scrolldelta(c, 0);
1140
1141 if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2) 1308 if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2)
1142 return 0; 1309 return 0;
1143 1310
1311 vgacon_restore_screen(c);
1144 oldo = c->vc_origin; 1312 oldo = c->vc_origin;
1145 delta = lines * c->vc_size_row; 1313 delta = lines * c->vc_size_row;
1146 if (dir == SM_UP) { 1314 if (dir == SM_UP) {
1315 vgacon_scrollback_update(c, t, lines);
1147 if (c->vc_scr_end + delta >= vga_vram_end) { 1316 if (c->vc_scr_end + delta >= vga_vram_end) {
1148 scr_memcpyw((u16 *) vga_vram_base, 1317 scr_memcpyw((u16 *) vga_vram_base,
1149 (u16 *) (oldo + delta), 1318 (u16 *) (oldo + delta),