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