X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fvga.c;h=f9c4e9022600a8c0f1c1ee74fda84e2cf1ecd574;hb=c2218fcbc6023d380dbf88895fed679a8e14a210;hp=a99faae25a6d47e423def2e45bcbf7e1a1070044;hpb=7618b2492af387a660879432bcf2d741d546437e;p=palacios.git
diff --git a/palacios/src/devices/vga.c b/palacios/src/devices/vga.c
index a99faae..f9c4e90 100644
--- a/palacios/src/devices/vga.c
+++ b/palacios/src/devices/vga.c
@@ -831,7 +831,7 @@ static void render_text(struct vga_internal *vga, void *fb)
rtw = tw < fw/cw ? tw : fw/cw;
rth = th < fh/ch ? th : fh/ch;
-
+ PrintDebug("\n");
// Now let's scan by char across the whole thing
for (y=0;y
65536 ? 65536 : (mem_end-mem_start));
if (vga->vga_sequencer.vga_mem_mode.odd_even) {
- return (guest_addr-mem_start) % size;
+ // NOT odd/even mode
+ return (guest_addr-mem_start) % size;
} else {
// odd/even mode
- return ((guest_addr-mem_start) >> 1 ) % size;
+ return ((guest_addr-mem_start) >> 1 ) % size;
}
}
@@ -1154,23 +1157,26 @@ static uint8_t find_map_write(struct vga_internal *vga, addr_t guest_addr)
uint8_t mm = vga->vga_sequencer.vga_map_mask.val;
if (vga->vga_sequencer.vga_mem_mode.odd_even) {
- return mm;
+ // NOT odd/even mode
+ return mm;
} else {
- if (guest_addr & 0x1) {
- return mm & 0xa; // 0x1010
- } else {
- return mm & 0x5; // 0x0101
- }
+ // odd/even mode
+ if (guest_addr & 0x1) {
+ return mm & 0xa; // 0x1010
+ } else {
+ return mm & 0x5; // 0x0101
+ }
}
}
static uint8_t find_increment_write(struct vga_internal *vga, addr_t new_guest_addr)
{
- if (vga->vga_sequencer.vga_mem_mode.odd_even) {
- return 1;
- } else {
- return !(new_guest_addr & 0x1);
- }
+ if (vga->vga_sequencer.vga_mem_mode.odd_even) {
+ // NOT odd/even mode
+ return 1;
+ } else {
+ return !(new_guest_addr & 0x1);
+ }
}
@@ -1184,7 +1190,8 @@ static int vga_write(struct guest_info * core,
struct vm_device *dev = (struct vm_device *)priv_data;
struct vga_internal *vga = (struct vga_internal *) dev->private_data;
- PrintDebug("vga: memory write: guest_addr=0x%p len=%u\n",(void*)guest_addr, length);
+ PrintDebug("vga: memory write: guest_addr=0x%p len=%u write_mode=%d\n",(void*)guest_addr, length,
+ vga->vga_graphics_controller.vga_graphics_mode.write_mode);
if (vga->passthrough) {
PrintDebug("vga: passthrough write to 0x%p\n", V3_VAddr((void*)guest_addr));
@@ -1499,22 +1506,61 @@ static uint64_t find_offset_read(struct vga_internal *vga, addr_t guest_addr)
size=(mem_end-mem_start > 65536 ? 65536 : (mem_end-mem_start));
- if (!vga->vga_sequencer.vga_mem_mode.chain4) {
- return (guest_addr-mem_start) % size;
- } else {
- // chain4 mode
- return ((guest_addr - mem_start) >> 2) % size;
+ if (!vga->vga_sequencer.vga_mem_mode.odd_even) {
+ // odd/even mode takes priority
+ return ((guest_addr-mem_start) >> 1 ) % size;
+ }
+
+ if (vga->vga_sequencer.vga_mem_mode.chain4) {
+ // otherwise chain4 if it's on
+ return ((guest_addr - mem_start) >> 2) % size;
}
+
+ // and what you would expect if neither are on
+ return (guest_addr-mem_start) % size;
}
-static uint8_t find_increment_read(struct vga_internal *vga, addr_t new_guest_addr)
+// Given this address
+// which specific map should we write into?
+// Note that unlike with find_map_write, here we are looking
+// for a single map number, not a bit vector of maps to be selected
+static uint8_t find_map_read(struct vga_internal *vga, addr_t guest_addr)
{
+ uint64_t mem_start, mem_end;
+
+ mem_start=mem_end=0;
+
+ get_mem_region(vga, &mem_start, &mem_end);
+
+ if (!vga->vga_sequencer.vga_mem_mode.odd_even) {
+ // odd-even mode
+ // last bit tells us map 0 or 1
+ return (guest_addr-mem_start) & 0x1;
+ }
- if (vga->vga_sequencer.vga_mem_mode.chain4) {
- return !(new_guest_addr & 0x3);
- } else {
- return 1;
+ if (vga->vga_sequencer.vga_mem_mode.chain4) {
+ // otherwise chain4 if it's on
+ // last two bits
+ return (guest_addr - mem_start) & 0x3;
}
+
+ // and what you would expect if neither are on
+ // note that it's not the same as a write!
+ return vga->vga_graphics_controller.vga_read_map_select.map_select;
+}
+
+static uint8_t find_increment_read(struct vga_internal *vga, addr_t new_guest_addr)
+{
+
+ if (!vga->vga_sequencer.vga_mem_mode.odd_even) {
+ // odd-even mode
+ return !(new_guest_addr & 0x1);
+ }
+
+ if (vga->vga_sequencer.vga_mem_mode.chain4) {
+ return !(new_guest_addr & 0x3);
+ }
+ return 1;
}
@@ -1528,7 +1574,8 @@ static int vga_read(struct guest_info * core,
struct vga_internal *vga = (struct vga_internal *) dev->private_data;
- PrintDebug("vga: memory read: guest_addr=0x%p len=%u\n",(void*)guest_addr, length);
+ PrintDebug("vga: memory read: guest_addr=0x%p len=%u read_mode=%d\n",(void*)guest_addr, length,
+ vga->vga_graphics_controller.vga_graphics_mode.read_mode);
@@ -1538,46 +1585,29 @@ static int vga_read(struct guest_info * core,
switch (vga->vga_graphics_controller.vga_graphics_mode.read_mode) {
case 0: {
/* 0 - a byte from ONE of the 4 planes is returned;
- which plane is determined by Read Map Select (Read Map Select Register (Index 04h)) */
+ which plane is determined by Read Map Select (Read Map Select Register (Index 04h))
+ OR by odd/even chaining OR by chain4 chaining
+ */
uint8_t mapnum;
uint64_t offset;
+ uint32_t i;
-
- if (vga->vga_sequencer.vga_mem_mode.chain4) {
- uint32_t i;
- offset = find_offset_read(vga,guest_addr);
- // address bytes select the map
- for (i=0;imap[mapnum]+offset);
+ for (i=0;imap[mapnum]+offset);
+
+ vga->latch[mapnum] = *(vga->map[mapnum]+offset);
- // presumably all the latches are to be reloaded, not just the selected one?
- for (mapnum=0;mapnum<4;mapnum++) {
- vga->latch[mapnum] = *(vga->map[mapnum]+offset);
- }
- }
- } else {
- mapnum = vga->vga_graphics_controller.vga_read_map_select.map_select;
- offset = find_offset_read(vga,guest_addr);
-
- if (offset>=65536) {
- PrintError("vga: read to offset=%llu map=%u (%u bytes)\n",offset,mapnum,length);
- }
-
-#if DEBUG_DEEP_MEM
- PrintDebug("vga: mode 0 read, not-chain4, offset=0x%llx, mapnum=%u\n",offset,mapnum);
-#endif
- memcpy(dst,(vga->map[mapnum])+offset,length);
-
- // load the latches with the last item read
- for (mapnum=0;mapnum<4;mapnum++) {
- vga->latch[mapnum] = vga->map[mapnum][offset+length-1];
- }
}
+
}
break;
@@ -2645,9 +2675,10 @@ static int dac_pixel_mask_write(struct guest_info *core,
static int init_vga(struct vga_internal *vga)
{
- // TODO: startup spec of register contents, if any
- PrintError("vga: init_vga is UNIMPLEMTED\n");
- return 0;
+ // TODO: startup spec of register contents, if any
+ vga->vga_misc.vga_input_stat1.val = 0x1; // display enable, not in retrace
+
+ return 0;
}
static int free_vga(struct vga_internal *vga)
@@ -2814,12 +2845,17 @@ static int vga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
// Now allocate the maps
for (i=0;imap[i] = (vga_map) V3_VAddr((void*)V3_AllocPages(MAP_SIZE/4096));
- if (!(vga->map[i])) {
+ void *temp;
+
+ temp = (void*)V3_AllocPages(MAP_SIZE/4096);
+ if (!temp) {
PrintError("vga: cannot allocate maps\n");
free_vga(vga);
return -1;
}
+
+ vga->map[i] = (vga_map) V3_VAddr(temp);
+
memset(vga->map[i],0,MAP_SIZE);
}
|