cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

cirrus_vga.c (92222B)


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