Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


VGA: Corrected memory offseting calculations
[palacios.git] / palacios / src / devices / vga.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2011, Peter Dinda <pdinda@northwestern.edu> 
11  * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Peter Dinda <pdinda@northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm.h>
21 #include <palacios/vmm_dev_mgr.h>
22 #include <palacios/vmm_types.h>
23 #include <palacios/vm_guest_mem.h>
24 #include <palacios/vmm_io.h>
25
26 #include "vga_regs.h"
27
28 #define MEM_REGION_START 0xa0000
29 #define MEM_REGION_END   0xc0000
30 #define MEM_REGION_NUM_PAGES (((MEM_REGION_END)-(MEM_REGION_START))/4096)
31
32 #define MAP_SIZE 65536
33 #define MAP_NUM  4
34
35 typedef uint8_t *vga_map; // points to MAP_SIZE data
36
37 /* HACK HACK HACK */
38
39 struct fb_info {
40     uint32_t rows;
41     uint32_t cols;
42     uint32_t bitsperpixel;
43 };
44
45 struct fb {
46     struct fb_info *info;
47     uint8_t * data;
48 };
49
50 //extern
51 struct fb *palacios_linux_fb_hack_pointer;
52
53 /* HACK HACK HACK */
54
55
56 #define VGA_MISC_OUT_READ 0x3cc
57 #define VGA_MISC_OUT_WRITE 0x3c2
58
59 #define VGA_INPUT_STAT0_READ 0x3c2
60
61 #define VGA_INPUT_STAT1_READ_MONO 0x3ba
62 #define VGA_INPUT_STAT1_READ_COLOR 0x3da
63
64 #define VGA_FEATURE_CONTROL_READ 0x3ca
65 #define VGA_FEATURE_CONTROL_WRITE_MONO 0x3ba
66 #define VGA_FEATURE_CONTROL_WRITE_COLOR 0x3da
67
68 #define VGA_VIDEO_SUBSYS_ENABLE 0x3c3
69
70 #define VGA_SEQUENCER_ADDRESS 0x3c4
71 #define VGA_SEQUENCER_DATA 0x3c5
72 #define VGA_SEQUENCER_NUM 5
73
74
75 #define VGA_CRT_CONTROLLER_ADDRESS_MONO 0x3b4
76 #define VGA_CRT_CONTROLLER_ADDRESS_COLOR 0x3d4
77 #define VGA_CRT_CONTROLLER_DATA_MONO 0x3b5
78 #define VGA_CRT_CONTROLLER_DATA_COLOR 0x3d5
79 #define VGA_CRT_CONTROLLER_NUM 25
80
81
82 #define VGA_GRAPHICS_CONTROLLER_ADDRESS 0x3ce
83 #define VGA_GRAPHICS_CONTROLLER_DATA 0x3cf
84 #define VGA_GRAPHICS_CONTROLLER_NUM 9
85
86 #define VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE 0x3c0
87 #define VGA_ATTRIBUTE_CONTROLLER_READ 0x3c1
88 #define VGA_ATTRIBUTE_CONTROLLER_NUM 21
89
90 #define VGA_DAC_WRITE_ADDR 0x3c8
91 #define VGA_DAC_READ_ADDR 0x3c7
92 #define VGA_DAC_DATA 0x3c9
93 #define VGA_DAC_PIXEL_MASK 0x3c6
94
95 #define VGA_DAC_NUM_ENTRIES 256
96
97 struct vga_misc_regs {
98     /* Read: 0x3cc; Write: 0x3c2 */
99     struct vga_misc_out_reg        vga_misc_out;
100     /* Read: 0x3c2 */
101     struct vga_input_stat0_reg     vga_input_stat0;
102     /* Read: 0x3?a  3ba for mono; 3da for cga set by misc.io_addr_sel */
103     struct vga_input_stat1_reg     vga_input_stat1; 
104     /* Read: 0x3ca; Write: 0x3?a 3ba for mono 3da for color - set by misc.io_addr_sel*/
105     struct vga_feature_control_reg vga_feature_control;
106     /* Read: 0x3c3; Write: 0x3c3 */
107     struct vga_video_subsys_enable_reg vga_video_subsys_enable;
108 } __attribute__((packed));
109
110 struct vga_sequencer_regs {
111     /*   Address register is 0x3c4, data register is 0x3c5 */
112     /* 0x3c4 */
113     struct vga_sequencer_addr_reg vga_sequencer_addr;
114
115     /* these can be accessed via the index, offset on start 
116        or via the specific regs.   For this reason, it is essential
117        that this is all packed and that the order does not change */
118     
119     uint8_t  vga_sequencer_regs[0];
120
121     /* Index 0 */
122     struct vga_reset_reg   vga_reset;
123     /* Index 1 */
124     struct vga_clocking_mode_reg vga_clocking_mode;
125     /* Index 2 */
126     struct vga_map_mask_reg vga_map_mask;
127     /* Index 3 */
128     struct vga_char_map_select_reg vga_char_map_select;
129     /* Index 4 */
130     struct vga_mem_mode_reg  vga_mem_mode;
131 } __attribute__((packed));
132
133 struct vga_crt_controller_regs {
134     /* Address Register is 0x3b4 or 0x3d4 */
135     /* Data register is 0x3b5 or 0x3d5 based on mono versus color */
136     struct vga_crt_addr_reg vga_crt_addr;
137
138     /* these can be accessed via the index, offset on start 
139        or via the specific regs.   For this reason, it is essential
140        that this is all packed and that the order does not change */
141     
142     uint8_t  vga_crt_controller_regs[0];
143
144     /* index 0 */
145     vga_horizontal_total_reg vga_horizontal_total;
146     /* index 1 */
147     vga_horizontal_display_enable_end_reg vga_horizontal_display_enable_end;
148     /* index 2 */
149     vga_start_horizontal_blanking_reg vga_start_horizontal_blanking;
150     /* index 3 */
151     struct vga_end_horizontal_blanking_reg vga_end_horizontal_blanking;
152     /* index 4 */
153     vga_start_horizontal_retrace_pulse_reg vga_start_horizontal_retrace_pulse;
154     /* index 5 */
155     struct vga_end_horizontal_retrace_reg vga_end_horizontal_retrace;
156     /* index 6 */
157     vga_vertical_total_reg vga_vertical_total;
158     /* index 7 */
159     struct vga_overflow_reg vga_overflow;
160     /* index 8 */
161     struct vga_preset_row_scan_reg vga_preset_row_scan;
162     /* index 9 */
163     struct vga_max_row_scan_reg vga_row_scan;
164     /* index 10 */
165     struct vga_cursor_start_reg vga_cursor_start;
166     /* index 11 */
167     struct vga_cursor_end_reg vga_cursor_end;
168     /* index 12 */
169     vga_start_address_high_reg vga_start_address_high;
170     /* index 13 */
171     vga_start_address_low_reg vga_start_address_low;
172     /* index 14 */
173     vga_cursor_location_high_reg vga_cursor_location_high;
174     /* index 15 */
175     vga_cursor_location_low_reg vga_cursor_location_low;
176     /* index 16 */
177     vga_vertical_retrace_start_reg vga_vertical_retrace_start;
178     /* index 17 */
179     struct vga_vertical_retrace_end_reg vga_vertical_retrace_end;
180     /* index 18 */
181     vga_vertical_display_enable_end_reg vga_vertical_display_enable;
182     /* index 19 */
183     vga_offset_reg vga_offset;
184     /* index 20 */
185     struct vga_underline_location_reg vga_underline_location;
186     /* index 21 */
187     vga_start_vertical_blanking_reg vga_start_vertical_blanking;
188     /* index 22 */
189     vga_end_vertical_blanking_reg vga_end_vertical_blanking;
190     /* index 23 */
191     struct vga_crt_mode_control_reg vga_crt_mode_control;
192     /* index 24 */
193     vga_line_compare_reg vga_line_compare;
194 } __attribute__((packed));
195
196 struct vga_graphics_controller_regs {
197     /*   Address: 0x3ce    Data: 0x3cf */
198
199     /* 0x3ce */
200     struct vga_graphics_ctrl_addr_reg vga_graphics_ctrl_addr;
201
202     /* these can be accessed via the index, offset on start 
203        or via the specific regs.   For this reason, it is essential
204        that this is all packed and that the order does not change */
205     
206     uint8_t  vga_graphics_controller_regs[0];
207
208     /* Index 0 */
209     struct vga_set_reset_reg vga_set_reset;
210     /* Index 1 */
211     struct vga_enable_set_reset_reg vga_enable_set_reset;
212     /* Index 2 */
213     struct vga_color_compare_reg vga_color_compare;
214     /* Index 3 */
215     struct vga_data_rotate_reg vga_data_rotate;
216     /* Index 4 */
217     struct vga_read_map_select_reg vga_read_map_select;
218     /* Index 5 */
219     struct vga_graphics_mode_reg vga_graphics_mode;
220     /* Index 6 */
221     struct vga_misc_reg vga_misc;
222     /* Index 7 */
223     struct vga_color_dont_care_reg vga_color_dont_care;
224     /* Index 8 */
225     vga_bit_mask_reg vga_bit_mask;
226 } __attribute__((packed));
227
228
229 struct vga_attribute_contoller_regs {
230     /*
231       Address AND WRITE: 0x3c0
232       Read: 0x3c1
233
234       The write protocol is to write the index to 0x3c0 followed by 
235       the data.  The read protocol is to write the index to 0x3c0
236       and then read from 0x3c1
237   
238       IMPORTANT: write address, write data flips state back to write address
239       write address, read data DOES NOT
240
241       To reset to write address state, read input status register 1
242 */
243     enum { ATTR_ADDR, ATTR_DATA }  state;  //state of the flip flop
244
245     /* 0x3c0 */
246     struct vga_attribute_controller_address_reg vga_attribute_controller_addr;
247
248
249     
250     /* these can be accessed via the index, offset on start 
251        or via the specific regs.   For this reason, it is essential
252        that this is all packed and that the order does not change */
253     
254     uint8_t  vga_attribute_controller_regs[0];
255
256     /* Indices 0..15 */
257     vga_internal_palette_regs   vga_internal_palette;
258     /* Index 16 */
259     struct vga_attribute_mode_control_reg vga_attribute_mode_control;
260     /* Index 17 */
261     vga_overscan_color_reg vga_overscan_color;
262     /* Index 18 */
263     struct vga_color_plane_enable_reg vga_color_plane_enable;
264     /* Index 19 */
265     struct vga_horizontal_pixel_pan_reg vga_horizontal_pixel_pan;
266     /* Index 20 */
267     struct vga_color_select_reg vga_color_select;
268 } __attribute__((packed));
269
270 struct vga_dac_regs {
271     enum {DAC_READ=0, DAC_WRITE} state;
272     enum {RED=0,GREEN,BLUE} channel;
273     vga_dac_pixel_mask_reg vga_pixel_mask;
274     vga_dac_write_addr_reg vga_dac_write_addr;
275     vga_dac_read_addr_reg vga_dac_read_addr;
276     // the dac_data register is used only to access the registers
277     // and thus has no representation here
278     vga_palette_reg vga_dac_palette[VGA_DAC_NUM_ENTRIES];
279 } __attribute__((packed));
280     
281
282 struct vga_internal {
283     struct vm_device *dev;  
284     
285     bool passthrough;
286
287     struct frame_buf *framebuf; // we render to this
288     
289     //    void *mem_store;     // This is the region where the memory hooks will go
290
291     vga_map  map[MAP_NUM];  // the maps that the host writes to
292
293     uint8_t  latch[MAP_NUM];  // written to in any read, used during writes
294
295     /* Range of I/O ports here for backward compat with MDA and CGA */
296     struct vga_misc_regs  vga_misc;
297
298     /* Address Register is 0x3b4 or 0x3d4 */
299     /* Data register is 0x3b5 or 0x3d5 based on MDA/CGA/VGA (backward compat) */
300     struct vga_crt_controller_regs vga_crt_controller;
301
302     /*   Address register is 0x3c4, data register is 0x3c5 */
303     struct vga_sequencer_regs vga_sequencer;
304
305     /*   Address: 0x3ce    Data: 0x3cf */
306     struct vga_graphics_controller_regs vga_graphics_controller;
307
308     /*
309       Address AND WRITE: 0x3c0
310       Read: 0x3c1
311       Flip-Flop
312     */
313     struct vga_attribute_contoller_regs vga_attribute_controller;
314
315     /*
316       address for reads: 0x3c7 (also resets state machine for access to 18 bit regs 
317       address for writes: 0x3c8 ("")
318       data: 0x3c9
319       pixel mask: 0x3c6 - do not write (init to 0xff)
320     */
321     struct vga_dac_regs vga_dac;
322 };
323
324
325 static void get_mem_region(struct vga_internal *vga, uint64_t *mem_start, uint64_t *mem_end) 
326 {
327     switch (vga->vga_graphics_controller.vga_misc.memory_map) { 
328         case 0: 
329             *mem_start=0xa0000;
330             *mem_end=0xc0000;
331             break;
332         case 1:
333             *mem_start=0xa0000;
334             *mem_end=0xb0000;
335             break;
336         case 2:
337             *mem_start=0xb0000;
338             *mem_end=0xb8000;
339             break;
340         case 3:
341             *mem_start=0xb8000;
342             *mem_end=0xc0000;
343             break;
344     }
345 }
346
347 static uint64_t find_offset(struct vga_internal *vga, addr_t guest_addr)
348 {
349     uint64_t mem_start, mem_end;
350     
351     mem_start=mem_end=0;
352     
353     get_mem_region(vga, &mem_start, &mem_end);
354
355     return (guest_addr-mem_start) % (mem_end-mem_start > 65536 ? 65536 : (mem_end-mem_start)); 
356
357 }
358
359     
360
361
362 static int vga_write(struct guest_info * core, 
363                      addr_t guest_addr, 
364                      void * src, 
365                      uint_t length, 
366                      void * priv_data)
367 {
368     struct vm_device *dev = (struct vm_device *)priv_data;
369     struct vga_internal *vga = (struct vga_internal *) dev->private_data;
370
371     PrintDebug("vga: memory write: guest_addr=0x%p len=%u\n",(void*)guest_addr, length);
372
373     if (vga->passthrough) { 
374         memcpy(V3_VAddr((void*)guest_addr),src,length);
375     }
376     
377     /* Write mode determine by Graphics Mode Register (Index 05h).writemode */
378     
379     switch (vga->vga_graphics_controller.vga_graphics_mode.write_mode) {
380         case 0: {
381             
382             /* 
383                00b -- Write Mode 0: In this mode, the host data is first rotated 
384                as per the Rotate Count field, then the Enable Set/Reset mechanism 
385                selects data from this or the Set/Reset field. Then the selected 
386                Logical Operation is performed on the resulting data and the data 
387                in the latch register. Then the Bit Mask field is used to select 
388                which bits come from the resulting data and which come 
389                from the latch register. Finally, only the bit planes enabled by 
390                the Memory Plane Write Enable field are written to memory.
391             */
392
393             int i;
394
395             uint8_t  mapnum;
396             uint64_t offset;
397
398             uint8_t ror = vga->vga_graphics_controller.vga_data_rotate.rotate_count;
399             uint8_t func = vga->vga_graphics_controller.vga_data_rotate.function;
400             
401             offset = find_offset(vga, guest_addr);
402
403             PrintDebug("vga: mode 0 write, offset=0x%llx, ror=%u, func=%u\n", offset,ror,func);
404
405             for (i=0;i<length;i++,offset++) { 
406                 // now for each map
407                 uint8_t sr = vga->vga_graphics_controller.vga_set_reset.val & 0xf;
408                 uint8_t esr = vga->vga_graphics_controller.vga_enable_set_reset.val &0xf;
409                 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask;
410                 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
411
412                 for (mapnum=0;mapnum<4;mapnum++, sr>>=1, esr>>=1, bm>>=1, mm>>=1) { 
413                     vga_map map = vga->map[mapnum];
414                     uint8_t data = ((uint8_t *)src)[i];
415                     uint8_t latchval = vga->latch[mapnum];
416                         
417                     // rotate data right
418                     data = (data>>ror) | data<<(8-ror);
419
420                     // use SR bit if ESR is on for this map
421                     if (esr & 0x1) { 
422                         data = (uint8_t)((((sint8_t)(sr&0x1))<<7)>>7);  // expand sr bit
423                     }
424                     
425                     // Apply function
426                     switch (func) { 
427                         case 0: // NOP
428                             break;
429                         case 1: // AND
430                             data &= latchval;
431                             break;
432                         case 2: // OR
433                             data |= latchval;
434                             break;
435                         case 3: // XOR
436                             data ^= latchval;
437                             break;
438                     }
439                             
440                     // mux between latch and alu output
441                     if (bm & 0x1) { 
442                         // use alu output, which is in data
443                     } else {
444                         // use latch value
445                         data=latchval;
446                     }
447                     
448                     // selective write
449                     if (mm & 0x1) { 
450                         // write to this map
451                         PrintDebug("vga: write map %u offset 0x%p map=0x%p pointer=0x%p\n",mapnum,(void*)offset,map,&(map[offset]));
452                         map[offset] = data;
453                     } else {
454                         // skip this map
455                     }
456                 }
457             }
458         }
459             break;
460
461
462             
463         case 1: {
464             /* 
465                01b -- Write Mode 1: In this mode, data is transferred directly 
466                from the 32 bit latch register to display memory, affected only by 
467                the Memory Plane Write Enable field. The host data is not used in this mode.
468             */
469
470             int i;
471
472             uint64_t offset = find_offset(vga,guest_addr);
473
474             PrintDebug("vga: mode 1 write, offset=0x%llx\n", offset);
475
476             for (i=0;i<length;i++,offset++) { 
477
478                 uint8_t mapnum;
479                 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
480
481                 for (mapnum=0;mapnum<4;mapnum++,  mm>>=1) { 
482                     vga_map map = vga->map[mapnum];
483                     uint8_t latchval = vga->latch[mapnum];
484                         
485                     // selective write
486                     if (mm & 0x1) { 
487                         // write to this map
488                         map[offset] = latchval;
489                     } else {
490                         // skip this map
491                     }
492                 }
493             }
494         }
495             break;
496
497         case 2: {
498             /*
499               10b -- Write Mode 2: In this mode, the bits 3-0 of the host data 
500               are replicated across all 8 bits of their respective planes. 
501               Then the selected Logical Operation is performed on the resulting 
502               data and the data in the latch register. Then the Bit Mask field is used to 
503               select which bits come from the resulting data and which come from 
504               the latch register. Finally, only the bit planes enabled by the 
505               Memory Plane Write Enable field are written to memory.
506             */
507             int i;
508             uint8_t  mapnum;
509             uint64_t offset;
510
511             uint8_t func = vga->vga_graphics_controller.vga_data_rotate.function;
512             
513             offset = find_offset(vga, guest_addr);
514
515             PrintDebug("vga: mode 2 write, offset=0x%llx, func=%u\n", offset,func);
516
517             for (i=0;i<length;i++,offset++) { 
518                 // now for each map
519                 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask;
520                 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
521
522                 for (mapnum=0;mapnum<4;mapnum++,  bm>>=1, mm>>=1) { 
523                     vga_map map = vga->map[mapnum];
524                     uint8_t data = ((uint8_t *)src)[i];
525                     uint8_t latchval = vga->latch[mapnum];
526                         
527                     // expand relevant bit to 8 bit
528                     // it's basically esr=1, sr=bit from write
529                     data = (uint8_t)(((sint8_t)(((data>>mapnum)&0x1)<<7))>>7);
530                     
531                     // Apply function
532                     switch (func) { 
533                         case 0: // NOP
534                             break;
535                         case 1: // AND
536                             data &= latchval;
537                             break;
538                         case 2: // OR
539                             data |= latchval;
540                             break;
541                         case 3: // XOR
542                             data ^= latchval;
543                             break;
544                     }
545                             
546                     // mux between latch and alu output
547                     if (bm & 0x1) { 
548                         // use alu output, which is in data
549                     } else {
550                         // use latch value
551                         data=latchval;
552                     }
553                     
554                     // selective write
555                     if (mm & 0x1) { 
556                         // write to this map
557                         map[offset] = data;
558                     } else {
559                         // skip this map
560                     }
561                 }
562             }
563         }
564             break;
565
566         case 3: {
567             /* 11b -- Write Mode 3: In this mode, the data in the Set/Reset field is used 
568                as if the Enable Set/Reset field were set to 1111b. Then the host data is 
569                first rotated as per the Rotate Count field, then logical ANDed with the 
570                value of the Bit Mask field. The resulting value is used on the data 
571                obtained from the Set/Reset field in the same way that the Bit Mask field 
572                would ordinarily be used. to select which bits come from the expansion 
573                of the Set/Reset field and which come from the latch register. Finally, 
574                only the bit planes enabled by the Memory Plane Write Enable field 
575                are written to memory.
576             */
577             int i;
578
579             uint8_t  mapnum;
580             uint64_t offset;
581
582             uint8_t ror = vga->vga_graphics_controller.vga_data_rotate.rotate_count;
583             
584             offset = find_offset(vga, guest_addr);
585
586             PrintDebug("vga: mode 3 write, offset=0x%llx, ror=%u\n", offset,ror);
587
588             for (i=0;i<length;i++,offset++) { 
589                 // now for each map
590                 uint8_t data = ((uint8_t *)src)[i];
591
592                 data = (data>>ror) | data<<(8-ror);
593
594                 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask & data;
595                 uint8_t sr = vga->vga_graphics_controller.vga_set_reset.val & 0xf;
596                 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
597
598                 for (mapnum=0;mapnum<4;mapnum++, sr>>=1, bm>>=1, mm>>=1) { 
599                     vga_map map = vga->map[mapnum];
600                     uint8_t latchval = vga->latch[mapnum];
601                         
602                     data = (uint8_t)((((sint8_t)(sr&0x1))<<7)>>7);  // expand sr bit
603                     
604                     
605                     // mux between latch and alu output
606                     if (bm & 0x1) { 
607                         // use alu output, which is in data
608                     } else {
609                         // use latch value
610                         data=latchval;
611                     }
612                     
613                     // selective write
614                     if (mm & 0x1) { 
615                         // write to this map
616                         map[offset] = data;
617                     } else {
618                         // skip this map
619                     }
620                 }
621             }
622
623         }
624             break;
625
626             // There is no default
627     }
628     
629     return length;
630 }
631
632     //    PrintError("vga: vga_write UNIMPLEMENTED\n");
633
634 /*
635 up to 256K mapped through a window of 128K
636
637 most cards support linear mode as well
638
639 Need to implement readability too
640
641 Write extended memory bit to enable all 256K: 
642
643    Sequencer Memory Mode Register (Index 04h) . extended memory
644
645 Must enable writes before effects happen:
646   
647   Miscellaneous Output Register (Read at 3CCh, Write at 3C2h).ram enable
648
649 Choose which addresses are supported for CPU writes:
650
651 Miscellaneous Graphics Register (Index 06h).memory map select
652  
653 00b -- A0000h-BFFFFh (128K region)
654 01b -- A0000h-AFFFFh (64K region)
655 10b -- B0000h-B7FFFh (32K region)
656 11b -- B8000h-BFFFFh (32K region)
657
658 There are three addressing modes: Chain 4, Odd/Even mode, and normal mode:
659
660 Chain 4: This mode is used for MCGA emulation in the 320x200 256-color mode. The address is mapped to memory MOD 4 (shifted right 2 places.)
661
662 Memory model: 64K 32 bit locations; divided into 4 64K bit planes
663
664
665    
666
667
668 Assume linear framebuffer, starting at address buf:
669
670 */
671
672
673
674 static int vga_read(struct guest_info * core, 
675                     addr_t guest_addr, 
676                     void * dst, 
677                     uint_t length, 
678                     void * priv_data)
679 {
680     struct vm_device *dev = (struct vm_device *)priv_data;
681     struct vga_internal *vga = (struct vga_internal *) dev->private_data;
682
683     PrintDebug("vga: memory read: guest_addr=0x%p len=%u\n",(void*)guest_addr, length);
684
685
686     if (vga->passthrough) { 
687         memcpy(dst,V3_VAddr((void*)guest_addr),length);
688     }
689
690                 
691    
692     /*
693       Reading, 2 modes, set via Graphics Mode Register (index 05h).Read Mode:
694     */
695     switch (vga->vga_graphics_controller.vga_graphics_mode.read_mode) { 
696         case 0: {
697             /*      0 - a byte from ONE of the 4 planes is returned; 
698                     which plane is determined by Read Map Select (Read Map Select Register (Index 04h)) */
699             uint8_t  mapnum;
700             uint64_t offset;
701             
702             mapnum = vga->vga_graphics_controller.vga_read_map_select.map_select;
703             offset = find_offset(vga,guest_addr);
704             
705             if (offset>=65536) { 
706                 PrintError("vga: read to offset=%llu map=%u (%u bytes)\n",offset,mapnum,length);
707             }
708
709             memcpy(dst,(vga->map[mapnum])+offset,length);
710
711             // load the latches with the last item read
712             for (mapnum=0;mapnum<4;mapnum++) { 
713                 vga->latch[mapnum] = vga->map[mapnum][offset+length-1];
714             }
715             
716         
717         }
718             break;
719         case 1: {
720             /*      1 - Compare video memory and reference color 
721                     (in Color Compare, except those not set in Color Don't Care), 
722                     each bit in returned result is one comparison between the reference color 
723
724                     Ref color is *4* bits, and thus a one byte read returns a comparison 
725                     with 8 pixels
726
727             */
728             int i;
729
730             uint8_t cc=vga->vga_graphics_controller.vga_color_compare.val & 0xf ;
731             uint8_t dc=vga->vga_graphics_controller.vga_color_dont_care.val & 0xf;
732
733             uint8_t  mapnum;
734             uint64_t offset;
735             uint8_t  byte;
736             uint8_t  bits;
737             
738             offset = find_offset(vga,guest_addr);
739             
740             for (i=0;i<length;i++,offset++) { 
741                 vga_map map;
742                 byte=0;
743                 for (mapnum=0;mapnum<4;mapnum++) { 
744                     map = vga->map[mapnum];
745                     if ( (dc>>mapnum)&0x1 ) { // don't care
746                         bits=0;
747                     } else {
748                         // lower 4 bits
749                         bits = (map[offset]&0xf) == cc;
750                         bits <<= 1;
751                         // upper 4 bits
752                         bits |= (((map[offset]>>4))&0xf) == cc;
753                     }
754                     // not clear whether it is 0..k or k..0
755                     byte<<=2;
756                     byte|=bits;
757                 }
758             }
759
760             // load the latches with the last item read
761             for (mapnum=0;mapnum<4;mapnum++) { 
762                 vga->latch[mapnum] = vga->map[mapnum][offset+length-1];
763             }
764
765         }
766             break;
767             // there is no default
768     }
769
770     return length;
771
772 }
773
774
775
776 static int render(struct vga_internal *vga)
777 {
778     PrintError("vga: render UNIMPLEMENTED\n");
779
780     if (!palacios_linux_fb_hack_pointer) { 
781         return 0;
782     }
783
784
785
786     return 0;
787 }
788
789
790 #define ERR_WRONG_SIZE(op,reg,len,min,max)      \
791     if (((len)<(min)) || ((len)>(max))) {       \
792         PrintError("vga: %s of %s wrong size (%d bytes, but only %d to %d allowed)\n",(op),(reg),(len),(min),(max)); \
793         return -1; \
794 }
795         
796 static inline void passthrough_io_in(uint16_t port, void * dest, uint_t length) {
797     switch (length) {
798         case 1:
799             *(uint8_t *)dest = v3_inb(port);
800             break;
801         case 2:
802             *(uint16_t *)dest = v3_inw(port);
803             break;
804         case 4:
805             *(uint32_t *)dest = v3_indw(port);
806             break;
807         default:
808             PrintError("vga: unsupported passthrough io in size %u\n",length);
809             break;
810     }
811 }
812
813
814 static inline void passthrough_io_out(uint16_t port, const void * src, uint_t length) {
815     switch (length) {
816         case 1:
817             v3_outb(port, *(uint8_t *)src);
818             break;
819         case 2:
820             v3_outw(port, *(uint16_t *)src);
821             break;
822         case 4:
823             v3_outdw(port, *(uint32_t *)src);
824             break;
825         default:
826             PrintError("vga: unsupported passthrough io out size %u\n",length);
827             break;
828     }
829 }
830
831 #define PASSTHROUGH_IO_IN(vga,port,dest,len)                            \
832     do { if ((vga)->passthrough) { passthrough_io_in(port,dest,len); } } while (0)
833
834 #define PASSTHROUGH_IO_OUT(vga,port,src,len)                            \
835     do { if ((vga)->passthrough) { passthrough_io_in(port,src,len); } } while (0)
836                 
837
838
839 static int misc_out_read(struct guest_info *core, 
840                          uint16_t port, 
841                          void *dest,
842                          uint_t len,
843                          void *priv_data)
844 {
845     struct vga_internal *vga = (struct vga_internal *) priv_data;
846
847     PrintDebug("vga: misc out read data=0x%x\n", vga->vga_misc.vga_misc_out.val);
848
849     ERR_WRONG_SIZE("read","misc out",len,1,1);
850     
851     PASSTHROUGH_IO_IN(vga,port,dest,len);
852
853     *((uint8_t*)dest) = vga->vga_misc.vga_misc_out.val;
854
855     return len;
856 }
857
858 static int misc_out_write(struct guest_info *core, 
859                           uint16_t port, 
860                           void *src,
861                           uint_t len,
862                           void *priv_data)
863 {
864     struct vga_internal *vga = (struct vga_internal *) priv_data;
865     
866     PrintDebug("vga: misc out write data=0x%x\n", *((uint8_t*)src));
867         
868     ERR_WRONG_SIZE("write","misc out",len,1,1);
869
870     PASSTHROUGH_IO_OUT(vga,port,src,len);
871
872     vga->vga_misc.vga_misc_out.val =  *((uint8_t*)src) ;
873     
874     render(vga);
875     
876     return len;
877 }
878
879
880
881 static int input_stat0_read(struct guest_info *core, 
882                             uint16_t port, 
883                             void *dest,
884                             uint_t len,
885                             void *priv_data)
886 {
887     struct vga_internal *vga = (struct vga_internal *) priv_data;
888
889     PrintDebug("vga: input stat0  read data=0x%x\n", vga->vga_misc.vga_input_stat0.val);
890
891     ERR_WRONG_SIZE("read","input stat0",len,1,1);
892
893     PASSTHROUGH_IO_IN(vga,port,dest,len);
894
895     *((uint8_t*)dest) = vga->vga_misc.vga_input_stat0.val;
896
897     return len;
898 }
899
900
901 static int input_stat1_read(struct guest_info *core, 
902                             uint16_t port, 
903                             void *dest,
904                             uint_t len,
905                             void *priv_data)
906 {
907     struct vga_internal *vga = (struct vga_internal *) priv_data;
908
909     PrintDebug("vga: input stat0 (%s) read data=0x%x\n", 
910                port==0x3ba ? "mono" : "color",
911                vga->vga_misc.vga_input_stat1.val);
912
913     ERR_WRONG_SIZE("read","input stat1",len,1,1);
914
915     PASSTHROUGH_IO_IN(vga,port,dest,len);
916
917     *((uint8_t*)dest) = vga->vga_misc.vga_input_stat1.val;
918
919     // Stunningly, reading stat1 is also a way to reset
920     // the state of attribute controller address/data flipflop
921     // That is some mighty fine crack the designers were smoking.
922     
923     vga->vga_attribute_controller.state=ATTR_ADDR;
924
925     return len;
926 }
927                          
928
929 static int feature_control_read(struct guest_info *core, 
930                                 uint16_t port, 
931                                 void *dest,
932                                 uint_t len,
933                                 void *priv_data)
934 {
935     struct vga_internal *vga = (struct vga_internal *) priv_data;
936
937     PrintDebug("vga: feature control  read data=0x%x\n", 
938                vga->vga_misc.vga_feature_control.val);
939
940     ERR_WRONG_SIZE("read","feature control",len,1,1);
941
942     PASSTHROUGH_IO_IN(vga,port,dest,len);
943
944     *((uint8_t*)dest) = vga->vga_misc.vga_feature_control.val;
945
946     return len;
947 }
948
949 static int feature_control_write(struct guest_info *core, 
950                                  uint16_t port, 
951                                  void *src,
952                                  uint_t len,
953                                  void *priv_data)
954 {
955     struct vga_internal *vga = (struct vga_internal *) priv_data;
956     
957     PrintDebug("vga: feature control (%s) write data=0x%x\n", 
958                port==0x3ba ? "mono" : "color",
959                *((uint8_t*)src));
960         
961     ERR_WRONG_SIZE("write","feature control",len,1,1);
962     
963     PASSTHROUGH_IO_OUT(vga,port,src,len);
964
965     vga->vga_misc.vga_feature_control.val =  *((uint8_t*)src) ;
966     
967     render(vga);
968     
969     return len;
970 }
971
972
973 static int video_subsys_enable_read(struct guest_info *core, 
974                                     uint16_t port, 
975                                     void *dest,
976                                     uint_t len,
977                                     void *priv_data)
978 {
979     struct vga_internal *vga = (struct vga_internal *) priv_data;
980
981     PrintDebug("vga: video subsys enable read data=0x%x\n", 
982                vga->vga_misc.vga_video_subsys_enable.val);
983
984     ERR_WRONG_SIZE("read","video subsys enable",len,1,1);
985
986     PASSTHROUGH_IO_IN(vga,port,dest,len);
987
988     *((uint8_t*)dest) = vga->vga_misc.vga_video_subsys_enable.val;
989
990     return len;
991 }
992
993 static int video_subsys_enable_write(struct guest_info *core, 
994                                      uint16_t port, 
995                                      void *src,
996                                      uint_t len,
997                                      void *priv_data)
998 {
999     struct vga_internal *vga = (struct vga_internal *) priv_data;
1000     
1001     PrintDebug("vga: video subsys enable write data=0x%x\n", *((uint8_t*)src));
1002         
1003     ERR_WRONG_SIZE("write","video subsys enable",len,1,1);
1004     
1005     PASSTHROUGH_IO_OUT(vga,port,src,len);
1006
1007     vga->vga_misc.vga_video_subsys_enable.val =  *((uint8_t*)src) ;
1008     
1009     render(vga);
1010     
1011     return len;
1012 }
1013
1014 static int sequencer_address_read(struct guest_info *core, 
1015                                   uint16_t port, 
1016                                   void *dest,
1017                                   uint_t len,
1018                                   void *priv_data)
1019 {
1020     struct vga_internal *vga = (struct vga_internal *) priv_data;
1021
1022     PrintDebug("vga: sequencer address read data=0x%x\n", 
1023                vga->vga_sequencer.vga_sequencer_addr.val);
1024
1025     ERR_WRONG_SIZE("read","vga sequencer addr",len,1,1);
1026
1027     PASSTHROUGH_IO_IN(vga,port,dest,len);
1028
1029     *((uint8_t*)dest) = vga->vga_sequencer.vga_sequencer_addr.val;
1030
1031     return len;
1032 }
1033
1034 static int sequencer_data_write(struct guest_info *core, 
1035                                uint16_t port, 
1036                                void *src,
1037                                uint_t len,
1038                                void *priv_data)
1039 {
1040     struct vga_internal *vga = (struct vga_internal *) priv_data;
1041     uint8_t index;
1042     uint8_t data;
1043     
1044     data=*((uint8_t*)src);
1045     index=vga->vga_sequencer.vga_sequencer_addr.val;  // should mask probably
1046     
1047     PrintDebug("vga: sequencer write data (index=%d) with 0x%x\n", 
1048                index, data);
1049     
1050     ERR_WRONG_SIZE("write","vga sequencer data",len,1,1);
1051     
1052     PASSTHROUGH_IO_OUT(vga,port,src,len);
1053
1054     vga->vga_sequencer.vga_sequencer_regs[index] = data;
1055
1056     render(vga);
1057     
1058     return len;
1059 }
1060
1061 static int sequencer_address_write(struct guest_info *core, 
1062                                   uint16_t port, 
1063                                   void *src,
1064                                   uint_t len,
1065                                   void *priv_data)
1066 {
1067     struct vga_internal *vga = (struct vga_internal *) priv_data;
1068     uint8_t new_addr;
1069
1070     new_addr=*((uint8_t*)src);
1071
1072     PrintDebug("vga: sequencer address write data=0x%x len=%u\n", new_addr,len);
1073
1074     ERR_WRONG_SIZE("write","vga sequencer addr",len,1,2);
1075
1076     PASSTHROUGH_IO_OUT(vga,port,src,1);
1077
1078     if (new_addr>VGA_SEQUENCER_NUM) {
1079         PrintError("vga: ignoring change of sequencer address to %u (>%u)\n",
1080                    new_addr, VGA_SEQUENCER_NUM);
1081         //return -1;
1082     } else {
1083         vga->vga_sequencer.vga_sequencer_addr.val =  *((uint8_t*)src) ;
1084         if (len==2) { 
1085             // second byte is the data
1086             if (sequencer_data_write(core,port,src+1,1,vga)!=1) { 
1087                 PrintError("vga: write of data failed\n");
1088                 return -1;
1089             }
1090         }
1091     }
1092
1093
1094     return len;
1095 }
1096
1097 static int sequencer_data_read(struct guest_info *core, 
1098                               uint16_t port, 
1099                               void *dest,
1100                               uint_t len,
1101                               void *priv_data)
1102 {
1103     struct vga_internal *vga = (struct vga_internal *) priv_data;
1104     uint8_t index;
1105     uint8_t data;
1106
1107     index=vga->vga_sequencer.vga_sequencer_addr.val;  // should mask probably
1108     data=vga->vga_sequencer.vga_sequencer_regs[index];
1109     
1110     PrintDebug("vga: sequencer data read data (index=%d) = 0x%x\n", 
1111                index, data);
1112
1113     ERR_WRONG_SIZE("read","vga sequenver data",len,1,1);
1114
1115     PASSTHROUGH_IO_IN(vga,port,dest,len);
1116
1117     *((uint8_t*)dest) = data;
1118
1119     return len;
1120 }
1121
1122  
1123  
1124
1125
1126 static int crt_controller_address_read(struct guest_info *core, 
1127                                         uint16_t port, 
1128                                         void *dest,
1129                                         uint_t len,
1130                                         void *priv_data)
1131 {
1132     struct vga_internal *vga = (struct vga_internal *) priv_data;
1133
1134     PrintDebug("vga: crt controller (%s) address read data=0x%x\n", 
1135                port==0x3b4 ? "mono" : "color",
1136                vga->vga_crt_controller.vga_crt_addr.val);
1137
1138     ERR_WRONG_SIZE("read","vga crt controller addr",len,1,1);
1139
1140     PASSTHROUGH_IO_IN(vga,port,dest,len);
1141
1142     *((uint8_t*)dest) = vga->vga_crt_controller.vga_crt_addr.val;
1143
1144     return len;
1145 }
1146
1147 static int crt_controller_data_write(struct guest_info *core, 
1148                                      uint16_t port, 
1149                                      void *src,
1150                                      uint_t len,
1151                                      void *priv_data)
1152 {
1153     struct vga_internal *vga = (struct vga_internal *) priv_data;
1154     uint8_t index;
1155     uint8_t data;
1156
1157     data=*((uint8_t*)src);
1158
1159     index=vga->vga_crt_controller.vga_crt_addr.val;  // should mask probably
1160     
1161     PrintDebug("vga: crt controller (%s) write data (index=%d) with 0x%x\n", 
1162                port==0x3b5 ? "mono" : "color",
1163                index, data);
1164
1165     ERR_WRONG_SIZE("write","vga crt controller data",len,1,1);
1166
1167     PASSTHROUGH_IO_OUT(vga,port,src,len);
1168
1169     vga->vga_crt_controller.vga_crt_controller_regs[index] = data;
1170
1171     render(vga);
1172
1173     return len;
1174 }
1175
1176 static int crt_controller_address_write(struct guest_info *core, 
1177                                         uint16_t port, 
1178                                         void *src,
1179                                         uint_t len,
1180                                         void *priv_data)
1181 {
1182     struct vga_internal *vga = (struct vga_internal *) priv_data;
1183     uint8_t new_addr;
1184
1185     new_addr=*((uint8_t*)src);
1186
1187     PrintDebug("vga: crt controller (%s) address write data=0x%x len=%u\n", 
1188                port==0x3b4 ? "mono" : "color",
1189                new_addr,len);
1190
1191     ERR_WRONG_SIZE("write","vga crt controller addr",len,1,2);
1192
1193     PASSTHROUGH_IO_OUT(vga,port,src,1);
1194
1195     if (new_addr>VGA_CRT_CONTROLLER_NUM) {
1196         PrintError("vga: ignoring change of crt controller address to %u (>%u)\n",
1197                    new_addr, VGA_CRT_CONTROLLER_NUM);
1198         //return -1;
1199     } else {
1200         vga->vga_crt_controller.vga_crt_addr.val =  *((uint8_t*)src) ;
1201         if (len==2) { 
1202             // second byte is the data
1203             if (crt_controller_data_write(core,port,src+1,1,vga)!=1) { 
1204                 PrintError("vga: write of data failed\n");
1205                 return -1;
1206             }
1207         }
1208
1209     }
1210
1211     return len;
1212 }
1213
1214 static int crt_controller_data_read(struct guest_info *core, 
1215                                     uint16_t port, 
1216                                     void *dest,
1217                                     uint_t len,
1218                                     void *priv_data)
1219 {
1220     struct vga_internal *vga = (struct vga_internal *) priv_data;
1221     uint8_t index;
1222     uint8_t data;
1223
1224     index=vga->vga_crt_controller.vga_crt_addr.val;  // should mask probably
1225     data=vga->vga_crt_controller.vga_crt_controller_regs[index];
1226     
1227     PrintDebug("vga: crt controller data (%s) read data (index=%d) = 0x%x\n", 
1228                port==0x3b5 ? "mono" : "color",
1229                index, data);
1230
1231     ERR_WRONG_SIZE("read","vga crt controller data",len,1,1);
1232
1233     PASSTHROUGH_IO_IN(vga,port,dest,len);
1234
1235     *((uint8_t*)dest) = data;
1236
1237     return len;
1238 }
1239
1240
1241
1242 static int graphics_controller_address_read(struct guest_info *core, 
1243                                             uint16_t port, 
1244                                             void *dest,
1245                                             uint_t len,
1246                                             void *priv_data)
1247 {
1248     struct vga_internal *vga = (struct vga_internal *) priv_data;
1249     
1250     PrintDebug("vga: graphics controller address read data=0x%x\n", 
1251                vga->vga_graphics_controller.vga_graphics_ctrl_addr.val);
1252
1253     ERR_WRONG_SIZE("read","vga graphics controller addr",len,1,1);
1254
1255     PASSTHROUGH_IO_IN(vga,port,dest,len);
1256
1257     *((uint8_t*)dest) = vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;
1258
1259     return len;
1260 }
1261
1262 static int graphics_controller_data_write(struct guest_info *core, 
1263                                           uint16_t port, 
1264                                           void *src,
1265                                           uint_t len,
1266                                           void *priv_data)
1267 {
1268     struct vga_internal *vga = (struct vga_internal *) priv_data;
1269     uint8_t index;
1270     uint8_t data;
1271     
1272     data=*((uint8_t*)src);
1273     index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;  // should mask probably
1274     
1275     PrintDebug("vga: graphics_controller write data (index=%d) with 0x%x\n", 
1276                index, data);
1277     
1278     ERR_WRONG_SIZE("write","vga graphics controller data",len,1,1);
1279     
1280     PASSTHROUGH_IO_OUT(vga,port,src,len);
1281
1282     vga->vga_graphics_controller.vga_graphics_controller_regs[index] = data;
1283
1284     render(vga);
1285     
1286     return len;
1287 }
1288
1289 static int graphics_controller_address_write(struct guest_info *core, 
1290                                              uint16_t port, 
1291                                              void *src,
1292                                              uint_t len,
1293                                              void *priv_data)
1294 {
1295     struct vga_internal *vga = (struct vga_internal *) priv_data;
1296     uint8_t new_addr;
1297
1298     new_addr=*((uint8_t*)src);
1299
1300     PrintDebug("vga: graphics controller address write data=0x%x len=%u\n", new_addr,len);
1301
1302     ERR_WRONG_SIZE("write","vga graphics controller addr",len,1,2);
1303
1304     PASSTHROUGH_IO_OUT(vga,port,src,1);
1305
1306     if (new_addr>VGA_GRAPHICS_CONTROLLER_NUM) {
1307         PrintError("vga: ignoring change of graphics controller address to %u (>%u)\n",
1308                    new_addr, VGA_GRAPHICS_CONTROLLER_NUM);
1309         //return -1;
1310     } else {
1311         vga->vga_graphics_controller.vga_graphics_ctrl_addr.val =  *((uint8_t*)src) ;
1312         if (len==2) { 
1313             // second byte is the data
1314             if (graphics_controller_data_write(core,port,src+1,1,vga)!=1) { 
1315                 PrintError("vga: write of data failed\n");
1316                 return -1;
1317             }
1318         }
1319     }
1320     return len;
1321 }
1322
1323 static int graphics_controller_data_read(struct guest_info *core, 
1324                                          uint16_t port, 
1325                                          void *dest,
1326                                          uint_t len,
1327                                          void *priv_data)
1328 {
1329     struct vga_internal *vga = (struct vga_internal *) priv_data;
1330     uint8_t index;
1331     uint8_t data;
1332
1333     index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;  // should mask probably
1334     data=vga->vga_graphics_controller.vga_graphics_controller_regs[index];
1335     
1336     PrintDebug("vga: graphics controller data read data (index=%d) = 0x%x\n", 
1337                index, data);
1338
1339     ERR_WRONG_SIZE("read","vga graphics controller data",len,1,1);
1340
1341     PASSTHROUGH_IO_IN(vga,port,dest,len);
1342
1343     *((uint8_t*)dest) = data;
1344
1345     return len;
1346 }
1347
1348
1349
1350
1351 /* Note that these guys have a bizarre protocol*/
1352
1353 static int attribute_controller_address_read(struct guest_info *core, 
1354                                              uint16_t port, 
1355                                              void *dest,
1356                                              uint_t len,
1357                                              void *priv_data)
1358 {
1359     struct vga_internal *vga = (struct vga_internal *) priv_data;
1360     
1361     PrintDebug("vga: attribute controller address read data=0x%x\n", 
1362                vga->vga_attribute_controller.vga_attribute_controller_addr.val);
1363
1364     ERR_WRONG_SIZE("read","vga attribute  controller addr",len,1,1);
1365
1366     PASSTHROUGH_IO_IN(vga,port,dest,len);
1367
1368     *((uint8_t*)dest) = vga->vga_attribute_controller.vga_attribute_controller_addr.val;
1369
1370     // Reading the attribute controller does not change the state
1371
1372     return len;
1373 }
1374
1375 static int attribute_controller_address_and_data_write(struct guest_info *core, 
1376                                                        uint16_t port, 
1377                                                        void *src,
1378                                                        uint_t len,
1379                                                        void *priv_data)
1380 {
1381     struct vga_internal *vga = (struct vga_internal *) priv_data;
1382
1383
1384     if (vga->vga_attribute_controller.state==ATTR_ADDR) { 
1385         uint8_t new_addr = *((uint8_t*)src);
1386         // We are to treat this as an address write, and flip state
1387         // to expect data ON THIS SAME PORT
1388         PrintDebug("vga: attribute controller address write data=0x%x\n", new_addr);
1389         
1390         ERR_WRONG_SIZE("write","vga attribute controller addr",len,1,1);
1391
1392         PASSTHROUGH_IO_OUT(vga,port,src,len);
1393
1394         if (new_addr>VGA_ATTRIBUTE_CONTROLLER_NUM) {
1395             PrintError("vga: ignoring change of attribute controller address to %u (>%u)\n",
1396                        new_addr, VGA_ATTRIBUTE_CONTROLLER_NUM);
1397             //return -1;
1398         } else {
1399             vga->vga_attribute_controller.vga_attribute_controller_addr.val =  *((uint8_t*)src) ;
1400         }
1401         vga->vga_attribute_controller.state=ATTR_DATA;
1402         return len;
1403
1404     } else if (vga->vga_attribute_controller.state==ATTR_DATA) { 
1405
1406         uint8_t data = *((uint8_t*)src);
1407         uint8_t index=vga->vga_attribute_controller.vga_attribute_controller_addr.val;  // should mask probably
1408
1409         PrintDebug("vga: attribute controller data write index %d with data=0x%x\n", index,data);
1410         
1411         ERR_WRONG_SIZE("write","vga attribute controller data",len,1,1);
1412
1413         PASSTHROUGH_IO_OUT(vga,port,src,len);
1414         
1415         vga->vga_attribute_controller.vga_attribute_controller_regs[index] = data;
1416         
1417         vga->vga_attribute_controller.state=ATTR_ADDR;
1418         
1419         return len;
1420     }
1421     
1422     return -1;
1423         
1424 }
1425
1426 static int attribute_controller_data_read(struct guest_info *core, 
1427                                           uint16_t port, 
1428                                           void *dest,
1429                                           uint_t len,
1430                                           void *priv_data)
1431 {
1432     struct vga_internal *vga = (struct vga_internal *) priv_data;
1433     uint8_t index;
1434     uint8_t data;
1435
1436     index=vga->vga_attribute_controller.vga_attribute_controller_addr.val;  // should mask probably
1437     data=vga->vga_attribute_controller.vga_attribute_controller_regs[index];
1438     
1439     PrintDebug("vga: attribute controller data read data (index=%d) = 0x%x\n", 
1440                index, data);
1441
1442     ERR_WRONG_SIZE("read","vga attribute controller data",len,1,1);
1443
1444     PASSTHROUGH_IO_IN(vga,port,dest,len);
1445
1446     *((uint8_t*)dest) = data;
1447
1448     return len;
1449 }
1450
1451
1452 /*
1453    Note that these guys also have a strange protocol
1454    since they need to squeeze 18 bits of data through
1455    an 8 bit port 
1456 */
1457 static int dac_write_address_read(struct guest_info *core, 
1458                                   uint16_t port, 
1459                                   void *dest,
1460                                   uint_t len,
1461                                   void *priv_data)
1462 {
1463     struct vga_internal *vga = (struct vga_internal *) priv_data;
1464     
1465     PrintDebug("vga: dac write address read data=0x%x\n", 
1466                vga->vga_dac.vga_dac_write_addr);
1467
1468     ERR_WRONG_SIZE("read","vga dac write addr",len,1,1);
1469
1470     PASSTHROUGH_IO_IN(vga,port,dest,len);
1471
1472     *((uint8_t*)dest) = vga->vga_dac.vga_dac_write_addr;
1473
1474     // This read does not reset the state machine
1475
1476     return len;
1477 }
1478
1479 static int dac_write_address_write(struct guest_info *core, 
1480                                    uint16_t port, 
1481                                    void *src,
1482                                    uint_t len,
1483                                    void *priv_data)
1484 {
1485     struct vga_internal *vga = (struct vga_internal *) priv_data;
1486     uint8_t new_addr;
1487
1488     new_addr=*((uint8_t*)src);
1489
1490     PrintDebug("vga: dac write address write data=0x%x\n", new_addr);
1491
1492     ERR_WRONG_SIZE("write","vga dac write addr",len,1,1);
1493
1494     PASSTHROUGH_IO_OUT(vga,port,src,len);
1495
1496     // cannot be out of bounds since there are 256 regs
1497
1498     vga->vga_dac.vga_dac_write_addr =  *((uint8_t*)src) ;
1499
1500     // Now we also need to reset the state machine
1501     
1502     vga->vga_dac.state=DAC_WRITE;
1503     vga->vga_dac.channel=RED;
1504
1505     return len;
1506 }
1507
1508
1509 static int dac_read_address_read(struct guest_info *core, 
1510                                  uint16_t port, 
1511                                  void *dest,
1512                                  uint_t len,
1513                                  void *priv_data)
1514 {
1515     struct vga_internal *vga = (struct vga_internal *) priv_data;
1516     
1517     PrintDebug("vga: dac read address read data=0x%x\n", 
1518                vga->vga_dac.vga_dac_read_addr);
1519
1520     ERR_WRONG_SIZE("read","vga dac read addr",len,1,1);
1521
1522     PASSTHROUGH_IO_IN(vga,port,dest,len);
1523
1524     *((uint8_t*)dest) = vga->vga_dac.vga_dac_read_addr;
1525
1526     // This read does not reset the state machine
1527
1528     return len;
1529 }
1530
1531 static int dac_read_address_write(struct guest_info *core, 
1532                                   uint16_t port, 
1533                                   void *src,
1534                                   uint_t len,
1535                                   void *priv_data)
1536 {
1537     struct vga_internal *vga = (struct vga_internal *) priv_data;
1538     uint8_t new_addr;
1539
1540     new_addr=*((uint8_t*)src);
1541
1542     PrintDebug("vga: dac read address write data=0x%x\n", new_addr);
1543
1544     ERR_WRONG_SIZE("write","vga dac read addr",len,1,1);
1545
1546     PASSTHROUGH_IO_OUT(vga,port,src,len);
1547
1548     // cannot be out of bounds since there are 256 regs
1549
1550     vga->vga_dac.vga_dac_read_addr =  *((uint8_t*)src) ;
1551
1552     // Now we also need to reset the state machine
1553     
1554     vga->vga_dac.state=DAC_READ;
1555     vga->vga_dac.channel=RED;
1556
1557     return len;
1558 }
1559
1560
1561 static int dac_data_read(struct guest_info *core, 
1562                          uint16_t port, 
1563                          void *dest,
1564                          uint_t len,
1565                          void *priv_data)
1566 {
1567     struct vga_internal *vga = (struct vga_internal *) priv_data;
1568     uint8_t curreg;
1569     uint8_t curchannel;
1570     uint8_t data;
1571     
1572     if (vga->vga_dac.state!=DAC_READ) { 
1573         PrintError("vga: dac data read while in other state\n");
1574         // results undefined, so we continue
1575     }
1576
1577     ERR_WRONG_SIZE("read","vga dac read data",len,1,1);
1578
1579     PASSTHROUGH_IO_IN(vga,port,dest,len);
1580
1581     curreg = vga->vga_dac.vga_dac_read_addr;
1582     curchannel = vga->vga_dac.channel;
1583     data = (vga->vga_dac.vga_dac_palette[curreg] >> curchannel*8) & 0x3f;
1584
1585     PrintDebug("vga: dac reg %u [%s] = 0x%x\n",
1586                curreg, 
1587                curchannel == 0 ? "RED" : curchannel == 1 ? "GREEN" 
1588                           : curchannel==2 ? "BLUE" : "BAD CHANNEL", 
1589                data);
1590
1591     *((uint8_t*)dest) = data;
1592     
1593     curchannel = (curchannel+1)%3;
1594     vga->vga_dac.channel=curchannel;
1595     if (curchannel==0) { 
1596         curreg = (curreg + 1) % VGA_DAC_NUM_ENTRIES;
1597     } 
1598     vga->vga_dac.vga_dac_read_addr = curreg;
1599     vga->vga_dac.state=DAC_READ;
1600
1601     return len;
1602 }
1603
1604
1605
1606 static int dac_data_write(struct guest_info *core, 
1607                           uint16_t port, 
1608                           void *src,
1609                           uint_t len,
1610                           void *priv_data)
1611 {
1612     struct vga_internal *vga = (struct vga_internal *) priv_data;
1613     uint8_t curreg;
1614     uint8_t curchannel;
1615     uint8_t data;
1616     vga_palette_reg data32;
1617     vga_palette_reg mask32;
1618     
1619     if (vga->vga_dac.state!=DAC_WRITE) { 
1620         PrintError("vga: dac data write while in other state\n");
1621         // results undefined, so we continue
1622     }
1623
1624     ERR_WRONG_SIZE("read","vga dac write data",len,1,1);
1625
1626     PASSTHROUGH_IO_OUT(vga,port,src,len);
1627
1628     curreg = vga->vga_dac.vga_dac_write_addr;
1629     curchannel = vga->vga_dac.channel;
1630     data = *((uint8_t *)src);
1631
1632     PrintDebug("vga: dac reg %u [%s] write with 0x%x\n",
1633                curreg, 
1634                curchannel == 0 ? "RED" : curchannel == 1 ? "GREEN" 
1635                           : curchannel==2 ? "BLUE" : "BAD CHANNEL", 
1636                data);
1637
1638     data32 = data & 0x3f ;
1639     data32 <<= curchannel*8;
1640     mask32 = ~(0xff << (curchannel * 8));
1641
1642     vga->vga_dac.vga_dac_palette[curreg] &= mask32;
1643     vga->vga_dac.vga_dac_palette[curreg] |= data32;
1644
1645     curchannel = (curchannel+1)%3;
1646     vga->vga_dac.channel=curchannel;
1647     if (curchannel==0) { 
1648         curreg = (curreg + 1) % VGA_DAC_NUM_ENTRIES;
1649     } 
1650     vga->vga_dac.vga_dac_write_addr = curreg;
1651     vga->vga_dac.state=DAC_WRITE;
1652
1653     render(vga);
1654
1655     return len;
1656 }
1657
1658  
1659
1660 static int dac_pixel_mask_read(struct guest_info *core, 
1661                                uint16_t port, 
1662                                void *dest,
1663                                uint_t len,
1664                                void *priv_data)
1665 {
1666     struct vga_internal *vga = (struct vga_internal *) priv_data;
1667     
1668     PrintDebug("vga: dac pixel mask read data=0x%x\n", 
1669                vga->vga_dac.vga_pixel_mask);
1670
1671     ERR_WRONG_SIZE("read","vga pixel mask",len,1,1);
1672
1673     PASSTHROUGH_IO_IN(vga,port,dest,len);
1674
1675     *((uint8_t*)dest) = vga->vga_dac.vga_pixel_mask;
1676
1677     return len;
1678 }
1679
1680 static int dac_pixel_mask_write(struct guest_info *core, 
1681                                 uint16_t port, 
1682                                 void *src,
1683                                 uint_t len,
1684                                 void *priv_data)
1685 {
1686     struct vga_internal *vga = (struct vga_internal *) priv_data;
1687     uint8_t new_data;
1688
1689     new_data=*((uint8_t*)src);
1690
1691     PrintDebug("vga: dac pixel mask write data=0x%x\n", new_data);
1692
1693     ERR_WRONG_SIZE("write","pixel mask",len,1,1);
1694
1695     PASSTHROUGH_IO_OUT(vga,port,src,len);
1696
1697     vga->vga_dac.vga_pixel_mask =  new_data;
1698
1699     return len;
1700 }
1701
1702 static int init_vga(struct vga_internal *vga)
1703 {
1704     // TODO: startup spec of register contents, if any
1705     PrintError("vga: init_vga is UNIMPLEMTED\n");
1706     return 0;
1707 }
1708
1709 static int free_vga(struct vga_internal *vga) 
1710 {
1711     int i;
1712     int ret;
1713     struct vm_device *dev = vga->dev;
1714
1715     // Framebuffer deletion is user's responsibility
1716
1717     //    if (vga->mem_store) {
1718     //  V3_FreePages(v3_hva_to_hpa(vga->mem_store),MEM_REGION_NUM_PAGES);
1719     //  vga->mem_store=0;
1720     //}
1721     
1722     for (i=0;i<MAP_NUM;i++) { 
1723         if (vga->map[i]) { 
1724             V3_FreePages(V3_PAddr(vga->map[i]),MAP_SIZE/4096);
1725             vga->map[i]=0;
1726         }
1727     }
1728
1729     v3_unhook_mem(vga->dev->vm, V3_MEM_CORE_ANY, MEM_REGION_START);
1730
1731     ret = 0;
1732
1733     ret |= v3_dev_unhook_io(dev, VGA_MISC_OUT_READ);
1734     // The following also covers VGA_INPUT_STAT0_READ
1735     ret |= v3_dev_unhook_io(dev, VGA_MISC_OUT_WRITE);
1736     // The following also covers VGA_FEATURE_CTRL_WRITE_MONO
1737     ret |= v3_dev_unhook_io(dev, VGA_INPUT_STAT1_READ_MONO);
1738     // The folowinn also covers VGA FEATURE_CONTROL_WRITE_COLOR
1739     ret |= v3_dev_unhook_io(dev, VGA_INPUT_STAT1_READ_COLOR);
1740     ret |= v3_dev_unhook_io(dev, VGA_FEATURE_CONTROL_READ);
1741     
1742     ret |= v3_dev_unhook_io(dev, VGA_VIDEO_SUBSYS_ENABLE);
1743
1744     /* Sequencer registers */
1745     ret |= v3_dev_unhook_io(dev, VGA_SEQUENCER_ADDRESS);
1746     ret |= v3_dev_unhook_io(dev, VGA_SEQUENCER_DATA);
1747
1748     /* CRT controller registers */
1749     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_MONO);
1750     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_COLOR);
1751     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_DATA_MONO);
1752     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_DATA_COLOR);
1753
1754     /* graphics controller registers */
1755     ret |= v3_dev_unhook_io(dev, VGA_GRAPHICS_CONTROLLER_ADDRESS);
1756     ret |= v3_dev_unhook_io(dev, VGA_GRAPHICS_CONTROLLER_DATA);
1757
1758     /* attribute controller registers */
1759     ret |= v3_dev_unhook_io(dev, VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE);
1760     ret |= v3_dev_unhook_io(dev, VGA_ATTRIBUTE_CONTROLLER_READ);
1761
1762     /* video DAC palette registers */
1763     ret |= v3_dev_unhook_io(dev, VGA_DAC_WRITE_ADDR);
1764     ret |= v3_dev_unhook_io(dev, VGA_DAC_READ_ADDR);
1765     ret |= v3_dev_unhook_io(dev, VGA_DAC_DATA);
1766     ret |= v3_dev_unhook_io(dev, VGA_DAC_PIXEL_MASK);
1767
1768
1769     V3_Free(vga);
1770
1771     return 0;
1772 }
1773
1774 static struct v3_device_ops dev_ops = {
1775     .free = (int (*)(void *))free_vga,
1776 };
1777
1778
1779 static int vga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1780     struct vga_internal *vga;
1781     int i;
1782     int ret;
1783
1784     char * dev_id = v3_cfg_val(cfg, "ID");
1785     char * passthrough = v3_cfg_val(cfg, "passthrough");
1786
1787     // DETERMINE THE FRAMEBUFFER AND SET IT EARLY
1788     // FRAMEBUFFER IS SUPPLIED BY THE BACKEND
1789
1790     PrintDebug("vga: init_device\n");
1791
1792     vga = (struct vga_internal *)V3_Malloc(sizeof(struct vga_internal));
1793
1794     if (!vga) { 
1795         PrintError("vga: cannot allocate\n");
1796         return -1;
1797     }
1798
1799     memset(vga, 0, sizeof(struct vga_internal));
1800
1801     if (passthrough && strcasecmp(passthrough,"enable")==0) {
1802         PrintDebug("vga: enabling passthrough\n");
1803         vga->passthrough=true;
1804     }
1805
1806     // No memory store is allocated since we will use a full memory hook
1807     // The VGA maps can be read as well as written
1808     // Reads also affect writes, since they are how you fill the latches
1809
1810     // Now allocate the maps
1811     for (i=0;i<MAP_NUM;i++) { 
1812         vga->map[i] = (vga_map) V3_VAddr((void*)V3_AllocPages(MAP_SIZE/4096));
1813         if (!(vga->map[i])) {
1814             PrintError("vga: cannot allocate maps\n");
1815             free_vga(vga);
1816             return -1;
1817         }
1818         memset(vga->map[i],0,MAP_SIZE);
1819     }
1820     
1821     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, vga);
1822     
1823     if (dev == NULL) {
1824         PrintError("Could not attach device %s\n", dev_id);
1825         free_vga(vga);
1826         return -1;
1827     }
1828     
1829     vga->dev = dev;
1830     
1831     if (v3_hook_full_mem(vm, V3_MEM_CORE_ANY, 
1832                          MEM_REGION_START, MEM_REGION_END,
1833                          &vga_read, 
1834                          &vga_write,
1835                          dev) == -1) {
1836         PrintError("vga: memory book failed\n");
1837         v3_remove_device(dev);
1838         return -1;
1839     }
1840
1841     ret = 0;
1842     
1843     /* Miscelaneous registers */
1844     ret |= v3_dev_hook_io(dev, VGA_MISC_OUT_READ, &misc_out_read, NULL);
1845     // The following also covers VGA_INPUT_STAT0_READ
1846     ret |= v3_dev_hook_io(dev, VGA_MISC_OUT_WRITE, &input_stat0_read, &misc_out_write);
1847     // The following also covers VGA_FEATURE_CTRL_WRITE_MONO
1848     ret |= v3_dev_hook_io(dev, VGA_INPUT_STAT1_READ_MONO, &input_stat1_read, &feature_control_write);
1849     // The folowinn also covers VGA FEATURE_CONTROL_WRITE_COLOR
1850     ret |= v3_dev_hook_io(dev, VGA_INPUT_STAT1_READ_COLOR, &input_stat1_read, &feature_control_write);
1851     ret |= v3_dev_hook_io(dev, VGA_FEATURE_CONTROL_READ, &feature_control_read, NULL);
1852     
1853     ret |= v3_dev_hook_io(dev, VGA_VIDEO_SUBSYS_ENABLE, &video_subsys_enable_read, &video_subsys_enable_write);
1854
1855     /* Sequencer registers */
1856     ret |= v3_dev_hook_io(dev, VGA_SEQUENCER_ADDRESS, &sequencer_address_read, &sequencer_address_write);
1857     ret |= v3_dev_hook_io(dev, VGA_SEQUENCER_DATA, &sequencer_data_read, &sequencer_data_write);
1858
1859     /* CRT controller registers */
1860     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_MONO, &crt_controller_address_read,&crt_controller_address_write);
1861     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_COLOR, &crt_controller_address_read,&crt_controller_address_write);
1862     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_DATA_MONO, &crt_controller_data_read,&crt_controller_data_write);
1863     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_DATA_COLOR, &crt_controller_data_read,&crt_controller_data_write);
1864
1865     /* graphics controller registers */
1866     ret |= v3_dev_hook_io(dev, VGA_GRAPHICS_CONTROLLER_ADDRESS, &graphics_controller_address_read,&graphics_controller_address_write);
1867     ret |= v3_dev_hook_io(dev, VGA_GRAPHICS_CONTROLLER_DATA, &graphics_controller_data_read,&graphics_controller_data_write);
1868
1869     /* attribute controller registers */
1870     ret |= v3_dev_hook_io(dev, VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE, &attribute_controller_address_read,&attribute_controller_address_and_data_write);
1871     ret |= v3_dev_hook_io(dev, VGA_ATTRIBUTE_CONTROLLER_READ, &attribute_controller_data_read,NULL);
1872
1873     /* video DAC palette registers */
1874     ret |= v3_dev_hook_io(dev, VGA_DAC_WRITE_ADDR, &dac_write_address_read,&dac_write_address_write);
1875     ret |= v3_dev_hook_io(dev, VGA_DAC_READ_ADDR, &dac_read_address_read,&dac_read_address_write);
1876     ret |= v3_dev_hook_io(dev, VGA_DAC_DATA, &dac_data_read, &dac_data_write);
1877     ret |= v3_dev_hook_io(dev, VGA_DAC_PIXEL_MASK, &dac_pixel_mask_read, &dac_pixel_mask_write);
1878
1879     if (ret != 0) {
1880         PrintError("vga: Error allocating VGA I/O ports\n");
1881         v3_remove_device(dev);
1882         return -1;
1883     }
1884
1885     init_vga(vga);
1886
1887     PrintDebug("vga: successfully added and initialized, waiting for framebuffer attach\n");
1888
1889     return 0;
1890
1891 }
1892
1893 device_register("VGA", vga_init);