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 state, i/o hooks, mem hook implemented
[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
38 #define VGA_MISC_OUT_READ 0x3cc
39 #define VGA_MISC_OUT_WRITE 0x3c2
40
41 #define VGA_INPUT_STAT0_READ 0x3c2
42
43 #define VGA_INPUT_STAT1_READ_MONO 0x3ba
44 #define VGA_INPUT_STAT1_READ_COLOR 0x3da
45
46 #define VGA_FEATURE_CONTROL_READ 0x3ca
47 #define VGA_FEATURE_CONTROL_WRITE_MONO 0x3ba
48 #define VGA_FEATURE_CONTROL_WRITE_COLOR 0x3da
49
50 #define VGA_VIDEO_SUBSYS_ENABLE 0x3c3
51
52 #define VGA_SEQUENCER_ADDRESS 0x3c4
53 #define VGA_SEQUENCER_DATA 0x3c5
54 #define VGA_SEQUENCER_NUM 5
55
56
57 #define VGA_CRT_CONTROLLER_ADDRESS_MONO 0x3b4
58 #define VGA_CRT_CONTROLLER_ADDRESS_COLOR 0x3d4
59 #define VGA_CRT_CONTROLLER_DATA_MONO 0x3b5
60 #define VGA_CRT_CONTROLLER_DATA_COLOR 0x3d5
61 #define VGA_CRT_CONTROLLER_NUM 25
62
63
64 #define VGA_GRAPHICS_CONTROLLER_ADDRESS 0x3ce
65 #define VGA_GRAPHICS_CONTROLLER_DATA 0x3cf
66 #define VGA_GRAPHICS_CONTROLLER_NUM 9
67
68 #define VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE 0x3c0
69 #define VGA_ATTRIBUTE_CONTROLLER_READ 0x3c1
70 #define VGA_ATTRIBUTE_CONTROLLER_NUM 21
71
72 #define VGA_DAC_WRITE_ADDR 0x3c8
73 #define VGA_DAC_READ_ADDR 0x3c7
74 #define VGA_DAC_DATA 0x3c8
75 #define VGA_DAC_PIXEL_MASK 0x3c6
76
77 #define VGA_DAC_NUM_ENTRIES 256
78
79 struct vga_misc_regs {
80     /* Read: 0x3cc; Write: 0x3c2 */
81     struct vga_misc_out_reg        vga_misc_out;
82     /* Read: 0x3c2 */
83     struct vga_input_stat0_reg     vga_input_stat0;
84     /* Read: 0x3?a  3ba for mono; 3da for cga set by misc.io_addr_sel */
85     struct vga_input_stat1_reg     vga_input_stat1; 
86     /* Read: 0x3ca; Write: 0x3?a 3ba for mono 3da for color - set by misc.io_addr_sel*/
87     struct vga_feature_control_reg vga_feature_control;
88     /* Read: 0x3c3; Write: 0x3c3 */
89     struct vga_video_subsys_enable_reg vga_video_subsys_enable;
90 } __attribute__((packed));
91
92 struct vga_sequencer_regs {
93     /*   Address register is 0x3c4, data register is 0x3c5 */
94     /* 0x3c4 */
95     struct vga_sequencer_addr_reg vga_sequencer_addr;
96
97     /* these can be accessed via the index, offset on start 
98        or via the specific regs.   For this reason, it is essential
99        that this is all packed and that the order does not change */
100     
101     uint8_t  vga_sequencer_regs[0];
102
103     /* Index 0 */
104     struct vga_reset_reg   vga_reset;
105     /* Index 1 */
106     struct vga_clocking_mode_reg vga_clocking_mode;
107     /* Index 2 */
108     struct vga_map_mask_reg vga_map_mask;
109     /* Index 3 */
110     struct vga_char_map_select_reg vga_char_map_select;
111     /* Index 4 */
112     struct vga_mem_mode_reg  vga_mem_mode;
113 } __attribute__((packed));
114
115 struct vga_crt_controller_regs {
116     /* Address Register is 0x3b4 or 0x3d4 */
117     /* Data register is 0x3b5 or 0x3d5 based on mono versus color */
118     struct vga_crt_addr_reg vga_crt_addr;
119
120     /* these can be accessed via the index, offset on start 
121        or via the specific regs.   For this reason, it is essential
122        that this is all packed and that the order does not change */
123     
124     uint8_t  vga_crt_controller_regs[0];
125
126     /* index 0 */
127     vga_horizontal_total_reg vga_horizontal_total;
128     /* index 1 */
129     vga_horizontal_display_enable_end_reg vga_horizontal_display_enable_end;
130     /* index 2 */
131     vga_start_horizontal_blanking_reg vga_start_horizontal_blanking;
132     /* index 3 */
133     struct vga_end_horizontal_blanking_reg vga_end_horizontal_blanking;
134     /* index 4 */
135     vga_start_horizontal_retrace_pulse_reg vga_start_horizontal_retrace_pulse;
136     /* index 5 */
137     struct vga_end_horizontal_retrace_reg vga_end_horizontal_retrace;
138     /* index 6 */
139     vga_vertical_total_reg vga_vertical_total;
140     /* index 7 */
141     struct vga_overflow_reg vga_overflow;
142     /* index 8 */
143     struct vga_preset_row_scan_reg vga_preset_row_scan;
144     /* index 9 */
145     struct vga_max_row_scan_reg vga_row_scan;
146     /* index 10 */
147     struct vga_cursor_start_reg vga_cursor_start;
148     /* index 11 */
149     struct vga_cursor_end_reg vga_cursor_end;
150     /* index 12 */
151     vga_start_address_high_reg vga_start_address_high;
152     /* index 13 */
153     vga_start_address_low_reg vga_start_address_low;
154     /* index 14 */
155     vga_cursor_location_high_reg vga_cursor_location_high;
156     /* index 15 */
157     vga_cursor_location_low_reg vga_cursor_location_low;
158     /* index 16 */
159     vga_vertical_retrace_start_reg vga_vertical_retrace_start;
160     /* index 17 */
161     struct vga_vertical_retrace_end_reg vga_vertical_retrace_end;
162     /* index 18 */
163     vga_vertical_display_enable_end_reg vga_vertical_display_enable;
164     /* index 19 */
165     vga_offset_reg vga_offset;
166     /* index 20 */
167     struct vga_underline_location_reg vga_underline_location;
168     /* index 21 */
169     vga_start_vertical_blanking_reg vga_start_vertical_blanking;
170     /* index 22 */
171     vga_end_vertical_blanking_reg vga_end_vertical_blanking;
172     /* index 23 */
173     struct vga_crt_mode_control_reg vga_crt_mode_control;
174     /* index 24 */
175     vga_line_compare_reg vga_line_compare;
176 } __attribute__((packed));
177
178 struct vga_graphics_controller_regs {
179     /*   Address: 0x3ce    Data: 0x3cf */
180
181     /* 0x3ce */
182     struct vga_graphics_ctrl_addr_reg vga_graphics_ctrl_addr;
183
184     /* these can be accessed via the index, offset on start 
185        or via the specific regs.   For this reason, it is essential
186        that this is all packed and that the order does not change */
187     
188     uint8_t  vga_graphics_controller_regs[0];
189
190     /* Index 0 */
191     struct vga_set_reset_reg vga_set_reset;
192     /* Index 1 */
193     struct vga_enable_set_reset_reg vga_enable_set_reset;
194     /* Index 2 */
195     struct vga_color_compare_reg vga_color_compare;
196     /* Index 3 */
197     struct vga_data_rotate_reg vga_data_rotate;
198     /* Index 4 */
199     struct vga_read_map_select_reg vga_read_map_select;
200     /* Index 5 */
201     struct vga_graphics_mode_reg vga_graphics_mode;
202     /* Index 6 */
203     struct vga_misc_reg vga_misc;
204     /* Index 7 */
205     struct vga_color_dont_care__reg vga_color_dont_care;
206     /* Index 8 */
207     vga_bit_mask_reg vga_bit_mask;
208 } __attribute__((packed));
209
210
211 struct vga_attribute_contoller_regs {
212     /*
213       Address AND WRITE: 0x3c0
214       Read: 0x3c1
215
216       The write protocol is to write the index to 0x3c0 followed by 
217       the data.  The read protocol is to write the index to 0x3c0
218       and then read from 0x3c1
219   
220       IMPORTANT: write address, write data flips state back to write address
221       write address, read data DOES NOT
222
223       To reset to write address state, read input status register 1
224 */
225     enum { ATTR_ADDR, ATTR_DATA }  state;  //state of the flip flop
226
227     /* 0x3c0 */
228     struct vga_attribute_controller_address_reg vga_attribute_controller_addr;
229
230
231     
232     /* these can be accessed via the index, offset on start 
233        or via the specific regs.   For this reason, it is essential
234        that this is all packed and that the order does not change */
235     
236     uint8_t  vga_attribute_controller_regs[0];
237
238     /* Indices 0..15 */
239     vga_internal_palette_regs   vga_internal_palette;
240     /* Index 16 */
241     struct vga_attribute_mode_control_reg vga_attribute_mode_control;
242     /* Index 17 */
243     vga_overscan_color_reg vga_overscan_color;
244     /* Index 18 */
245     struct vga_color_plane_enable_reg vga_color_plane_enable;
246     /* Index 19 */
247     struct vga_horizontal_pixel_pan_reg vga_horizontal_pixel_pan;
248     /* Index 20 */
249     struct vga_color_select_reg vga_color_select;
250 } __attribute__((packed));
251
252 struct vga_dac_regs {
253     enum {DAC_READ=0, DAC_WRITE} state;
254     enum {RED=0,GREEN,BLUE} channel;
255     vga_dac_pixel_mask_reg vga_pixel_mask;
256     vga_dac_write_addr_reg vga_dac_write_addr;
257     vga_dac_read_addr_reg vga_dac_read_addr;
258     // the dac_data register is used only to access the registers
259     // and thus has no representation here
260     vga_palette_reg vga_dac_palette[VGA_DAC_NUM_ENTRIES];
261 } __attribute__((packed));
262     
263
264 struct vga_internal {
265     struct vm_device *dev;  
266
267     struct frame_buf *framebuf; // we render to this
268     
269     //    void *mem_store;     // This is the region where the memory hooks will go
270
271     vga_map  map[MAP_NUM];  // the maps that the host writes to
272
273     /* Range of I/O ports here for backward compat with MDA and CGA */
274     struct vga_misc_regs  vga_misc;
275
276     /* Address Register is 0x3b4 or 0x3d4 */
277     /* Data register is 0x3b5 or 0x3d5 based on MDA/CGA/VGA (backward compat) */
278     struct vga_crt_controller_regs vga_crt_controller;
279
280     /*   Address register is 0x3c4, data register is 0x3c5 */
281     struct vga_sequencer_regs vga_sequencer;
282
283     /*   Address: 0x3ce    Data: 0x3cf */
284     struct vga_graphics_controller_regs vga_graphics_controller;
285
286     /*
287       Address AND WRITE: 0x3c0
288       Read: 0x3c1
289       Flip-Flop
290     */
291     struct vga_attribute_contoller_regs vga_attribute_controller;
292
293     /*
294       address for reads: 0x3c7 (also resets state machine for access to 18 bit regs 
295       address for writes: 0x3c8 ("")
296       data: 0x3c9
297       pixel mask: 0x3c6 - do not write (init to 0xff)
298     */
299     struct vga_dac_regs vga_dac;
300 };
301
302
303
304 static int vga_write(struct guest_info * core, 
305                      addr_t guest_addr, 
306                      void * src, 
307                      uint_t length, 
308                      void * priv_data)
309 {
310
311
312     PrintError("vga: vga_write UNIMPLEMENTED\n");
313
314 /*
315 up to 256K mapped through a window of 128K
316
317 most cards support linear mode as well
318
319 Need to implement readability too
320
321 Write extended memory bit to enable all 256K: 
322
323    Sequencer Memory Mode Register (Index 04h) . extended memory
324
325 Must enable writes before effects happen:
326   
327   Miscellaneous Output Register (Read at 3CCh, Write at 3C2h).ram enable
328
329 Choose which addresses are supported for CPU writes:
330
331 Miscellaneous Graphics Register (Index 06h).memory map select
332  
333 00b -- A0000h-BFFFFh (128K region)
334 01b -- A0000h-AFFFFh (64K region)
335 10b -- B0000h-B7FFFh (32K region)
336 11b -- B8000h-BFFFFh (32K region)
337
338 There are three addressing modes: Chain 4, Odd/Even mode, and normal mode:
339
340 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.)
341
342 Memory model: 64K 32 bit locations; divided into 4 64K bit planes
343
344 Write Modes - set via Graphics Mode Register (Index 05h).writemode
345
346 00b -- Write Mode 0: In this mode, the host data is first rotated as per the Rotate Count field, then the Enable Set/Reset mechanism selects data from this or the Set/Reset field. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory.
347
348 01b -- Write Mode 1: In this mode, data is transferred directly from the 32 bit latch register to display memory, affected only by the Memory Plane Write Enable field. The host data is not used in this mode.
349
350 10b -- Write Mode 2: In this mode, the bits 3-0 of the host data are replicated across all 8 bits of their respective planes. Then the selected Logical Operation is performed on the resulting data and the data in the latch register. Then the Bit Mask field is used to select which bits come from the resulting data and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory.
351
352 11b -- Write Mode 3: In this mode, the data in the Set/Reset field is used as if the Enable Set/Reset field were set to 1111b. Then the host data is first rotated as per the Rotate Count field, then logical ANDed with the value of the Bit Mask field. The resulting value is used on the data obtained from the Set/Reset field in the same way that the Bit Mask field would ordinarily be used. to select which bits come from the expansion of the Set/Reset field and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory.
353
354 five stages of a write:
355
356 write(void *adx, uint8_t x)  // or 4 byte?!
357   
358 uint8_t rx[4];
359
360 switch (Write Mode) { 
361 case 0:
362 // 1. Rotate
363    x = ROR(x,Rotate Count)
364
365 // 2. Clone from Host Data or Set/Reset Reg
366    for (i=0;i<4;i++) { 
367       if (Enable Set/Reset[i]) {
368           rx[i]=Set/Reset (expanded to 8 bits)
369        } else { 
370           rx[i]=x;
371        }
372    }    
373
374 // 3. Logical Operator 
375    for (i=0;i<4;i++) {
376       rx[i] = rx[i] LOP LATCH_REG[i]
377 //    LOP = NOP, AND, OR, XOR
378    }
379
380 // 4. Select
381    for (i=0;i<4;i++) { 
382       rx[i] = BITWISE_MUX(rx[i], LATCH_REG[i], Bit Mask Reg);
383    }
384
385 // 5. Selective Write
386    for (i=0;i<4;i++) { 
387      if (Map Mask Reg.Memory Plane Write Enable[i])
388       BUF[TRANSLATE(adx,i)] = rx[i];
389    }
390 break;
391
392 case 1:
393 // 4. Select latch register directly
394    for (i=0;i<4;i++) { 
395       rx[i] = LATCH_REG[i];
396    }
397 // 5. Selective Write
398    for (i=0;i<4;i++) { 
399      if (Map Mask Reg.Memory Plane Write Enable[i])
400       BUF[TRANSLATE(adx,i)] = rx[i];
401    }
402
403
404
405    
406
407
408 Assume linear framebuffer, starting at address buf:
409
410 */
411     return -1;
412 }
413
414
415 static int vga_read(struct guest_info * core, 
416                     addr_t guest_addr, 
417                     void * dst, 
418                     uint_t length, 
419                     void * priv_data)
420 {
421
422     PrintError("vga: vga_read UNIMPLEMENTED\n");
423
424     /*
425       Reading, 2 modes, set via Graphics Mode Register (index 05h).Read Mode:
426       0 - a byte from ONE of the 4 planes is returned; which plane is determined by Read Map Select (Read Map Select Register (Index 04h))
427       1 - Compare video memory and reference color (in Color Compare, except those not set in Color Don't Care), each bit in returned result is one comparison between the reference color, and is set to one if true (plane by plane, I assume)
428     */
429     
430     return -1;
431 }
432
433
434
435 static int render(struct vga_internal *vga)
436 {
437     PrintError("vga: render UNIMPLEMENTED\n");
438     return 0;
439 }
440
441
442 #define ERR_WRONG_SIZE(op,reg,len,min,max)      \
443     if (((len)<(min)) || ((len)>(max))) {       \
444         PrintError("vga: %s of %s wrong size (%d bytes, but only %d to %d allowed)\n",(op),(reg),(len),(min),(max)); \
445         return -1; \
446 }
447         
448
449
450 static int misc_out_read(struct guest_info *core, 
451                          uint16_t port, 
452                          void *dest,
453                          uint_t len,
454                          void *priv_data)
455 {
456     struct vga_internal *vga = (struct vga_internal *) priv_data;
457
458     PrintDebug("vga: misc out read data=0x%x\n", vga->vga_misc.vga_misc_out.val);
459
460     ERR_WRONG_SIZE("read","misc out",len,1,1);
461
462     *((uint8_t*)dest) = vga->vga_misc.vga_misc_out.val;
463
464     return len;
465 }
466
467 static int misc_out_write(struct guest_info *core, 
468                           uint16_t port, 
469                           void *src,
470                           uint_t len,
471                           void *priv_data)
472 {
473     struct vga_internal *vga = (struct vga_internal *) priv_data;
474     
475     PrintDebug("vga: misc out write data=0x%x\n", *((uint8_t*)src));
476         
477     ERR_WRONG_SIZE("write","misc out",len,1,1);
478     
479     vga->vga_misc.vga_misc_out.val =  *((uint8_t*)src) ;
480     
481     render(vga);
482     
483     return len;
484 }
485
486
487
488 static int input_stat0_read(struct guest_info *core, 
489                             uint16_t port, 
490                             void *dest,
491                             uint_t len,
492                             void *priv_data)
493 {
494     struct vga_internal *vga = (struct vga_internal *) priv_data;
495
496     PrintDebug("vga: input stat0  read data=0x%x\n", vga->vga_misc.vga_input_stat0.val);
497
498     ERR_WRONG_SIZE("read","inpust stat0",len,1,1);
499
500     *((uint8_t*)dest) = vga->vga_misc.vga_input_stat0.val;
501
502     return len;
503 }
504
505
506 static int input_stat1_read(struct guest_info *core, 
507                             uint16_t port, 
508                             void *dest,
509                             uint_t len,
510                             void *priv_data)
511 {
512     struct vga_internal *vga = (struct vga_internal *) priv_data;
513
514     PrintDebug("vga: input stat0 (%s) read data=0x%x\n", 
515                port==0x3ba ? "mono" : "color",
516                vga->vga_misc.vga_input_stat1.val);
517
518     ERR_WRONG_SIZE("read","inpust stat1",len,1,1);
519
520     *((uint8_t*)dest) = vga->vga_misc.vga_input_stat1.val;
521
522     // Stunningly, reading stat1 is also a way to reset
523     // the state of attribute controller address/data flipflop
524     // That is some mighty fine crack the designers were smoking.
525     
526     vga->vga_attribute_controller.state=ATTR_ADDR;
527
528     return len;
529 }
530                          
531
532 static int feature_control_read(struct guest_info *core, 
533                                 uint16_t port, 
534                                 void *dest,
535                                 uint_t len,
536                                 void *priv_data)
537 {
538     struct vga_internal *vga = (struct vga_internal *) priv_data;
539
540     PrintDebug("vga: feature control  read data=0x%x\n", 
541                vga->vga_misc.vga_feature_control.val);
542
543     ERR_WRONG_SIZE("read","feature control",len,1,1);
544
545     *((uint8_t*)dest) = vga->vga_misc.vga_feature_control.val;
546
547     return len;
548 }
549
550 static int feature_control_write(struct guest_info *core, 
551                                  uint16_t port, 
552                                  void *src,
553                                  uint_t len,
554                                  void *priv_data)
555 {
556     struct vga_internal *vga = (struct vga_internal *) priv_data;
557     
558     PrintDebug("vga: feature control (%s) write data=0x%x\n", 
559                port==0x3ba ? "mono" : "color",
560                *((uint8_t*)src));
561         
562     ERR_WRONG_SIZE("write","feature control",len,1,1);
563     
564     vga->vga_misc.vga_feature_control.val =  *((uint8_t*)src) ;
565     
566     render(vga);
567     
568     return len;
569 }
570
571
572 static int video_subsys_enable_read(struct guest_info *core, 
573                                     uint16_t port, 
574                                     void *dest,
575                                     uint_t len,
576                                     void *priv_data)
577 {
578     struct vga_internal *vga = (struct vga_internal *) priv_data;
579
580     PrintDebug("vga: video subsys enable read data=0x%x\n", 
581                vga->vga_misc.vga_video_subsys_enable.val);
582
583     ERR_WRONG_SIZE("read","video subsys enable",len,1,1);
584
585     *((uint8_t*)dest) = vga->vga_misc.vga_video_subsys_enable.val;
586
587     return len;
588 }
589
590 static int video_subsys_enable_write(struct guest_info *core, 
591                                      uint16_t port, 
592                                      void *src,
593                                      uint_t len,
594                                      void *priv_data)
595 {
596     struct vga_internal *vga = (struct vga_internal *) priv_data;
597     
598     PrintDebug("vga: video subsys enable write data=0x%x\n", *((uint8_t*)src));
599         
600     ERR_WRONG_SIZE("write","video subsys enable",len,1,1);
601     
602     vga->vga_misc.vga_video_subsys_enable.val =  *((uint8_t*)src) ;
603     
604     render(vga);
605     
606     return len;
607 }
608
609 static int sequencer_address_read(struct guest_info *core, 
610                                   uint16_t port, 
611                                   void *dest,
612                                   uint_t len,
613                                   void *priv_data)
614 {
615     struct vga_internal *vga = (struct vga_internal *) priv_data;
616
617     PrintDebug("vga: sequencer address read data=0x%x\n", 
618                vga->vga_sequencer.vga_sequencer_addr.val);
619
620     ERR_WRONG_SIZE("read","vga sequenver addr",len,1,1);
621
622     *((uint8_t*)dest) = vga->vga_sequencer.vga_sequencer_addr.val;
623
624     return len;
625 }
626
627 static int sequencer_address_write(struct guest_info *core, 
628                                   uint16_t port, 
629                                   void *src,
630                                   uint_t len,
631                                   void *priv_data)
632 {
633     struct vga_internal *vga = (struct vga_internal *) priv_data;
634     uint8_t new_addr;
635
636     new_addr=*((uint8_t*)src);
637
638     PrintDebug("vga: sequencer address write data=0x%x\n", new_addr);
639
640     ERR_WRONG_SIZE("write","vga sequenver addr",len,1,1);
641
642     if (new_addr>VGA_SEQUENCER_NUM) {
643         PrintError("vga: ignoring change of sequencer address to %u (>%u)\n",
644                    new_addr, VGA_SEQUENCER_NUM);
645         //return -1;
646     } else {
647         vga->vga_sequencer.vga_sequencer_addr.val =  *((uint8_t*)src) ;
648     }
649
650     return len;
651 }
652
653 static int sequencer_data_read(struct guest_info *core, 
654                               uint16_t port, 
655                               void *dest,
656                               uint_t len,
657                               void *priv_data)
658 {
659     struct vga_internal *vga = (struct vga_internal *) priv_data;
660     uint8_t index;
661     uint8_t data;
662
663     index=vga->vga_sequencer.vga_sequencer_addr.val;  // should mask probably
664     data=vga->vga_sequencer.vga_sequencer_regs[index];
665     
666     PrintDebug("vga: sequencer data read data (index=%d) = 0x%x\n", 
667                index, data);
668
669     ERR_WRONG_SIZE("read","vga sequenver data",len,1,1);
670
671     *((uint8_t*)dest) = data;
672
673     return len;
674 }
675
676 static int sequencer_data_write(struct guest_info *core, 
677                                uint16_t port, 
678                                void *src,
679                                uint_t len,
680                                void *priv_data)
681 {
682     struct vga_internal *vga = (struct vga_internal *) priv_data;
683     uint8_t index;
684     uint8_t data;
685     
686     data=*((uint8_t*)src);
687     index=vga->vga_sequencer.vga_sequencer_addr.val;  // should mask probably
688     
689     PrintDebug("vga: sequencer write data (index=%d) with 0x%x\n", 
690                index, data);
691     
692     ERR_WRONG_SIZE("read","vga sequenver data",len,1,1);
693     
694     vga->vga_sequencer.vga_sequencer_regs[index] = data;
695
696     render(vga);
697     
698     return len;
699 }
700  
701  
702
703
704 static int crt_controller_address_read(struct guest_info *core, 
705                                         uint16_t port, 
706                                         void *dest,
707                                         uint_t len,
708                                         void *priv_data)
709 {
710     struct vga_internal *vga = (struct vga_internal *) priv_data;
711
712     PrintDebug("vga: crt controller (%s) address read data=0x%x\n", 
713                port==0x3b4 ? "mono" : "color",
714                vga->vga_crt_controller.vga_crt_addr.val);
715
716     ERR_WRONG_SIZE("read","vga crt controller addr",len,1,1);
717
718     *((uint8_t*)dest) = vga->vga_crt_controller.vga_crt_addr.val;
719
720     return len;
721 }
722
723 static int crt_controller_address_write(struct guest_info *core, 
724                                         uint16_t port, 
725                                         void *src,
726                                         uint_t len,
727                                         void *priv_data)
728 {
729     struct vga_internal *vga = (struct vga_internal *) priv_data;
730     uint8_t new_addr;
731
732     new_addr=*((uint8_t*)src);
733
734     PrintDebug("vga: crt controller (%s) address write data=0x%x\n", 
735                port==0x3b4 ? "mono" : "color",
736                new_addr);
737
738     ERR_WRONG_SIZE("write","vga crt controller addr",len,1,1);
739
740     if (new_addr>VGA_CRT_CONTROLLER_NUM) {
741         PrintError("vga: ignoring change of crt controller address to %u (>%u)\n",
742                    new_addr, VGA_CRT_CONTROLLER_NUM);
743         //return -1;
744     } else {
745         vga->vga_crt_controller.vga_crt_addr.val =  *((uint8_t*)src) ;
746     }
747
748     return len;
749 }
750
751 static int crt_controller_data_read(struct guest_info *core, 
752                                     uint16_t port, 
753                                     void *dest,
754                                     uint_t len,
755                                     void *priv_data)
756 {
757     struct vga_internal *vga = (struct vga_internal *) priv_data;
758     uint8_t index;
759     uint8_t data;
760
761     index=vga->vga_crt_controller.vga_crt_addr.val;  // should mask probably
762     data=vga->vga_crt_controller.vga_crt_controller_regs[index];
763     
764     PrintDebug("vga: crt controller data (%s) read data (index=%d) = 0x%x\n", 
765                port==0x3b5 ? "mono" : "color",
766                index, data);
767
768     ERR_WRONG_SIZE("read","vga crt controller data",len,1,1);
769
770     *((uint8_t*)dest) = data;
771
772     return len;
773 }
774
775 static int crt_controller_data_write(struct guest_info *core, 
776                                      uint16_t port, 
777                                      void *src,
778                                      uint_t len,
779                                      void *priv_data)
780 {
781     struct vga_internal *vga = (struct vga_internal *) priv_data;
782     uint8_t index;
783     uint8_t data;
784
785     data=*((uint8_t*)src);
786
787     index=vga->vga_crt_controller.vga_crt_addr.val;  // should mask probably
788     
789     PrintDebug("vga: crt controller (%s) write data (index=%d) with 0x%x\n", 
790                port==0x3b5 ? "mono" : "color",
791                index, data);
792
793     ERR_WRONG_SIZE("read","vga crt controlle data",len,1,1);
794
795     vga->vga_crt_controller.vga_crt_controller_regs[index] = data;
796
797     render(vga);
798
799     return len;
800 }
801
802
803 static int graphics_controller_address_read(struct guest_info *core, 
804                                             uint16_t port, 
805                                             void *dest,
806                                             uint_t len,
807                                             void *priv_data)
808 {
809     struct vga_internal *vga = (struct vga_internal *) priv_data;
810     
811     PrintDebug("vga: graphics controller address read data=0x%x\n", 
812                vga->vga_graphics_controller.vga_graphics_ctrl_addr.val);
813
814     ERR_WRONG_SIZE("read","vga graphics controller addr",len,1,1);
815
816     *((uint8_t*)dest) = vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;
817
818     return len;
819 }
820
821 static int graphics_controller_address_write(struct guest_info *core, 
822                                              uint16_t port, 
823                                              void *src,
824                                              uint_t len,
825                                              void *priv_data)
826 {
827     struct vga_internal *vga = (struct vga_internal *) priv_data;
828     uint8_t new_addr;
829
830     new_addr=*((uint8_t*)src);
831
832     PrintDebug("vga: graphics controller address write data=0x%x\n", new_addr);
833
834     ERR_WRONG_SIZE("write","vga graphics controller addr",len,1,1);
835
836     if (new_addr>VGA_GRAPHICS_CONTROLLER_NUM) {
837         PrintError("vga: ignoring change of graphics controller address to %u (>%u)\n",
838                    new_addr, VGA_GRAPHICS_CONTROLLER_NUM);
839         //return -1;
840     } else {
841         vga->vga_graphics_controller.vga_graphics_ctrl_addr.val =  *((uint8_t*)src) ;
842     }
843
844     return len;
845 }
846
847 static int graphics_controller_data_read(struct guest_info *core, 
848                                          uint16_t port, 
849                                          void *dest,
850                                          uint_t len,
851                                          void *priv_data)
852 {
853     struct vga_internal *vga = (struct vga_internal *) priv_data;
854     uint8_t index;
855     uint8_t data;
856
857     index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;  // should mask probably
858     data=vga->vga_graphics_controller.vga_graphics_controller_regs[index];
859     
860     PrintDebug("vga: graphics controller data read data (index=%d) = 0x%x\n", 
861                index, data);
862
863     ERR_WRONG_SIZE("read","vga graphics controller data",len,1,1);
864
865     *((uint8_t*)dest) = data;
866
867     return len;
868 }
869
870 static int graphics_controller_data_write(struct guest_info *core, 
871                                           uint16_t port, 
872                                           void *src,
873                                           uint_t len,
874                                           void *priv_data)
875 {
876     struct vga_internal *vga = (struct vga_internal *) priv_data;
877     uint8_t index;
878     uint8_t data;
879     
880     data=*((uint8_t*)src);
881     index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;  // should mask probably
882     
883     PrintDebug("vga: graphics_controller write data (index=%d) with 0x%x\n", 
884                index, data);
885     
886     ERR_WRONG_SIZE("read","vga sequenver data",len,1,1);
887     
888     vga->vga_graphics_controller.vga_graphics_controller_regs[index] = data;
889
890     render(vga);
891     
892     return len;
893 }
894
895
896
897 /* Note that these guys have a bizarre protocol*/
898
899 static int attribute_controller_address_read(struct guest_info *core, 
900                                              uint16_t port, 
901                                              void *dest,
902                                              uint_t len,
903                                              void *priv_data)
904 {
905     struct vga_internal *vga = (struct vga_internal *) priv_data;
906     
907     PrintDebug("vga: attribute controller address read data=0x%x\n", 
908                vga->vga_attribute_controller.vga_attribute_controller_addr.val);
909
910     ERR_WRONG_SIZE("read","vga attribute  controller addr",len,1,1);
911
912     *((uint8_t*)dest) = vga->vga_attribute_controller.vga_attribute_controller_addr.val;
913
914     // Reading the attribute controller does not change the state
915
916     return len;
917 }
918
919 static int attribute_controller_address_and_data_write(struct guest_info *core, 
920                                                        uint16_t port, 
921                                                        void *src,
922                                                        uint_t len,
923                                                        void *priv_data)
924 {
925     struct vga_internal *vga = (struct vga_internal *) priv_data;
926
927
928     if (vga->vga_attribute_controller.state==ATTR_ADDR) { 
929         uint8_t new_addr = *((uint8_t*)src);
930         // We are to treat this as an address write, and flip state
931         // to expect data ON THIS SAME PORT
932         PrintDebug("vga: graphics controller address write data=0x%x\n", new_addr);
933         
934         ERR_WRONG_SIZE("write","vga graphics controller addr",len,1,1);
935
936         if (new_addr>VGA_ATTRIBUTE_CONTROLLER_NUM) {
937             PrintError("vga: ignoring change of attribute controller address to %u (>%u)\n",
938                        new_addr, VGA_ATTRIBUTE_CONTROLLER_NUM);
939             //return -1;
940         } else {
941             vga->vga_attribute_controller.vga_attribute_controller_addr.val =  *((uint8_t*)src) ;
942         }
943         vga->vga_attribute_controller.state=ATTR_DATA;
944         return len;
945
946     } else if (vga->vga_attribute_controller.state==ATTR_DATA) { 
947
948         uint8_t data = *((uint8_t*)src);
949         uint8_t index=vga->vga_attribute_controller.vga_attribute_controller_addr.val;  // should mask probably
950
951         PrintDebug("vga: graphics controller data write index %d with data=0x%x\n", index,data);
952         
953         ERR_WRONG_SIZE("write","vga graphics controller data",len,1,1);
954
955         vga->vga_attribute_controller.vga_attribute_controller_regs[index] = data;
956         
957         vga->vga_attribute_controller.state=ATTR_ADDR;
958         
959         return len;
960     }
961     
962     return -1;
963         
964 }
965
966 static int attribute_controller_data_read(struct guest_info *core, 
967                                           uint16_t port, 
968                                           void *dest,
969                                           uint_t len,
970                                           void *priv_data)
971 {
972     struct vga_internal *vga = (struct vga_internal *) priv_data;
973     uint8_t index;
974     uint8_t data;
975
976     index=vga->vga_attribute_controller.vga_attribute_controller_addr.val;  // should mask probably
977     data=vga->vga_attribute_controller.vga_attribute_controller_regs[index];
978     
979     PrintDebug("vga: attribute controller data read data (index=%d) = 0x%x\n", 
980                index, data);
981
982     ERR_WRONG_SIZE("read","vga attribute controller data",len,1,1);
983
984     *((uint8_t*)dest) = data;
985
986     return len;
987 }
988
989
990 /*
991    Note that these guys also have a strange protocol
992    since they need to squeeze 18 bits of data through
993    an 8 bit port 
994 */
995 static int dac_write_address_read(struct guest_info *core, 
996                                   uint16_t port, 
997                                   void *dest,
998                                   uint_t len,
999                                   void *priv_data)
1000 {
1001     struct vga_internal *vga = (struct vga_internal *) priv_data;
1002     
1003     PrintDebug("vga: dac write address read data=0x%x\n", 
1004                vga->vga_dac.vga_dac_write_addr);
1005
1006     ERR_WRONG_SIZE("read","vga dac write addr",len,1,1);
1007
1008     *((uint8_t*)dest) = vga->vga_dac.vga_dac_write_addr;
1009
1010     // This read does not reset the state machine
1011
1012     return len;
1013 }
1014
1015 static int dac_write_address_write(struct guest_info *core, 
1016                                    uint16_t port, 
1017                                    void *src,
1018                                    uint_t len,
1019                                    void *priv_data)
1020 {
1021     struct vga_internal *vga = (struct vga_internal *) priv_data;
1022     uint8_t new_addr;
1023
1024     new_addr=*((uint8_t*)src);
1025
1026     PrintDebug("vga: dac write address write data=0x%x\n", new_addr);
1027
1028     ERR_WRONG_SIZE("write","vga dac write addr",len,1,1);
1029
1030     // cannot be out of bounds since there are 256 regs
1031
1032     vga->vga_dac.vga_dac_write_addr =  *((uint8_t*)src) ;
1033
1034     // Now we also need to reset the state machine
1035     
1036     vga->vga_dac.state=DAC_WRITE;
1037     vga->vga_dac.channel=RED;
1038
1039     return len;
1040 }
1041
1042
1043 static int dac_read_address_read(struct guest_info *core, 
1044                                  uint16_t port, 
1045                                  void *dest,
1046                                  uint_t len,
1047                                  void *priv_data)
1048 {
1049     struct vga_internal *vga = (struct vga_internal *) priv_data;
1050     
1051     PrintDebug("vga: dac read address read data=0x%x\n", 
1052                vga->vga_dac.vga_dac_read_addr);
1053
1054     ERR_WRONG_SIZE("read","vga dac read addr",len,1,1);
1055
1056     *((uint8_t*)dest) = vga->vga_dac.vga_dac_read_addr;
1057
1058     // This read does not reset the state machine
1059
1060     return len;
1061 }
1062
1063 static int dac_read_address_write(struct guest_info *core, 
1064                                   uint16_t port, 
1065                                   void *src,
1066                                   uint_t len,
1067                                   void *priv_data)
1068 {
1069     struct vga_internal *vga = (struct vga_internal *) priv_data;
1070     uint8_t new_addr;
1071
1072     new_addr=*((uint8_t*)src);
1073
1074     PrintDebug("vga: dac read address write data=0x%x\n", new_addr);
1075
1076     ERR_WRONG_SIZE("write","vga dac read addr",len,1,1);
1077
1078     // cannot be out of bounds since there are 256 regs
1079
1080     vga->vga_dac.vga_dac_read_addr =  *((uint8_t*)src) ;
1081
1082     // Now we also need to reset the state machine
1083     
1084     vga->vga_dac.state=DAC_READ;
1085     vga->vga_dac.channel=RED;
1086
1087     return len;
1088 }
1089
1090
1091 static int dac_data_read(struct guest_info *core, 
1092                          uint16_t port, 
1093                          void *dest,
1094                          uint_t len,
1095                          void *priv_data)
1096 {
1097     struct vga_internal *vga = (struct vga_internal *) priv_data;
1098     uint8_t curreg;
1099     uint8_t curchannel;
1100     uint8_t data;
1101     
1102     if (vga->vga_dac.state!=DAC_READ) { 
1103         PrintError("vga: dac data read while in other state\n");
1104         // results undefined, so we continue
1105     }
1106
1107     ERR_WRONG_SIZE("read","vga dac read data",len,1,1);
1108
1109     curreg = vga->vga_dac.vga_dac_read_addr;
1110     curchannel = vga->vga_dac.channel;
1111     data = (vga->vga_dac.vga_dac_palette[curreg] >> curchannel*8) & 0x3f;
1112
1113     PrintDebug("vga: dac reg %u [%s] = 0x%x\n",
1114                curreg, 
1115                curchannel == 0 ? "RED" : curchannel == 1 ? "GREEN" 
1116                           : curchannel==2 ? "BLUE" : "BAD CHANNEL", 
1117                data);
1118
1119     *((uint8_t*)dest) = data;
1120     
1121     curchannel = (curchannel+1)%3;
1122     vga->vga_dac.channel=curchannel;
1123     if (curchannel==0) { 
1124         curreg = (curreg + 1) % VGA_DAC_NUM_ENTRIES;
1125     } 
1126     vga->vga_dac.vga_dac_read_addr = curreg;
1127     vga->vga_dac.state=DAC_READ;
1128
1129     return len;
1130 }
1131
1132
1133
1134 static int dac_data_write(struct guest_info *core, 
1135                           uint16_t port, 
1136                           void *src,
1137                           uint_t len,
1138                           void *priv_data)
1139 {
1140     struct vga_internal *vga = (struct vga_internal *) priv_data;
1141     uint8_t curreg;
1142     uint8_t curchannel;
1143     uint8_t data;
1144     vga_palette_reg data32;
1145     vga_palette_reg mask32;
1146     
1147     if (vga->vga_dac.state!=DAC_WRITE) { 
1148         PrintError("vga: dac data write while in other state\n");
1149         // results undefined, so we continue
1150     }
1151
1152     ERR_WRONG_SIZE("read","vga dac write data",len,1,1);
1153
1154     curreg = vga->vga_dac.vga_dac_write_addr;
1155     curchannel = vga->vga_dac.channel;
1156     data = *((uint8_t *)src);
1157
1158     PrintDebug("vga: dac reg %u [%s] write with 0x%x\n",
1159                curreg, 
1160                curchannel == 0 ? "RED" : curchannel == 1 ? "GREEN" 
1161                           : curchannel==2 ? "BLUE" : "BAD CHANNEL", 
1162                data);
1163
1164     data32 = data & 0x3f ;
1165     data32 <<= curchannel*8;
1166     mask32 = ~(0xff << (curchannel * 8));
1167
1168     vga->vga_dac.vga_dac_palette[curreg] &= mask32;
1169     vga->vga_dac.vga_dac_palette[curreg] |= data32;
1170
1171     curchannel = (curchannel+1)%3;
1172     vga->vga_dac.channel=curchannel;
1173     if (curchannel==0) { 
1174         curreg = (curreg + 1) % VGA_DAC_NUM_ENTRIES;
1175     } 
1176     vga->vga_dac.vga_dac_write_addr = curreg;
1177     vga->vga_dac.state=DAC_WRITE;
1178
1179     render(vga);
1180
1181     return len;
1182 }
1183
1184  
1185
1186 static int dac_pixel_mask_read(struct guest_info *core, 
1187                                uint16_t port, 
1188                                void *dest,
1189                                uint_t len,
1190                                void *priv_data)
1191 {
1192     struct vga_internal *vga = (struct vga_internal *) priv_data;
1193     
1194     PrintDebug("vga: dac pixel mask read data=0x%x\n", 
1195                vga->vga_dac.vga_pixel_mask);
1196
1197     ERR_WRONG_SIZE("read","vga pixel mask",len,1,1);
1198
1199     *((uint8_t*)dest) = vga->vga_dac.vga_pixel_mask;
1200
1201     return len;
1202 }
1203
1204 static int dac_pixel_mask_write(struct guest_info *core, 
1205                                 uint16_t port, 
1206                                 void *src,
1207                                 uint_t len,
1208                                 void *priv_data)
1209 {
1210     struct vga_internal *vga = (struct vga_internal *) priv_data;
1211     uint8_t new_data;
1212
1213     new_data=*((uint8_t*)src);
1214
1215     PrintDebug("vga: dac pixel mask write data=0x%x\n", new_data);
1216
1217     ERR_WRONG_SIZE("write","pixel mask",len,1,1);
1218
1219     vga->vga_dac.vga_pixel_mask =  new_data;
1220
1221     return len;
1222 }
1223
1224 static int init_vga(struct vga_internal *vga)
1225 {
1226     // TODO: startup spec of register contents, if any
1227     PrintError("vga: init_vga is UNIMPLEMTED\n");
1228     return 0;
1229 }
1230
1231 static int free_vga(struct vga_internal *vga) 
1232 {
1233     int i;
1234     int ret;
1235     struct vm_device *dev = vga->dev;
1236
1237     // Framebuffer deletion is user's responsibility
1238
1239     //    if (vga->mem_store) {
1240     //  V3_FreePages(v3_hva_to_hpa(vga->mem_store),MEM_REGION_NUM_PAGES);
1241     //  vga->mem_store=0;
1242     //}
1243     
1244     for (i=0;i<MAP_NUM;i++) { 
1245         if (vga->map[i]) { 
1246             V3_FreePages(V3_PAddr(vga->map[i]),MAP_SIZE/4096);
1247             vga->map[i]=0;
1248         }
1249     }
1250
1251     v3_unhook_mem(vga->dev->vm, V3_MEM_CORE_ANY, MEM_REGION_START);
1252
1253     ret = 0;
1254
1255     ret |= v3_dev_unhook_io(dev, VGA_MISC_OUT_READ);
1256     // The following also covers VGA_INPUT_STAT0_READ
1257     ret |= v3_dev_unhook_io(dev, VGA_MISC_OUT_WRITE);
1258     // The following also covers VGA_FEATURE_CTRL_WRITE_MONO
1259     ret |= v3_dev_unhook_io(dev, VGA_INPUT_STAT1_READ_MONO);
1260     // The folowinn also covers VGA FEATURE_CONTROL_WRITE_COLOR
1261     ret |= v3_dev_unhook_io(dev, VGA_INPUT_STAT1_READ_COLOR);
1262     ret |= v3_dev_unhook_io(dev, VGA_FEATURE_CONTROL_READ);
1263     
1264     ret |= v3_dev_unhook_io(dev, VGA_VIDEO_SUBSYS_ENABLE);
1265
1266     /* Sequencer registers */
1267     ret |= v3_dev_unhook_io(dev, VGA_SEQUENCER_ADDRESS);
1268     ret |= v3_dev_unhook_io(dev, VGA_SEQUENCER_DATA);
1269
1270     /* CRT controller registers */
1271     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_MONO);
1272     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_COLOR);
1273     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_DATA_MONO);
1274     ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_DATA_COLOR);
1275
1276     /* graphics controller registers */
1277     ret |= v3_dev_unhook_io(dev, VGA_GRAPHICS_CONTROLLER_ADDRESS);
1278     ret |= v3_dev_unhook_io(dev, VGA_GRAPHICS_CONTROLLER_DATA);
1279
1280     /* attribute controller registers */
1281     ret |= v3_dev_unhook_io(dev, VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE);
1282     ret |= v3_dev_unhook_io(dev, VGA_ATTRIBUTE_CONTROLLER_READ);
1283
1284     /* video DAC palette registers */
1285     ret |= v3_dev_unhook_io(dev, VGA_DAC_WRITE_ADDR);
1286     ret |= v3_dev_unhook_io(dev, VGA_DAC_READ_ADDR);
1287     ret |= v3_dev_unhook_io(dev, VGA_DAC_DATA);
1288     ret |= v3_dev_unhook_io(dev, VGA_DAC_PIXEL_MASK);
1289
1290
1291     V3_Free(vga);
1292
1293     return 0;
1294 }
1295
1296 static struct v3_device_ops dev_ops = {
1297     .free = (int (*)(void *))free_vga,
1298 };
1299
1300
1301 static int vga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1302     struct vga_internal *vga;
1303     int i;
1304     int ret;
1305
1306     char * dev_id = v3_cfg_val(cfg, "ID");
1307
1308     // DETERMINE THE FRAMEBUFFER AND SET IT EARLY
1309     // FRAMEBUFFER IS SUPPLIED BY THE BACKEND
1310
1311     PrintDebug("vga: init_device\n");
1312
1313     vga = (struct vga_internal *)V3_Malloc(sizeof(struct vga_internal));
1314
1315     if (!vga) { 
1316         PrintError("vga: cannot allocate\n");
1317         return -1;
1318     }
1319
1320     memset(vga, 0, sizeof(struct vga_internal));
1321
1322     // No memory store is allocated since we will use a full memory hook
1323     // The VGA maps can be read as well as written
1324
1325     // Now allocate the maps
1326     for (i=0;i<MAP_NUM;i++) { 
1327         vga->map[i] = (vga_map) V3_VAddr((void*)V3_AllocPages(MAP_SIZE/4096));
1328         if (!(vga->map[i])) {
1329             free_vga(vga);
1330         }
1331         memset(vga->map[i],0,MAP_SIZE);
1332     }
1333     
1334     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, vga);
1335     
1336     if (dev == NULL) {
1337         PrintError("Could not attach device %s\n", dev_id);
1338         free_vga(vga);
1339         return -1;
1340     }
1341     
1342     vga->dev = dev;
1343     
1344     if (v3_hook_full_mem(vm, V3_MEM_CORE_ANY, 
1345                          MEM_REGION_START, MEM_REGION_END,
1346                          &vga_read, 
1347                          &vga_write,
1348                          dev) == -1) {
1349         PrintError("vga: memory book failed\n");
1350         v3_remove_device(dev);
1351         return -1;
1352     }
1353
1354     ret = 0;
1355     
1356     /* Miscelaneous registers */
1357     ret |= v3_dev_hook_io(dev, VGA_MISC_OUT_READ, &misc_out_read, NULL);
1358     // The following also covers VGA_INPUT_STAT0_READ
1359     ret |= v3_dev_hook_io(dev, VGA_MISC_OUT_WRITE, &input_stat0_read, &misc_out_write);
1360     // The following also covers VGA_FEATURE_CTRL_WRITE_MONO
1361     ret |= v3_dev_hook_io(dev, VGA_INPUT_STAT1_READ_MONO, &input_stat1_read, &feature_control_write);
1362     // The folowinn also covers VGA FEATURE_CONTROL_WRITE_COLOR
1363     ret |= v3_dev_hook_io(dev, VGA_INPUT_STAT1_READ_COLOR, &input_stat1_read, &feature_control_write);
1364     ret |= v3_dev_hook_io(dev, VGA_FEATURE_CONTROL_READ, &feature_control_read, NULL);
1365     
1366     ret |= v3_dev_hook_io(dev, VGA_VIDEO_SUBSYS_ENABLE, &video_subsys_enable_read, &video_subsys_enable_write);
1367
1368     /* Sequencer registers */
1369     ret |= v3_dev_hook_io(dev, VGA_SEQUENCER_ADDRESS, &sequencer_address_read, &sequencer_address_write);
1370     ret |= v3_dev_hook_io(dev, VGA_SEQUENCER_DATA, &sequencer_data_read, &sequencer_data_write);
1371
1372     /* CRT controller registers */
1373     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_MONO, &crt_controller_address_read,&crt_controller_address_write);
1374     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_COLOR, &crt_controller_address_read,&crt_controller_address_write);
1375     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_DATA_MONO, &crt_controller_data_read,&crt_controller_data_write);
1376     ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_DATA_COLOR, &crt_controller_data_read,&crt_controller_data_write);
1377
1378     /* graphics controller registers */
1379     ret |= v3_dev_hook_io(dev, VGA_GRAPHICS_CONTROLLER_ADDRESS, &graphics_controller_address_read,&graphics_controller_address_write);
1380     ret |= v3_dev_hook_io(dev, VGA_GRAPHICS_CONTROLLER_DATA, &graphics_controller_data_read,&graphics_controller_data_write);
1381
1382     /* attribute controller registers */
1383     ret |= v3_dev_hook_io(dev, VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE, &attribute_controller_address_read,&attribute_controller_address_and_data_write);
1384     ret |= v3_dev_hook_io(dev, VGA_ATTRIBUTE_CONTROLLER_READ, &attribute_controller_data_read,NULL);
1385
1386     /* video DAC palette registers */
1387     ret |= v3_dev_hook_io(dev, VGA_DAC_WRITE_ADDR, &dac_write_address_read,&dac_write_address_write);
1388     ret |= v3_dev_hook_io(dev, VGA_DAC_READ_ADDR, &dac_read_address_read,&dac_read_address_write);
1389     ret |= v3_dev_hook_io(dev, VGA_DAC_DATA, &dac_data_read, &dac_data_write);
1390     ret |= v3_dev_hook_io(dev, VGA_DAC_PIXEL_MASK, &dac_pixel_mask_read, &dac_pixel_mask_write);
1391
1392     if (ret != 0) {
1393         PrintError("vga: Error allocating VGA I/O ports\n");
1394         v3_remove_device(dev);
1395         return -1;
1396     }
1397
1398     init_vga(vga);
1399
1400     PrintDebug("vga: successfully added and initialized, waiting for framebuffer attach\n");
1401
1402     return 0;
1403
1404 }
1405
1406 device_register("VGA", vga_init);