qemu

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

cirrus_vga.c (100223B)


      1 /*
      2  * QEMU Cirrus CLGD 54xx VGA Emulator.
      3  *
      4  * Copyright (c) 2004 Fabrice Bellard
      5  * Copyright (c) 2004 Makoto Suzuki (suzu)
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a copy
      8  * of this software and associated documentation files (the "Software"), to deal
      9  * in the Software without restriction, including without limitation the rights
     10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     11  * copies of the Software, and to permit persons to whom the Software is
     12  * furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included in
     15  * all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     23  * THE SOFTWARE.
     24  */
     25 /*
     26  * Reference: Finn Thogersons' VGADOC4b:
     27  *
     28  *  http://web.archive.org/web/20021019054927/http://home.worldonline.dk/finth/
     29  *
     30  * VGADOC4b.ZIP content available at:
     31  *
     32  *  https://pdos.csail.mit.edu/6.828/2005/readings/hardware/vgadoc
     33  */
     34 
     35 #include "qemu/osdep.h"
     36 #include "qemu/module.h"
     37 #include "qemu/units.h"
     38 #include "qemu/log.h"
     39 #include "sysemu/reset.h"
     40 #include "qapi/error.h"
     41 #include "trace.h"
     42 #include "hw/pci/pci.h"
     43 #include "hw/qdev-properties.h"
     44 #include "migration/vmstate.h"
     45 #include "ui/pixel_ops.h"
     46 #include "cirrus_vga_internal.h"
     47 #include "qom/object.h"
     48 #include "ui/console.h"
     49 
     50 /*
     51  * TODO:
     52  *    - destination write mask support not complete (bits 5..7)
     53  *    - optimize linear mappings
     54  *    - optimize bitblt functions
     55  */
     56 
     57 //#define DEBUG_CIRRUS
     58 
     59 /***************************************
     60  *
     61  *  definitions
     62  *
     63  ***************************************/
     64 
     65 // sequencer 0x07
     66 #define CIRRUS_SR7_BPP_VGA            0x00
     67 #define CIRRUS_SR7_BPP_SVGA           0x01
     68 #define CIRRUS_SR7_BPP_MASK           0x0e
     69 #define CIRRUS_SR7_BPP_8              0x00
     70 #define CIRRUS_SR7_BPP_16_DOUBLEVCLK  0x02
     71 #define CIRRUS_SR7_BPP_24             0x04
     72 #define CIRRUS_SR7_BPP_16             0x06
     73 #define CIRRUS_SR7_BPP_32             0x08
     74 #define CIRRUS_SR7_ISAADDR_MASK       0xe0
     75 
     76 // sequencer 0x0f
     77 #define CIRRUS_MEMSIZE_512k        0x08
     78 #define CIRRUS_MEMSIZE_1M          0x10
     79 #define CIRRUS_MEMSIZE_2M          0x18
     80 #define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled.
     81 
     82 // sequencer 0x12
     83 #define CIRRUS_CURSOR_SHOW         0x01
     84 #define CIRRUS_CURSOR_HIDDENPEL    0x02
     85 #define CIRRUS_CURSOR_LARGE        0x04 // 64x64 if set, 32x32 if clear
     86 
     87 // sequencer 0x17
     88 #define CIRRUS_BUSTYPE_VLBFAST   0x10
     89 #define CIRRUS_BUSTYPE_PCI       0x20
     90 #define CIRRUS_BUSTYPE_VLBSLOW   0x30
     91 #define CIRRUS_BUSTYPE_ISA       0x38
     92 #define CIRRUS_MMIO_ENABLE       0x04
     93 #define CIRRUS_MMIO_USE_PCIADDR  0x40   // 0xb8000 if cleared.
     94 #define CIRRUS_MEMSIZEEXT_DOUBLE 0x80
     95 
     96 // control 0x0b
     97 #define CIRRUS_BANKING_DUAL             0x01
     98 #define CIRRUS_BANKING_GRANULARITY_16K  0x20    // set:16k, clear:4k
     99 
    100 // control 0x30
    101 #define CIRRUS_BLTMODE_BACKWARDS        0x01
    102 #define CIRRUS_BLTMODE_MEMSYSDEST       0x02
    103 #define CIRRUS_BLTMODE_MEMSYSSRC        0x04
    104 #define CIRRUS_BLTMODE_TRANSPARENTCOMP  0x08
    105 #define CIRRUS_BLTMODE_PATTERNCOPY      0x40
    106 #define CIRRUS_BLTMODE_COLOREXPAND      0x80
    107 #define CIRRUS_BLTMODE_PIXELWIDTHMASK   0x30
    108 #define CIRRUS_BLTMODE_PIXELWIDTH8      0x00
    109 #define CIRRUS_BLTMODE_PIXELWIDTH16     0x10
    110 #define CIRRUS_BLTMODE_PIXELWIDTH24     0x20
    111 #define CIRRUS_BLTMODE_PIXELWIDTH32     0x30
    112 
    113 // control 0x31
    114 #define CIRRUS_BLT_BUSY                 0x01
    115 #define CIRRUS_BLT_START                0x02
    116 #define CIRRUS_BLT_RESET                0x04
    117 #define CIRRUS_BLT_FIFOUSED             0x10
    118 #define CIRRUS_BLT_AUTOSTART            0x80
    119 
    120 // control 0x32
    121 #define CIRRUS_ROP_0                    0x00
    122 #define CIRRUS_ROP_SRC_AND_DST          0x05
    123 #define CIRRUS_ROP_NOP                  0x06
    124 #define CIRRUS_ROP_SRC_AND_NOTDST       0x09
    125 #define CIRRUS_ROP_NOTDST               0x0b
    126 #define CIRRUS_ROP_SRC                  0x0d
    127 #define CIRRUS_ROP_1                    0x0e
    128 #define CIRRUS_ROP_NOTSRC_AND_DST       0x50
    129 #define CIRRUS_ROP_SRC_XOR_DST          0x59
    130 #define CIRRUS_ROP_SRC_OR_DST           0x6d
    131 #define CIRRUS_ROP_NOTSRC_OR_NOTDST     0x90
    132 #define CIRRUS_ROP_SRC_NOTXOR_DST       0x95
    133 #define CIRRUS_ROP_SRC_OR_NOTDST        0xad
    134 #define CIRRUS_ROP_NOTSRC               0xd0
    135 #define CIRRUS_ROP_NOTSRC_OR_DST        0xd6
    136 #define CIRRUS_ROP_NOTSRC_AND_NOTDST    0xda
    137 
    138 #define CIRRUS_ROP_NOP_INDEX 2
    139 #define CIRRUS_ROP_SRC_INDEX 5
    140 
    141 // control 0x33
    142 #define CIRRUS_BLTMODEEXT_SOLIDFILL        0x04
    143 #define CIRRUS_BLTMODEEXT_COLOREXPINV      0x02
    144 #define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
    145 
    146 // memory-mapped IO
    147 #define CIRRUS_MMIO_BLTBGCOLOR        0x00      // dword
    148 #define CIRRUS_MMIO_BLTFGCOLOR        0x04      // dword
    149 #define CIRRUS_MMIO_BLTWIDTH          0x08      // word
    150 #define CIRRUS_MMIO_BLTHEIGHT         0x0a      // word
    151 #define CIRRUS_MMIO_BLTDESTPITCH      0x0c      // word
    152 #define CIRRUS_MMIO_BLTSRCPITCH       0x0e      // word
    153 #define CIRRUS_MMIO_BLTDESTADDR       0x10      // dword
    154 #define CIRRUS_MMIO_BLTSRCADDR        0x14      // dword
    155 #define CIRRUS_MMIO_BLTWRITEMASK      0x17      // byte
    156 #define CIRRUS_MMIO_BLTMODE           0x18      // byte
    157 #define CIRRUS_MMIO_BLTROP            0x1a      // byte
    158 #define CIRRUS_MMIO_BLTMODEEXT        0x1b      // byte
    159 #define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c    // word?
    160 #define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20        // word?
    161 #define CIRRUS_MMIO_LINEARDRAW_START_X 0x24     // word
    162 #define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26     // word
    163 #define CIRRUS_MMIO_LINEARDRAW_END_X  0x28      // word
    164 #define CIRRUS_MMIO_LINEARDRAW_END_Y  0x2a      // word
    165 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c       // byte
    166 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d  // byte
    167 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e      // byte
    168 #define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f     // byte
    169 #define CIRRUS_MMIO_BRESENHAM_K1      0x30      // word
    170 #define CIRRUS_MMIO_BRESENHAM_K3      0x32      // word
    171 #define CIRRUS_MMIO_BRESENHAM_ERROR   0x34      // word
    172 #define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36  // word
    173 #define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38    // byte
    174 #define CIRRUS_MMIO_LINEDRAW_MODE     0x39      // byte
    175 #define CIRRUS_MMIO_BLTSTATUS         0x40      // byte
    176 
    177 #define CIRRUS_PNPMMIO_SIZE         0x1000
    178 
    179 typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
    180                               uint32_t dstaddr, int dst_pitch,
    181                               int width, int height);
    182 
    183 struct PCICirrusVGAState {
    184     PCIDevice dev;
    185     CirrusVGAState cirrus_vga;
    186 };
    187 
    188 #define TYPE_PCI_CIRRUS_VGA "cirrus-vga"
    189 OBJECT_DECLARE_SIMPLE_TYPE(PCICirrusVGAState, PCI_CIRRUS_VGA)
    190 
    191 static uint8_t rop_to_index[256];
    192 
    193 /***************************************
    194  *
    195  *  prototypes.
    196  *
    197  ***************************************/
    198 
    199 
    200 static void cirrus_bitblt_reset(CirrusVGAState *s);
    201 static void cirrus_update_memory_access(CirrusVGAState *s);
    202 
    203 /***************************************
    204  *
    205  *  raster operations
    206  *
    207  ***************************************/
    208 
    209 static bool blit_region_is_unsafe(struct CirrusVGAState *s,
    210                                   int32_t pitch, int32_t addr)
    211 {
    212     if (!pitch) {
    213         return true;
    214     }
    215     if (pitch < 0) {
    216         int64_t min = addr
    217             + ((int64_t)s->cirrus_blt_height - 1) * pitch
    218             - s->cirrus_blt_width;
    219         if (min < -1 || addr >= s->vga.vram_size) {
    220             return true;
    221         }
    222     } else {
    223         int64_t max = addr
    224             + ((int64_t)s->cirrus_blt_height-1) * pitch
    225             + s->cirrus_blt_width;
    226         if (max > s->vga.vram_size) {
    227             return true;
    228         }
    229     }
    230     return false;
    231 }
    232 
    233 static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only)
    234 {
    235     /* should be the case, see cirrus_bitblt_start */
    236     assert(s->cirrus_blt_width > 0);
    237     assert(s->cirrus_blt_height > 0);
    238 
    239     if (s->cirrus_blt_width > CIRRUS_BLTBUFSIZE) {
    240         return true;
    241     }
    242 
    243     if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch,
    244                               s->cirrus_blt_dstaddr)) {
    245         return true;
    246     }
    247     if (dst_only) {
    248         return false;
    249     }
    250     if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch,
    251                               s->cirrus_blt_srcaddr)) {
    252         return true;
    253     }
    254 
    255     return false;
    256 }
    257 
    258 static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
    259                                   uint32_t dstaddr, uint32_t srcaddr,
    260                                   int dstpitch,int srcpitch,
    261                                   int bltwidth,int bltheight)
    262 {
    263 }
    264 
    265 static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
    266                                    uint32_t dstaddr,
    267                                    int dstpitch, int bltwidth,int bltheight)
    268 {
    269 }
    270 
    271 static inline uint8_t cirrus_src(CirrusVGAState *s, uint32_t srcaddr)
    272 {
    273     if (s->cirrus_srccounter) {
    274         /* cputovideo */
    275         return s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1)];
    276     } else {
    277         /* videotovideo */
    278         return s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask];
    279     }
    280 }
    281 
    282 static inline uint16_t cirrus_src16(CirrusVGAState *s, uint32_t srcaddr)
    283 {
    284     uint16_t *src;
    285 
    286     if (s->cirrus_srccounter) {
    287         /* cputovideo */
    288         src = (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1) & ~1];
    289     } else {
    290         /* videotovideo */
    291         src = (void *)&s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask & ~1];
    292     }
    293     return *src;
    294 }
    295 
    296 static inline uint32_t cirrus_src32(CirrusVGAState *s, uint32_t srcaddr)
    297 {
    298     uint32_t *src;
    299 
    300     if (s->cirrus_srccounter) {
    301         /* cputovideo */
    302         src = (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1) & ~3];
    303     } else {
    304         /* videotovideo */
    305         src = (void *)&s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask & ~3];
    306     }
    307     return *src;
    308 }
    309 
    310 #define ROP_NAME 0
    311 #define ROP_FN(d, s) 0
    312 #include "cirrus_vga_rop.h"
    313 
    314 #define ROP_NAME src_and_dst
    315 #define ROP_FN(d, s) (s) & (d)
    316 #include "cirrus_vga_rop.h"
    317 
    318 #define ROP_NAME src_and_notdst
    319 #define ROP_FN(d, s) (s) & (~(d))
    320 #include "cirrus_vga_rop.h"
    321 
    322 #define ROP_NAME notdst
    323 #define ROP_FN(d, s) ~(d)
    324 #include "cirrus_vga_rop.h"
    325 
    326 #define ROP_NAME src
    327 #define ROP_FN(d, s) s
    328 #include "cirrus_vga_rop.h"
    329 
    330 #define ROP_NAME 1
    331 #define ROP_FN(d, s) ~0
    332 #include "cirrus_vga_rop.h"
    333 
    334 #define ROP_NAME notsrc_and_dst
    335 #define ROP_FN(d, s) (~(s)) & (d)
    336 #include "cirrus_vga_rop.h"
    337 
    338 #define ROP_NAME src_xor_dst
    339 #define ROP_FN(d, s) (s) ^ (d)
    340 #include "cirrus_vga_rop.h"
    341 
    342 #define ROP_NAME src_or_dst
    343 #define ROP_FN(d, s) (s) | (d)
    344 #include "cirrus_vga_rop.h"
    345 
    346 #define ROP_NAME notsrc_or_notdst
    347 #define ROP_FN(d, s) (~(s)) | (~(d))
    348 #include "cirrus_vga_rop.h"
    349 
    350 #define ROP_NAME src_notxor_dst
    351 #define ROP_FN(d, s) ~((s) ^ (d))
    352 #include "cirrus_vga_rop.h"
    353 
    354 #define ROP_NAME src_or_notdst
    355 #define ROP_FN(d, s) (s) | (~(d))
    356 #include "cirrus_vga_rop.h"
    357 
    358 #define ROP_NAME notsrc
    359 #define ROP_FN(d, s) (~(s))
    360 #include "cirrus_vga_rop.h"
    361 
    362 #define ROP_NAME notsrc_or_dst
    363 #define ROP_FN(d, s) (~(s)) | (d)
    364 #include "cirrus_vga_rop.h"
    365 
    366 #define ROP_NAME notsrc_and_notdst
    367 #define ROP_FN(d, s) (~(s)) & (~(d))
    368 #include "cirrus_vga_rop.h"
    369 
    370 static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = {
    371     cirrus_bitblt_rop_fwd_0,
    372     cirrus_bitblt_rop_fwd_src_and_dst,
    373     cirrus_bitblt_rop_nop,
    374     cirrus_bitblt_rop_fwd_src_and_notdst,
    375     cirrus_bitblt_rop_fwd_notdst,
    376     cirrus_bitblt_rop_fwd_src,
    377     cirrus_bitblt_rop_fwd_1,
    378     cirrus_bitblt_rop_fwd_notsrc_and_dst,
    379     cirrus_bitblt_rop_fwd_src_xor_dst,
    380     cirrus_bitblt_rop_fwd_src_or_dst,
    381     cirrus_bitblt_rop_fwd_notsrc_or_notdst,
    382     cirrus_bitblt_rop_fwd_src_notxor_dst,
    383     cirrus_bitblt_rop_fwd_src_or_notdst,
    384     cirrus_bitblt_rop_fwd_notsrc,
    385     cirrus_bitblt_rop_fwd_notsrc_or_dst,
    386     cirrus_bitblt_rop_fwd_notsrc_and_notdst,
    387 };
    388 
    389 static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = {
    390     cirrus_bitblt_rop_bkwd_0,
    391     cirrus_bitblt_rop_bkwd_src_and_dst,
    392     cirrus_bitblt_rop_nop,
    393     cirrus_bitblt_rop_bkwd_src_and_notdst,
    394     cirrus_bitblt_rop_bkwd_notdst,
    395     cirrus_bitblt_rop_bkwd_src,
    396     cirrus_bitblt_rop_bkwd_1,
    397     cirrus_bitblt_rop_bkwd_notsrc_and_dst,
    398     cirrus_bitblt_rop_bkwd_src_xor_dst,
    399     cirrus_bitblt_rop_bkwd_src_or_dst,
    400     cirrus_bitblt_rop_bkwd_notsrc_or_notdst,
    401     cirrus_bitblt_rop_bkwd_src_notxor_dst,
    402     cirrus_bitblt_rop_bkwd_src_or_notdst,
    403     cirrus_bitblt_rop_bkwd_notsrc,
    404     cirrus_bitblt_rop_bkwd_notsrc_or_dst,
    405     cirrus_bitblt_rop_bkwd_notsrc_and_notdst,
    406 };
    407 
    408 #define TRANSP_ROP(name) {\
    409     name ## _8,\
    410     name ## _16,\
    411         }
    412 #define TRANSP_NOP(func) {\
    413     func,\
    414     func,\
    415         }
    416 
    417 static const cirrus_bitblt_rop_t cirrus_fwd_transp_rop[16][2] = {
    418     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_0),
    419     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_dst),
    420     TRANSP_NOP(cirrus_bitblt_rop_nop),
    421     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_and_notdst),
    422     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notdst),
    423     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src),
    424     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_1),
    425     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_dst),
    426     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_xor_dst),
    427     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_dst),
    428     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_notdst),
    429     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_notxor_dst),
    430     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_src_or_notdst),
    431     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc),
    432     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_or_dst),
    433     TRANSP_ROP(cirrus_bitblt_rop_fwd_transp_notsrc_and_notdst),
    434 };
    435 
    436 static const cirrus_bitblt_rop_t cirrus_bkwd_transp_rop[16][2] = {
    437     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_0),
    438     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_dst),
    439     TRANSP_NOP(cirrus_bitblt_rop_nop),
    440     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_and_notdst),
    441     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notdst),
    442     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src),
    443     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_1),
    444     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_dst),
    445     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_xor_dst),
    446     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_dst),
    447     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_notdst),
    448     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_notxor_dst),
    449     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_src_or_notdst),
    450     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc),
    451     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_or_dst),
    452     TRANSP_ROP(cirrus_bitblt_rop_bkwd_transp_notsrc_and_notdst),
    453 };
    454 
    455 #define ROP2(name) {\
    456     name ## _8,\
    457     name ## _16,\
    458     name ## _24,\
    459     name ## _32,\
    460         }
    461 
    462 #define ROP_NOP2(func) {\
    463     func,\
    464     func,\
    465     func,\
    466     func,\
    467         }
    468 
    469 static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = {
    470     ROP2(cirrus_patternfill_0),
    471     ROP2(cirrus_patternfill_src_and_dst),
    472     ROP_NOP2(cirrus_bitblt_rop_nop),
    473     ROP2(cirrus_patternfill_src_and_notdst),
    474     ROP2(cirrus_patternfill_notdst),
    475     ROP2(cirrus_patternfill_src),
    476     ROP2(cirrus_patternfill_1),
    477     ROP2(cirrus_patternfill_notsrc_and_dst),
    478     ROP2(cirrus_patternfill_src_xor_dst),
    479     ROP2(cirrus_patternfill_src_or_dst),
    480     ROP2(cirrus_patternfill_notsrc_or_notdst),
    481     ROP2(cirrus_patternfill_src_notxor_dst),
    482     ROP2(cirrus_patternfill_src_or_notdst),
    483     ROP2(cirrus_patternfill_notsrc),
    484     ROP2(cirrus_patternfill_notsrc_or_dst),
    485     ROP2(cirrus_patternfill_notsrc_and_notdst),
    486 };
    487 
    488 static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = {
    489     ROP2(cirrus_colorexpand_transp_0),
    490     ROP2(cirrus_colorexpand_transp_src_and_dst),
    491     ROP_NOP2(cirrus_bitblt_rop_nop),
    492     ROP2(cirrus_colorexpand_transp_src_and_notdst),
    493     ROP2(cirrus_colorexpand_transp_notdst),
    494     ROP2(cirrus_colorexpand_transp_src),
    495     ROP2(cirrus_colorexpand_transp_1),
    496     ROP2(cirrus_colorexpand_transp_notsrc_and_dst),
    497     ROP2(cirrus_colorexpand_transp_src_xor_dst),
    498     ROP2(cirrus_colorexpand_transp_src_or_dst),
    499     ROP2(cirrus_colorexpand_transp_notsrc_or_notdst),
    500     ROP2(cirrus_colorexpand_transp_src_notxor_dst),
    501     ROP2(cirrus_colorexpand_transp_src_or_notdst),
    502     ROP2(cirrus_colorexpand_transp_notsrc),
    503     ROP2(cirrus_colorexpand_transp_notsrc_or_dst),
    504     ROP2(cirrus_colorexpand_transp_notsrc_and_notdst),
    505 };
    506 
    507 static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = {
    508     ROP2(cirrus_colorexpand_0),
    509     ROP2(cirrus_colorexpand_src_and_dst),
    510     ROP_NOP2(cirrus_bitblt_rop_nop),
    511     ROP2(cirrus_colorexpand_src_and_notdst),
    512     ROP2(cirrus_colorexpand_notdst),
    513     ROP2(cirrus_colorexpand_src),
    514     ROP2(cirrus_colorexpand_1),
    515     ROP2(cirrus_colorexpand_notsrc_and_dst),
    516     ROP2(cirrus_colorexpand_src_xor_dst),
    517     ROP2(cirrus_colorexpand_src_or_dst),
    518     ROP2(cirrus_colorexpand_notsrc_or_notdst),
    519     ROP2(cirrus_colorexpand_src_notxor_dst),
    520     ROP2(cirrus_colorexpand_src_or_notdst),
    521     ROP2(cirrus_colorexpand_notsrc),
    522     ROP2(cirrus_colorexpand_notsrc_or_dst),
    523     ROP2(cirrus_colorexpand_notsrc_and_notdst),
    524 };
    525 
    526 static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = {
    527     ROP2(cirrus_colorexpand_pattern_transp_0),
    528     ROP2(cirrus_colorexpand_pattern_transp_src_and_dst),
    529     ROP_NOP2(cirrus_bitblt_rop_nop),
    530     ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst),
    531     ROP2(cirrus_colorexpand_pattern_transp_notdst),
    532     ROP2(cirrus_colorexpand_pattern_transp_src),
    533     ROP2(cirrus_colorexpand_pattern_transp_1),
    534     ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst),
    535     ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst),
    536     ROP2(cirrus_colorexpand_pattern_transp_src_or_dst),
    537     ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst),
    538     ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst),
    539     ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst),
    540     ROP2(cirrus_colorexpand_pattern_transp_notsrc),
    541     ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst),
    542     ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst),
    543 };
    544 
    545 static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = {
    546     ROP2(cirrus_colorexpand_pattern_0),
    547     ROP2(cirrus_colorexpand_pattern_src_and_dst),
    548     ROP_NOP2(cirrus_bitblt_rop_nop),
    549     ROP2(cirrus_colorexpand_pattern_src_and_notdst),
    550     ROP2(cirrus_colorexpand_pattern_notdst),
    551     ROP2(cirrus_colorexpand_pattern_src),
    552     ROP2(cirrus_colorexpand_pattern_1),
    553     ROP2(cirrus_colorexpand_pattern_notsrc_and_dst),
    554     ROP2(cirrus_colorexpand_pattern_src_xor_dst),
    555     ROP2(cirrus_colorexpand_pattern_src_or_dst),
    556     ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst),
    557     ROP2(cirrus_colorexpand_pattern_src_notxor_dst),
    558     ROP2(cirrus_colorexpand_pattern_src_or_notdst),
    559     ROP2(cirrus_colorexpand_pattern_notsrc),
    560     ROP2(cirrus_colorexpand_pattern_notsrc_or_dst),
    561     ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst),
    562 };
    563 
    564 static const cirrus_fill_t cirrus_fill[16][4] = {
    565     ROP2(cirrus_fill_0),
    566     ROP2(cirrus_fill_src_and_dst),
    567     ROP_NOP2(cirrus_bitblt_fill_nop),
    568     ROP2(cirrus_fill_src_and_notdst),
    569     ROP2(cirrus_fill_notdst),
    570     ROP2(cirrus_fill_src),
    571     ROP2(cirrus_fill_1),
    572     ROP2(cirrus_fill_notsrc_and_dst),
    573     ROP2(cirrus_fill_src_xor_dst),
    574     ROP2(cirrus_fill_src_or_dst),
    575     ROP2(cirrus_fill_notsrc_or_notdst),
    576     ROP2(cirrus_fill_src_notxor_dst),
    577     ROP2(cirrus_fill_src_or_notdst),
    578     ROP2(cirrus_fill_notsrc),
    579     ROP2(cirrus_fill_notsrc_or_dst),
    580     ROP2(cirrus_fill_notsrc_and_notdst),
    581 };
    582 
    583 static inline void cirrus_bitblt_fgcol(CirrusVGAState *s)
    584 {
    585     unsigned int color;
    586     switch (s->cirrus_blt_pixelwidth) {
    587     case 1:
    588         s->cirrus_blt_fgcol = s->cirrus_shadow_gr1;
    589         break;
    590     case 2:
    591         color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8);
    592         s->cirrus_blt_fgcol = le16_to_cpu(color);
    593         break;
    594     case 3:
    595         s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 |
    596             (s->vga.gr[0x11] << 8) | (s->vga.gr[0x13] << 16);
    597         break;
    598     default:
    599     case 4:
    600         color = s->cirrus_shadow_gr1 | (s->vga.gr[0x11] << 8) |
    601             (s->vga.gr[0x13] << 16) | (s->vga.gr[0x15] << 24);
    602         s->cirrus_blt_fgcol = le32_to_cpu(color);
    603         break;
    604     }
    605 }
    606 
    607 static inline void cirrus_bitblt_bgcol(CirrusVGAState *s)
    608 {
    609     unsigned int color;
    610     switch (s->cirrus_blt_pixelwidth) {
    611     case 1:
    612         s->cirrus_blt_bgcol = s->cirrus_shadow_gr0;
    613         break;
    614     case 2:
    615         color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8);
    616         s->cirrus_blt_bgcol = le16_to_cpu(color);
    617         break;
    618     case 3:
    619         s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 |
    620             (s->vga.gr[0x10] << 8) | (s->vga.gr[0x12] << 16);
    621         break;
    622     default:
    623     case 4:
    624         color = s->cirrus_shadow_gr0 | (s->vga.gr[0x10] << 8) |
    625             (s->vga.gr[0x12] << 16) | (s->vga.gr[0x14] << 24);
    626         s->cirrus_blt_bgcol = le32_to_cpu(color);
    627         break;
    628     }
    629 }
    630 
    631 static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
    632                                      int off_pitch, int bytesperline,
    633                                      int lines)
    634 {
    635     int y;
    636     int off_cur;
    637     int off_cur_end;
    638 
    639     if (off_pitch < 0) {
    640         off_begin -= bytesperline - 1;
    641     }
    642 
    643     for (y = 0; y < lines; y++) {
    644         off_cur = off_begin & s->cirrus_addr_mask;
    645         off_cur_end = ((off_cur + bytesperline - 1) & s->cirrus_addr_mask) + 1;
    646         if (off_cur_end >= off_cur) {
    647             memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur);
    648         } else {
    649             /* wraparound */
    650             memory_region_set_dirty(&s->vga.vram, off_cur,
    651                                     s->cirrus_addr_mask + 1 - off_cur);
    652             memory_region_set_dirty(&s->vga.vram, 0, off_cur_end);
    653         }
    654         off_begin += off_pitch;
    655     }
    656 }
    657 
    658 static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s)
    659 {
    660     uint32_t patternsize;
    661     bool videosrc = !s->cirrus_srccounter;
    662 
    663     if (videosrc) {
    664         switch (s->vga.get_bpp(&s->vga)) {
    665         case 8:
    666             patternsize = 64;
    667             break;
    668         case 15:
    669         case 16:
    670             patternsize = 128;
    671             break;
    672         case 24:
    673         case 32:
    674         default:
    675             patternsize = 256;
    676             break;
    677         }
    678         s->cirrus_blt_srcaddr &= ~(patternsize - 1);
    679         if (s->cirrus_blt_srcaddr + patternsize > s->vga.vram_size) {
    680             return 0;
    681         }
    682     }
    683 
    684     if (blit_is_unsafe(s, true)) {
    685         return 0;
    686     }
    687 
    688     (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr,
    689                       videosrc ? s->cirrus_blt_srcaddr : 0,
    690                       s->cirrus_blt_dstpitch, 0,
    691                       s->cirrus_blt_width, s->cirrus_blt_height);
    692     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
    693                              s->cirrus_blt_dstpitch, s->cirrus_blt_width,
    694                              s->cirrus_blt_height);
    695     return 1;
    696 }
    697 
    698 /* fill */
    699 
    700 static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
    701 {
    702     cirrus_fill_t rop_func;
    703 
    704     if (blit_is_unsafe(s, true)) {
    705         return 0;
    706     }
    707     rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
    708     rop_func(s, s->cirrus_blt_dstaddr,
    709              s->cirrus_blt_dstpitch,
    710              s->cirrus_blt_width, s->cirrus_blt_height);
    711     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
    712                              s->cirrus_blt_dstpitch, s->cirrus_blt_width,
    713                              s->cirrus_blt_height);
    714     cirrus_bitblt_reset(s);
    715     return 1;
    716 }
    717 
    718 /***************************************
    719  *
    720  *  bitblt (video-to-video)
    721  *
    722  ***************************************/
    723 
    724 static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
    725 {
    726     return cirrus_bitblt_common_patterncopy(s);
    727 }
    728 
    729 static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
    730 {
    731     int sx = 0, sy = 0;
    732     int dx = 0, dy = 0;
    733     int depth = 0;
    734     int notify = 0;
    735 
    736     /* make sure to only copy if it's a plain copy ROP */
    737     if (*s->cirrus_rop == cirrus_bitblt_rop_fwd_src ||
    738         *s->cirrus_rop == cirrus_bitblt_rop_bkwd_src) {
    739 
    740         int width, height;
    741 
    742         depth = s->vga.get_bpp(&s->vga) / 8;
    743         if (!depth) {
    744             return 0;
    745         }
    746         s->vga.get_resolution(&s->vga, &width, &height);
    747 
    748         /* extra x, y */
    749         sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
    750         sy = (src / ABS(s->cirrus_blt_srcpitch));
    751         dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
    752         dy = (dst / ABS(s->cirrus_blt_dstpitch));
    753 
    754         /* normalize width */
    755         w /= depth;
    756 
    757         /* if we're doing a backward copy, we have to adjust
    758            our x/y to be the upper left corner (instead of the lower
    759            right corner) */
    760         if (s->cirrus_blt_dstpitch < 0) {
    761             sx -= (s->cirrus_blt_width / depth) - 1;
    762             dx -= (s->cirrus_blt_width / depth) - 1;
    763             sy -= s->cirrus_blt_height - 1;
    764             dy -= s->cirrus_blt_height - 1;
    765         }
    766 
    767         /* are we in the visible portion of memory? */
    768         if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&
    769             (sx + w) <= width && (sy + h) <= height &&
    770             (dx + w) <= width && (dy + h) <= height) {
    771             notify = 1;
    772         }
    773     }
    774 
    775     (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr,
    776                       s->cirrus_blt_srcaddr,
    777                       s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
    778                       s->cirrus_blt_width, s->cirrus_blt_height);
    779 
    780     if (notify) {
    781         dpy_gfx_update(s->vga.con, dx, dy,
    782                        s->cirrus_blt_width / depth,
    783                        s->cirrus_blt_height);
    784     }
    785 
    786     /* we don't have to notify the display that this portion has
    787        changed since qemu_console_copy implies this */
    788 
    789     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
    790                                 s->cirrus_blt_dstpitch, s->cirrus_blt_width,
    791                                 s->cirrus_blt_height);
    792 
    793     return 1;
    794 }
    795 
    796 static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
    797 {
    798     if (blit_is_unsafe(s, false))
    799         return 0;
    800 
    801     return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
    802             s->cirrus_blt_srcaddr - s->vga.start_addr,
    803             s->cirrus_blt_width, s->cirrus_blt_height);
    804 }
    805 
    806 /***************************************
    807  *
    808  *  bitblt (cpu-to-video)
    809  *
    810  ***************************************/
    811 
    812 static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
    813 {
    814     int copy_count;
    815     uint8_t *end_ptr;
    816 
    817     if (s->cirrus_srccounter > 0) {
    818         if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
    819             cirrus_bitblt_common_patterncopy(s);
    820         the_end:
    821             s->cirrus_srccounter = 0;
    822             cirrus_bitblt_reset(s);
    823         } else {
    824             /* at least one scan line */
    825             do {
    826                 (*s->cirrus_rop)(s, s->cirrus_blt_dstaddr,
    827                                  0, 0, 0, s->cirrus_blt_width, 1);
    828                 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
    829                                          s->cirrus_blt_width, 1);
    830                 s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
    831                 s->cirrus_srccounter -= s->cirrus_blt_srcpitch;
    832                 if (s->cirrus_srccounter <= 0)
    833                     goto the_end;
    834                 /* more bytes than needed can be transferred because of
    835                    word alignment, so we keep them for the next line */
    836                 /* XXX: keep alignment to speed up transfer */
    837                 end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
    838                 copy_count = MIN(s->cirrus_srcptr_end - end_ptr, CIRRUS_BLTBUFSIZE);
    839                 memmove(s->cirrus_bltbuf, end_ptr, copy_count);
    840                 s->cirrus_srcptr = s->cirrus_bltbuf + copy_count;
    841                 s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
    842             } while (s->cirrus_srcptr >= s->cirrus_srcptr_end);
    843         }
    844     }
    845 }
    846 
    847 /***************************************
    848  *
    849  *  bitblt wrapper
    850  *
    851  ***************************************/
    852 
    853 static void cirrus_bitblt_reset(CirrusVGAState * s)
    854 {
    855     int need_update;
    856 
    857     s->vga.gr[0x31] &=
    858         ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED);
    859     need_update = s->cirrus_srcptr != &s->cirrus_bltbuf[0]
    860         || s->cirrus_srcptr_end != &s->cirrus_bltbuf[0];
    861     s->cirrus_srcptr = &s->cirrus_bltbuf[0];
    862     s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
    863     s->cirrus_srccounter = 0;
    864     if (!need_update)
    865         return;
    866     cirrus_update_memory_access(s);
    867 }
    868 
    869 static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
    870 {
    871     int w;
    872 
    873     if (blit_is_unsafe(s, true)) {
    874         return 0;
    875     }
    876 
    877     s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
    878     s->cirrus_srcptr = &s->cirrus_bltbuf[0];
    879     s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
    880 
    881     if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
    882         if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
    883             s->cirrus_blt_srcpitch = 8;
    884         } else {
    885             /* XXX: check for 24 bpp */
    886             s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth;
    887         }
    888         s->cirrus_srccounter = s->cirrus_blt_srcpitch;
    889     } else {
    890         if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
    891             w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth;
    892             if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
    893                 s->cirrus_blt_srcpitch = ((w + 31) >> 5);
    894             else
    895                 s->cirrus_blt_srcpitch = ((w + 7) >> 3);
    896         } else {
    897             /* always align input size to 32 bits */
    898             s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3;
    899         }
    900         s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
    901     }
    902 
    903     /* the blit_is_unsafe call above should catch this */
    904     assert(s->cirrus_blt_srcpitch <= CIRRUS_BLTBUFSIZE);
    905 
    906     s->cirrus_srcptr = s->cirrus_bltbuf;
    907     s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
    908     cirrus_update_memory_access(s);
    909     return 1;
    910 }
    911 
    912 static int cirrus_bitblt_videotocpu(CirrusVGAState * s)
    913 {
    914     /* XXX */
    915     qemu_log_mask(LOG_UNIMP,
    916                   "cirrus: bitblt (video to cpu) is not implemented\n");
    917     return 0;
    918 }
    919 
    920 static int cirrus_bitblt_videotovideo(CirrusVGAState * s)
    921 {
    922     int ret;
    923 
    924     if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
    925         ret = cirrus_bitblt_videotovideo_patterncopy(s);
    926     } else {
    927         ret = cirrus_bitblt_videotovideo_copy(s);
    928     }
    929     if (ret)
    930         cirrus_bitblt_reset(s);
    931     return ret;
    932 }
    933 
    934 static void cirrus_bitblt_start(CirrusVGAState * s)
    935 {
    936     uint8_t blt_rop;
    937 
    938     if (!s->enable_blitter) {
    939         goto bitblt_ignore;
    940     }
    941 
    942     s->vga.gr[0x31] |= CIRRUS_BLT_BUSY;
    943 
    944     s->cirrus_blt_width = (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1;
    945     s->cirrus_blt_height = (s->vga.gr[0x22] | (s->vga.gr[0x23] << 8)) + 1;
    946     s->cirrus_blt_dstpitch = (s->vga.gr[0x24] | (s->vga.gr[0x25] << 8));
    947     s->cirrus_blt_srcpitch = (s->vga.gr[0x26] | (s->vga.gr[0x27] << 8));
    948     s->cirrus_blt_dstaddr =
    949         (s->vga.gr[0x28] | (s->vga.gr[0x29] << 8) | (s->vga.gr[0x2a] << 16));
    950     s->cirrus_blt_srcaddr =
    951         (s->vga.gr[0x2c] | (s->vga.gr[0x2d] << 8) | (s->vga.gr[0x2e] << 16));
    952     s->cirrus_blt_mode = s->vga.gr[0x30];
    953     s->cirrus_blt_modeext = s->vga.gr[0x33];
    954     blt_rop = s->vga.gr[0x32];
    955 
    956     s->cirrus_blt_dstaddr &= s->cirrus_addr_mask;
    957     s->cirrus_blt_srcaddr &= s->cirrus_addr_mask;
    958 
    959     trace_vga_cirrus_bitblt_start(blt_rop,
    960                                   s->cirrus_blt_mode,
    961                                   s->cirrus_blt_modeext,
    962                                   s->cirrus_blt_width,
    963                                   s->cirrus_blt_height,
    964                                   s->cirrus_blt_dstpitch,
    965                                   s->cirrus_blt_srcpitch,
    966                                   s->cirrus_blt_dstaddr,
    967                                   s->cirrus_blt_srcaddr,
    968                                   s->vga.gr[0x2f]);
    969 
    970     switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
    971     case CIRRUS_BLTMODE_PIXELWIDTH8:
    972         s->cirrus_blt_pixelwidth = 1;
    973         break;
    974     case CIRRUS_BLTMODE_PIXELWIDTH16:
    975         s->cirrus_blt_pixelwidth = 2;
    976         break;
    977     case CIRRUS_BLTMODE_PIXELWIDTH24:
    978         s->cirrus_blt_pixelwidth = 3;
    979         break;
    980     case CIRRUS_BLTMODE_PIXELWIDTH32:
    981         s->cirrus_blt_pixelwidth = 4;
    982         break;
    983     default:
    984         qemu_log_mask(LOG_GUEST_ERROR,
    985                       "cirrus: bitblt - pixel width is unknown\n");
    986         goto bitblt_ignore;
    987     }
    988     s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK;
    989 
    990     if ((s->
    991          cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC |
    992                             CIRRUS_BLTMODE_MEMSYSDEST))
    993         == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) {
    994         qemu_log_mask(LOG_UNIMP,
    995                       "cirrus: bitblt - memory-to-memory copy requested\n");
    996         goto bitblt_ignore;
    997     }
    998 
    999     if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
   1000         (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
   1001                                CIRRUS_BLTMODE_TRANSPARENTCOMP |
   1002                                CIRRUS_BLTMODE_PATTERNCOPY |
   1003                                CIRRUS_BLTMODE_COLOREXPAND)) ==
   1004          (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
   1005         cirrus_bitblt_fgcol(s);
   1006         cirrus_bitblt_solidfill(s, blt_rop);
   1007     } else {
   1008         if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |
   1009                                    CIRRUS_BLTMODE_PATTERNCOPY)) ==
   1010             CIRRUS_BLTMODE_COLOREXPAND) {
   1011 
   1012             if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
   1013                 if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
   1014                     cirrus_bitblt_bgcol(s);
   1015                 else
   1016                     cirrus_bitblt_fgcol(s);
   1017                 s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
   1018             } else {
   1019                 cirrus_bitblt_fgcol(s);
   1020                 cirrus_bitblt_bgcol(s);
   1021                 s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
   1022             }
   1023         } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
   1024             if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
   1025                 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
   1026                     if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
   1027                         cirrus_bitblt_bgcol(s);
   1028                     else
   1029                         cirrus_bitblt_fgcol(s);
   1030                     s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
   1031                 } else {
   1032                     cirrus_bitblt_fgcol(s);
   1033                     cirrus_bitblt_bgcol(s);
   1034                     s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
   1035                 }
   1036             } else {
   1037                 s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
   1038             }
   1039         } else {
   1040             if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
   1041                 if (s->cirrus_blt_pixelwidth > 2) {
   1042                     qemu_log_mask(LOG_GUEST_ERROR,
   1043                                   "cirrus: src transparent without colorexpand "
   1044                                   "must be 8bpp or 16bpp\n");
   1045                     goto bitblt_ignore;
   1046                 }
   1047                 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
   1048                     s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
   1049                     s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
   1050                     s->cirrus_rop = cirrus_bkwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
   1051                 } else {
   1052                     s->cirrus_rop = cirrus_fwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
   1053                 }
   1054             } else {
   1055                 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
   1056                     s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
   1057                     s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
   1058                     s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]];
   1059                 } else {
   1060                     s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]];
   1061                 }
   1062             }
   1063         }
   1064         // setup bitblt engine.
   1065         if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) {
   1066             if (!cirrus_bitblt_cputovideo(s))
   1067                 goto bitblt_ignore;
   1068         } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) {
   1069             if (!cirrus_bitblt_videotocpu(s))
   1070                 goto bitblt_ignore;
   1071         } else {
   1072             if (!cirrus_bitblt_videotovideo(s))
   1073                 goto bitblt_ignore;
   1074         }
   1075     }
   1076     return;
   1077   bitblt_ignore:;
   1078     cirrus_bitblt_reset(s);
   1079 }
   1080 
   1081 static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
   1082 {
   1083     unsigned old_value;
   1084 
   1085     old_value = s->vga.gr[0x31];
   1086     s->vga.gr[0x31] = reg_value;
   1087 
   1088     if (((old_value & CIRRUS_BLT_RESET) != 0) &&
   1089         ((reg_value & CIRRUS_BLT_RESET) == 0)) {
   1090         cirrus_bitblt_reset(s);
   1091     } else if (((old_value & CIRRUS_BLT_START) == 0) &&
   1092                ((reg_value & CIRRUS_BLT_START) != 0)) {
   1093         cirrus_bitblt_start(s);
   1094     }
   1095 }
   1096 
   1097 
   1098 /***************************************
   1099  *
   1100  *  basic parameters
   1101  *
   1102  ***************************************/
   1103 
   1104 static void cirrus_get_offsets(VGACommonState *s1,
   1105                                uint32_t *pline_offset,
   1106                                uint32_t *pstart_addr,
   1107                                uint32_t *pline_compare)
   1108 {
   1109     CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
   1110     uint32_t start_addr, line_offset, line_compare;
   1111 
   1112     line_offset = s->vga.cr[0x13]
   1113         | ((s->vga.cr[0x1b] & 0x10) << 4);
   1114     line_offset <<= 3;
   1115     *pline_offset = line_offset;
   1116 
   1117     start_addr = (s->vga.cr[0x0c] << 8)
   1118         | s->vga.cr[0x0d]
   1119         | ((s->vga.cr[0x1b] & 0x01) << 16)
   1120         | ((s->vga.cr[0x1b] & 0x0c) << 15)
   1121         | ((s->vga.cr[0x1d] & 0x80) << 12);
   1122     *pstart_addr = start_addr;
   1123 
   1124     line_compare = s->vga.cr[0x18] |
   1125         ((s->vga.cr[0x07] & 0x10) << 4) |
   1126         ((s->vga.cr[0x09] & 0x40) << 3);
   1127     *pline_compare = line_compare;
   1128 }
   1129 
   1130 static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
   1131 {
   1132     uint32_t ret = 16;
   1133 
   1134     switch (s->cirrus_hidden_dac_data & 0xf) {
   1135     case 0:
   1136         ret = 15;
   1137         break;                  /* Sierra HiColor */
   1138     case 1:
   1139         ret = 16;
   1140         break;                  /* XGA HiColor */
   1141     default:
   1142         qemu_log_mask(LOG_GUEST_ERROR,
   1143                       "cirrus: invalid DAC value 0x%x in 16bpp\n",
   1144                       (s->cirrus_hidden_dac_data & 0xf));
   1145         ret = 15;               /* XXX */
   1146         break;
   1147     }
   1148     return ret;
   1149 }
   1150 
   1151 static int cirrus_get_bpp(VGACommonState *s1)
   1152 {
   1153     CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
   1154     uint32_t ret = 8;
   1155 
   1156     if ((s->vga.sr[0x07] & 0x01) != 0) {
   1157         /* Cirrus SVGA */
   1158         switch (s->vga.sr[0x07] & CIRRUS_SR7_BPP_MASK) {
   1159         case CIRRUS_SR7_BPP_8:
   1160             ret = 8;
   1161             break;
   1162         case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
   1163             ret = cirrus_get_bpp16_depth(s);
   1164             break;
   1165         case CIRRUS_SR7_BPP_24:
   1166             ret = 24;
   1167             break;
   1168         case CIRRUS_SR7_BPP_16:
   1169             ret = cirrus_get_bpp16_depth(s);
   1170             break;
   1171         case CIRRUS_SR7_BPP_32:
   1172             ret = 32;
   1173             break;
   1174         default:
   1175 #ifdef DEBUG_CIRRUS
   1176             printf("cirrus: unknown bpp - sr7=%x\n", s->vga.sr[0x7]);
   1177 #endif
   1178             ret = 8;
   1179             break;
   1180         }
   1181     } else {
   1182         /* VGA */
   1183         ret = 0;
   1184     }
   1185 
   1186     return ret;
   1187 }
   1188 
   1189 static void cirrus_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
   1190 {
   1191     int width, height;
   1192 
   1193     width = (s->cr[0x01] + 1) * 8;
   1194     height = s->cr[0x12] |
   1195         ((s->cr[0x07] & 0x02) << 7) |
   1196         ((s->cr[0x07] & 0x40) << 3);
   1197     height = (height + 1);
   1198     /* interlace support */
   1199     if (s->cr[0x1a] & 0x01)
   1200         height = height * 2;
   1201     *pwidth = width;
   1202     *pheight = height;
   1203 }
   1204 
   1205 /***************************************
   1206  *
   1207  * bank memory
   1208  *
   1209  ***************************************/
   1210 
   1211 static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
   1212 {
   1213     unsigned offset;
   1214     unsigned limit;
   1215 
   1216     if ((s->vga.gr[0x0b] & 0x01) != 0)  /* dual bank */
   1217         offset = s->vga.gr[0x09 + bank_index];
   1218     else                        /* single bank */
   1219         offset = s->vga.gr[0x09];
   1220 
   1221     if ((s->vga.gr[0x0b] & 0x20) != 0)
   1222         offset <<= 14;
   1223     else
   1224         offset <<= 12;
   1225 
   1226     if (s->real_vram_size <= offset)
   1227         limit = 0;
   1228     else
   1229         limit = s->real_vram_size - offset;
   1230 
   1231     if (((s->vga.gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {
   1232         if (limit > 0x8000) {
   1233             offset += 0x8000;
   1234             limit -= 0x8000;
   1235         } else {
   1236             limit = 0;
   1237         }
   1238     }
   1239 
   1240     if (limit > 0) {
   1241         s->cirrus_bank_base[bank_index] = offset;
   1242         s->cirrus_bank_limit[bank_index] = limit;
   1243     } else {
   1244         s->cirrus_bank_base[bank_index] = 0;
   1245         s->cirrus_bank_limit[bank_index] = 0;
   1246     }
   1247 }
   1248 
   1249 /***************************************
   1250  *
   1251  *  I/O access between 0x3c4-0x3c5
   1252  *
   1253  ***************************************/
   1254 
   1255 static int cirrus_vga_read_sr(CirrusVGAState * s)
   1256 {
   1257     switch (s->vga.sr_index) {
   1258     case 0x00:                  // Standard VGA
   1259     case 0x01:                  // Standard VGA
   1260     case 0x02:                  // Standard VGA
   1261     case 0x03:                  // Standard VGA
   1262     case 0x04:                  // Standard VGA
   1263         return s->vga.sr[s->vga.sr_index];
   1264     case 0x06:                  // Unlock Cirrus extensions
   1265         return s->vga.sr[s->vga.sr_index];
   1266     case 0x10:
   1267     case 0x30:
   1268     case 0x50:
   1269     case 0x70:                  // Graphics Cursor X
   1270     case 0x90:
   1271     case 0xb0:
   1272     case 0xd0:
   1273     case 0xf0:                  // Graphics Cursor X
   1274         return s->vga.sr[0x10];
   1275     case 0x11:
   1276     case 0x31:
   1277     case 0x51:
   1278     case 0x71:                  // Graphics Cursor Y
   1279     case 0x91:
   1280     case 0xb1:
   1281     case 0xd1:
   1282     case 0xf1:                  // Graphics Cursor Y
   1283         return s->vga.sr[0x11];
   1284     case 0x05:                  // ???
   1285     case 0x07:                  // Extended Sequencer Mode
   1286     case 0x08:                  // EEPROM Control
   1287     case 0x09:                  // Scratch Register 0
   1288     case 0x0a:                  // Scratch Register 1
   1289     case 0x0b:                  // VCLK 0
   1290     case 0x0c:                  // VCLK 1
   1291     case 0x0d:                  // VCLK 2
   1292     case 0x0e:                  // VCLK 3
   1293     case 0x0f:                  // DRAM Control
   1294     case 0x12:                  // Graphics Cursor Attribute
   1295     case 0x13:                  // Graphics Cursor Pattern Address
   1296     case 0x14:                  // Scratch Register 2
   1297     case 0x15:                  // Scratch Register 3
   1298     case 0x16:                  // Performance Tuning Register
   1299     case 0x17:                  // Configuration Readback and Extended Control
   1300     case 0x18:                  // Signature Generator Control
   1301     case 0x19:                  // Signal Generator Result
   1302     case 0x1a:                  // Signal Generator Result
   1303     case 0x1b:                  // VCLK 0 Denominator & Post
   1304     case 0x1c:                  // VCLK 1 Denominator & Post
   1305     case 0x1d:                  // VCLK 2 Denominator & Post
   1306     case 0x1e:                  // VCLK 3 Denominator & Post
   1307     case 0x1f:                  // BIOS Write Enable and MCLK select
   1308 #ifdef DEBUG_CIRRUS
   1309         printf("cirrus: handled inport sr_index %02x\n", s->vga.sr_index);
   1310 #endif
   1311         return s->vga.sr[s->vga.sr_index];
   1312     default:
   1313         qemu_log_mask(LOG_GUEST_ERROR,
   1314                       "cirrus: inport sr_index 0x%02x\n", s->vga.sr_index);
   1315         return 0xff;
   1316     }
   1317 }
   1318 
   1319 static void cirrus_vga_write_sr(CirrusVGAState * s, uint32_t val)
   1320 {
   1321     switch (s->vga.sr_index) {
   1322     case 0x00:                  // Standard VGA
   1323     case 0x01:                  // Standard VGA
   1324     case 0x02:                  // Standard VGA
   1325     case 0x03:                  // Standard VGA
   1326     case 0x04:                  // Standard VGA
   1327         s->vga.sr[s->vga.sr_index] = val & sr_mask[s->vga.sr_index];
   1328         if (s->vga.sr_index == 1)
   1329             s->vga.update_retrace_info(&s->vga);
   1330         break;
   1331     case 0x06:                  // Unlock Cirrus extensions
   1332         val &= 0x17;
   1333         if (val == 0x12) {
   1334             s->vga.sr[s->vga.sr_index] = 0x12;
   1335         } else {
   1336             s->vga.sr[s->vga.sr_index] = 0x0f;
   1337         }
   1338         break;
   1339     case 0x10:
   1340     case 0x30:
   1341     case 0x50:
   1342     case 0x70:                  // Graphics Cursor X
   1343     case 0x90:
   1344     case 0xb0:
   1345     case 0xd0:
   1346     case 0xf0:                  // Graphics Cursor X
   1347         s->vga.sr[0x10] = val;
   1348         s->vga.hw_cursor_x = (val << 3) | (s->vga.sr_index >> 5);
   1349         break;
   1350     case 0x11:
   1351     case 0x31:
   1352     case 0x51:
   1353     case 0x71:                  // Graphics Cursor Y
   1354     case 0x91:
   1355     case 0xb1:
   1356     case 0xd1:
   1357     case 0xf1:                  // Graphics Cursor Y
   1358         s->vga.sr[0x11] = val;
   1359         s->vga.hw_cursor_y = (val << 3) | (s->vga.sr_index >> 5);
   1360         break;
   1361     case 0x07:                  // Extended Sequencer Mode
   1362         cirrus_update_memory_access(s);
   1363         /* fall through */
   1364     case 0x08:                  // EEPROM Control
   1365     case 0x09:                  // Scratch Register 0
   1366     case 0x0a:                  // Scratch Register 1
   1367     case 0x0b:                  // VCLK 0
   1368     case 0x0c:                  // VCLK 1
   1369     case 0x0d:                  // VCLK 2
   1370     case 0x0e:                  // VCLK 3
   1371     case 0x0f:                  // DRAM Control
   1372     case 0x13:                  // Graphics Cursor Pattern Address
   1373     case 0x14:                  // Scratch Register 2
   1374     case 0x15:                  // Scratch Register 3
   1375     case 0x16:                  // Performance Tuning Register
   1376     case 0x18:                  // Signature Generator Control
   1377     case 0x19:                  // Signature Generator Result
   1378     case 0x1a:                  // Signature Generator Result
   1379     case 0x1b:                  // VCLK 0 Denominator & Post
   1380     case 0x1c:                  // VCLK 1 Denominator & Post
   1381     case 0x1d:                  // VCLK 2 Denominator & Post
   1382     case 0x1e:                  // VCLK 3 Denominator & Post
   1383     case 0x1f:                  // BIOS Write Enable and MCLK select
   1384         s->vga.sr[s->vga.sr_index] = val;
   1385 #ifdef DEBUG_CIRRUS
   1386         printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",
   1387                s->vga.sr_index, val);
   1388 #endif
   1389         break;
   1390     case 0x12:                  // Graphics Cursor Attribute
   1391         s->vga.sr[0x12] = val;
   1392         s->vga.force_shadow = !!(val & CIRRUS_CURSOR_SHOW);
   1393 #ifdef DEBUG_CIRRUS
   1394         printf("cirrus: cursor ctl SR12=%02x (force shadow: %d)\n",
   1395                val, s->vga.force_shadow);
   1396 #endif
   1397         break;
   1398     case 0x17:                  // Configuration Readback and Extended Control
   1399         s->vga.sr[s->vga.sr_index] = (s->vga.sr[s->vga.sr_index] & 0x38)
   1400                                    | (val & 0xc7);
   1401         cirrus_update_memory_access(s);
   1402         break;
   1403     default:
   1404         qemu_log_mask(LOG_GUEST_ERROR,
   1405                       "cirrus: outport sr_index 0x%02x, sr_value 0x%02x\n",
   1406                       s->vga.sr_index, val);
   1407         break;
   1408     }
   1409 }
   1410 
   1411 /***************************************
   1412  *
   1413  *  I/O access at 0x3c6
   1414  *
   1415  ***************************************/
   1416 
   1417 static int cirrus_read_hidden_dac(CirrusVGAState * s)
   1418 {
   1419     if (++s->cirrus_hidden_dac_lockindex == 5) {
   1420         s->cirrus_hidden_dac_lockindex = 0;
   1421         return s->cirrus_hidden_dac_data;
   1422     }
   1423     return 0xff;
   1424 }
   1425 
   1426 static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
   1427 {
   1428     if (s->cirrus_hidden_dac_lockindex == 4) {
   1429         s->cirrus_hidden_dac_data = reg_value;
   1430 #if defined(DEBUG_CIRRUS)
   1431         printf("cirrus: outport hidden DAC, value %02x\n", reg_value);
   1432 #endif
   1433     }
   1434     s->cirrus_hidden_dac_lockindex = 0;
   1435 }
   1436 
   1437 /***************************************
   1438  *
   1439  *  I/O access at 0x3c9
   1440  *
   1441  ***************************************/
   1442 
   1443 static int cirrus_vga_read_palette(CirrusVGAState * s)
   1444 {
   1445     int val;
   1446 
   1447     if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) {
   1448         val = s->cirrus_hidden_palette[(s->vga.dac_read_index & 0x0f) * 3 +
   1449                                        s->vga.dac_sub_index];
   1450     } else {
   1451         val = s->vga.palette[s->vga.dac_read_index * 3 + s->vga.dac_sub_index];
   1452     }
   1453     if (++s->vga.dac_sub_index == 3) {
   1454         s->vga.dac_sub_index = 0;
   1455         s->vga.dac_read_index++;
   1456     }
   1457     return val;
   1458 }
   1459 
   1460 static void cirrus_vga_write_palette(CirrusVGAState * s, int reg_value)
   1461 {
   1462     s->vga.dac_cache[s->vga.dac_sub_index] = reg_value;
   1463     if (++s->vga.dac_sub_index == 3) {
   1464         if ((s->vga.sr[0x12] & CIRRUS_CURSOR_HIDDENPEL)) {
   1465             memcpy(&s->cirrus_hidden_palette[(s->vga.dac_write_index & 0x0f) * 3],
   1466                    s->vga.dac_cache, 3);
   1467         } else {
   1468             memcpy(&s->vga.palette[s->vga.dac_write_index * 3], s->vga.dac_cache, 3);
   1469         }
   1470         /* XXX update cursor */
   1471         s->vga.dac_sub_index = 0;
   1472         s->vga.dac_write_index++;
   1473     }
   1474 }
   1475 
   1476 /***************************************
   1477  *
   1478  *  I/O access between 0x3ce-0x3cf
   1479  *
   1480  ***************************************/
   1481 
   1482 static int cirrus_vga_read_gr(CirrusVGAState * s, unsigned reg_index)
   1483 {
   1484     switch (reg_index) {
   1485     case 0x00: // Standard VGA, BGCOLOR 0x000000ff
   1486         return s->cirrus_shadow_gr0;
   1487     case 0x01: // Standard VGA, FGCOLOR 0x000000ff
   1488         return s->cirrus_shadow_gr1;
   1489     case 0x02:                  // Standard VGA
   1490     case 0x03:                  // Standard VGA
   1491     case 0x04:                  // Standard VGA
   1492     case 0x06:                  // Standard VGA
   1493     case 0x07:                  // Standard VGA
   1494     case 0x08:                  // Standard VGA
   1495         return s->vga.gr[s->vga.gr_index];
   1496     case 0x05:                  // Standard VGA, Cirrus extended mode
   1497     default:
   1498         break;
   1499     }
   1500 
   1501     if (reg_index < 0x3a) {
   1502         return s->vga.gr[reg_index];
   1503     } else {
   1504         qemu_log_mask(LOG_GUEST_ERROR,
   1505                       "cirrus: inport gr_index 0x%02x\n", reg_index);
   1506         return 0xff;
   1507     }
   1508 }
   1509 
   1510 static void
   1511 cirrus_vga_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
   1512 {
   1513     trace_vga_cirrus_write_gr(reg_index, reg_value);
   1514     switch (reg_index) {
   1515     case 0x00:                  // Standard VGA, BGCOLOR 0x000000ff
   1516         s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
   1517         s->cirrus_shadow_gr0 = reg_value;
   1518         break;
   1519     case 0x01:                  // Standard VGA, FGCOLOR 0x000000ff
   1520         s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
   1521         s->cirrus_shadow_gr1 = reg_value;
   1522         break;
   1523     case 0x02:                  // Standard VGA
   1524     case 0x03:                  // Standard VGA
   1525     case 0x04:                  // Standard VGA
   1526     case 0x06:                  // Standard VGA
   1527     case 0x07:                  // Standard VGA
   1528     case 0x08:                  // Standard VGA
   1529         s->vga.gr[reg_index] = reg_value & gr_mask[reg_index];
   1530         break;
   1531     case 0x05:                  // Standard VGA, Cirrus extended mode
   1532         s->vga.gr[reg_index] = reg_value & 0x7f;
   1533         cirrus_update_memory_access(s);
   1534         break;
   1535     case 0x09:                  // bank offset #0
   1536     case 0x0A:                  // bank offset #1
   1537         s->vga.gr[reg_index] = reg_value;
   1538         cirrus_update_bank_ptr(s, 0);
   1539         cirrus_update_bank_ptr(s, 1);
   1540         cirrus_update_memory_access(s);
   1541         break;
   1542     case 0x0B:
   1543         s->vga.gr[reg_index] = reg_value;
   1544         cirrus_update_bank_ptr(s, 0);
   1545         cirrus_update_bank_ptr(s, 1);
   1546         cirrus_update_memory_access(s);
   1547         break;
   1548     case 0x10:                  // BGCOLOR 0x0000ff00
   1549     case 0x11:                  // FGCOLOR 0x0000ff00
   1550     case 0x12:                  // BGCOLOR 0x00ff0000
   1551     case 0x13:                  // FGCOLOR 0x00ff0000
   1552     case 0x14:                  // BGCOLOR 0xff000000
   1553     case 0x15:                  // FGCOLOR 0xff000000
   1554     case 0x20:                  // BLT WIDTH 0x0000ff
   1555     case 0x22:                  // BLT HEIGHT 0x0000ff
   1556     case 0x24:                  // BLT DEST PITCH 0x0000ff
   1557     case 0x26:                  // BLT SRC PITCH 0x0000ff
   1558     case 0x28:                  // BLT DEST ADDR 0x0000ff
   1559     case 0x29:                  // BLT DEST ADDR 0x00ff00
   1560     case 0x2c:                  // BLT SRC ADDR 0x0000ff
   1561     case 0x2d:                  // BLT SRC ADDR 0x00ff00
   1562     case 0x2f:                  // BLT WRITEMASK
   1563     case 0x30:                  // BLT MODE
   1564     case 0x32:                  // RASTER OP
   1565     case 0x33:                  // BLT MODEEXT
   1566     case 0x34:                  // BLT TRANSPARENT COLOR 0x00ff
   1567     case 0x35:                  // BLT TRANSPARENT COLOR 0xff00
   1568     case 0x38:                  // BLT TRANSPARENT COLOR MASK 0x00ff
   1569     case 0x39:                  // BLT TRANSPARENT COLOR MASK 0xff00
   1570         s->vga.gr[reg_index] = reg_value;
   1571         break;
   1572     case 0x21:                  // BLT WIDTH 0x001f00
   1573     case 0x23:                  // BLT HEIGHT 0x001f00
   1574     case 0x25:                  // BLT DEST PITCH 0x001f00
   1575     case 0x27:                  // BLT SRC PITCH 0x001f00
   1576         s->vga.gr[reg_index] = reg_value & 0x1f;
   1577         break;
   1578     case 0x2a:                  // BLT DEST ADDR 0x3f0000
   1579         s->vga.gr[reg_index] = reg_value & 0x3f;
   1580         /* if auto start mode, starts bit blt now */
   1581         if (s->vga.gr[0x31] & CIRRUS_BLT_AUTOSTART) {
   1582             cirrus_bitblt_start(s);
   1583         }
   1584         break;
   1585     case 0x2e:                  // BLT SRC ADDR 0x3f0000
   1586         s->vga.gr[reg_index] = reg_value & 0x3f;
   1587         break;
   1588     case 0x31:                  // BLT STATUS/START
   1589         cirrus_write_bitblt(s, reg_value);
   1590         break;
   1591     default:
   1592         qemu_log_mask(LOG_GUEST_ERROR,
   1593                       "cirrus: outport gr_index 0x%02x, gr_value 0x%02x\n",
   1594                       reg_index, reg_value);
   1595         break;
   1596     }
   1597 }
   1598 
   1599 /***************************************
   1600  *
   1601  *  I/O access between 0x3d4-0x3d5
   1602  *
   1603  ***************************************/
   1604 
   1605 static int cirrus_vga_read_cr(CirrusVGAState * s, unsigned reg_index)
   1606 {
   1607     switch (reg_index) {
   1608     case 0x00:                  // Standard VGA
   1609     case 0x01:                  // Standard VGA
   1610     case 0x02:                  // Standard VGA
   1611     case 0x03:                  // Standard VGA
   1612     case 0x04:                  // Standard VGA
   1613     case 0x05:                  // Standard VGA
   1614     case 0x06:                  // Standard VGA
   1615     case 0x07:                  // Standard VGA
   1616     case 0x08:                  // Standard VGA
   1617     case 0x09:                  // Standard VGA
   1618     case 0x0a:                  // Standard VGA
   1619     case 0x0b:                  // Standard VGA
   1620     case 0x0c:                  // Standard VGA
   1621     case 0x0d:                  // Standard VGA
   1622     case 0x0e:                  // Standard VGA
   1623     case 0x0f:                  // Standard VGA
   1624     case 0x10:                  // Standard VGA
   1625     case 0x11:                  // Standard VGA
   1626     case 0x12:                  // Standard VGA
   1627     case 0x13:                  // Standard VGA
   1628     case 0x14:                  // Standard VGA
   1629     case 0x15:                  // Standard VGA
   1630     case 0x16:                  // Standard VGA
   1631     case 0x17:                  // Standard VGA
   1632     case 0x18:                  // Standard VGA
   1633         return s->vga.cr[s->vga.cr_index];
   1634     case 0x24:                  // Attribute Controller Toggle Readback (R)
   1635         return (s->vga.ar_flip_flop << 7);
   1636     case 0x19:                  // Interlace End
   1637     case 0x1a:                  // Miscellaneous Control
   1638     case 0x1b:                  // Extended Display Control
   1639     case 0x1c:                  // Sync Adjust and Genlock
   1640     case 0x1d:                  // Overlay Extended Control
   1641     case 0x22:                  // Graphics Data Latches Readback (R)
   1642     case 0x25:                  // Part Status
   1643     case 0x27:                  // Part ID (R)
   1644         return s->vga.cr[s->vga.cr_index];
   1645     case 0x26:                  // Attribute Controller Index Readback (R)
   1646         return s->vga.ar_index & 0x3f;
   1647     default:
   1648         qemu_log_mask(LOG_GUEST_ERROR,
   1649                       "cirrus: inport cr_index 0x%02x\n", reg_index);
   1650         return 0xff;
   1651     }
   1652 }
   1653 
   1654 static void cirrus_vga_write_cr(CirrusVGAState * s, int reg_value)
   1655 {
   1656     switch (s->vga.cr_index) {
   1657     case 0x00:                  // Standard VGA
   1658     case 0x01:                  // Standard VGA
   1659     case 0x02:                  // Standard VGA
   1660     case 0x03:                  // Standard VGA
   1661     case 0x04:                  // Standard VGA
   1662     case 0x05:                  // Standard VGA
   1663     case 0x06:                  // Standard VGA
   1664     case 0x07:                  // Standard VGA
   1665     case 0x08:                  // Standard VGA
   1666     case 0x09:                  // Standard VGA
   1667     case 0x0a:                  // Standard VGA
   1668     case 0x0b:                  // Standard VGA
   1669     case 0x0c:                  // Standard VGA
   1670     case 0x0d:                  // Standard VGA
   1671     case 0x0e:                  // Standard VGA
   1672     case 0x0f:                  // Standard VGA
   1673     case 0x10:                  // Standard VGA
   1674     case 0x11:                  // Standard VGA
   1675     case 0x12:                  // Standard VGA
   1676     case 0x13:                  // Standard VGA
   1677     case 0x14:                  // Standard VGA
   1678     case 0x15:                  // Standard VGA
   1679     case 0x16:                  // Standard VGA
   1680     case 0x17:                  // Standard VGA
   1681     case 0x18:                  // Standard VGA
   1682         /* handle CR0-7 protection */
   1683         if ((s->vga.cr[0x11] & 0x80) && s->vga.cr_index <= 7) {
   1684             /* can always write bit 4 of CR7 */
   1685             if (s->vga.cr_index == 7)
   1686                 s->vga.cr[7] = (s->vga.cr[7] & ~0x10) | (reg_value & 0x10);
   1687             return;
   1688         }
   1689         s->vga.cr[s->vga.cr_index] = reg_value;
   1690         switch(s->vga.cr_index) {
   1691         case 0x00:
   1692         case 0x04:
   1693         case 0x05:
   1694         case 0x06:
   1695         case 0x07:
   1696         case 0x11:
   1697         case 0x17:
   1698             s->vga.update_retrace_info(&s->vga);
   1699             break;
   1700         }
   1701         break;
   1702     case 0x19:                  // Interlace End
   1703     case 0x1a:                  // Miscellaneous Control
   1704     case 0x1b:                  // Extended Display Control
   1705     case 0x1c:                  // Sync Adjust and Genlock
   1706     case 0x1d:                  // Overlay Extended Control
   1707         s->vga.cr[s->vga.cr_index] = reg_value;
   1708 #ifdef DEBUG_CIRRUS
   1709         printf("cirrus: handled outport cr_index %02x, cr_value %02x\n",
   1710                s->vga.cr_index, reg_value);
   1711 #endif
   1712         break;
   1713     case 0x22:                  // Graphics Data Latches Readback (R)
   1714     case 0x24:                  // Attribute Controller Toggle Readback (R)
   1715     case 0x26:                  // Attribute Controller Index Readback (R)
   1716     case 0x27:                  // Part ID (R)
   1717         break;
   1718     case 0x25:                  // Part Status
   1719     default:
   1720         qemu_log_mask(LOG_GUEST_ERROR,
   1721                       "cirrus: outport cr_index 0x%02x, cr_value 0x%02x\n",
   1722                       s->vga.cr_index, reg_value);
   1723         break;
   1724     }
   1725 }
   1726 
   1727 /***************************************
   1728  *
   1729  *  memory-mapped I/O (bitblt)
   1730  *
   1731  ***************************************/
   1732 
   1733 static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address)
   1734 {
   1735     int value = 0xff;
   1736 
   1737     switch (address) {
   1738     case (CIRRUS_MMIO_BLTBGCOLOR + 0):
   1739         value = cirrus_vga_read_gr(s, 0x00);
   1740         break;
   1741     case (CIRRUS_MMIO_BLTBGCOLOR + 1):
   1742         value = cirrus_vga_read_gr(s, 0x10);
   1743         break;
   1744     case (CIRRUS_MMIO_BLTBGCOLOR + 2):
   1745         value = cirrus_vga_read_gr(s, 0x12);
   1746         break;
   1747     case (CIRRUS_MMIO_BLTBGCOLOR + 3):
   1748         value = cirrus_vga_read_gr(s, 0x14);
   1749         break;
   1750     case (CIRRUS_MMIO_BLTFGCOLOR + 0):
   1751         value = cirrus_vga_read_gr(s, 0x01);
   1752         break;
   1753     case (CIRRUS_MMIO_BLTFGCOLOR + 1):
   1754         value = cirrus_vga_read_gr(s, 0x11);
   1755         break;
   1756     case (CIRRUS_MMIO_BLTFGCOLOR + 2):
   1757         value = cirrus_vga_read_gr(s, 0x13);
   1758         break;
   1759     case (CIRRUS_MMIO_BLTFGCOLOR + 3):
   1760         value = cirrus_vga_read_gr(s, 0x15);
   1761         break;
   1762     case (CIRRUS_MMIO_BLTWIDTH + 0):
   1763         value = cirrus_vga_read_gr(s, 0x20);
   1764         break;
   1765     case (CIRRUS_MMIO_BLTWIDTH + 1):
   1766         value = cirrus_vga_read_gr(s, 0x21);
   1767         break;
   1768     case (CIRRUS_MMIO_BLTHEIGHT + 0):
   1769         value = cirrus_vga_read_gr(s, 0x22);
   1770         break;
   1771     case (CIRRUS_MMIO_BLTHEIGHT + 1):
   1772         value = cirrus_vga_read_gr(s, 0x23);
   1773         break;
   1774     case (CIRRUS_MMIO_BLTDESTPITCH + 0):
   1775         value = cirrus_vga_read_gr(s, 0x24);
   1776         break;
   1777     case (CIRRUS_MMIO_BLTDESTPITCH + 1):
   1778         value = cirrus_vga_read_gr(s, 0x25);
   1779         break;
   1780     case (CIRRUS_MMIO_BLTSRCPITCH + 0):
   1781         value = cirrus_vga_read_gr(s, 0x26);
   1782         break;
   1783     case (CIRRUS_MMIO_BLTSRCPITCH + 1):
   1784         value = cirrus_vga_read_gr(s, 0x27);
   1785         break;
   1786     case (CIRRUS_MMIO_BLTDESTADDR + 0):
   1787         value = cirrus_vga_read_gr(s, 0x28);
   1788         break;
   1789     case (CIRRUS_MMIO_BLTDESTADDR + 1):
   1790         value = cirrus_vga_read_gr(s, 0x29);
   1791         break;
   1792     case (CIRRUS_MMIO_BLTDESTADDR + 2):
   1793         value = cirrus_vga_read_gr(s, 0x2a);
   1794         break;
   1795     case (CIRRUS_MMIO_BLTSRCADDR + 0):
   1796         value = cirrus_vga_read_gr(s, 0x2c);
   1797         break;
   1798     case (CIRRUS_MMIO_BLTSRCADDR + 1):
   1799         value = cirrus_vga_read_gr(s, 0x2d);
   1800         break;
   1801     case (CIRRUS_MMIO_BLTSRCADDR + 2):
   1802         value = cirrus_vga_read_gr(s, 0x2e);
   1803         break;
   1804     case CIRRUS_MMIO_BLTWRITEMASK:
   1805         value = cirrus_vga_read_gr(s, 0x2f);
   1806         break;
   1807     case CIRRUS_MMIO_BLTMODE:
   1808         value = cirrus_vga_read_gr(s, 0x30);
   1809         break;
   1810     case CIRRUS_MMIO_BLTROP:
   1811         value = cirrus_vga_read_gr(s, 0x32);
   1812         break;
   1813     case CIRRUS_MMIO_BLTMODEEXT:
   1814         value = cirrus_vga_read_gr(s, 0x33);
   1815         break;
   1816     case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
   1817         value = cirrus_vga_read_gr(s, 0x34);
   1818         break;
   1819     case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
   1820         value = cirrus_vga_read_gr(s, 0x35);
   1821         break;
   1822     case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
   1823         value = cirrus_vga_read_gr(s, 0x38);
   1824         break;
   1825     case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
   1826         value = cirrus_vga_read_gr(s, 0x39);
   1827         break;
   1828     case CIRRUS_MMIO_BLTSTATUS:
   1829         value = cirrus_vga_read_gr(s, 0x31);
   1830         break;
   1831     default:
   1832         qemu_log_mask(LOG_GUEST_ERROR,
   1833                       "cirrus: mmio read - address 0x%04x\n", address);
   1834         break;
   1835     }
   1836 
   1837     trace_vga_cirrus_write_blt(address, value);
   1838     return (uint8_t) value;
   1839 }
   1840 
   1841 static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address,
   1842                                   uint8_t value)
   1843 {
   1844     trace_vga_cirrus_write_blt(address, value);
   1845     switch (address) {
   1846     case (CIRRUS_MMIO_BLTBGCOLOR + 0):
   1847         cirrus_vga_write_gr(s, 0x00, value);
   1848         break;
   1849     case (CIRRUS_MMIO_BLTBGCOLOR + 1):
   1850         cirrus_vga_write_gr(s, 0x10, value);
   1851         break;
   1852     case (CIRRUS_MMIO_BLTBGCOLOR + 2):
   1853         cirrus_vga_write_gr(s, 0x12, value);
   1854         break;
   1855     case (CIRRUS_MMIO_BLTBGCOLOR + 3):
   1856         cirrus_vga_write_gr(s, 0x14, value);
   1857         break;
   1858     case (CIRRUS_MMIO_BLTFGCOLOR + 0):
   1859         cirrus_vga_write_gr(s, 0x01, value);
   1860         break;
   1861     case (CIRRUS_MMIO_BLTFGCOLOR + 1):
   1862         cirrus_vga_write_gr(s, 0x11, value);
   1863         break;
   1864     case (CIRRUS_MMIO_BLTFGCOLOR + 2):
   1865         cirrus_vga_write_gr(s, 0x13, value);
   1866         break;
   1867     case (CIRRUS_MMIO_BLTFGCOLOR + 3):
   1868         cirrus_vga_write_gr(s, 0x15, value);
   1869         break;
   1870     case (CIRRUS_MMIO_BLTWIDTH + 0):
   1871         cirrus_vga_write_gr(s, 0x20, value);
   1872         break;
   1873     case (CIRRUS_MMIO_BLTWIDTH + 1):
   1874         cirrus_vga_write_gr(s, 0x21, value);
   1875         break;
   1876     case (CIRRUS_MMIO_BLTHEIGHT + 0):
   1877         cirrus_vga_write_gr(s, 0x22, value);
   1878         break;
   1879     case (CIRRUS_MMIO_BLTHEIGHT + 1):
   1880         cirrus_vga_write_gr(s, 0x23, value);
   1881         break;
   1882     case (CIRRUS_MMIO_BLTDESTPITCH + 0):
   1883         cirrus_vga_write_gr(s, 0x24, value);
   1884         break;
   1885     case (CIRRUS_MMIO_BLTDESTPITCH + 1):
   1886         cirrus_vga_write_gr(s, 0x25, value);
   1887         break;
   1888     case (CIRRUS_MMIO_BLTSRCPITCH + 0):
   1889         cirrus_vga_write_gr(s, 0x26, value);
   1890         break;
   1891     case (CIRRUS_MMIO_BLTSRCPITCH + 1):
   1892         cirrus_vga_write_gr(s, 0x27, value);
   1893         break;
   1894     case (CIRRUS_MMIO_BLTDESTADDR + 0):
   1895         cirrus_vga_write_gr(s, 0x28, value);
   1896         break;
   1897     case (CIRRUS_MMIO_BLTDESTADDR + 1):
   1898         cirrus_vga_write_gr(s, 0x29, value);
   1899         break;
   1900     case (CIRRUS_MMIO_BLTDESTADDR + 2):
   1901         cirrus_vga_write_gr(s, 0x2a, value);
   1902         break;
   1903     case (CIRRUS_MMIO_BLTDESTADDR + 3):
   1904         /* ignored */
   1905         break;
   1906     case (CIRRUS_MMIO_BLTSRCADDR + 0):
   1907         cirrus_vga_write_gr(s, 0x2c, value);
   1908         break;
   1909     case (CIRRUS_MMIO_BLTSRCADDR + 1):
   1910         cirrus_vga_write_gr(s, 0x2d, value);
   1911         break;
   1912     case (CIRRUS_MMIO_BLTSRCADDR + 2):
   1913         cirrus_vga_write_gr(s, 0x2e, value);
   1914         break;
   1915     case CIRRUS_MMIO_BLTWRITEMASK:
   1916         cirrus_vga_write_gr(s, 0x2f, value);
   1917         break;
   1918     case CIRRUS_MMIO_BLTMODE:
   1919         cirrus_vga_write_gr(s, 0x30, value);
   1920         break;
   1921     case CIRRUS_MMIO_BLTROP:
   1922         cirrus_vga_write_gr(s, 0x32, value);
   1923         break;
   1924     case CIRRUS_MMIO_BLTMODEEXT:
   1925         cirrus_vga_write_gr(s, 0x33, value);
   1926         break;
   1927     case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
   1928         cirrus_vga_write_gr(s, 0x34, value);
   1929         break;
   1930     case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
   1931         cirrus_vga_write_gr(s, 0x35, value);
   1932         break;
   1933     case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
   1934         cirrus_vga_write_gr(s, 0x38, value);
   1935         break;
   1936     case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
   1937         cirrus_vga_write_gr(s, 0x39, value);
   1938         break;
   1939     case CIRRUS_MMIO_BLTSTATUS:
   1940         cirrus_vga_write_gr(s, 0x31, value);
   1941         break;
   1942     default:
   1943         qemu_log_mask(LOG_GUEST_ERROR,
   1944                       "cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n",
   1945                       address, value);
   1946         break;
   1947     }
   1948 }
   1949 
   1950 /***************************************
   1951  *
   1952  *  write mode 4/5
   1953  *
   1954  ***************************************/
   1955 
   1956 static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
   1957                                              unsigned mode,
   1958                                              unsigned offset,
   1959                                              uint32_t mem_value)
   1960 {
   1961     int x;
   1962     unsigned val = mem_value;
   1963     uint8_t *dst;
   1964 
   1965     for (x = 0; x < 8; x++) {
   1966         dst = s->vga.vram_ptr + ((offset + x) & s->cirrus_addr_mask);
   1967         if (val & 0x80) {
   1968             *dst = s->cirrus_shadow_gr1;
   1969         } else if (mode == 5) {
   1970             *dst = s->cirrus_shadow_gr0;
   1971         }
   1972         val <<= 1;
   1973     }
   1974     memory_region_set_dirty(&s->vga.vram, offset, 8);
   1975 }
   1976 
   1977 static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
   1978                                               unsigned mode,
   1979                                               unsigned offset,
   1980                                               uint32_t mem_value)
   1981 {
   1982     int x;
   1983     unsigned val = mem_value;
   1984     uint8_t *dst;
   1985 
   1986     for (x = 0; x < 8; x++) {
   1987         dst = s->vga.vram_ptr + ((offset + 2 * x) & s->cirrus_addr_mask & ~1);
   1988         if (val & 0x80) {
   1989             *dst = s->cirrus_shadow_gr1;
   1990             *(dst + 1) = s->vga.gr[0x11];
   1991         } else if (mode == 5) {
   1992             *dst = s->cirrus_shadow_gr0;
   1993             *(dst + 1) = s->vga.gr[0x10];
   1994         }
   1995         val <<= 1;
   1996     }
   1997     memory_region_set_dirty(&s->vga.vram, offset, 16);
   1998 }
   1999 
   2000 /***************************************
   2001  *
   2002  *  memory access between 0xa0000-0xbffff
   2003  *
   2004  ***************************************/
   2005 
   2006 static uint64_t cirrus_vga_mem_read(void *opaque,
   2007                                     hwaddr addr,
   2008                                     uint32_t size)
   2009 {
   2010     CirrusVGAState *s = opaque;
   2011     unsigned bank_index;
   2012     unsigned bank_offset;
   2013     uint32_t val;
   2014 
   2015     if ((s->vga.sr[0x07] & 0x01) == 0) {
   2016         return vga_mem_readb(&s->vga, addr);
   2017     }
   2018 
   2019     if (addr < 0x10000) {
   2020         /* XXX handle bitblt */
   2021         /* video memory */
   2022         bank_index = addr >> 15;
   2023         bank_offset = addr & 0x7fff;
   2024         if (bank_offset < s->cirrus_bank_limit[bank_index]) {
   2025             bank_offset += s->cirrus_bank_base[bank_index];
   2026             if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
   2027                 bank_offset <<= 4;
   2028             } else if (s->vga.gr[0x0B] & 0x02) {
   2029                 bank_offset <<= 3;
   2030             }
   2031             bank_offset &= s->cirrus_addr_mask;
   2032             val = *(s->vga.vram_ptr + bank_offset);
   2033         } else
   2034             val = 0xff;
   2035     } else if (addr >= 0x18000 && addr < 0x18100) {
   2036         /* memory-mapped I/O */
   2037         val = 0xff;
   2038         if ((s->vga.sr[0x17] & 0x44) == 0x04) {
   2039             val = cirrus_mmio_blt_read(s, addr & 0xff);
   2040         }
   2041     } else {
   2042         val = 0xff;
   2043         qemu_log_mask(LOG_GUEST_ERROR,
   2044                       "cirrus: mem_readb 0x" TARGET_FMT_plx "\n", addr);
   2045     }
   2046     return val;
   2047 }
   2048 
   2049 static void cirrus_vga_mem_write(void *opaque,
   2050                                  hwaddr addr,
   2051                                  uint64_t mem_value,
   2052                                  uint32_t size)
   2053 {
   2054     CirrusVGAState *s = opaque;
   2055     unsigned bank_index;
   2056     unsigned bank_offset;
   2057     unsigned mode;
   2058 
   2059     if ((s->vga.sr[0x07] & 0x01) == 0) {
   2060         vga_mem_writeb(&s->vga, addr, mem_value);
   2061         return;
   2062     }
   2063 
   2064     if (addr < 0x10000) {
   2065         if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
   2066             /* bitblt */
   2067             *s->cirrus_srcptr++ = (uint8_t) mem_value;
   2068             if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
   2069                 cirrus_bitblt_cputovideo_next(s);
   2070             }
   2071         } else {
   2072             /* video memory */
   2073             bank_index = addr >> 15;
   2074             bank_offset = addr & 0x7fff;
   2075             if (bank_offset < s->cirrus_bank_limit[bank_index]) {
   2076                 bank_offset += s->cirrus_bank_base[bank_index];
   2077                 if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
   2078                     bank_offset <<= 4;
   2079                 } else if (s->vga.gr[0x0B] & 0x02) {
   2080                     bank_offset <<= 3;
   2081                 }
   2082                 bank_offset &= s->cirrus_addr_mask;
   2083                 mode = s->vga.gr[0x05] & 0x7;
   2084                 if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
   2085                     *(s->vga.vram_ptr + bank_offset) = mem_value;
   2086                     memory_region_set_dirty(&s->vga.vram, bank_offset,
   2087                                             sizeof(mem_value));
   2088                 } else {
   2089                     if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
   2090                         cirrus_mem_writeb_mode4and5_8bpp(s, mode,
   2091                                                          bank_offset,
   2092                                                          mem_value);
   2093                     } else {
   2094                         cirrus_mem_writeb_mode4and5_16bpp(s, mode,
   2095                                                           bank_offset,
   2096                                                           mem_value);
   2097                     }
   2098                 }
   2099             }
   2100         }
   2101     } else if (addr >= 0x18000 && addr < 0x18100) {
   2102         /* memory-mapped I/O */
   2103         if ((s->vga.sr[0x17] & 0x44) == 0x04) {
   2104             cirrus_mmio_blt_write(s, addr & 0xff, mem_value);
   2105         }
   2106     } else {
   2107         qemu_log_mask(LOG_GUEST_ERROR,
   2108                       "cirrus: mem_writeb 0x" TARGET_FMT_plx " "
   2109                       "value 0x%02" PRIx64 "\n", addr, mem_value);
   2110     }
   2111 }
   2112 
   2113 static const MemoryRegionOps cirrus_vga_mem_ops = {
   2114     .read = cirrus_vga_mem_read,
   2115     .write = cirrus_vga_mem_write,
   2116     .endianness = DEVICE_LITTLE_ENDIAN,
   2117     .impl = {
   2118         .min_access_size = 1,
   2119         .max_access_size = 1,
   2120     },
   2121 };
   2122 
   2123 /***************************************
   2124  *
   2125  *  hardware cursor
   2126  *
   2127  ***************************************/
   2128 
   2129 static inline void invalidate_cursor1(CirrusVGAState *s)
   2130 {
   2131     if (s->last_hw_cursor_size) {
   2132         vga_invalidate_scanlines(&s->vga,
   2133                                  s->last_hw_cursor_y + s->last_hw_cursor_y_start,
   2134                                  s->last_hw_cursor_y + s->last_hw_cursor_y_end);
   2135     }
   2136 }
   2137 
   2138 static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s)
   2139 {
   2140     const uint8_t *src;
   2141     uint32_t content;
   2142     int y, y_min, y_max;
   2143 
   2144     src = s->vga.vram_ptr + s->real_vram_size - 16 * KiB;
   2145     if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
   2146         src += (s->vga.sr[0x13] & 0x3c) * 256;
   2147         y_min = 64;
   2148         y_max = -1;
   2149         for(y = 0; y < 64; y++) {
   2150             content = ((uint32_t *)src)[0] |
   2151                 ((uint32_t *)src)[1] |
   2152                 ((uint32_t *)src)[2] |
   2153                 ((uint32_t *)src)[3];
   2154             if (content) {
   2155                 if (y < y_min)
   2156                     y_min = y;
   2157                 if (y > y_max)
   2158                     y_max = y;
   2159             }
   2160             src += 16;
   2161         }
   2162     } else {
   2163         src += (s->vga.sr[0x13] & 0x3f) * 256;
   2164         y_min = 32;
   2165         y_max = -1;
   2166         for(y = 0; y < 32; y++) {
   2167             content = ((uint32_t *)src)[0] |
   2168                 ((uint32_t *)(src + 128))[0];
   2169             if (content) {
   2170                 if (y < y_min)
   2171                     y_min = y;
   2172                 if (y > y_max)
   2173                     y_max = y;
   2174             }
   2175             src += 4;
   2176         }
   2177     }
   2178     if (y_min > y_max) {
   2179         s->last_hw_cursor_y_start = 0;
   2180         s->last_hw_cursor_y_end = 0;
   2181     } else {
   2182         s->last_hw_cursor_y_start = y_min;
   2183         s->last_hw_cursor_y_end = y_max + 1;
   2184     }
   2185 }
   2186 
   2187 /* NOTE: we do not currently handle the cursor bitmap change, so we
   2188    update the cursor only if it moves. */
   2189 static void cirrus_cursor_invalidate(VGACommonState *s1)
   2190 {
   2191     CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
   2192     int size;
   2193 
   2194     if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW)) {
   2195         size = 0;
   2196     } else {
   2197         if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE)
   2198             size = 64;
   2199         else
   2200             size = 32;
   2201     }
   2202     /* invalidate last cursor and new cursor if any change */
   2203     if (s->last_hw_cursor_size != size ||
   2204         s->last_hw_cursor_x != s->vga.hw_cursor_x ||
   2205         s->last_hw_cursor_y != s->vga.hw_cursor_y) {
   2206 
   2207         invalidate_cursor1(s);
   2208 
   2209         s->last_hw_cursor_size = size;
   2210         s->last_hw_cursor_x = s->vga.hw_cursor_x;
   2211         s->last_hw_cursor_y = s->vga.hw_cursor_y;
   2212         /* compute the real cursor min and max y */
   2213         cirrus_cursor_compute_yrange(s);
   2214         invalidate_cursor1(s);
   2215     }
   2216 }
   2217 
   2218 static void vga_draw_cursor_line(uint8_t *d1,
   2219                                  const uint8_t *src1,
   2220                                  int poffset, int w,
   2221                                  unsigned int color0,
   2222                                  unsigned int color1,
   2223                                  unsigned int color_xor)
   2224 {
   2225     const uint8_t *plane0, *plane1;
   2226     int x, b0, b1;
   2227     uint8_t *d;
   2228 
   2229     d = d1;
   2230     plane0 = src1;
   2231     plane1 = src1 + poffset;
   2232     for (x = 0; x < w; x++) {
   2233         b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
   2234         b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
   2235         switch (b0 | (b1 << 1)) {
   2236         case 0:
   2237             break;
   2238         case 1:
   2239             ((uint32_t *)d)[0] ^= color_xor;
   2240             break;
   2241         case 2:
   2242             ((uint32_t *)d)[0] = color0;
   2243             break;
   2244         case 3:
   2245             ((uint32_t *)d)[0] = color1;
   2246             break;
   2247         }
   2248         d += 4;
   2249     }
   2250 }
   2251 
   2252 static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
   2253 {
   2254     CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
   2255     int w, h, x1, x2, poffset;
   2256     unsigned int color0, color1;
   2257     const uint8_t *palette, *src;
   2258     uint32_t content;
   2259 
   2260     if (!(s->vga.sr[0x12] & CIRRUS_CURSOR_SHOW))
   2261         return;
   2262     /* fast test to see if the cursor intersects with the scan line */
   2263     if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
   2264         h = 64;
   2265     } else {
   2266         h = 32;
   2267     }
   2268     if (scr_y < s->vga.hw_cursor_y ||
   2269         scr_y >= (s->vga.hw_cursor_y + h)) {
   2270         return;
   2271     }
   2272 
   2273     src = s->vga.vram_ptr + s->real_vram_size - 16 * KiB;
   2274     if (s->vga.sr[0x12] & CIRRUS_CURSOR_LARGE) {
   2275         src += (s->vga.sr[0x13] & 0x3c) * 256;
   2276         src += (scr_y - s->vga.hw_cursor_y) * 16;
   2277         poffset = 8;
   2278         content = ((uint32_t *)src)[0] |
   2279             ((uint32_t *)src)[1] |
   2280             ((uint32_t *)src)[2] |
   2281             ((uint32_t *)src)[3];
   2282     } else {
   2283         src += (s->vga.sr[0x13] & 0x3f) * 256;
   2284         src += (scr_y - s->vga.hw_cursor_y) * 4;
   2285 
   2286 
   2287         poffset = 128;
   2288         content = ((uint32_t *)src)[0] |
   2289             ((uint32_t *)(src + 128))[0];
   2290     }
   2291     /* if nothing to draw, no need to continue */
   2292     if (!content)
   2293         return;
   2294     w = h;
   2295 
   2296     x1 = s->vga.hw_cursor_x;
   2297     if (x1 >= s->vga.last_scr_width)
   2298         return;
   2299     x2 = s->vga.hw_cursor_x + w;
   2300     if (x2 > s->vga.last_scr_width)
   2301         x2 = s->vga.last_scr_width;
   2302     w = x2 - x1;
   2303     palette = s->cirrus_hidden_palette;
   2304     color0 = rgb_to_pixel32(c6_to_8(palette[0x0 * 3]),
   2305                             c6_to_8(palette[0x0 * 3 + 1]),
   2306                             c6_to_8(palette[0x0 * 3 + 2]));
   2307     color1 = rgb_to_pixel32(c6_to_8(palette[0xf * 3]),
   2308                             c6_to_8(palette[0xf * 3 + 1]),
   2309                             c6_to_8(palette[0xf * 3 + 2]));
   2310     d1 += x1 * 4;
   2311     vga_draw_cursor_line(d1, src, poffset, w, color0, color1, 0xffffff);
   2312 }
   2313 
   2314 /***************************************
   2315  *
   2316  *  LFB memory access
   2317  *
   2318  ***************************************/
   2319 
   2320 static uint64_t cirrus_linear_read(void *opaque, hwaddr addr,
   2321                                    unsigned size)
   2322 {
   2323     CirrusVGAState *s = opaque;
   2324     uint32_t ret;
   2325 
   2326     addr &= s->cirrus_addr_mask;
   2327 
   2328     if (((s->vga.sr[0x17] & 0x44) == 0x44) &&
   2329         ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
   2330         /* memory-mapped I/O */
   2331         ret = cirrus_mmio_blt_read(s, addr & 0xff);
   2332     } else if (0) {
   2333         /* XXX handle bitblt */
   2334         ret = 0xff;
   2335     } else {
   2336         /* video memory */
   2337         if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
   2338             addr <<= 4;
   2339         } else if (s->vga.gr[0x0B] & 0x02) {
   2340             addr <<= 3;
   2341         }
   2342         addr &= s->cirrus_addr_mask;
   2343         ret = *(s->vga.vram_ptr + addr);
   2344     }
   2345 
   2346     return ret;
   2347 }
   2348 
   2349 static void cirrus_linear_write(void *opaque, hwaddr addr,
   2350                                 uint64_t val, unsigned size)
   2351 {
   2352     CirrusVGAState *s = opaque;
   2353     unsigned mode;
   2354 
   2355     addr &= s->cirrus_addr_mask;
   2356 
   2357     if (((s->vga.sr[0x17] & 0x44) == 0x44) &&
   2358         ((addr & s->linear_mmio_mask) ==  s->linear_mmio_mask)) {
   2359         /* memory-mapped I/O */
   2360         cirrus_mmio_blt_write(s, addr & 0xff, val);
   2361     } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
   2362         /* bitblt */
   2363         *s->cirrus_srcptr++ = (uint8_t) val;
   2364         if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
   2365             cirrus_bitblt_cputovideo_next(s);
   2366         }
   2367     } else {
   2368         /* video memory */
   2369         if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
   2370             addr <<= 4;
   2371         } else if (s->vga.gr[0x0B] & 0x02) {
   2372             addr <<= 3;
   2373         }
   2374         addr &= s->cirrus_addr_mask;
   2375 
   2376         mode = s->vga.gr[0x05] & 0x7;
   2377         if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
   2378             *(s->vga.vram_ptr + addr) = (uint8_t) val;
   2379             memory_region_set_dirty(&s->vga.vram, addr, 1);
   2380         } else {
   2381             if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
   2382                 cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
   2383             } else {
   2384                 cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val);
   2385             }
   2386         }
   2387     }
   2388 }
   2389 
   2390 /***************************************
   2391  *
   2392  *  system to screen memory access
   2393  *
   2394  ***************************************/
   2395 
   2396 
   2397 static uint64_t cirrus_linear_bitblt_read(void *opaque,
   2398                                           hwaddr addr,
   2399                                           unsigned size)
   2400 {
   2401     CirrusVGAState *s = opaque;
   2402 
   2403     /* XXX handle bitblt */
   2404     (void)s;
   2405     qemu_log_mask(LOG_UNIMP,
   2406                   "cirrus: linear bitblt is not implemented\n");
   2407 
   2408     return 0xff;
   2409 }
   2410 
   2411 static void cirrus_linear_bitblt_write(void *opaque,
   2412                                        hwaddr addr,
   2413                                        uint64_t val,
   2414                                        unsigned size)
   2415 {
   2416     CirrusVGAState *s = opaque;
   2417 
   2418     if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
   2419         /* bitblt */
   2420         *s->cirrus_srcptr++ = (uint8_t) val;
   2421         if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
   2422             cirrus_bitblt_cputovideo_next(s);
   2423         }
   2424     }
   2425 }
   2426 
   2427 static const MemoryRegionOps cirrus_linear_bitblt_io_ops = {
   2428     .read = cirrus_linear_bitblt_read,
   2429     .write = cirrus_linear_bitblt_write,
   2430     .endianness = DEVICE_LITTLE_ENDIAN,
   2431     .impl = {
   2432         .min_access_size = 1,
   2433         .max_access_size = 1,
   2434     },
   2435 };
   2436 
   2437 static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank)
   2438 {
   2439     MemoryRegion *mr = &s->cirrus_bank[bank];
   2440     bool enabled = !(s->cirrus_srcptr != s->cirrus_srcptr_end)
   2441         && !((s->vga.sr[0x07] & 0x01) == 0)
   2442         && !((s->vga.gr[0x0B] & 0x14) == 0x14)
   2443         && !(s->vga.gr[0x0B] & 0x02);
   2444 
   2445     memory_region_set_enabled(mr, enabled);
   2446     memory_region_set_alias_offset(mr, s->cirrus_bank_base[bank]);
   2447 }
   2448 
   2449 static void map_linear_vram(CirrusVGAState *s)
   2450 {
   2451     if (s->bustype == CIRRUS_BUSTYPE_PCI && !s->linear_vram) {
   2452         s->linear_vram = true;
   2453         memory_region_add_subregion_overlap(&s->pci_bar, 0, &s->vga.vram, 1);
   2454     }
   2455     map_linear_vram_bank(s, 0);
   2456     map_linear_vram_bank(s, 1);
   2457 }
   2458 
   2459 static void unmap_linear_vram(CirrusVGAState *s)
   2460 {
   2461     if (s->bustype == CIRRUS_BUSTYPE_PCI && s->linear_vram) {
   2462         s->linear_vram = false;
   2463         memory_region_del_subregion(&s->pci_bar, &s->vga.vram);
   2464     }
   2465     memory_region_set_enabled(&s->cirrus_bank[0], false);
   2466     memory_region_set_enabled(&s->cirrus_bank[1], false);
   2467 }
   2468 
   2469 /* Compute the memory access functions */
   2470 static void cirrus_update_memory_access(CirrusVGAState *s)
   2471 {
   2472     unsigned mode;
   2473 
   2474     memory_region_transaction_begin();
   2475     if ((s->vga.sr[0x17] & 0x44) == 0x44) {
   2476         goto generic_io;
   2477     } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
   2478         goto generic_io;
   2479     } else {
   2480         if ((s->vga.gr[0x0B] & 0x14) == 0x14) {
   2481             goto generic_io;
   2482         } else if (s->vga.gr[0x0B] & 0x02) {
   2483             goto generic_io;
   2484         }
   2485 
   2486         mode = s->vga.gr[0x05] & 0x7;
   2487         if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
   2488             map_linear_vram(s);
   2489         } else {
   2490         generic_io:
   2491             unmap_linear_vram(s);
   2492         }
   2493     }
   2494     memory_region_transaction_commit();
   2495 }
   2496 
   2497 
   2498 /* I/O ports */
   2499 
   2500 static uint64_t cirrus_vga_ioport_read(void *opaque, hwaddr addr,
   2501                                        unsigned size)
   2502 {
   2503     CirrusVGAState *c = opaque;
   2504     VGACommonState *s = &c->vga;
   2505     int val, index;
   2506 
   2507     addr += 0x3b0;
   2508 
   2509     if (vga_ioport_invalid(s, addr)) {
   2510         val = 0xff;
   2511     } else {
   2512         switch (addr) {
   2513         case 0x3c0:
   2514             if (s->ar_flip_flop == 0) {
   2515                 val = s->ar_index;
   2516             } else {
   2517                 val = 0;
   2518             }
   2519             break;
   2520         case 0x3c1:
   2521             index = s->ar_index & 0x1f;
   2522             if (index < 21)
   2523                 val = s->ar[index];
   2524             else
   2525                 val = 0;
   2526             break;
   2527         case 0x3c2:
   2528             val = s->st00;
   2529             break;
   2530         case 0x3c4:
   2531             val = s->sr_index;
   2532             break;
   2533         case 0x3c5:
   2534             val = cirrus_vga_read_sr(c);
   2535             break;
   2536             break;
   2537         case 0x3c6:
   2538             val = cirrus_read_hidden_dac(c);
   2539             break;
   2540         case 0x3c7:
   2541             val = s->dac_state;
   2542             break;
   2543         case 0x3c8:
   2544             val = s->dac_write_index;
   2545             c->cirrus_hidden_dac_lockindex = 0;
   2546             break;
   2547         case 0x3c9:
   2548             val = cirrus_vga_read_palette(c);
   2549             break;
   2550         case 0x3ca:
   2551             val = s->fcr;
   2552             break;
   2553         case 0x3cc:
   2554             val = s->msr;
   2555             break;
   2556         case 0x3ce:
   2557             val = s->gr_index;
   2558             break;
   2559         case 0x3cf:
   2560             val = cirrus_vga_read_gr(c, s->gr_index);
   2561             break;
   2562         case 0x3b4:
   2563         case 0x3d4:
   2564             val = s->cr_index;
   2565             break;
   2566         case 0x3b5:
   2567         case 0x3d5:
   2568             val = cirrus_vga_read_cr(c, s->cr_index);
   2569             break;
   2570         case 0x3ba:
   2571         case 0x3da:
   2572             /* just toggle to fool polling */
   2573             val = s->st01 = s->retrace(s);
   2574             s->ar_flip_flop = 0;
   2575             break;
   2576         default:
   2577             val = 0x00;
   2578             break;
   2579         }
   2580     }
   2581     trace_vga_cirrus_read_io(addr, val);
   2582     return val;
   2583 }
   2584 
   2585 static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val,
   2586                                     unsigned size)
   2587 {
   2588     CirrusVGAState *c = opaque;
   2589     VGACommonState *s = &c->vga;
   2590     int index;
   2591 
   2592     addr += 0x3b0;
   2593 
   2594     /* check port range access depending on color/monochrome mode */
   2595     if (vga_ioport_invalid(s, addr)) {
   2596         return;
   2597     }
   2598     trace_vga_cirrus_write_io(addr, val);
   2599 
   2600     switch (addr) {
   2601     case 0x3c0:
   2602         if (s->ar_flip_flop == 0) {
   2603             val &= 0x3f;
   2604             s->ar_index = val;
   2605         } else {
   2606             index = s->ar_index & 0x1f;
   2607             switch (index) {
   2608             case 0x00 ... 0x0f:
   2609                 s->ar[index] = val & 0x3f;
   2610                 break;
   2611             case 0x10:
   2612                 s->ar[index] = val & ~0x10;
   2613                 break;
   2614             case 0x11:
   2615                 s->ar[index] = val;
   2616                 break;
   2617             case 0x12:
   2618                 s->ar[index] = val & ~0xc0;
   2619                 break;
   2620             case 0x13:
   2621                 s->ar[index] = val & ~0xf0;
   2622                 break;
   2623             case 0x14:
   2624                 s->ar[index] = val & ~0xf0;
   2625                 break;
   2626             default:
   2627                 break;
   2628             }
   2629         }
   2630         s->ar_flip_flop ^= 1;
   2631         break;
   2632     case 0x3c2:
   2633         s->msr = val & ~0x10;
   2634         s->update_retrace_info(s);
   2635         break;
   2636     case 0x3c4:
   2637         s->sr_index = val;
   2638         break;
   2639     case 0x3c5:
   2640         cirrus_vga_write_sr(c, val);
   2641         break;
   2642     case 0x3c6:
   2643         cirrus_write_hidden_dac(c, val);
   2644         break;
   2645     case 0x3c7:
   2646         s->dac_read_index = val;
   2647         s->dac_sub_index = 0;
   2648         s->dac_state = 3;
   2649         break;
   2650     case 0x3c8:
   2651         s->dac_write_index = val;
   2652         s->dac_sub_index = 0;
   2653         s->dac_state = 0;
   2654         break;
   2655     case 0x3c9:
   2656         cirrus_vga_write_palette(c, val);
   2657         break;
   2658     case 0x3ce:
   2659         s->gr_index = val;
   2660         break;
   2661     case 0x3cf:
   2662         cirrus_vga_write_gr(c, s->gr_index, val);
   2663         break;
   2664     case 0x3b4:
   2665     case 0x3d4:
   2666         s->cr_index = val;
   2667         break;
   2668     case 0x3b5:
   2669     case 0x3d5:
   2670         cirrus_vga_write_cr(c, val);
   2671         break;
   2672     case 0x3ba:
   2673     case 0x3da:
   2674         s->fcr = val & 0x10;
   2675         break;
   2676     }
   2677 }
   2678 
   2679 /***************************************
   2680  *
   2681  *  memory-mapped I/O access
   2682  *
   2683  ***************************************/
   2684 
   2685 static uint64_t cirrus_mmio_read(void *opaque, hwaddr addr,
   2686                                  unsigned size)
   2687 {
   2688     CirrusVGAState *s = opaque;
   2689 
   2690     if (addr >= 0x100) {
   2691         return cirrus_mmio_blt_read(s, addr - 0x100);
   2692     } else {
   2693         return cirrus_vga_ioport_read(s, addr + 0x10, size);
   2694     }
   2695 }
   2696 
   2697 static void cirrus_mmio_write(void *opaque, hwaddr addr,
   2698                               uint64_t val, unsigned size)
   2699 {
   2700     CirrusVGAState *s = opaque;
   2701 
   2702     if (addr >= 0x100) {
   2703         cirrus_mmio_blt_write(s, addr - 0x100, val);
   2704     } else {
   2705         cirrus_vga_ioport_write(s, addr + 0x10, val, size);
   2706     }
   2707 }
   2708 
   2709 static const MemoryRegionOps cirrus_mmio_io_ops = {
   2710     .read = cirrus_mmio_read,
   2711     .write = cirrus_mmio_write,
   2712     .endianness = DEVICE_LITTLE_ENDIAN,
   2713     .impl = {
   2714         .min_access_size = 1,
   2715         .max_access_size = 1,
   2716     },
   2717 };
   2718 
   2719 /* load/save state */
   2720 
   2721 static int cirrus_post_load(void *opaque, int version_id)
   2722 {
   2723     CirrusVGAState *s = opaque;
   2724 
   2725     s->vga.gr[0x00] = s->cirrus_shadow_gr0 & 0x0f;
   2726     s->vga.gr[0x01] = s->cirrus_shadow_gr1 & 0x0f;
   2727 
   2728     cirrus_update_bank_ptr(s, 0);
   2729     cirrus_update_bank_ptr(s, 1);
   2730     cirrus_update_memory_access(s);
   2731     /* force refresh */
   2732     s->vga.graphic_mode = -1;
   2733 
   2734     return 0;
   2735 }
   2736 
   2737 const VMStateDescription vmstate_cirrus_vga = {
   2738     .name = "cirrus_vga",
   2739     .version_id = 2,
   2740     .minimum_version_id = 1,
   2741     .post_load = cirrus_post_load,
   2742     .fields = (VMStateField[]) {
   2743         VMSTATE_UINT32(vga.latch, CirrusVGAState),
   2744         VMSTATE_UINT8(vga.sr_index, CirrusVGAState),
   2745         VMSTATE_BUFFER(vga.sr, CirrusVGAState),
   2746         VMSTATE_UINT8(vga.gr_index, CirrusVGAState),
   2747         VMSTATE_UINT8(cirrus_shadow_gr0, CirrusVGAState),
   2748         VMSTATE_UINT8(cirrus_shadow_gr1, CirrusVGAState),
   2749         VMSTATE_BUFFER_START_MIDDLE(vga.gr, CirrusVGAState, 2),
   2750         VMSTATE_UINT8(vga.ar_index, CirrusVGAState),
   2751         VMSTATE_BUFFER(vga.ar, CirrusVGAState),
   2752         VMSTATE_INT32(vga.ar_flip_flop, CirrusVGAState),
   2753         VMSTATE_UINT8(vga.cr_index, CirrusVGAState),
   2754         VMSTATE_BUFFER(vga.cr, CirrusVGAState),
   2755         VMSTATE_UINT8(vga.msr, CirrusVGAState),
   2756         VMSTATE_UINT8(vga.fcr, CirrusVGAState),
   2757         VMSTATE_UINT8(vga.st00, CirrusVGAState),
   2758         VMSTATE_UINT8(vga.st01, CirrusVGAState),
   2759         VMSTATE_UINT8(vga.dac_state, CirrusVGAState),
   2760         VMSTATE_UINT8(vga.dac_sub_index, CirrusVGAState),
   2761         VMSTATE_UINT8(vga.dac_read_index, CirrusVGAState),
   2762         VMSTATE_UINT8(vga.dac_write_index, CirrusVGAState),
   2763         VMSTATE_BUFFER(vga.dac_cache, CirrusVGAState),
   2764         VMSTATE_BUFFER(vga.palette, CirrusVGAState),
   2765         VMSTATE_INT32(vga.bank_offset, CirrusVGAState),
   2766         VMSTATE_UINT8(cirrus_hidden_dac_lockindex, CirrusVGAState),
   2767         VMSTATE_UINT8(cirrus_hidden_dac_data, CirrusVGAState),
   2768         VMSTATE_UINT32(vga.hw_cursor_x, CirrusVGAState),
   2769         VMSTATE_UINT32(vga.hw_cursor_y, CirrusVGAState),
   2770         /* XXX: we do not save the bitblt state - we assume we do not save
   2771            the state when the blitter is active */
   2772         VMSTATE_END_OF_LIST()
   2773     }
   2774 };
   2775 
   2776 static const VMStateDescription vmstate_pci_cirrus_vga = {
   2777     .name = "cirrus_vga",
   2778     .version_id = 2,
   2779     .minimum_version_id = 2,
   2780     .fields = (VMStateField[]) {
   2781         VMSTATE_PCI_DEVICE(dev, PCICirrusVGAState),
   2782         VMSTATE_STRUCT(cirrus_vga, PCICirrusVGAState, 0,
   2783                        vmstate_cirrus_vga, CirrusVGAState),
   2784         VMSTATE_END_OF_LIST()
   2785     }
   2786 };
   2787 
   2788 /***************************************
   2789  *
   2790  *  initialize
   2791  *
   2792  ***************************************/
   2793 
   2794 static void cirrus_reset(void *opaque)
   2795 {
   2796     CirrusVGAState *s = opaque;
   2797 
   2798     vga_common_reset(&s->vga);
   2799     unmap_linear_vram(s);
   2800     s->vga.sr[0x06] = 0x0f;
   2801     if (s->device_id == CIRRUS_ID_CLGD5446) {
   2802         /* 4MB 64 bit memory config, always PCI */
   2803         s->vga.sr[0x1F] = 0x2d;         // MemClock
   2804         s->vga.gr[0x18] = 0x0f;             // fastest memory configuration
   2805         s->vga.sr[0x0f] = 0x98;
   2806         s->vga.sr[0x17] = 0x20;
   2807         s->vga.sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */
   2808     } else {
   2809         s->vga.sr[0x1F] = 0x22;         // MemClock
   2810         s->vga.sr[0x0F] = CIRRUS_MEMSIZE_2M;
   2811         s->vga.sr[0x17] = s->bustype;
   2812         s->vga.sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
   2813     }
   2814     s->vga.cr[0x27] = s->device_id;
   2815 
   2816     s->cirrus_hidden_dac_lockindex = 5;
   2817     s->cirrus_hidden_dac_data = 0;
   2818 }
   2819 
   2820 static const MemoryRegionOps cirrus_linear_io_ops = {
   2821     .read = cirrus_linear_read,
   2822     .write = cirrus_linear_write,
   2823     .endianness = DEVICE_LITTLE_ENDIAN,
   2824     .impl = {
   2825         .min_access_size = 1,
   2826         .max_access_size = 1,
   2827     },
   2828 };
   2829 
   2830 static const MemoryRegionOps cirrus_vga_io_ops = {
   2831     .read = cirrus_vga_ioport_read,
   2832     .write = cirrus_vga_ioport_write,
   2833     .endianness = DEVICE_LITTLE_ENDIAN,
   2834     .impl = {
   2835         .min_access_size = 1,
   2836         .max_access_size = 1,
   2837     },
   2838 };
   2839 
   2840 void cirrus_init_common(CirrusVGAState *s, Object *owner,
   2841                         int device_id, int is_pci,
   2842                         MemoryRegion *system_memory, MemoryRegion *system_io)
   2843 {
   2844     int i;
   2845     static int inited;
   2846 
   2847     if (!inited) {
   2848         inited = 1;
   2849         for(i = 0;i < 256; i++)
   2850             rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */
   2851         rop_to_index[CIRRUS_ROP_0] = 0;
   2852         rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1;
   2853         rop_to_index[CIRRUS_ROP_NOP] = 2;
   2854         rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3;
   2855         rop_to_index[CIRRUS_ROP_NOTDST] = 4;
   2856         rop_to_index[CIRRUS_ROP_SRC] = 5;
   2857         rop_to_index[CIRRUS_ROP_1] = 6;
   2858         rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7;
   2859         rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8;
   2860         rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9;
   2861         rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10;
   2862         rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11;
   2863         rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12;
   2864         rop_to_index[CIRRUS_ROP_NOTSRC] = 13;
   2865         rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14;
   2866         rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
   2867         s->device_id = device_id;
   2868         if (is_pci)
   2869             s->bustype = CIRRUS_BUSTYPE_PCI;
   2870         else
   2871             s->bustype = CIRRUS_BUSTYPE_ISA;
   2872     }
   2873 
   2874     /* Register ioport 0x3b0 - 0x3df */
   2875     memory_region_init_io(&s->cirrus_vga_io, owner, &cirrus_vga_io_ops, s,
   2876                           "cirrus-io", 0x30);
   2877     memory_region_set_flush_coalesced(&s->cirrus_vga_io);
   2878     memory_region_add_subregion(system_io, 0x3b0, &s->cirrus_vga_io);
   2879 
   2880     memory_region_init(&s->low_mem_container, owner,
   2881                        "cirrus-lowmem-container",
   2882                        0x20000);
   2883 
   2884     memory_region_init_io(&s->low_mem, owner, &cirrus_vga_mem_ops, s,
   2885                           "cirrus-low-memory", 0x20000);
   2886     memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
   2887     for (i = 0; i < 2; ++i) {
   2888         static const char *names[] = { "vga.bank0", "vga.bank1" };
   2889         MemoryRegion *bank = &s->cirrus_bank[i];
   2890         memory_region_init_alias(bank, owner, names[i], &s->vga.vram,
   2891                                  0, 0x8000);
   2892         memory_region_set_enabled(bank, false);
   2893         memory_region_add_subregion_overlap(&s->low_mem_container, i * 0x8000,
   2894                                             bank, 1);
   2895     }
   2896     memory_region_add_subregion_overlap(system_memory,
   2897                                         0x000a0000,
   2898                                         &s->low_mem_container,
   2899                                         1);
   2900     memory_region_set_coalescing(&s->low_mem);
   2901 
   2902     /* I/O handler for LFB */
   2903     memory_region_init_io(&s->cirrus_linear_io, owner, &cirrus_linear_io_ops, s,
   2904                           "cirrus-linear-io", s->vga.vram_size_mb * MiB);
   2905     memory_region_set_flush_coalesced(&s->cirrus_linear_io);
   2906 
   2907     /* I/O handler for LFB */
   2908     memory_region_init_io(&s->cirrus_linear_bitblt_io, owner,
   2909                           &cirrus_linear_bitblt_io_ops,
   2910                           s,
   2911                           "cirrus-bitblt-mmio",
   2912                           0x400000);
   2913     memory_region_set_flush_coalesced(&s->cirrus_linear_bitblt_io);
   2914 
   2915     /* I/O handler for memory-mapped I/O */
   2916     memory_region_init_io(&s->cirrus_mmio_io, owner, &cirrus_mmio_io_ops, s,
   2917                           "cirrus-mmio", CIRRUS_PNPMMIO_SIZE);
   2918     memory_region_set_flush_coalesced(&s->cirrus_mmio_io);
   2919 
   2920     s->real_vram_size =
   2921         (s->device_id == CIRRUS_ID_CLGD5446) ? 4 * MiB : 2 * MiB;
   2922 
   2923     /* XXX: s->vga.vram_size must be a power of two */
   2924     s->cirrus_addr_mask = s->real_vram_size - 1;
   2925     s->linear_mmio_mask = s->real_vram_size - 256;
   2926 
   2927     s->vga.get_bpp = cirrus_get_bpp;
   2928     s->vga.get_offsets = cirrus_get_offsets;
   2929     s->vga.get_resolution = cirrus_get_resolution;
   2930     s->vga.cursor_invalidate = cirrus_cursor_invalidate;
   2931     s->vga.cursor_draw_line = cirrus_cursor_draw_line;
   2932 
   2933     qemu_register_reset(cirrus_reset, s);
   2934 }
   2935 
   2936 /***************************************
   2937  *
   2938  *  PCI bus support
   2939  *
   2940  ***************************************/
   2941 
   2942 static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp)
   2943 {
   2944     PCICirrusVGAState *d = PCI_CIRRUS_VGA(dev);
   2945     CirrusVGAState *s = &d->cirrus_vga;
   2946     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
   2947     int16_t device_id = pc->device_id;
   2948 
   2949     /*
   2950      * Follow real hardware, cirrus card emulated has 4 MB video memory.
   2951      * Also accept 8 MB/16 MB for backward compatibility.
   2952      */
   2953     if (s->vga.vram_size_mb != 4 && s->vga.vram_size_mb != 8 &&
   2954         s->vga.vram_size_mb != 16) {
   2955         error_setg(errp, "Invalid cirrus_vga ram size '%u'",
   2956                    s->vga.vram_size_mb);
   2957         return;
   2958     }
   2959     /* setup VGA */
   2960     if (!vga_common_init(&s->vga, OBJECT(dev), errp)) {
   2961         return;
   2962     }
   2963     cirrus_init_common(s, OBJECT(dev), device_id, 1, pci_address_space(dev),
   2964                        pci_address_space_io(dev));
   2965     s->vga.con = graphic_console_init(DEVICE(dev), 0, s->vga.hw_ops, &s->vga);
   2966 
   2967     /* setup PCI */
   2968     memory_region_init(&s->pci_bar, OBJECT(dev), "cirrus-pci-bar0", 0x2000000);
   2969 
   2970     /* XXX: add byte swapping apertures */
   2971     memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io);
   2972     memory_region_add_subregion(&s->pci_bar, 0x1000000,
   2973                                 &s->cirrus_linear_bitblt_io);
   2974 
   2975     /* setup memory space */
   2976     /* memory #0 LFB */
   2977     /* memory #1 memory-mapped I/O */
   2978     /* XXX: s->vga.vram_size must be a power of two */
   2979     pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->pci_bar);
   2980     if (device_id == CIRRUS_ID_CLGD5446) {
   2981         pci_register_bar(&d->dev, 1, 0, &s->cirrus_mmio_io);
   2982     }
   2983 }
   2984 
   2985 static Property pci_vga_cirrus_properties[] = {
   2986     DEFINE_PROP_UINT32("vgamem_mb", struct PCICirrusVGAState,
   2987                        cirrus_vga.vga.vram_size_mb, 4),
   2988     DEFINE_PROP_BOOL("blitter", struct PCICirrusVGAState,
   2989                      cirrus_vga.enable_blitter, true),
   2990     DEFINE_PROP_BOOL("global-vmstate", struct PCICirrusVGAState,
   2991                      cirrus_vga.vga.global_vmstate, false),
   2992     DEFINE_PROP_END_OF_LIST(),
   2993 };
   2994 
   2995 static void cirrus_vga_class_init(ObjectClass *klass, void *data)
   2996 {
   2997     DeviceClass *dc = DEVICE_CLASS(klass);
   2998     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
   2999 
   3000     k->realize = pci_cirrus_vga_realize;
   3001     k->romfile = VGABIOS_CIRRUS_FILENAME;
   3002     k->vendor_id = PCI_VENDOR_ID_CIRRUS;
   3003     k->device_id = CIRRUS_ID_CLGD5446;
   3004     k->class_id = PCI_CLASS_DISPLAY_VGA;
   3005     set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
   3006     dc->desc = "Cirrus CLGD 54xx VGA";
   3007     dc->vmsd = &vmstate_pci_cirrus_vga;
   3008     device_class_set_props(dc, pci_vga_cirrus_properties);
   3009     dc->hotpluggable = false;
   3010 }
   3011 
   3012 static const TypeInfo cirrus_vga_info = {
   3013     .name          = TYPE_PCI_CIRRUS_VGA,
   3014     .parent        = TYPE_PCI_DEVICE,
   3015     .instance_size = sizeof(PCICirrusVGAState),
   3016     .class_init    = cirrus_vga_class_init,
   3017     .interfaces = (InterfaceInfo[]) {
   3018         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
   3019         { },
   3020     },
   3021 };
   3022 
   3023 static void cirrus_vga_register_types(void)
   3024 {
   3025     type_register_static(&cirrus_vga_info);
   3026 }
   3027 
   3028 type_init(cirrus_vga_register_types)