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