From: <jsi...@us...> - 2007-04-10 13:39:59
|
Revision: 2363 http://linuxconsole.svn.sourceforge.net/linuxconsole/?rev=2363&view=rev Author: jsimmons Date: 2007-04-10 06:36:51 -0700 (Tue, 10 Apr 2007) Log Message: ----------- merge vgacon to 2.6.21 Modified Paths: -------------- branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c Modified: branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c 2007-04-10 02:01:16 UTC (rev 2362) +++ branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c 2007-04-10 13:36:51 UTC (rev 2363) @@ -33,13 +33,10 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> -#include <linux/sched.h> #include <linux/fs.h> #include <linux/kernel.h> -#include <linux/tty.h> #include <linux/console.h> #include <linux/string.h> #include <linux/slab.h> @@ -48,6 +45,8 @@ #include <linux/spinlock.h> #include <linux/ioport.h> #include <linux/init.h> +#include <linux/screen_info.h> +#include <linux/smp_lock.h> #ifdef CONFIG_IA64 #include <linux/efi.h> #endif @@ -96,22 +95,22 @@ static void vgacon_invert_region(struct vc_data *c, u16 * p, int count); static unsigned long vgacon_uni_pagedir[2]; - /* Description of the hardware situation */ -static unsigned long vga_vram_base; /* Base of video memory */ -static unsigned long vga_vram_end; /* End of video memory */ -static int vga_vram_size; /* Size of video memory */ -static u16 vga_video_port_reg; /* Video register select port */ -static u16 vga_video_port_val; /* Video register value port */ -static unsigned char vga_video_type; /* Card type */ -static unsigned char vga_hardscroll_enabled; -static unsigned char vga_hardscroll_user_enable = 1; +static int vga_init_done __read_mostly; +static unsigned long vga_vram_base __read_mostly; /* Base of video memory */ +static unsigned long vga_vram_end __read_mostly; /* End of video memory */ +static unsigned int vga_vram_size __read_mostly; /* Size of video memory */ +static u16 vga_video_port_reg __read_mostly; /* Video register select port */ +static u16 vga_video_port_val __read_mostly; /* Video register value port */ +static unsigned char vga_video_type __read_mostly; /* Card type */ +static unsigned char vga_hardscroll_enabled __read_mostly; +static unsigned char vga_hardscroll_user_enable __read_mostly = 1; static unsigned char vga_font_is_default = 1; static int vga_vesa_blanked; static int vga_palette_blanked; static int vga_is_gfx; static int vga_512_chars; -static unsigned int vga_rolled_over = 0; +static unsigned int vga_rolled_over; static int __init no_scroll(char *str) { @@ -158,8 +157,203 @@ spin_unlock_irqrestore(&vga_lock, flags); } -static const char __init *vgacon_startup(struct vt_struct *vt, int init) +static inline void vga_set_mem_top(struct vc_data *c) { + write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2); +} + +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK +#include <linux/bootmem.h> +/* software scrollback */ +static void *vgacon_scrollback; +static int vgacon_scrollback_tail; +static int vgacon_scrollback_size; +static int vgacon_scrollback_rows; +static int vgacon_scrollback_cnt; +static int vgacon_scrollback_cur; +static int vgacon_scrollback_save; +static int vgacon_scrollback_restore; + +static void vgacon_scrollback_init(int pitch) +{ + int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; + + if (vgacon_scrollback) { + vgacon_scrollback_cnt = 0; + vgacon_scrollback_tail = 0; + vgacon_scrollback_cur = 0; + vgacon_scrollback_rows = rows - 1; + vgacon_scrollback_size = rows * pitch; + } +} + +static void vgacon_scrollback_startup(void) +{ + vgacon_scrollback = alloc_bootmem(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE + * 1024); + vgacon_scrollback_init(vga_video_num_columns * 2); +} + +static void vgacon_scrollback_update(struct vc_data *c, int t, int count) +{ + void *p; + + if (!vgacon_scrollback_size || c->vc_num != fg_console) + return; + + p = (void *) (c->vc_origin + t * c->vc_size_row); + + while (count--) { + scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail, + p, c->vc_size_row); + vgacon_scrollback_cnt++; + p += c->vc_size_row; + vgacon_scrollback_tail += c->vc_size_row; + + if (vgacon_scrollback_tail >= vgacon_scrollback_size) + vgacon_scrollback_tail = 0; + + if (vgacon_scrollback_cnt > vgacon_scrollback_rows) + vgacon_scrollback_cnt = vgacon_scrollback_rows; + + vgacon_scrollback_cur = vgacon_scrollback_cnt; + } +} + +static void vgacon_restore_screen(struct vc_data *c) +{ + vgacon_scrollback_save = 0; + + if (!vga_is_gfx && !vgacon_scrollback_restore) { + scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, + c->vc_screenbuf_size > vga_vram_size ? + vga_vram_size : c->vc_screenbuf_size); + vgacon_scrollback_restore = 1; + vgacon_scrollback_cur = vgacon_scrollback_cnt; + } +} + +static int vgacon_scroll(struct vc_data *c, int lines) +{ + int start, end, count, soff, diff; + void *d, *s; + + if (!lines) { + c->vc_visible_origin = c->vc_origin; + vga_set_mem_top(c); + return 1; + } + + if (!vgacon_scrollback) + return 1; + + if (!vgacon_scrollback_save) { + vgacon_cursor(c, CM_ERASE); + vgacon_save_screen(c); + vgacon_scrollback_save = 1; + } + + vgacon_scrollback_restore = 0; + start = vgacon_scrollback_cur + lines; + end = start + abs(lines); + + if (start < 0) + start = 0; + + if (start > vgacon_scrollback_cnt) + start = vgacon_scrollback_cnt; + + if (end < 0) + end = 0; + + if (end > vgacon_scrollback_cnt) + end = vgacon_scrollback_cnt; + + vgacon_scrollback_cur = start; + count = end - start; + soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) * + c->vc_size_row); + soff -= count * c->vc_size_row; + + if (soff < 0) + soff += vgacon_scrollback_size; + + count = vgacon_scrollback_cnt - start; + + if (count > c->vc_rows) + count = c->vc_rows; + + diff = c->vc_rows - count; + + d = (void *) c->vc_origin; + s = (void *) c->vc_screenbuf; + + while (count--) { + scr_memcpyw(d, vgacon_scrollback + soff, c->vc_size_row); + d += c->vc_size_row; + soff += c->vc_size_row; + + if (soff >= vgacon_scrollback_size) + soff = 0; + } + + if (diff == c->vc_rows) { + vgacon_cursor(c, CM_MOVE); + } else { + while (diff--) { + scr_memcpyw(d, s, c->vc_size_row); + d += c->vc_size_row; + s += c->vc_size_row; + } + } + + return 1; +} +#else +#define vgacon_scrollback_startup(...) do { } while (0) +#define vgacon_scrollback_init(...) do { } while (0) +#define vgacon_scrollback_update(...) do { } while (0) + +static void vgacon_restore_screen(struct vc_data *c) +{ + if (c->vc_origin != c->vc_visible_origin) + vgacon_scroll(c, 0); +} + +static int vgacon_scroll(struct vc_data *c, int lines) +{ + if (!lines) /* Turn scrollback off */ + c->vc_visible_origin = c->vc_origin; + else { + int margin = c->vc_size_row * 4; + int ul, we, p, st; + + if (vga_rolled_over > + (c->vc_scr_end - vga_vram_base) + margin) { + ul = c->vc_scr_end - vga_vram_base; + we = vga_rolled_over + c->vc_size_row; + } else { + ul = 0; + we = vga_vram_size; + } + p = (c->vc_visible_origin - vga_vram_base - ul + we) % we + + lines * c->vc_size_row; + st = (c->vc_origin - vga_vram_base - ul + we) % we; + if (st < 2 * margin) + margin = 0; + if (p < margin) + p = 0; + if (p > st - margin) + p = st; + c->vc_visible_origin = vga_vram_base + (p + ul) % we; + } + vga_set_mem_top(c); + return 1; +} +#endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ + +static const char *vgacon_startup(struct vt_struct *vt, int init) +{ struct vc_data *vc = &vga_default; const char *display_desc = NULL; u16 saved1, saved2; @@ -194,19 +388,19 @@ vga_video_port_val = VGA_CRT_DM; if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { static struct resource ega_console_resource = - { "ega", 0x3B0, 0x3BF }; + { .name = "ega", .start = 0x3B0, .end = 0x3BF }; vga_video_type = VIDEO_TYPE_EGAM; - vga_vram_end = 0xb8000; + vga_vram_size = 0x8000; display_desc = "EGA+"; request_resource(&ioport_resource, &ega_console_resource); } else { static struct resource mda1_console_resource = - { "mda", 0x3B0, 0x3BB }; + { .name = "mda", .start = 0x3B0, .end = 0x3BB }; static struct resource mda2_console_resource = - { "mda", 0x3BF, 0x3BF }; + { .name = "mda", .start = 0x3BF, .end = 0x3BF }; vga_video_type = VIDEO_TYPE_MDA; - vga_vram_end = 0xb2000; + vga_vram_size = 0x2000; display_desc = "*MDA"; request_resource(&ioport_resource, &mda1_console_resource); @@ -223,18 +417,18 @@ if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { int i; - vga_vram_end = 0xc0000; + vga_vram_size = 0x8000; if (!ORIG_VIDEO_ISVGA) { static struct resource ega_console_resource - = { "ega", 0x3C0, 0x3DF }; + = { .name = "ega", .start = 0x3C0, .end = 0x3DF }; vga_video_type = VIDEO_TYPE_EGAC; display_desc = "EGA"; request_resource(&ioport_resource, &ega_console_resource); } else { static struct resource vga_console_resource - = { "vga+", 0x3C0, 0x3DF }; + = { .name = "vga+", .start = 0x3C0, .end = 0x3DF }; vga_video_type = VIDEO_TYPE_VGAC; display_desc = "VGA+"; request_resource(&ioport_resource, @@ -248,7 +442,7 @@ * and COE=1 isn't necessarily a good idea) */ vga_vram_base = 0xa0000; - vga_vram_end = 0xb0000; + vga_vram_size = 0x10000; outb_p(6, VGA_GFX_I); outb_p(6, VGA_GFX_D); #endif @@ -278,9 +472,9 @@ } } else { static struct resource cga_console_resource = - { "cga", 0x3D4, 0x3D5 }; + { .name = "cga", .start = 0x3D4, .end = 0x3D5 }; vga_video_type = VIDEO_TYPE_CGA; - vga_vram_end = 0xba000; + vga_vram_size = 0x2000; display_desc = "*CGA"; request_resource(&ioport_resource, &cga_console_resource); @@ -288,9 +482,8 @@ } } - vga_vram_base = VGA_MAP_MEM(vga_vram_base); - vga_vram_end = VGA_MAP_MEM(vga_vram_end); - vga_vram_size = vga_vram_end - vga_vram_base; + vga_vram_base = VGA_MAP_MEM(vga_vram_base, vga_vram_size); + vga_vram_end = vga_vram_base + vga_vram_size; /* * Find out if there is a graphics card present. @@ -324,6 +517,12 @@ /* This may be suboptimal but is a safe bet - go with it */ vc->vc_scan_lines = vc->vc_font.height * vc->vc_rows; } + + if (!vga_init_done) { + vgacon_scrollback_startup(); + vga_init_done = 1; + } + return display_desc; } @@ -332,13 +531,22 @@ struct vc_data *default_mode = c->display_fg->default_mode; unsigned long p; - /* We cannot be loaded as a module, therefore init is always 1 */ + /* + * We cannot be loaded as a module, therefore init is always 1, + * but vgacon_init can be called more than once, and init will + * not be 1. + */ c->vc_can_do_color = default_mode->vc_can_do_color; + + /* set dimensions manually if init != 0 since vc_resize() will fail */ c->vc_cols = default_mode->vc_cols; c->vc_rows = default_mode->vc_rows; + c->vc_scan_lines = default_mode->vc_scan_lines; c->vc_font.height = default_mode->vc_font.height; c->vc_complement_mask = 0x7700; + if (vga_512_chars) + c->vc_hi_font_mask = 0x0800; p = *c->vc_uni_pagedir_loc; if (c->vc_uni_pagedir_loc == &c->vc_uni_pagedir || !--c->vc_uni_pagedir_loc[1]) @@ -349,11 +557,6 @@ con_set_default_unimap(c); } -static inline void vga_set_mem_top(struct vc_data *c) -{ - write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2); -} - static void vgacon_deinit(struct vc_data *c) { /* When closing the last console, reset video origin */ @@ -425,28 +628,37 @@ cursor_size_lastto = to; spin_lock_irqsave(&vga_lock, flags); - outb_p(0x0a, vga_video_port_reg); /* Cursor start */ - curs = inb_p(vga_video_port_val); - outb_p(0x0b, vga_video_port_reg); /* Cursor end */ - cure = inb_p(vga_video_port_val); + if (vga_video_type >= VIDEO_TYPE_VGAC) { + outb_p(VGA_CRTC_CURSOR_START, vga_video_port_reg); + curs = inb_p(vga_video_port_val); + outb_p(VGA_CRTC_CURSOR_END, vga_video_port_reg); + cure = inb_p(vga_video_port_val); + } else { + curs = 0; + cure = 0; + } curs = (curs & 0xc0) | from; cure = (cure & 0xe0) | to; - outb_p(0x0a, vga_video_port_reg); /* Cursor start */ + outb_p(VGA_CRTC_CURSOR_START, vga_video_port_reg); outb_p(curs, vga_video_port_val); - outb_p(0x0b, vga_video_port_reg); /* Cursor end */ + outb_p(VGA_CRTC_CURSOR_END, vga_video_port_reg); outb_p(cure, vga_video_port_val); spin_unlock_irqrestore(&vga_lock, flags); } static void vgacon_cursor(struct vc_data *c, int mode) { - if (c->vc_origin != c->vc_visible_origin) - vgacon_scroll(c, 0); + vgacon_restore_screen(c); + switch (mode) { case CM_ERASE: - write_vga(14, (vga_vram_end - vga_vram_base - 1) / 2); + write_vga(14, (c->vc_pos - vga_vram_base) / 2); + if (vga_video_type >= VIDEO_TYPE_VGAC) + vgacon_set_cursor_size(c->vc_x, 31, 30); + else + vgacon_set_cursor_size(c->vc_x, 31, 31); break; case CM_MOVE: @@ -484,7 +696,10 @@ 10 ? 1 : 2)); break; case CUR_NONE: - vgacon_set_cursor_size(c->vc_x, 31, 30); + if (vga_video_type >= VIDEO_TYPE_VGAC) + vgacon_set_cursor_size(c->vc_x, 31, 30); + else + vgacon_set_cursor_size(c->vc_x, 31, 31); break; default: vgacon_set_cursor_size(c->vc_x, 1, @@ -495,14 +710,88 @@ } } +static int vgacon_doresize(struct vc_data *c, + unsigned int width, unsigned int height) +{ + unsigned long flags; + unsigned int scanlines = height * c->vc_font.height; + u8 scanlines_lo = 0, r7 = 0, vsync_end = 0, mode, max_scan; + + spin_lock_irqsave(&vga_lock, flags); + + vgacon_xres = width * VGA_FONTWIDTH; + vgacon_yres = height * c->vc_font.height; + if (vga_video_type >= VIDEO_TYPE_VGAC) { + outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg); + max_scan = inb_p(vga_video_port_val); + + if (max_scan & 0x80) + scanlines <<= 1; + + outb_p(VGA_CRTC_MODE, vga_video_port_reg); + mode = inb_p(vga_video_port_val); + + if (mode & 0x04) + scanlines >>= 1; + + scanlines -= 1; + scanlines_lo = scanlines & 0xff; + + outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg); + r7 = inb_p(vga_video_port_val) & ~0x42; + + if (scanlines & 0x100) + r7 |= 0x02; + if (scanlines & 0x200) + r7 |= 0x40; + + /* deprotect registers */ + outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg); + vsync_end = inb_p(vga_video_port_val); + outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg); + outb_p(vsync_end & ~0x80, vga_video_port_val); + } + + outb_p(VGA_CRTC_H_DISP, vga_video_port_reg); + outb_p(width - 1, vga_video_port_val); + outb_p(VGA_CRTC_OFFSET, vga_video_port_reg); + outb_p(width >> 1, vga_video_port_val); + + if (vga_video_type >= VIDEO_TYPE_VGAC) { + outb_p(VGA_CRTC_V_DISP_END, vga_video_port_reg); + outb_p(scanlines_lo, vga_video_port_val); + outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg); + outb_p(r7,vga_video_port_val); + + /* reprotect registers */ + outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg); + outb_p(vsync_end, vga_video_port_val); + } + + spin_unlock_irqrestore(&vga_lock, flags); + return 0; +} + static int vgacon_switch(struct vc_data *c) { /* We can only copy out the size of the video buffer here, - * otherwise we get into VGA BIOS */ + * otherwise we get into VGA BIOS. We can only copy out + * the size of the video buffer here, otherwise we get + * into VGA BIOS */ - if (!vga_is_gfx) + if (!vga_is_gfx) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, - c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); + c->vc_screenbuf_size > vga_vram_size ? + vga_vram_size : c->vc_screenbuf_size); + + if ((vgacon_xres != x || vgacon_yres != y) && + (!(vga_video_num_columns % 2) && + vga_video_num_columns <= ORIG_VIDEO_COLS && + vga_video_num_lines <= rows)) + vgacon_doresize(c, c->vc_cols, c->vc_rows); + } + + vgacon_scrollback_init(c->vc_size_row); return 0; /* Redrawing not needed */ } @@ -510,6 +799,7 @@ { int i, j; + vga_w(state.vgabase, VGA_PEL_MSK, 0xff); for (i = j = 0; i < 16; i++) { vga_w(state.vgabase, VGA_PEL_IW, table[i]); vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); @@ -651,6 +941,7 @@ { int i; + vga_w(state->vgabase, VGA_PEL_MSK, 0xff); for (i = 0; i < 16; i++) { vga_w(state->vgabase, VGA_PEL_IW, i); vga_w(state->vgabase, VGA_PEL_D, 0); @@ -724,14 +1015,14 @@ char *charmap; if (vga_video_type != VIDEO_TYPE_EGAM) { - charmap = (char *) VGA_MAP_MEM(colourmap); + charmap = (char *) VGA_MAP_MEM(colourmap, 0); beg = 0x0e; #ifdef VGA_CAN_DO_64KB if (vga_video_type == VIDEO_TYPE_VGAC) beg = 0x06; #endif } else { - charmap = (char *) VGA_MAP_MEM(blackwmap); + charmap = (char *) VGA_MAP_MEM(blackwmap, 0); beg = 0x0a; } @@ -951,35 +1242,18 @@ #endif -static int vgacon_scroll(struct vc_data *c, int lines) +static int vgacon_resize(struct vc_data *c, unsigned int width, + unsigned int height) { - if (!lines) /* Turn scrollback off */ - c->vc_visible_origin = c->vc_origin; - else { - int margin = c->vc_size_row * 4; - int ul, we, p, st; + if (width % 2 || width > ORIG_VIDEO_COLS || + height > (ORIG_VIDEO_LINES * vga_default_font_height)/ + c->vc_font.height) + /* let svgatextmode tinker with video timings */ + return 0; - if (vga_rolled_over > - (c->vc_scr_end - vga_vram_base) + margin) { - ul = c->vc_scr_end - vga_vram_base; - we = vga_rolled_over + c->vc_size_row; - } else { - ul = 0; - we = vga_vram_size; - } - p = (c->vc_visible_origin - vga_vram_base - ul + we) % we + - lines * c->vc_size_row; - st = (c->vc_origin - vga_vram_base - ul + we) % we; - if (st < 2 * margin) - margin = 0; - if (p < margin) - p = 0; - if (p > st - margin) - p = st; - c->vc_visible_origin = vga_vram_base + (p + ul) % we; - } - vga_set_mem_top(c); - return 1; + if (IS_VISIBLE && !vga_is_gfx) /* who knows */ + vgacon_doresize(c, width, height); + return 0; } static int vgacon_set_origin(struct vc_data *c) @@ -997,6 +1271,7 @@ { /* We can't copy in more then the size of the video buffer, * or we'll be copying in VGA BIOS */ + if (!vga_is_gfx) scr_memcpyw((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); @@ -1011,15 +1286,14 @@ if (t || b != c->vc_rows || vga_is_gfx) return 0; - if (c->vc_origin != c->vc_visible_origin) - vgacon_scroll(c, 0); - if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2) return 0; + vgacon_restore_screen(c); oldo = c->vc_origin; delta = lines * c->vc_size_row; if (dir == SM_UP) { + vgacon_scrollback_update(c, t, lines); if (c->vc_scr_end + delta >= vga_vram_end) { scr_memcpyw((u16 *) vga_vram_base, (u16 *) (oldo + delta), @@ -1079,6 +1353,7 @@ .con_blank = vgacon_blank, .con_font_set = vgacon_font_set, .con_font_get = vgacon_font_get, + .con_resize = vgacon_resize, .con_set_palette = vgacon_set_palette, .con_scroll = vgacon_scroll, .con_set_origin = vgacon_set_origin, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jsi...@us...> - 2007-07-16 15:52:27
|
Revision: 2382 http://linuxconsole.svn.sourceforge.net/linuxconsole/?rev=2382&view=rev Author: jsimmons Date: 2007-07-16 08:52:23 -0700 (Mon, 16 Jul 2007) Log Message: ----------- Some changes to vga con causes a lock up. Will find later Modified Paths: -------------- branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c Modified: branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c 2007-07-16 15:51:42 UTC (rev 2381) +++ branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c 2007-07-16 15:52:23 UTC (rev 2382) @@ -47,10 +47,6 @@ #include <linux/init.h> #include <linux/screen_info.h> #include <linux/smp_lock.h> -#ifdef CONFIG_IA64 -#include <linux/efi.h> -#endif - #include <video/vga.h> #include <asm/io.h> @@ -60,6 +56,8 @@ static int cursor_size_lastfrom; static int cursor_size_lastto; +static u32 vgacon_xres; +static u32 vgacon_yres; static struct vgastate state; #define BLANK 0x0020 @@ -73,7 +71,7 @@ * appear. */ #undef TRIDENT_GLITCH - +#define VGA_FONTWIDTH 8 /* VGA does not support fontwidths != 8 */ /* * Interface used by the world */ @@ -89,7 +87,7 @@ static int vgacon_set_origin(struct vc_data *c); static void vgacon_save_screen(struct vc_data *c); static int vgacon_scroll_region(struct vc_data *c, int t, int b, int dir, - int lines); + int lines); static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, u8 blink, u8 underline, u8 reverse); static void vgacon_invert_region(struct vc_data *c, u16 * p, int count); @@ -102,6 +100,10 @@ static unsigned int vga_vram_size __read_mostly; /* Size of video memory */ static u16 vga_video_port_reg __read_mostly; /* Video register select port */ static u16 vga_video_port_val __read_mostly; /* Video register value port */ +static unsigned int vga_video_num_columns; /* Number of text columns */ +static unsigned int vga_video_num_lines; /* Number of text lines */ +static int vga_can_do_color __read_mostly; /* Do we support colors? */ +static unsigned int vga_default_font_height __read_mostly; /* Height of default screen font */ static unsigned char vga_video_type __read_mostly; /* Card type */ static unsigned char vga_hardscroll_enabled __read_mostly; static unsigned char vga_hardscroll_user_enable __read_mostly = 1; @@ -110,6 +112,8 @@ static int vga_palette_blanked; static int vga_is_gfx; static int vga_512_chars; +static int vga_video_font_height; +static int vga_scan_lines __read_mostly; static unsigned int vga_rolled_over; static int __init no_scroll(char *str) @@ -354,21 +358,15 @@ static const char *vgacon_startup(struct vt_struct *vt, int init) { - struct vc_data *vc = &vga_default; + struct vc_data *vc = vt->default_mode = &vga_default; const char *display_desc = NULL; u16 saved1, saved2; volatile u16 *p; -#ifdef CONFIG_IA64 - if (efi_mem_type(0xA0000) == EFI_CONVENTIONAL_MEMORY) - goto no_vga: -#endif - if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB) { no_vga: return NULL; } - vt->default_mode = vc; /* VGA16 modes are not handled by VGACON */ if ((ORIG_VIDEO_MODE == 0x0D) || /* 320x200/4 */ @@ -378,8 +376,8 @@ (ORIG_VIDEO_MODE == 0x6A)) /* 800x600/4, 0x6A is very common */ goto no_vga; - vc->vc_rows = ORIG_VIDEO_LINES; - vc->vc_cols = ORIG_VIDEO_COLS; + vc->vc_rows = vga_video_num_lines = ORIG_VIDEO_LINES; + vc->vc_cols = vga_video_num_columns = ORIG_VIDEO_COLS; state.vgabase = NULL; if (ORIG_VIDEO_MODE == 7) { /* Is this a monochrome display? */ @@ -406,11 +404,11 @@ &mda1_console_resource); request_resource(&ioport_resource, &mda2_console_resource); - vc->vc_font.height = 14; + vc->vc_font.height = vga_video_font_height = 14; } } else { /* If not, it is color. */ - vc->vc_can_do_color = 1; + vc->vc_can_do_color = vga_can_do_color = 1; vga_vram_base = 0xb8000; vga_video_port_reg = VGA_CRT_IC; vga_video_port_val = VGA_CRT_DC; @@ -478,7 +476,7 @@ display_desc = "*CGA"; request_resource(&ioport_resource, &cga_console_resource); - vc->vc_font.height = 8; + vc->vc_font.height = vga_video_font_height = 8; } } @@ -513,11 +511,18 @@ || vga_video_type == VIDEO_TYPE_VGAC || vga_video_type == VIDEO_TYPE_EGAM) { vga_hardscroll_enabled = vga_hardscroll_user_enable; - vc->vc_font.height = ORIG_VIDEO_POINTS; + vga_default_font_height = ORIG_VIDEO_POINTS; + vga_video_font_height = ORIG_VIDEO_POINTS; /* This may be suboptimal but is a safe bet - go with it */ - vc->vc_scan_lines = vc->vc_font.height * vc->vc_rows; + vga_scan_lines = + vga_video_font_height * vga_video_num_lines; + vc->vc_font.height = vga_default_font_height; + vc->vc_scan_lines = vga_scan_lines; } + vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH; + vgacon_yres = vga_scan_lines; + if (!vga_init_done) { vgacon_scrollback_startup(); vga_init_done = 1; @@ -528,7 +533,6 @@ static void vgacon_init(struct vc_data *c, int init) { - struct vc_data *default_mode = c->display_fg->default_mode; unsigned long p; /* @@ -536,14 +540,17 @@ * but vgacon_init can be called more than once, and init will * not be 1. */ - c->vc_can_do_color = default_mode->vc_can_do_color; - + c->vc_can_do_color = vga_can_do_color; + /* set dimensions manually if init != 0 since vc_resize() will fail */ - c->vc_cols = default_mode->vc_cols; - c->vc_rows = default_mode->vc_rows; + if (init) { + c->vc_cols = vga_video_num_columns; + c->vc_rows = vga_video_num_lines; + } else + vc_resize(c, vga_video_num_columns, vga_video_num_lines); - c->vc_scan_lines = default_mode->vc_scan_lines; - c->vc_font.height = default_mode->vc_font.height; + c->vc_scan_lines = vga_scan_lines; + c->vc_font.height = vga_video_font_height; c->vc_complement_mask = 0x7700; if (vga_512_chars) c->vc_hi_font_mask = 0x0800; @@ -574,7 +581,7 @@ { u8 attr = color; - if (c->vc_can_do_color) { + if (vga_can_do_color) { if (underline) attr = (attr & 0xf0) | c->vc_ulcolor; else if (intensity == 0) @@ -588,7 +595,7 @@ attr ^= 0x80; if (intensity == 2) attr ^= 0x08; - if (!c->vc_can_do_color) { + if (!vga_can_do_color) { if (underline) attr = (attr & 0xf8) | 0x01; else if (intensity == 0) @@ -599,7 +606,7 @@ static void vgacon_invert_region(struct vc_data *c, u16 * p, int count) { - int col = c->vc_can_do_color; + int col = vga_can_do_color; while (count--) { u16 a = scr_readw(p); @@ -655,7 +662,7 @@ switch (mode) { case CM_ERASE: write_vga(14, (c->vc_pos - vga_vram_base) / 2); - if (vga_video_type >= VIDEO_TYPE_VGAC) + if (vga_video_type >= VIDEO_TYPE_VGAC) vgacon_set_cursor_size(c->vc_x, 31, 30); else vgacon_set_cursor_size(c->vc_x, 31, 31); @@ -719,6 +726,8 @@ spin_lock_irqsave(&vga_lock, flags); + vgacon_xres = width * VGA_FONTWIDTH; + vgacon_yres = height * c->vc_font.height; if (vga_video_type >= VIDEO_TYPE_VGAC) { outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg); max_scan = inb_p(vga_video_port_val); @@ -772,23 +781,30 @@ static int vgacon_switch(struct vc_data *c) { + int x = c->vc_cols * VGA_FONTWIDTH; int y = c->vc_rows * c->vc_font.height; - int x = c->vc_cols = 8; + int rows = ORIG_VIDEO_LINES * vga_default_font_height/ + c->vc_font.height; + /* + * We need to save screen size here as it's the only way + * we can spot the screen has been resized and we need to + * set size of freshly allocated screens ourselves. + */ + vga_video_num_columns = c->vc_cols; + vga_video_num_lines = c->vc_rows; /* We can only copy out the size of the video buffer here, - * otherwise we get into VGA BIOS. We can only copy out - * the size of the video buffer here, otherwise we get - * into VGA BIOS */ + * otherwise we get into VGA BIOS */ if (!vga_is_gfx) { - struct winsize *ws = &c->vc_tty->winsize; - scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - if ((ws->ws_xpixel != x || ws->ws_ypixel != y) && - (!(c->vc_cols % 2) && c->vc_cols <= ORIG_VIDEO_COLS)) + if ((vgacon_xres != x || vgacon_yres != y) && + (!(vga_video_num_columns % 2) && + vga_video_num_columns <= ORIG_VIDEO_COLS && + vga_video_num_lines <= rows)) vgacon_doresize(c, c->vc_cols, c->vc_rows); } @@ -812,7 +828,8 @@ static int vgacon_set_palette(struct vc_data *vc, unsigned char *table) { #ifdef CAN_LOAD_PALETTE - if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked) + if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked + || !IS_VISIBLE) return -EINVAL; vga_set_palette(vc, table); return 0; @@ -1125,7 +1142,6 @@ /* attribute controller */ for (i = 0; i < vga_vt.vc_count; i++) { struct vc_data *vc = vga_vt.vc_cons[i]; - if (vc) vc->vc_hi_font_mask = ch512 ? 0x0800 : 0; } @@ -1151,13 +1167,8 @@ static int vgacon_adjust_height(struct vc_data *vc, unsigned fontheight) { unsigned char ovr, vde, fsr; - int rows, maxscan; + int rows, maxscan, i; - if (fontheight == vc->vc_font.height) - return 0; - - vc->vc_font.height = fontheight; - rows = vc->vc_scan_lines / fontheight; /* Number of video rows we end up with */ maxscan = rows * fontheight - 1; /* Scan lines to actually display-1 */ @@ -1191,14 +1202,21 @@ outb_p(0x12, vga_video_port_reg); /* Vertical display limit */ outb_p(vde, vga_video_port_val); spin_unlock_irq(&vga_lock); + vga_video_font_height = fontheight; - if (IS_VISIBLE) { - /* void size to cause regs to be rewritten */ - cursor_size_lastfrom = 0; - cursor_size_lastto = 0; - vgacon_cursor(vc, CM_DRAW); - vc->vc_font.height = fontheight; - vc_resize(vc, 0, rows); /* Adjust console size */ + for (i = 0; i < vga_vt.vc_count; i++) { + struct vc_data *vc = vga_vt.vc_cons[i]; + + if (vc) { + if (IS_VISIBLE) { + /* void size to cause regs to be rewritten */ + cursor_size_lastfrom = 0; + cursor_size_lastto = 0; + vc->display_fg->vt_sw->con_cursor(vc, CM_DRAW); + } + vc->vc_font.height = fontheight; + vc_resize(vc, 0, rows); /* Adjust console size */ + } } return 0; } @@ -1211,7 +1229,8 @@ if (vga_video_type < VIDEO_TYPE_EGAM) return -EINVAL; - if (font->width != 8 || (charcount != 256 && charcount != 512)) + if (font->width != VGA_FONTWIDTH || + (charcount != 256 && charcount != 512)) return -EINVAL; rc = vgacon_do_font_op(&state, font->data, 1, charcount == 512); @@ -1228,7 +1247,7 @@ if (vga_video_type < VIDEO_TYPE_EGAM) return -EINVAL; - font->width = 8; + font->width = VGA_FONTWIDTH; font->height = c->vc_font.height; font->charcount = vga_512_chars ? 512 : 256; if (!font->data) @@ -1247,7 +1266,7 @@ unsigned int height) { if (width % 2 || width > ORIG_VIDEO_COLS || - height > (ORIG_VIDEO_LINES * vc->vc_font.height)/ + height > (ORIG_VIDEO_LINES * vga_default_font_height)/ vc->vc_font.height) /* let svgatextmode tinker with video timings */ return 0; @@ -1260,7 +1279,7 @@ static int vgacon_set_origin(struct vc_data *c) { if (vga_is_gfx || /* We don't play origin tricks in graphic modes */ - (c->display_fg->vt_blanked && !vga_palette_blanked)) /* Nor we write to blanked screens */ + (c->display_fg->vt_blanked && !vga_palette_blanked))/* Nor we write to blanked screens */ return 0; c->vc_origin = c->vc_visible_origin = vga_vram_base; vga_set_mem_top(c); @@ -1270,6 +1289,18 @@ static void vgacon_save_screen(struct vc_data *c) { + static int vga_bootup_console = 0; + + if (!vga_bootup_console) { + /* This is a gross hack, but here is the only place we can + * set bootup console parameters without messing up generic + * console initialization routines. + */ + vga_bootup_console = 1; + c->vc_x = ORIG_X; + c->vc_y = ORIG_Y; + } + /* We can't copy in more then the size of the video buffer, * or we'll be copying in VGA BIOS */ @@ -1279,7 +1310,7 @@ } static int vgacon_scroll_region(struct vc_data *c, int t, int b, int dir, - int lines) + int lines) { unsigned long oldo; unsigned int delta; @@ -1370,7 +1401,7 @@ memset(&vga_vt, 0, sizeof(struct vt_struct)); vga_vt.kmalloced = 0; vga_vt.vt_sw = &vga_con; - display_desc = vt_map_display(&vga_vt, 1, MAX_NR_USER_CONSOLES); + display_desc = vt_map_display(&vga_vt, 1, 16); if (!display_desc) return -ENODEV; printk("Console: %s %s %dx%d vc:%d-%d\n", vga_vt.default_mode->vc_can_do_color ? "Colour" : "Mono", @@ -1378,6 +1409,6 @@ vga_vt.default_mode->vc_rows, vga_vt.first_vc + 1, vga_vt.first_vc + vga_vt.vc_count); return 0; -} +} MODULE_LICENSE("GPL"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |