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