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.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2011, Peter Dinda <pdinda@northwestern.edu>
11 * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Peter Dinda <pdinda@northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
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>
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)
32 #define MAP_SIZE 65536
35 #define UPDATES_PER_RENDER 100
37 typedef uint8_t *vga_map; // points to MAP_SIZE data
44 uint32_t bitsperpixel;
53 struct fb *palacios_linux_fb_hack_pointer;
58 #define VGA_MISC_OUT_READ 0x3cc
59 #define VGA_MISC_OUT_WRITE 0x3c2
61 #define VGA_INPUT_STAT0_READ 0x3c2
63 #define VGA_INPUT_STAT1_READ_MONO 0x3ba
64 #define VGA_INPUT_STAT1_READ_COLOR 0x3da
66 #define VGA_FEATURE_CONTROL_READ 0x3ca
67 #define VGA_FEATURE_CONTROL_WRITE_MONO 0x3ba
68 #define VGA_FEATURE_CONTROL_WRITE_COLOR 0x3da
70 #define VGA_VIDEO_SUBSYS_ENABLE 0x3c3
72 #define VGA_SEQUENCER_ADDRESS 0x3c4
73 #define VGA_SEQUENCER_DATA 0x3c5
74 #define VGA_SEQUENCER_NUM 5
77 #define VGA_CRT_CONTROLLER_ADDRESS_MONO 0x3b4
78 #define VGA_CRT_CONTROLLER_ADDRESS_COLOR 0x3d4
79 #define VGA_CRT_CONTROLLER_DATA_MONO 0x3b5
80 #define VGA_CRT_CONTROLLER_DATA_COLOR 0x3d5
81 #define VGA_CRT_CONTROLLER_NUM 25
84 #define VGA_GRAPHICS_CONTROLLER_ADDRESS 0x3ce
85 #define VGA_GRAPHICS_CONTROLLER_DATA 0x3cf
86 #define VGA_GRAPHICS_CONTROLLER_NUM 9
88 #define VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE 0x3c0
89 #define VGA_ATTRIBUTE_CONTROLLER_READ 0x3c1
90 #define VGA_ATTRIBUTE_CONTROLLER_NUM 21
92 #define VGA_DAC_WRITE_ADDR 0x3c8
93 #define VGA_DAC_READ_ADDR 0x3c7
94 #define VGA_DAC_DATA 0x3c9
95 #define VGA_DAC_PIXEL_MASK 0x3c6
97 #define VGA_DAC_NUM_ENTRIES 256
99 struct vga_misc_regs {
100 /* Read: 0x3cc; Write: 0x3c2 */
101 struct vga_misc_out_reg vga_misc_out;
103 struct vga_input_stat0_reg vga_input_stat0;
104 /* Read: 0x3?a 3ba for mono; 3da for cga set by misc.io_addr_sel */
105 struct vga_input_stat1_reg vga_input_stat1;
106 /* Read: 0x3ca; Write: 0x3?a 3ba for mono 3da for color - set by misc.io_addr_sel*/
107 struct vga_feature_control_reg vga_feature_control;
108 /* Read: 0x3c3; Write: 0x3c3 */
109 struct vga_video_subsys_enable_reg vga_video_subsys_enable;
110 } __attribute__((packed));
112 struct vga_sequencer_regs {
113 /* Address register is 0x3c4, data register is 0x3c5 */
115 struct vga_sequencer_addr_reg vga_sequencer_addr;
117 /* these can be accessed via the index, offset on start
118 or via the specific regs. For this reason, it is essential
119 that this is all packed and that the order does not change */
121 uint8_t vga_sequencer_regs[0];
124 struct vga_reset_reg vga_reset;
126 struct vga_clocking_mode_reg vga_clocking_mode;
128 struct vga_map_mask_reg vga_map_mask;
130 struct vga_char_map_select_reg vga_char_map_select;
132 struct vga_mem_mode_reg vga_mem_mode;
133 } __attribute__((packed));
135 struct vga_crt_controller_regs {
136 /* Address Register is 0x3b4 or 0x3d4 */
137 /* Data register is 0x3b5 or 0x3d5 based on mono versus color */
138 struct vga_crt_addr_reg vga_crt_addr;
140 /* these can be accessed via the index, offset on start
141 or via the specific regs. For this reason, it is essential
142 that this is all packed and that the order does not change */
144 uint8_t vga_crt_controller_regs[0];
147 vga_horizontal_total_reg vga_horizontal_total;
149 vga_horizontal_display_enable_end_reg vga_horizontal_display_enable_end;
151 vga_start_horizontal_blanking_reg vga_start_horizontal_blanking;
153 struct vga_end_horizontal_blanking_reg vga_end_horizontal_blanking;
155 vga_start_horizontal_retrace_pulse_reg vga_start_horizontal_retrace_pulse;
157 struct vga_end_horizontal_retrace_reg vga_end_horizontal_retrace;
159 vga_vertical_total_reg vga_vertical_total;
161 struct vga_overflow_reg vga_overflow;
163 struct vga_preset_row_scan_reg vga_preset_row_scan;
165 struct vga_max_row_scan_reg vga_row_scan;
167 struct vga_cursor_start_reg vga_cursor_start;
169 struct vga_cursor_end_reg vga_cursor_end;
171 vga_start_address_high_reg vga_start_address_high;
173 vga_start_address_low_reg vga_start_address_low;
175 vga_cursor_location_high_reg vga_cursor_location_high;
177 vga_cursor_location_low_reg vga_cursor_location_low;
179 vga_vertical_retrace_start_reg vga_vertical_retrace_start;
181 struct vga_vertical_retrace_end_reg vga_vertical_retrace_end;
183 vga_vertical_display_enable_end_reg vga_vertical_display_enable;
185 vga_offset_reg vga_offset;
187 struct vga_underline_location_reg vga_underline_location;
189 vga_start_vertical_blanking_reg vga_start_vertical_blanking;
191 vga_end_vertical_blanking_reg vga_end_vertical_blanking;
193 struct vga_crt_mode_control_reg vga_crt_mode_control;
195 vga_line_compare_reg vga_line_compare;
196 } __attribute__((packed));
198 struct vga_graphics_controller_regs {
199 /* Address: 0x3ce Data: 0x3cf */
202 struct vga_graphics_ctrl_addr_reg vga_graphics_ctrl_addr;
204 /* these can be accessed via the index, offset on start
205 or via the specific regs. For this reason, it is essential
206 that this is all packed and that the order does not change */
208 uint8_t vga_graphics_controller_regs[0];
211 struct vga_set_reset_reg vga_set_reset;
213 struct vga_enable_set_reset_reg vga_enable_set_reset;
215 struct vga_color_compare_reg vga_color_compare;
217 struct vga_data_rotate_reg vga_data_rotate;
219 struct vga_read_map_select_reg vga_read_map_select;
221 struct vga_graphics_mode_reg vga_graphics_mode;
223 struct vga_misc_reg vga_misc;
225 struct vga_color_dont_care_reg vga_color_dont_care;
227 vga_bit_mask_reg vga_bit_mask;
228 } __attribute__((packed));
231 struct vga_attribute_contoller_regs {
233 Address AND WRITE: 0x3c0
236 The write protocol is to write the index to 0x3c0 followed by
237 the data. The read protocol is to write the index to 0x3c0
238 and then read from 0x3c1
240 IMPORTANT: write address, write data flips state back to write address
241 write address, read data DOES NOT
243 To reset to write address state, read input status register 1
245 enum { ATTR_ADDR, ATTR_DATA } state; //state of the flip flop
248 struct vga_attribute_controller_address_reg vga_attribute_controller_addr;
252 /* these can be accessed via the index, offset on start
253 or via the specific regs. For this reason, it is essential
254 that this is all packed and that the order does not change */
256 uint8_t vga_attribute_controller_regs[0];
259 vga_internal_palette_regs vga_internal_palette;
261 struct vga_attribute_mode_control_reg vga_attribute_mode_control;
263 vga_overscan_color_reg vga_overscan_color;
265 struct vga_color_plane_enable_reg vga_color_plane_enable;
267 struct vga_horizontal_pixel_pan_reg vga_horizontal_pixel_pan;
269 struct vga_color_select_reg vga_color_select;
270 } __attribute__((packed));
272 struct vga_dac_regs {
273 enum {DAC_READ=0, DAC_WRITE} state;
274 enum {RED=0,GREEN,BLUE} channel;
275 vga_dac_pixel_mask_reg vga_pixel_mask;
276 vga_dac_write_addr_reg vga_dac_write_addr;
277 vga_dac_read_addr_reg vga_dac_read_addr;
278 // the dac_data register is used only to access the registers
279 // and thus has no representation here
280 vga_palette_reg vga_dac_palette[VGA_DAC_NUM_ENTRIES];
281 } __attribute__((packed));
284 struct vga_internal {
285 struct vm_device *dev;
288 bool skip_next_passthrough_out; // for word access
290 uint32_t updates_since_render;
292 struct frame_buf *framebuf; // we render to this
294 // void *mem_store; // This is the region where the memory hooks will go
296 vga_map map[MAP_NUM]; // the maps that the host writes to
298 uint8_t latch[MAP_NUM]; // written to in any read, used during writes
300 /* Range of I/O ports here for backward compat with MDA and CGA */
301 struct vga_misc_regs vga_misc;
303 /* Address Register is 0x3b4 or 0x3d4 */
304 /* Data register is 0x3b5 or 0x3d5 based on MDA/CGA/VGA (backward compat) */
305 struct vga_crt_controller_regs vga_crt_controller;
307 /* Address register is 0x3c4, data register is 0x3c5 */
308 struct vga_sequencer_regs vga_sequencer;
310 /* Address: 0x3ce Data: 0x3cf */
311 struct vga_graphics_controller_regs vga_graphics_controller;
314 Address AND WRITE: 0x3c0
318 struct vga_attribute_contoller_regs vga_attribute_controller;
321 address for reads: 0x3c7 (also resets state machine for access to 18 bit regs
322 address for writes: 0x3c8 ("")
324 pixel mask: 0x3c6 - do not write (init to 0xff)
326 struct vga_dac_regs vga_dac;
331 static int render(struct vga_internal *vga)
333 vga->updates_since_render++;
335 if (vga->updates_since_render<UPDATES_PER_RENDER) {
339 // PrintError("vga: render UNIMPLEMENTED\n");
341 vga->updates_since_render=0;
343 if (!palacios_linux_fb_hack_pointer) {
354 static void get_mem_region(struct vga_internal *vga, uint64_t *mem_start, uint64_t *mem_end)
356 switch (vga->vga_graphics_controller.vga_misc.memory_map) {
376 static uint64_t find_offset(struct vga_internal *vga, addr_t guest_addr)
378 uint64_t mem_start, mem_end;
382 get_mem_region(vga, &mem_start, &mem_end);
384 return (guest_addr-mem_start) % (mem_end-mem_start > 65536 ? 65536 : (mem_end-mem_start));
391 static int vga_write(struct guest_info * core,
398 struct vm_device *dev = (struct vm_device *)priv_data;
399 struct vga_internal *vga = (struct vga_internal *) dev->private_data;
401 PrintDebug("vga: memory write: guest_addr=0x%p len=%u\n",(void*)guest_addr, length);
403 if (vga->passthrough) {
404 PrintDebug("vga: passthrough write to 0x%p\n", V3_VAddr((void*)guest_addr));
405 memcpy(V3_VAddr((void*)guest_addr),src,length);
408 PrintDebug("vga: data written was \"");
409 for (i=0;i<length;i++) {
410 char c= ((char*)src)[i];
411 PrintDebug("%c", (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') ? c : '.');
415 /* Write mode determine by Graphics Mode Register (Index 05h).writemode */
417 switch (vga->vga_graphics_controller.vga_graphics_mode.write_mode) {
421 00b -- Write Mode 0: In this mode, the host data is first rotated
422 as per the Rotate Count field, then the Enable Set/Reset mechanism
423 selects data from this or the Set/Reset field. Then the selected
424 Logical Operation is performed on the resulting data and the data
425 in the latch register. Then the Bit Mask field is used to select
426 which bits come from the resulting data and which come
427 from the latch register. Finally, only the bit planes enabled by
428 the Memory Plane Write Enable field are written to memory.
436 uint8_t ror = vga->vga_graphics_controller.vga_data_rotate.rotate_count;
437 uint8_t func = vga->vga_graphics_controller.vga_data_rotate.function;
439 offset = find_offset(vga, guest_addr);
441 PrintDebug("vga: mode 0 write, offset=0x%llx, ror=%u, func=%u\n", offset,ror,func);
443 for (i=0;i<length;i++,offset++) {
445 uint8_t sr = vga->vga_graphics_controller.vga_set_reset.val & 0xf;
446 uint8_t esr = vga->vga_graphics_controller.vga_enable_set_reset.val &0xf;
447 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask;
448 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
450 for (mapnum=0;mapnum<4;mapnum++, sr>>=1, esr>>=1, bm>>=1, mm>>=1) {
451 vga_map map = vga->map[mapnum];
452 uint8_t data = ((uint8_t *)src)[i];
453 uint8_t latchval = vga->latch[mapnum];
456 data = (data>>ror) | data<<(8-ror);
458 // use SR bit if ESR is on for this map
460 data = (uint8_t)((((sint8_t)(sr&0x1))<<7)>>7); // expand sr bit
478 // mux between latch and alu output
480 // use alu output, which is in data
489 //PrintDebug("vga: write map %u offset 0x%p map=0x%p pointer=0x%p\n",mapnum,(void*)offset,map,&(map[offset]));
503 01b -- Write Mode 1: In this mode, data is transferred directly
504 from the 32 bit latch register to display memory, affected only by
505 the Memory Plane Write Enable field. The host data is not used in this mode.
510 uint64_t offset = find_offset(vga,guest_addr);
512 PrintDebug("vga: mode 1 write, offset=0x%llx\n", offset);
514 for (i=0;i<length;i++,offset++) {
517 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
519 for (mapnum=0;mapnum<4;mapnum++, mm>>=1) {
520 vga_map map = vga->map[mapnum];
521 uint8_t latchval = vga->latch[mapnum];
526 map[offset] = latchval;
537 10b -- Write Mode 2: In this mode, the bits 3-0 of the host data
538 are replicated across all 8 bits of their respective planes.
539 Then the selected Logical Operation is performed on the resulting
540 data and the data in the latch register. Then the Bit Mask field is used to
541 select which bits come from the resulting data and which come from
542 the latch register. Finally, only the bit planes enabled by the
543 Memory Plane Write Enable field are written to memory.
549 uint8_t func = vga->vga_graphics_controller.vga_data_rotate.function;
551 offset = find_offset(vga, guest_addr);
553 PrintDebug("vga: mode 2 write, offset=0x%llx, func=%u\n", offset,func);
555 for (i=0;i<length;i++,offset++) {
557 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask;
558 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
560 for (mapnum=0;mapnum<4;mapnum++, bm>>=1, mm>>=1) {
561 vga_map map = vga->map[mapnum];
562 uint8_t data = ((uint8_t *)src)[i];
563 uint8_t latchval = vga->latch[mapnum];
565 // expand relevant bit to 8 bit
566 // it's basically esr=1, sr=bit from write
567 data = (uint8_t)(((sint8_t)(((data>>mapnum)&0x1)<<7))>>7);
584 // mux between latch and alu output
586 // use alu output, which is in data
605 /* 11b -- Write Mode 3: In this mode, the data in the Set/Reset field is used
606 as if the Enable Set/Reset field were set to 1111b. Then the host data is
607 first rotated as per the Rotate Count field, then logical ANDed with the
608 value of the Bit Mask field. The resulting value is used on the data
609 obtained from the Set/Reset field in the same way that the Bit Mask field
610 would ordinarily be used. to select which bits come from the expansion
611 of the Set/Reset field and which come from the latch register. Finally,
612 only the bit planes enabled by the Memory Plane Write Enable field
613 are written to memory.
620 uint8_t ror = vga->vga_graphics_controller.vga_data_rotate.rotate_count;
622 offset = find_offset(vga, guest_addr);
624 PrintDebug("vga: mode 3 write, offset=0x%llx, ror=%u\n", offset,ror);
626 for (i=0;i<length;i++,offset++) {
628 uint8_t data = ((uint8_t *)src)[i];
630 data = (data>>ror) | data<<(8-ror);
632 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask & data;
633 uint8_t sr = vga->vga_graphics_controller.vga_set_reset.val & 0xf;
634 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
636 for (mapnum=0;mapnum<4;mapnum++, sr>>=1, bm>>=1, mm>>=1) {
637 vga_map map = vga->map[mapnum];
638 uint8_t latchval = vga->latch[mapnum];
640 data = (uint8_t)((((sint8_t)(sr&0x1))<<7)>>7); // expand sr bit
643 // mux between latch and alu output
645 // use alu output, which is in data
664 // There is no default
674 up to 256K mapped through a window of 32 to 128K
676 most cards support linear mode as well
678 Need to implement readability too
680 Write extended memory bit to enable all 256K:
682 Sequencer Memory Mode Register (Index 04h) . extended memory
684 Must enable writes before effects happen:
686 Miscellaneous Output Register (Read at 3CCh, Write at 3C2h).ram enable
688 Choose which addresses are supported for CPU writes:
690 Miscellaneous Graphics Register (Index 06h).memory map select
692 00b -- A0000h-BFFFFh (128K region)
693 01b -- A0000h-AFFFFh (64K region)
694 10b -- B0000h-B7FFFh (32K region)
695 11b -- B8000h-BFFFFh (32K region)
697 There are three addressing modes: Chain 4, Odd/Even mode, and normal mode:
699 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.)
701 Memory model: 64K 32 bit locations; divided into 4 64K bit planes
707 Assume linear framebuffer, starting at address buf:
713 static int vga_read(struct guest_info * core,
720 struct vm_device *dev = (struct vm_device *)priv_data;
721 struct vga_internal *vga = (struct vga_internal *) dev->private_data;
724 PrintDebug("vga: memory read: guest_addr=0x%p len=%u\n",(void*)guest_addr, length);
730 Reading, 2 modes, set via Graphics Mode Register (index 05h).Read Mode:
732 switch (vga->vga_graphics_controller.vga_graphics_mode.read_mode) {
734 /* 0 - a byte from ONE of the 4 planes is returned;
735 which plane is determined by Read Map Select (Read Map Select Register (Index 04h)) */
739 mapnum = vga->vga_graphics_controller.vga_read_map_select.map_select;
740 offset = find_offset(vga,guest_addr);
743 PrintError("vga: read to offset=%llu map=%u (%u bytes)\n",offset,mapnum,length);
746 memcpy(dst,(vga->map[mapnum])+offset,length);
748 // load the latches with the last item read
749 for (mapnum=0;mapnum<4;mapnum++) {
750 vga->latch[mapnum] = vga->map[mapnum][offset+length-1];
757 /* 1 - Compare video memory and reference color
758 (in Color Compare, except those not set in Color Don't Care),
759 each bit in returned result is one comparison between the reference color
761 Ref color is *4* bits, and thus a one byte read returns a comparison
767 uint8_t cc=vga->vga_graphics_controller.vga_color_compare.val & 0xf ;
768 uint8_t dc=vga->vga_graphics_controller.vga_color_dont_care.val & 0xf;
775 offset = find_offset(vga,guest_addr);
777 for (i=0;i<length;i++,offset++) {
780 for (mapnum=0;mapnum<4;mapnum++) {
781 map = vga->map[mapnum];
782 if ( (dc>>mapnum)&0x1 ) { // don't care
786 bits = (map[offset]&0xf) == cc;
789 bits |= (((map[offset]>>4))&0xf) == cc;
791 // not clear whether it is 0..k or k..0
797 // load the latches with the last item read
798 for (mapnum=0;mapnum<4;mapnum++) {
799 vga->latch[mapnum] = vga->map[mapnum][offset+length-1];
804 // there is no default
807 if (vga->passthrough) {
808 PrintDebug("vga: passthrough read from 0x%p\n",V3_VAddr((void*)guest_addr));
809 memcpy(dst,V3_VAddr((void*)guest_addr),length);
813 PrintDebug("vga: data read is \"");
814 for (i=0;i<length;i++) {
815 char c= ((char*)dst)[i];
816 PrintDebug("%c", (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') ? c : '.');
828 #define ERR_WRONG_SIZE(op,reg,len,min,max) \
829 if (((len)<(min)) || ((len)>(max))) { \
830 PrintError("vga: %s of %s wrong size (%d bytes, but only %d to %d allowed)\n",(op),(reg),(len),(min),(max)); \
834 static inline void passthrough_io_in(uint16_t port, void * dest, uint_t length) {
837 *(uint8_t *)dest = v3_inb(port);
840 *(uint16_t *)dest = v3_inw(port);
843 *(uint32_t *)dest = v3_indw(port);
846 PrintError("vga: unsupported passthrough io in size %u\n",length);
852 static inline void passthrough_io_out(uint16_t port, const void * src, uint_t length) {
855 v3_outb(port, *(uint8_t *)src);
858 v3_outw(port, *(uint16_t *)src);
861 v3_outdw(port, *(uint32_t *)src);
864 PrintError("vga: unsupported passthrough io out size %u\n",length);
869 #define PASSTHROUGH_IO_IN(vga,port,dest,len) \
870 do { if ((vga)->passthrough) { passthrough_io_in(port,dest,len); } } while (0)
872 #define PASSTHROUGH_IO_OUT(vga,port,src,len) \
873 do { if ((vga)->passthrough && (!(vga)->skip_next_passthrough_out)) { passthrough_io_out(port,src,len); } (vga)->skip_next_passthrough_out=false; } while (0)
875 #define PASSTHROUGH_IO_SKIP_NEXT_OUT(vga) \
876 do { if ((vga)->passthrough) { (vga)->skip_next_passthrough_out=true; } } while (0)
878 #define PASSTHROUGH_READ_CHECK(vga,inter,pass) \
879 do { if ((vga)->passthrough) { if ((inter)!=(pass)) { PrintError("vga: passthrough error: passthrough value read is 0x%x, but internal value read is 0x%x\n",(pass),(inter)); } } } while (0)
881 static int misc_out_read(struct guest_info *core,
887 struct vga_internal *vga = (struct vga_internal *) priv_data;
889 PrintDebug("vga: misc out read data=0x%x\n", vga->vga_misc.vga_misc_out.val);
891 ERR_WRONG_SIZE("read","misc out",len,1,1);
893 *((uint8_t*)dest) = vga->vga_misc.vga_misc_out.val;
895 PASSTHROUGH_IO_IN(vga,port,dest,len);
897 PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_misc_out.val,*((uint8_t*)dest));
902 static int misc_out_write(struct guest_info *core,
908 struct vga_internal *vga = (struct vga_internal *) priv_data;
910 PrintDebug("vga: misc out write data=0x%x\n", *((uint8_t*)src));
912 ERR_WRONG_SIZE("write","misc out",len,1,1);
914 PASSTHROUGH_IO_OUT(vga,port,src,len);
916 vga->vga_misc.vga_misc_out.val = *((uint8_t*)src) ;
925 static int input_stat0_read(struct guest_info *core,
931 struct vga_internal *vga = (struct vga_internal *) priv_data;
933 PrintDebug("vga: input stat0 read data=0x%x\n", vga->vga_misc.vga_input_stat0.val);
935 ERR_WRONG_SIZE("read","input stat0",len,1,1);
937 *((uint8_t*)dest) = vga->vga_misc.vga_input_stat0.val;
939 PASSTHROUGH_IO_IN(vga,port,dest,len);
941 PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_input_stat0.val,*(uint8_t*)dest);
947 static int input_stat1_read(struct guest_info *core,
953 struct vga_internal *vga = (struct vga_internal *) priv_data;
955 PrintDebug("vga: input stat0 (%s) read data=0x%x\n",
956 port==0x3ba ? "mono" : "color",
957 vga->vga_misc.vga_input_stat1.val);
959 ERR_WRONG_SIZE("read","input stat1",len,1,1);
962 *((uint8_t*)dest) = vga->vga_misc.vga_input_stat1.val;
964 // Stunningly, reading stat1 is also a way to reset
965 // the state of attribute controller address/data flipflop
966 // That is some mighty fine crack the designers were smoking.
968 vga->vga_attribute_controller.state=ATTR_ADDR;
970 PASSTHROUGH_IO_IN(vga,port,dest,len);
972 PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_input_stat1.val,*(uint8_t*)dest);
978 static int feature_control_read(struct guest_info *core,
984 struct vga_internal *vga = (struct vga_internal *) priv_data;
986 PrintDebug("vga: feature control read data=0x%x\n",
987 vga->vga_misc.vga_feature_control.val);
989 ERR_WRONG_SIZE("read","feature control",len,1,1);
992 *((uint8_t*)dest) = vga->vga_misc.vga_feature_control.val;
994 PASSTHROUGH_IO_IN(vga,port,dest,len);
996 PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_feature_control.val,*(uint8_t*)dest);
1001 static int feature_control_write(struct guest_info *core,
1007 struct vga_internal *vga = (struct vga_internal *) priv_data;
1009 PrintDebug("vga: feature control (%s) write data=0x%x\n",
1010 port==0x3ba ? "mono" : "color",
1013 ERR_WRONG_SIZE("write","feature control",len,1,1);
1015 PASSTHROUGH_IO_OUT(vga,port,src,len);
1017 vga->vga_misc.vga_feature_control.val = *((uint8_t*)src) ;
1025 static int video_subsys_enable_read(struct guest_info *core,
1031 struct vga_internal *vga = (struct vga_internal *) priv_data;
1033 PrintDebug("vga: video subsys enable read data=0x%x\n",
1034 vga->vga_misc.vga_video_subsys_enable.val);
1036 ERR_WRONG_SIZE("read","video subsys enable",len,1,1);
1038 *((uint8_t*)dest) = vga->vga_misc.vga_video_subsys_enable.val;
1040 PASSTHROUGH_IO_IN(vga,port,dest,len);
1042 PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_video_subsys_enable.val,*(uint8_t*)dest);
1047 static int video_subsys_enable_write(struct guest_info *core,
1053 struct vga_internal *vga = (struct vga_internal *) priv_data;
1055 PrintDebug("vga: video subsys enable write data=0x%x\n", *((uint8_t*)src));
1057 ERR_WRONG_SIZE("write","video subsys enable",len,1,1);
1059 PASSTHROUGH_IO_OUT(vga,port,src,len);
1061 vga->vga_misc.vga_video_subsys_enable.val = *((uint8_t*)src) ;
1068 static int sequencer_address_read(struct guest_info *core,
1074 struct vga_internal *vga = (struct vga_internal *) priv_data;
1076 PrintDebug("vga: sequencer address read data=0x%x\n",
1077 vga->vga_sequencer.vga_sequencer_addr.val);
1079 ERR_WRONG_SIZE("read","vga sequencer addr",len,1,1);
1081 *((uint8_t*)dest) = vga->vga_sequencer.vga_sequencer_addr.val;
1083 PASSTHROUGH_IO_IN(vga,port,dest,len);
1085 PASSTHROUGH_READ_CHECK(vga,vga->vga_sequencer.vga_sequencer_addr.val,*(uint8_t*)dest);
1090 static int sequencer_data_write(struct guest_info *core,
1096 struct vga_internal *vga = (struct vga_internal *) priv_data;
1100 data=*((uint8_t*)src);
1101 index=vga->vga_sequencer.vga_sequencer_addr.val; // should mask probably
1103 PrintDebug("vga: sequencer write data (index=%d) with 0x%x\n",
1106 ERR_WRONG_SIZE("write","vga sequencer data",len,1,1);
1108 PASSTHROUGH_IO_OUT(vga,port,src,len);
1111 if (index>=VGA_SEQUENCER_NUM) {
1112 PrintError("vga: sequencer data write is for invalid index %d, ignoring\n",index);
1114 vga->vga_sequencer.vga_sequencer_regs[index] = data;
1122 static int sequencer_address_write(struct guest_info *core,
1128 struct vga_internal *vga = (struct vga_internal *) priv_data;
1131 new_addr=*((uint8_t*)src);
1133 PrintDebug("vga: sequencer address write data=0x%x len=%u\n", len==1 ? *((uint8_t*)src) : len==2 ? *((uint16_t*)src) : *((uint32_t*)src), len);
1135 ERR_WRONG_SIZE("write","vga sequencer addr",len,1,2);
1137 PASSTHROUGH_IO_OUT(vga,port,src,len);
1139 vga->vga_sequencer.vga_sequencer_addr.val = *((uint8_t*)src) ;
1142 PASSTHROUGH_IO_SKIP_NEXT_OUT(vga);
1143 // second byte is the data
1144 if (sequencer_data_write(core,port,src+1,1,vga)!=1) {
1145 PrintError("vga: write of data failed\n");
1153 static int sequencer_data_read(struct guest_info *core,
1159 struct vga_internal *vga = (struct vga_internal *) priv_data;
1163 index=vga->vga_sequencer.vga_sequencer_addr.val; // should mask probably
1165 if (index>=VGA_SEQUENCER_NUM) {
1167 PrintError("vga: sequencer data read at invalid index %d, returning zero\n",index);
1169 data=vga->vga_sequencer.vga_sequencer_regs[index];
1172 PrintDebug("vga: sequencer data read data (index=%d) = 0x%x\n",
1175 ERR_WRONG_SIZE("read","vga sequencer data",len,1,1);
1177 *((uint8_t*)dest) = data;
1179 PASSTHROUGH_IO_IN(vga,port,dest,len);
1181 PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1190 static int crt_controller_address_read(struct guest_info *core,
1196 struct vga_internal *vga = (struct vga_internal *) priv_data;
1198 PrintDebug("vga: crt controller (%s) address read data=0x%x\n",
1199 port==0x3b4 ? "mono" : "color",
1200 vga->vga_crt_controller.vga_crt_addr.val);
1202 ERR_WRONG_SIZE("read","vga crt controller addr",len,1,1);
1204 *((uint8_t*)dest) = vga->vga_crt_controller.vga_crt_addr.val;
1206 PASSTHROUGH_IO_IN(vga,port,dest,len);
1208 PASSTHROUGH_READ_CHECK(vga,vga->vga_crt_controller.vga_crt_addr.val,*(uint8_t*)dest);
1213 static int crt_controller_data_write(struct guest_info *core,
1219 struct vga_internal *vga = (struct vga_internal *) priv_data;
1223 data=*((uint8_t*)src);
1225 index=vga->vga_crt_controller.vga_crt_addr.val; // should mask probably
1227 PrintDebug("vga: crt controller (%s) write data (index=%d) with 0x%x\n",
1228 port==0x3b5 ? "mono" : "color",
1231 ERR_WRONG_SIZE("write","vga crt controller data",len,1,1);
1233 PASSTHROUGH_IO_OUT(vga,port,src,len);
1235 if (index>=VGA_CRT_CONTROLLER_NUM) {
1236 PrintError("vga; crt controller write is for illegal index %d, ignoring\n",index);
1238 vga->vga_crt_controller.vga_crt_controller_regs[index] = data;
1246 static int crt_controller_address_write(struct guest_info *core,
1252 struct vga_internal *vga = (struct vga_internal *) priv_data;
1255 new_addr=*((uint8_t*)src);
1257 PrintDebug("vga: crt controller (%s) address write data=0x%x len=%u\n",
1258 port==0x3b4 ? "mono" : "color",
1259 len==1 ? *((uint8_t*)src) : len==2 ? *((uint16_t*)src) : *((uint32_t*)src), len);
1261 ERR_WRONG_SIZE("write","vga crt controller addr",len,1,2);
1263 PASSTHROUGH_IO_OUT(vga,port,src,len);
1265 vga->vga_crt_controller.vga_crt_addr.val = *((uint8_t*)src) ;
1268 PASSTHROUGH_IO_SKIP_NEXT_OUT(vga);
1269 // second byte is the data
1270 if (crt_controller_data_write(core,port,src+1,1,vga)!=1) {
1271 PrintError("vga: write of data failed\n");
1279 static int crt_controller_data_read(struct guest_info *core,
1285 struct vga_internal *vga = (struct vga_internal *) priv_data;
1289 index=vga->vga_crt_controller.vga_crt_addr.val; // should mask probably
1291 if (index>=VGA_CRT_CONTROLLER_NUM) {
1293 PrintError("vga: crt controller data read for illegal index %d, returning zero\n",index);
1295 data=vga->vga_crt_controller.vga_crt_controller_regs[index];
1298 PrintDebug("vga: crt controller data (index=%d) = 0x%x\n",index,data);
1300 ERR_WRONG_SIZE("read","vga crt controller data",len,1,1);
1302 *((uint8_t*)dest) = data;
1304 PASSTHROUGH_IO_IN(vga,port,dest,len);
1306 PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t *)dest);
1313 static int graphics_controller_address_read(struct guest_info *core,
1319 struct vga_internal *vga = (struct vga_internal *) priv_data;
1321 PrintDebug("vga: graphics controller address read data=0x%x\n",
1322 vga->vga_graphics_controller.vga_graphics_ctrl_addr.val);
1324 ERR_WRONG_SIZE("read","vga graphics controller addr",len,1,1);
1326 *((uint8_t*)dest) = vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;
1328 PASSTHROUGH_IO_IN(vga,port,dest,len);
1330 PASSTHROUGH_READ_CHECK(vga,vga->vga_graphics_controller.vga_graphics_ctrl_addr.val,*(uint8_t*)dest);
1335 static int graphics_controller_data_write(struct guest_info *core,
1341 struct vga_internal *vga = (struct vga_internal *) priv_data;
1345 data=*((uint8_t*)src);
1346 index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val; // should mask probably
1349 PrintDebug("vga: graphics_controller write data (index=%d) with 0x%x\n",
1352 ERR_WRONG_SIZE("write","vga graphics controller data",len,1,1);
1354 PASSTHROUGH_IO_OUT(vga,port,src,len);
1356 if (index>=VGA_GRAPHICS_CONTROLLER_NUM) {
1357 PrintError("vga: graphics controller write for illegal index %d ignored\n",index);
1359 vga->vga_graphics_controller.vga_graphics_controller_regs[index] = data;
1367 static int graphics_controller_address_write(struct guest_info *core,
1373 struct vga_internal *vga = (struct vga_internal *) priv_data;
1376 new_addr=*((uint8_t*)src);
1378 PrintDebug("vga: graphics controller address write data=0x%x len=%u\n",
1379 len==1 ? *((uint8_t*)src) : len==2 ? *((uint16_t*)src) : *((uint32_t*)src), len);
1381 ERR_WRONG_SIZE("write","vga graphics controller addr",len,1,2);
1383 PASSTHROUGH_IO_OUT(vga,port,src,len);
1385 vga->vga_graphics_controller.vga_graphics_ctrl_addr.val = *((uint8_t*)src) ;
1388 PASSTHROUGH_IO_SKIP_NEXT_OUT(vga);
1389 // second byte is the data
1390 if (graphics_controller_data_write(core,port,src+1,1,vga)!=1) {
1391 PrintError("vga: write of data failed\n");
1399 static int graphics_controller_data_read(struct guest_info *core,
1405 struct vga_internal *vga = (struct vga_internal *) priv_data;
1409 index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val; // should mask probably
1412 if (index>=VGA_GRAPHICS_CONTROLLER_NUM) {
1414 PrintError("vga: graphics controller data read from illegal index %d, returning zero\n",index);
1416 data=vga->vga_graphics_controller.vga_graphics_controller_regs[index];
1419 PrintDebug("vga: graphics controller data read data (index=%d) = 0x%x\n",
1422 ERR_WRONG_SIZE("read","vga graphics controller data",len,1,1);
1424 *((uint8_t*)dest) = data;
1426 PASSTHROUGH_IO_IN(vga,port,dest,len);
1428 PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1436 /* Note that these guys have a bizarre protocol*/
1438 static int attribute_controller_address_read(struct guest_info *core,
1444 struct vga_internal *vga = (struct vga_internal *) priv_data;
1446 PrintDebug("vga: attribute controller address read data=0x%x\n",
1447 vga->vga_attribute_controller.vga_attribute_controller_addr.val);
1449 ERR_WRONG_SIZE("read","vga attribute controller addr",len,1,1);
1451 *((uint8_t*)dest) = vga->vga_attribute_controller.vga_attribute_controller_addr.val;
1453 PASSTHROUGH_IO_IN(vga,port,dest,len);
1455 PASSTHROUGH_READ_CHECK(vga,vga->vga_attribute_controller.vga_attribute_controller_addr.val,*(uint8_t*)dest);
1457 // Reading the attribute controller does not change the state
1462 static int attribute_controller_address_and_data_write(struct guest_info *core,
1468 struct vga_internal *vga = (struct vga_internal *) priv_data;
1471 if (vga->vga_attribute_controller.state==ATTR_ADDR) {
1472 uint8_t new_addr = *((uint8_t*)src);
1473 // We are to treat this as an address write, and flip state
1474 // to expect data ON THIS SAME PORT
1475 PrintDebug("vga: attribute controller address write data=0x%x\n", new_addr);
1477 ERR_WRONG_SIZE("write","vga attribute controller addr",len,1,1);
1479 PASSTHROUGH_IO_OUT(vga,port,src,len);
1481 vga->vga_attribute_controller.vga_attribute_controller_addr.val = new_addr;
1483 vga->vga_attribute_controller.state=ATTR_DATA;
1486 } else if (vga->vga_attribute_controller.state==ATTR_DATA) {
1488 uint8_t data = *((uint8_t*)src);
1489 uint8_t index=vga->vga_attribute_controller.vga_attribute_controller_addr.val; // should mask probably
1491 PrintDebug("vga: attribute controller data write index %d with data=0x%x\n", index,data);
1493 ERR_WRONG_SIZE("write","vga attribute controller data",len,1,1);
1495 PASSTHROUGH_IO_OUT(vga,port,src,len);
1497 if (index>=VGA_ATTRIBUTE_CONTROLLER_NUM) {
1498 PrintError("vga: attribute controller write to illegal index %d ignored\n",index);
1500 vga->vga_attribute_controller.vga_attribute_controller_regs[index] = data;
1503 vga->vga_attribute_controller.state=ATTR_ADDR;
1512 static int attribute_controller_data_read(struct guest_info *core,
1518 struct vga_internal *vga = (struct vga_internal *) priv_data;
1522 index=vga->vga_attribute_controller.vga_attribute_controller_addr.val; // should mask probably
1524 if (index>=VGA_ATTRIBUTE_CONTROLLER_NUM) {
1526 PrintError("vga: attribute controller read of illegal index %d, returning zero\n",index);
1528 data=vga->vga_attribute_controller.vga_attribute_controller_regs[index];
1531 PrintDebug("vga: attribute controller data read data (index=%d) = 0x%x\n",
1534 ERR_WRONG_SIZE("read","vga attribute controller data",len,1,1);
1536 *((uint8_t*)dest) = data;
1538 PASSTHROUGH_IO_IN(vga,port,dest,len);
1540 PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1547 Note that these guys also have a strange protocol
1548 since they need to squeeze 18 bits of data through
1551 static int dac_write_address_read(struct guest_info *core,
1557 struct vga_internal *vga = (struct vga_internal *) priv_data;
1559 PrintDebug("vga: dac write address read data=0x%x\n",
1560 vga->vga_dac.vga_dac_write_addr);
1562 ERR_WRONG_SIZE("read","vga dac write addr",len,1,1);
1565 *((uint8_t*)dest) = vga->vga_dac.vga_dac_write_addr;
1567 PASSTHROUGH_IO_IN(vga,port,dest,len);
1569 PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_dac_write_addr,*(uint8_t*)dest);
1571 // This read does not reset the state machine
1576 static int dac_write_address_write(struct guest_info *core,
1582 struct vga_internal *vga = (struct vga_internal *) priv_data;
1585 new_addr=*((uint8_t*)src);
1587 PrintDebug("vga: dac write address write data=0x%x\n", new_addr);
1589 ERR_WRONG_SIZE("write","vga dac write addr",len,1,1);
1591 PASSTHROUGH_IO_OUT(vga,port,src,len);
1593 // cannot be out of bounds since there are 256 regs
1595 vga->vga_dac.vga_dac_write_addr = *((uint8_t*)src) ;
1597 // Now we also need to reset the state machine
1599 vga->vga_dac.state=DAC_WRITE;
1600 vga->vga_dac.channel=RED;
1606 static int dac_read_address_read(struct guest_info *core,
1612 struct vga_internal *vga = (struct vga_internal *) priv_data;
1614 PrintDebug("vga: dac read address read data=0x%x\n",
1615 vga->vga_dac.vga_dac_read_addr);
1617 ERR_WRONG_SIZE("read","vga dac read addr",len,1,1);
1619 *((uint8_t*)dest) = vga->vga_dac.vga_dac_read_addr;
1621 PASSTHROUGH_IO_IN(vga,port,dest,len);
1623 PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_dac_read_addr,*(uint8_t*)dest);
1625 // This read does not reset the state machine
1630 static int dac_read_address_write(struct guest_info *core,
1636 struct vga_internal *vga = (struct vga_internal *) priv_data;
1639 new_addr=*((uint8_t*)src);
1641 PrintDebug("vga: dac read address write data=0x%x\n", new_addr);
1643 ERR_WRONG_SIZE("write","vga dac read addr",len,1,1);
1645 PASSTHROUGH_IO_OUT(vga,port,src,len);
1647 // cannot be out of bounds since there are 256 regs
1649 vga->vga_dac.vga_dac_read_addr = *((uint8_t*)src) ;
1651 // Now we also need to reset the state machine
1653 vga->vga_dac.state=DAC_READ;
1654 vga->vga_dac.channel=RED;
1660 static int dac_data_read(struct guest_info *core,
1666 struct vga_internal *vga = (struct vga_internal *) priv_data;
1671 if (vga->vga_dac.state!=DAC_READ) {
1672 PrintError("vga: dac data read while in other state\n");
1673 // results undefined, so we continue
1676 ERR_WRONG_SIZE("read","vga dac read data",len,1,1);
1678 curreg = vga->vga_dac.vga_dac_read_addr;
1679 curchannel = vga->vga_dac.channel;
1680 data = (vga->vga_dac.vga_dac_palette[curreg] >> curchannel*8) & 0x3f;
1682 PrintDebug("vga: dac reg %u [%s] = 0x%x\n",
1684 curchannel == 0 ? "RED" : curchannel == 1 ? "GREEN"
1685 : curchannel==2 ? "BLUE" : "BAD CHANNEL",
1688 *((uint8_t*)dest) = data;
1690 PASSTHROUGH_IO_IN(vga,port,dest,len);
1692 PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1694 curchannel = (curchannel+1)%3;
1695 vga->vga_dac.channel=curchannel;
1696 if (curchannel==0) {
1697 curreg = (curreg + 1) % VGA_DAC_NUM_ENTRIES;
1699 vga->vga_dac.vga_dac_read_addr = curreg;
1700 vga->vga_dac.state=DAC_READ;
1707 static int dac_data_write(struct guest_info *core,
1713 struct vga_internal *vga = (struct vga_internal *) priv_data;
1717 vga_palette_reg data32;
1718 vga_palette_reg mask32;
1720 if (vga->vga_dac.state!=DAC_WRITE) {
1721 PrintError("vga: dac data write while in other state\n");
1722 // results undefined, so we continue
1725 ERR_WRONG_SIZE("read","vga dac write data",len,1,1);
1727 PASSTHROUGH_IO_OUT(vga,port,src,len);
1729 curreg = vga->vga_dac.vga_dac_write_addr;
1730 curchannel = vga->vga_dac.channel;
1731 data = *((uint8_t *)src);
1733 PrintDebug("vga: dac reg %u [%s] write with 0x%x\n",
1735 curchannel == 0 ? "RED" : curchannel == 1 ? "GREEN"
1736 : curchannel==2 ? "BLUE" : "BAD CHANNEL",
1739 data32 = data & 0x3f ;
1740 data32 <<= curchannel*8;
1741 mask32 = ~(0xff << (curchannel * 8));
1743 vga->vga_dac.vga_dac_palette[curreg] &= mask32;
1744 vga->vga_dac.vga_dac_palette[curreg] |= data32;
1746 curchannel = (curchannel+1)%3;
1747 vga->vga_dac.channel=curchannel;
1748 if (curchannel==0) {
1749 curreg = (curreg + 1) % VGA_DAC_NUM_ENTRIES;
1751 vga->vga_dac.vga_dac_write_addr = curreg;
1752 vga->vga_dac.state=DAC_WRITE;
1761 static int dac_pixel_mask_read(struct guest_info *core,
1767 struct vga_internal *vga = (struct vga_internal *) priv_data;
1769 PrintDebug("vga: dac pixel mask read data=0x%x\n",
1770 vga->vga_dac.vga_pixel_mask);
1772 ERR_WRONG_SIZE("read","vga pixel mask",len,1,1);
1774 *((uint8_t*)dest) = vga->vga_dac.vga_pixel_mask;
1776 PASSTHROUGH_IO_IN(vga,port,dest,len);
1778 PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_pixel_mask,*(uint8_t*)dest);
1783 static int dac_pixel_mask_write(struct guest_info *core,
1789 struct vga_internal *vga = (struct vga_internal *) priv_data;
1792 new_data=*((uint8_t*)src);
1794 PrintDebug("vga: dac pixel mask write data=0x%x\n", new_data);
1796 ERR_WRONG_SIZE("write","pixel mask",len,1,1);
1798 PASSTHROUGH_IO_OUT(vga,port,src,len);
1800 vga->vga_dac.vga_pixel_mask = new_data;
1805 static int init_vga(struct vga_internal *vga)
1807 // TODO: startup spec of register contents, if any
1808 PrintError("vga: init_vga is UNIMPLEMTED\n");
1812 static int free_vga(struct vga_internal *vga)
1816 struct vm_device *dev = vga->dev;
1818 // Framebuffer deletion is user's responsibility
1820 // if (vga->mem_store) {
1821 // V3_FreePages(v3_hva_to_hpa(vga->mem_store),MEM_REGION_NUM_PAGES);
1822 // vga->mem_store=0;
1825 for (i=0;i<MAP_NUM;i++) {
1827 V3_FreePages(V3_PAddr(vga->map[i]),MAP_SIZE/4096);
1832 v3_unhook_mem(vga->dev->vm, V3_MEM_CORE_ANY, MEM_REGION_START);
1836 ret |= v3_dev_unhook_io(dev, VGA_MISC_OUT_READ);
1837 // The following also covers VGA_INPUT_STAT0_READ
1838 ret |= v3_dev_unhook_io(dev, VGA_MISC_OUT_WRITE);
1839 // The following also covers VGA_FEATURE_CTRL_WRITE_MONO
1840 ret |= v3_dev_unhook_io(dev, VGA_INPUT_STAT1_READ_MONO);
1841 // The folowinn also covers VGA FEATURE_CONTROL_WRITE_COLOR
1842 ret |= v3_dev_unhook_io(dev, VGA_INPUT_STAT1_READ_COLOR);
1843 ret |= v3_dev_unhook_io(dev, VGA_FEATURE_CONTROL_READ);
1845 ret |= v3_dev_unhook_io(dev, VGA_VIDEO_SUBSYS_ENABLE);
1847 /* Sequencer registers */
1848 ret |= v3_dev_unhook_io(dev, VGA_SEQUENCER_ADDRESS);
1849 ret |= v3_dev_unhook_io(dev, VGA_SEQUENCER_DATA);
1851 /* CRT controller registers */
1852 ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_MONO);
1853 ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_COLOR);
1854 ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_DATA_MONO);
1855 ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_DATA_COLOR);
1857 /* graphics controller registers */
1858 ret |= v3_dev_unhook_io(dev, VGA_GRAPHICS_CONTROLLER_ADDRESS);
1859 ret |= v3_dev_unhook_io(dev, VGA_GRAPHICS_CONTROLLER_DATA);
1861 /* attribute controller registers */
1862 ret |= v3_dev_unhook_io(dev, VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE);
1863 ret |= v3_dev_unhook_io(dev, VGA_ATTRIBUTE_CONTROLLER_READ);
1865 /* video DAC palette registers */
1866 ret |= v3_dev_unhook_io(dev, VGA_DAC_WRITE_ADDR);
1867 ret |= v3_dev_unhook_io(dev, VGA_DAC_READ_ADDR);
1868 ret |= v3_dev_unhook_io(dev, VGA_DAC_DATA);
1869 ret |= v3_dev_unhook_io(dev, VGA_DAC_PIXEL_MASK);
1877 static struct v3_device_ops dev_ops = {
1878 .free = (int (*)(void *))free_vga,
1882 static int vga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1883 struct vga_internal *vga;
1887 char * dev_id = v3_cfg_val(cfg, "ID");
1888 char * passthrough = v3_cfg_val(cfg, "passthrough");
1890 // DETERMINE THE FRAMEBUFFER AND SET IT EARLY
1891 // FRAMEBUFFER IS SUPPLIED BY THE BACKEND
1893 PrintDebug("vga: init_device\n");
1895 vga = (struct vga_internal *)V3_Malloc(sizeof(struct vga_internal));
1898 PrintError("vga: cannot allocate\n");
1902 memset(vga, 0, sizeof(struct vga_internal));
1904 if (passthrough && strcasecmp(passthrough,"enable")==0) {
1905 PrintDebug("vga: enabling passthrough\n");
1906 vga->passthrough=true;
1907 vga->skip_next_passthrough_out=false;
1910 // No memory store is allocated since we will use a full memory hook
1911 // The VGA maps can be read as well as written
1912 // Reads also affect writes, since they are how you fill the latches
1914 // Now allocate the maps
1915 for (i=0;i<MAP_NUM;i++) {
1916 vga->map[i] = (vga_map) V3_VAddr((void*)V3_AllocPages(MAP_SIZE/4096));
1917 if (!(vga->map[i])) {
1918 PrintError("vga: cannot allocate maps\n");
1922 memset(vga->map[i],0,MAP_SIZE);
1925 struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, vga);
1928 PrintError("Could not attach device %s\n", dev_id);
1935 if (v3_hook_full_mem(vm, V3_MEM_CORE_ANY,
1936 MEM_REGION_START, MEM_REGION_END,
1940 PrintError("vga: memory book failed\n");
1941 v3_remove_device(dev);
1947 /* Miscelaneous registers */
1948 ret |= v3_dev_hook_io(dev, VGA_MISC_OUT_READ, &misc_out_read, NULL);
1949 // The following also covers VGA_INPUT_STAT0_READ
1950 ret |= v3_dev_hook_io(dev, VGA_MISC_OUT_WRITE, &input_stat0_read, &misc_out_write);
1951 // The following also covers VGA_FEATURE_CTRL_WRITE_MONO
1952 ret |= v3_dev_hook_io(dev, VGA_INPUT_STAT1_READ_MONO, &input_stat1_read, &feature_control_write);
1953 // The folowinn also covers VGA FEATURE_CONTROL_WRITE_COLOR
1954 ret |= v3_dev_hook_io(dev, VGA_INPUT_STAT1_READ_COLOR, &input_stat1_read, &feature_control_write);
1955 ret |= v3_dev_hook_io(dev, VGA_FEATURE_CONTROL_READ, &feature_control_read, NULL);
1957 ret |= v3_dev_hook_io(dev, VGA_VIDEO_SUBSYS_ENABLE, &video_subsys_enable_read, &video_subsys_enable_write);
1959 /* Sequencer registers */
1960 ret |= v3_dev_hook_io(dev, VGA_SEQUENCER_ADDRESS, &sequencer_address_read, &sequencer_address_write);
1961 ret |= v3_dev_hook_io(dev, VGA_SEQUENCER_DATA, &sequencer_data_read, &sequencer_data_write);
1963 /* CRT controller registers */
1964 ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_MONO, &crt_controller_address_read,&crt_controller_address_write);
1965 ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_COLOR, &crt_controller_address_read,&crt_controller_address_write);
1966 ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_DATA_MONO, &crt_controller_data_read,&crt_controller_data_write);
1967 ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_DATA_COLOR, &crt_controller_data_read,&crt_controller_data_write);
1969 /* graphics controller registers */
1970 ret |= v3_dev_hook_io(dev, VGA_GRAPHICS_CONTROLLER_ADDRESS, &graphics_controller_address_read,&graphics_controller_address_write);
1971 ret |= v3_dev_hook_io(dev, VGA_GRAPHICS_CONTROLLER_DATA, &graphics_controller_data_read,&graphics_controller_data_write);
1973 /* attribute controller registers */
1974 ret |= v3_dev_hook_io(dev, VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE, &attribute_controller_address_read,&attribute_controller_address_and_data_write);
1975 ret |= v3_dev_hook_io(dev, VGA_ATTRIBUTE_CONTROLLER_READ, &attribute_controller_data_read,NULL);
1977 /* video DAC palette registers */
1978 ret |= v3_dev_hook_io(dev, VGA_DAC_WRITE_ADDR, &dac_write_address_read,&dac_write_address_write);
1979 ret |= v3_dev_hook_io(dev, VGA_DAC_READ_ADDR, &dac_read_address_read,&dac_read_address_write);
1980 ret |= v3_dev_hook_io(dev, VGA_DAC_DATA, &dac_data_read, &dac_data_write);
1981 ret |= v3_dev_hook_io(dev, VGA_DAC_PIXEL_MASK, &dac_pixel_mask_read, &dac_pixel_mask_write);
1984 PrintError("vga: Error allocating VGA I/O ports\n");
1985 v3_remove_device(dev);
1991 PrintDebug("vga: successfully added and initialized, waiting for framebuffer attach\n");
1997 device_register("VGA", vga_init);