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