xref: /openbmc/qemu/hw/display/vga.c (revision d36f7de8)
1 /*
2  * QEMU VGA Emulator.
3  *
4  * Copyright (c) 2003 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "qemu/osdep.h"
25 #include "qemu/units.h"
26 #include "qapi/error.h"
27 #include "hw/hw.h"
28 #include "hw/display/vga.h"
29 #include "hw/pci/pci.h"
30 #include "vga_int.h"
31 #include "vga_regs.h"
32 #include "ui/pixel_ops.h"
33 #include "qemu/timer.h"
34 #include "hw/xen/xen.h"
35 #include "trace.h"
36 
37 //#define DEBUG_VGA_MEM
38 //#define DEBUG_VGA_REG
39 
40 /* 16 state changes per vertical frame @60 Hz */
41 #define VGA_TEXT_CURSOR_PERIOD_MS       (1000 * 2 * 16 / 60)
42 
43 /*
44  * Video Graphics Array (VGA)
45  *
46  * Chipset docs for original IBM VGA:
47  * http://www.mcamafia.de/pdf/ibm_vgaxga_trm2.pdf
48  *
49  * FreeVGA site:
50  * http://www.osdever.net/FreeVGA/home.htm
51  *
52  * Standard VGA features and Bochs VBE extensions are implemented.
53  */
54 
55 /* force some bits to zero */
56 const uint8_t sr_mask[8] = {
57     0x03,
58     0x3d,
59     0x0f,
60     0x3f,
61     0x0e,
62     0x00,
63     0x00,
64     0xff,
65 };
66 
67 const uint8_t gr_mask[16] = {
68     0x0f, /* 0x00 */
69     0x0f, /* 0x01 */
70     0x0f, /* 0x02 */
71     0x1f, /* 0x03 */
72     0x03, /* 0x04 */
73     0x7b, /* 0x05 */
74     0x0f, /* 0x06 */
75     0x0f, /* 0x07 */
76     0xff, /* 0x08 */
77     0x00, /* 0x09 */
78     0x00, /* 0x0a */
79     0x00, /* 0x0b */
80     0x00, /* 0x0c */
81     0x00, /* 0x0d */
82     0x00, /* 0x0e */
83     0x00, /* 0x0f */
84 };
85 
86 #define cbswap_32(__x) \
87 ((uint32_t)( \
88 		(((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
89 		(((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
90 		(((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
91 		(((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
92 
93 #ifdef HOST_WORDS_BIGENDIAN
94 #define PAT(x) cbswap_32(x)
95 #else
96 #define PAT(x) (x)
97 #endif
98 
99 #ifdef HOST_WORDS_BIGENDIAN
100 #define BIG 1
101 #else
102 #define BIG 0
103 #endif
104 
105 #ifdef HOST_WORDS_BIGENDIAN
106 #define GET_PLANE(data, p) (((data) >> (24 - (p) * 8)) & 0xff)
107 #else
108 #define GET_PLANE(data, p) (((data) >> ((p) * 8)) & 0xff)
109 #endif
110 
111 static const uint32_t mask16[16] = {
112     PAT(0x00000000),
113     PAT(0x000000ff),
114     PAT(0x0000ff00),
115     PAT(0x0000ffff),
116     PAT(0x00ff0000),
117     PAT(0x00ff00ff),
118     PAT(0x00ffff00),
119     PAT(0x00ffffff),
120     PAT(0xff000000),
121     PAT(0xff0000ff),
122     PAT(0xff00ff00),
123     PAT(0xff00ffff),
124     PAT(0xffff0000),
125     PAT(0xffff00ff),
126     PAT(0xffffff00),
127     PAT(0xffffffff),
128 };
129 
130 #undef PAT
131 
132 #ifdef HOST_WORDS_BIGENDIAN
133 #define PAT(x) (x)
134 #else
135 #define PAT(x) cbswap_32(x)
136 #endif
137 
138 static uint32_t expand4[256];
139 static uint16_t expand2[256];
140 static uint8_t expand4to8[16];
141 
142 static void vbe_update_vgaregs(VGACommonState *s);
143 
144 static inline bool vbe_enabled(VGACommonState *s)
145 {
146     return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED;
147 }
148 
149 static inline uint8_t sr(VGACommonState *s, int idx)
150 {
151     return vbe_enabled(s) ? s->sr_vbe[idx] : s->sr[idx];
152 }
153 
154 static void vga_update_memory_access(VGACommonState *s)
155 {
156     hwaddr base, offset, size;
157 
158     if (s->legacy_address_space == NULL) {
159         return;
160     }
161 
162     if (s->has_chain4_alias) {
163         memory_region_del_subregion(s->legacy_address_space, &s->chain4_alias);
164         object_unparent(OBJECT(&s->chain4_alias));
165         s->has_chain4_alias = false;
166         s->plane_updated = 0xf;
167     }
168     if ((sr(s, VGA_SEQ_PLANE_WRITE) & VGA_SR02_ALL_PLANES) ==
169         VGA_SR02_ALL_PLANES && sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
170         offset = 0;
171         switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) {
172         case 0:
173             base = 0xa0000;
174             size = 0x20000;
175             break;
176         case 1:
177             base = 0xa0000;
178             size = 0x10000;
179             offset = s->bank_offset;
180             break;
181         case 2:
182             base = 0xb0000;
183             size = 0x8000;
184             break;
185         case 3:
186         default:
187             base = 0xb8000;
188             size = 0x8000;
189             break;
190         }
191         assert(offset + size <= s->vram_size);
192         memory_region_init_alias(&s->chain4_alias, memory_region_owner(&s->vram),
193                                  "vga.chain4", &s->vram, offset, size);
194         memory_region_add_subregion_overlap(s->legacy_address_space, base,
195                                             &s->chain4_alias, 2);
196         s->has_chain4_alias = true;
197     }
198 }
199 
200 static void vga_dumb_update_retrace_info(VGACommonState *s)
201 {
202     (void) s;
203 }
204 
205 static void vga_precise_update_retrace_info(VGACommonState *s)
206 {
207     int htotal_chars;
208     int hretr_start_char;
209     int hretr_skew_chars;
210     int hretr_end_char;
211 
212     int vtotal_lines;
213     int vretr_start_line;
214     int vretr_end_line;
215 
216     int dots;
217 #if 0
218     int div2, sldiv2;
219 #endif
220     int clocking_mode;
221     int clock_sel;
222     const int clk_hz[] = {25175000, 28322000, 25175000, 25175000};
223     int64_t chars_per_sec;
224     struct vga_precise_retrace *r = &s->retrace_info.precise;
225 
226     htotal_chars = s->cr[VGA_CRTC_H_TOTAL] + 5;
227     hretr_start_char = s->cr[VGA_CRTC_H_SYNC_START];
228     hretr_skew_chars = (s->cr[VGA_CRTC_H_SYNC_END] >> 5) & 3;
229     hretr_end_char = s->cr[VGA_CRTC_H_SYNC_END] & 0x1f;
230 
231     vtotal_lines = (s->cr[VGA_CRTC_V_TOTAL] |
232                     (((s->cr[VGA_CRTC_OVERFLOW] & 1) |
233                       ((s->cr[VGA_CRTC_OVERFLOW] >> 4) & 2)) << 8)) + 2;
234     vretr_start_line = s->cr[VGA_CRTC_V_SYNC_START] |
235         ((((s->cr[VGA_CRTC_OVERFLOW] >> 2) & 1) |
236           ((s->cr[VGA_CRTC_OVERFLOW] >> 6) & 2)) << 8);
237     vretr_end_line = s->cr[VGA_CRTC_V_SYNC_END] & 0xf;
238 
239     clocking_mode = (sr(s, VGA_SEQ_CLOCK_MODE) >> 3) & 1;
240     clock_sel = (s->msr >> 2) & 3;
241     dots = (s->msr & 1) ? 8 : 9;
242 
243     chars_per_sec = clk_hz[clock_sel] / dots;
244 
245     htotal_chars <<= clocking_mode;
246 
247     r->total_chars = vtotal_lines * htotal_chars;
248     if (r->freq) {
249         r->ticks_per_char = NANOSECONDS_PER_SECOND / (r->total_chars * r->freq);
250     } else {
251         r->ticks_per_char = NANOSECONDS_PER_SECOND / chars_per_sec;
252     }
253 
254     r->vstart = vretr_start_line;
255     r->vend = r->vstart + vretr_end_line + 1;
256 
257     r->hstart = hretr_start_char + hretr_skew_chars;
258     r->hend = r->hstart + hretr_end_char + 1;
259     r->htotal = htotal_chars;
260 
261 #if 0
262     div2 = (s->cr[VGA_CRTC_MODE] >> 2) & 1;
263     sldiv2 = (s->cr[VGA_CRTC_MODE] >> 3) & 1;
264     printf (
265         "hz=%f\n"
266         "htotal = %d\n"
267         "hretr_start = %d\n"
268         "hretr_skew = %d\n"
269         "hretr_end = %d\n"
270         "vtotal = %d\n"
271         "vretr_start = %d\n"
272         "vretr_end = %d\n"
273         "div2 = %d sldiv2 = %d\n"
274         "clocking_mode = %d\n"
275         "clock_sel = %d %d\n"
276         "dots = %d\n"
277         "ticks/char = %" PRId64 "\n"
278         "\n",
279         (double) NANOSECONDS_PER_SECOND / (r->ticks_per_char * r->total_chars),
280         htotal_chars,
281         hretr_start_char,
282         hretr_skew_chars,
283         hretr_end_char,
284         vtotal_lines,
285         vretr_start_line,
286         vretr_end_line,
287         div2, sldiv2,
288         clocking_mode,
289         clock_sel,
290         clk_hz[clock_sel],
291         dots,
292         r->ticks_per_char
293         );
294 #endif
295 }
296 
297 static uint8_t vga_precise_retrace(VGACommonState *s)
298 {
299     struct vga_precise_retrace *r = &s->retrace_info.precise;
300     uint8_t val = s->st01 & ~(ST01_V_RETRACE | ST01_DISP_ENABLE);
301 
302     if (r->total_chars) {
303         int cur_line, cur_line_char, cur_char;
304         int64_t cur_tick;
305 
306         cur_tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
307 
308         cur_char = (cur_tick / r->ticks_per_char) % r->total_chars;
309         cur_line = cur_char / r->htotal;
310 
311         if (cur_line >= r->vstart && cur_line <= r->vend) {
312             val |= ST01_V_RETRACE | ST01_DISP_ENABLE;
313         } else {
314             cur_line_char = cur_char % r->htotal;
315             if (cur_line_char >= r->hstart && cur_line_char <= r->hend) {
316                 val |= ST01_DISP_ENABLE;
317             }
318         }
319 
320         return val;
321     } else {
322         return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
323     }
324 }
325 
326 static uint8_t vga_dumb_retrace(VGACommonState *s)
327 {
328     return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
329 }
330 
331 int vga_ioport_invalid(VGACommonState *s, uint32_t addr)
332 {
333     if (s->msr & VGA_MIS_COLOR) {
334         /* Color */
335         return (addr >= 0x3b0 && addr <= 0x3bf);
336     } else {
337         /* Monochrome */
338         return (addr >= 0x3d0 && addr <= 0x3df);
339     }
340 }
341 
342 uint32_t vga_ioport_read(void *opaque, uint32_t addr)
343 {
344     VGACommonState *s = opaque;
345     int val, index;
346 
347     if (vga_ioport_invalid(s, addr)) {
348         val = 0xff;
349     } else {
350         switch(addr) {
351         case VGA_ATT_W:
352             if (s->ar_flip_flop == 0) {
353                 val = s->ar_index;
354             } else {
355                 val = 0;
356             }
357             break;
358         case VGA_ATT_R:
359             index = s->ar_index & 0x1f;
360             if (index < VGA_ATT_C) {
361                 val = s->ar[index];
362             } else {
363                 val = 0;
364             }
365             break;
366         case VGA_MIS_W:
367             val = s->st00;
368             break;
369         case VGA_SEQ_I:
370             val = s->sr_index;
371             break;
372         case VGA_SEQ_D:
373             val = s->sr[s->sr_index];
374 #ifdef DEBUG_VGA_REG
375             printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
376 #endif
377             break;
378         case VGA_PEL_IR:
379             val = s->dac_state;
380             break;
381         case VGA_PEL_IW:
382             val = s->dac_write_index;
383             break;
384         case VGA_PEL_D:
385             val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
386             if (++s->dac_sub_index == 3) {
387                 s->dac_sub_index = 0;
388                 s->dac_read_index++;
389             }
390             break;
391         case VGA_FTC_R:
392             val = s->fcr;
393             break;
394         case VGA_MIS_R:
395             val = s->msr;
396             break;
397         case VGA_GFX_I:
398             val = s->gr_index;
399             break;
400         case VGA_GFX_D:
401             val = s->gr[s->gr_index];
402 #ifdef DEBUG_VGA_REG
403             printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
404 #endif
405             break;
406         case VGA_CRT_IM:
407         case VGA_CRT_IC:
408             val = s->cr_index;
409             break;
410         case VGA_CRT_DM:
411         case VGA_CRT_DC:
412             val = s->cr[s->cr_index];
413 #ifdef DEBUG_VGA_REG
414             printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
415 #endif
416             break;
417         case VGA_IS1_RM:
418         case VGA_IS1_RC:
419             /* just toggle to fool polling */
420             val = s->st01 = s->retrace(s);
421             s->ar_flip_flop = 0;
422             break;
423         default:
424             val = 0x00;
425             break;
426         }
427     }
428     trace_vga_std_read_io(addr, val);
429     return val;
430 }
431 
432 void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
433 {
434     VGACommonState *s = opaque;
435     int index;
436 
437     /* check port range access depending on color/monochrome mode */
438     if (vga_ioport_invalid(s, addr)) {
439         return;
440     }
441     trace_vga_std_write_io(addr, val);
442 
443     switch(addr) {
444     case VGA_ATT_W:
445         if (s->ar_flip_flop == 0) {
446             val &= 0x3f;
447             s->ar_index = val;
448         } else {
449             index = s->ar_index & 0x1f;
450             switch(index) {
451             case VGA_ATC_PALETTE0 ... VGA_ATC_PALETTEF:
452                 s->ar[index] = val & 0x3f;
453                 break;
454             case VGA_ATC_MODE:
455                 s->ar[index] = val & ~0x10;
456                 break;
457             case VGA_ATC_OVERSCAN:
458                 s->ar[index] = val;
459                 break;
460             case VGA_ATC_PLANE_ENABLE:
461                 s->ar[index] = val & ~0xc0;
462                 break;
463             case VGA_ATC_PEL:
464                 s->ar[index] = val & ~0xf0;
465                 break;
466             case VGA_ATC_COLOR_PAGE:
467                 s->ar[index] = val & ~0xf0;
468                 break;
469             default:
470                 break;
471             }
472         }
473         s->ar_flip_flop ^= 1;
474         break;
475     case VGA_MIS_W:
476         s->msr = val & ~0x10;
477         s->update_retrace_info(s);
478         break;
479     case VGA_SEQ_I:
480         s->sr_index = val & 7;
481         break;
482     case VGA_SEQ_D:
483 #ifdef DEBUG_VGA_REG
484         printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
485 #endif
486         s->sr[s->sr_index] = val & sr_mask[s->sr_index];
487         if (s->sr_index == VGA_SEQ_CLOCK_MODE) {
488             s->update_retrace_info(s);
489         }
490         vga_update_memory_access(s);
491         break;
492     case VGA_PEL_IR:
493         s->dac_read_index = val;
494         s->dac_sub_index = 0;
495         s->dac_state = 3;
496         break;
497     case VGA_PEL_IW:
498         s->dac_write_index = val;
499         s->dac_sub_index = 0;
500         s->dac_state = 0;
501         break;
502     case VGA_PEL_D:
503         s->dac_cache[s->dac_sub_index] = val;
504         if (++s->dac_sub_index == 3) {
505             memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
506             s->dac_sub_index = 0;
507             s->dac_write_index++;
508         }
509         break;
510     case VGA_GFX_I:
511         s->gr_index = val & 0x0f;
512         break;
513     case VGA_GFX_D:
514 #ifdef DEBUG_VGA_REG
515         printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
516 #endif
517         s->gr[s->gr_index] = val & gr_mask[s->gr_index];
518         vbe_update_vgaregs(s);
519         vga_update_memory_access(s);
520         break;
521     case VGA_CRT_IM:
522     case VGA_CRT_IC:
523         s->cr_index = val;
524         break;
525     case VGA_CRT_DM:
526     case VGA_CRT_DC:
527 #ifdef DEBUG_VGA_REG
528         printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
529 #endif
530         /* handle CR0-7 protection */
531         if ((s->cr[VGA_CRTC_V_SYNC_END] & VGA_CR11_LOCK_CR0_CR7) &&
532             s->cr_index <= VGA_CRTC_OVERFLOW) {
533             /* can always write bit 4 of CR7 */
534             if (s->cr_index == VGA_CRTC_OVERFLOW) {
535                 s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
536                     (val & 0x10);
537                 vbe_update_vgaregs(s);
538             }
539             return;
540         }
541         s->cr[s->cr_index] = val;
542         vbe_update_vgaregs(s);
543 
544         switch(s->cr_index) {
545         case VGA_CRTC_H_TOTAL:
546         case VGA_CRTC_H_SYNC_START:
547         case VGA_CRTC_H_SYNC_END:
548         case VGA_CRTC_V_TOTAL:
549         case VGA_CRTC_OVERFLOW:
550         case VGA_CRTC_V_SYNC_END:
551         case VGA_CRTC_MODE:
552             s->update_retrace_info(s);
553             break;
554         }
555         break;
556     case VGA_IS1_RM:
557     case VGA_IS1_RC:
558         s->fcr = val & 0x10;
559         break;
560     }
561 }
562 
563 /*
564  * Sanity check vbe register writes.
565  *
566  * As we don't have a way to signal errors to the guest in the bochs
567  * dispi interface we'll go adjust the registers to the closest valid
568  * value.
569  */
570 static void vbe_fixup_regs(VGACommonState *s)
571 {
572     uint16_t *r = s->vbe_regs;
573     uint32_t bits, linelength, maxy, offset;
574 
575     if (!vbe_enabled(s)) {
576         /* vbe is turned off -- nothing to do */
577         return;
578     }
579 
580     /* check depth */
581     switch (r[VBE_DISPI_INDEX_BPP]) {
582     case 4:
583     case 8:
584     case 16:
585     case 24:
586     case 32:
587         bits = r[VBE_DISPI_INDEX_BPP];
588         break;
589     case 15:
590         bits = 16;
591         break;
592     default:
593         bits = r[VBE_DISPI_INDEX_BPP] = 8;
594         break;
595     }
596 
597     /* check width */
598     r[VBE_DISPI_INDEX_XRES] &= ~7u;
599     if (r[VBE_DISPI_INDEX_XRES] == 0) {
600         r[VBE_DISPI_INDEX_XRES] = 8;
601     }
602     if (r[VBE_DISPI_INDEX_XRES] > VBE_DISPI_MAX_XRES) {
603         r[VBE_DISPI_INDEX_XRES] = VBE_DISPI_MAX_XRES;
604     }
605     r[VBE_DISPI_INDEX_VIRT_WIDTH] &= ~7u;
606     if (r[VBE_DISPI_INDEX_VIRT_WIDTH] > VBE_DISPI_MAX_XRES) {
607         r[VBE_DISPI_INDEX_VIRT_WIDTH] = VBE_DISPI_MAX_XRES;
608     }
609     if (r[VBE_DISPI_INDEX_VIRT_WIDTH] < r[VBE_DISPI_INDEX_XRES]) {
610         r[VBE_DISPI_INDEX_VIRT_WIDTH] = r[VBE_DISPI_INDEX_XRES];
611     }
612 
613     /* check height */
614     linelength = r[VBE_DISPI_INDEX_VIRT_WIDTH] * bits / 8;
615     maxy = s->vbe_size / linelength;
616     if (r[VBE_DISPI_INDEX_YRES] == 0) {
617         r[VBE_DISPI_INDEX_YRES] = 1;
618     }
619     if (r[VBE_DISPI_INDEX_YRES] > VBE_DISPI_MAX_YRES) {
620         r[VBE_DISPI_INDEX_YRES] = VBE_DISPI_MAX_YRES;
621     }
622     if (r[VBE_DISPI_INDEX_YRES] > maxy) {
623         r[VBE_DISPI_INDEX_YRES] = maxy;
624     }
625 
626     /* check offset */
627     if (r[VBE_DISPI_INDEX_X_OFFSET] > VBE_DISPI_MAX_XRES) {
628         r[VBE_DISPI_INDEX_X_OFFSET] = VBE_DISPI_MAX_XRES;
629     }
630     if (r[VBE_DISPI_INDEX_Y_OFFSET] > VBE_DISPI_MAX_YRES) {
631         r[VBE_DISPI_INDEX_Y_OFFSET] = VBE_DISPI_MAX_YRES;
632     }
633     offset = r[VBE_DISPI_INDEX_X_OFFSET] * bits / 8;
634     offset += r[VBE_DISPI_INDEX_Y_OFFSET] * linelength;
635     if (offset + r[VBE_DISPI_INDEX_YRES] * linelength > s->vbe_size) {
636         r[VBE_DISPI_INDEX_Y_OFFSET] = 0;
637         offset = r[VBE_DISPI_INDEX_X_OFFSET] * bits / 8;
638         if (offset + r[VBE_DISPI_INDEX_YRES] * linelength > s->vbe_size) {
639             r[VBE_DISPI_INDEX_X_OFFSET] = 0;
640             offset = 0;
641         }
642     }
643 
644     /* update vga state */
645     r[VBE_DISPI_INDEX_VIRT_HEIGHT] = maxy;
646     s->vbe_line_offset = linelength;
647     s->vbe_start_addr  = offset / 4;
648 }
649 
650 /* we initialize the VGA graphic mode */
651 static void vbe_update_vgaregs(VGACommonState *s)
652 {
653     int h, shift_control;
654 
655     if (!vbe_enabled(s)) {
656         /* vbe is turned off -- nothing to do */
657         return;
658     }
659 
660     /* graphic mode + memory map 1 */
661     s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
662         VGA_GR06_GRAPHICS_MODE;
663     s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
664     s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
665     /* width */
666     s->cr[VGA_CRTC_H_DISP] =
667         (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
668     /* height (only meaningful if < 1024) */
669     h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
670     s->cr[VGA_CRTC_V_DISP_END] = h;
671     s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
672         ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
673     /* line compare to 1023 */
674     s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
675     s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
676     s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
677 
678     if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
679         shift_control = 0;
680         s->sr_vbe[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
681     } else {
682         shift_control = 2;
683         /* set chain 4 mode */
684         s->sr_vbe[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
685         /* activate all planes */
686         s->sr_vbe[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
687     }
688     s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
689         (shift_control << 5);
690     s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
691 }
692 
693 static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
694 {
695     VGACommonState *s = opaque;
696     return s->vbe_index;
697 }
698 
699 uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
700 {
701     VGACommonState *s = opaque;
702     uint32_t val;
703 
704     if (s->vbe_index < VBE_DISPI_INDEX_NB) {
705         if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) {
706             switch(s->vbe_index) {
707                 /* XXX: do not hardcode ? */
708             case VBE_DISPI_INDEX_XRES:
709                 val = VBE_DISPI_MAX_XRES;
710                 break;
711             case VBE_DISPI_INDEX_YRES:
712                 val = VBE_DISPI_MAX_YRES;
713                 break;
714             case VBE_DISPI_INDEX_BPP:
715                 val = VBE_DISPI_MAX_BPP;
716                 break;
717             default:
718                 val = s->vbe_regs[s->vbe_index];
719                 break;
720             }
721         } else {
722             val = s->vbe_regs[s->vbe_index];
723         }
724     } else if (s->vbe_index == VBE_DISPI_INDEX_VIDEO_MEMORY_64K) {
725         val = s->vbe_size / (64 * KiB);
726     } else {
727         val = 0;
728     }
729     trace_vga_vbe_read(s->vbe_index, val);
730     return val;
731 }
732 
733 void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
734 {
735     VGACommonState *s = opaque;
736     s->vbe_index = val;
737 }
738 
739 void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
740 {
741     VGACommonState *s = opaque;
742 
743     if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
744         trace_vga_vbe_write(s->vbe_index, val);
745         switch(s->vbe_index) {
746         case VBE_DISPI_INDEX_ID:
747             if (val == VBE_DISPI_ID0 ||
748                 val == VBE_DISPI_ID1 ||
749                 val == VBE_DISPI_ID2 ||
750                 val == VBE_DISPI_ID3 ||
751                 val == VBE_DISPI_ID4) {
752                 s->vbe_regs[s->vbe_index] = val;
753             }
754             break;
755         case VBE_DISPI_INDEX_XRES:
756         case VBE_DISPI_INDEX_YRES:
757         case VBE_DISPI_INDEX_BPP:
758         case VBE_DISPI_INDEX_VIRT_WIDTH:
759         case VBE_DISPI_INDEX_X_OFFSET:
760         case VBE_DISPI_INDEX_Y_OFFSET:
761             s->vbe_regs[s->vbe_index] = val;
762             vbe_fixup_regs(s);
763             vbe_update_vgaregs(s);
764             break;
765         case VBE_DISPI_INDEX_BANK:
766             val &= s->vbe_bank_mask;
767             s->vbe_regs[s->vbe_index] = val;
768             s->bank_offset = (val << 16);
769             vga_update_memory_access(s);
770             break;
771         case VBE_DISPI_INDEX_ENABLE:
772             if ((val & VBE_DISPI_ENABLED) &&
773                 !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
774 
775                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0;
776                 s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
777                 s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
778                 s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
779                 vbe_fixup_regs(s);
780                 vbe_update_vgaregs(s);
781 
782                 /* clear the screen */
783                 if (!(val & VBE_DISPI_NOCLEARMEM)) {
784                     memset(s->vram_ptr, 0,
785                            s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
786                 }
787             } else {
788                 s->bank_offset = 0;
789             }
790             s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
791             s->vbe_regs[s->vbe_index] = val;
792             vga_update_memory_access(s);
793             break;
794         default:
795             break;
796         }
797     }
798 }
799 
800 /* called for accesses between 0xa0000 and 0xc0000 */
801 uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr)
802 {
803     int memory_map_mode, plane;
804     uint32_t ret;
805 
806     /* convert to VGA memory offset */
807     memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
808     addr &= 0x1ffff;
809     switch(memory_map_mode) {
810     case 0:
811         break;
812     case 1:
813         if (addr >= 0x10000)
814             return 0xff;
815         addr += s->bank_offset;
816         break;
817     case 2:
818         addr -= 0x10000;
819         if (addr >= 0x8000)
820             return 0xff;
821         break;
822     default:
823     case 3:
824         addr -= 0x18000;
825         if (addr >= 0x8000)
826             return 0xff;
827         break;
828     }
829 
830     if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
831         /* chain 4 mode : simplest access */
832         assert(addr < s->vram_size);
833         ret = s->vram_ptr[addr];
834     } else if (s->gr[VGA_GFX_MODE] & 0x10) {
835         /* odd/even mode (aka text mode mapping) */
836         plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
837         addr = ((addr & ~1) << 1) | plane;
838         if (addr >= s->vram_size) {
839             return 0xff;
840         }
841         ret = s->vram_ptr[addr];
842     } else {
843         /* standard VGA latched access */
844         if (addr * sizeof(uint32_t) >= s->vram_size) {
845             return 0xff;
846         }
847         s->latch = ((uint32_t *)s->vram_ptr)[addr];
848 
849         if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
850             /* read mode 0 */
851             plane = s->gr[VGA_GFX_PLANE_READ];
852             ret = GET_PLANE(s->latch, plane);
853         } else {
854             /* read mode 1 */
855             ret = (s->latch ^ mask16[s->gr[VGA_GFX_COMPARE_VALUE]]) &
856                 mask16[s->gr[VGA_GFX_COMPARE_MASK]];
857             ret |= ret >> 16;
858             ret |= ret >> 8;
859             ret = (~ret) & 0xff;
860         }
861     }
862     return ret;
863 }
864 
865 /* called for accesses between 0xa0000 and 0xc0000 */
866 void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
867 {
868     int memory_map_mode, plane, write_mode, b, func_select, mask;
869     uint32_t write_mask, bit_mask, set_mask;
870 
871 #ifdef DEBUG_VGA_MEM
872     printf("vga: [0x" TARGET_FMT_plx "] = 0x%02x\n", addr, val);
873 #endif
874     /* convert to VGA memory offset */
875     memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3;
876     addr &= 0x1ffff;
877     switch(memory_map_mode) {
878     case 0:
879         break;
880     case 1:
881         if (addr >= 0x10000)
882             return;
883         addr += s->bank_offset;
884         break;
885     case 2:
886         addr -= 0x10000;
887         if (addr >= 0x8000)
888             return;
889         break;
890     default:
891     case 3:
892         addr -= 0x18000;
893         if (addr >= 0x8000)
894             return;
895         break;
896     }
897 
898     if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
899         /* chain 4 mode : simplest access */
900         plane = addr & 3;
901         mask = (1 << plane);
902         if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) {
903             assert(addr < s->vram_size);
904             s->vram_ptr[addr] = val;
905 #ifdef DEBUG_VGA_MEM
906             printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
907 #endif
908             s->plane_updated |= mask; /* only used to detect font change */
909             memory_region_set_dirty(&s->vram, addr, 1);
910         }
911     } else if (s->gr[VGA_GFX_MODE] & 0x10) {
912         /* odd/even mode (aka text mode mapping) */
913         plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
914         mask = (1 << plane);
915         if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) {
916             addr = ((addr & ~1) << 1) | plane;
917             if (addr >= s->vram_size) {
918                 return;
919             }
920             s->vram_ptr[addr] = val;
921 #ifdef DEBUG_VGA_MEM
922             printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
923 #endif
924             s->plane_updated |= mask; /* only used to detect font change */
925             memory_region_set_dirty(&s->vram, addr, 1);
926         }
927     } else {
928         /* standard VGA latched access */
929         write_mode = s->gr[VGA_GFX_MODE] & 3;
930         switch(write_mode) {
931         default:
932         case 0:
933             /* rotate */
934             b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
935             val = ((val >> b) | (val << (8 - b))) & 0xff;
936             val |= val << 8;
937             val |= val << 16;
938 
939             /* apply set/reset mask */
940             set_mask = mask16[s->gr[VGA_GFX_SR_ENABLE]];
941             val = (val & ~set_mask) |
942                 (mask16[s->gr[VGA_GFX_SR_VALUE]] & set_mask);
943             bit_mask = s->gr[VGA_GFX_BIT_MASK];
944             break;
945         case 1:
946             val = s->latch;
947             goto do_write;
948         case 2:
949             val = mask16[val & 0x0f];
950             bit_mask = s->gr[VGA_GFX_BIT_MASK];
951             break;
952         case 3:
953             /* rotate */
954             b = s->gr[VGA_GFX_DATA_ROTATE] & 7;
955             val = (val >> b) | (val << (8 - b));
956 
957             bit_mask = s->gr[VGA_GFX_BIT_MASK] & val;
958             val = mask16[s->gr[VGA_GFX_SR_VALUE]];
959             break;
960         }
961 
962         /* apply logical operation */
963         func_select = s->gr[VGA_GFX_DATA_ROTATE] >> 3;
964         switch(func_select) {
965         case 0:
966         default:
967             /* nothing to do */
968             break;
969         case 1:
970             /* and */
971             val &= s->latch;
972             break;
973         case 2:
974             /* or */
975             val |= s->latch;
976             break;
977         case 3:
978             /* xor */
979             val ^= s->latch;
980             break;
981         }
982 
983         /* apply bit mask */
984         bit_mask |= bit_mask << 8;
985         bit_mask |= bit_mask << 16;
986         val = (val & bit_mask) | (s->latch & ~bit_mask);
987 
988     do_write:
989         /* mask data according to sr[2] */
990         mask = sr(s, VGA_SEQ_PLANE_WRITE);
991         s->plane_updated |= mask; /* only used to detect font change */
992         write_mask = mask16[mask];
993         if (addr * sizeof(uint32_t) >= s->vram_size) {
994             return;
995         }
996         ((uint32_t *)s->vram_ptr)[addr] =
997             (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
998             (val & write_mask);
999 #ifdef DEBUG_VGA_MEM
1000         printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
1001                addr * 4, write_mask, val);
1002 #endif
1003         memory_region_set_dirty(&s->vram, addr << 2, sizeof(uint32_t));
1004     }
1005 }
1006 
1007 typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
1008                                 uint32_t srcaddr, int width);
1009 
1010 #include "vga-helpers.h"
1011 
1012 /* return true if the palette was modified */
1013 static int update_palette16(VGACommonState *s)
1014 {
1015     int full_update, i;
1016     uint32_t v, col, *palette;
1017 
1018     full_update = 0;
1019     palette = s->last_palette;
1020     for(i = 0; i < 16; i++) {
1021         v = s->ar[i];
1022         if (s->ar[VGA_ATC_MODE] & 0x80) {
1023             v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xf) << 4) | (v & 0xf);
1024         } else {
1025             v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f);
1026         }
1027         v = v * 3;
1028         col = rgb_to_pixel32(c6_to_8(s->palette[v]),
1029                              c6_to_8(s->palette[v + 1]),
1030                              c6_to_8(s->palette[v + 2]));
1031         if (col != palette[i]) {
1032             full_update = 1;
1033             palette[i] = col;
1034         }
1035     }
1036     return full_update;
1037 }
1038 
1039 /* return true if the palette was modified */
1040 static int update_palette256(VGACommonState *s)
1041 {
1042     int full_update, i;
1043     uint32_t v, col, *palette;
1044 
1045     full_update = 0;
1046     palette = s->last_palette;
1047     v = 0;
1048     for(i = 0; i < 256; i++) {
1049         if (s->dac_8bit) {
1050             col = rgb_to_pixel32(s->palette[v],
1051                                  s->palette[v + 1],
1052                                  s->palette[v + 2]);
1053         } else {
1054             col = rgb_to_pixel32(c6_to_8(s->palette[v]),
1055                                  c6_to_8(s->palette[v + 1]),
1056                                  c6_to_8(s->palette[v + 2]));
1057         }
1058         if (col != palette[i]) {
1059             full_update = 1;
1060             palette[i] = col;
1061         }
1062         v += 3;
1063     }
1064     return full_update;
1065 }
1066 
1067 static void vga_get_offsets(VGACommonState *s,
1068                             uint32_t *pline_offset,
1069                             uint32_t *pstart_addr,
1070                             uint32_t *pline_compare)
1071 {
1072     uint32_t start_addr, line_offset, line_compare;
1073 
1074     if (vbe_enabled(s)) {
1075         line_offset = s->vbe_line_offset;
1076         start_addr = s->vbe_start_addr;
1077         line_compare = 65535;
1078     } else {
1079         /* compute line_offset in bytes */
1080         line_offset = s->cr[VGA_CRTC_OFFSET];
1081         line_offset <<= 3;
1082 
1083         /* starting address */
1084         start_addr = s->cr[VGA_CRTC_START_LO] |
1085             (s->cr[VGA_CRTC_START_HI] << 8);
1086 
1087         /* line compare */
1088         line_compare = s->cr[VGA_CRTC_LINE_COMPARE] |
1089             ((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) |
1090             ((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3);
1091     }
1092     *pline_offset = line_offset;
1093     *pstart_addr = start_addr;
1094     *pline_compare = line_compare;
1095 }
1096 
1097 /* update start_addr and line_offset. Return TRUE if modified */
1098 static int update_basic_params(VGACommonState *s)
1099 {
1100     int full_update;
1101     uint32_t start_addr, line_offset, line_compare;
1102 
1103     full_update = 0;
1104 
1105     s->get_offsets(s, &line_offset, &start_addr, &line_compare);
1106 
1107     if (line_offset != s->line_offset ||
1108         start_addr != s->start_addr ||
1109         line_compare != s->line_compare) {
1110         s->line_offset = line_offset;
1111         s->start_addr = start_addr;
1112         s->line_compare = line_compare;
1113         full_update = 1;
1114     }
1115     return full_update;
1116 }
1117 
1118 
1119 static const uint8_t cursor_glyph[32 * 4] = {
1120     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1121     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1122     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1123     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1124     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1125     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1126     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1127     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1128     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1129     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1130     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1131     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1132     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1133     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1134     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1135     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1136 };
1137 
1138 static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight,
1139                                     int *pcwidth, int *pcheight)
1140 {
1141     int width, cwidth, height, cheight;
1142 
1143     /* total width & height */
1144     cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1145     cwidth = 8;
1146     if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
1147         cwidth = 9;
1148     }
1149     if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
1150         cwidth = 16; /* NOTE: no 18 pixel wide */
1151     }
1152     width = (s->cr[VGA_CRTC_H_DISP] + 1);
1153     if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1154         /* ugly hack for CGA 160x100x16 - explain me the logic */
1155         height = 100;
1156     } else {
1157         height = s->cr[VGA_CRTC_V_DISP_END] |
1158             ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1159             ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1160         height = (height + 1) / cheight;
1161     }
1162 
1163     *pwidth = width;
1164     *pheight = height;
1165     *pcwidth = cwidth;
1166     *pcheight = cheight;
1167 }
1168 
1169 /*
1170  * Text mode update
1171  * Missing:
1172  * - double scan
1173  * - double width
1174  * - underline
1175  * - flashing
1176  */
1177 static void vga_draw_text(VGACommonState *s, int full_update)
1178 {
1179     DisplaySurface *surface = qemu_console_surface(s->con);
1180     int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
1181     int cx_min, cx_max, linesize, x_incr, line, line1;
1182     uint32_t offset, fgcol, bgcol, v, cursor_offset;
1183     uint8_t *d1, *d, *src, *dest, *cursor_ptr;
1184     const uint8_t *font_ptr, *font_base[2];
1185     int dup9, line_offset;
1186     uint32_t *palette;
1187     uint32_t *ch_attr_ptr;
1188     int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1189 
1190     /* compute font data address (in plane 2) */
1191     v = sr(s, VGA_SEQ_CHARACTER_MAP);
1192     offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
1193     if (offset != s->font_offsets[0]) {
1194         s->font_offsets[0] = offset;
1195         full_update = 1;
1196     }
1197     font_base[0] = s->vram_ptr + offset;
1198 
1199     offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
1200     font_base[1] = s->vram_ptr + offset;
1201     if (offset != s->font_offsets[1]) {
1202         s->font_offsets[1] = offset;
1203         full_update = 1;
1204     }
1205     if (s->plane_updated & (1 << 2) || s->has_chain4_alias) {
1206         /* if the plane 2 was modified since the last display, it
1207            indicates the font may have been modified */
1208         s->plane_updated = 0;
1209         full_update = 1;
1210     }
1211     full_update |= update_basic_params(s);
1212 
1213     line_offset = s->line_offset;
1214 
1215     vga_get_text_resolution(s, &width, &height, &cw, &cheight);
1216     if ((height * width) <= 1) {
1217         /* better than nothing: exit if transient size is too small */
1218         return;
1219     }
1220     if ((height * width) > CH_ATTR_SIZE) {
1221         /* better than nothing: exit if transient size is too big */
1222         return;
1223     }
1224 
1225     if (width != s->last_width || height != s->last_height ||
1226         cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
1227         s->last_scr_width = width * cw;
1228         s->last_scr_height = height * cheight;
1229         qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
1230         surface = qemu_console_surface(s->con);
1231         dpy_text_resize(s->con, width, height);
1232         s->last_depth = 0;
1233         s->last_width = width;
1234         s->last_height = height;
1235         s->last_ch = cheight;
1236         s->last_cw = cw;
1237         full_update = 1;
1238     }
1239     full_update |= update_palette16(s);
1240     palette = s->last_palette;
1241     x_incr = cw * surface_bytes_per_pixel(surface);
1242 
1243     if (full_update) {
1244         s->full_update_text = 1;
1245     }
1246     if (s->full_update_gfx) {
1247         s->full_update_gfx = 0;
1248         full_update |= 1;
1249     }
1250 
1251     cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1252                      s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
1253     if (cursor_offset != s->cursor_offset ||
1254         s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1255         s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end) {
1256       /* if the cursor position changed, we update the old and new
1257          chars */
1258         if (s->cursor_offset < CH_ATTR_SIZE)
1259             s->last_ch_attr[s->cursor_offset] = -1;
1260         if (cursor_offset < CH_ATTR_SIZE)
1261             s->last_ch_attr[cursor_offset] = -1;
1262         s->cursor_offset = cursor_offset;
1263         s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1264         s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1265     }
1266     cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
1267     if (now >= s->cursor_blink_time) {
1268         s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2;
1269         s->cursor_visible_phase = !s->cursor_visible_phase;
1270     }
1271 
1272     dest = surface_data(surface);
1273     linesize = surface_stride(surface);
1274     ch_attr_ptr = s->last_ch_attr;
1275     line = 0;
1276     offset = s->start_addr * 4;
1277     for(cy = 0; cy < height; cy++) {
1278         d1 = dest;
1279         src = s->vram_ptr + offset;
1280         cx_min = width;
1281         cx_max = -1;
1282         for(cx = 0; cx < width; cx++) {
1283             if (src + sizeof(uint16_t) > s->vram_ptr + s->vram_size) {
1284                 break;
1285             }
1286             ch_attr = *(uint16_t *)src;
1287             if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
1288                 if (cx < cx_min)
1289                     cx_min = cx;
1290                 if (cx > cx_max)
1291                     cx_max = cx;
1292                 *ch_attr_ptr = ch_attr;
1293 #ifdef HOST_WORDS_BIGENDIAN
1294                 ch = ch_attr >> 8;
1295                 cattr = ch_attr & 0xff;
1296 #else
1297                 ch = ch_attr & 0xff;
1298                 cattr = ch_attr >> 8;
1299 #endif
1300                 font_ptr = font_base[(cattr >> 3) & 1];
1301                 font_ptr += 32 * 4 * ch;
1302                 bgcol = palette[cattr >> 4];
1303                 fgcol = palette[cattr & 0x0f];
1304                 if (cw == 16) {
1305                     vga_draw_glyph16(d1, linesize,
1306                                      font_ptr, cheight, fgcol, bgcol);
1307                 } else if (cw != 9) {
1308                     vga_draw_glyph8(d1, linesize,
1309                                     font_ptr, cheight, fgcol, bgcol);
1310                 } else {
1311                     dup9 = 0;
1312                     if (ch >= 0xb0 && ch <= 0xdf &&
1313                         (s->ar[VGA_ATC_MODE] & 0x04)) {
1314                         dup9 = 1;
1315                     }
1316                     vga_draw_glyph9(d1, linesize,
1317                                     font_ptr, cheight, fgcol, bgcol, dup9);
1318                 }
1319                 if (src == cursor_ptr &&
1320                     !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) &&
1321                     s->cursor_visible_phase) {
1322                     int line_start, line_last, h;
1323                     /* draw the cursor */
1324                     line_start = s->cr[VGA_CRTC_CURSOR_START] & 0x1f;
1325                     line_last = s->cr[VGA_CRTC_CURSOR_END] & 0x1f;
1326                     /* XXX: check that */
1327                     if (line_last > cheight - 1)
1328                         line_last = cheight - 1;
1329                     if (line_last >= line_start && line_start < cheight) {
1330                         h = line_last - line_start + 1;
1331                         d = d1 + linesize * line_start;
1332                         if (cw == 16) {
1333                             vga_draw_glyph16(d, linesize,
1334                                              cursor_glyph, h, fgcol, bgcol);
1335                         } else if (cw != 9) {
1336                             vga_draw_glyph8(d, linesize,
1337                                             cursor_glyph, h, fgcol, bgcol);
1338                         } else {
1339                             vga_draw_glyph9(d, linesize,
1340                                             cursor_glyph, h, fgcol, bgcol, 1);
1341                         }
1342                     }
1343                 }
1344             }
1345             d1 += x_incr;
1346             src += 4;
1347             ch_attr_ptr++;
1348         }
1349         if (cx_max != -1) {
1350             dpy_gfx_update(s->con, cx_min * cw, cy * cheight,
1351                            (cx_max - cx_min + 1) * cw, cheight);
1352         }
1353         dest += linesize * cheight;
1354         line1 = line + cheight;
1355         offset += line_offset;
1356         if (line < s->line_compare && line1 >= s->line_compare) {
1357             offset = 0;
1358         }
1359         line = line1;
1360     }
1361 }
1362 
1363 enum {
1364     VGA_DRAW_LINE2,
1365     VGA_DRAW_LINE2D2,
1366     VGA_DRAW_LINE4,
1367     VGA_DRAW_LINE4D2,
1368     VGA_DRAW_LINE8D2,
1369     VGA_DRAW_LINE8,
1370     VGA_DRAW_LINE15_LE,
1371     VGA_DRAW_LINE16_LE,
1372     VGA_DRAW_LINE24_LE,
1373     VGA_DRAW_LINE32_LE,
1374     VGA_DRAW_LINE15_BE,
1375     VGA_DRAW_LINE16_BE,
1376     VGA_DRAW_LINE24_BE,
1377     VGA_DRAW_LINE32_BE,
1378     VGA_DRAW_LINE_NB,
1379 };
1380 
1381 static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = {
1382     vga_draw_line2,
1383     vga_draw_line2d2,
1384     vga_draw_line4,
1385     vga_draw_line4d2,
1386     vga_draw_line8d2,
1387     vga_draw_line8,
1388     vga_draw_line15_le,
1389     vga_draw_line16_le,
1390     vga_draw_line24_le,
1391     vga_draw_line32_le,
1392     vga_draw_line15_be,
1393     vga_draw_line16_be,
1394     vga_draw_line24_be,
1395     vga_draw_line32_be,
1396 };
1397 
1398 static int vga_get_bpp(VGACommonState *s)
1399 {
1400     int ret;
1401 
1402     if (vbe_enabled(s)) {
1403         ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
1404     } else {
1405         ret = 0;
1406     }
1407     return ret;
1408 }
1409 
1410 static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
1411 {
1412     int width, height;
1413 
1414     if (vbe_enabled(s)) {
1415         width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
1416         height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
1417     } else {
1418         width = (s->cr[VGA_CRTC_H_DISP] + 1) * 8;
1419         height = s->cr[VGA_CRTC_V_DISP_END] |
1420             ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1421             ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1422         height = (height + 1);
1423     }
1424     *pwidth = width;
1425     *pheight = height;
1426 }
1427 
1428 void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
1429 {
1430     int y;
1431     if (y1 >= VGA_MAX_HEIGHT)
1432         return;
1433     if (y2 >= VGA_MAX_HEIGHT)
1434         y2 = VGA_MAX_HEIGHT;
1435     for(y = y1; y < y2; y++) {
1436         s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
1437     }
1438 }
1439 
1440 static bool vga_scanline_invalidated(VGACommonState *s, int y)
1441 {
1442     if (y >= VGA_MAX_HEIGHT) {
1443         return false;
1444     }
1445     return s->invalidated_y_table[y >> 5] & (1 << (y & 0x1f));
1446 }
1447 
1448 void vga_dirty_log_start(VGACommonState *s)
1449 {
1450     memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
1451 }
1452 
1453 void vga_dirty_log_stop(VGACommonState *s)
1454 {
1455     memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
1456 }
1457 
1458 /*
1459  * graphic modes
1460  */
1461 static void vga_draw_graphic(VGACommonState *s, int full_update)
1462 {
1463     DisplaySurface *surface = qemu_console_surface(s->con);
1464     int y1, y, update, linesize, y_start, double_scan, mask, depth;
1465     int width, height, shift_control, bwidth, bits;
1466     ram_addr_t page0, page1, region_start, region_end;
1467     DirtyBitmapSnapshot *snap = NULL;
1468     int disp_width, multi_scan, multi_run;
1469     uint8_t *d;
1470     uint32_t v, addr1, addr;
1471     vga_draw_line_func *vga_draw_line = NULL;
1472     bool share_surface, force_shadow = false;
1473     pixman_format_code_t format;
1474 #ifdef HOST_WORDS_BIGENDIAN
1475     bool byteswap = !s->big_endian_fb;
1476 #else
1477     bool byteswap = s->big_endian_fb;
1478 #endif
1479 
1480     full_update |= update_basic_params(s);
1481 
1482     s->get_resolution(s, &width, &height);
1483     disp_width = width;
1484     depth = s->get_bpp(s);
1485 
1486     region_start = (s->start_addr * 4);
1487     region_end = region_start + (ram_addr_t)s->line_offset * height;
1488     region_end += width * depth / 8; /* scanline length */
1489     region_end -= s->line_offset;
1490     if (region_end > s->vbe_size || depth == 0 || depth == 15) {
1491         /*
1492          * We land here on:
1493          *  - wraps around (can happen with cirrus vbe modes)
1494          *  - depth == 0 (256 color palette video mode)
1495          *  - depth == 15
1496          *
1497          * Take the safe and slow route:
1498          *   - create a dirty bitmap snapshot for all vga memory.
1499          *   - force shadowing (so all vga memory access goes
1500          *     through vga_read_*() helpers).
1501          *
1502          * Given this affects only vga features which are pretty much
1503          * unused by modern guests there should be no performance
1504          * impact.
1505          */
1506         region_start = 0;
1507         region_end = s->vbe_size;
1508         force_shadow = true;
1509     }
1510 
1511     shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
1512     double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
1513     if (shift_control != 1) {
1514         multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)
1515             - 1;
1516     } else {
1517         /* in CGA modes, multi_scan is ignored */
1518         /* XXX: is it correct ? */
1519         multi_scan = double_scan;
1520     }
1521     multi_run = multi_scan;
1522     if (shift_control != s->shift_control ||
1523         double_scan != s->double_scan) {
1524         full_update = 1;
1525         s->shift_control = shift_control;
1526         s->double_scan = double_scan;
1527     }
1528 
1529     if (shift_control == 0) {
1530         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1531             disp_width <<= 1;
1532         }
1533     } else if (shift_control == 1) {
1534         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1535             disp_width <<= 1;
1536         }
1537     }
1538 
1539     /*
1540      * Check whether we can share the surface with the backend
1541      * or whether we need a shadow surface. We share native
1542      * endian surfaces for 15bpp and above and byteswapped
1543      * surfaces for 24bpp and above.
1544      */
1545     format = qemu_default_pixman_format(depth, !byteswap);
1546     if (format) {
1547         share_surface = dpy_gfx_check_format(s->con, format)
1548             && !s->force_shadow && !force_shadow;
1549     } else {
1550         share_surface = false;
1551     }
1552 
1553     if (s->line_offset != s->last_line_offset ||
1554         disp_width != s->last_width ||
1555         height != s->last_height ||
1556         s->last_depth != depth ||
1557         s->last_byteswap != byteswap ||
1558         share_surface != is_buffer_shared(surface)) {
1559         /* display parameters changed -> need new display surface */
1560         s->last_scr_width = disp_width;
1561         s->last_scr_height = height;
1562         s->last_width = disp_width;
1563         s->last_height = height;
1564         s->last_line_offset = s->line_offset;
1565         s->last_depth = depth;
1566         s->last_byteswap = byteswap;
1567         full_update = 1;
1568     }
1569     if (surface_data(surface) != s->vram_ptr + (s->start_addr * 4)
1570         && is_buffer_shared(surface)) {
1571         /* base address changed (page flip) -> shared display surfaces
1572          * must be updated with the new base address */
1573         full_update = 1;
1574     }
1575 
1576     if (full_update) {
1577         if (share_surface) {
1578             surface = qemu_create_displaysurface_from(disp_width,
1579                     height, format, s->line_offset,
1580                     s->vram_ptr + (s->start_addr * 4));
1581             dpy_gfx_replace_surface(s->con, surface);
1582         } else {
1583             qemu_console_resize(s->con, disp_width, height);
1584             surface = qemu_console_surface(s->con);
1585         }
1586     }
1587 
1588     if (shift_control == 0) {
1589         full_update |= update_palette16(s);
1590         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1591             v = VGA_DRAW_LINE4D2;
1592         } else {
1593             v = VGA_DRAW_LINE4;
1594         }
1595         bits = 4;
1596     } else if (shift_control == 1) {
1597         full_update |= update_palette16(s);
1598         if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
1599             v = VGA_DRAW_LINE2D2;
1600         } else {
1601             v = VGA_DRAW_LINE2;
1602         }
1603         bits = 4;
1604     } else {
1605         switch(s->get_bpp(s)) {
1606         default:
1607         case 0:
1608             full_update |= update_palette256(s);
1609             v = VGA_DRAW_LINE8D2;
1610             bits = 4;
1611             break;
1612         case 8:
1613             full_update |= update_palette256(s);
1614             v = VGA_DRAW_LINE8;
1615             bits = 8;
1616             break;
1617         case 15:
1618             v = s->big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE;
1619             bits = 16;
1620             break;
1621         case 16:
1622             v = s->big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE;
1623             bits = 16;
1624             break;
1625         case 24:
1626             v = s->big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE;
1627             bits = 24;
1628             break;
1629         case 32:
1630             v = s->big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE;
1631             bits = 32;
1632             break;
1633         }
1634     }
1635     vga_draw_line = vga_draw_line_table[v];
1636 
1637     if (!is_buffer_shared(surface) && s->cursor_invalidate) {
1638         s->cursor_invalidate(s);
1639     }
1640 
1641 #if 0
1642     printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
1643            width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
1644            s->line_compare, sr(s, VGA_SEQ_CLOCK_MODE));
1645 #endif
1646     addr1 = (s->start_addr * 4);
1647     bwidth = DIV_ROUND_UP(width * bits, 8);
1648     y_start = -1;
1649     d = surface_data(surface);
1650     linesize = surface_stride(surface);
1651     y1 = 0;
1652 
1653     if (!full_update) {
1654         if (s->line_compare < height) {
1655             /* split screen mode */
1656             region_start = 0;
1657         }
1658         snap = memory_region_snapshot_and_clear_dirty(&s->vram, region_start,
1659                                                       region_end - region_start,
1660                                                       DIRTY_MEMORY_VGA);
1661     }
1662 
1663     for(y = 0; y < height; y++) {
1664         addr = addr1;
1665         if (!(s->cr[VGA_CRTC_MODE] & 1)) {
1666             int shift;
1667             /* CGA compatibility handling */
1668             shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);
1669             addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
1670         }
1671         if (!(s->cr[VGA_CRTC_MODE] & 2)) {
1672             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
1673         }
1674         update = full_update;
1675         page0 = addr & s->vbe_size_mask;
1676         page1 = (addr + bwidth - 1) & s->vbe_size_mask;
1677         if (full_update) {
1678             update = 1;
1679         } else if (page1 < page0) {
1680             /* scanline wraps from end of video memory to the start */
1681             assert(force_shadow);
1682             update = memory_region_snapshot_get_dirty(&s->vram, snap,
1683                                                       page0, s->vbe_size - page0);
1684             update |= memory_region_snapshot_get_dirty(&s->vram, snap,
1685                                                        0, page1);
1686         } else {
1687             update = memory_region_snapshot_get_dirty(&s->vram, snap,
1688                                                       page0, page1 - page0);
1689         }
1690         /* explicit invalidation for the hardware cursor (cirrus only) */
1691         update |= vga_scanline_invalidated(s, y);
1692         if (update) {
1693             if (y_start < 0)
1694                 y_start = y;
1695             if (!(is_buffer_shared(surface))) {
1696                 vga_draw_line(s, d, addr, width);
1697                 if (s->cursor_draw_line)
1698                     s->cursor_draw_line(s, d, y);
1699             }
1700         } else {
1701             if (y_start >= 0) {
1702                 /* flush to display */
1703                 dpy_gfx_update(s->con, 0, y_start,
1704                                disp_width, y - y_start);
1705                 y_start = -1;
1706             }
1707         }
1708         if (!multi_run) {
1709             mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
1710             if ((y1 & mask) == mask)
1711                 addr1 += s->line_offset;
1712             y1++;
1713             multi_run = multi_scan;
1714         } else {
1715             multi_run--;
1716         }
1717         /* line compare acts on the displayed lines */
1718         if (y == s->line_compare)
1719             addr1 = 0;
1720         d += linesize;
1721     }
1722     if (y_start >= 0) {
1723         /* flush to display */
1724         dpy_gfx_update(s->con, 0, y_start,
1725                        disp_width, y - y_start);
1726     }
1727     g_free(snap);
1728     memset(s->invalidated_y_table, 0, sizeof(s->invalidated_y_table));
1729 }
1730 
1731 static void vga_draw_blank(VGACommonState *s, int full_update)
1732 {
1733     DisplaySurface *surface = qemu_console_surface(s->con);
1734     int i, w;
1735     uint8_t *d;
1736 
1737     if (!full_update)
1738         return;
1739     if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
1740         return;
1741 
1742     w = s->last_scr_width * surface_bytes_per_pixel(surface);
1743     d = surface_data(surface);
1744     for(i = 0; i < s->last_scr_height; i++) {
1745         memset(d, 0, w);
1746         d += surface_stride(surface);
1747     }
1748     dpy_gfx_update(s->con, 0, 0,
1749                    s->last_scr_width, s->last_scr_height);
1750 }
1751 
1752 #define GMODE_TEXT     0
1753 #define GMODE_GRAPH    1
1754 #define GMODE_BLANK 2
1755 
1756 static void vga_update_display(void *opaque)
1757 {
1758     VGACommonState *s = opaque;
1759     DisplaySurface *surface = qemu_console_surface(s->con);
1760     int full_update, graphic_mode;
1761 
1762     qemu_flush_coalesced_mmio_buffer();
1763 
1764     if (surface_bits_per_pixel(surface) == 0) {
1765         /* nothing to do */
1766     } else {
1767         full_update = 0;
1768         if (!(s->ar_index & 0x20)) {
1769             graphic_mode = GMODE_BLANK;
1770         } else {
1771             graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1772         }
1773         if (graphic_mode != s->graphic_mode) {
1774             s->graphic_mode = graphic_mode;
1775             s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
1776             full_update = 1;
1777         }
1778         switch(graphic_mode) {
1779         case GMODE_TEXT:
1780             vga_draw_text(s, full_update);
1781             break;
1782         case GMODE_GRAPH:
1783             vga_draw_graphic(s, full_update);
1784             break;
1785         case GMODE_BLANK:
1786         default:
1787             vga_draw_blank(s, full_update);
1788             break;
1789         }
1790     }
1791 }
1792 
1793 /* force a full display refresh */
1794 static void vga_invalidate_display(void *opaque)
1795 {
1796     VGACommonState *s = opaque;
1797 
1798     s->last_width = -1;
1799     s->last_height = -1;
1800 }
1801 
1802 void vga_common_reset(VGACommonState *s)
1803 {
1804     s->sr_index = 0;
1805     memset(s->sr, '\0', sizeof(s->sr));
1806     memset(s->sr_vbe, '\0', sizeof(s->sr_vbe));
1807     s->gr_index = 0;
1808     memset(s->gr, '\0', sizeof(s->gr));
1809     s->ar_index = 0;
1810     memset(s->ar, '\0', sizeof(s->ar));
1811     s->ar_flip_flop = 0;
1812     s->cr_index = 0;
1813     memset(s->cr, '\0', sizeof(s->cr));
1814     s->msr = 0;
1815     s->fcr = 0;
1816     s->st00 = 0;
1817     s->st01 = 0;
1818     s->dac_state = 0;
1819     s->dac_sub_index = 0;
1820     s->dac_read_index = 0;
1821     s->dac_write_index = 0;
1822     memset(s->dac_cache, '\0', sizeof(s->dac_cache));
1823     s->dac_8bit = 0;
1824     memset(s->palette, '\0', sizeof(s->palette));
1825     s->bank_offset = 0;
1826     s->vbe_index = 0;
1827     memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
1828     s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
1829     s->vbe_start_addr = 0;
1830     s->vbe_line_offset = 0;
1831     s->vbe_bank_mask = (s->vram_size >> 16) - 1;
1832     memset(s->font_offsets, '\0', sizeof(s->font_offsets));
1833     s->graphic_mode = -1; /* force full update */
1834     s->shift_control = 0;
1835     s->double_scan = 0;
1836     s->line_offset = 0;
1837     s->line_compare = 0;
1838     s->start_addr = 0;
1839     s->plane_updated = 0;
1840     s->last_cw = 0;
1841     s->last_ch = 0;
1842     s->last_width = 0;
1843     s->last_height = 0;
1844     s->last_scr_width = 0;
1845     s->last_scr_height = 0;
1846     s->cursor_start = 0;
1847     s->cursor_end = 0;
1848     s->cursor_offset = 0;
1849     s->big_endian_fb = s->default_endian_fb;
1850     memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
1851     memset(s->last_palette, '\0', sizeof(s->last_palette));
1852     memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
1853     switch (vga_retrace_method) {
1854     case VGA_RETRACE_DUMB:
1855         break;
1856     case VGA_RETRACE_PRECISE:
1857         memset(&s->retrace_info, 0, sizeof (s->retrace_info));
1858         break;
1859     }
1860     vga_update_memory_access(s);
1861 }
1862 
1863 static void vga_reset(void *opaque)
1864 {
1865     VGACommonState *s =  opaque;
1866     vga_common_reset(s);
1867 }
1868 
1869 #define TEXTMODE_X(x)	((x) % width)
1870 #define TEXTMODE_Y(x)	((x) / width)
1871 #define VMEM2CHTYPE(v)	((v & 0xff0007ff) | \
1872         ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
1873 /* relay text rendering to the display driver
1874  * instead of doing a full vga_update_display() */
1875 static void vga_update_text(void *opaque, console_ch_t *chardata)
1876 {
1877     VGACommonState *s =  opaque;
1878     int graphic_mode, i, cursor_offset, cursor_visible;
1879     int cw, cheight, width, height, size, c_min, c_max;
1880     uint32_t *src;
1881     console_ch_t *dst, val;
1882     char msg_buffer[80];
1883     int full_update = 0;
1884 
1885     qemu_flush_coalesced_mmio_buffer();
1886 
1887     if (!(s->ar_index & 0x20)) {
1888         graphic_mode = GMODE_BLANK;
1889     } else {
1890         graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE;
1891     }
1892     if (graphic_mode != s->graphic_mode) {
1893         s->graphic_mode = graphic_mode;
1894         full_update = 1;
1895     }
1896     if (s->last_width == -1) {
1897         s->last_width = 0;
1898         full_update = 1;
1899     }
1900 
1901     switch (graphic_mode) {
1902     case GMODE_TEXT:
1903         /* TODO: update palette */
1904         full_update |= update_basic_params(s);
1905 
1906         /* total width & height */
1907         cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
1908         cw = 8;
1909         if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
1910             cw = 9;
1911         }
1912         if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
1913             cw = 16; /* NOTE: no 18 pixel wide */
1914         }
1915         width = (s->cr[VGA_CRTC_H_DISP] + 1);
1916         if (s->cr[VGA_CRTC_V_TOTAL] == 100) {
1917             /* ugly hack for CGA 160x100x16 - explain me the logic */
1918             height = 100;
1919         } else {
1920             height = s->cr[VGA_CRTC_V_DISP_END] |
1921                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
1922                 ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3);
1923             height = (height + 1) / cheight;
1924         }
1925 
1926         size = (height * width);
1927         if (size > CH_ATTR_SIZE) {
1928             if (!full_update)
1929                 return;
1930 
1931             snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
1932                      width, height);
1933             break;
1934         }
1935 
1936         if (width != s->last_width || height != s->last_height ||
1937             cw != s->last_cw || cheight != s->last_ch) {
1938             s->last_scr_width = width * cw;
1939             s->last_scr_height = height * cheight;
1940             qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
1941             dpy_text_resize(s->con, width, height);
1942             s->last_depth = 0;
1943             s->last_width = width;
1944             s->last_height = height;
1945             s->last_ch = cheight;
1946             s->last_cw = cw;
1947             full_update = 1;
1948         }
1949 
1950         if (full_update) {
1951             s->full_update_gfx = 1;
1952         }
1953         if (s->full_update_text) {
1954             s->full_update_text = 0;
1955             full_update |= 1;
1956         }
1957 
1958         /* Update "hardware" cursor */
1959         cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
1960                          s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
1961         if (cursor_offset != s->cursor_offset ||
1962             s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
1963             s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
1964             cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
1965             if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
1966                 dpy_text_cursor(s->con,
1967                                 TEXTMODE_X(cursor_offset),
1968                                 TEXTMODE_Y(cursor_offset));
1969             else
1970                 dpy_text_cursor(s->con, -1, -1);
1971             s->cursor_offset = cursor_offset;
1972             s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
1973             s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
1974         }
1975 
1976         src = (uint32_t *) s->vram_ptr + s->start_addr;
1977         dst = chardata;
1978 
1979         if (full_update) {
1980             for (i = 0; i < size; src ++, dst ++, i ++)
1981                 console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
1982 
1983             dpy_text_update(s->con, 0, 0, width, height);
1984         } else {
1985             c_max = 0;
1986 
1987             for (i = 0; i < size; src ++, dst ++, i ++) {
1988                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
1989                 if (*dst != val) {
1990                     *dst = val;
1991                     c_max = i;
1992                     break;
1993                 }
1994             }
1995             c_min = i;
1996             for (; i < size; src ++, dst ++, i ++) {
1997                 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
1998                 if (*dst != val) {
1999                     *dst = val;
2000                     c_max = i;
2001                 }
2002             }
2003 
2004             if (c_min <= c_max) {
2005                 i = TEXTMODE_Y(c_min);
2006                 dpy_text_update(s->con, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
2007             }
2008         }
2009 
2010         return;
2011     case GMODE_GRAPH:
2012         if (!full_update)
2013             return;
2014 
2015         s->get_resolution(s, &width, &height);
2016         snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
2017                  width, height);
2018         break;
2019     case GMODE_BLANK:
2020     default:
2021         if (!full_update)
2022             return;
2023 
2024         snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
2025         break;
2026     }
2027 
2028     /* Display a message */
2029     s->last_width = 60;
2030     s->last_height = height = 3;
2031     dpy_text_cursor(s->con, -1, -1);
2032     dpy_text_resize(s->con, s->last_width, height);
2033 
2034     for (dst = chardata, i = 0; i < s->last_width * height; i ++)
2035         console_write_ch(dst ++, ' ');
2036 
2037     size = strlen(msg_buffer);
2038     width = (s->last_width - size) / 2;
2039     dst = chardata + s->last_width + width;
2040     for (i = 0; i < size; i ++)
2041         console_write_ch(dst ++, ATTR2CHTYPE(msg_buffer[i], QEMU_COLOR_BLUE,
2042                                              QEMU_COLOR_BLACK, 1));
2043 
2044     dpy_text_update(s->con, 0, 0, s->last_width, height);
2045 }
2046 
2047 static uint64_t vga_mem_read(void *opaque, hwaddr addr,
2048                              unsigned size)
2049 {
2050     VGACommonState *s = opaque;
2051 
2052     return vga_mem_readb(s, addr);
2053 }
2054 
2055 static void vga_mem_write(void *opaque, hwaddr addr,
2056                           uint64_t data, unsigned size)
2057 {
2058     VGACommonState *s = opaque;
2059 
2060     vga_mem_writeb(s, addr, data);
2061 }
2062 
2063 const MemoryRegionOps vga_mem_ops = {
2064     .read = vga_mem_read,
2065     .write = vga_mem_write,
2066     .endianness = DEVICE_LITTLE_ENDIAN,
2067     .impl = {
2068         .min_access_size = 1,
2069         .max_access_size = 1,
2070     },
2071 };
2072 
2073 static int vga_common_post_load(void *opaque, int version_id)
2074 {
2075     VGACommonState *s = opaque;
2076 
2077     /* force refresh */
2078     s->graphic_mode = -1;
2079     vbe_update_vgaregs(s);
2080     vga_update_memory_access(s);
2081     return 0;
2082 }
2083 
2084 static bool vga_endian_state_needed(void *opaque)
2085 {
2086     VGACommonState *s = opaque;
2087 
2088     /*
2089      * Only send the endian state if it's different from the
2090      * default one, thus ensuring backward compatibility for
2091      * migration of the common case
2092      */
2093     return s->default_endian_fb != s->big_endian_fb;
2094 }
2095 
2096 static const VMStateDescription vmstate_vga_endian = {
2097     .name = "vga.endian",
2098     .version_id = 1,
2099     .minimum_version_id = 1,
2100     .needed = vga_endian_state_needed,
2101     .fields = (VMStateField[]) {
2102         VMSTATE_BOOL(big_endian_fb, VGACommonState),
2103         VMSTATE_END_OF_LIST()
2104     }
2105 };
2106 
2107 const VMStateDescription vmstate_vga_common = {
2108     .name = "vga",
2109     .version_id = 2,
2110     .minimum_version_id = 2,
2111     .post_load = vga_common_post_load,
2112     .fields = (VMStateField[]) {
2113         VMSTATE_UINT32(latch, VGACommonState),
2114         VMSTATE_UINT8(sr_index, VGACommonState),
2115         VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8),
2116         VMSTATE_UINT8(gr_index, VGACommonState),
2117         VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16),
2118         VMSTATE_UINT8(ar_index, VGACommonState),
2119         VMSTATE_BUFFER(ar, VGACommonState),
2120         VMSTATE_INT32(ar_flip_flop, VGACommonState),
2121         VMSTATE_UINT8(cr_index, VGACommonState),
2122         VMSTATE_BUFFER(cr, VGACommonState),
2123         VMSTATE_UINT8(msr, VGACommonState),
2124         VMSTATE_UINT8(fcr, VGACommonState),
2125         VMSTATE_UINT8(st00, VGACommonState),
2126         VMSTATE_UINT8(st01, VGACommonState),
2127 
2128         VMSTATE_UINT8(dac_state, VGACommonState),
2129         VMSTATE_UINT8(dac_sub_index, VGACommonState),
2130         VMSTATE_UINT8(dac_read_index, VGACommonState),
2131         VMSTATE_UINT8(dac_write_index, VGACommonState),
2132         VMSTATE_BUFFER(dac_cache, VGACommonState),
2133         VMSTATE_BUFFER(palette, VGACommonState),
2134 
2135         VMSTATE_INT32(bank_offset, VGACommonState),
2136         VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState, NULL),
2137         VMSTATE_UINT16(vbe_index, VGACommonState),
2138         VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
2139         VMSTATE_UINT32(vbe_start_addr, VGACommonState),
2140         VMSTATE_UINT32(vbe_line_offset, VGACommonState),
2141         VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
2142         VMSTATE_END_OF_LIST()
2143     },
2144     .subsections = (const VMStateDescription*[]) {
2145         &vmstate_vga_endian,
2146         NULL
2147     }
2148 };
2149 
2150 static const GraphicHwOps vga_ops = {
2151     .invalidate  = vga_invalidate_display,
2152     .gfx_update  = vga_update_display,
2153     .text_update = vga_update_text,
2154 };
2155 
2156 static inline uint32_t uint_clamp(uint32_t val, uint32_t vmin, uint32_t vmax)
2157 {
2158     if (val < vmin) {
2159         return vmin;
2160     }
2161     if (val > vmax) {
2162         return vmax;
2163     }
2164     return val;
2165 }
2166 
2167 void vga_common_init(VGACommonState *s, Object *obj)
2168 {
2169     int i, j, v, b;
2170 
2171     for(i = 0;i < 256; i++) {
2172         v = 0;
2173         for(j = 0; j < 8; j++) {
2174             v |= ((i >> j) & 1) << (j * 4);
2175         }
2176         expand4[i] = v;
2177 
2178         v = 0;
2179         for(j = 0; j < 4; j++) {
2180             v |= ((i >> (2 * j)) & 3) << (j * 4);
2181         }
2182         expand2[i] = v;
2183     }
2184     for(i = 0; i < 16; i++) {
2185         v = 0;
2186         for(j = 0; j < 4; j++) {
2187             b = ((i >> j) & 1);
2188             v |= b << (2 * j);
2189             v |= b << (2 * j + 1);
2190         }
2191         expand4to8[i] = v;
2192     }
2193 
2194     s->vram_size_mb = uint_clamp(s->vram_size_mb, 1, 512);
2195     s->vram_size_mb = pow2ceil(s->vram_size_mb);
2196     s->vram_size = s->vram_size_mb * MiB;
2197 
2198     if (!s->vbe_size) {
2199         s->vbe_size = s->vram_size;
2200     }
2201     s->vbe_size_mask = s->vbe_size - 1;
2202 
2203     s->is_vbe_vmstate = 1;
2204     memory_region_init_ram_nomigrate(&s->vram, obj, "vga.vram", s->vram_size,
2205                            &error_fatal);
2206     vmstate_register_ram(&s->vram, s->global_vmstate ? NULL : DEVICE(obj));
2207     xen_register_framebuffer(&s->vram);
2208     s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
2209     s->get_bpp = vga_get_bpp;
2210     s->get_offsets = vga_get_offsets;
2211     s->get_resolution = vga_get_resolution;
2212     s->hw_ops = &vga_ops;
2213     switch (vga_retrace_method) {
2214     case VGA_RETRACE_DUMB:
2215         s->retrace = vga_dumb_retrace;
2216         s->update_retrace_info = vga_dumb_update_retrace_info;
2217         break;
2218 
2219     case VGA_RETRACE_PRECISE:
2220         s->retrace = vga_precise_retrace;
2221         s->update_retrace_info = vga_precise_update_retrace_info;
2222         break;
2223     }
2224 
2225     /*
2226      * Set default fb endian based on target, could probably be turned
2227      * into a device attribute set by the machine/platform to remove
2228      * all target endian dependencies from this file.
2229      */
2230 #ifdef TARGET_WORDS_BIGENDIAN
2231     s->default_endian_fb = true;
2232 #else
2233     s->default_endian_fb = false;
2234 #endif
2235     vga_dirty_log_start(s);
2236 }
2237 
2238 static const MemoryRegionPortio vga_portio_list[] = {
2239     { 0x04,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
2240     { 0x0a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
2241     { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
2242     { 0x24,  2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
2243     { 0x2a,  1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
2244     PORTIO_END_OF_LIST(),
2245 };
2246 
2247 static const MemoryRegionPortio vbe_portio_list[] = {
2248     { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
2249 # ifdef TARGET_I386
2250     { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2251 # endif
2252     { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
2253     PORTIO_END_OF_LIST(),
2254 };
2255 
2256 /* Used by both ISA and PCI */
2257 MemoryRegion *vga_init_io(VGACommonState *s, Object *obj,
2258                           const MemoryRegionPortio **vga_ports,
2259                           const MemoryRegionPortio **vbe_ports)
2260 {
2261     MemoryRegion *vga_mem;
2262 
2263     *vga_ports = vga_portio_list;
2264     *vbe_ports = vbe_portio_list;
2265 
2266     vga_mem = g_malloc(sizeof(*vga_mem));
2267     memory_region_init_io(vga_mem, obj, &vga_mem_ops, s,
2268                           "vga-lowmem", 0x20000);
2269     memory_region_set_flush_coalesced(vga_mem);
2270 
2271     return vga_mem;
2272 }
2273 
2274 void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
2275               MemoryRegion *address_space_io, bool init_vga_ports)
2276 {
2277     MemoryRegion *vga_io_memory;
2278     const MemoryRegionPortio *vga_ports, *vbe_ports;
2279 
2280     qemu_register_reset(vga_reset, s);
2281 
2282     s->bank_offset = 0;
2283 
2284     s->legacy_address_space = address_space;
2285 
2286     vga_io_memory = vga_init_io(s, obj, &vga_ports, &vbe_ports);
2287     memory_region_add_subregion_overlap(address_space,
2288                                         0x000a0000,
2289                                         vga_io_memory,
2290                                         1);
2291     memory_region_set_coalescing(vga_io_memory);
2292     if (init_vga_ports) {
2293         portio_list_init(&s->vga_port_list, obj, vga_ports, s, "vga");
2294         portio_list_set_flush_coalesced(&s->vga_port_list);
2295         portio_list_add(&s->vga_port_list, address_space_io, 0x3b0);
2296     }
2297     if (vbe_ports) {
2298         portio_list_init(&s->vbe_port_list, obj, vbe_ports, s, "vbe");
2299         portio_list_add(&s->vbe_port_list, address_space_io, 0x1ce);
2300     }
2301 }
2302 
2303 void vga_init_vbe(VGACommonState *s, Object *obj, MemoryRegion *system_memory)
2304 {
2305     /* With pc-0.12 and below we map both the PCI BAR and the fixed VBE region,
2306      * so use an alias to avoid double-mapping the same region.
2307      */
2308     memory_region_init_alias(&s->vram_vbe, obj, "vram.vbe",
2309                              &s->vram, 0, memory_region_size(&s->vram));
2310     /* XXX: use optimized standard vga accesses */
2311     memory_region_add_subregion(system_memory,
2312                                 VBE_DISPI_LFB_PHYSICAL_ADDRESS,
2313                                 &s->vram_vbe);
2314     s->vbe_mapped = 1;
2315 }
2316