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