qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

ati.c (35630B)


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