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>
25 #include <palacios/vmm_graphics_console.h>
29 #define MEM_REGION_START 0xa0000
30 #define MEM_REGION_END 0xc0000
31 #define MEM_REGION_NUM_PAGES (((MEM_REGION_END)-(MEM_REGION_START))/4096)
33 #define MAP_SIZE 65536
36 #define UPDATES_PER_RENDER 100
38 typedef uint8_t *vga_map; // points to MAP_SIZE data
44 #define VGA_MISC_OUT_READ 0x3cc
45 #define VGA_MISC_OUT_WRITE 0x3c2
47 #define VGA_INPUT_STAT0_READ 0x3c2
49 #define VGA_INPUT_STAT1_READ_MONO 0x3ba
50 #define VGA_INPUT_STAT1_READ_COLOR 0x3da
52 #define VGA_FEATURE_CONTROL_READ 0x3ca
53 #define VGA_FEATURE_CONTROL_WRITE_MONO 0x3ba
54 #define VGA_FEATURE_CONTROL_WRITE_COLOR 0x3da
56 #define VGA_VIDEO_SUBSYS_ENABLE 0x3c3
58 #define VGA_SEQUENCER_ADDRESS 0x3c4
59 #define VGA_SEQUENCER_DATA 0x3c5
60 #define VGA_SEQUENCER_NUM 5
63 #define VGA_CRT_CONTROLLER_ADDRESS_MONO 0x3b4
64 #define VGA_CRT_CONTROLLER_ADDRESS_COLOR 0x3d4
65 #define VGA_CRT_CONTROLLER_DATA_MONO 0x3b5
66 #define VGA_CRT_CONTROLLER_DATA_COLOR 0x3d5
67 #define VGA_CRT_CONTROLLER_NUM 25
70 #define VGA_GRAPHICS_CONTROLLER_ADDRESS 0x3ce
71 #define VGA_GRAPHICS_CONTROLLER_DATA 0x3cf
72 #define VGA_GRAPHICS_CONTROLLER_NUM 9
74 #define VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE 0x3c0
75 #define VGA_ATTRIBUTE_CONTROLLER_READ 0x3c1
76 #define VGA_ATTRIBUTE_CONTROLLER_NUM 21
78 #define VGA_DAC_WRITE_ADDR 0x3c8
79 #define VGA_DAC_READ_ADDR 0x3c7
80 #define VGA_DAC_DATA 0x3c9
81 #define VGA_DAC_PIXEL_MASK 0x3c6
83 #define VGA_DAC_NUM_ENTRIES 256
85 struct vga_misc_regs {
86 /* Read: 0x3cc; Write: 0x3c2 */
87 struct vga_misc_out_reg vga_misc_out;
89 struct vga_input_stat0_reg vga_input_stat0;
90 /* Read: 0x3?a 3ba for mono; 3da for cga set by misc.io_addr_sel */
91 struct vga_input_stat1_reg vga_input_stat1;
92 /* Read: 0x3ca; Write: 0x3?a 3ba for mono 3da for color - set by misc.io_addr_sel*/
93 struct vga_feature_control_reg vga_feature_control;
94 /* Read: 0x3c3; Write: 0x3c3 */
95 struct vga_video_subsys_enable_reg vga_video_subsys_enable;
96 } __attribute__((packed));
98 struct vga_sequencer_regs {
99 /* Address register is 0x3c4, data register is 0x3c5 */
101 struct vga_sequencer_addr_reg vga_sequencer_addr;
103 /* these can be accessed via the index, offset on start
104 or via the specific regs. For this reason, it is essential
105 that this is all packed and that the order does not change */
107 uint8_t vga_sequencer_regs[0];
110 struct vga_reset_reg vga_reset;
112 struct vga_clocking_mode_reg vga_clocking_mode;
114 struct vga_map_mask_reg vga_map_mask;
116 struct vga_char_map_select_reg vga_char_map_select;
118 struct vga_mem_mode_reg vga_mem_mode;
119 } __attribute__((packed));
121 struct vga_crt_controller_regs {
122 /* Address Register is 0x3b4 or 0x3d4 */
123 /* Data register is 0x3b5 or 0x3d5 based on mono versus color */
124 struct vga_crt_addr_reg vga_crt_addr;
126 /* these can be accessed via the index, offset on start
127 or via the specific regs. For this reason, it is essential
128 that this is all packed and that the order does not change */
130 uint8_t vga_crt_controller_regs[0];
133 vga_horizontal_total_reg vga_horizontal_total;
135 vga_horizontal_display_enable_end_reg vga_horizontal_display_enable_end;
137 vga_start_horizontal_blanking_reg vga_start_horizontal_blanking;
139 struct vga_end_horizontal_blanking_reg vga_end_horizontal_blanking;
141 vga_start_horizontal_retrace_pulse_reg vga_start_horizontal_retrace_pulse;
143 struct vga_end_horizontal_retrace_reg vga_end_horizontal_retrace;
145 vga_vertical_total_reg vga_vertical_total;
147 struct vga_overflow_reg vga_overflow;
149 struct vga_preset_row_scan_reg vga_preset_row_scan;
151 struct vga_max_row_scan_reg vga_row_scan;
153 struct vga_cursor_start_reg vga_cursor_start;
155 struct vga_cursor_end_reg vga_cursor_end;
157 vga_start_address_high_reg vga_start_address_high;
159 vga_start_address_low_reg vga_start_address_low;
161 vga_cursor_location_high_reg vga_cursor_location_high;
163 vga_cursor_location_low_reg vga_cursor_location_low;
165 vga_vertical_retrace_start_reg vga_vertical_retrace_start;
167 struct vga_vertical_retrace_end_reg vga_vertical_retrace_end;
169 vga_vertical_display_enable_end_reg vga_vertical_display_enable;
171 vga_offset_reg vga_offset;
173 struct vga_underline_location_reg vga_underline_location;
175 vga_start_vertical_blanking_reg vga_start_vertical_blanking;
177 vga_end_vertical_blanking_reg vga_end_vertical_blanking;
179 struct vga_crt_mode_control_reg vga_crt_mode_control;
181 vga_line_compare_reg vga_line_compare;
182 } __attribute__((packed));
184 struct vga_graphics_controller_regs {
185 /* Address: 0x3ce Data: 0x3cf */
188 struct vga_graphics_ctrl_addr_reg vga_graphics_ctrl_addr;
190 /* these can be accessed via the index, offset on start
191 or via the specific regs. For this reason, it is essential
192 that this is all packed and that the order does not change */
194 uint8_t vga_graphics_controller_regs[0];
197 struct vga_set_reset_reg vga_set_reset;
199 struct vga_enable_set_reset_reg vga_enable_set_reset;
201 struct vga_color_compare_reg vga_color_compare;
203 struct vga_data_rotate_reg vga_data_rotate;
205 struct vga_read_map_select_reg vga_read_map_select;
207 struct vga_graphics_mode_reg vga_graphics_mode;
209 struct vga_misc_reg vga_misc;
211 struct vga_color_dont_care_reg vga_color_dont_care;
213 vga_bit_mask_reg vga_bit_mask;
214 } __attribute__((packed));
217 struct vga_attribute_contoller_regs {
219 Address AND WRITE: 0x3c0
222 The write protocol is to write the index to 0x3c0 followed by
223 the data. The read protocol is to write the index to 0x3c0
224 and then read from 0x3c1
226 IMPORTANT: write address, write data flips state back to write address
227 write address, read data DOES NOT
229 To reset to write address state, read input status register 1
231 enum { ATTR_ADDR, ATTR_DATA } state; //state of the flip flop
234 struct vga_attribute_controller_address_reg vga_attribute_controller_addr;
238 /* these can be accessed via the index, offset on start
239 or via the specific regs. For this reason, it is essential
240 that this is all packed and that the order does not change */
242 uint8_t vga_attribute_controller_regs[0];
245 vga_internal_palette_regs vga_internal_palette;
247 struct vga_attribute_mode_control_reg vga_attribute_mode_control;
249 vga_overscan_color_reg vga_overscan_color;
251 struct vga_color_plane_enable_reg vga_color_plane_enable;
253 struct vga_horizontal_pixel_pan_reg vga_horizontal_pixel_pan;
255 struct vga_color_select_reg vga_color_select;
256 } __attribute__((packed));
258 struct vga_dac_regs {
259 enum {DAC_READ=0, DAC_WRITE} state;
260 enum {RED=0,GREEN,BLUE} channel;
261 vga_dac_pixel_mask_reg vga_pixel_mask;
262 vga_dac_write_addr_reg vga_dac_write_addr;
263 vga_dac_read_addr_reg vga_dac_read_addr;
264 // the dac_data register is used only to access the registers
265 // and thus has no representation here
266 vga_palette_reg vga_dac_palette[VGA_DAC_NUM_ENTRIES];
267 } __attribute__((packed));
270 struct vga_internal {
271 struct vm_device *dev;
274 bool skip_next_passthrough_out; // for word access
276 struct v3_frame_buffer_spec target_spec;
277 v3_graphics_console_t host_cons;
279 uint32_t updates_since_render;
281 struct frame_buf *framebuf; // we render to this
283 // void *mem_store; // This is the region where the memory hooks will go
285 vga_map map[MAP_NUM]; // the maps that the host writes to
287 uint8_t latch[MAP_NUM]; // written to in any read, used during writes
289 /* Range of I/O ports here for backward compat with MDA and CGA */
290 struct vga_misc_regs vga_misc;
292 /* Address Register is 0x3b4 or 0x3d4 */
293 /* Data register is 0x3b5 or 0x3d5 based on MDA/CGA/VGA (backward compat) */
294 struct vga_crt_controller_regs vga_crt_controller;
296 /* Address register is 0x3c4, data register is 0x3c5 */
297 struct vga_sequencer_regs vga_sequencer;
299 /* Address: 0x3ce Data: 0x3cf */
300 struct vga_graphics_controller_regs vga_graphics_controller;
303 Address AND WRITE: 0x3c0
307 struct vga_attribute_contoller_regs vga_attribute_controller;
310 address for reads: 0x3c7 (also resets state machine for access to 18 bit regs
311 address for writes: 0x3c8 ("")
313 pixel mask: 0x3c6 - do not write (init to 0xff)
315 struct vga_dac_regs vga_dac;
320 static int render(struct vga_internal *vga)
322 vga->updates_since_render++;
324 if (vga->host_cons && v3_graphics_console_inform_update(vga->host_cons)>0) {
325 // Draw some crap for testing for now
328 struct v3_frame_buffer_spec *s;
330 fb = v3_graphics_console_get_frame_buffer_data_rw(vga->host_cons,&(vga->target_spec));
332 s=&(vga->target_spec);
334 if (fb && s->height>=480 && s->width>=640 ) {
335 uint8_t color = (uint8_t)(vga->updates_since_render);
339 for (y=0;y<480;y++) {
340 for (x=0;x<640;x++) {
341 void *pixel = fb + (x + y*s->width) *s->bytes_per_pixel;
342 uint8_t *red = pixel + s->red_offset;
343 uint8_t *green = pixel + s->green_offset;
344 uint8_t *blue = pixel + s->blue_offset;
350 } else if (y<480/2) {
354 } else if (y<3*480/4) {
359 *red=*green=*blue=color+x;
370 static void get_mem_region(struct vga_internal *vga, uint64_t *mem_start, uint64_t *mem_end)
372 switch (vga->vga_graphics_controller.vga_misc.memory_map) {
392 static uint64_t find_offset(struct vga_internal *vga, addr_t guest_addr)
394 uint64_t mem_start, mem_end;
398 get_mem_region(vga, &mem_start, &mem_end);
400 return (guest_addr-mem_start) % (mem_end-mem_start > 65536 ? 65536 : (mem_end-mem_start));
407 static int vga_write(struct guest_info * core,
414 struct vm_device *dev = (struct vm_device *)priv_data;
415 struct vga_internal *vga = (struct vga_internal *) dev->private_data;
417 PrintDebug("vga: memory write: guest_addr=0x%p len=%u\n",(void*)guest_addr, length);
419 if (vga->passthrough) {
420 PrintDebug("vga: passthrough write to 0x%p\n", V3_VAddr((void*)guest_addr));
421 memcpy(V3_VAddr((void*)guest_addr),src,length);
424 PrintDebug("vga: data written was \"");
425 for (i=0;i<length;i++) {
426 char c= ((char*)src)[i];
427 PrintDebug("%c", (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') ? c : '.');
431 /* Write mode determine by Graphics Mode Register (Index 05h).writemode */
433 switch (vga->vga_graphics_controller.vga_graphics_mode.write_mode) {
437 00b -- Write Mode 0: In this mode, the host data is first rotated
438 as per the Rotate Count field, then the Enable Set/Reset mechanism
439 selects data from this or the Set/Reset field. Then the selected
440 Logical Operation is performed on the resulting data and the data
441 in the latch register. Then the Bit Mask field is used to select
442 which bits come from the resulting data and which come
443 from the latch register. Finally, only the bit planes enabled by
444 the Memory Plane Write Enable field are written to memory.
452 uint8_t ror = vga->vga_graphics_controller.vga_data_rotate.rotate_count;
453 uint8_t func = vga->vga_graphics_controller.vga_data_rotate.function;
455 offset = find_offset(vga, guest_addr);
457 PrintDebug("vga: mode 0 write, offset=0x%llx, ror=%u, func=%u\n", offset,ror,func);
459 for (i=0;i<length;i++,offset++) {
461 uint8_t sr = vga->vga_graphics_controller.vga_set_reset.val & 0xf;
462 uint8_t esr = vga->vga_graphics_controller.vga_enable_set_reset.val &0xf;
463 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask;
464 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
466 for (mapnum=0;mapnum<4;mapnum++, sr>>=1, esr>>=1, bm>>=1, mm>>=1) {
467 vga_map map = vga->map[mapnum];
468 uint8_t data = ((uint8_t *)src)[i];
469 uint8_t latchval = vga->latch[mapnum];
472 data = (data>>ror) | data<<(8-ror);
474 // use SR bit if ESR is on for this map
476 data = (uint8_t)((((sint8_t)(sr&0x1))<<7)>>7); // expand sr bit
494 // mux between latch and alu output
496 // use alu output, which is in data
505 //PrintDebug("vga: write map %u offset 0x%p map=0x%p pointer=0x%p\n",mapnum,(void*)offset,map,&(map[offset]));
519 01b -- Write Mode 1: In this mode, data is transferred directly
520 from the 32 bit latch register to display memory, affected only by
521 the Memory Plane Write Enable field. The host data is not used in this mode.
526 uint64_t offset = find_offset(vga,guest_addr);
528 PrintDebug("vga: mode 1 write, offset=0x%llx\n", offset);
530 for (i=0;i<length;i++,offset++) {
533 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
535 for (mapnum=0;mapnum<4;mapnum++, mm>>=1) {
536 vga_map map = vga->map[mapnum];
537 uint8_t latchval = vga->latch[mapnum];
542 map[offset] = latchval;
553 10b -- Write Mode 2: In this mode, the bits 3-0 of the host data
554 are replicated across all 8 bits of their respective planes.
555 Then the selected Logical Operation is performed on the resulting
556 data and the data in the latch register. Then the Bit Mask field is used to
557 select which bits come from the resulting data and which come from
558 the latch register. Finally, only the bit planes enabled by the
559 Memory Plane Write Enable field are written to memory.
565 uint8_t func = vga->vga_graphics_controller.vga_data_rotate.function;
567 offset = find_offset(vga, guest_addr);
569 PrintDebug("vga: mode 2 write, offset=0x%llx, func=%u\n", offset,func);
571 for (i=0;i<length;i++,offset++) {
573 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask;
574 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
576 for (mapnum=0;mapnum<4;mapnum++, bm>>=1, mm>>=1) {
577 vga_map map = vga->map[mapnum];
578 uint8_t data = ((uint8_t *)src)[i];
579 uint8_t latchval = vga->latch[mapnum];
581 // expand relevant bit to 8 bit
582 // it's basically esr=1, sr=bit from write
583 data = (uint8_t)(((sint8_t)(((data>>mapnum)&0x1)<<7))>>7);
600 // mux between latch and alu output
602 // use alu output, which is in data
621 /* 11b -- Write Mode 3: In this mode, the data in the Set/Reset field is used
622 as if the Enable Set/Reset field were set to 1111b. Then the host data is
623 first rotated as per the Rotate Count field, then logical ANDed with the
624 value of the Bit Mask field. The resulting value is used on the data
625 obtained from the Set/Reset field in the same way that the Bit Mask field
626 would ordinarily be used. to select which bits come from the expansion
627 of the Set/Reset field and which come from the latch register. Finally,
628 only the bit planes enabled by the Memory Plane Write Enable field
629 are written to memory.
636 uint8_t ror = vga->vga_graphics_controller.vga_data_rotate.rotate_count;
638 offset = find_offset(vga, guest_addr);
640 PrintDebug("vga: mode 3 write, offset=0x%llx, ror=%u\n", offset,ror);
642 for (i=0;i<length;i++,offset++) {
644 uint8_t data = ((uint8_t *)src)[i];
646 data = (data>>ror) | data<<(8-ror);
648 uint8_t bm = vga->vga_graphics_controller.vga_bit_mask & data;
649 uint8_t sr = vga->vga_graphics_controller.vga_set_reset.val & 0xf;
650 uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
652 for (mapnum=0;mapnum<4;mapnum++, sr>>=1, bm>>=1, mm>>=1) {
653 vga_map map = vga->map[mapnum];
654 uint8_t latchval = vga->latch[mapnum];
656 data = (uint8_t)((((sint8_t)(sr&0x1))<<7)>>7); // expand sr bit
659 // mux between latch and alu output
661 // use alu output, which is in data
680 // There is no default
690 up to 256K mapped through a window of 32 to 128K
692 most cards support linear mode as well
694 Need to implement readability too
696 Write extended memory bit to enable all 256K:
698 Sequencer Memory Mode Register (Index 04h) . extended memory
700 Must enable writes before effects happen:
702 Miscellaneous Output Register (Read at 3CCh, Write at 3C2h).ram enable
704 Choose which addresses are supported for CPU writes:
706 Miscellaneous Graphics Register (Index 06h).memory map select
708 00b -- A0000h-BFFFFh (128K region)
709 01b -- A0000h-AFFFFh (64K region)
710 10b -- B0000h-B7FFFh (32K region)
711 11b -- B8000h-BFFFFh (32K region)
713 There are three addressing modes: Chain 4, Odd/Even mode, and normal mode:
715 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.)
717 Memory model: 64K 32 bit locations; divided into 4 64K bit planes
723 Assume linear framebuffer, starting at address buf:
729 static int vga_read(struct guest_info * core,
736 struct vm_device *dev = (struct vm_device *)priv_data;
737 struct vga_internal *vga = (struct vga_internal *) dev->private_data;
740 PrintDebug("vga: memory read: guest_addr=0x%p len=%u\n",(void*)guest_addr, length);
746 Reading, 2 modes, set via Graphics Mode Register (index 05h).Read Mode:
748 switch (vga->vga_graphics_controller.vga_graphics_mode.read_mode) {
750 /* 0 - a byte from ONE of the 4 planes is returned;
751 which plane is determined by Read Map Select (Read Map Select Register (Index 04h)) */
755 mapnum = vga->vga_graphics_controller.vga_read_map_select.map_select;
756 offset = find_offset(vga,guest_addr);
759 PrintError("vga: read to offset=%llu map=%u (%u bytes)\n",offset,mapnum,length);
762 memcpy(dst,(vga->map[mapnum])+offset,length);
764 // load the latches with the last item read
765 for (mapnum=0;mapnum<4;mapnum++) {
766 vga->latch[mapnum] = vga->map[mapnum][offset+length-1];
773 /* 1 - Compare video memory and reference color
774 (in Color Compare, except those not set in Color Don't Care),
775 each bit in returned result is one comparison between the reference color
777 Ref color is *4* bits, and thus a one byte read returns a comparison
783 uint8_t cc=vga->vga_graphics_controller.vga_color_compare.val & 0xf ;
784 uint8_t dc=vga->vga_graphics_controller.vga_color_dont_care.val & 0xf;
791 offset = find_offset(vga,guest_addr);
793 for (i=0;i<length;i++,offset++) {
796 for (mapnum=0;mapnum<4;mapnum++) {
797 map = vga->map[mapnum];
798 if ( (dc>>mapnum)&0x1 ) { // don't care
802 bits = (map[offset]&0xf) == cc;
805 bits |= (((map[offset]>>4))&0xf) == cc;
807 // not clear whether it is 0..k or k..0
813 // load the latches with the last item read
814 for (mapnum=0;mapnum<4;mapnum++) {
815 vga->latch[mapnum] = vga->map[mapnum][offset+length-1];
820 // there is no default
823 if (vga->passthrough) {
824 PrintDebug("vga: passthrough read from 0x%p\n",V3_VAddr((void*)guest_addr));
825 memcpy(dst,V3_VAddr((void*)guest_addr),length);
829 PrintDebug("vga: data read is \"");
830 for (i=0;i<length;i++) {
831 char c= ((char*)dst)[i];
832 PrintDebug("%c", (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') ? c : '.');
844 #define ERR_WRONG_SIZE(op,reg,len,min,max) \
845 if (((len)<(min)) || ((len)>(max))) { \
846 PrintError("vga: %s of %s wrong size (%d bytes, but only %d to %d allowed)\n",(op),(reg),(len),(min),(max)); \
850 static inline void passthrough_io_in(uint16_t port, void * dest, uint_t length) {
853 *(uint8_t *)dest = v3_inb(port);
856 *(uint16_t *)dest = v3_inw(port);
859 *(uint32_t *)dest = v3_indw(port);
862 PrintError("vga: unsupported passthrough io in size %u\n",length);
868 static inline void passthrough_io_out(uint16_t port, const void * src, uint_t length) {
871 v3_outb(port, *(uint8_t *)src);
874 v3_outw(port, *(uint16_t *)src);
877 v3_outdw(port, *(uint32_t *)src);
880 PrintError("vga: unsupported passthrough io out size %u\n",length);
885 #define PASSTHROUGH_IO_IN(vga,port,dest,len) \
886 do { if ((vga)->passthrough) { passthrough_io_in(port,dest,len); } } while (0)
888 #define PASSTHROUGH_IO_OUT(vga,port,src,len) \
889 do { if ((vga)->passthrough && (!(vga)->skip_next_passthrough_out)) { passthrough_io_out(port,src,len); } (vga)->skip_next_passthrough_out=false; } while (0)
891 #define PASSTHROUGH_IO_SKIP_NEXT_OUT(vga) \
892 do { if ((vga)->passthrough) { (vga)->skip_next_passthrough_out=true; } } while (0)
894 #define PASSTHROUGH_READ_CHECK(vga,inter,pass) \
895 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)
897 static int misc_out_read(struct guest_info *core,
903 struct vga_internal *vga = (struct vga_internal *) priv_data;
905 PrintDebug("vga: misc out read data=0x%x\n", vga->vga_misc.vga_misc_out.val);
907 ERR_WRONG_SIZE("read","misc out",len,1,1);
909 *((uint8_t*)dest) = vga->vga_misc.vga_misc_out.val;
911 PASSTHROUGH_IO_IN(vga,port,dest,len);
913 PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_misc_out.val,*((uint8_t*)dest));
918 static int misc_out_write(struct guest_info *core,
924 struct vga_internal *vga = (struct vga_internal *) priv_data;
926 PrintDebug("vga: misc out write data=0x%x\n", *((uint8_t*)src));
928 ERR_WRONG_SIZE("write","misc out",len,1,1);
930 PASSTHROUGH_IO_OUT(vga,port,src,len);
932 vga->vga_misc.vga_misc_out.val = *((uint8_t*)src) ;
941 static int input_stat0_read(struct guest_info *core,
947 struct vga_internal *vga = (struct vga_internal *) priv_data;
949 PrintDebug("vga: input stat0 read data=0x%x\n", vga->vga_misc.vga_input_stat0.val);
951 ERR_WRONG_SIZE("read","input stat0",len,1,1);
953 *((uint8_t*)dest) = vga->vga_misc.vga_input_stat0.val;
955 PASSTHROUGH_IO_IN(vga,port,dest,len);
957 PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_input_stat0.val,*(uint8_t*)dest);
963 static int input_stat1_read(struct guest_info *core,
969 struct vga_internal *vga = (struct vga_internal *) priv_data;
971 PrintDebug("vga: input stat0 (%s) read data=0x%x\n",
972 port==0x3ba ? "mono" : "color",
973 vga->vga_misc.vga_input_stat1.val);
975 ERR_WRONG_SIZE("read","input stat1",len,1,1);
978 *((uint8_t*)dest) = vga->vga_misc.vga_input_stat1.val;
980 // Stunningly, reading stat1 is also a way to reset
981 // the state of attribute controller address/data flipflop
982 // That is some mighty fine crack the designers were smoking.
984 vga->vga_attribute_controller.state=ATTR_ADDR;
986 PASSTHROUGH_IO_IN(vga,port,dest,len);
988 PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_input_stat1.val,*(uint8_t*)dest);
994 static int feature_control_read(struct guest_info *core,
1000 struct vga_internal *vga = (struct vga_internal *) priv_data;
1002 PrintDebug("vga: feature control read data=0x%x\n",
1003 vga->vga_misc.vga_feature_control.val);
1005 ERR_WRONG_SIZE("read","feature control",len,1,1);
1008 *((uint8_t*)dest) = vga->vga_misc.vga_feature_control.val;
1010 PASSTHROUGH_IO_IN(vga,port,dest,len);
1012 PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_feature_control.val,*(uint8_t*)dest);
1017 static int feature_control_write(struct guest_info *core,
1023 struct vga_internal *vga = (struct vga_internal *) priv_data;
1025 PrintDebug("vga: feature control (%s) write data=0x%x\n",
1026 port==0x3ba ? "mono" : "color",
1029 ERR_WRONG_SIZE("write","feature control",len,1,1);
1031 PASSTHROUGH_IO_OUT(vga,port,src,len);
1033 vga->vga_misc.vga_feature_control.val = *((uint8_t*)src) ;
1041 static int video_subsys_enable_read(struct guest_info *core,
1047 struct vga_internal *vga = (struct vga_internal *) priv_data;
1049 PrintDebug("vga: video subsys enable read data=0x%x\n",
1050 vga->vga_misc.vga_video_subsys_enable.val);
1052 ERR_WRONG_SIZE("read","video subsys enable",len,1,1);
1054 *((uint8_t*)dest) = vga->vga_misc.vga_video_subsys_enable.val;
1056 PASSTHROUGH_IO_IN(vga,port,dest,len);
1058 PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_video_subsys_enable.val,*(uint8_t*)dest);
1063 static int video_subsys_enable_write(struct guest_info *core,
1069 struct vga_internal *vga = (struct vga_internal *) priv_data;
1071 PrintDebug("vga: video subsys enable write data=0x%x\n", *((uint8_t*)src));
1073 ERR_WRONG_SIZE("write","video subsys enable",len,1,1);
1075 PASSTHROUGH_IO_OUT(vga,port,src,len);
1077 vga->vga_misc.vga_video_subsys_enable.val = *((uint8_t*)src) ;
1084 static int sequencer_address_read(struct guest_info *core,
1090 struct vga_internal *vga = (struct vga_internal *) priv_data;
1092 PrintDebug("vga: sequencer address read data=0x%x\n",
1093 vga->vga_sequencer.vga_sequencer_addr.val);
1095 ERR_WRONG_SIZE("read","vga sequencer addr",len,1,1);
1097 *((uint8_t*)dest) = vga->vga_sequencer.vga_sequencer_addr.val;
1099 PASSTHROUGH_IO_IN(vga,port,dest,len);
1101 PASSTHROUGH_READ_CHECK(vga,vga->vga_sequencer.vga_sequencer_addr.val,*(uint8_t*)dest);
1106 static int sequencer_data_write(struct guest_info *core,
1112 struct vga_internal *vga = (struct vga_internal *) priv_data;
1116 data=*((uint8_t*)src);
1117 index=vga->vga_sequencer.vga_sequencer_addr.val; // should mask probably
1119 PrintDebug("vga: sequencer write data (index=%d) with 0x%x\n",
1122 ERR_WRONG_SIZE("write","vga sequencer data",len,1,1);
1124 PASSTHROUGH_IO_OUT(vga,port,src,len);
1127 if (index>=VGA_SEQUENCER_NUM) {
1128 PrintError("vga: sequencer data write is for invalid index %d, ignoring\n",index);
1130 vga->vga_sequencer.vga_sequencer_regs[index] = data;
1138 static int sequencer_address_write(struct guest_info *core,
1144 struct vga_internal *vga = (struct vga_internal *) priv_data;
1147 new_addr=*((uint8_t*)src);
1149 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);
1151 ERR_WRONG_SIZE("write","vga sequencer addr",len,1,2);
1153 PASSTHROUGH_IO_OUT(vga,port,src,len);
1155 vga->vga_sequencer.vga_sequencer_addr.val = *((uint8_t*)src) ;
1158 PASSTHROUGH_IO_SKIP_NEXT_OUT(vga);
1159 // second byte is the data
1160 if (sequencer_data_write(core,port,src+1,1,vga)!=1) {
1161 PrintError("vga: write of data failed\n");
1169 static int sequencer_data_read(struct guest_info *core,
1175 struct vga_internal *vga = (struct vga_internal *) priv_data;
1179 index=vga->vga_sequencer.vga_sequencer_addr.val; // should mask probably
1181 if (index>=VGA_SEQUENCER_NUM) {
1183 PrintError("vga: sequencer data read at invalid index %d, returning zero\n",index);
1185 data=vga->vga_sequencer.vga_sequencer_regs[index];
1188 PrintDebug("vga: sequencer data read data (index=%d) = 0x%x\n",
1191 ERR_WRONG_SIZE("read","vga sequencer data",len,1,1);
1193 *((uint8_t*)dest) = data;
1195 PASSTHROUGH_IO_IN(vga,port,dest,len);
1197 PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1206 static int crt_controller_address_read(struct guest_info *core,
1212 struct vga_internal *vga = (struct vga_internal *) priv_data;
1214 PrintDebug("vga: crt controller (%s) address read data=0x%x\n",
1215 port==0x3b4 ? "mono" : "color",
1216 vga->vga_crt_controller.vga_crt_addr.val);
1218 ERR_WRONG_SIZE("read","vga crt controller addr",len,1,1);
1220 *((uint8_t*)dest) = vga->vga_crt_controller.vga_crt_addr.val;
1222 PASSTHROUGH_IO_IN(vga,port,dest,len);
1224 PASSTHROUGH_READ_CHECK(vga,vga->vga_crt_controller.vga_crt_addr.val,*(uint8_t*)dest);
1229 static int crt_controller_data_write(struct guest_info *core,
1235 struct vga_internal *vga = (struct vga_internal *) priv_data;
1239 data=*((uint8_t*)src);
1241 index=vga->vga_crt_controller.vga_crt_addr.val; // should mask probably
1243 PrintDebug("vga: crt controller (%s) write data (index=%d) with 0x%x\n",
1244 port==0x3b5 ? "mono" : "color",
1247 ERR_WRONG_SIZE("write","vga crt controller data",len,1,1);
1249 PASSTHROUGH_IO_OUT(vga,port,src,len);
1251 if (index>=VGA_CRT_CONTROLLER_NUM) {
1252 PrintError("vga; crt controller write is for illegal index %d, ignoring\n",index);
1254 vga->vga_crt_controller.vga_crt_controller_regs[index] = data;
1262 static int crt_controller_address_write(struct guest_info *core,
1268 struct vga_internal *vga = (struct vga_internal *) priv_data;
1271 new_addr=*((uint8_t*)src);
1273 PrintDebug("vga: crt controller (%s) address write data=0x%x len=%u\n",
1274 port==0x3b4 ? "mono" : "color",
1275 len==1 ? *((uint8_t*)src) : len==2 ? *((uint16_t*)src) : *((uint32_t*)src), len);
1277 ERR_WRONG_SIZE("write","vga crt controller addr",len,1,2);
1279 PASSTHROUGH_IO_OUT(vga,port,src,len);
1281 vga->vga_crt_controller.vga_crt_addr.val = *((uint8_t*)src) ;
1284 PASSTHROUGH_IO_SKIP_NEXT_OUT(vga);
1285 // second byte is the data
1286 if (crt_controller_data_write(core,port,src+1,1,vga)!=1) {
1287 PrintError("vga: write of data failed\n");
1295 static int crt_controller_data_read(struct guest_info *core,
1301 struct vga_internal *vga = (struct vga_internal *) priv_data;
1305 index=vga->vga_crt_controller.vga_crt_addr.val; // should mask probably
1307 if (index>=VGA_CRT_CONTROLLER_NUM) {
1309 PrintError("vga: crt controller data read for illegal index %d, returning zero\n",index);
1311 data=vga->vga_crt_controller.vga_crt_controller_regs[index];
1314 PrintDebug("vga: crt controller data (index=%d) = 0x%x\n",index,data);
1316 ERR_WRONG_SIZE("read","vga crt controller data",len,1,1);
1318 *((uint8_t*)dest) = data;
1320 PASSTHROUGH_IO_IN(vga,port,dest,len);
1322 PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t *)dest);
1329 static int graphics_controller_address_read(struct guest_info *core,
1335 struct vga_internal *vga = (struct vga_internal *) priv_data;
1337 PrintDebug("vga: graphics controller address read data=0x%x\n",
1338 vga->vga_graphics_controller.vga_graphics_ctrl_addr.val);
1340 ERR_WRONG_SIZE("read","vga graphics controller addr",len,1,1);
1342 *((uint8_t*)dest) = vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;
1344 PASSTHROUGH_IO_IN(vga,port,dest,len);
1346 PASSTHROUGH_READ_CHECK(vga,vga->vga_graphics_controller.vga_graphics_ctrl_addr.val,*(uint8_t*)dest);
1351 static int graphics_controller_data_write(struct guest_info *core,
1357 struct vga_internal *vga = (struct vga_internal *) priv_data;
1361 data=*((uint8_t*)src);
1362 index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val; // should mask probably
1365 PrintDebug("vga: graphics_controller write data (index=%d) with 0x%x\n",
1368 ERR_WRONG_SIZE("write","vga graphics controller data",len,1,1);
1370 PASSTHROUGH_IO_OUT(vga,port,src,len);
1372 if (index>=VGA_GRAPHICS_CONTROLLER_NUM) {
1373 PrintError("vga: graphics controller write for illegal index %d ignored\n",index);
1375 vga->vga_graphics_controller.vga_graphics_controller_regs[index] = data;
1383 static int graphics_controller_address_write(struct guest_info *core,
1389 struct vga_internal *vga = (struct vga_internal *) priv_data;
1392 new_addr=*((uint8_t*)src);
1394 PrintDebug("vga: graphics controller address write data=0x%x len=%u\n",
1395 len==1 ? *((uint8_t*)src) : len==2 ? *((uint16_t*)src) : *((uint32_t*)src), len);
1397 ERR_WRONG_SIZE("write","vga graphics controller addr",len,1,2);
1399 PASSTHROUGH_IO_OUT(vga,port,src,len);
1401 vga->vga_graphics_controller.vga_graphics_ctrl_addr.val = *((uint8_t*)src) ;
1404 PASSTHROUGH_IO_SKIP_NEXT_OUT(vga);
1405 // second byte is the data
1406 if (graphics_controller_data_write(core,port,src+1,1,vga)!=1) {
1407 PrintError("vga: write of data failed\n");
1415 static int graphics_controller_data_read(struct guest_info *core,
1421 struct vga_internal *vga = (struct vga_internal *) priv_data;
1425 index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val; // should mask probably
1428 if (index>=VGA_GRAPHICS_CONTROLLER_NUM) {
1430 PrintError("vga: graphics controller data read from illegal index %d, returning zero\n",index);
1432 data=vga->vga_graphics_controller.vga_graphics_controller_regs[index];
1435 PrintDebug("vga: graphics controller data read data (index=%d) = 0x%x\n",
1438 ERR_WRONG_SIZE("read","vga graphics controller data",len,1,1);
1440 *((uint8_t*)dest) = data;
1442 PASSTHROUGH_IO_IN(vga,port,dest,len);
1444 PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1452 /* Note that these guys have a bizarre protocol*/
1454 static int attribute_controller_address_read(struct guest_info *core,
1460 struct vga_internal *vga = (struct vga_internal *) priv_data;
1462 PrintDebug("vga: attribute controller address read data=0x%x\n",
1463 vga->vga_attribute_controller.vga_attribute_controller_addr.val);
1465 ERR_WRONG_SIZE("read","vga attribute controller addr",len,1,1);
1467 *((uint8_t*)dest) = vga->vga_attribute_controller.vga_attribute_controller_addr.val;
1469 PASSTHROUGH_IO_IN(vga,port,dest,len);
1471 PASSTHROUGH_READ_CHECK(vga,vga->vga_attribute_controller.vga_attribute_controller_addr.val,*(uint8_t*)dest);
1473 // Reading the attribute controller does not change the state
1478 static int attribute_controller_address_and_data_write(struct guest_info *core,
1484 struct vga_internal *vga = (struct vga_internal *) priv_data;
1487 if (vga->vga_attribute_controller.state==ATTR_ADDR) {
1488 uint8_t new_addr = *((uint8_t*)src);
1489 // We are to treat this as an address write, and flip state
1490 // to expect data ON THIS SAME PORT
1491 PrintDebug("vga: attribute controller address write data=0x%x\n", new_addr);
1493 ERR_WRONG_SIZE("write","vga attribute controller addr",len,1,1);
1495 PASSTHROUGH_IO_OUT(vga,port,src,len);
1497 vga->vga_attribute_controller.vga_attribute_controller_addr.val = new_addr;
1499 vga->vga_attribute_controller.state=ATTR_DATA;
1502 } else if (vga->vga_attribute_controller.state==ATTR_DATA) {
1504 uint8_t data = *((uint8_t*)src);
1505 uint8_t index=vga->vga_attribute_controller.vga_attribute_controller_addr.val; // should mask probably
1507 PrintDebug("vga: attribute controller data write index %d with data=0x%x\n", index,data);
1509 ERR_WRONG_SIZE("write","vga attribute controller data",len,1,1);
1511 PASSTHROUGH_IO_OUT(vga,port,src,len);
1513 if (index>=VGA_ATTRIBUTE_CONTROLLER_NUM) {
1514 PrintError("vga: attribute controller write to illegal index %d ignored\n",index);
1516 vga->vga_attribute_controller.vga_attribute_controller_regs[index] = data;
1519 vga->vga_attribute_controller.state=ATTR_ADDR;
1528 static int attribute_controller_data_read(struct guest_info *core,
1534 struct vga_internal *vga = (struct vga_internal *) priv_data;
1538 index=vga->vga_attribute_controller.vga_attribute_controller_addr.val; // should mask probably
1540 if (index>=VGA_ATTRIBUTE_CONTROLLER_NUM) {
1542 PrintError("vga: attribute controller read of illegal index %d, returning zero\n",index);
1544 data=vga->vga_attribute_controller.vga_attribute_controller_regs[index];
1547 PrintDebug("vga: attribute controller data read data (index=%d) = 0x%x\n",
1550 ERR_WRONG_SIZE("read","vga attribute controller data",len,1,1);
1552 *((uint8_t*)dest) = data;
1554 PASSTHROUGH_IO_IN(vga,port,dest,len);
1556 PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1563 Note that these guys also have a strange protocol
1564 since they need to squeeze 18 bits of data through
1567 static int dac_write_address_read(struct guest_info *core,
1573 struct vga_internal *vga = (struct vga_internal *) priv_data;
1575 PrintDebug("vga: dac write address read data=0x%x\n",
1576 vga->vga_dac.vga_dac_write_addr);
1578 ERR_WRONG_SIZE("read","vga dac write addr",len,1,1);
1581 *((uint8_t*)dest) = vga->vga_dac.vga_dac_write_addr;
1583 PASSTHROUGH_IO_IN(vga,port,dest,len);
1585 PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_dac_write_addr,*(uint8_t*)dest);
1587 // This read does not reset the state machine
1592 static int dac_write_address_write(struct guest_info *core,
1598 struct vga_internal *vga = (struct vga_internal *) priv_data;
1601 new_addr=*((uint8_t*)src);
1603 PrintDebug("vga: dac write address write data=0x%x\n", new_addr);
1605 ERR_WRONG_SIZE("write","vga dac write addr",len,1,1);
1607 PASSTHROUGH_IO_OUT(vga,port,src,len);
1609 // cannot be out of bounds since there are 256 regs
1611 vga->vga_dac.vga_dac_write_addr = *((uint8_t*)src) ;
1613 // Now we also need to reset the state machine
1615 vga->vga_dac.state=DAC_WRITE;
1616 vga->vga_dac.channel=RED;
1622 static int dac_read_address_read(struct guest_info *core,
1628 struct vga_internal *vga = (struct vga_internal *) priv_data;
1630 PrintDebug("vga: dac read address read data=0x%x\n",
1631 vga->vga_dac.vga_dac_read_addr);
1633 ERR_WRONG_SIZE("read","vga dac read addr",len,1,1);
1635 *((uint8_t*)dest) = vga->vga_dac.vga_dac_read_addr;
1637 PASSTHROUGH_IO_IN(vga,port,dest,len);
1639 PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_dac_read_addr,*(uint8_t*)dest);
1641 // This read does not reset the state machine
1646 static int dac_read_address_write(struct guest_info *core,
1652 struct vga_internal *vga = (struct vga_internal *) priv_data;
1655 new_addr=*((uint8_t*)src);
1657 PrintDebug("vga: dac read address write data=0x%x\n", new_addr);
1659 ERR_WRONG_SIZE("write","vga dac read addr",len,1,1);
1661 PASSTHROUGH_IO_OUT(vga,port,src,len);
1663 // cannot be out of bounds since there are 256 regs
1665 vga->vga_dac.vga_dac_read_addr = *((uint8_t*)src) ;
1667 // Now we also need to reset the state machine
1669 vga->vga_dac.state=DAC_READ;
1670 vga->vga_dac.channel=RED;
1676 static int dac_data_read(struct guest_info *core,
1682 struct vga_internal *vga = (struct vga_internal *) priv_data;
1687 if (vga->vga_dac.state!=DAC_READ) {
1688 PrintError("vga: dac data read while in other state\n");
1689 // results undefined, so we continue
1692 ERR_WRONG_SIZE("read","vga dac read data",len,1,1);
1694 curreg = vga->vga_dac.vga_dac_read_addr;
1695 curchannel = vga->vga_dac.channel;
1696 data = (vga->vga_dac.vga_dac_palette[curreg] >> curchannel*8) & 0x3f;
1698 PrintDebug("vga: dac reg %u [%s] = 0x%x\n",
1700 curchannel == 0 ? "RED" : curchannel == 1 ? "GREEN"
1701 : curchannel==2 ? "BLUE" : "BAD CHANNEL",
1704 *((uint8_t*)dest) = data;
1706 PASSTHROUGH_IO_IN(vga,port,dest,len);
1708 PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
1710 curchannel = (curchannel+1)%3;
1711 vga->vga_dac.channel=curchannel;
1712 if (curchannel==0) {
1713 curreg = (curreg + 1) % VGA_DAC_NUM_ENTRIES;
1715 vga->vga_dac.vga_dac_read_addr = curreg;
1716 vga->vga_dac.state=DAC_READ;
1723 static int dac_data_write(struct guest_info *core,
1729 struct vga_internal *vga = (struct vga_internal *) priv_data;
1733 vga_palette_reg data32;
1734 vga_palette_reg mask32;
1736 if (vga->vga_dac.state!=DAC_WRITE) {
1737 PrintError("vga: dac data write while in other state\n");
1738 // results undefined, so we continue
1741 ERR_WRONG_SIZE("read","vga dac write data",len,1,1);
1743 PASSTHROUGH_IO_OUT(vga,port,src,len);
1745 curreg = vga->vga_dac.vga_dac_write_addr;
1746 curchannel = vga->vga_dac.channel;
1747 data = *((uint8_t *)src);
1749 PrintDebug("vga: dac reg %u [%s] write with 0x%x\n",
1751 curchannel == 0 ? "RED" : curchannel == 1 ? "GREEN"
1752 : curchannel==2 ? "BLUE" : "BAD CHANNEL",
1755 data32 = data & 0x3f ;
1756 data32 <<= curchannel*8;
1757 mask32 = ~(0xff << (curchannel * 8));
1759 vga->vga_dac.vga_dac_palette[curreg] &= mask32;
1760 vga->vga_dac.vga_dac_palette[curreg] |= data32;
1762 curchannel = (curchannel+1)%3;
1763 vga->vga_dac.channel=curchannel;
1764 if (curchannel==0) {
1765 curreg = (curreg + 1) % VGA_DAC_NUM_ENTRIES;
1767 vga->vga_dac.vga_dac_write_addr = curreg;
1768 vga->vga_dac.state=DAC_WRITE;
1777 static int dac_pixel_mask_read(struct guest_info *core,
1783 struct vga_internal *vga = (struct vga_internal *) priv_data;
1785 PrintDebug("vga: dac pixel mask read data=0x%x\n",
1786 vga->vga_dac.vga_pixel_mask);
1788 ERR_WRONG_SIZE("read","vga pixel mask",len,1,1);
1790 *((uint8_t*)dest) = vga->vga_dac.vga_pixel_mask;
1792 PASSTHROUGH_IO_IN(vga,port,dest,len);
1794 PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_pixel_mask,*(uint8_t*)dest);
1799 static int dac_pixel_mask_write(struct guest_info *core,
1805 struct vga_internal *vga = (struct vga_internal *) priv_data;
1808 new_data=*((uint8_t*)src);
1810 PrintDebug("vga: dac pixel mask write data=0x%x\n", new_data);
1812 ERR_WRONG_SIZE("write","pixel mask",len,1,1);
1814 PASSTHROUGH_IO_OUT(vga,port,src,len);
1816 vga->vga_dac.vga_pixel_mask = new_data;
1821 static int init_vga(struct vga_internal *vga)
1823 // TODO: startup spec of register contents, if any
1824 PrintError("vga: init_vga is UNIMPLEMTED\n");
1828 static int free_vga(struct vga_internal *vga)
1832 struct vm_device *dev = vga->dev;
1834 // Framebuffer deletion is user's responsibility
1836 // if (vga->mem_store) {
1837 // V3_FreePages(v3_hva_to_hpa(vga->mem_store),MEM_REGION_NUM_PAGES);
1838 // vga->mem_store=0;
1841 for (i=0;i<MAP_NUM;i++) {
1843 V3_FreePages(V3_PAddr(vga->map[i]),MAP_SIZE/4096);
1848 v3_unhook_mem(vga->dev->vm, V3_MEM_CORE_ANY, MEM_REGION_START);
1852 ret |= v3_dev_unhook_io(dev, VGA_MISC_OUT_READ);
1853 // The following also covers VGA_INPUT_STAT0_READ
1854 ret |= v3_dev_unhook_io(dev, VGA_MISC_OUT_WRITE);
1855 // The following also covers VGA_FEATURE_CTRL_WRITE_MONO
1856 ret |= v3_dev_unhook_io(dev, VGA_INPUT_STAT1_READ_MONO);
1857 // The folowinn also covers VGA FEATURE_CONTROL_WRITE_COLOR
1858 ret |= v3_dev_unhook_io(dev, VGA_INPUT_STAT1_READ_COLOR);
1859 ret |= v3_dev_unhook_io(dev, VGA_FEATURE_CONTROL_READ);
1861 ret |= v3_dev_unhook_io(dev, VGA_VIDEO_SUBSYS_ENABLE);
1863 /* Sequencer registers */
1864 ret |= v3_dev_unhook_io(dev, VGA_SEQUENCER_ADDRESS);
1865 ret |= v3_dev_unhook_io(dev, VGA_SEQUENCER_DATA);
1867 /* CRT controller registers */
1868 ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_MONO);
1869 ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_COLOR);
1870 ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_DATA_MONO);
1871 ret |= v3_dev_unhook_io(dev, VGA_CRT_CONTROLLER_DATA_COLOR);
1873 /* graphics controller registers */
1874 ret |= v3_dev_unhook_io(dev, VGA_GRAPHICS_CONTROLLER_ADDRESS);
1875 ret |= v3_dev_unhook_io(dev, VGA_GRAPHICS_CONTROLLER_DATA);
1877 /* attribute controller registers */
1878 ret |= v3_dev_unhook_io(dev, VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE);
1879 ret |= v3_dev_unhook_io(dev, VGA_ATTRIBUTE_CONTROLLER_READ);
1881 /* video DAC palette registers */
1882 ret |= v3_dev_unhook_io(dev, VGA_DAC_WRITE_ADDR);
1883 ret |= v3_dev_unhook_io(dev, VGA_DAC_READ_ADDR);
1884 ret |= v3_dev_unhook_io(dev, VGA_DAC_DATA);
1885 ret |= v3_dev_unhook_io(dev, VGA_DAC_PIXEL_MASK);
1888 if (vga->host_cons) {
1889 v3_graphics_console_close(vga->host_cons);
1897 static struct v3_device_ops dev_ops = {
1898 .free = (int (*)(void *))free_vga,
1902 static int vga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1903 struct vga_internal *vga;
1907 char * dev_id = v3_cfg_val(cfg, "ID");
1908 char * passthrough = v3_cfg_val(cfg, "passthrough");
1909 char * hostframebuf = v3_cfg_val(cfg, "hostframebuf");
1911 PrintDebug("vga: init_device\n");
1913 vga = (struct vga_internal *)V3_Malloc(sizeof(struct vga_internal));
1916 PrintError("vga: cannot allocate\n");
1920 memset(vga, 0, sizeof(struct vga_internal));
1922 if (passthrough && strcasecmp(passthrough,"enable")==0) {
1923 PrintDebug("vga: enabling passthrough\n");
1924 vga->passthrough=true;
1925 vga->skip_next_passthrough_out=false;
1929 if (hostframebuf && strcasecmp(hostframebuf,"enable")==0) {
1930 struct v3_frame_buffer_spec req;
1932 PrintDebug("vga: enabling host frame buffer console (GRAPHICS_CONSOLE)\n");
1934 memset(&req,0,sizeof(struct v3_frame_buffer_spec));
1935 memset(&(vga->target_spec),0,sizeof(struct v3_frame_buffer_spec));
1937 req.height=VGA_MAXY;
1939 req.bytes_per_pixel=4;
1940 req.bits_per_channel=8;
1946 vga->host_cons = v3_graphics_console_open(vm,&req,&(vga->target_spec));
1948 if (!vga->host_cons) {
1949 PrintError("vga: unable to open host OS's graphics console\n");
1954 if (memcmp(&req,&(vga->target_spec),sizeof(req))) {
1955 PrintDebug("vga: warning: target spec differs from requested spec\n");
1956 PrintDebug("vga: request: %u by %u by %u with %u bpc and r,g,b at %u, %u, %u\n", req.width, req.height, req.bytes_per_pixel, req.bits_per_channel, req.red_offset, req.green_offset, req.blue_offset);
1957 PrintDebug("vga: response: %u by %u by %u with %u bpc and r,g,b at %u, %u, %u\n", vga->target_spec.width, vga->target_spec.height, vga->target_spec.bytes_per_pixel, vga->target_spec.bits_per_channel, vga->target_spec.red_offset, vga->target_spec.green_offset, vga->target_spec.blue_offset);
1962 if (!vga->passthrough && !vga->host_cons) {
1963 V3_Print("vga: neither passthrough nor host console are enabled - no way to display anything!\n");
1967 // No memory store is allocated since we will use a full memory hook
1968 // The VGA maps can be read as well as written
1969 // Reads also affect writes, since they are how you fill the latches
1971 // Now allocate the maps
1972 for (i=0;i<MAP_NUM;i++) {
1973 vga->map[i] = (vga_map) V3_VAddr((void*)V3_AllocPages(MAP_SIZE/4096));
1974 if (!(vga->map[i])) {
1975 PrintError("vga: cannot allocate maps\n");
1979 memset(vga->map[i],0,MAP_SIZE);
1982 struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, vga);
1985 PrintError("Could not attach device %s\n", dev_id);
1992 if (v3_hook_full_mem(vm, V3_MEM_CORE_ANY,
1993 MEM_REGION_START, MEM_REGION_END,
1997 PrintError("vga: memory book failed\n");
1998 v3_remove_device(dev);
2004 /* Miscelaneous registers */
2005 ret |= v3_dev_hook_io(dev, VGA_MISC_OUT_READ, &misc_out_read, NULL);
2006 // The following also covers VGA_INPUT_STAT0_READ
2007 ret |= v3_dev_hook_io(dev, VGA_MISC_OUT_WRITE, &input_stat0_read, &misc_out_write);
2008 // The following also covers VGA_FEATURE_CTRL_WRITE_MONO
2009 ret |= v3_dev_hook_io(dev, VGA_INPUT_STAT1_READ_MONO, &input_stat1_read, &feature_control_write);
2010 // The folowinn also covers VGA FEATURE_CONTROL_WRITE_COLOR
2011 ret |= v3_dev_hook_io(dev, VGA_INPUT_STAT1_READ_COLOR, &input_stat1_read, &feature_control_write);
2012 ret |= v3_dev_hook_io(dev, VGA_FEATURE_CONTROL_READ, &feature_control_read, NULL);
2014 ret |= v3_dev_hook_io(dev, VGA_VIDEO_SUBSYS_ENABLE, &video_subsys_enable_read, &video_subsys_enable_write);
2016 /* Sequencer registers */
2017 ret |= v3_dev_hook_io(dev, VGA_SEQUENCER_ADDRESS, &sequencer_address_read, &sequencer_address_write);
2018 ret |= v3_dev_hook_io(dev, VGA_SEQUENCER_DATA, &sequencer_data_read, &sequencer_data_write);
2020 /* CRT controller registers */
2021 ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_MONO, &crt_controller_address_read,&crt_controller_address_write);
2022 ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_ADDRESS_COLOR, &crt_controller_address_read,&crt_controller_address_write);
2023 ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_DATA_MONO, &crt_controller_data_read,&crt_controller_data_write);
2024 ret |= v3_dev_hook_io(dev, VGA_CRT_CONTROLLER_DATA_COLOR, &crt_controller_data_read,&crt_controller_data_write);
2026 /* graphics controller registers */
2027 ret |= v3_dev_hook_io(dev, VGA_GRAPHICS_CONTROLLER_ADDRESS, &graphics_controller_address_read,&graphics_controller_address_write);
2028 ret |= v3_dev_hook_io(dev, VGA_GRAPHICS_CONTROLLER_DATA, &graphics_controller_data_read,&graphics_controller_data_write);
2030 /* attribute controller registers */
2031 ret |= v3_dev_hook_io(dev, VGA_ATTRIBUTE_CONTROLLER_ADDRESS_AND_WRITE, &attribute_controller_address_read,&attribute_controller_address_and_data_write);
2032 ret |= v3_dev_hook_io(dev, VGA_ATTRIBUTE_CONTROLLER_READ, &attribute_controller_data_read,NULL);
2034 /* video DAC palette registers */
2035 ret |= v3_dev_hook_io(dev, VGA_DAC_WRITE_ADDR, &dac_write_address_read,&dac_write_address_write);
2036 ret |= v3_dev_hook_io(dev, VGA_DAC_READ_ADDR, &dac_read_address_read,&dac_read_address_write);
2037 ret |= v3_dev_hook_io(dev, VGA_DAC_DATA, &dac_data_read, &dac_data_write);
2038 ret |= v3_dev_hook_io(dev, VGA_DAC_PIXEL_MASK, &dac_pixel_mask_read, &dac_pixel_mask_write);
2041 PrintError("vga: Error allocating VGA I/O ports\n");
2042 v3_remove_device(dev);
2048 PrintDebug("vga: successfully added and initialized.\n");
2054 device_register("VGA", vga_init);