1 /* 2 * QEMU ATI SVGA emulation 3 * 4 * Copyright (c) 2019 BALATON Zoltan 5 * 6 * This work is licensed under the GNU GPL license version 2 or later. 7 */ 8 9 /* 10 * WARNING: 11 * This is very incomplete and only enough for Linux console and some 12 * unaccelerated X output at the moment. 13 * Currently it's little more than a frame buffer with minimal functions, 14 * other more advanced features of the hardware are yet to be implemented. 15 * We only aim for Rage 128 Pro (and some RV100) and 2D only at first, 16 * No 3D at all yet (maybe after 2D works, but feel free to improve it) 17 */ 18 19 #include "qemu/osdep.h" 20 #include "ati_int.h" 21 #include "ati_regs.h" 22 #include "hw/qdev-properties.h" 23 #include "vga_regs.h" 24 #include "qemu/log.h" 25 #include "qemu/module.h" 26 #include "qemu/error-report.h" 27 #include "qapi/error.h" 28 #include "ui/console.h" 29 #include "hw/display/i2c-ddc.h" 30 #include "trace.h" 31 32 #define ATI_DEBUG_HW_CURSOR 0 33 34 static const struct { 35 const char *name; 36 uint16_t dev_id; 37 } ati_model_aliases[] = { 38 { "rage128p", PCI_DEVICE_ID_ATI_RAGE128_PF }, 39 { "rv100", PCI_DEVICE_ID_ATI_RADEON_QY }, 40 }; 41 42 enum { VGA_MODE, EXT_MODE }; 43 44 static void ati_vga_switch_mode(ATIVGAState *s) 45 { 46 DPRINTF("%d -> %d\n", 47 s->mode, !!(s->regs.crtc_gen_cntl & CRTC2_EXT_DISP_EN)); 48 if (s->regs.crtc_gen_cntl & CRTC2_EXT_DISP_EN) { 49 /* Extended mode enabled */ 50 s->mode = EXT_MODE; 51 if (s->regs.crtc_gen_cntl & CRTC2_EN) { 52 /* CRT controller enabled, use CRTC values */ 53 /* FIXME Should these be the same as VGA CRTC regs? */ 54 uint32_t offs = s->regs.crtc_offset & 0x07ffffff; 55 int stride = (s->regs.crtc_pitch & 0x7ff) * 8; 56 int bpp = 0; 57 int h, v; 58 59 if (s->regs.crtc_h_total_disp == 0) { 60 s->regs.crtc_h_total_disp = ((640 / 8) - 1) << 16; 61 } 62 if (s->regs.crtc_v_total_disp == 0) { 63 s->regs.crtc_v_total_disp = (480 - 1) << 16; 64 } 65 h = ((s->regs.crtc_h_total_disp >> 16) + 1) * 8; 66 v = (s->regs.crtc_v_total_disp >> 16) + 1; 67 switch (s->regs.crtc_gen_cntl & CRTC_PIX_WIDTH_MASK) { 68 case CRTC_PIX_WIDTH_4BPP: 69 bpp = 4; 70 break; 71 case CRTC_PIX_WIDTH_8BPP: 72 bpp = 8; 73 break; 74 case CRTC_PIX_WIDTH_15BPP: 75 bpp = 15; 76 break; 77 case CRTC_PIX_WIDTH_16BPP: 78 bpp = 16; 79 break; 80 case CRTC_PIX_WIDTH_24BPP: 81 bpp = 24; 82 break; 83 case CRTC_PIX_WIDTH_32BPP: 84 bpp = 32; 85 break; 86 default: 87 qemu_log_mask(LOG_UNIMP, "Unsupported bpp value\n"); 88 } 89 assert(bpp != 0); 90 DPRINTF("Switching to %dx%d %d %d @ %x\n", h, v, stride, bpp, offs); 91 vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE); 92 vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_DISABLED); 93 s->vga.big_endian_fb = (s->regs.config_cntl & APER_0_ENDIAN || 94 s->regs.config_cntl & APER_1_ENDIAN ? 95 true : false); 96 /* reset VBE regs then set up mode */ 97 s->vga.vbe_regs[VBE_DISPI_INDEX_XRES] = h; 98 s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] = v; 99 s->vga.vbe_regs[VBE_DISPI_INDEX_BPP] = bpp; 100 /* enable mode via ioport so it updates vga regs */ 101 vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE); 102 vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_ENABLED | 103 VBE_DISPI_LFB_ENABLED | VBE_DISPI_NOCLEARMEM | 104 (s->regs.dac_cntl & DAC_8BIT_EN ? VBE_DISPI_8BIT_DAC : 0)); 105 /* now set offset and stride after enable as that resets these */ 106 if (stride) { 107 int bypp = DIV_ROUND_UP(bpp, BITS_PER_BYTE); 108 109 vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_VIRT_WIDTH); 110 vbe_ioport_write_data(&s->vga, 0, stride); 111 stride *= bypp; 112 if (offs % stride) { 113 DPRINTF("CRTC offset is not multiple of pitch\n"); 114 vbe_ioport_write_index(&s->vga, 0, 115 VBE_DISPI_INDEX_X_OFFSET); 116 vbe_ioport_write_data(&s->vga, 0, offs % stride / bypp); 117 } 118 vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_Y_OFFSET); 119 vbe_ioport_write_data(&s->vga, 0, offs / stride); 120 DPRINTF("VBE offset (%d,%d), vbe_start_addr=%x\n", 121 s->vga.vbe_regs[VBE_DISPI_INDEX_X_OFFSET], 122 s->vga.vbe_regs[VBE_DISPI_INDEX_Y_OFFSET], 123 s->vga.vbe_start_addr); 124 } 125 } 126 } else { 127 /* VGA mode enabled */ 128 s->mode = VGA_MODE; 129 vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE); 130 vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_DISABLED); 131 } 132 } 133 134 /* Used by host side hardware cursor */ 135 static void ati_cursor_define(ATIVGAState *s) 136 { 137 uint8_t data[1024]; 138 uint8_t *src; 139 int i, j, idx = 0; 140 141 if ((s->regs.cur_offset & BIT(31)) || s->cursor_guest_mode) { 142 return; /* Do not update cursor if locked or rendered by guest */ 143 } 144 /* FIXME handle cur_hv_offs correctly */ 145 src = s->vga.vram_ptr + s->regs.cur_offset - 146 (s->regs.cur_hv_offs >> 16) - (s->regs.cur_hv_offs & 0xffff) * 16; 147 for (i = 0; i < 64; i++) { 148 for (j = 0; j < 8; j++, idx++) { 149 data[idx] = src[i * 16 + j]; 150 data[512 + idx] = src[i * 16 + j + 8]; 151 } 152 } 153 if (!s->cursor) { 154 s->cursor = cursor_alloc(64, 64); 155 } 156 cursor_set_mono(s->cursor, s->regs.cur_color1, s->regs.cur_color0, 157 &data[512], 1, &data[0]); 158 dpy_cursor_define(s->vga.con, s->cursor); 159 } 160 161 /* Alternatively support guest rendered hardware cursor */ 162 static void ati_cursor_invalidate(VGACommonState *vga) 163 { 164 ATIVGAState *s = container_of(vga, ATIVGAState, vga); 165 int size = (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) ? 64 : 0; 166 167 if (s->regs.cur_offset & BIT(31)) { 168 return; /* Do not update cursor if locked */ 169 } 170 if (s->cursor_size != size || 171 vga->hw_cursor_x != s->regs.cur_hv_pos >> 16 || 172 vga->hw_cursor_y != (s->regs.cur_hv_pos & 0xffff) || 173 s->cursor_offset != s->regs.cur_offset - (s->regs.cur_hv_offs >> 16) - 174 (s->regs.cur_hv_offs & 0xffff) * 16) { 175 /* Remove old cursor then update and show new one if needed */ 176 vga_invalidate_scanlines(vga, vga->hw_cursor_y, vga->hw_cursor_y + 63); 177 vga->hw_cursor_x = s->regs.cur_hv_pos >> 16; 178 vga->hw_cursor_y = s->regs.cur_hv_pos & 0xffff; 179 s->cursor_offset = s->regs.cur_offset - (s->regs.cur_hv_offs >> 16) - 180 (s->regs.cur_hv_offs & 0xffff) * 16; 181 s->cursor_size = size; 182 if (size) { 183 vga_invalidate_scanlines(vga, 184 vga->hw_cursor_y, vga->hw_cursor_y + 63); 185 } 186 } 187 } 188 189 static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y) 190 { 191 ATIVGAState *s = container_of(vga, ATIVGAState, vga); 192 uint8_t *src; 193 uint32_t *dp = (uint32_t *)d; 194 int i, j, h; 195 196 if (!(s->regs.crtc_gen_cntl & CRTC2_CUR_EN) || 197 scr_y < vga->hw_cursor_y || scr_y >= vga->hw_cursor_y + 64 || 198 scr_y > s->regs.crtc_v_total_disp >> 16) { 199 return; 200 } 201 /* FIXME handle cur_hv_offs correctly */ 202 src = s->vga.vram_ptr + s->cursor_offset + (scr_y - vga->hw_cursor_y) * 16; 203 dp = &dp[vga->hw_cursor_x]; 204 h = ((s->regs.crtc_h_total_disp >> 16) + 1) * 8; 205 for (i = 0; i < 8; i++) { 206 uint32_t color; 207 uint8_t abits = src[i]; 208 uint8_t xbits = src[i + 8]; 209 for (j = 0; j < 8; j++, abits <<= 1, xbits <<= 1) { 210 if (abits & BIT(7)) { 211 if (xbits & BIT(7)) { 212 color = dp[i * 8 + j] ^ 0xffffffff; /* complement */ 213 } else { 214 continue; /* transparent, no change */ 215 } 216 } else { 217 color = (xbits & BIT(7) ? s->regs.cur_color1 : 218 s->regs.cur_color0) | 0xff000000; 219 } 220 if (vga->hw_cursor_x + i * 8 + j >= h) { 221 return; /* end of screen, don't span to next line */ 222 } 223 dp[i * 8 + j] = color; 224 } 225 } 226 } 227 228 static uint64_t ati_i2c(bitbang_i2c_interface *i2c, uint64_t data, int base) 229 { 230 bool c = (data & BIT(base + 17) ? !!(data & BIT(base + 1)) : 1); 231 bool d = (data & BIT(base + 16) ? !!(data & BIT(base)) : 1); 232 233 bitbang_i2c_set(i2c, BITBANG_I2C_SCL, c); 234 d = bitbang_i2c_set(i2c, BITBANG_I2C_SDA, d); 235 236 data &= ~0xf00ULL; 237 if (c) { 238 data |= BIT(base + 9); 239 } 240 if (d) { 241 data |= BIT(base + 8); 242 } 243 return data; 244 } 245 246 static void ati_vga_update_irq(ATIVGAState *s) 247 { 248 pci_set_irq(&s->dev, !!(s->regs.gen_int_status & s->regs.gen_int_cntl)); 249 } 250 251 static void ati_vga_vblank_irq(void *opaque) 252 { 253 ATIVGAState *s = opaque; 254 255 timer_mod(&s->vblank_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 256 NANOSECONDS_PER_SECOND / 60); 257 s->regs.gen_int_status |= CRTC_VBLANK_INT; 258 ati_vga_update_irq(s); 259 } 260 261 static inline uint64_t ati_reg_read_offs(uint32_t reg, int offs, 262 unsigned int size) 263 { 264 if (offs == 0 && size == 4) { 265 return reg; 266 } else { 267 return extract32(reg, offs * BITS_PER_BYTE, size * BITS_PER_BYTE); 268 } 269 } 270 271 static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size) 272 { 273 ATIVGAState *s = opaque; 274 uint64_t val = 0; 275 276 switch (addr) { 277 case MM_INDEX: 278 val = s->regs.mm_index; 279 break; 280 case MM_DATA ... MM_DATA + 3: 281 /* indexed access to regs or memory */ 282 if (s->regs.mm_index & BIT(31)) { 283 uint32_t idx = s->regs.mm_index & ~BIT(31); 284 if (idx <= s->vga.vram_size - size) { 285 val = ldn_le_p(s->vga.vram_ptr + idx, size); 286 } 287 } else { 288 val = ati_mm_read(s, s->regs.mm_index + addr - MM_DATA, size); 289 } 290 break; 291 case BIOS_0_SCRATCH ... BUS_CNTL - 1: 292 { 293 int i = (addr - BIOS_0_SCRATCH) / 4; 294 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF && i > 3) { 295 break; 296 } 297 val = ati_reg_read_offs(s->regs.bios_scratch[i], 298 addr - (BIOS_0_SCRATCH + i * 4), size); 299 break; 300 } 301 case GEN_INT_CNTL: 302 val = s->regs.gen_int_cntl; 303 break; 304 case GEN_INT_STATUS: 305 val = s->regs.gen_int_status; 306 break; 307 case CRTC_GEN_CNTL ... CRTC_GEN_CNTL + 3: 308 val = ati_reg_read_offs(s->regs.crtc_gen_cntl, 309 addr - CRTC_GEN_CNTL, size); 310 break; 311 case CRTC_EXT_CNTL ... CRTC_EXT_CNTL + 3: 312 val = ati_reg_read_offs(s->regs.crtc_ext_cntl, 313 addr - CRTC_EXT_CNTL, size); 314 break; 315 case DAC_CNTL: 316 val = s->regs.dac_cntl; 317 break; 318 case GPIO_VGA_DDC: 319 val = s->regs.gpio_vga_ddc; 320 break; 321 case GPIO_DVI_DDC: 322 val = s->regs.gpio_dvi_ddc; 323 break; 324 case GPIO_MONID ... GPIO_MONID + 3: 325 val = ati_reg_read_offs(s->regs.gpio_monid, 326 addr - GPIO_MONID, size); 327 break; 328 case PALETTE_INDEX: 329 /* FIXME unaligned access */ 330 val = vga_ioport_read(&s->vga, VGA_PEL_IR) << 16; 331 val |= vga_ioport_read(&s->vga, VGA_PEL_IW) & 0xff; 332 break; 333 case PALETTE_DATA: 334 val = vga_ioport_read(&s->vga, VGA_PEL_D); 335 break; 336 case CNFG_CNTL: 337 val = s->regs.config_cntl; 338 break; 339 case CNFG_MEMSIZE: 340 val = s->vga.vram_size; 341 break; 342 case CONFIG_APER_0_BASE: 343 case CONFIG_APER_1_BASE: 344 val = pci_default_read_config(&s->dev, 345 PCI_BASE_ADDRESS_0, size) & 0xfffffff0; 346 break; 347 case CONFIG_APER_SIZE: 348 val = s->vga.vram_size; 349 break; 350 case CONFIG_REG_1_BASE: 351 val = pci_default_read_config(&s->dev, 352 PCI_BASE_ADDRESS_2, size) & 0xfffffff0; 353 break; 354 case CONFIG_REG_APER_SIZE: 355 val = memory_region_size(&s->mm); 356 break; 357 case MC_STATUS: 358 val = 5; 359 break; 360 case RBBM_STATUS: 361 case GUI_STAT: 362 val = 64; /* free CMDFIFO entries */ 363 break; 364 case CRTC_H_TOTAL_DISP: 365 val = s->regs.crtc_h_total_disp; 366 break; 367 case CRTC_H_SYNC_STRT_WID: 368 val = s->regs.crtc_h_sync_strt_wid; 369 break; 370 case CRTC_V_TOTAL_DISP: 371 val = s->regs.crtc_v_total_disp; 372 break; 373 case CRTC_V_SYNC_STRT_WID: 374 val = s->regs.crtc_v_sync_strt_wid; 375 break; 376 case CRTC_OFFSET: 377 val = s->regs.crtc_offset; 378 break; 379 case CRTC_OFFSET_CNTL: 380 val = s->regs.crtc_offset_cntl; 381 break; 382 case CRTC_PITCH: 383 val = s->regs.crtc_pitch; 384 break; 385 case 0xf00 ... 0xfff: 386 val = pci_default_read_config(&s->dev, addr - 0xf00, size); 387 break; 388 case CUR_OFFSET: 389 val = s->regs.cur_offset; 390 break; 391 case CUR_HORZ_VERT_POSN: 392 val = s->regs.cur_hv_pos; 393 val |= s->regs.cur_offset & BIT(31); 394 break; 395 case CUR_HORZ_VERT_OFF: 396 val = s->regs.cur_hv_offs; 397 val |= s->regs.cur_offset & BIT(31); 398 break; 399 case CUR_CLR0: 400 val = s->regs.cur_color0; 401 break; 402 case CUR_CLR1: 403 val = s->regs.cur_color1; 404 break; 405 case DST_OFFSET: 406 val = s->regs.dst_offset; 407 break; 408 case DST_PITCH: 409 val = s->regs.dst_pitch; 410 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) { 411 val &= s->regs.dst_tile << 16; 412 } 413 break; 414 case DST_WIDTH: 415 val = s->regs.dst_width; 416 break; 417 case DST_HEIGHT: 418 val = s->regs.dst_height; 419 break; 420 case SRC_X: 421 val = s->regs.src_x; 422 break; 423 case SRC_Y: 424 val = s->regs.src_y; 425 break; 426 case DST_X: 427 val = s->regs.dst_x; 428 break; 429 case DST_Y: 430 val = s->regs.dst_y; 431 break; 432 case DP_GUI_MASTER_CNTL: 433 val = s->regs.dp_gui_master_cntl; 434 break; 435 case SRC_OFFSET: 436 val = s->regs.src_offset; 437 break; 438 case SRC_PITCH: 439 val = s->regs.src_pitch; 440 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) { 441 val &= s->regs.src_tile << 16; 442 } 443 break; 444 case DP_BRUSH_BKGD_CLR: 445 val = s->regs.dp_brush_bkgd_clr; 446 break; 447 case DP_BRUSH_FRGD_CLR: 448 val = s->regs.dp_brush_frgd_clr; 449 break; 450 case DP_SRC_FRGD_CLR: 451 val = s->regs.dp_src_frgd_clr; 452 break; 453 case DP_SRC_BKGD_CLR: 454 val = s->regs.dp_src_bkgd_clr; 455 break; 456 case DP_CNTL: 457 val = s->regs.dp_cntl; 458 break; 459 case DP_DATATYPE: 460 val = s->regs.dp_datatype; 461 break; 462 case DP_MIX: 463 val = s->regs.dp_mix; 464 break; 465 case DP_WRITE_MASK: 466 val = s->regs.dp_write_mask; 467 break; 468 case DEFAULT_OFFSET: 469 val = s->regs.default_offset; 470 if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) { 471 val >>= 10; 472 val |= s->regs.default_pitch << 16; 473 val |= s->regs.default_tile << 30; 474 } 475 break; 476 case DEFAULT_PITCH: 477 val = s->regs.default_pitch; 478 val |= s->regs.default_tile << 16; 479 break; 480 case DEFAULT_SC_BOTTOM_RIGHT: 481 val = s->regs.default_sc_bottom_right; 482 break; 483 default: 484 break; 485 } 486 if (addr < CUR_OFFSET || addr > CUR_CLR1 || ATI_DEBUG_HW_CURSOR) { 487 trace_ati_mm_read(size, addr, ati_reg_name(addr & ~3ULL), val); 488 } 489 return val; 490 } 491 492 static inline void ati_reg_write_offs(uint32_t *reg, int offs, 493 uint64_t data, unsigned int size) 494 { 495 if (offs == 0 && size == 4) { 496 *reg = data; 497 } else { 498 *reg = deposit32(*reg, offs * BITS_PER_BYTE, size * BITS_PER_BYTE, 499 data); 500 } 501 } 502 503 static void ati_mm_write(void *opaque, hwaddr addr, 504 uint64_t data, unsigned int size) 505 { 506 ATIVGAState *s = opaque; 507 508 if (addr < CUR_OFFSET || addr > CUR_CLR1 || ATI_DEBUG_HW_CURSOR) { 509 trace_ati_mm_write(size, addr, ati_reg_name(addr & ~3ULL), data); 510 } 511 switch (addr) { 512 case MM_INDEX: 513 s->regs.mm_index = data; 514 break; 515 case MM_DATA ... MM_DATA + 3: 516 /* indexed access to regs or memory */ 517 if (s->regs.mm_index & BIT(31)) { 518 uint32_t idx = s->regs.mm_index & ~BIT(31); 519 if (idx <= s->vga.vram_size - size) { 520 stn_le_p(s->vga.vram_ptr + idx, size, data); 521 } 522 } else { 523 ati_mm_write(s, s->regs.mm_index + addr - MM_DATA, data, size); 524 } 525 break; 526 case BIOS_0_SCRATCH ... BUS_CNTL - 1: 527 { 528 int i = (addr - BIOS_0_SCRATCH) / 4; 529 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF && i > 3) { 530 break; 531 } 532 ati_reg_write_offs(&s->regs.bios_scratch[i], 533 addr - (BIOS_0_SCRATCH + i * 4), data, size); 534 break; 535 } 536 case GEN_INT_CNTL: 537 s->regs.gen_int_cntl = data; 538 if (data & CRTC_VBLANK_INT) { 539 ati_vga_vblank_irq(s); 540 } else { 541 timer_del(&s->vblank_timer); 542 ati_vga_update_irq(s); 543 } 544 break; 545 case GEN_INT_STATUS: 546 data &= (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF ? 547 0x000f040fUL : 0xfc080effUL); 548 s->regs.gen_int_status &= ~data; 549 ati_vga_update_irq(s); 550 break; 551 case CRTC_GEN_CNTL ... CRTC_GEN_CNTL + 3: 552 { 553 uint32_t val = s->regs.crtc_gen_cntl; 554 ati_reg_write_offs(&s->regs.crtc_gen_cntl, 555 addr - CRTC_GEN_CNTL, data, size); 556 if ((val & CRTC2_CUR_EN) != (s->regs.crtc_gen_cntl & CRTC2_CUR_EN)) { 557 if (s->cursor_guest_mode) { 558 s->vga.force_shadow = !!(s->regs.crtc_gen_cntl & CRTC2_CUR_EN); 559 } else { 560 if (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) { 561 ati_cursor_define(s); 562 } 563 dpy_mouse_set(s->vga.con, s->regs.cur_hv_pos >> 16, 564 s->regs.cur_hv_pos & 0xffff, 565 (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) != 0); 566 } 567 } 568 if ((val & (CRTC2_EXT_DISP_EN | CRTC2_EN)) != 569 (s->regs.crtc_gen_cntl & (CRTC2_EXT_DISP_EN | CRTC2_EN))) { 570 ati_vga_switch_mode(s); 571 } 572 break; 573 } 574 case CRTC_EXT_CNTL ... CRTC_EXT_CNTL + 3: 575 { 576 uint32_t val = s->regs.crtc_ext_cntl; 577 ati_reg_write_offs(&s->regs.crtc_ext_cntl, 578 addr - CRTC_EXT_CNTL, data, size); 579 if (s->regs.crtc_ext_cntl & CRT_CRTC_DISPLAY_DIS) { 580 DPRINTF("Display disabled\n"); 581 s->vga.ar_index &= ~BIT(5); 582 } else { 583 DPRINTF("Display enabled\n"); 584 s->vga.ar_index |= BIT(5); 585 ati_vga_switch_mode(s); 586 } 587 if ((val & CRT_CRTC_DISPLAY_DIS) != 588 (s->regs.crtc_ext_cntl & CRT_CRTC_DISPLAY_DIS)) { 589 ati_vga_switch_mode(s); 590 } 591 break; 592 } 593 case DAC_CNTL: 594 s->regs.dac_cntl = data & 0xffffe3ff; 595 s->vga.dac_8bit = !!(data & DAC_8BIT_EN); 596 break; 597 case GPIO_VGA_DDC: 598 if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) { 599 /* FIXME: Maybe add a property to select VGA or DVI port? */ 600 } 601 break; 602 case GPIO_DVI_DDC: 603 if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) { 604 s->regs.gpio_dvi_ddc = ati_i2c(&s->bbi2c, data, 0); 605 } 606 break; 607 case GPIO_MONID ... GPIO_MONID + 3: 608 /* FIXME What does Radeon have here? */ 609 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) { 610 ati_reg_write_offs(&s->regs.gpio_monid, 611 addr - GPIO_MONID, data, size); 612 /* 613 * Rage128p accesses DDC used to get EDID via these bits. 614 * Because some drivers access this via multiple byte writes 615 * we have to be careful when we send bits to avoid spurious 616 * changes in bitbang_i2c state. So only do it when mask is set 617 * and either the enable bits are changed or output bits changed 618 * while enabled. 619 */ 620 if ((s->regs.gpio_monid & BIT(25)) && 621 ((addr <= GPIO_MONID + 2 && addr + size > GPIO_MONID + 2) || 622 (addr == GPIO_MONID && (s->regs.gpio_monid & 0x60000)))) { 623 s->regs.gpio_monid = ati_i2c(&s->bbi2c, s->regs.gpio_monid, 1); 624 } 625 } 626 break; 627 case PALETTE_INDEX ... PALETTE_INDEX + 3: 628 if (size == 4) { 629 vga_ioport_write(&s->vga, VGA_PEL_IR, (data >> 16) & 0xff); 630 vga_ioport_write(&s->vga, VGA_PEL_IW, data & 0xff); 631 } else { 632 if (addr == PALETTE_INDEX) { 633 vga_ioport_write(&s->vga, VGA_PEL_IW, data & 0xff); 634 } else { 635 vga_ioport_write(&s->vga, VGA_PEL_IR, data & 0xff); 636 } 637 } 638 break; 639 case PALETTE_DATA ... PALETTE_DATA + 3: 640 data <<= addr - PALETTE_DATA; 641 data = bswap32(data) >> 8; 642 vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff); 643 data >>= 8; 644 vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff); 645 data >>= 8; 646 vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff); 647 break; 648 case CNFG_CNTL: 649 s->regs.config_cntl = data; 650 break; 651 case CRTC_H_TOTAL_DISP: 652 s->regs.crtc_h_total_disp = data & 0x07ff07ff; 653 break; 654 case CRTC_H_SYNC_STRT_WID: 655 s->regs.crtc_h_sync_strt_wid = data & 0x17bf1fff; 656 break; 657 case CRTC_V_TOTAL_DISP: 658 s->regs.crtc_v_total_disp = data & 0x0fff0fff; 659 break; 660 case CRTC_V_SYNC_STRT_WID: 661 s->regs.crtc_v_sync_strt_wid = data & 0x9f0fff; 662 break; 663 case CRTC_OFFSET: 664 s->regs.crtc_offset = data & 0xc7ffffff; 665 break; 666 case CRTC_OFFSET_CNTL: 667 s->regs.crtc_offset_cntl = data; /* FIXME */ 668 break; 669 case CRTC_PITCH: 670 s->regs.crtc_pitch = data & 0x07ff07ff; 671 break; 672 case 0xf00 ... 0xfff: 673 /* read-only copy of PCI config space so ignore writes */ 674 break; 675 case CUR_OFFSET: 676 if (s->regs.cur_offset != (data & 0x87fffff0)) { 677 s->regs.cur_offset = data & 0x87fffff0; 678 ati_cursor_define(s); 679 } 680 break; 681 case CUR_HORZ_VERT_POSN: 682 s->regs.cur_hv_pos = data & 0x3fff0fff; 683 if (data & BIT(31)) { 684 s->regs.cur_offset |= data & BIT(31); 685 } else if (s->regs.cur_offset & BIT(31)) { 686 s->regs.cur_offset &= ~BIT(31); 687 ati_cursor_define(s); 688 } 689 if (!s->cursor_guest_mode && 690 (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) && !(data & BIT(31))) { 691 dpy_mouse_set(s->vga.con, s->regs.cur_hv_pos >> 16, 692 s->regs.cur_hv_pos & 0xffff, 1); 693 } 694 break; 695 case CUR_HORZ_VERT_OFF: 696 s->regs.cur_hv_offs = data & 0x3f003f; 697 if (data & BIT(31)) { 698 s->regs.cur_offset |= data & BIT(31); 699 } else if (s->regs.cur_offset & BIT(31)) { 700 s->regs.cur_offset &= ~BIT(31); 701 ati_cursor_define(s); 702 } 703 break; 704 case CUR_CLR0: 705 if (s->regs.cur_color0 != (data & 0xffffff)) { 706 s->regs.cur_color0 = data & 0xffffff; 707 ati_cursor_define(s); 708 } 709 break; 710 case CUR_CLR1: 711 /* 712 * Update cursor unconditionally here because some clients set up 713 * other registers before actually writing cursor data to memory at 714 * offset so we would miss cursor change unless always updating here 715 */ 716 s->regs.cur_color1 = data & 0xffffff; 717 ati_cursor_define(s); 718 break; 719 case DST_OFFSET: 720 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) { 721 s->regs.dst_offset = data & 0xfffffff0; 722 } else { 723 s->regs.dst_offset = data & 0xfffffc00; 724 } 725 break; 726 case DST_PITCH: 727 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) { 728 s->regs.dst_pitch = data & 0x3fff; 729 s->regs.dst_tile = (data >> 16) & 1; 730 } else { 731 s->regs.dst_pitch = data & 0x3ff0; 732 } 733 break; 734 case DST_TILE: 735 if (s->dev_id == PCI_DEVICE_ID_ATI_RADEON_QY) { 736 s->regs.dst_tile = data & 3; 737 } 738 break; 739 case DST_WIDTH: 740 s->regs.dst_width = data & 0x3fff; 741 ati_2d_blt(s); 742 break; 743 case DST_HEIGHT: 744 s->regs.dst_height = data & 0x3fff; 745 break; 746 case SRC_X: 747 s->regs.src_x = data & 0x3fff; 748 break; 749 case SRC_Y: 750 s->regs.src_y = data & 0x3fff; 751 break; 752 case DST_X: 753 s->regs.dst_x = data & 0x3fff; 754 break; 755 case DST_Y: 756 s->regs.dst_y = data & 0x3fff; 757 break; 758 case SRC_PITCH_OFFSET: 759 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) { 760 s->regs.src_offset = (data & 0x1fffff) << 5; 761 s->regs.src_pitch = (data & 0x7fe00000) >> 21; 762 s->regs.src_tile = data >> 31; 763 } else { 764 s->regs.src_offset = (data & 0x3fffff) << 10; 765 s->regs.src_pitch = (data & 0x3fc00000) >> 16; 766 s->regs.src_tile = (data >> 30) & 1; 767 } 768 break; 769 case DST_PITCH_OFFSET: 770 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) { 771 s->regs.dst_offset = (data & 0x1fffff) << 5; 772 s->regs.dst_pitch = (data & 0x7fe00000) >> 21; 773 s->regs.dst_tile = data >> 31; 774 } else { 775 s->regs.dst_offset = (data & 0x3fffff) << 10; 776 s->regs.dst_pitch = (data & 0x3fc00000) >> 16; 777 s->regs.dst_tile = data >> 30; 778 } 779 break; 780 case SRC_Y_X: 781 s->regs.src_x = data & 0x3fff; 782 s->regs.src_y = (data >> 16) & 0x3fff; 783 break; 784 case DST_Y_X: 785 s->regs.dst_x = data & 0x3fff; 786 s->regs.dst_y = (data >> 16) & 0x3fff; 787 break; 788 case DST_HEIGHT_WIDTH: 789 s->regs.dst_width = data & 0x3fff; 790 s->regs.dst_height = (data >> 16) & 0x3fff; 791 ati_2d_blt(s); 792 break; 793 case DP_GUI_MASTER_CNTL: 794 s->regs.dp_gui_master_cntl = data & 0xf800000f; 795 s->regs.dp_datatype = (data & 0x0f00) >> 8 | (data & 0x30f0) << 4 | 796 (data & 0x4000) << 16; 797 s->regs.dp_mix = (data & GMC_ROP3_MASK) | (data & 0x7000000) >> 16; 798 break; 799 case DST_WIDTH_X: 800 s->regs.dst_x = data & 0x3fff; 801 s->regs.dst_width = (data >> 16) & 0x3fff; 802 ati_2d_blt(s); 803 break; 804 case SRC_X_Y: 805 s->regs.src_y = data & 0x3fff; 806 s->regs.src_x = (data >> 16) & 0x3fff; 807 break; 808 case DST_X_Y: 809 s->regs.dst_y = data & 0x3fff; 810 s->regs.dst_x = (data >> 16) & 0x3fff; 811 break; 812 case DST_WIDTH_HEIGHT: 813 s->regs.dst_height = data & 0x3fff; 814 s->regs.dst_width = (data >> 16) & 0x3fff; 815 ati_2d_blt(s); 816 break; 817 case DST_HEIGHT_Y: 818 s->regs.dst_y = data & 0x3fff; 819 s->regs.dst_height = (data >> 16) & 0x3fff; 820 break; 821 case SRC_OFFSET: 822 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) { 823 s->regs.src_offset = data & 0xfffffff0; 824 } else { 825 s->regs.src_offset = data & 0xfffffc00; 826 } 827 break; 828 case SRC_PITCH: 829 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) { 830 s->regs.src_pitch = data & 0x3fff; 831 s->regs.src_tile = (data >> 16) & 1; 832 } else { 833 s->regs.src_pitch = data & 0x3ff0; 834 } 835 break; 836 case DP_BRUSH_BKGD_CLR: 837 s->regs.dp_brush_bkgd_clr = data; 838 break; 839 case DP_BRUSH_FRGD_CLR: 840 s->regs.dp_brush_frgd_clr = data; 841 break; 842 case DP_CNTL: 843 s->regs.dp_cntl = data; 844 break; 845 case DP_DATATYPE: 846 s->regs.dp_datatype = data & 0xe0070f0f; 847 break; 848 case DP_MIX: 849 s->regs.dp_mix = data & 0x00ff0700; 850 break; 851 case DP_WRITE_MASK: 852 s->regs.dp_write_mask = data; 853 break; 854 case DEFAULT_OFFSET: 855 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) { 856 s->regs.default_offset = data & 0xfffffff0; 857 } else { 858 /* Radeon has DEFAULT_PITCH_OFFSET here like DST_PITCH_OFFSET */ 859 s->regs.default_offset = (data & 0x3fffff) << 10; 860 s->regs.default_pitch = (data & 0x3fc00000) >> 16; 861 s->regs.default_tile = data >> 30; 862 } 863 break; 864 case DEFAULT_PITCH: 865 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) { 866 s->regs.default_pitch = data & 0x3fff; 867 s->regs.default_tile = (data >> 16) & 1; 868 } 869 break; 870 case DEFAULT_SC_BOTTOM_RIGHT: 871 s->regs.default_sc_bottom_right = data & 0x3fff3fff; 872 break; 873 default: 874 break; 875 } 876 } 877 878 static const MemoryRegionOps ati_mm_ops = { 879 .read = ati_mm_read, 880 .write = ati_mm_write, 881 .endianness = DEVICE_LITTLE_ENDIAN, 882 }; 883 884 static void ati_vga_realize(PCIDevice *dev, Error **errp) 885 { 886 ATIVGAState *s = ATI_VGA(dev); 887 VGACommonState *vga = &s->vga; 888 889 if (s->model) { 890 int i; 891 for (i = 0; i < ARRAY_SIZE(ati_model_aliases); i++) { 892 if (!strcmp(s->model, ati_model_aliases[i].name)) { 893 s->dev_id = ati_model_aliases[i].dev_id; 894 break; 895 } 896 } 897 if (i >= ARRAY_SIZE(ati_model_aliases)) { 898 warn_report("Unknown ATI VGA model name, " 899 "using default rage128p"); 900 } 901 } 902 if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF && 903 s->dev_id != PCI_DEVICE_ID_ATI_RADEON_QY) { 904 error_setg(errp, "Unknown ATI VGA device id, " 905 "only 0x5046 and 0x5159 are supported"); 906 return; 907 } 908 pci_set_word(dev->config + PCI_DEVICE_ID, s->dev_id); 909 910 if (s->dev_id == PCI_DEVICE_ID_ATI_RADEON_QY && 911 s->vga.vram_size_mb < 16) { 912 warn_report("Too small video memory for device id"); 913 s->vga.vram_size_mb = 16; 914 } 915 916 /* init vga bits */ 917 vga_common_init(vga, OBJECT(s)); 918 vga_init(vga, OBJECT(s), pci_address_space(dev), 919 pci_address_space_io(dev), true); 920 vga->con = graphic_console_init(DEVICE(s), 0, s->vga.hw_ops, &s->vga); 921 if (s->cursor_guest_mode) { 922 vga->cursor_invalidate = ati_cursor_invalidate; 923 vga->cursor_draw_line = ati_cursor_draw_line; 924 } 925 926 /* ddc, edid */ 927 I2CBus *i2cbus = i2c_init_bus(DEVICE(s), "ati-vga.ddc"); 928 bitbang_i2c_init(&s->bbi2c, i2cbus); 929 I2CSlave *i2cddc = I2C_SLAVE(qdev_create(BUS(i2cbus), TYPE_I2CDDC)); 930 i2c_set_slave_address(i2cddc, 0x50); 931 932 /* mmio register space */ 933 memory_region_init_io(&s->mm, OBJECT(s), &ati_mm_ops, s, 934 "ati.mmregs", 0x4000); 935 /* io space is alias to beginning of mmregs */ 936 memory_region_init_alias(&s->io, OBJECT(s), "ati.io", &s->mm, 0, 0x100); 937 938 pci_register_bar(dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &vga->vram); 939 pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io); 940 pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mm); 941 942 /* most interrupts are not yet emulated but MacOS needs at least VBlank */ 943 dev->config[PCI_INTERRUPT_PIN] = 1; 944 timer_init_ns(&s->vblank_timer, QEMU_CLOCK_VIRTUAL, ati_vga_vblank_irq, s); 945 } 946 947 static void ati_vga_reset(DeviceState *dev) 948 { 949 ATIVGAState *s = ATI_VGA(dev); 950 951 timer_del(&s->vblank_timer); 952 ati_vga_update_irq(s); 953 954 /* reset vga */ 955 vga_common_reset(&s->vga); 956 s->mode = VGA_MODE; 957 } 958 959 static void ati_vga_exit(PCIDevice *dev) 960 { 961 ATIVGAState *s = ATI_VGA(dev); 962 963 timer_del(&s->vblank_timer); 964 graphic_console_close(s->vga.con); 965 } 966 967 static Property ati_vga_properties[] = { 968 DEFINE_PROP_UINT32("vgamem_mb", ATIVGAState, vga.vram_size_mb, 16), 969 DEFINE_PROP_STRING("model", ATIVGAState, model), 970 DEFINE_PROP_UINT16("x-device-id", ATIVGAState, dev_id, 971 PCI_DEVICE_ID_ATI_RAGE128_PF), 972 DEFINE_PROP_BOOL("guest_hwcursor", ATIVGAState, cursor_guest_mode, false), 973 DEFINE_PROP_END_OF_LIST() 974 }; 975 976 static void ati_vga_class_init(ObjectClass *klass, void *data) 977 { 978 DeviceClass *dc = DEVICE_CLASS(klass); 979 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 980 981 dc->reset = ati_vga_reset; 982 dc->props = ati_vga_properties; 983 dc->hotpluggable = false; 984 set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); 985 986 k->class_id = PCI_CLASS_DISPLAY_VGA; 987 k->vendor_id = PCI_VENDOR_ID_ATI; 988 k->device_id = PCI_DEVICE_ID_ATI_RAGE128_PF; 989 k->romfile = "vgabios-ati.bin"; 990 k->realize = ati_vga_realize; 991 k->exit = ati_vga_exit; 992 } 993 994 static const TypeInfo ati_vga_info = { 995 .name = TYPE_ATI_VGA, 996 .parent = TYPE_PCI_DEVICE, 997 .instance_size = sizeof(ATIVGAState), 998 .class_init = ati_vga_class_init, 999 .interfaces = (InterfaceInfo[]) { 1000 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 1001 { }, 1002 }, 1003 }; 1004 1005 static void ati_vga_register_types(void) 1006 { 1007 type_register_static(&ati_vga_info); 1008 } 1009 1010 type_init(ati_vga_register_types) 1011