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