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