master
c 1,231 lines 40.5 KB
Raw
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 "vga-access.h"
23 #include "hw/core/qdev-properties.h"
24 #include "vga_regs.h"
25 #include "qemu/bswap.h"
26 #include "qemu/log.h"
27 #include "qemu/module.h"
28 #include "qemu/error-report.h"
29 #include "qapi/error.h"
30 #include "ui/console.h"
31 #include "trace.h"
32
33 #define ATI_DEBUG_HW_CURSOR 0
34
35 #ifdef CONFIG_PIXMAN
36 #define DEFAULT_X_PIXMAN 3
37 #else
38 #define DEFAULT_X_PIXMAN 0
39 #endif
40
41 static const struct {
42 const char *name;
43 uint16_t dev_id;
44 } ati_model_aliases[] = {
45 { "rage128p", PCI_DEVICE_ID_ATI_RAGE128_PF },
46 { "rv100", PCI_DEVICE_ID_ATI_RADEON_QY },
47 };
48
49 enum { VGA_MODE, EXT_MODE };
50
51 static void ati_vga_set_offset(VGACommonState *vga, uint32_t offs)
52 {
53 int bypp = DIV_ROUND_UP(vga->vbe_regs[VBE_DISPI_INDEX_BPP], BITS_PER_BYTE);
54
55 if (!bypp ||
56 vga->vbe_regs[VBE_DISPI_INDEX_YRES] *
57 vga->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * bypp + offs >
58 vga->vbe_size) {
59 return;
60 }
61 vga->vbe_start_addr = offs / 4;
62 }
63
64 static void ati_vga_switch_mode(ATIVGAState *s)
65 {
66 DPRINTF("%d -> %d\n",
67 s->mode, !!(s->regs.crtc_gen_cntl & CRTC2_EXT_DISP_EN));
68 if (s->regs.crtc_gen_cntl & CRTC2_EXT_DISP_EN) {
69 /* Extended mode enabled */
70 s->mode = EXT_MODE;
71 if (s->regs.crtc_gen_cntl & CRTC2_EN) {
72 /* CRT controller enabled, use CRTC values */
73 /* FIXME Should these be the same as VGA CRTC regs? */
74 uint32_t offs = s->regs.crtc_offset & 0x07ffffff;
75 int stride = (s->regs.crtc_pitch & 0x7ff) * 8;
76 int bpp = 0;
77 int h, v;
78
79 if (s->regs.crtc_h_total_disp == 0) {
80 s->regs.crtc_h_total_disp = ((640 / 8) - 1) << 16;
81 }
82 if (s->regs.crtc_v_total_disp == 0) {
83 s->regs.crtc_v_total_disp = (480 - 1) << 16;
84 }
85 h = ((s->regs.crtc_h_total_disp >> 16) + 1) * 8;
86 v = (s->regs.crtc_v_total_disp >> 16) + 1;
87 switch (s->regs.crtc_gen_cntl & CRTC_PIX_WIDTH_MASK) {
88 case CRTC_PIX_WIDTH_4BPP:
89 bpp = 4;
90 break;
91 case CRTC_PIX_WIDTH_8BPP:
92 bpp = 8;
93 break;
94 case CRTC_PIX_WIDTH_15BPP:
95 bpp = 15;
96 break;
97 case CRTC_PIX_WIDTH_16BPP:
98 bpp = 16;
99 break;
100 case CRTC_PIX_WIDTH_24BPP:
101 bpp = 24;
102 break;
103 case CRTC_PIX_WIDTH_32BPP:
104 bpp = 32;
105 break;
106 default:
107 qemu_log_mask(LOG_UNIMP, "Unsupported bpp value\n");
108 return;
109 }
110 DPRINTF("Switching to %dx%d %d %d @ %x\n", h, v, stride, bpp, offs);
111 vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE);
112 vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_DISABLED);
113 s->vga.big_endian_fb = (s->regs.config_cntl & APER_0_ENDIAN ||
114 s->regs.config_cntl & APER_1_ENDIAN ?
115 true : false);
116 /* reset VBE regs then set up mode */
117 s->vga.vbe_regs[VBE_DISPI_INDEX_XRES] = h;
118 s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] = v;
119 s->vga.vbe_regs[VBE_DISPI_INDEX_BPP] = bpp;
120 /* enable mode via ioport so it updates vga regs */
121 vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE);
122 vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_ENABLED |
123 VBE_DISPI_LFB_ENABLED | VBE_DISPI_NOCLEARMEM |
124 (s->regs.dac_cntl & DAC_8BIT_EN ? VBE_DISPI_8BIT_DAC : 0));
125 /* now set offset and stride because enable resets these */
126 if (stride) {
127 vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_VIRT_WIDTH);
128 vbe_ioport_write_data(&s->vga, 0, stride);
129 }
130 ati_vga_set_offset(&s->vga, offs);
131 }
132 } else {
133 /* VGA mode enabled */
134 s->mode = VGA_MODE;
135 vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE);
136 vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_DISABLED);
137 }
138 }
139
140 /* Used by host side hardware cursor */
141 static void ati_cursor_define(ATIVGAState *s)
142 {
143 uint64_t data[128];
144 uint32_t srcoff;
145
146 if ((s->regs.cur_offset & BIT(31)) || s->cursor_guest_mode) {
147 return; /* Do not update cursor if locked or rendered by guest */
148 }
149 /* FIXME handle cur_hv_offs correctly */
150 srcoff = (s->regs.cur_offset & 0x07fffff0) - (s->regs.cur_hv_offs >> 16) -
151 (s->regs.cur_hv_offs & 0xffff) * 16;
152 if (srcoff > s->vga.vram_size - 64 * 16) {
153 return;
154 }
155 for (int i = 0; i < 64; i++, srcoff += 16) {
156 data[i] = ldq_le_p(&s->vga.vram_ptr[srcoff]);
157 data[i + 64] = ldq_le_p(&s->vga.vram_ptr[srcoff + 8]);
158 }
159 if (!s->cursor) {
160 s->cursor = cursor_alloc(64, 64);
161 }
162 cursor_set_mono(s->cursor, s->regs.cur_color1, s->regs.cur_color0,
163 (uint8_t *)&data[64], 1, (uint8_t *)&data[0]);
164 qemu_console_set_cursor(s->vga.con, s->cursor);
165 }
166
167 /* Alternatively support guest rendered hardware cursor */
168 static void ati_cursor_invalidate(VGACommonState *vga)
169 {
170 ATIVGAState *s = container_of(vga, ATIVGAState, vga);
171 int size = (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) ? 64 : 0;
172
173 if (s->regs.cur_offset & BIT(31)) {
174 return; /* Do not update cursor if locked */
175 }
176 if (s->cursor_size != size ||
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 & 0x07fffff0) -
180 (s->regs.cur_hv_offs >> 16) -
181 (s->regs.cur_hv_offs & 0xffff) * 16) {
182 /* Remove old cursor then update and show new one if needed */
183 vga_invalidate_scanlines(vga, vga->hw_cursor_y, vga->hw_cursor_y + 63);
184 vga->hw_cursor_x = s->regs.cur_hv_pos >> 16;
185 vga->hw_cursor_y = s->regs.cur_hv_pos & 0xffff;
186 s->cursor_offset = (s->regs.cur_offset & 0x07fffff0) -
187 (s->regs.cur_hv_offs >> 16) -
188 (s->regs.cur_hv_offs & 0xffff) * 16;
189 s->cursor_size = size;
190 if (size) {
191 vga_invalidate_scanlines(vga,
192 vga->hw_cursor_y, vga->hw_cursor_y + 63);
193 }
194 }
195 }
196
197 static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
198 {
199 ATIVGAState *s = container_of(vga, ATIVGAState, vga);
200 uint32_t h, srcoff, color;
201 uint64_t abits, xbits, mask;
202 uint32_t *dp = (uint32_t *)d;
203
204 if (!(s->regs.crtc_gen_cntl & CRTC2_CUR_EN) ||
205 scr_y < vga->hw_cursor_y || scr_y >= vga->hw_cursor_y + 64 ||
206 scr_y > s->regs.crtc_v_total_disp >> 16) {
207 return;
208 }
209 /* FIXME handle cur_hv_offs correctly */
210 srcoff = s->cursor_offset + (scr_y - vga->hw_cursor_y) * 16;
211 if (srcoff > s->vga.vram_size - 16) {
212 return;
213 }
214 dp = &dp[vga->hw_cursor_x];
215 h = ((s->regs.crtc_h_total_disp >> 16) + 1) * 8;
216 abits = ldq_be_p(&vga->vram_ptr[srcoff]);
217 xbits = ldq_be_p(&vga->vram_ptr[srcoff + 8]);
218 mask = BIT_ULL(63);
219 for (int i = 0; i < 64; i++, mask >>= 1) {
220 if (vga->hw_cursor_x + i >= h) {
221 return; /* end of screen, don't span to next line */
222 }
223 if (abits & mask) {
224 if (xbits & mask) {
225 color = dp[i] ^ 0xffffffff; /* complement */
226 } else {
227 continue; /* transparent, no change */
228 }
229 } else {
230 color = (xbits & mask ? s->regs.cur_color1 :
231 s->regs.cur_color0) | 0xff000000;
232 }
233 dp[i] = color;
234 }
235 }
236
237 static uint64_t ati_i2c(bitbang_i2c_interface *i2c, uint64_t data, int base)
238 {
239 bool c = (data & BIT(base + 17) ? !!(data & BIT(base + 1)) : 1);
240 bool d = (data & BIT(base + 16) ? !!(data & BIT(base)) : 1);
241
242 bitbang_i2c_set(i2c, BITBANG_I2C_SCL, c);
243 d = bitbang_i2c_set(i2c, BITBANG_I2C_SDA, d);
244
245 data &= ~0xf00ULL;
246 if (c) {
247 data |= BIT(base + 9);
248 }
249 if (d) {
250 data |= BIT(base + 8);
251 }
252 return data;
253 }
254
255 static void ati_vga_update_irq(ATIVGAState *s)
256 {
257 pci_set_irq(&s->dev, !!(s->regs.gen_int_status & s->regs.gen_int_cntl));
258 }
259
260 static void ati_vga_vblank_irq(void *opaque)
261 {
262 ATIVGAState *s = opaque;
263
264 timer_mod(&s->vblank_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
265 NANOSECONDS_PER_SECOND / 60);
266 s->regs.gen_int_status |= CRTC_VBLANK_INT;
267 ati_vga_update_irq(s);
268 }
269
270 static inline uint32_t ati_reg_read_offs(uint32_t reg, int offs,
271 unsigned int size)
272 {
273 if (offs == 0 && size == 4) {
274 return reg;
275 } else {
276 return extract32(reg, offs * BITS_PER_BYTE, size * BITS_PER_BYTE);
277 }
278 }
279
280 static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
281 {
282 ATIVGAState *s = opaque;
283 uint32_t val = 0;
284
285 switch (addr) {
286 case MM_INDEX:
287 val = s->regs.mm_index;
288 break;
289 case MM_DATA ... MM_DATA + 3:
290 /* indexed access to regs or memory */
291 if (s->regs.mm_index & BIT(31)) {
292 uint32_t idx = s->regs.mm_index & ~BIT(31);
293 if (idx <= s->vga.vram_size - size) {
294 val = ldn_le_p(s->vga.vram_ptr + idx, size);
295 }
296 } else if (s->regs.mm_index > MM_DATA + 3) {
297 val = ati_mm_read(s, s->regs.mm_index + addr - MM_DATA, size);
298 } else {
299 qemu_log_mask(LOG_GUEST_ERROR,
300 "ati_mm_read: mm_index too small: %u\n", s->regs.mm_index);
301 }
302 break;
303 case BIOS_0_SCRATCH ... BUS_CNTL - 1:
304 {
305 int i = (addr - BIOS_0_SCRATCH) / 4;
306 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF && i > 3) {
307 break;
308 }
309 val = ati_reg_read_offs(s->regs.bios_scratch[i],
310 addr - (BIOS_0_SCRATCH + i * 4), size);
311 break;
312 }
313 case GEN_INT_CNTL:
314 val = s->regs.gen_int_cntl;
315 break;
316 case GEN_INT_STATUS:
317 val = s->regs.gen_int_status;
318 break;
319 case CRTC_GEN_CNTL ... CRTC_GEN_CNTL + 3:
320 val = ati_reg_read_offs(s->regs.crtc_gen_cntl,
321 addr - CRTC_GEN_CNTL, size);
322 break;
323 case CRTC_EXT_CNTL ... CRTC_EXT_CNTL + 3:
324 val = ati_reg_read_offs(s->regs.crtc_ext_cntl,
325 addr - CRTC_EXT_CNTL, size);
326 break;
327 case DAC_CNTL:
328 val = s->regs.dac_cntl;
329 break;
330 case GPIO_VGA_DDC ... GPIO_VGA_DDC + 3:
331 val = ati_reg_read_offs(s->regs.gpio_vga_ddc,
332 addr - GPIO_VGA_DDC, size);
333 break;
334 case GPIO_DVI_DDC ... GPIO_DVI_DDC + 3:
335 val = ati_reg_read_offs(s->regs.gpio_dvi_ddc,
336 addr - GPIO_DVI_DDC, size);
337 break;
338 case GPIO_MONID ... GPIO_MONID + 3:
339 val = ati_reg_read_offs(s->regs.gpio_monid,
340 addr - GPIO_MONID, size);
341 break;
342 case PALETTE_INDEX:
343 /* FIXME unaligned access */
344 val = vga_ioport_read(&s->vga, VGA_PEL_IR) << 16;
345 val |= vga_ioport_read(&s->vga, VGA_PEL_IW) & 0xff;
346 break;
347 case PALETTE_DATA:
348 val = vga_ioport_read(&s->vga, VGA_PEL_D);
349 break;
350 case PALETTE_30_DATA:
351 val = s->regs.palette[vga_ioport_read(&s->vga, VGA_PEL_IR)];
352 break;
353 case CNFG_CNTL:
354 val = s->regs.config_cntl;
355 break;
356 case CNFG_MEMSIZE:
357 val = s->vga.vram_size;
358 break;
359 case CONFIG_APER_0_BASE:
360 case CONFIG_APER_1_BASE:
361 val = pci_default_read_config(&s->dev,
362 PCI_BASE_ADDRESS_0, size) & 0xfffffff0;
363 break;
364 case CONFIG_APER_SIZE:
365 val = memory_region_size(&s->linear_aper) / 2;
366 break;
367 case CONFIG_REG_1_BASE:
368 val = pci_default_read_config(&s->dev,
369 PCI_BASE_ADDRESS_2, size) & 0xfffffff0;
370 break;
371 case CONFIG_REG_APER_SIZE:
372 val = memory_region_size(&s->mm) / 2;
373 break;
374 case HOST_PATH_CNTL:
375 val = BIT(23); /* Radeon HDP_APER_CNTL */
376 break;
377 case MC_STATUS:
378 val = 5;
379 break;
380 case MEM_SDRAM_MODE_REG:
381 if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) {
382 val = BIT(28) | BIT(20);
383 }
384 break;
385 case RBBM_STATUS:
386 case GUI_STAT:
387 val = 64; /* free CMDFIFO entries */
388 break;
389 case CRTC_H_TOTAL_DISP:
390 val = s->regs.crtc_h_total_disp;
391 break;
392 case CRTC_H_SYNC_STRT_WID:
393 val = s->regs.crtc_h_sync_strt_wid;
394 break;
395 case CRTC_V_TOTAL_DISP:
396 val = s->regs.crtc_v_total_disp;
397 break;
398 case CRTC_V_SYNC_STRT_WID:
399 val = s->regs.crtc_v_sync_strt_wid;
400 break;
401 case CRTC_OFFSET:
402 val = s->regs.crtc_offset;
403 break;
404 case CRTC_OFFSET_CNTL:
405 val = s->regs.crtc_offset_cntl;
406 break;
407 case CRTC_PITCH:
408 val = s->regs.crtc_pitch;
409 break;
410 case 0xf00 ... 0xfff:
411 val = pci_default_read_config(&s->dev, addr - 0xf00, size);
412 break;
413 case CUR_OFFSET ... CUR_OFFSET + 3:
414 val = ati_reg_read_offs(s->regs.cur_offset, addr - CUR_OFFSET, size);
415 break;
416 case CUR_HORZ_VERT_POSN ... CUR_HORZ_VERT_POSN + 3:
417 val = ati_reg_read_offs(s->regs.cur_hv_pos,
418 addr - CUR_HORZ_VERT_POSN, size);
419 if (addr + size > CUR_HORZ_VERT_POSN + 3) {
420 val |= (s->regs.cur_offset & BIT(31)) >> (4 - size);
421 }
422 break;
423 case CUR_HORZ_VERT_OFF ... CUR_HORZ_VERT_OFF + 3:
424 val = ati_reg_read_offs(s->regs.cur_hv_offs,
425 addr - CUR_HORZ_VERT_OFF, size);
426 if (addr + size > CUR_HORZ_VERT_OFF + 3) {
427 val |= (s->regs.cur_offset & BIT(31)) >> (4 - size);
428 }
429 break;
430 case CUR_CLR0 ... CUR_CLR0 + 3:
431 val = ati_reg_read_offs(s->regs.cur_color0, addr - CUR_CLR0, size);
432 break;
433 case CUR_CLR1 ... CUR_CLR1 + 3:
434 val = ati_reg_read_offs(s->regs.cur_color1, addr - CUR_CLR1, size);
435 break;
436 case DST_OFFSET:
437 val = s->regs.dst_offset;
438 break;
439 case DST_PITCH:
440 val = s->regs.dst_pitch;
441 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
442 val |= s->regs.dst_tile << 16;
443 }
444 break;
445 case DST_WIDTH:
446 val = s->regs.dst_width;
447 break;
448 case DST_HEIGHT:
449 val = s->regs.dst_height;
450 break;
451 case SRC_X:
452 val = s->regs.src_x;
453 break;
454 case SRC_Y:
455 val = s->regs.src_y;
456 break;
457 case DST_X:
458 val = s->regs.dst_x;
459 break;
460 case DST_Y:
461 val = s->regs.dst_y;
462 break;
463 case DP_GUI_MASTER_CNTL:
464 /* DP_GUI_MASTER_CNTL aliases fields from DP_MIX and DP_DATATYPE */
465 val = s->regs.dp_gui_master_cntl |
466 ((s->regs.dp_datatype & DP_BRUSH_DATATYPE) >> 4) |
467 ((s->regs.dp_datatype & DP_DST_DATATYPE) << 8) |
468 ((s->regs.dp_datatype & DP_SRC_DATATYPE) >> 4) |
469 (s->regs.dp_mix & DP_ROP3) |
470 ((s->regs.dp_mix & DP_SRC_SOURCE) << 16);
471 break;
472 case SRC_OFFSET:
473 val = s->regs.src_offset;
474 break;
475 case SRC_PITCH:
476 val = s->regs.src_pitch;
477 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
478 val |= s->regs.src_tile << 16;
479 }
480 break;
481 case DP_BRUSH_BKGD_CLR:
482 val = s->regs.dp_brush_bkgd_clr;
483 break;
484 case DP_BRUSH_FRGD_CLR:
485 val = s->regs.dp_brush_frgd_clr;
486 break;
487 case DP_SRC_FRGD_CLR:
488 val = s->regs.dp_src_frgd_clr;
489 break;
490 case DP_SRC_BKGD_CLR:
491 val = s->regs.dp_src_bkgd_clr;
492 break;
493 case DP_CNTL:
494 val = s->regs.dp_cntl;
495 break;
496 case DP_DATATYPE:
497 val = s->regs.dp_datatype;
498 break;
499 case DP_MIX:
500 val = s->regs.dp_mix;
501 break;
502 case DP_WRITE_MASK:
503 val = s->regs.dp_write_mask;
504 break;
505 case DEFAULT_OFFSET:
506 val = s->regs.default_offset;
507 if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) {
508 val >>= 10;
509 val |= s->regs.default_pitch << 16;
510 val |= s->regs.default_tile << 30;
511 }
512 break;
513 case DEFAULT_PITCH:
514 val = s->regs.default_pitch;
515 val |= s->regs.default_tile << 16;
516 break;
517 case DEFAULT_SC_BOTTOM_RIGHT:
518 val = s->regs.default_sc_right;
519 val |= s->regs.default_sc_bottom << 16;
520 break;
521 case SC_TOP:
522 val = s->regs.sc_top;
523 break;
524 case SC_LEFT:
525 val = s->regs.sc_left;
526 break;
527 case SC_BOTTOM:
528 val = s->regs.sc_bottom;
529 break;
530 case SC_RIGHT:
531 val = s->regs.sc_right;
532 break;
533 case SRC_SC_BOTTOM:
534 val = s->regs.src_sc_bottom;
535 break;
536 case SRC_SC_RIGHT:
537 val = s->regs.src_sc_right;
538 break;
539 case SC_TOP_LEFT:
540 case SC_BOTTOM_RIGHT:
541 case SRC_SC_BOTTOM_RIGHT:
542 qemu_log_mask(LOG_GUEST_ERROR,
543 "Read from write-only register 0x%x\n", (unsigned)addr);
544 break;
545 default:
546 break;
547 }
548 if (addr < CUR_OFFSET || addr > CUR_CLR1 || ATI_DEBUG_HW_CURSOR) {
549 trace_ati_mm_read(size, addr, ati_reg_name(addr & ~3ULL), val);
550 }
551 return val;
552 }
553
554 static inline void ati_reg_write_offs(uint32_t *reg, int offs,
555 uint64_t data, unsigned int size)
556 {
557 if (offs == 0 && size == 4) {
558 *reg = data;
559 } else {
560 *reg = deposit32(*reg, offs * BITS_PER_BYTE, size * BITS_PER_BYTE,
561 data);
562 }
563 }
564
565 static void ati_mm_write(void *opaque, hwaddr addr,
566 uint64_t data, unsigned int size)
567 {
568 ATIVGAState *s = opaque;
569
570 if (addr < CUR_OFFSET || addr > CUR_CLR1 || ATI_DEBUG_HW_CURSOR) {
571 trace_ati_mm_write(size, addr, ati_reg_name(addr & ~3ULL), data);
572 }
573 switch (addr) {
574 case MM_INDEX:
575 s->regs.mm_index = data & ~3;
576 break;
577 case MM_DATA ... MM_DATA + 3:
578 /* indexed access to regs or memory */
579 if (s->regs.mm_index & BIT(31)) {
580 uint32_t idx = s->regs.mm_index & ~BIT(31);
581 if (idx <= s->vga.vram_size - size) {
582 stn_le_p(s->vga.vram_ptr + idx, size, data);
583 }
584 } else if (s->regs.mm_index > MM_DATA + 3) {
585 ati_mm_write(s, s->regs.mm_index + addr - MM_DATA, data, size);
586 } else {
587 qemu_log_mask(LOG_GUEST_ERROR,
588 "ati_mm_write: mm_index too small: %u\n", s->regs.mm_index);
589 }
590 break;
591 case BIOS_0_SCRATCH ... BUS_CNTL - 1:
592 {
593 int i = (addr - BIOS_0_SCRATCH) / 4;
594 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF && i > 3) {
595 break;
596 }
597 ati_reg_write_offs(&s->regs.bios_scratch[i],
598 addr - (BIOS_0_SCRATCH + i * 4), data, size);
599 break;
600 }
601 case GEN_INT_CNTL:
602 s->regs.gen_int_cntl = data;
603 if (data & CRTC_VBLANK_INT) {
604 ati_vga_vblank_irq(s);
605 } else {
606 timer_del(&s->vblank_timer);
607 ati_vga_update_irq(s);
608 }
609 break;
610 case GEN_INT_STATUS:
611 data &= (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF ?
612 0x000f040fUL : 0xfc080effUL);
613 s->regs.gen_int_status &= ~data;
614 ati_vga_update_irq(s);
615 break;
616 case CRTC_GEN_CNTL ... CRTC_GEN_CNTL + 3:
617 {
618 uint32_t val = s->regs.crtc_gen_cntl;
619 ati_reg_write_offs(&s->regs.crtc_gen_cntl,
620 addr - CRTC_GEN_CNTL, data, size);
621 if ((val & CRTC2_CUR_EN) != (s->regs.crtc_gen_cntl & CRTC2_CUR_EN)) {
622 ati_vga_switch_mode(s);
623 if (s->cursor_guest_mode) {
624 s->vga.force_shadow = !!(s->regs.crtc_gen_cntl & CRTC2_CUR_EN);
625 } else {
626 if (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) {
627 ati_cursor_define(s);
628 }
629 qemu_console_set_mouse(s->vga.con, s->regs.cur_hv_pos >> 16,
630 s->regs.cur_hv_pos & 0xffff,
631 (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) != 0);
632 }
633 }
634 if ((val & (CRTC2_EXT_DISP_EN | CRTC2_EN)) !=
635 (s->regs.crtc_gen_cntl & (CRTC2_EXT_DISP_EN | CRTC2_EN))) {
636 ati_vga_switch_mode(s);
637 }
638 break;
639 }
640 case CRTC_EXT_CNTL ... CRTC_EXT_CNTL + 3:
641 {
642 uint32_t val = s->regs.crtc_ext_cntl;
643 ati_reg_write_offs(&s->regs.crtc_ext_cntl,
644 addr - CRTC_EXT_CNTL, data, size);
645 if (s->regs.crtc_ext_cntl & CRT_CRTC_DISPLAY_DIS) {
646 DPRINTF("Display disabled\n");
647 s->vga.ar_index &= ~BIT(5);
648 } else {
649 DPRINTF("Display enabled\n");
650 s->vga.ar_index |= BIT(5);
651 ati_vga_switch_mode(s);
652 }
653 if ((val & CRT_CRTC_DISPLAY_DIS) !=
654 (s->regs.crtc_ext_cntl & CRT_CRTC_DISPLAY_DIS)) {
655 ati_vga_switch_mode(s);
656 }
657 break;
658 }
659 case DAC_CNTL:
660 s->regs.dac_cntl = data & 0xffffe3ff;
661 s->vga.dac_8bit = !!(data & DAC_8BIT_EN);
662 break;
663 /*
664 * GPIO regs for DDC access. Because some drivers access these via
665 * multiple byte writes we have to be careful when we send bits to
666 * avoid spurious changes in bitbang_i2c state. Only do it when either
667 * the enable bits are changed or output bits changed while enabled.
668 */
669 case GPIO_VGA_DDC ... GPIO_VGA_DDC + 3:
670 if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) {
671 /* FIXME: Maybe add a property to select VGA or DVI port? */
672 }
673 break;
674 case GPIO_DVI_DDC ... GPIO_DVI_DDC + 3:
675 if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) {
676 ati_reg_write_offs(&s->regs.gpio_dvi_ddc,
677 addr - GPIO_DVI_DDC, data, size);
678 if ((addr <= GPIO_DVI_DDC + 2 && addr + size > GPIO_DVI_DDC + 2) ||
679 (addr == GPIO_DVI_DDC && (s->regs.gpio_dvi_ddc & 0x30000))) {
680 s->regs.gpio_dvi_ddc = ati_i2c(&s->bbi2c,
681 s->regs.gpio_dvi_ddc, 0);
682 }
683 }
684 break;
685 case GPIO_MONID ... GPIO_MONID + 3:
686 /* FIXME What does Radeon have here? */
687 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
688 /* Rage128p accesses DDC via MONID(1-2) with additional mask bit */
689 ati_reg_write_offs(&s->regs.gpio_monid,
690 addr - GPIO_MONID, data, size);
691 if ((s->regs.gpio_monid & BIT(25)) &&
692 ((addr <= GPIO_MONID + 2 && addr + size > GPIO_MONID + 2) ||
693 (addr == GPIO_MONID && (s->regs.gpio_monid & 0x60000)))) {
694 s->regs.gpio_monid = ati_i2c(&s->bbi2c, s->regs.gpio_monid, 1);
695 }
696 }
697 break;
698 case PALETTE_INDEX ... PALETTE_INDEX + 3:
699 if (size == 4) {
700 vga_ioport_write(&s->vga, VGA_PEL_IR, (data >> 16) & 0xff);
701 vga_ioport_write(&s->vga, VGA_PEL_IW, data & 0xff);
702 } else {
703 if (addr == PALETTE_INDEX) {
704 vga_ioport_write(&s->vga, VGA_PEL_IW, data & 0xff);
705 } else {
706 vga_ioport_write(&s->vga, VGA_PEL_IR, data & 0xff);
707 }
708 }
709 break;
710 case PALETTE_DATA ... PALETTE_DATA + 3:
711 data <<= addr - PALETTE_DATA;
712 data = bswap32(data) >> 8;
713 vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff);
714 data >>= 8;
715 vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff);
716 data >>= 8;
717 vga_ioport_write(&s->vga, VGA_PEL_D, data & 0xff);
718 break;
719 case PALETTE_30_DATA:
720 s->regs.palette[vga_ioport_read(&s->vga, VGA_PEL_IW)] = data;
721 vga_ioport_write(&s->vga, VGA_PEL_D, (data >> 22) & 0xff);
722 vga_ioport_write(&s->vga, VGA_PEL_D, (data >> 12) & 0xff);
723 vga_ioport_write(&s->vga, VGA_PEL_D, (data >> 2) & 0xff);
724 break;
725 case CNFG_CNTL:
726 s->regs.config_cntl = data;
727 break;
728 case CRTC_H_TOTAL_DISP:
729 s->regs.crtc_h_total_disp = data & 0x07ff07ff;
730 break;
731 case CRTC_H_SYNC_STRT_WID:
732 s->regs.crtc_h_sync_strt_wid = data & 0x17bf1fff;
733 break;
734 case CRTC_V_TOTAL_DISP:
735 s->regs.crtc_v_total_disp = data & 0x0fff0fff;
736 break;
737 case CRTC_V_SYNC_STRT_WID:
738 s->regs.crtc_v_sync_strt_wid = data & 0x9f0fff;
739 break;
740 case CRTC_OFFSET:
741 s->regs.crtc_offset = data & 0x87fffff8;
742 ati_vga_set_offset(&s->vga, s->regs.crtc_offset & 0x07ffffff);
743 break;
744 case CRTC_OFFSET_CNTL:
745 s->regs.crtc_offset_cntl = data; /* FIXME */
746 break;
747 case CRTC_PITCH:
748 data &= 0x07ff07ff;
749 if (s->regs.crtc_pitch != data) {
750 s->regs.crtc_pitch = data;
751 ati_vga_switch_mode(s);
752 }
753 break;
754 case 0xf00 ... 0xfff:
755 /* read-only copy of PCI config space so ignore writes */
756 break;
757 case CUR_OFFSET ... CUR_OFFSET + 3:
758 {
759 uint32_t t = s->regs.cur_offset;
760
761 ati_reg_write_offs(&t, addr - CUR_OFFSET, data, size);
762 t &= 0x87fffff0;
763 if (s->regs.cur_offset != t) {
764 s->regs.cur_offset = t;
765 ati_cursor_define(s);
766 }
767 break;
768 }
769 case CUR_HORZ_VERT_POSN ... CUR_HORZ_VERT_POSN + 3:
770 {
771 uint32_t t = s->regs.cur_hv_pos | (s->regs.cur_offset & BIT(31));
772
773 ati_reg_write_offs(&t, addr - CUR_HORZ_VERT_POSN, data, size);
774 s->regs.cur_hv_pos = t & 0x3fff0fff;
775 if (t & BIT(31)) {
776 s->regs.cur_offset |= t & BIT(31);
777 } else if (s->regs.cur_offset & BIT(31)) {
778 s->regs.cur_offset &= ~BIT(31);
779 ati_cursor_define(s);
780 }
781 if (!s->cursor_guest_mode &&
782 (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) && !(t & BIT(31))) {
783 qemu_console_set_mouse(s->vga.con, s->regs.cur_hv_pos >> 16,
784 s->regs.cur_hv_pos & 0xffff, true);
785 }
786 break;
787 }
788 case CUR_HORZ_VERT_OFF:
789 {
790 uint32_t t = s->regs.cur_hv_offs | (s->regs.cur_offset & BIT(31));
791
792 ati_reg_write_offs(&t, addr - CUR_HORZ_VERT_OFF, data, size);
793 s->regs.cur_hv_offs = t & 0x3f003f;
794 if (t & BIT(31)) {
795 s->regs.cur_offset |= t & BIT(31);
796 } else if (s->regs.cur_offset & BIT(31)) {
797 s->regs.cur_offset &= ~BIT(31);
798 ati_cursor_define(s);
799 }
800 break;
801 }
802 case CUR_CLR0 ... CUR_CLR0 + 3:
803 {
804 uint32_t t = s->regs.cur_color0;
805
806 ati_reg_write_offs(&t, addr - CUR_CLR0, data, size);
807 t &= 0xffffff;
808 if (s->regs.cur_color0 != t) {
809 s->regs.cur_color0 = t;
810 ati_cursor_define(s);
811 }
812 break;
813 }
814 case CUR_CLR1 ... CUR_CLR1 + 3:
815 /*
816 * Update cursor unconditionally here because some clients set up
817 * other registers before actually writing cursor data to memory at
818 * offset so we would miss cursor change unless always updating here
819 */
820 ati_reg_write_offs(&s->regs.cur_color1, addr - CUR_CLR1, data, size);
821 s->regs.cur_color1 &= 0xffffff;
822 ati_cursor_define(s);
823 break;
824 case DST_OFFSET:
825 s->regs.dst_offset = data & 0xfffffff0;
826 break;
827 case DST_PITCH:
828 s->regs.dst_pitch = data & 0x3fff;
829 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
830 s->regs.dst_tile = (data >> 16) & 1;
831 }
832 break;
833 case DST_TILE:
834 if (s->dev_id == PCI_DEVICE_ID_ATI_RADEON_QY) {
835 s->regs.dst_tile = data & 3;
836 }
837 break;
838 case DST_WIDTH:
839 s->regs.dst_width = data & 0x3fff;
840 ati_2d_blt(s);
841 break;
842 case DST_HEIGHT:
843 s->regs.dst_height = data & 0x3fff;
844 break;
845 case SRC_X:
846 s->regs.src_x = data & 0x3fff;
847 break;
848 case SRC_Y:
849 s->regs.src_y = data & 0x3fff;
850 break;
851 case DST_X:
852 s->regs.dst_x = data & 0x3fff;
853 break;
854 case DST_Y:
855 s->regs.dst_y = data & 0x3fff;
856 break;
857 case SRC_PITCH_OFFSET:
858 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
859 s->regs.src_offset = (data & 0x1fffff) << 5;
860 s->regs.src_pitch = (data & 0x7fe00000) >> 21;
861 s->regs.src_tile = data >> 31;
862 } else {
863 s->regs.src_offset = (data & 0x3fffff) << 10;
864 s->regs.src_pitch = (data & 0x3fc00000) >> 16;
865 s->regs.src_tile = (data >> 30) & 1;
866 }
867 break;
868 case DST_PITCH_OFFSET:
869 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
870 s->regs.dst_offset = (data & 0x1fffff) << 5;
871 s->regs.dst_pitch = (data & 0x7fe00000) >> 21;
872 s->regs.dst_tile = data >> 31;
873 } else {
874 s->regs.dst_offset = (data & 0x3fffff) << 10;
875 s->regs.dst_pitch = (data & 0x3fc00000) >> 16;
876 s->regs.dst_tile = data >> 30;
877 }
878 break;
879 case SRC_Y_X:
880 s->regs.src_x = data & 0x3fff;
881 s->regs.src_y = (data >> 16) & 0x3fff;
882 break;
883 case DST_Y_X:
884 s->regs.dst_x = data & 0x3fff;
885 s->regs.dst_y = (data >> 16) & 0x3fff;
886 break;
887 case DST_HEIGHT_WIDTH:
888 s->regs.dst_width = data & 0x3fff;
889 s->regs.dst_height = (data >> 16) & 0x3fff;
890 ati_2d_blt(s);
891 break;
892 case DP_GUI_MASTER_CNTL:
893 s->regs.dp_gui_master_cntl = data & 0xf800000f;
894 s->regs.dp_datatype = (data & 0x0f00) >> 8 | (data & 0x30f0) << 4 |
895 (data & 0x4000) << 16;
896 s->regs.dp_mix = (data & GMC_ROP3_MASK) | (data & 0x7000000) >> 16;
897
898 if (!(data & GMC_SRC_PITCH_OFFSET_CNTL)) {
899 s->regs.src_offset = s->regs.default_offset;
900 s->regs.src_pitch = s->regs.default_pitch;
901 }
902 if (!(data & GMC_DST_PITCH_OFFSET_CNTL)) {
903 s->regs.dst_offset = s->regs.default_offset;
904 s->regs.dst_pitch = s->regs.default_pitch;
905 }
906 if (!(data & GMC_SRC_CLIPPING)) {
907 s->regs.src_sc_right = s->regs.default_sc_right;
908 s->regs.src_sc_bottom = s->regs.default_sc_bottom;
909 }
910 if (!(data & GMC_DST_CLIPPING)) {
911 s->regs.sc_top = 0;
912 s->regs.sc_left = 0;
913 s->regs.sc_right = s->regs.default_sc_right;
914 s->regs.sc_bottom = s->regs.default_sc_bottom;
915 }
916 break;
917 case DST_WIDTH_X:
918 s->regs.dst_x = data & 0x3fff;
919 s->regs.dst_width = (data >> 16) & 0x3fff;
920 ati_2d_blt(s);
921 break;
922 case SRC_X_Y:
923 s->regs.src_y = data & 0x3fff;
924 s->regs.src_x = (data >> 16) & 0x3fff;
925 break;
926 case DST_X_Y:
927 s->regs.dst_y = data & 0x3fff;
928 s->regs.dst_x = (data >> 16) & 0x3fff;
929 break;
930 case DST_WIDTH_HEIGHT:
931 s->regs.dst_height = data & 0x3fff;
932 s->regs.dst_width = (data >> 16) & 0x3fff;
933 ati_2d_blt(s);
934 break;
935 case DST_HEIGHT_Y:
936 s->regs.dst_y = data & 0x3fff;
937 s->regs.dst_height = (data >> 16) & 0x3fff;
938 break;
939 case SRC_OFFSET:
940 s->regs.src_offset = data & 0xfffffff0;
941 break;
942 case SRC_PITCH:
943 s->regs.src_pitch = data & 0x3fff;
944 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
945 s->regs.src_tile = (data >> 16) & 1;
946 }
947 break;
948 case DP_BRUSH_BKGD_CLR:
949 s->regs.dp_brush_bkgd_clr = data;
950 break;
951 case DP_BRUSH_FRGD_CLR:
952 s->regs.dp_brush_frgd_clr = data;
953 break;
954 case DP_CNTL:
955 s->regs.dp_cntl = data;
956 break;
957 case DP_SRC_FRGD_CLR:
958 s->regs.dp_src_frgd_clr = data;
959 break;
960 case DP_SRC_BKGD_CLR:
961 s->regs.dp_src_bkgd_clr = data;
962 break;
963 case DP_DATATYPE:
964 s->regs.dp_datatype = data & 0xe0070f0f;
965 break;
966 case DP_MIX:
967 s->regs.dp_mix = data & 0x00ff0700;
968 break;
969 case DP_WRITE_MASK:
970 s->regs.dp_write_mask = data;
971 break;
972 case DEFAULT_OFFSET:
973 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
974 s->regs.default_offset = data & 0xfffffff0;
975 } else {
976 /* Radeon has DEFAULT_PITCH_OFFSET here like DST_PITCH_OFFSET */
977 s->regs.default_offset = (data & 0x3fffff) << 10;
978 s->regs.default_pitch = (data & 0x3fc00000) >> 16;
979 s->regs.default_tile = data >> 30;
980 }
981 break;
982 case DEFAULT_PITCH:
983 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
984 s->regs.default_pitch = data & 0x3fff;
985 s->regs.default_tile = (data >> 16) & 1;
986 }
987 break;
988 case DEFAULT_SC_BOTTOM_RIGHT:
989 s->regs.default_sc_right = data & 0x3fff;
990 s->regs.default_sc_bottom = (data >> 16) & 0x3fff;
991 break;
992 case SC_TOP_LEFT:
993 s->regs.sc_left = data & 0x3fff;
994 s->regs.sc_top = (data >> 16) & 0x3fff;
995 break;
996 case SC_LEFT:
997 s->regs.sc_left = data & 0x3fff;
998 break;
999 case SC_TOP:
1000 s->regs.sc_top = data & 0x3fff;
1001 break;
1002 case SC_BOTTOM_RIGHT:
1003 s->regs.sc_right = data & 0x3fff;
1004 s->regs.sc_bottom = (data >> 16) & 0x3fff;
1005 break;
1006 case SC_RIGHT:
1007 s->regs.sc_right = data & 0x3fff;
1008 break;
1009 case SC_BOTTOM:
1010 s->regs.sc_bottom = data & 0x3fff;
1011 break;
1012 case SRC_SC_BOTTOM_RIGHT:
1013 s->regs.src_sc_right = data & 0x3fff;
1014 s->regs.src_sc_bottom = (data >> 16) & 0x3fff;
1015 break;
1016 case SRC_SC_RIGHT:
1017 s->regs.src_sc_right = data & 0x3fff;
1018 break;
1019 case SRC_SC_BOTTOM:
1020 s->regs.src_sc_bottom = data & 0x3fff;
1021 break;
1022 case HOST_DATA0:
1023 case HOST_DATA1:
1024 case HOST_DATA2:
1025 case HOST_DATA3:
1026 case HOST_DATA4:
1027 case HOST_DATA5:
1028 case HOST_DATA6:
1029 case HOST_DATA7:
1030 case HOST_DATA_LAST:
1031 if (!s->host_data.active) {
1032 break;
1033 }
1034 s->host_data.acc[s->host_data.next++] = data;
1035 if (addr == HOST_DATA_LAST) {
1036 ati_host_data_finish(s);
1037 s->host_data.next = 0;
1038 } else if (s->host_data.next >= 4) {
1039 ati_host_data_flush(s);
1040 s->host_data.next = 0;
1041 }
1042 break;
1043 default:
1044 break;
1045 }
1046 }
1047
1048 static const MemoryRegionOps ati_mm_ops = {
1049 .read = ati_mm_read,
1050 .write = ati_mm_write,
1051 .endianness = DEVICE_LITTLE_ENDIAN,
1052 };
1053
1054 static void ati_vga_realize(PCIDevice *dev, Error **errp)
1055 {
1056 ATIVGAState *s = ATI_VGA(dev);
1057 VGACommonState *vga = &s->vga;
1058 I2CBus *i2cbus;
1059
1060 #ifndef CONFIG_PIXMAN
1061 if (s->use_pixman != 0) {
1062 warn_report("x-pixman != 0, not effective without PIXMAN");
1063 }
1064 #endif
1065
1066 if (s->model) {
1067 int i;
1068 for (i = 0; i < ARRAY_SIZE(ati_model_aliases); i++) {
1069 if (!strcmp(s->model, ati_model_aliases[i].name)) {
1070 s->dev_id = ati_model_aliases[i].dev_id;
1071 break;
1072 }
1073 }
1074 if (i >= ARRAY_SIZE(ati_model_aliases)) {
1075 warn_report("Unknown ATI VGA model name, "
1076 "using default rage128p");
1077 }
1078 }
1079 if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF &&
1080 s->dev_id != PCI_DEVICE_ID_ATI_RADEON_QY) {
1081 error_setg(errp, "Unknown ATI VGA device id, "
1082 "only 0x5046 and 0x5159 are supported");
1083 return;
1084 }
1085 pci_set_word(dev->config + PCI_DEVICE_ID, s->dev_id);
1086
1087 if (s->dev_id == PCI_DEVICE_ID_ATI_RADEON_QY &&
1088 s->vga.vram_size_mb < 16) {
1089 warn_report("Too small video memory for device id");
1090 s->vga.vram_size_mb = 16;
1091 }
1092
1093 /* init vga bits */
1094 if (!vga_common_init(vga, OBJECT(s), errp)) {
1095 return;
1096 }
1097 vga_init(vga, OBJECT(s), pci_address_space(dev),
1098 pci_address_space_io(dev), true);
1099 vga->con = qemu_graphic_console_create(DEVICE(s), 0, s->vga.hw_ops, vga);
1100 if (s->cursor_guest_mode) {
1101 vga->cursor_invalidate = ati_cursor_invalidate;
1102 vga->cursor_draw_line = ati_cursor_draw_line;
1103 }
1104
1105 /* ddc, edid */
1106 i2cbus = i2c_init_bus(DEVICE(s), "ati-vga.ddc");
1107 bitbang_i2c_init(&s->bbi2c, i2cbus);
1108 i2c_slave_set_address(I2C_SLAVE(&s->i2cddc), 0x50);
1109 qdev_realize(DEVICE(&s->i2cddc), BUS(i2cbus), &error_abort);
1110
1111 /* mmio register space */
1112 memory_region_init_io(&s->mm, OBJECT(s), &ati_mm_ops, s,
1113 "ati.mmregs", 0x4000);
1114 /* io space is alias to beginning of mmregs */
1115 memory_region_init_alias(&s->io, OBJECT(s), "ati.io", &s->mm, 0, 0x100);
1116
1117 /*
1118 * The framebuffer is at the beginning of the linear aperture. For
1119 * Rage128 the upper half of the aperture is reserved for an AGP
1120 * window (which we do not emulate.)
1121 */
1122 if (!s->linear_aper_sz) {
1123 if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
1124 s->linear_aper_sz = ATI_RAGE128_LINEAR_APER_SIZE;
1125 } else {
1126 s->linear_aper_sz = ATI_R100_LINEAR_APER_SIZE;
1127 }
1128 }
1129 if (s->linear_aper_sz > 256 * MiB) {
1130 error_setg(errp, "x-linear-aper-size is too large (maximum 256 MiB)");
1131 return;
1132 }
1133 if (s->linear_aper_sz < 16 * MiB) {
1134 error_setg(errp, "x-linear-aper-size is too small (minimum 16 MiB)");
1135 return;
1136 }
1137 memory_region_init(&s->linear_aper, OBJECT(dev), "ati-linear-aperture0",
1138 s->linear_aper_sz);
1139 memory_region_add_subregion(&s->linear_aper, 0, &vga->vram);
1140
1141 pci_register_bar(dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->linear_aper);
1142 pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
1143 pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mm);
1144
1145 /* most interrupts are not yet emulated but MacOS needs at least VBlank */
1146 dev->config[PCI_INTERRUPT_PIN] = 1;
1147 timer_init_ns(&s->vblank_timer, QEMU_CLOCK_VIRTUAL, ati_vga_vblank_irq, s);
1148 }
1149
1150 static void ati_vga_reset(DeviceState *dev)
1151 {
1152 ATIVGAState *s = ATI_VGA(dev);
1153
1154 timer_del(&s->vblank_timer);
1155 ati_vga_update_irq(s);
1156
1157 /* reset vga */
1158 vga_common_reset(&s->vga);
1159 s->mode = VGA_MODE;
1160
1161 s->host_data.active = false;
1162 s->host_data.next = 0;
1163 s->host_data.row = 0;
1164 s->host_data.col = 0;
1165 }
1166
1167 static void ati_vga_exit(PCIDevice *dev)
1168 {
1169 ATIVGAState *s = ATI_VGA(dev);
1170
1171 timer_del(&s->vblank_timer);
1172 qemu_graphic_console_close(s->vga.con);
1173 }
1174
1175 static const Property ati_vga_properties[] = {
1176 DEFINE_PROP_UINT32("vgamem_mb", ATIVGAState, vga.vram_size_mb, 16),
1177 DEFINE_PROP_STRING("model", ATIVGAState, model),
1178 DEFINE_PROP_UINT16("x-device-id", ATIVGAState, dev_id,
1179 PCI_DEVICE_ID_ATI_RAGE128_PF),
1180 DEFINE_PROP_BOOL("guest_hwcursor", ATIVGAState, cursor_guest_mode, false),
1181 /* this is a debug option, prefer PROP_UINT over PROP_BIT for simplicity */
1182 DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, DEFAULT_X_PIXMAN),
1183 DEFINE_PROP_UINT64("x-linear-aper-size", ATIVGAState, linear_aper_sz, 0),
1184 DEFINE_EDID_PROPERTIES(ATIVGAState, i2cddc.edid_info),
1185 };
1186
1187 static void ati_vga_class_init(ObjectClass *klass, const void *data)
1188 {
1189 DeviceClass *dc = DEVICE_CLASS(klass);
1190 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1191
1192 device_class_set_legacy_reset(dc, ati_vga_reset);
1193 device_class_set_props(dc, ati_vga_properties);
1194 dc->hotpluggable = false;
1195 set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
1196
1197 k->class_id = PCI_CLASS_DISPLAY_VGA;
1198 k->vendor_id = PCI_VENDOR_ID_ATI;
1199 k->device_id = PCI_DEVICE_ID_ATI_RAGE128_PF;
1200 k->romfile = "vgabios-ati.bin";
1201 k->realize = ati_vga_realize;
1202 k->exit = ati_vga_exit;
1203 }
1204
1205 static void ati_vga_init(Object *o)
1206 {
1207 ATIVGAState *s = ATI_VGA(o);
1208
1209 object_initialize_child(o, "edid", &s->i2cddc, TYPE_I2CDDC);
1210 object_property_set_description(o, "x-pixman", "Use pixman for: "
1211 "1: fill, 2: blit");
1212 }
1213
1214 static const TypeInfo ati_vga_info = {
1215 .name = TYPE_ATI_VGA,
1216 .parent = TYPE_PCI_DEVICE,
1217 .instance_size = sizeof(ATIVGAState),
1218 .class_init = ati_vga_class_init,
1219 .instance_init = ati_vga_init,
1220 .interfaces = (const InterfaceInfo[]) {
1221 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
1222 { },
1223 },
1224 };
1225
1226 static void ati_vga_register_types(void)
1227 {
1228 type_register_static(&ati_vga_info);
1229 }
1230
1231 type_init(ati_vga_register_types)