aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/console/vgacon.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-01-23 23:14:19 -0500
committerDave Airlie <airlied@redhat.com>2013-02-06 21:37:03 -0500
commit2a2483072393b27f4336ab068a1f48ca19ff1c1e (patch)
tree388d0b8d5f208db9dabcca235a4da79a8bafd1ff /drivers/video/console/vgacon.c
parent1589a3e7777631ff56dd58cd7dcdf275185e62b5 (diff)
vgacon/vt: clear buffer attributes when we load a 512 character font (v2)
When we switch from 256->512 byte font rendering mode, it means the current contents of the screen is being reinterpreted. The bit that holds the high bit of the 9-bit font, may have been previously set, and thus the new font misrenders. The problem case we see is grub2 writes spaces with the bit set, so it ends up with data like 0x820, which gets reinterpreted into 0x120 char which the font translates into G with a circumflex. This flashes up on screen at boot and is quite ugly. A current side effect of this patch though is that any rendering on the screen changes color to a slightly darker color, but at least the screen no longer corrupts. v2: as suggested by hpa, always clear the attribute space, whether we are are going to or from 512 chars. Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/video/console/vgacon.c')
-rw-r--r--drivers/video/console/vgacon.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index d449a74d4a31..5855d17d19ac 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -1064,7 +1064,7 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
1064 unsigned short video_port_status = vga_video_port_reg + 6; 1064 unsigned short video_port_status = vga_video_port_reg + 6;
1065 int font_select = 0x00, beg, i; 1065 int font_select = 0x00, beg, i;
1066 char *charmap; 1066 char *charmap;
1067 1067 bool clear_attribs = false;
1068 if (vga_video_type != VIDEO_TYPE_EGAM) { 1068 if (vga_video_type != VIDEO_TYPE_EGAM) {
1069 charmap = (char *) VGA_MAP_MEM(colourmap, 0); 1069 charmap = (char *) VGA_MAP_MEM(colourmap, 0);
1070 beg = 0x0e; 1070 beg = 0x0e;
@@ -1169,12 +1169,6 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
1169 1169
1170 /* if 512 char mode is already enabled don't re-enable it. */ 1170 /* if 512 char mode is already enabled don't re-enable it. */
1171 if ((set) && (ch512 != vga_512_chars)) { 1171 if ((set) && (ch512 != vga_512_chars)) {
1172 /* attribute controller */
1173 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1174 struct vc_data *c = vc_cons[i].d;
1175 if (c && c->vc_sw == &vga_con)
1176 c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
1177 }
1178 vga_512_chars = ch512; 1172 vga_512_chars = ch512;
1179 /* 256-char: enable intensity bit 1173 /* 256-char: enable intensity bit
1180 512-char: disable intensity bit */ 1174 512-char: disable intensity bit */
@@ -1185,8 +1179,22 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
1185 it means, but it works, and it appears necessary */ 1179 it means, but it works, and it appears necessary */
1186 inb_p(video_port_status); 1180 inb_p(video_port_status);
1187 vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0); 1181 vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0);
1182 clear_attribs = true;
1188 } 1183 }
1189 raw_spin_unlock_irq(&vga_lock); 1184 raw_spin_unlock_irq(&vga_lock);
1185
1186 if (clear_attribs) {
1187 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1188 struct vc_data *c = vc_cons[i].d;
1189 if (c && c->vc_sw == &vga_con) {
1190 /* force hi font mask to 0, so we always clear
1191 the bit on either transition */
1192 c->vc_hi_font_mask = 0x00;
1193 clear_buffer_attributes(c);
1194 c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
1195 }
1196 }
1197 }
1190 return 0; 1198 return 0;
1191} 1199}
1192 1200