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