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 /* 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 130 static inline bool vbe_enabled(VGACommonState *s) 131 { 132 return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED; 133 } 134 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 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 186 static void vga_dumb_update_retrace_info(VGACommonState *s) 187 { 188 (void) s; 189 } 190 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 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 312 static uint8_t vga_dumb_retrace(VGACommonState *s) 313 { 314 return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE); 315 } 316 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 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 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 */ 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 */ 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 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 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 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 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 */ 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 /* chain 4 mode : simplest access (but it should use the same 819 * algorithms as below; see e.g. vga_mem_writeb's plane mask check). 820 */ 821 assert(addr < s->vram_size); 822 return s->vram_ptr[addr]; 823 } 824 825 if (s->gr[VGA_GFX_MODE] & 0x10) { 826 /* odd/even mode (aka text mode mapping) */ 827 plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1); 828 addr = ((addr & ~1) << 1) | plane; 829 if (addr >= s->vram_size) { 830 return 0xff; 831 } 832 return s->vram_ptr[addr]; 833 } 834 835 /* standard VGA latched access */ 836 plane = s->gr[VGA_GFX_PLANE_READ]; 837 if (addr * sizeof(uint32_t) >= s->vram_size) { 838 return 0xff; 839 } 840 s->latch = ((uint32_t *)s->vram_ptr)[addr]; 841 if (!(s->gr[VGA_GFX_MODE] & 0x08)) { 842 /* read mode 0 */ 843 ret = GET_PLANE(s->latch, plane); 844 } else { 845 /* read mode 1 */ 846 ret = (s->latch ^ mask16[s->gr[VGA_GFX_COMPARE_VALUE]]) & 847 mask16[s->gr[VGA_GFX_COMPARE_MASK]]; 848 ret |= ret >> 16; 849 ret |= ret >> 8; 850 ret = (~ret) & 0xff; 851 } 852 853 return ret; 854 } 855 856 /* called for accesses between 0xa0000 and 0xc0000 */ 857 void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val) 858 { 859 int memory_map_mode, plane, write_mode, b, func_select, mask; 860 uint32_t write_mask, bit_mask, set_mask; 861 862 #ifdef DEBUG_VGA_MEM 863 printf("vga: [0x" HWADDR_FMT_plx "] = 0x%02x\n", addr, val); 864 #endif 865 /* convert to VGA memory offset */ 866 memory_map_mode = (s->gr[VGA_GFX_MISC] >> 2) & 3; 867 addr &= 0x1ffff; 868 switch(memory_map_mode) { 869 case 0: 870 break; 871 case 1: 872 if (addr >= 0x10000) 873 return; 874 addr += s->bank_offset; 875 break; 876 case 2: 877 addr -= 0x10000; 878 if (addr >= 0x8000) 879 return; 880 break; 881 default: 882 case 3: 883 addr -= 0x18000; 884 if (addr >= 0x8000) 885 return; 886 break; 887 } 888 889 if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) { 890 /* chain 4 mode : simplest access */ 891 plane = addr & 3; 892 mask = (1 << plane); 893 if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) { 894 assert(addr < s->vram_size); 895 s->vram_ptr[addr] = val; 896 #ifdef DEBUG_VGA_MEM 897 printf("vga: chain4: [0x" HWADDR_FMT_plx "]\n", addr); 898 #endif 899 s->plane_updated |= mask; /* only used to detect font change */ 900 memory_region_set_dirty(&s->vram, addr, 1); 901 } 902 return; 903 } 904 905 if (s->gr[VGA_GFX_MODE] & 0x10) { 906 /* odd/even mode (aka text mode mapping) */ 907 plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1); 908 mask = (1 << plane); 909 if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) { 910 addr = ((addr & ~1) << 1) | plane; 911 if (addr >= s->vram_size) { 912 return; 913 } 914 s->vram_ptr[addr] = val; 915 #ifdef DEBUG_VGA_MEM 916 printf("vga: odd/even: [0x" HWADDR_FMT_plx "]\n", addr); 917 #endif 918 s->plane_updated |= mask; /* only used to detect font change */ 919 memory_region_set_dirty(&s->vram, addr, 1); 920 } 921 return; 922 } 923 924 mask = sr(s, VGA_SEQ_PLANE_WRITE); 925 926 /* standard VGA latched access */ 927 write_mode = s->gr[VGA_GFX_MODE] & 3; 928 switch(write_mode) { 929 default: 930 case 0: 931 /* rotate */ 932 b = s->gr[VGA_GFX_DATA_ROTATE] & 7; 933 val = ((val >> b) | (val << (8 - b))) & 0xff; 934 val |= val << 8; 935 val |= val << 16; 936 937 /* apply set/reset mask */ 938 set_mask = mask16[s->gr[VGA_GFX_SR_ENABLE]]; 939 val = (val & ~set_mask) | 940 (mask16[s->gr[VGA_GFX_SR_VALUE]] & set_mask); 941 bit_mask = s->gr[VGA_GFX_BIT_MASK]; 942 break; 943 case 1: 944 val = s->latch; 945 goto do_write; 946 case 2: 947 val = mask16[val & 0x0f]; 948 bit_mask = s->gr[VGA_GFX_BIT_MASK]; 949 break; 950 case 3: 951 /* rotate */ 952 b = s->gr[VGA_GFX_DATA_ROTATE] & 7; 953 val = (val >> b) | (val << (8 - b)); 954 955 bit_mask = s->gr[VGA_GFX_BIT_MASK] & val; 956 val = mask16[s->gr[VGA_GFX_SR_VALUE]]; 957 break; 958 } 959 960 /* apply logical operation */ 961 func_select = s->gr[VGA_GFX_DATA_ROTATE] >> 3; 962 switch(func_select) { 963 case 0: 964 default: 965 /* nothing to do */ 966 break; 967 case 1: 968 /* and */ 969 val &= s->latch; 970 break; 971 case 2: 972 /* or */ 973 val |= s->latch; 974 break; 975 case 3: 976 /* xor */ 977 val ^= s->latch; 978 break; 979 } 980 981 /* apply bit mask */ 982 bit_mask |= bit_mask << 8; 983 bit_mask |= bit_mask << 16; 984 val = (val & bit_mask) | (s->latch & ~bit_mask); 985 986 do_write: 987 /* mask data according to sr[2] */ 988 s->plane_updated |= mask; /* only used to detect font change */ 989 write_mask = mask16[mask]; 990 if (addr * sizeof(uint32_t) >= s->vram_size) { 991 return; 992 } 993 ((uint32_t *)s->vram_ptr)[addr] = 994 (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) | 995 (val & write_mask); 996 #ifdef DEBUG_VGA_MEM 997 printf("vga: latch: [0x" HWADDR_FMT_plx "] mask=0x%08x val=0x%08x\n", 998 addr * 4, write_mask, val); 999 #endif 1000 memory_region_set_dirty(&s->vram, addr << 2, sizeof(uint32_t)); 1001 } 1002 1003 typedef void *vga_draw_line_func(VGACommonState *s1, uint8_t *d, 1004 uint32_t srcaddr, int width, int hpel); 1005 1006 #include "vga-access.h" 1007 #include "vga-helpers.h" 1008 1009 /* return true if the palette was modified */ 1010 static int update_palette16(VGACommonState *s) 1011 { 1012 int full_update, i; 1013 uint32_t v, col, *palette; 1014 1015 full_update = 0; 1016 palette = s->last_palette; 1017 for(i = 0; i < 16; i++) { 1018 v = s->ar[i]; 1019 if (s->ar[VGA_ATC_MODE] & 0x80) { 1020 v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xf) << 4) | (v & 0xf); 1021 } else { 1022 v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f); 1023 } 1024 v = v * 3; 1025 col = rgb_to_pixel32(c6_to_8(s->palette[v]), 1026 c6_to_8(s->palette[v + 1]), 1027 c6_to_8(s->palette[v + 2])); 1028 if (col != palette[i]) { 1029 full_update = 1; 1030 palette[i] = col; 1031 } 1032 } 1033 return full_update; 1034 } 1035 1036 /* return true if the palette was modified */ 1037 static int update_palette256(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 v = 0; 1045 for(i = 0; i < 256; i++) { 1046 if (s->dac_8bit) { 1047 col = rgb_to_pixel32(s->palette[v], 1048 s->palette[v + 1], 1049 s->palette[v + 2]); 1050 } else { 1051 col = rgb_to_pixel32(c6_to_8(s->palette[v]), 1052 c6_to_8(s->palette[v + 1]), 1053 c6_to_8(s->palette[v + 2])); 1054 } 1055 if (col != palette[i]) { 1056 full_update = 1; 1057 palette[i] = col; 1058 } 1059 v += 3; 1060 } 1061 return full_update; 1062 } 1063 1064 static void vga_get_params(VGACommonState *s, 1065 VGADisplayParams *params) 1066 { 1067 if (vbe_enabled(s)) { 1068 params->line_offset = s->vbe_line_offset; 1069 params->start_addr = s->vbe_start_addr; 1070 params->line_compare = 65535; 1071 params->hpel = VGA_HPEL_NEUTRAL; 1072 params->hpel_split = false; 1073 } else { 1074 /* compute line_offset in bytes */ 1075 params->line_offset = s->cr[VGA_CRTC_OFFSET] << 3; 1076 1077 /* starting address */ 1078 params->start_addr = s->cr[VGA_CRTC_START_LO] | 1079 (s->cr[VGA_CRTC_START_HI] << 8); 1080 1081 /* line compare */ 1082 params->line_compare = s->cr[VGA_CRTC_LINE_COMPARE] | 1083 ((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) | 1084 ((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3); 1085 1086 params->hpel = s->ar[VGA_ATC_PEL]; 1087 params->hpel_split = s->ar[VGA_ATC_MODE] & 0x20; 1088 } 1089 } 1090 1091 /* update start_addr and line_offset. Return TRUE if modified */ 1092 static int update_basic_params(VGACommonState *s) 1093 { 1094 int full_update; 1095 VGADisplayParams current; 1096 1097 full_update = 0; 1098 1099 s->get_params(s, ¤t); 1100 1101 if (memcmp(¤t, &s->params, sizeof(current))) { 1102 s->params = current; 1103 full_update = 1; 1104 } 1105 return full_update; 1106 } 1107 1108 1109 static const uint8_t cursor_glyph[32 * 4] = { 1110 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1111 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1112 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1113 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1114 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1115 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1116 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1117 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1118 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1119 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1120 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1121 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1122 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1123 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1124 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1125 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1126 }; 1127 1128 static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight, 1129 int *pcwidth, int *pcheight) 1130 { 1131 int width, cwidth, height, cheight; 1132 1133 /* total width & height */ 1134 cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1; 1135 cwidth = 8; 1136 if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) { 1137 cwidth = 9; 1138 } 1139 if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) { 1140 cwidth = 16; /* NOTE: no 18 pixel wide */ 1141 } 1142 width = (s->cr[VGA_CRTC_H_DISP] + 1); 1143 if (s->cr[VGA_CRTC_V_TOTAL] == 100) { 1144 /* ugly hack for CGA 160x100x16 - explain me the logic */ 1145 height = 100; 1146 } else { 1147 height = s->cr[VGA_CRTC_V_DISP_END] | 1148 ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) | 1149 ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3); 1150 height = (height + 1) / cheight; 1151 } 1152 1153 *pwidth = width; 1154 *pheight = height; 1155 *pcwidth = cwidth; 1156 *pcheight = cheight; 1157 } 1158 1159 /* 1160 * Text mode update 1161 * Missing: 1162 * - double scan 1163 * - double width 1164 * - underline 1165 * - flashing 1166 */ 1167 static void vga_draw_text(VGACommonState *s, int full_update) 1168 { 1169 DisplaySurface *surface = qemu_console_surface(s->con); 1170 int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr; 1171 int cx_min, cx_max, linesize, x_incr, line, line1; 1172 uint32_t offset, fgcol, bgcol, v, cursor_offset; 1173 uint8_t *d1, *d, *src, *dest, *cursor_ptr; 1174 const uint8_t *font_ptr, *font_base[2]; 1175 int dup9, line_offset; 1176 uint32_t *palette; 1177 uint32_t *ch_attr_ptr; 1178 int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); 1179 1180 /* compute font data address (in plane 2) */ 1181 v = sr(s, VGA_SEQ_CHARACTER_MAP); 1182 offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2; 1183 if (offset != s->font_offsets[0]) { 1184 s->font_offsets[0] = offset; 1185 full_update = 1; 1186 } 1187 font_base[0] = s->vram_ptr + offset; 1188 1189 offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2; 1190 font_base[1] = s->vram_ptr + offset; 1191 if (offset != s->font_offsets[1]) { 1192 s->font_offsets[1] = offset; 1193 full_update = 1; 1194 } 1195 if (s->plane_updated & (1 << 2) || s->has_chain4_alias) { 1196 /* if the plane 2 was modified since the last display, it 1197 indicates the font may have been modified */ 1198 s->plane_updated = 0; 1199 full_update = 1; 1200 } 1201 full_update |= update_basic_params(s); 1202 1203 line_offset = s->params.line_offset; 1204 1205 vga_get_text_resolution(s, &width, &height, &cw, &cheight); 1206 if ((height * width) <= 1) { 1207 /* better than nothing: exit if transient size is too small */ 1208 return; 1209 } 1210 if ((height * width) > CH_ATTR_SIZE) { 1211 /* better than nothing: exit if transient size is too big */ 1212 return; 1213 } 1214 1215 if (width != s->last_width || height != s->last_height || 1216 cw != s->last_cw || cheight != s->last_ch || s->last_depth) { 1217 s->last_scr_width = width * cw; 1218 s->last_scr_height = height * cheight; 1219 qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height); 1220 surface = qemu_console_surface(s->con); 1221 dpy_text_resize(s->con, width, height); 1222 s->last_depth = 0; 1223 s->last_width = width; 1224 s->last_height = height; 1225 s->last_ch = cheight; 1226 s->last_cw = cw; 1227 full_update = 1; 1228 } 1229 full_update |= update_palette16(s); 1230 palette = s->last_palette; 1231 x_incr = cw * surface_bytes_per_pixel(surface); 1232 1233 if (full_update) { 1234 s->full_update_text = 1; 1235 } 1236 if (s->full_update_gfx) { 1237 s->full_update_gfx = 0; 1238 full_update |= 1; 1239 } 1240 1241 cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) | 1242 s->cr[VGA_CRTC_CURSOR_LO]) - s->params.start_addr; 1243 if (cursor_offset != s->cursor_offset || 1244 s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start || 1245 s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end) { 1246 /* if the cursor position changed, we update the old and new 1247 chars */ 1248 if (s->cursor_offset < CH_ATTR_SIZE) 1249 s->last_ch_attr[s->cursor_offset] = -1; 1250 if (cursor_offset < CH_ATTR_SIZE) 1251 s->last_ch_attr[cursor_offset] = -1; 1252 s->cursor_offset = cursor_offset; 1253 s->cursor_start = s->cr[VGA_CRTC_CURSOR_START]; 1254 s->cursor_end = s->cr[VGA_CRTC_CURSOR_END]; 1255 } 1256 cursor_ptr = s->vram_ptr + (s->params.start_addr + cursor_offset) * 4; 1257 if (now >= s->cursor_blink_time) { 1258 s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2; 1259 s->cursor_visible_phase = !s->cursor_visible_phase; 1260 } 1261 1262 dest = surface_data(surface); 1263 linesize = surface_stride(surface); 1264 ch_attr_ptr = s->last_ch_attr; 1265 line = 0; 1266 offset = s->params.start_addr * 4; 1267 for(cy = 0; cy < height; cy++) { 1268 d1 = dest; 1269 src = s->vram_ptr + offset; 1270 cx_min = width; 1271 cx_max = -1; 1272 for(cx = 0; cx < width; cx++) { 1273 if (src + sizeof(uint16_t) > s->vram_ptr + s->vram_size) { 1274 break; 1275 } 1276 ch_attr = *(uint16_t *)src; 1277 if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) { 1278 if (cx < cx_min) 1279 cx_min = cx; 1280 if (cx > cx_max) 1281 cx_max = cx; 1282 *ch_attr_ptr = ch_attr; 1283 #if HOST_BIG_ENDIAN 1284 ch = ch_attr >> 8; 1285 cattr = ch_attr & 0xff; 1286 #else 1287 ch = ch_attr & 0xff; 1288 cattr = ch_attr >> 8; 1289 #endif 1290 font_ptr = font_base[(cattr >> 3) & 1]; 1291 font_ptr += 32 * 4 * ch; 1292 bgcol = palette[cattr >> 4]; 1293 fgcol = palette[cattr & 0x0f]; 1294 if (cw == 16) { 1295 vga_draw_glyph16(d1, linesize, 1296 font_ptr, cheight, fgcol, bgcol); 1297 } else if (cw != 9) { 1298 vga_draw_glyph8(d1, linesize, 1299 font_ptr, cheight, fgcol, bgcol); 1300 } else { 1301 dup9 = 0; 1302 if (ch >= 0xb0 && ch <= 0xdf && 1303 (s->ar[VGA_ATC_MODE] & 0x04)) { 1304 dup9 = 1; 1305 } 1306 vga_draw_glyph9(d1, linesize, 1307 font_ptr, cheight, fgcol, bgcol, dup9); 1308 } 1309 if (src == cursor_ptr && 1310 !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) && 1311 s->cursor_visible_phase) { 1312 int line_start, line_last, h; 1313 /* draw the cursor */ 1314 line_start = s->cr[VGA_CRTC_CURSOR_START] & 0x1f; 1315 line_last = s->cr[VGA_CRTC_CURSOR_END] & 0x1f; 1316 /* XXX: check that */ 1317 if (line_last > cheight - 1) 1318 line_last = cheight - 1; 1319 if (line_last >= line_start && line_start < cheight) { 1320 h = line_last - line_start + 1; 1321 d = d1 + linesize * line_start; 1322 if (cw == 16) { 1323 vga_draw_glyph16(d, linesize, 1324 cursor_glyph, h, fgcol, bgcol); 1325 } else if (cw != 9) { 1326 vga_draw_glyph8(d, linesize, 1327 cursor_glyph, h, fgcol, bgcol); 1328 } else { 1329 vga_draw_glyph9(d, linesize, 1330 cursor_glyph, h, fgcol, bgcol, 1); 1331 } 1332 } 1333 } 1334 } 1335 d1 += x_incr; 1336 src += 4; 1337 ch_attr_ptr++; 1338 } 1339 if (cx_max != -1) { 1340 dpy_gfx_update(s->con, cx_min * cw, cy * cheight, 1341 (cx_max - cx_min + 1) * cw, cheight); 1342 } 1343 dest += linesize * cheight; 1344 line1 = line + cheight; 1345 offset += line_offset; 1346 if (line < s->params.line_compare && line1 >= s->params.line_compare) { 1347 offset = 0; 1348 } 1349 line = line1; 1350 } 1351 } 1352 1353 enum { 1354 VGA_DRAW_LINE2, 1355 VGA_DRAW_LINE2D2, 1356 VGA_DRAW_LINE4, 1357 VGA_DRAW_LINE4D2, 1358 VGA_DRAW_LINE8D2, 1359 VGA_DRAW_LINE8, 1360 VGA_DRAW_LINE15_LE, 1361 VGA_DRAW_LINE16_LE, 1362 VGA_DRAW_LINE24_LE, 1363 VGA_DRAW_LINE32_LE, 1364 VGA_DRAW_LINE15_BE, 1365 VGA_DRAW_LINE16_BE, 1366 VGA_DRAW_LINE24_BE, 1367 VGA_DRAW_LINE32_BE, 1368 VGA_DRAW_LINE_NB, 1369 }; 1370 1371 static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = { 1372 vga_draw_line2, 1373 vga_draw_line2d2, 1374 vga_draw_line4, 1375 vga_draw_line4d2, 1376 vga_draw_line8d2, 1377 vga_draw_line8, 1378 vga_draw_line15_le, 1379 vga_draw_line16_le, 1380 vga_draw_line24_le, 1381 vga_draw_line32_le, 1382 vga_draw_line15_be, 1383 vga_draw_line16_be, 1384 vga_draw_line24_be, 1385 vga_draw_line32_be, 1386 }; 1387 1388 static int vga_get_bpp(VGACommonState *s) 1389 { 1390 int ret; 1391 1392 if (vbe_enabled(s)) { 1393 ret = s->vbe_regs[VBE_DISPI_INDEX_BPP]; 1394 } else { 1395 ret = 0; 1396 } 1397 return ret; 1398 } 1399 1400 static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight) 1401 { 1402 int width, height; 1403 1404 if (vbe_enabled(s)) { 1405 width = s->vbe_regs[VBE_DISPI_INDEX_XRES]; 1406 height = s->vbe_regs[VBE_DISPI_INDEX_YRES]; 1407 } else { 1408 width = (s->cr[VGA_CRTC_H_DISP] + 1) * 8; 1409 height = s->cr[VGA_CRTC_V_DISP_END] | 1410 ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) | 1411 ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3); 1412 height = (height + 1); 1413 } 1414 *pwidth = width; 1415 *pheight = height; 1416 } 1417 1418 void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2) 1419 { 1420 int y; 1421 if (y1 >= VGA_MAX_HEIGHT) 1422 return; 1423 if (y2 >= VGA_MAX_HEIGHT) 1424 y2 = VGA_MAX_HEIGHT; 1425 for(y = y1; y < y2; y++) { 1426 s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f); 1427 } 1428 } 1429 1430 static bool vga_scanline_invalidated(VGACommonState *s, int y) 1431 { 1432 if (y >= VGA_MAX_HEIGHT) { 1433 return false; 1434 } 1435 return s->invalidated_y_table[y >> 5] & (1 << (y & 0x1f)); 1436 } 1437 1438 void vga_dirty_log_start(VGACommonState *s) 1439 { 1440 memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA); 1441 } 1442 1443 void vga_dirty_log_stop(VGACommonState *s) 1444 { 1445 memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA); 1446 } 1447 1448 /* 1449 * graphic modes 1450 */ 1451 static void vga_draw_graphic(VGACommonState *s, int full_update) 1452 { 1453 DisplaySurface *surface = qemu_console_surface(s->con); 1454 int y1, y, update, linesize, y_start, double_scan, mask, depth; 1455 int width, height, shift_control, bwidth, bits; 1456 ram_addr_t page0, page1, region_start, region_end; 1457 DirtyBitmapSnapshot *snap = NULL; 1458 int disp_width, multi_scan, multi_run; 1459 int hpel; 1460 uint8_t *d; 1461 uint32_t v, addr1, addr; 1462 vga_draw_line_func *vga_draw_line = NULL; 1463 bool share_surface, force_shadow = false; 1464 pixman_format_code_t format; 1465 #if HOST_BIG_ENDIAN 1466 bool byteswap = !s->big_endian_fb; 1467 #else 1468 bool byteswap = s->big_endian_fb; 1469 #endif 1470 1471 full_update |= update_basic_params(s); 1472 1473 s->get_resolution(s, &width, &height); 1474 disp_width = width; 1475 depth = s->get_bpp(s); 1476 1477 region_start = (s->params.start_addr * 4); 1478 region_end = region_start + (ram_addr_t)s->params.line_offset * height; 1479 region_end += width * depth / 8; /* scanline length */ 1480 region_end -= s->params.line_offset; 1481 if (region_end > s->vbe_size || depth == 0 || depth == 15) { 1482 /* 1483 * We land here on: 1484 * - wraps around (can happen with cirrus vbe modes) 1485 * - depth == 0 (256 color palette video mode) 1486 * - depth == 15 1487 * 1488 * Take the safe and slow route: 1489 * - create a dirty bitmap snapshot for all vga memory. 1490 * - force shadowing (so all vga memory access goes 1491 * through vga_read_*() helpers). 1492 * 1493 * Given this affects only vga features which are pretty much 1494 * unused by modern guests there should be no performance 1495 * impact. 1496 */ 1497 region_start = 0; 1498 region_end = s->vbe_size; 1499 force_shadow = true; 1500 } 1501 1502 /* bits 5-6: 0 = 16-color mode, 1 = 4-color mode, 2 = 256-color mode. */ 1503 shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3; 1504 double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7); 1505 if (s->cr[VGA_CRTC_MODE] & 1) { 1506 multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan) 1507 - 1; 1508 } else { 1509 /* in CGA modes, multi_scan is ignored */ 1510 /* XXX: is it correct ? */ 1511 multi_scan = double_scan; 1512 } 1513 multi_run = multi_scan; 1514 if (shift_control != s->shift_control || 1515 double_scan != s->double_scan) { 1516 full_update = 1; 1517 s->shift_control = shift_control; 1518 s->double_scan = double_scan; 1519 } 1520 1521 if (shift_control == 0) { 1522 if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) { 1523 disp_width <<= 1; 1524 } 1525 } else if (shift_control == 1) { 1526 if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) { 1527 disp_width <<= 1; 1528 } 1529 } 1530 1531 /* 1532 * Check whether we can share the surface with the backend 1533 * or whether we need a shadow surface. We share native 1534 * endian surfaces for 15bpp and above and byteswapped 1535 * surfaces for 24bpp and above. 1536 */ 1537 format = qemu_default_pixman_format(depth, !byteswap); 1538 if (format) { 1539 share_surface = dpy_gfx_check_format(s->con, format) 1540 && !s->force_shadow && !force_shadow; 1541 } else { 1542 share_surface = false; 1543 } 1544 1545 if (s->params.line_offset != s->last_line_offset || 1546 disp_width != s->last_width || 1547 height != s->last_height || 1548 s->last_depth != depth || 1549 s->last_byteswap != byteswap || 1550 share_surface != is_buffer_shared(surface)) { 1551 /* display parameters changed -> need new display surface */ 1552 s->last_scr_width = disp_width; 1553 s->last_scr_height = height; 1554 s->last_width = disp_width; 1555 s->last_height = height; 1556 s->last_line_offset = s->params.line_offset; 1557 s->last_depth = depth; 1558 s->last_byteswap = byteswap; 1559 /* 16 extra pixels are needed for double-width planar modes. */ 1560 s->panning_buf = g_realloc(s->panning_buf, 1561 (disp_width + 16) * sizeof(uint32_t)); 1562 full_update = 1; 1563 } 1564 if (surface_data(surface) != s->vram_ptr + (s->params.start_addr * 4) 1565 && is_buffer_shared(surface)) { 1566 /* base address changed (page flip) -> shared display surfaces 1567 * must be updated with the new base address */ 1568 full_update = 1; 1569 } 1570 1571 if (full_update) { 1572 if (share_surface) { 1573 surface = qemu_create_displaysurface_from(disp_width, 1574 height, format, s->params.line_offset, 1575 s->vram_ptr + (s->params.start_addr * 4)); 1576 dpy_gfx_replace_surface(s->con, surface); 1577 } else { 1578 qemu_console_resize(s->con, disp_width, height); 1579 surface = qemu_console_surface(s->con); 1580 } 1581 } 1582 1583 if (shift_control == 0) { 1584 full_update |= update_palette16(s); 1585 if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) { 1586 v = VGA_DRAW_LINE4D2; 1587 } else { 1588 v = VGA_DRAW_LINE4; 1589 } 1590 bits = 4; 1591 } else if (shift_control == 1) { 1592 full_update |= update_palette16(s); 1593 if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) { 1594 v = VGA_DRAW_LINE2D2; 1595 } else { 1596 v = VGA_DRAW_LINE2; 1597 } 1598 bits = 4; 1599 } else { 1600 switch(s->get_bpp(s)) { 1601 default: 1602 case 0: 1603 full_update |= update_palette256(s); 1604 v = VGA_DRAW_LINE8D2; 1605 bits = 4; 1606 break; 1607 case 8: 1608 full_update |= update_palette256(s); 1609 v = VGA_DRAW_LINE8; 1610 bits = 8; 1611 break; 1612 case 15: 1613 v = s->big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE; 1614 bits = 16; 1615 break; 1616 case 16: 1617 v = s->big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE; 1618 bits = 16; 1619 break; 1620 case 24: 1621 v = s->big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE; 1622 bits = 24; 1623 break; 1624 case 32: 1625 v = s->big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE; 1626 bits = 32; 1627 break; 1628 } 1629 } 1630 vga_draw_line = vga_draw_line_table[v]; 1631 1632 if (!is_buffer_shared(surface) && s->cursor_invalidate) { 1633 s->cursor_invalidate(s); 1634 } 1635 1636 #if 0 1637 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", 1638 width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE], 1639 s->params.line_compare, sr(s, VGA_SEQ_CLOCK_MODE)); 1640 #endif 1641 hpel = bits <= 8 ? s->params.hpel : 0; 1642 addr1 = (s->params.start_addr * 4); 1643 bwidth = DIV_ROUND_UP(width * bits, 8); 1644 if (hpel) { 1645 bwidth += 4; 1646 } 1647 y_start = -1; 1648 d = surface_data(surface); 1649 linesize = surface_stride(surface); 1650 y1 = 0; 1651 1652 if (!full_update) { 1653 if (s->params.line_compare < height) { 1654 /* split screen mode */ 1655 region_start = 0; 1656 } 1657 snap = memory_region_snapshot_and_clear_dirty(&s->vram, region_start, 1658 region_end - region_start, 1659 DIRTY_MEMORY_VGA); 1660 } 1661 1662 for(y = 0; y < height; y++) { 1663 addr = addr1; 1664 if (!(s->cr[VGA_CRTC_MODE] & 1)) { 1665 int shift; 1666 /* CGA compatibility handling */ 1667 shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1); 1668 addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift); 1669 } 1670 if (!(s->cr[VGA_CRTC_MODE] & 2)) { 1671 addr = (addr & ~0x8000) | ((y1 & 2) << 14); 1672 } 1673 page0 = addr & s->vbe_size_mask; 1674 page1 = (addr + bwidth - 1) & s->vbe_size_mask; 1675 if (full_update) { 1676 update = 1; 1677 } else if (page1 < page0) { 1678 /* scanline wraps from end of video memory to the start */ 1679 assert(force_shadow); 1680 update = memory_region_snapshot_get_dirty(&s->vram, snap, 1681 page0, s->vbe_size - page0); 1682 update |= memory_region_snapshot_get_dirty(&s->vram, snap, 1683 0, page1); 1684 } else { 1685 update = memory_region_snapshot_get_dirty(&s->vram, snap, 1686 page0, page1 - page0); 1687 } 1688 /* explicit invalidation for the hardware cursor (cirrus only) */ 1689 update |= vga_scanline_invalidated(s, y); 1690 if (update) { 1691 if (y_start < 0) 1692 y_start = y; 1693 if (!(is_buffer_shared(surface))) { 1694 uint8_t *p; 1695 p = vga_draw_line(s, d, addr, width, hpel); 1696 if (p) { 1697 memcpy(d, p, disp_width * sizeof(uint32_t)); 1698 } 1699 if (s->cursor_draw_line) 1700 s->cursor_draw_line(s, d, y); 1701 } 1702 } else { 1703 if (y_start >= 0) { 1704 /* flush to display */ 1705 dpy_gfx_update(s->con, 0, y_start, 1706 disp_width, y - y_start); 1707 y_start = -1; 1708 } 1709 } 1710 if (!multi_run) { 1711 mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3; 1712 if ((y1 & mask) == mask) 1713 addr1 += s->params.line_offset; 1714 y1++; 1715 multi_run = multi_scan; 1716 } else { 1717 multi_run--; 1718 } 1719 /* line compare acts on the displayed lines */ 1720 if (y == s->params.line_compare) { 1721 if (s->params.hpel_split) { 1722 hpel = VGA_HPEL_NEUTRAL; 1723 } 1724 addr1 = 0; 1725 } 1726 d += linesize; 1727 } 1728 if (y_start >= 0) { 1729 /* flush to display */ 1730 dpy_gfx_update(s->con, 0, y_start, 1731 disp_width, y - y_start); 1732 } 1733 g_free(snap); 1734 memset(s->invalidated_y_table, 0, sizeof(s->invalidated_y_table)); 1735 } 1736 1737 static void vga_draw_blank(VGACommonState *s, int full_update) 1738 { 1739 DisplaySurface *surface = qemu_console_surface(s->con); 1740 int i, w; 1741 uint8_t *d; 1742 1743 if (!full_update) 1744 return; 1745 if (s->last_scr_width <= 0 || s->last_scr_height <= 0) 1746 return; 1747 1748 w = s->last_scr_width * surface_bytes_per_pixel(surface); 1749 d = surface_data(surface); 1750 for(i = 0; i < s->last_scr_height; i++) { 1751 memset(d, 0, w); 1752 d += surface_stride(surface); 1753 } 1754 dpy_gfx_update_full(s->con); 1755 } 1756 1757 #define GMODE_TEXT 0 1758 #define GMODE_GRAPH 1 1759 #define GMODE_BLANK 2 1760 1761 static void vga_update_display(void *opaque) 1762 { 1763 VGACommonState *s = opaque; 1764 DisplaySurface *surface = qemu_console_surface(s->con); 1765 int full_update, graphic_mode; 1766 1767 qemu_flush_coalesced_mmio_buffer(); 1768 1769 if (surface_bits_per_pixel(surface) == 0) { 1770 /* nothing to do */ 1771 } else { 1772 full_update = 0; 1773 if (!(s->ar_index & 0x20)) { 1774 graphic_mode = GMODE_BLANK; 1775 } else { 1776 graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE; 1777 } 1778 if (graphic_mode != s->graphic_mode) { 1779 s->graphic_mode = graphic_mode; 1780 s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); 1781 full_update = 1; 1782 } 1783 switch(graphic_mode) { 1784 case GMODE_TEXT: 1785 vga_draw_text(s, full_update); 1786 break; 1787 case GMODE_GRAPH: 1788 vga_draw_graphic(s, full_update); 1789 break; 1790 case GMODE_BLANK: 1791 default: 1792 vga_draw_blank(s, full_update); 1793 break; 1794 } 1795 } 1796 } 1797 1798 /* force a full display refresh */ 1799 static void vga_invalidate_display(void *opaque) 1800 { 1801 VGACommonState *s = opaque; 1802 1803 s->last_width = -1; 1804 s->last_height = -1; 1805 } 1806 1807 void vga_common_reset(VGACommonState *s) 1808 { 1809 s->sr_index = 0; 1810 memset(s->sr, '\0', sizeof(s->sr)); 1811 memset(s->sr_vbe, '\0', sizeof(s->sr_vbe)); 1812 s->gr_index = 0; 1813 memset(s->gr, '\0', sizeof(s->gr)); 1814 s->ar_index = 0; 1815 memset(s->ar, '\0', sizeof(s->ar)); 1816 s->ar_flip_flop = 0; 1817 s->cr_index = 0; 1818 memset(s->cr, '\0', sizeof(s->cr)); 1819 s->msr = 0; 1820 s->fcr = 0; 1821 s->st00 = 0; 1822 s->st01 = 0; 1823 s->dac_state = 0; 1824 s->dac_sub_index = 0; 1825 s->dac_read_index = 0; 1826 s->dac_write_index = 0; 1827 memset(s->dac_cache, '\0', sizeof(s->dac_cache)); 1828 s->dac_8bit = 0; 1829 memset(s->palette, '\0', sizeof(s->palette)); 1830 s->bank_offset = 0; 1831 s->vbe_index = 0; 1832 memset(s->vbe_regs, '\0', sizeof(s->vbe_regs)); 1833 s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5; 1834 s->vbe_start_addr = 0; 1835 s->vbe_line_offset = 0; 1836 s->vbe_bank_mask = (s->vram_size >> 16) - 1; 1837 memset(s->font_offsets, '\0', sizeof(s->font_offsets)); 1838 s->graphic_mode = -1; /* force full update */ 1839 s->shift_control = 0; 1840 s->double_scan = 0; 1841 memset(&s->params, '\0', sizeof(s->params)); 1842 s->plane_updated = 0; 1843 s->last_cw = 0; 1844 s->last_ch = 0; 1845 s->last_width = 0; 1846 s->last_height = 0; 1847 s->last_scr_width = 0; 1848 s->last_scr_height = 0; 1849 s->cursor_start = 0; 1850 s->cursor_end = 0; 1851 s->cursor_offset = 0; 1852 s->big_endian_fb = s->default_endian_fb; 1853 memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table)); 1854 memset(s->last_palette, '\0', sizeof(s->last_palette)); 1855 memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr)); 1856 switch (vga_retrace_method) { 1857 case VGA_RETRACE_DUMB: 1858 break; 1859 case VGA_RETRACE_PRECISE: 1860 memset(&s->retrace_info, 0, sizeof (s->retrace_info)); 1861 break; 1862 } 1863 vga_update_memory_access(s); 1864 } 1865 1866 static void vga_reset(void *opaque) 1867 { 1868 VGACommonState *s = opaque; 1869 vga_common_reset(s); 1870 } 1871 1872 #define TEXTMODE_X(x) ((x) % width) 1873 #define TEXTMODE_Y(x) ((x) / width) 1874 #define VMEM2CHTYPE(v) ((v & 0xff0007ff) | \ 1875 ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1)) 1876 /* relay text rendering to the display driver 1877 * instead of doing a full vga_update_display() */ 1878 static void vga_update_text(void *opaque, console_ch_t *chardata) 1879 { 1880 VGACommonState *s = opaque; 1881 int graphic_mode, i, cursor_offset, cursor_visible; 1882 int cw, cheight, width, height, size, c_min, c_max; 1883 uint32_t *src; 1884 console_ch_t *dst, val; 1885 char msg_buffer[80]; 1886 int full_update = 0; 1887 1888 qemu_flush_coalesced_mmio_buffer(); 1889 1890 if (!(s->ar_index & 0x20)) { 1891 graphic_mode = GMODE_BLANK; 1892 } else { 1893 graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE; 1894 } 1895 if (graphic_mode != s->graphic_mode) { 1896 s->graphic_mode = graphic_mode; 1897 full_update = 1; 1898 } 1899 if (s->last_width == -1) { 1900 s->last_width = 0; 1901 full_update = 1; 1902 } 1903 1904 switch (graphic_mode) { 1905 case GMODE_TEXT: 1906 /* TODO: update palette */ 1907 full_update |= update_basic_params(s); 1908 1909 /* total width & height */ 1910 cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1; 1911 cw = 8; 1912 if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) { 1913 cw = 9; 1914 } 1915 if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) { 1916 cw = 16; /* NOTE: no 18 pixel wide */ 1917 } 1918 width = (s->cr[VGA_CRTC_H_DISP] + 1); 1919 if (s->cr[VGA_CRTC_V_TOTAL] == 100) { 1920 /* ugly hack for CGA 160x100x16 - explain me the logic */ 1921 height = 100; 1922 } else { 1923 height = s->cr[VGA_CRTC_V_DISP_END] | 1924 ((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) | 1925 ((s->cr[VGA_CRTC_OVERFLOW] & 0x40) << 3); 1926 height = (height + 1) / cheight; 1927 } 1928 1929 size = (height * width); 1930 if (size > CH_ATTR_SIZE) { 1931 if (!full_update) 1932 return; 1933 1934 snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode", 1935 width, height); 1936 break; 1937 } 1938 1939 if (width != s->last_width || height != s->last_height || 1940 cw != s->last_cw || cheight != s->last_ch) { 1941 s->last_scr_width = width * cw; 1942 s->last_scr_height = height * cheight; 1943 qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height); 1944 dpy_text_resize(s->con, width, height); 1945 s->last_depth = 0; 1946 s->last_width = width; 1947 s->last_height = height; 1948 s->last_ch = cheight; 1949 s->last_cw = cw; 1950 full_update = 1; 1951 } 1952 1953 if (full_update) { 1954 s->full_update_gfx = 1; 1955 } 1956 if (s->full_update_text) { 1957 s->full_update_text = 0; 1958 full_update |= 1; 1959 } 1960 1961 /* Update "hardware" cursor */ 1962 cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) | 1963 s->cr[VGA_CRTC_CURSOR_LO]) - s->params.start_addr; 1964 if (cursor_offset != s->cursor_offset || 1965 s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start || 1966 s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) { 1967 cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20); 1968 if (cursor_visible && cursor_offset < size && cursor_offset >= 0) 1969 dpy_text_cursor(s->con, 1970 TEXTMODE_X(cursor_offset), 1971 TEXTMODE_Y(cursor_offset)); 1972 else 1973 dpy_text_cursor(s->con, -1, -1); 1974 s->cursor_offset = cursor_offset; 1975 s->cursor_start = s->cr[VGA_CRTC_CURSOR_START]; 1976 s->cursor_end = s->cr[VGA_CRTC_CURSOR_END]; 1977 } 1978 1979 src = (uint32_t *) s->vram_ptr + s->params.start_addr; 1980 dst = chardata; 1981 1982 if (full_update) { 1983 for (i = 0; i < size; src ++, dst ++, i ++) 1984 console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src))); 1985 1986 dpy_text_update(s->con, 0, 0, width, height); 1987 } else { 1988 c_max = 0; 1989 1990 for (i = 0; i < size; src ++, dst ++, i ++) { 1991 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src))); 1992 if (*dst != val) { 1993 *dst = val; 1994 c_max = i; 1995 break; 1996 } 1997 } 1998 c_min = i; 1999 for (; i < size; src ++, dst ++, i ++) { 2000 console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src))); 2001 if (*dst != val) { 2002 *dst = val; 2003 c_max = i; 2004 } 2005 } 2006 2007 if (c_min <= c_max) { 2008 i = TEXTMODE_Y(c_min); 2009 dpy_text_update(s->con, 0, i, width, TEXTMODE_Y(c_max) - i + 1); 2010 } 2011 } 2012 2013 return; 2014 case GMODE_GRAPH: 2015 if (!full_update) 2016 return; 2017 2018 s->get_resolution(s, &width, &height); 2019 snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode", 2020 width, height); 2021 break; 2022 case GMODE_BLANK: 2023 default: 2024 if (!full_update) 2025 return; 2026 2027 snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode"); 2028 break; 2029 } 2030 2031 /* Display a message */ 2032 s->last_width = 60; 2033 s->last_height = height = 3; 2034 dpy_text_cursor(s->con, -1, -1); 2035 dpy_text_resize(s->con, s->last_width, height); 2036 2037 for (dst = chardata, i = 0; i < s->last_width * height; i ++) 2038 console_write_ch(dst ++, ' '); 2039 2040 size = strlen(msg_buffer); 2041 width = (s->last_width - size) / 2; 2042 dst = chardata + s->last_width + width; 2043 for (i = 0; i < size; i ++) 2044 console_write_ch(dst ++, ATTR2CHTYPE(msg_buffer[i], QEMU_COLOR_BLUE, 2045 QEMU_COLOR_BLACK, 1)); 2046 2047 dpy_text_update(s->con, 0, 0, s->last_width, height); 2048 } 2049 2050 static uint64_t vga_mem_read(void *opaque, hwaddr addr, 2051 unsigned size) 2052 { 2053 VGACommonState *s = opaque; 2054 2055 return vga_mem_readb(s, addr); 2056 } 2057 2058 static void vga_mem_write(void *opaque, hwaddr addr, 2059 uint64_t data, unsigned size) 2060 { 2061 VGACommonState *s = opaque; 2062 2063 vga_mem_writeb(s, addr, data); 2064 } 2065 2066 const MemoryRegionOps vga_mem_ops = { 2067 .read = vga_mem_read, 2068 .write = vga_mem_write, 2069 .endianness = DEVICE_LITTLE_ENDIAN, 2070 .impl = { 2071 .min_access_size = 1, 2072 .max_access_size = 1, 2073 }, 2074 }; 2075 2076 static int vga_common_post_load(void *opaque, int version_id) 2077 { 2078 VGACommonState *s = opaque; 2079 2080 /* force refresh */ 2081 s->graphic_mode = -1; 2082 vbe_update_vgaregs(s); 2083 vga_update_memory_access(s); 2084 return 0; 2085 } 2086 2087 static bool vga_endian_state_needed(void *opaque) 2088 { 2089 VGACommonState *s = opaque; 2090 2091 /* 2092 * Only send the endian state if it's different from the 2093 * default one, thus ensuring backward compatibility for 2094 * migration of the common case 2095 */ 2096 return s->default_endian_fb != s->big_endian_fb; 2097 } 2098 2099 static const VMStateDescription vmstate_vga_endian = { 2100 .name = "vga.endian", 2101 .version_id = 1, 2102 .minimum_version_id = 1, 2103 .needed = vga_endian_state_needed, 2104 .fields = (const VMStateField[]) { 2105 VMSTATE_BOOL(big_endian_fb, VGACommonState), 2106 VMSTATE_END_OF_LIST() 2107 } 2108 }; 2109 2110 const VMStateDescription vmstate_vga_common = { 2111 .name = "vga", 2112 .version_id = 2, 2113 .minimum_version_id = 2, 2114 .post_load = vga_common_post_load, 2115 .fields = (const VMStateField[]) { 2116 VMSTATE_UINT32(latch, VGACommonState), 2117 VMSTATE_UINT8(sr_index, VGACommonState), 2118 VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8), 2119 VMSTATE_UINT8(gr_index, VGACommonState), 2120 VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16), 2121 VMSTATE_UINT8(ar_index, VGACommonState), 2122 VMSTATE_BUFFER(ar, VGACommonState), 2123 VMSTATE_INT32(ar_flip_flop, VGACommonState), 2124 VMSTATE_UINT8(cr_index, VGACommonState), 2125 VMSTATE_BUFFER(cr, VGACommonState), 2126 VMSTATE_UINT8(msr, VGACommonState), 2127 VMSTATE_UINT8(fcr, VGACommonState), 2128 VMSTATE_UINT8(st00, VGACommonState), 2129 VMSTATE_UINT8(st01, VGACommonState), 2130 2131 VMSTATE_UINT8(dac_state, VGACommonState), 2132 VMSTATE_UINT8(dac_sub_index, VGACommonState), 2133 VMSTATE_UINT8(dac_read_index, VGACommonState), 2134 VMSTATE_UINT8(dac_write_index, VGACommonState), 2135 VMSTATE_BUFFER(dac_cache, VGACommonState), 2136 VMSTATE_BUFFER(palette, VGACommonState), 2137 2138 VMSTATE_INT32(bank_offset, VGACommonState), 2139 VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState, NULL), 2140 VMSTATE_UINT16(vbe_index, VGACommonState), 2141 VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB), 2142 VMSTATE_UINT32(vbe_start_addr, VGACommonState), 2143 VMSTATE_UINT32(vbe_line_offset, VGACommonState), 2144 VMSTATE_UINT32(vbe_bank_mask, VGACommonState), 2145 VMSTATE_END_OF_LIST() 2146 }, 2147 .subsections = (const VMStateDescription * const []) { 2148 &vmstate_vga_endian, 2149 NULL 2150 } 2151 }; 2152 2153 static const GraphicHwOps vga_ops = { 2154 .invalidate = vga_invalidate_display, 2155 .gfx_update = vga_update_display, 2156 .text_update = vga_update_text, 2157 }; 2158 2159 static inline uint32_t uint_clamp(uint32_t val, uint32_t vmin, uint32_t vmax) 2160 { 2161 if (val < vmin) { 2162 return vmin; 2163 } 2164 if (val > vmax) { 2165 return vmax; 2166 } 2167 return val; 2168 } 2169 2170 bool vga_common_init(VGACommonState *s, Object *obj, Error **errp) 2171 { 2172 int i, j, v, b; 2173 Error *local_err = NULL; 2174 2175 for(i = 0;i < 256; i++) { 2176 v = 0; 2177 for(j = 0; j < 8; j++) { 2178 v |= ((i >> j) & 1) << (j * 4); 2179 } 2180 expand4[i] = v; 2181 2182 v = 0; 2183 for(j = 0; j < 4; j++) { 2184 v |= ((i >> (2 * j)) & 3) << (j * 4); 2185 } 2186 expand2[i] = v; 2187 } 2188 for(i = 0; i < 16; i++) { 2189 v = 0; 2190 for(j = 0; j < 4; j++) { 2191 b = ((i >> j) & 1); 2192 v |= b << (2 * j); 2193 v |= b << (2 * j + 1); 2194 } 2195 expand4to8[i] = v; 2196 } 2197 2198 s->vram_size_mb = uint_clamp(s->vram_size_mb, 1, 512); 2199 s->vram_size_mb = pow2ceil(s->vram_size_mb); 2200 s->vram_size = s->vram_size_mb * MiB; 2201 2202 if (!s->vbe_size) { 2203 s->vbe_size = s->vram_size; 2204 } 2205 s->vbe_size_mask = s->vbe_size - 1; 2206 2207 s->is_vbe_vmstate = 1; 2208 2209 if (s->global_vmstate && qemu_ram_block_by_name("vga.vram")) { 2210 error_setg(errp, "Only one global VGA device can be used at a time"); 2211 return false; 2212 } 2213 2214 memory_region_init_ram_nomigrate(&s->vram, obj, "vga.vram", s->vram_size, 2215 &local_err); 2216 if (local_err) { 2217 error_propagate(errp, local_err); 2218 return false; 2219 } 2220 vmstate_register_ram(&s->vram, s->global_vmstate ? NULL : DEVICE(obj)); 2221 xen_register_framebuffer(&s->vram); 2222 s->vram_ptr = memory_region_get_ram_ptr(&s->vram); 2223 s->get_bpp = vga_get_bpp; 2224 s->get_params = vga_get_params; 2225 s->get_resolution = vga_get_resolution; 2226 s->hw_ops = &vga_ops; 2227 switch (vga_retrace_method) { 2228 case VGA_RETRACE_DUMB: 2229 s->retrace = vga_dumb_retrace; 2230 s->update_retrace_info = vga_dumb_update_retrace_info; 2231 break; 2232 2233 case VGA_RETRACE_PRECISE: 2234 s->retrace = vga_precise_retrace; 2235 s->update_retrace_info = vga_precise_update_retrace_info; 2236 break; 2237 } 2238 2239 /* 2240 * Set default fb endian based on target, could probably be turned 2241 * into a device attribute set by the machine/platform to remove 2242 * all target endian dependencies from this file. 2243 */ 2244 s->default_endian_fb = target_words_bigendian(); 2245 2246 vga_dirty_log_start(s); 2247 2248 return true; 2249 } 2250 2251 static const MemoryRegionPortio vga_portio_list[] = { 2252 { 0x04, 2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */ 2253 { 0x0a, 1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */ 2254 { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */ 2255 { 0x24, 2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */ 2256 { 0x2a, 1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */ 2257 PORTIO_END_OF_LIST(), 2258 }; 2259 2260 static const MemoryRegionPortio vbe_portio_list_x86[] = { 2261 { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index }, 2262 { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data }, 2263 { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data }, 2264 PORTIO_END_OF_LIST(), 2265 }; 2266 2267 static const MemoryRegionPortio vbe_portio_list_no_x86[] = { 2268 { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index }, 2269 { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data }, 2270 PORTIO_END_OF_LIST(), 2271 }; 2272 2273 /* Used by both ISA and PCI */ 2274 MemoryRegion *vga_init_io(VGACommonState *s, Object *obj, 2275 const MemoryRegionPortio **vga_ports, 2276 const MemoryRegionPortio **vbe_ports) 2277 { 2278 MemoryRegion *vga_mem; 2279 MachineState *ms = MACHINE(qdev_get_machine()); 2280 2281 /* 2282 * We unfortunately need two VBE lists since non-x86 machines might 2283 * not be able to do 16-bit accesses at unaligned addresses (0x1cf) 2284 */ 2285 if (object_dynamic_cast(OBJECT(ms), TYPE_X86_MACHINE)) { 2286 *vbe_ports = vbe_portio_list_x86; 2287 } else { 2288 *vbe_ports = vbe_portio_list_no_x86; 2289 } 2290 2291 *vga_ports = vga_portio_list; 2292 2293 vga_mem = g_malloc(sizeof(*vga_mem)); 2294 memory_region_init_io(vga_mem, obj, &vga_mem_ops, s, 2295 "vga-lowmem", 0x20000); 2296 memory_region_set_flush_coalesced(vga_mem); 2297 2298 return vga_mem; 2299 } 2300 2301 void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space, 2302 MemoryRegion *address_space_io, bool init_vga_ports) 2303 { 2304 MemoryRegion *vga_io_memory; 2305 const MemoryRegionPortio *vga_ports, *vbe_ports; 2306 2307 qemu_register_reset(vga_reset, s); 2308 2309 s->bank_offset = 0; 2310 2311 s->legacy_address_space = address_space; 2312 2313 vga_io_memory = vga_init_io(s, obj, &vga_ports, &vbe_ports); 2314 memory_region_add_subregion_overlap(address_space, 2315 0x000a0000, 2316 vga_io_memory, 2317 1); 2318 memory_region_set_coalescing(vga_io_memory); 2319 if (init_vga_ports) { 2320 portio_list_init(&s->vga_port_list, obj, vga_ports, s, "vga"); 2321 portio_list_set_flush_coalesced(&s->vga_port_list); 2322 portio_list_add(&s->vga_port_list, address_space_io, 0x3b0); 2323 } 2324 if (vbe_ports) { 2325 portio_list_init(&s->vbe_port_list, obj, vbe_ports, s, "vbe"); 2326 portio_list_add(&s->vbe_port_list, address_space_io, 0x1ce); 2327 } 2328 } 2329