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