summaryrefslogtreecommitdiff
path: root/src/VBox/Devices/Graphics/DevVGA.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/Graphics/DevVGA.cpp')
-rw-r--r--src/VBox/Devices/Graphics/DevVGA.cpp2602
1 files changed, 1334 insertions, 1268 deletions
diff --git a/src/VBox/Devices/Graphics/DevVGA.cpp b/src/VBox/Devices/Graphics/DevVGA.cpp
index 14164a0a..da28d9be 100644
--- a/src/VBox/Devices/Graphics/DevVGA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -45,7 +45,7 @@
*******************************************************************************/
/* WARNING!!! All defines that affect VGAState should be placed to DevVGA.h !!!
- * NEVER place them here as this would lead to VGAState inconsistency
+ * NEVER place them here as this would lead to VGASTATE inconsistency
* across different .cpp files !!!
*/
/** The size of the VGA GC mapping.
@@ -58,7 +58,7 @@
#define VGA_MAPPING_SIZE _512K
#ifdef VBOX_WITH_HGSMI
-#define PCIDEV_2_VGASTATE(pPciDev) ((VGAState *)((uintptr_t)pPciDev - RT_OFFSETOF(VGAState, Dev)))
+#define PCIDEV_2_VGASTATE(pPciDev) ((PVGASTATE)((uintptr_t)pPciDev - RT_OFFSETOF(VGASTATE, Dev)))
#endif /* VBOX_WITH_HGSMI */
/** Converts a vga adaptor state pointer to a device instance pointer. */
#define VGASTATE2DEVINS(pVgaState) ((pVgaState)->CTX_SUFF(pDevIns))
@@ -137,6 +137,10 @@
#include "VBoxDD.h"
#include "VBoxDD2.h"
+#ifdef VBOX_WITH_VMSVGA
+#include "DevVGA-SVGA.h"
+#include "vmsvga/svga_reg.h"
+#endif
/*******************************************************************************
* Structures and Typedefs *
@@ -236,7 +240,7 @@ typedef WINHDR *PWINHDR;
/** The BIOS boot menu text position, X. */
#define LOGO_F12TEXT_X 304
/** The BIOS boot menu text position, Y. */
-#define LOGO_F12TEXT_Y 464
+#define LOGO_F12TEXT_Y 460
/** Width of the "Press F12 to select boot device." bitmap.
Anything that exceeds the limit of F12BootText below is filled with
@@ -304,7 +308,7 @@ static const uint8_t g_abLogoF12BootText[] =
* @param pThis VGA instance data.
* @param offVRAM The VRAM offset of the page to set.
*/
-DECLINLINE(void) vga_set_dirty(VGAState *pThis, RTGCPHYS offVRAM)
+DECLINLINE(void) vga_set_dirty(PVGASTATE pThis, RTGCPHYS offVRAM)
{
AssertMsg(offVRAM < pThis->vram_size, ("offVRAM = %p, pThis->vram_size = %p\n", offVRAM, pThis->vram_size));
ASMBitSet(&pThis->au32DirtyBitmap[0], offVRAM >> PAGE_SHIFT);
@@ -319,7 +323,7 @@ DECLINLINE(void) vga_set_dirty(VGAState *pThis, RTGCPHYS offVRAM)
* @param pThis VGA instance data.
* @param offVRAM The VRAM offset of the page to check.
*/
-DECLINLINE(bool) vga_is_dirty(VGAState *pThis, RTGCPHYS offVRAM)
+DECLINLINE(bool) vga_is_dirty(PVGASTATE pThis, RTGCPHYS offVRAM)
{
AssertMsg(offVRAM < pThis->vram_size, ("offVRAM = %p, pThis->vram_size = %p\n", offVRAM, pThis->vram_size));
return ASMBitTest(&pThis->au32DirtyBitmap[0], offVRAM >> PAGE_SHIFT);
@@ -332,7 +336,7 @@ DECLINLINE(bool) vga_is_dirty(VGAState *pThis, RTGCPHYS offVRAM)
* @param offVRAMStart Offset into the VRAM buffer of the first page.
* @param offVRAMEnd Offset into the VRAM buffer of the last page - exclusive.
*/
-DECLINLINE(void) vga_reset_dirty(VGAState *pThis, RTGCPHYS offVRAMStart, RTGCPHYS offVRAMEnd)
+DECLINLINE(void) vga_reset_dirty(PVGASTATE pThis, RTGCPHYS offVRAMStart, RTGCPHYS offVRAMEnd)
{
Assert(offVRAMStart < pThis->vram_size);
Assert(offVRAMEnd <= pThis->vram_size);
@@ -462,7 +466,7 @@ static uint8_t expand4to8[16];
* Vertical Retrace bit is set when vertical retrace (vsync) is active.
* Unless the CRTC is horribly misprogrammed, vsync implies vblank.
*/
-static void vga_update_retrace_state(VGAState *s)
+static void vga_update_retrace_state(PVGASTATE pThis)
{
unsigned htotal_cclks, vtotal_lines, chars_per_sec;
unsigned hblank_start_cclk, hblank_end_cclk, hblank_width, hblank_skew_cclks;
@@ -470,21 +474,21 @@ static void vga_update_retrace_state(VGAState *s)
unsigned vblank_start_line, vblank_end, vblank_width;
unsigned char_dots, clock_doubled, clock_index;
const int clocks[] = {25175000, 28322000, 25175000, 25175000};
- vga_retrace_s *r = &s->retrace_state;
+ vga_retrace_s *r = &pThis->retrace_state;
/* For horizontal timings, we only care about the blanking start/end. */
- htotal_cclks = s->cr[0x00] + 5;
- hblank_start_cclk = s->cr[0x02];
- hblank_end_cclk = (s->cr[0x03] & 0x1f) + ((s->cr[0x05] & 0x80) >> 2);
- hblank_skew_cclks = (s->cr[0x03] >> 5) & 3;
+ htotal_cclks = pThis->cr[0x00] + 5;
+ hblank_start_cclk = pThis->cr[0x02];
+ hblank_end_cclk = (pThis->cr[0x03] & 0x1f) + ((pThis->cr[0x05] & 0x80) >> 2);
+ hblank_skew_cclks = (pThis->cr[0x03] >> 5) & 3;
/* For vertical timings, we need both the blanking start/end... */
- vtotal_lines = s->cr[0x06] + ((s->cr[0x07] & 1) << 8) + ((s->cr[0x07] & 0x20) << 4) + 2;
- vblank_start_line = s->cr[0x15] + ((s->cr[0x07] & 8) << 5) + ((s->cr[0x09] & 0x20) << 4);
- vblank_end = s->cr[0x16];
+ vtotal_lines = pThis->cr[0x06] + ((pThis->cr[0x07] & 1) << 8) + ((pThis->cr[0x07] & 0x20) << 4) + 2;
+ vblank_start_line = pThis->cr[0x15] + ((pThis->cr[0x07] & 8) << 5) + ((pThis->cr[0x09] & 0x20) << 4);
+ vblank_end = pThis->cr[0x16];
/* ... and the vertical retrace (vsync) start/end. */
- vsync_start_line = s->cr[0x10] + ((s->cr[0x07] & 4) << 6) + ((s->cr[0x07] & 0x80) << 2);
- vsync_end = s->cr[0x11] & 0xf;
+ vsync_start_line = pThis->cr[0x10] + ((pThis->cr[0x07] & 4) << 6) + ((pThis->cr[0x07] & 0x80) << 2);
+ vsync_end = pThis->cr[0x11] & 0xf;
/* Calculate the blanking and sync widths. The way it's implemented in
* the VGA with limited-width compare counters is quite a piece of work.
@@ -494,9 +498,9 @@ static void vga_update_retrace_state(VGAState *s)
vsync_width = (vsync_end - vsync_start_line) & 0xf; /* 4 bits */
/* Calculate the dot and character clock rates. */
- clock_doubled = (s->sr[0x01] >> 3) & 1; /* Clock doubling bit. */
- clock_index = (s->msr >> 2) & 3;
- char_dots = (s->sr[0x01] & 1) ? 8 : 9; /* 8 or 9 dots per cclk. */
+ clock_doubled = (pThis->sr[0x01] >> 3) & 1; /* Clock doubling bit. */
+ clock_index = (pThis->msr >> 2) & 3;
+ char_dots = (pThis->sr[0x01] & 1) ? 8 : 9; /* 8 or 9 dots per cclk. */
chars_per_sec = clocks[clock_index] / char_dots;
Assert(chars_per_sec); /* Can't possibly be zero. */
@@ -538,16 +542,16 @@ static void vga_update_retrace_state(VGAState *s)
Assert(r->h_total_ns); /* See h_total. */
}
-static uint8_t vga_retrace(VGAState *s)
+static uint8_t vga_retrace(PVGASTATE pThis)
{
- vga_retrace_s *r = &s->retrace_state;
+ vga_retrace_s *r = &pThis->retrace_state;
if (r->frame_ns) {
- uint8_t val = s->st01 & ~(ST01_V_RETRACE | ST01_DISP_ENABLE);
+ uint8_t val = pThis->st01 & ~(ST01_V_RETRACE | ST01_DISP_ENABLE);
unsigned cur_frame_ns, cur_line_ns;
uint64_t time_ns;
- time_ns = PDMDevHlpTMTimeVirtGetNano(VGASTATE2DEVINS(s));
+ time_ns = PDMDevHlpTMTimeVirtGetNano(VGASTATE2DEVINS(pThis));
/* Determine the time within the frame. */
cur_frame_ns = time_ns % r->frame_ns;
@@ -567,13 +571,13 @@ static uint8_t vga_retrace(VGAState *s)
}
return val;
} else {
- return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
+ return pThis->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
}
}
-int vga_ioport_invalid(VGAState *s, uint32_t addr)
+int vga_ioport_invalid(PVGASTATE pThis, uint32_t addr)
{
- if (s->msr & MSR_COLOR_EMULATION) {
+ if (pThis->msr & MSR_COLOR_EMULATION) {
/* Color */
return (addr >= 0x3b0 && addr <= 0x3bf);
} else {
@@ -582,80 +586,79 @@ int vga_ioport_invalid(VGAState *s, uint32_t addr)
}
}
-static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
+static uint32_t vga_ioport_read(PVGASTATE pThis, uint32_t addr)
{
- VGAState *s = (VGAState*)opaque;
int val, index;
/* check port range access depending on color/monochrome mode */
- if (vga_ioport_invalid(s, addr)) {
+ if (vga_ioport_invalid(pThis, addr)) {
val = 0xff;
Log(("VGA: following read ignored\n"));
} else {
switch(addr) {
case 0x3c0:
- if (s->ar_flip_flop == 0) {
- val = s->ar_index;
+ if (pThis->ar_flip_flop == 0) {
+ val = pThis->ar_index;
} else {
val = 0;
}
break;
case 0x3c1:
- index = s->ar_index & 0x1f;
+ index = pThis->ar_index & 0x1f;
if (index < 21)
- val = s->ar[index];
+ val = pThis->ar[index];
else
val = 0;
break;
case 0x3c2:
- val = s->st00;
+ val = pThis->st00;
break;
case 0x3c4:
- val = s->sr_index;
+ val = pThis->sr_index;
break;
case 0x3c5:
- val = s->sr[s->sr_index];
- Log2(("vga: read SR%x = 0x%02x\n", s->sr_index, val));
+ val = pThis->sr[pThis->sr_index];
+ Log2(("vga: read SR%x = 0x%02x\n", pThis->sr_index, val));
break;
case 0x3c7:
- val = s->dac_state;
+ val = pThis->dac_state;
break;
case 0x3c8:
- val = s->dac_write_index;
+ val = pThis->dac_write_index;
break;
case 0x3c9:
- val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
- if (++s->dac_sub_index == 3) {
- s->dac_sub_index = 0;
- s->dac_read_index++;
+ val = pThis->palette[pThis->dac_read_index * 3 + pThis->dac_sub_index];
+ if (++pThis->dac_sub_index == 3) {
+ pThis->dac_sub_index = 0;
+ pThis->dac_read_index++;
}
break;
case 0x3ca:
- val = s->fcr;
+ val = pThis->fcr;
break;
case 0x3cc:
- val = s->msr;
+ val = pThis->msr;
break;
case 0x3ce:
- val = s->gr_index;
+ val = pThis->gr_index;
break;
case 0x3cf:
- val = s->gr[s->gr_index];
- Log2(("vga: read GR%x = 0x%02x\n", s->gr_index, val));
+ val = pThis->gr[pThis->gr_index];
+ Log2(("vga: read GR%x = 0x%02x\n", pThis->gr_index, val));
break;
case 0x3b4:
case 0x3d4:
- val = s->cr_index;
+ val = pThis->cr_index;
break;
case 0x3b5:
case 0x3d5:
- val = s->cr[s->cr_index];
- Log2(("vga: read CR%x = 0x%02x\n", s->cr_index, val));
+ val = pThis->cr[pThis->cr_index];
+ Log2(("vga: read CR%x = 0x%02x\n", pThis->cr_index, val));
break;
case 0x3ba:
case 0x3da:
- val = s->st01 = vga_retrace(s);
- s->ar_flip_flop = 0;
+ val = pThis->st01 = vga_retrace(pThis);
+ pThis->ar_flip_flop = 0;
break;
default:
val = 0x00;
@@ -666,118 +669,117 @@ static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
return val;
}
-static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void vga_ioport_write(PVGASTATE pThis, uint32_t addr, uint32_t val)
{
- VGAState *s = (VGAState*)opaque;
int index;
Log(("VGA: write addr=0x%04x data=0x%02x\n", addr, val));
/* check port range access depending on color/monochrome mode */
- if (vga_ioport_invalid(s, addr)) {
+ if (vga_ioport_invalid(pThis, addr)) {
Log(("VGA: previous write ignored\n"));
return;
}
switch(addr) {
case 0x3c0:
- if (s->ar_flip_flop == 0) {
+ if (pThis->ar_flip_flop == 0) {
val &= 0x3f;
- s->ar_index = val;
+ pThis->ar_index = val;
} else {
- index = s->ar_index & 0x1f;
+ index = pThis->ar_index & 0x1f;
switch(index) {
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
- s->ar[index] = val & 0x3f;
+ pThis->ar[index] = val & 0x3f;
break;
case 0x10:
- s->ar[index] = val & ~0x10;
+ pThis->ar[index] = val & ~0x10;
break;
case 0x11:
- s->ar[index] = val;
+ pThis->ar[index] = val;
break;
case 0x12:
- s->ar[index] = val & ~0xc0;
+ pThis->ar[index] = val & ~0xc0;
break;
case 0x13:
- s->ar[index] = val & ~0xf0;
+ pThis->ar[index] = val & ~0xf0;
break;
case 0x14:
- s->ar[index] = val & ~0xf0;
+ pThis->ar[index] = val & ~0xf0;
break;
default:
break;
}
}
- s->ar_flip_flop ^= 1;
+ pThis->ar_flip_flop ^= 1;
break;
case 0x3c2:
- s->msr = val & ~0x10;
- if (s->fRealRetrace)
- vga_update_retrace_state(s);
- s->st00 = (s->st00 & ~0x10) | (0x90 >> ((val >> 2) & 0x3));
+ pThis->msr = val & ~0x10;
+ if (pThis->fRealRetrace)
+ vga_update_retrace_state(pThis);
+ pThis->st00 = (pThis->st00 & ~0x10) | (0x90 >> ((val >> 2) & 0x3));
break;
case 0x3c4:
- s->sr_index = val & 7;
+ pThis->sr_index = val & 7;
break;
case 0x3c5:
- Log2(("vga: write SR%x = 0x%02x\n", s->sr_index, val));
- s->sr[s->sr_index] = val & sr_mask[s->sr_index];
+ Log2(("vga: write SR%x = 0x%02x\n", pThis->sr_index, val));
+ pThis->sr[pThis->sr_index] = val & sr_mask[pThis->sr_index];
/* Allow SR07 to disable VBE. */
- if (s->sr_index == 0x07 && !(val & 1))
+ if (pThis->sr_index == 0x07 && !(val & 1))
{
- s->vbe_regs[VBE_DISPI_INDEX_ENABLE] = VBE_DISPI_DISABLED;
- s->bank_offset = 0;
+ pThis->vbe_regs[VBE_DISPI_INDEX_ENABLE] = VBE_DISPI_DISABLED;
+ pThis->bank_offset = 0;
}
- if (s->fRealRetrace && s->sr_index == 0x01)
- vga_update_retrace_state(s);
+ if (pThis->fRealRetrace && pThis->sr_index == 0x01)
+ vga_update_retrace_state(pThis);
#ifndef IN_RC
/* The VGA region is (could be) affected by this change; reset all aliases we've created. */
- if ( s->sr_index == 4 /* mode */
- || s->sr_index == 2 /* plane mask */)
+ if ( pThis->sr_index == 4 /* mode */
+ || pThis->sr_index == 2 /* plane mask */)
{
- if (s->fRemappedVGA)
+ if (pThis->fRemappedVGA)
{
- IOMMMIOResetRegion(PDMDevHlpGetVM(s->CTX_SUFF(pDevIns)), 0x000a0000);
- s->fRemappedVGA = false;
+ IOMMMIOResetRegion(PDMDevHlpGetVM(pThis->CTX_SUFF(pDevIns)), 0x000a0000);
+ pThis->fRemappedVGA = false;
}
}
#endif
break;
case 0x3c7:
- s->dac_read_index = val;
- s->dac_sub_index = 0;
- s->dac_state = 3;
+ pThis->dac_read_index = val;
+ pThis->dac_sub_index = 0;
+ pThis->dac_state = 3;
break;
case 0x3c8:
- s->dac_write_index = val;
- s->dac_sub_index = 0;
- s->dac_state = 0;
+ pThis->dac_write_index = val;
+ pThis->dac_sub_index = 0;
+ pThis->dac_state = 0;
break;
case 0x3c9:
- s->dac_cache[s->dac_sub_index] = val;
- if (++s->dac_sub_index == 3) {
- memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
- s->dac_sub_index = 0;
- s->dac_write_index++;
+ pThis->dac_cache[pThis->dac_sub_index] = val;
+ if (++pThis->dac_sub_index == 3) {
+ memcpy(&pThis->palette[pThis->dac_write_index * 3], pThis->dac_cache, 3);
+ pThis->dac_sub_index = 0;
+ pThis->dac_write_index++;
}
break;
case 0x3ce:
- s->gr_index = val & 0x0f;
+ pThis->gr_index = val & 0x0f;
break;
case 0x3cf:
- Log2(("vga: write GR%x = 0x%02x\n", s->gr_index, val));
- s->gr[s->gr_index] = val & gr_mask[s->gr_index];
+ Log2(("vga: write GR%x = 0x%02x\n", pThis->gr_index, val));
+ pThis->gr[pThis->gr_index] = val & gr_mask[pThis->gr_index];
#ifndef IN_RC
/* The VGA region is (could be) affected by this change; reset all aliases we've created. */
- if (s->gr_index == 6 /* memory map mode */)
+ if (pThis->gr_index == 6 /* memory map mode */)
{
- if (s->fRemappedVGA)
+ if (pThis->fRemappedVGA)
{
- IOMMMIOResetRegion(PDMDevHlpGetVM(s->CTX_SUFF(pDevIns)), 0x000a0000);
- s->fRemappedVGA = false;
+ IOMMMIOResetRegion(PDMDevHlpGetVM(pThis->CTX_SUFF(pDevIns)), 0x000a0000);
+ pThis->fRemappedVGA = false;
}
}
#endif
@@ -785,23 +787,23 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
case 0x3b4:
case 0x3d4:
- s->cr_index = val;
+ pThis->cr_index = val;
break;
case 0x3b5:
case 0x3d5:
- Log2(("vga: write CR%x = 0x%02x\n", s->cr_index, val));
+ Log2(("vga: write CR%x = 0x%02x\n", pThis->cr_index, val));
/* handle CR0-7 protection */
- if ((s->cr[0x11] & 0x80) && s->cr_index <= 7) {
+ if ((pThis->cr[0x11] & 0x80) && pThis->cr_index <= 7) {
/* can always write bit 4 of CR7 */
- if (s->cr_index == 7)
- s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
+ if (pThis->cr_index == 7)
+ pThis->cr[7] = (pThis->cr[7] & ~0x10) | (val & 0x10);
return;
}
- s->cr[s->cr_index] = val;
+ pThis->cr[pThis->cr_index] = val;
- if (s->fRealRetrace) {
+ if (pThis->fRealRetrace) {
/* The following registers are only updated during a mode set. */
- switch(s->cr_index) {
+ switch(pThis->cr_index) {
case 0x00:
case 0x02:
case 0x03:
@@ -813,36 +815,34 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
case 0x11:
case 0x15:
case 0x16:
- vga_update_retrace_state(s);
+ vga_update_retrace_state(pThis);
break;
}
}
break;
case 0x3ba:
case 0x3da:
- s->fcr = val & 0x10;
+ pThis->fcr = val & 0x10;
break;
}
}
#ifdef CONFIG_BOCHS_VBE
-static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
+static uint32_t vbe_ioport_read_index(PVGASTATE pThis, uint32_t addr)
{
- VGAState *s = (VGAState*)opaque;
- uint32_t val = s->vbe_index;
+ uint32_t val = pThis->vbe_index;
NOREF(addr);
return val;
}
-static uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
+static uint32_t vbe_ioport_read_data(PVGASTATE pThis, uint32_t addr)
{
- VGAState *s = (VGAState*)opaque;
uint32_t val;
NOREF(addr);
- if (s->vbe_index < VBE_DISPI_INDEX_NB) {
- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) {
- switch(s->vbe_index) {
+ if (pThis->vbe_index < VBE_DISPI_INDEX_NB) {
+ if (pThis->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) {
+ switch(pThis->vbe_index) {
/* XXX: do not hardcode ? */
case VBE_DISPI_INDEX_XRES:
val = VBE_DISPI_MAX_XRES;
@@ -854,26 +854,26 @@ static uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
val = VBE_DISPI_MAX_BPP;
break;
default:
- Assert(s->vbe_index < VBE_DISPI_INDEX_NB);
- val = s->vbe_regs[s->vbe_index];
+ Assert(pThis->vbe_index < VBE_DISPI_INDEX_NB);
+ val = pThis->vbe_regs[pThis->vbe_index];
break;
}
} else {
- switch(s->vbe_index) {
+ switch(pThis->vbe_index) {
case VBE_DISPI_INDEX_VBOX_VIDEO:
/* Reading from the port means that the old additions are requesting the number of monitors. */
val = 1;
break;
default:
- Assert(s->vbe_index < VBE_DISPI_INDEX_NB);
- val = s->vbe_regs[s->vbe_index];
+ Assert(pThis->vbe_index < VBE_DISPI_INDEX_NB);
+ val = pThis->vbe_regs[pThis->vbe_index];
break;
}
}
} else {
val = 0;
}
- Log(("VBE: read index=0x%x val=0x%x\n", s->vbe_index, val));
+ Log(("VBE: read index=0x%x val=0x%x\n", pThis->vbe_index, val));
return val;
}
@@ -912,106 +912,105 @@ static uint32_t calc_line_width(uint16_t bpp, uint32_t pitch)
}
#endif
-static void recalculate_data(VGAState *s, bool fVirtHeightOnly)
+static void recalculate_data(PVGASTATE pThis, bool fVirtHeightOnly)
{
- uint16_t cBPP = s->vbe_regs[VBE_DISPI_INDEX_BPP];
- uint16_t cVirtWidth = s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH];
- uint16_t cX = s->vbe_regs[VBE_DISPI_INDEX_XRES];
+ uint16_t cBPP = pThis->vbe_regs[VBE_DISPI_INDEX_BPP];
+ uint16_t cVirtWidth = pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH];
+ uint16_t cX = pThis->vbe_regs[VBE_DISPI_INDEX_XRES];
if (!cBPP || !cX)
return; /* Not enough data has been set yet. */
uint32_t cbLinePitch = calc_line_pitch(cBPP, cVirtWidth);
if (!cbLinePitch)
cbLinePitch = calc_line_pitch(cBPP, cX);
Assert(cbLinePitch != 0);
- uint32_t cVirtHeight = s->vram_size / cbLinePitch;
+ uint32_t cVirtHeight = pThis->vram_size / cbLinePitch;
if (!fVirtHeightOnly)
{
- uint16_t offX = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
- uint16_t offY = s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
+ uint16_t offX = pThis->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
+ uint16_t offY = pThis->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
uint32_t offStart = cbLinePitch * offY;
if (cBPP == 4)
offStart += offX >> 1;
else
offStart += offX * ((cBPP + 7) >> 3);
offStart >>= 2;
- s->vbe_line_offset = RT_MIN(cbLinePitch, s->vram_size);
- s->vbe_start_addr = RT_MIN(offStart, s->vram_size);
+ pThis->vbe_line_offset = RT_MIN(cbLinePitch, pThis->vram_size);
+ pThis->vbe_start_addr = RT_MIN(offStart, pThis->vram_size);
}
/* The VBE_DISPI_INDEX_VIRT_HEIGHT is used to prevent setting resolution bigger than VRAM permits
* it is used instead of VBE_DISPI_INDEX_YRES *only* in case
- * s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] < s->vbe_regs[VBE_DISPI_INDEX_YRES]
- * We can not simply do s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = cVirtHeight since
+ * pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] < pThis->vbe_regs[VBE_DISPI_INDEX_YRES]
+ * We can not simply do pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = cVirtHeight since
* the cVirtHeight we calculated can exceed the 16bit value range
- * instead we'll check if it's bigger than s->vbe_regs[VBE_DISPI_INDEX_YRES], and if yes,
- * assign the s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] with a dummy UINT16_MAX value
- * that is always bigger than s->vbe_regs[VBE_DISPI_INDEX_YRES]
- * to just ensure the s->vbe_regs[VBE_DISPI_INDEX_YRES] is always used */
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = (cVirtHeight >= (uint32_t)s->vbe_regs[VBE_DISPI_INDEX_YRES]) ? UINT16_MAX : (uint16_t)cVirtHeight;
+ * instead we'll check if it's bigger than pThis->vbe_regs[VBE_DISPI_INDEX_YRES], and if yes,
+ * assign the pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] with a dummy UINT16_MAX value
+ * that is always bigger than pThis->vbe_regs[VBE_DISPI_INDEX_YRES]
+ * to just ensure the pThis->vbe_regs[VBE_DISPI_INDEX_YRES] is always used */
+ pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = (cVirtHeight >= (uint32_t)pThis->vbe_regs[VBE_DISPI_INDEX_YRES])
+ ? UINT16_MAX : (uint16_t)cVirtHeight;
}
-static void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
+static void vbe_ioport_write_index(PVGASTATE pThis, uint32_t addr, uint32_t val)
{
- VGAState *s = (VGAState*)opaque;
- s->vbe_index = val;
+ pThis->vbe_index = val;
NOREF(addr);
}
-static int vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
+static int vbe_ioport_write_data(PVGASTATE pThis, uint32_t addr, uint32_t val)
{
- VGAState *s = (VGAState*)opaque;
uint32_t max_bank;
NOREF(addr);
- if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
+ if (pThis->vbe_index <= VBE_DISPI_INDEX_NB) {
bool fRecalculate = false;
- Log(("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val));
- switch(s->vbe_index) {
+ Log(("VBE: write index=0x%x val=0x%x\n", pThis->vbe_index, val));
+ switch(pThis->vbe_index) {
case VBE_DISPI_INDEX_ID:
if (val == VBE_DISPI_ID0 ||
val == VBE_DISPI_ID1 ||
val == VBE_DISPI_ID2 ||
val == VBE_DISPI_ID3 ||
val == VBE_DISPI_ID4) {
- s->vbe_regs[s->vbe_index] = val;
+ pThis->vbe_regs[pThis->vbe_index] = val;
}
if (val == VBE_DISPI_ID_VBOX_VIDEO) {
- s->vbe_regs[s->vbe_index] = val;
+ pThis->vbe_regs[pThis->vbe_index] = val;
} else if (val == VBE_DISPI_ID_ANYX) {
- s->vbe_regs[s->vbe_index] = val;
+ pThis->vbe_regs[pThis->vbe_index] = val;
}
#ifdef VBOX_WITH_HGSMI
else if (val == VBE_DISPI_ID_HGSMI) {
- s->vbe_regs[s->vbe_index] = val;
+ pThis->vbe_regs[pThis->vbe_index] = val;
}
#endif /* VBOX_WITH_HGSMI */
break;
case VBE_DISPI_INDEX_XRES:
if (val <= VBE_DISPI_MAX_XRES)
{
- s->vbe_regs[s->vbe_index] = val;
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = val;
+ pThis->vbe_regs[pThis->vbe_index] = val;
+ pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = val;
fRecalculate = true;
}
break;
case VBE_DISPI_INDEX_YRES:
if (val <= VBE_DISPI_MAX_YRES)
- s->vbe_regs[s->vbe_index] = val;
+ pThis->vbe_regs[pThis->vbe_index] = val;
break;
case VBE_DISPI_INDEX_BPP:
if (val == 0)
val = 8;
if (val == 4 || val == 8 || val == 15 ||
val == 16 || val == 24 || val == 32) {
- s->vbe_regs[s->vbe_index] = val;
+ pThis->vbe_regs[pThis->vbe_index] = val;
fRecalculate = true;
}
break;
case VBE_DISPI_INDEX_BANK:
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] <= 4)
- max_bank = s->vbe_bank_max >> 2; /* Each bank really covers 256K */
+ if (pThis->vbe_regs[VBE_DISPI_INDEX_BPP] <= 4)
+ max_bank = pThis->vbe_bank_max >> 2; /* Each bank really covers 256K */
else
- max_bank = s->vbe_bank_max;
+ max_bank = pThis->vbe_bank_max;
/* Old software may pass garbage in the high byte of bank. If the maximum
* bank fits into a single byte, toss the high byte the user supplied.
*/
@@ -1019,15 +1018,15 @@ static int vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
val &= 0xff;
if (val > max_bank)
val = max_bank;
- s->vbe_regs[s->vbe_index] = val;
- s->bank_offset = (val << 16);
+ pThis->vbe_regs[pThis->vbe_index] = val;
+ pThis->bank_offset = (val << 16);
#ifndef IN_RC
/* The VGA region is (could be) affected by this change; reset all aliases we've created. */
- if (s->fRemappedVGA)
+ if (pThis->fRemappedVGA)
{
- IOMMMIOResetRegion(PDMDevHlpGetVM(s->CTX_SUFF(pDevIns)), 0x000a0000);
- s->fRemappedVGA = false;
+ IOMMMIOResetRegion(PDMDevHlpGetVM(pThis->CTX_SUFF(pDevIns)), 0x000a0000);
+ pThis->fRemappedVGA = false;
}
#endif
break;
@@ -1037,102 +1036,105 @@ static int vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
return VINF_IOM_R3_IOPORT_WRITE;
#else
if ((val & VBE_DISPI_ENABLED) &&
- !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
+ !(pThis->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
int h, shift_control;
/* Check the values before we screw up with a resolution which is too big or small. */
- size_t cb = s->vbe_regs[VBE_DISPI_INDEX_XRES];
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
- cb = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
+ size_t cb = pThis->vbe_regs[VBE_DISPI_INDEX_XRES];
+ if (pThis->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
+ cb = pThis->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
else
- cb = s->vbe_regs[VBE_DISPI_INDEX_XRES] * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
- cb *= s->vbe_regs[VBE_DISPI_INDEX_YRES];
- uint16_t cVirtWidth = s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH];
+ cb = pThis->vbe_regs[VBE_DISPI_INDEX_XRES] * ((pThis->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
+ cb *= pThis->vbe_regs[VBE_DISPI_INDEX_YRES];
+ uint16_t cVirtWidth = pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH];
if (!cVirtWidth)
- cVirtWidth = s->vbe_regs[VBE_DISPI_INDEX_XRES];
+ cVirtWidth = pThis->vbe_regs[VBE_DISPI_INDEX_XRES];
if ( !cVirtWidth
- || !s->vbe_regs[VBE_DISPI_INDEX_YRES]
- || cb > s->vram_size)
+ || !pThis->vbe_regs[VBE_DISPI_INDEX_YRES]
+ || cb > pThis->vram_size)
{
AssertMsgFailed(("VIRT WIDTH=%d YRES=%d cb=%d vram_size=%d\n",
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH], s->vbe_regs[VBE_DISPI_INDEX_YRES], cb, s->vram_size));
+ pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH], pThis->vbe_regs[VBE_DISPI_INDEX_YRES], cb, pThis->vram_size));
return VINF_SUCCESS; /* Note: silent failure like before */
}
/* When VBE interface is enabled, it is reset. */
- s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
- s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
+ pThis->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
+ pThis->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
fRecalculate = true;
/* clear the screen (should be done in BIOS) */
if (!(val & VBE_DISPI_NOCLEARMEM)) {
- uint16_t cY = RT_MIN(s->vbe_regs[VBE_DISPI_INDEX_YRES],
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT]);
- uint16_t cbLinePitch = s->vbe_line_offset;
- memset(s->CTX_SUFF(vram_ptr), 0,
+ uint16_t cY = RT_MIN(pThis->vbe_regs[VBE_DISPI_INDEX_YRES],
+ pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT]);
+ uint16_t cbLinePitch = pThis->vbe_line_offset;
+ memset(pThis->CTX_SUFF(vram_ptr), 0,
cY * cbLinePitch);
}
/* we initialize the VGA graphic mode (should be done
in BIOS) */
- s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */
- s->cr[0x17] |= 3; /* no CGA modes */
- s->cr[0x13] = s->vbe_line_offset >> 3;
+ pThis->gr[0x06] = (pThis->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */
+ pThis->cr[0x17] |= 3; /* no CGA modes */
+ pThis->cr[0x13] = pThis->vbe_line_offset >> 3;
/* width */
- s->cr[0x01] = (cVirtWidth >> 3) - 1;
+ pThis->cr[0x01] = (cVirtWidth >> 3) - 1;
/* height (only meaningful if < 1024) */
- h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
- s->cr[0x12] = h;
- s->cr[0x07] = (s->cr[0x07] & ~0x42) |
+ h = pThis->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
+ pThis->cr[0x12] = h;
+ pThis->cr[0x07] = (pThis->cr[0x07] & ~0x42) |
((h >> 7) & 0x02) | ((h >> 3) & 0x40);
/* line compare to 1023 */
- s->cr[0x18] = 0xff;
- s->cr[0x07] |= 0x10;
- s->cr[0x09] |= 0x40;
+ pThis->cr[0x18] = 0xff;
+ pThis->cr[0x07] |= 0x10;
+ pThis->cr[0x09] |= 0x40;
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
+ if (pThis->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
shift_control = 0;
- s->sr[0x01] &= ~8; /* no double line */
+ pThis->sr[0x01] &= ~8; /* no double line */
} else {
shift_control = 2;
- s->sr[4] |= 0x08; /* set chain 4 mode */
- s->sr[2] |= 0x0f; /* activate all planes */
+ pThis->sr[4] |= 0x08; /* set chain 4 mode */
+ pThis->sr[2] |= 0x0f; /* activate all planes */
/* Indicate non-VGA mode in SR07. */
- s->sr[7] |= 1;
+ pThis->sr[7] |= 1;
}
- s->gr[0x05] = (s->gr[0x05] & ~0x60) | (shift_control << 5);
- s->cr[0x09] &= ~0x9f; /* no double scan */
+ pThis->gr[0x05] = (pThis->gr[0x05] & ~0x60) | (shift_control << 5);
+ pThis->cr[0x09] &= ~0x9f; /* no double scan */
/* sunlover 30.05.2007
* The ar_index remains with bit 0x20 cleared after a switch from fullscreen
* DOS mode on Windows XP guest. That leads to GMODE_BLANK in vga_update_display.
* But the VBE mode is graphics, so not a blank anymore.
*/
- s->ar_index |= 0x20;
+ pThis->ar_index |= 0x20;
} else {
/* XXX: the bios should do that */
/* sunlover 21.12.2006
* Here is probably more to reset. When this was executed in GC
* then the *update* functions could not detect a mode change.
- * Or may be these update function should take the s->vbe_regs[s->vbe_index]
+ * Or may be these update function should take the pThis->vbe_regs[pThis->vbe_index]
* into account when detecting a mode change.
*
* The 'mode reset not detected' problem is now fixed by executing the
* VBE_DISPI_INDEX_ENABLE case always in RING3 in order to call the
* LFBChange callback.
*/
- s->bank_offset = 0;
+ pThis->bank_offset = 0;
}
- s->vbe_regs[s->vbe_index] = val;
+ pThis->vbe_regs[pThis->vbe_index] = val;
/*
* LFB video mode is either disabled or changed. This notification
* is used by the display to disable VBVA.
*/
- s->pDrv->pfnLFBModeChange(s->pDrv, (val & VBE_DISPI_ENABLED) != 0);
+ pThis->pDrv->pfnLFBModeChange(pThis->pDrv, (val & VBE_DISPI_ENABLED) != 0);
+#ifdef VBOX_WITH_HGSMI
+ VBVAPause(pThis, (val & VBE_DISPI_ENABLED) == 0);
+#endif /* VBOX_WITH_HGSMI */
/* The VGA region is (could be) affected by this change; reset all aliases we've created. */
- if (s->fRemappedVGA)
+ if (pThis->fRemappedVGA)
{
- IOMMMIOResetRegion(PDMDevHlpGetVM(s->CTX_SUFF(pDevIns)), 0x000a0000);
- s->fRemappedVGA = false;
+ IOMMMIOResetRegion(PDMDevHlpGetVM(pThis->CTX_SUFF(pDevIns)), 0x000a0000);
+ pThis->fRemappedVGA = false;
}
break;
#endif /* IN_RING3 */
@@ -1140,7 +1142,7 @@ static int vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
case VBE_DISPI_INDEX_X_OFFSET:
case VBE_DISPI_INDEX_Y_OFFSET:
{
- s->vbe_regs[s->vbe_index] = val;
+ pThis->vbe_regs[pThis->vbe_index] = val;
fRecalculate = true;
}
break;
@@ -1151,15 +1153,15 @@ static int vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
/* Changes in the VGA device are minimal. The device is bypassed. The driver does all work. */
if (val == VBOX_VIDEO_DISABLE_ADAPTER_MEMORY)
{
- s->pDrv->pfnProcessAdapterData(s->pDrv, NULL, 0);
+ pThis->pDrv->pfnProcessAdapterData(pThis->pDrv, NULL, 0);
}
else if (val == VBOX_VIDEO_INTERPRET_ADAPTER_MEMORY)
{
- s->pDrv->pfnProcessAdapterData(s->pDrv, s->CTX_SUFF(vram_ptr), s->vram_size);
+ pThis->pDrv->pfnProcessAdapterData(pThis->pDrv, pThis->CTX_SUFF(vram_ptr), pThis->vram_size);
}
else if ((val & 0xFFFF0000) == VBOX_VIDEO_INTERPRET_DISPLAY_MEMORY_BASE)
{
- s->pDrv->pfnProcessDisplayData(s->pDrv, s->CTX_SUFF(vram_ptr), val & 0xFFFF);
+ pThis->pDrv->pfnProcessDisplayData(pThis->pDrv, pThis->CTX_SUFF(vram_ptr), val & 0xFFFF);
}
#endif /* IN_RING3 */
break;
@@ -1168,7 +1170,7 @@ static int vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
}
if (fRecalculate)
{
- recalculate_data(s, false);
+ recalculate_data(pThis, false);
}
}
return VINF_SUCCESS;
@@ -1176,15 +1178,14 @@ static int vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
#endif
/* called for accesses between 0xa0000 and 0xc0000 */
-static uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr, int *prc)
+static uint32_t vga_mem_readb(PVGASTATE pThis, target_phys_addr_t addr, int *prc)
{
- VGAState *s = (VGAState*)opaque;
int memory_map_mode, plane;
uint32_t ret;
Log3(("vga: read [0x%x] -> ", addr));
/* convert to VGA memory offset */
- memory_map_mode = (s->gr[6] >> 2) & 3;
+ memory_map_mode = (pThis->gr[6] >> 2) & 3;
#ifndef IN_RC
RTGCPHYS GCPhys = addr; /* save original address */
#endif
@@ -1196,7 +1197,7 @@ static uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr, int *prc)
case 1:
if (addr >= 0x10000)
return 0xff;
- addr += s->bank_offset;
+ addr += pThis->bank_offset;
break;
case 2:
addr -= 0x10000;
@@ -1211,42 +1212,43 @@ static uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr, int *prc)
break;
}
- if (s->sr[4] & 0x08) {
+ if (pThis->sr[4] & 0x08) {
/* chain 4 mode : simplest access */
# ifndef IN_RC
/* If all planes are accessible, then map the page to the frame buffer and make it writable. */
- if ( (s->sr[2] & 3) == 3
- && !vga_is_dirty(s, addr))
+ if ( (pThis->sr[2] & 3) == 3
+ && !vga_is_dirty(pThis, addr))
{
/** @todo only allow read access (doesn't work now) */
- STAM_COUNTER_INC(&s->StatMapPage);
- IOMMMIOMapMMIO2Page(PDMDevHlpGetVM(s->CTX_SUFF(pDevIns)), GCPhys, s->GCPhysVRAM + addr, X86_PTE_RW|X86_PTE_P);
+ STAM_COUNTER_INC(&pThis->StatMapPage);
+ IOMMMIOMapMMIO2Page(PDMDevHlpGetVM(pThis->CTX_SUFF(pDevIns)), GCPhys,
+ pThis->GCPhysVRAM + addr, X86_PTE_RW | X86_PTE_P);
/* Set as dirty as write accesses won't be noticed now. */
- vga_set_dirty(s, addr);
- s->fRemappedVGA = true;
+ vga_set_dirty(pThis, addr);
+ pThis->fRemappedVGA = true;
}
# endif /* IN_RC */
- VERIFY_VRAM_READ_OFF_RETURN(s, addr, *prc);
- ret = s->CTX_SUFF(vram_ptr)[addr];
- } else if (!(s->sr[4] & 0x04)) { /* Host access is controlled by SR4, not GR5! */
+ VERIFY_VRAM_READ_OFF_RETURN(pThis, addr, *prc);
+ ret = pThis->CTX_SUFF(vram_ptr)[addr];
+ } else if (!(pThis->sr[4] & 0x04)) { /* Host access is controlled by SR4, not GR5! */
/* odd/even mode (aka text mode mapping) */
- plane = (s->gr[4] & 2) | (addr & 1);
+ plane = (pThis->gr[4] & 2) | (addr & 1);
/* See the comment for a similar line in vga_mem_writeb. */
RTGCPHYS off = ((addr & ~1) << 2) | plane;
- VERIFY_VRAM_READ_OFF_RETURN(s, off, *prc);
- ret = s->CTX_SUFF(vram_ptr)[off];
+ VERIFY_VRAM_READ_OFF_RETURN(pThis, off, *prc);
+ ret = pThis->CTX_SUFF(vram_ptr)[off];
} else {
/* standard VGA latched access */
- VERIFY_VRAM_READ_OFF_RETURN(s, addr, *prc);
- s->latch = ((uint32_t *)s->CTX_SUFF(vram_ptr))[addr];
+ VERIFY_VRAM_READ_OFF_RETURN(pThis, addr, *prc);
+ pThis->latch = ((uint32_t *)pThis->CTX_SUFF(vram_ptr))[addr];
- if (!(s->gr[5] & 0x08)) {
+ if (!(pThis->gr[5] & 0x08)) {
/* read mode 0 */
- plane = s->gr[4];
- ret = GET_PLANE(s->latch, plane);
+ plane = pThis->gr[4];
+ ret = GET_PLANE(pThis->latch, plane);
} else {
/* read mode 1 */
- ret = (s->latch ^ mask16[s->gr[2]]) & mask16[s->gr[7]];
+ ret = (pThis->latch ^ mask16[pThis->gr[2]]) & mask16[pThis->gr[7]];
ret |= ret >> 16;
ret |= ret >> 8;
ret = (~ret) & 0xff;
@@ -1257,15 +1259,14 @@ static uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr, int *prc)
}
/* called for accesses between 0xa0000 and 0xc0000 */
-static int vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static int vga_mem_writeb(PVGASTATE pThis, target_phys_addr_t addr, uint32_t val)
{
- VGAState *s = (VGAState*)opaque;
int memory_map_mode, plane, write_mode, b, func_select, mask;
uint32_t write_mask, bit_mask, set_mask;
Log3(("vga: [0x%x] = 0x%02x\n", addr, val));
/* convert to VGA memory offset */
- memory_map_mode = (s->gr[6] >> 2) & 3;
+ memory_map_mode = (pThis->gr[6] >> 2) & 3;
#ifndef IN_RC
RTGCPHYS GCPhys = addr; /* save original address */
#endif
@@ -1277,7 +1278,7 @@ static int vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
case 1:
if (addr >= 0x10000)
return VINF_SUCCESS;
- addr += s->bank_offset;
+ addr += pThis->bank_offset;
break;
case 2:
addr -= 0x10000;
@@ -1292,122 +1293,123 @@ static int vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
break;
}
- if (s->sr[4] & 0x08) {
+ if (pThis->sr[4] & 0x08) {
/* chain 4 mode : simplest access */
plane = addr & 3;
mask = (1 << plane);
- if (s->sr[2] & mask) {
+ if (pThis->sr[2] & mask) {
# ifndef IN_RC
/* If all planes are accessible, then map the page to the frame buffer and make it writable. */
- if ( (s->sr[2] & 3) == 3
- && !vga_is_dirty(s, addr))
+ if ( (pThis->sr[2] & 3) == 3
+ && !vga_is_dirty(pThis, addr))
{
- STAM_COUNTER_INC(&s->StatMapPage);
- IOMMMIOMapMMIO2Page(PDMDevHlpGetVM(s->CTX_SUFF(pDevIns)), GCPhys, s->GCPhysVRAM + addr, X86_PTE_RW | X86_PTE_P);
- s->fRemappedVGA = true;
+ STAM_COUNTER_INC(&pThis->StatMapPage);
+ IOMMMIOMapMMIO2Page(PDMDevHlpGetVM(pThis->CTX_SUFF(pDevIns)), GCPhys,
+ pThis->GCPhysVRAM + addr, X86_PTE_RW | X86_PTE_P);
+ pThis->fRemappedVGA = true;
}
# endif /* IN_RC */
- VERIFY_VRAM_WRITE_OFF_RETURN(s, addr);
- s->CTX_SUFF(vram_ptr)[addr] = val;
+ VERIFY_VRAM_WRITE_OFF_RETURN(pThis, addr);
+ pThis->CTX_SUFF(vram_ptr)[addr] = val;
Log3(("vga: chain4: [0x%x]\n", addr));
- s->plane_updated |= mask; /* only used to detect font change */
- vga_set_dirty(s, addr);
+ pThis->plane_updated |= mask; /* only used to detect font change */
+ vga_set_dirty(pThis, addr);
}
- } else if (!(s->sr[4] & 0x04)) { /* Host access is controlled by SR4, not GR5! */
+ } else if (!(pThis->sr[4] & 0x04)) { /* Host access is controlled by SR4, not GR5! */
/* odd/even mode (aka text mode mapping) */
- plane = (s->gr[4] & 2) | (addr & 1);
+ plane = (pThis->gr[4] & 2) | (addr & 1);
mask = (1 << plane);
- if (s->sr[2] & mask) {
+ if (pThis->sr[2] & mask) {
/* 'addr' is offset in a plane, bit 0 selects the plane.
* Mask the bit 0, convert plane index to vram offset,
* that is multiply by the number of planes,
* and select the plane byte in the vram offset.
*/
addr = ((addr & ~1) << 2) | plane;
- VERIFY_VRAM_WRITE_OFF_RETURN(s, addr);
- s->CTX_SUFF(vram_ptr)[addr] = val;
+ VERIFY_VRAM_WRITE_OFF_RETURN(pThis, addr);
+ pThis->CTX_SUFF(vram_ptr)[addr] = val;
Log3(("vga: odd/even: [0x%x]\n", addr));
- s->plane_updated |= mask; /* only used to detect font change */
- vga_set_dirty(s, addr);
+ pThis->plane_updated |= mask; /* only used to detect font change */
+ vga_set_dirty(pThis, addr);
}
} else {
/* standard VGA latched access */
- VERIFY_VRAM_WRITE_OFF_RETURN(s, addr * 4 + 3);
+ VERIFY_VRAM_WRITE_OFF_RETURN(pThis, addr * 4 + 3);
#ifdef IN_RING0
- if (((++s->cLatchAccesses) & s->uMaskLatchAccess) == s->uMaskLatchAccess)
+ if (((++pThis->cLatchAccesses) & pThis->uMaskLatchAccess) == pThis->uMaskLatchAccess)
{
static uint32_t const s_aMask[5] = { 0x3ff, 0x1ff, 0x7f, 0x3f, 0x1f};
static uint64_t const s_aDelta[5] = {10000000, 5000000, 2500000, 1250000, 625000};
- if (PDMDevHlpCanEmulateIoBlock(s->CTX_SUFF(pDevIns)))
+ if (PDMDevHlpCanEmulateIoBlock(pThis->CTX_SUFF(pDevIns)))
{
uint64_t u64CurTime = RTTimeSystemNanoTS();
/* About 1000 (or more) accesses per 10 ms will trigger a reschedule
* to the recompiler
*/
- if (u64CurTime - s->u64LastLatchedAccess < s_aDelta[s->iMask])
+ if (u64CurTime - pThis->u64LastLatchedAccess < s_aDelta[pThis->iMask])
{
- s->u64LastLatchedAccess = 0;
- s->iMask = RT_MIN(s->iMask + 1U, RT_ELEMENTS(s_aMask) - 1U);
- s->uMaskLatchAccess = s_aMask[s->iMask];
- s->cLatchAccesses = s->uMaskLatchAccess - 1;
+ pThis->u64LastLatchedAccess = 0;
+ pThis->iMask = RT_MIN(pThis->iMask + 1U, RT_ELEMENTS(s_aMask) - 1U);
+ pThis->uMaskLatchAccess = s_aMask[pThis->iMask];
+ pThis->cLatchAccesses = pThis->uMaskLatchAccess - 1;
return VINF_EM_RAW_EMULATE_IO_BLOCK;
}
- if (s->u64LastLatchedAccess)
+ if (pThis->u64LastLatchedAccess)
{
- Log2(("Reset mask (was %d) delta %RX64 (limit %x)\n", s->iMask, u64CurTime - s->u64LastLatchedAccess, s_aDelta[s->iMask]));
- if (s->iMask)
- s->iMask--;
- s->uMaskLatchAccess = s_aMask[s->iMask];
+ Log2(("Reset mask (was %d) delta %RX64 (limit %x)\n", pThis->iMask, u64CurTime - pThis->u64LastLatchedAccess, s_aDelta[pThis->iMask]));
+ if (pThis->iMask)
+ pThis->iMask--;
+ pThis->uMaskLatchAccess = s_aMask[pThis->iMask];
}
- s->u64LastLatchedAccess = u64CurTime;
+ pThis->u64LastLatchedAccess = u64CurTime;
}
else
{
- s->u64LastLatchedAccess = 0;
- s->iMask = 0;
- s->uMaskLatchAccess = s_aMask[s->iMask];
- s->cLatchAccesses = 0;
+ pThis->u64LastLatchedAccess = 0;
+ pThis->iMask = 0;
+ pThis->uMaskLatchAccess = s_aMask[pThis->iMask];
+ pThis->cLatchAccesses = 0;
}
}
#endif
- write_mode = s->gr[5] & 3;
+ write_mode = pThis->gr[5] & 3;
switch(write_mode) {
default:
case 0:
/* rotate */
- b = s->gr[3] & 7;
+ b = pThis->gr[3] & 7;
val = ((val >> b) | (val << (8 - b))) & 0xff;
val |= val << 8;
val |= val << 16;
/* apply set/reset mask */
- set_mask = mask16[s->gr[1]];
- val = (val & ~set_mask) | (mask16[s->gr[0]] & set_mask);
- bit_mask = s->gr[8];
+ set_mask = mask16[pThis->gr[1]];
+ val = (val & ~set_mask) | (mask16[pThis->gr[0]] & set_mask);
+ bit_mask = pThis->gr[8];
break;
case 1:
- val = s->latch;
+ val = pThis->latch;
goto do_write;
case 2:
val = mask16[val & 0x0f];
- bit_mask = s->gr[8];
+ bit_mask = pThis->gr[8];
break;
case 3:
/* rotate */
- b = s->gr[3] & 7;
+ b = pThis->gr[3] & 7;
val = (val >> b) | (val << (8 - b));
- bit_mask = s->gr[8] & val;
- val = mask16[s->gr[0]];
+ bit_mask = pThis->gr[8] & val;
+ val = mask16[pThis->gr[0]];
break;
}
/* apply logical operation */
- func_select = s->gr[3] >> 3;
+ func_select = pThis->gr[3] >> 3;
switch(func_select) {
case 0:
default:
@@ -1415,34 +1417,34 @@ static int vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
break;
case 1:
/* and */
- val &= s->latch;
+ val &= pThis->latch;
break;
case 2:
/* or */
- val |= s->latch;
+ val |= pThis->latch;
break;
case 3:
/* xor */
- val ^= s->latch;
+ val ^= pThis->latch;
break;
}
/* apply bit mask */
bit_mask |= bit_mask << 8;
bit_mask |= bit_mask << 16;
- val = (val & bit_mask) | (s->latch & ~bit_mask);
+ val = (val & bit_mask) | (pThis->latch & ~bit_mask);
do_write:
/* mask data according to sr[2] */
- mask = s->sr[2];
- s->plane_updated |= mask; /* only used to detect font change */
+ mask = pThis->sr[2];
+ pThis->plane_updated |= mask; /* only used to detect font change */
write_mask = mask16[mask];
- ((uint32_t *)s->CTX_SUFF(vram_ptr))[addr] =
- (((uint32_t *)s->CTX_SUFF(vram_ptr))[addr] & ~write_mask) |
+ ((uint32_t *)pThis->CTX_SUFF(vram_ptr))[addr] =
+ (((uint32_t *)pThis->CTX_SUFF(vram_ptr))[addr] & ~write_mask) |
(val & write_mask);
Log3(("vga: latch: [0x%x] mask=0x%08x val=0x%08x\n",
addr * 4, write_mask, val));
- vga_set_dirty(s, (addr << 2));
+ vga_set_dirty(pThis, (addr << 2));
}
return VINF_SUCCESS;
@@ -1450,14 +1452,13 @@ static int vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
#if defined(IN_RING3)
typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol,
- int dscan);
+ const uint8_t *font_ptr, int h,
+ uint32_t fgcol, uint32_t bgcol,
+ int dscan);
typedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
const uint8_t *font_ptr, int h,
uint32_t fgcol, uint32_t bgcol, int dup9);
-typedef void vga_draw_line_func(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width);
+typedef void vga_draw_line_func(PVGASTATE pThis, uint8_t *pbDst, const uint8_t *pbSrc, int width);
static inline unsigned int rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
{
@@ -1524,23 +1525,23 @@ static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned
}
/* return true if the palette was modified */
-static bool update_palette16(VGAState *s)
+static bool update_palette16(PVGASTATE pThis)
{
bool full_update = false;
int i;
uint32_t v, col, *palette;
- palette = s->last_palette;
+ palette = pThis->last_palette;
for(i = 0; i < 16; i++) {
- v = s->ar[i];
- if (s->ar[0x10] & 0x80)
- v = ((s->ar[0x14] & 0xf) << 4) | (v & 0xf);
+ v = pThis->ar[i];
+ if (pThis->ar[0x10] & 0x80)
+ v = ((pThis->ar[0x14] & 0xf) << 4) | (v & 0xf);
else
- v = ((s->ar[0x14] & 0xc) << 4) | (v & 0x3f);
+ v = ((pThis->ar[0x14] & 0xc) << 4) | (v & 0x3f);
v = v * 3;
- col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
- c6_to_8(s->palette[v + 1]),
- c6_to_8(s->palette[v + 2]));
+ col = pThis->rgb_to_pixel(c6_to_8(pThis->palette[v]),
+ c6_to_8(pThis->palette[v + 1]),
+ c6_to_8(pThis->palette[v + 2]));
if (col != palette[i]) {
full_update = true;
palette[i] = col;
@@ -1550,26 +1551,26 @@ static bool update_palette16(VGAState *s)
}
/* return true if the palette was modified */
-static bool update_palette256(VGAState *s)
+static bool update_palette256(PVGASTATE pThis)
{
bool full_update = false;
int i;
uint32_t v, col, *palette;
int wide_dac;
- palette = s->last_palette;
+ palette = pThis->last_palette;
v = 0;
- wide_dac = (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & (VBE_DISPI_ENABLED | VBE_DISPI_8BIT_DAC))
+ wide_dac = (pThis->vbe_regs[VBE_DISPI_INDEX_ENABLE] & (VBE_DISPI_ENABLED | VBE_DISPI_8BIT_DAC))
== (VBE_DISPI_ENABLED | VBE_DISPI_8BIT_DAC);
for(i = 0; i < 256; i++) {
if (wide_dac)
- col = s->rgb_to_pixel(s->palette[v],
- s->palette[v + 1],
- s->palette[v + 2]);
+ col = pThis->rgb_to_pixel(pThis->palette[v],
+ pThis->palette[v + 1],
+ pThis->palette[v + 2]);
else
- col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
- c6_to_8(s->palette[v + 1]),
- c6_to_8(s->palette[v + 2]));
+ col = pThis->rgb_to_pixel(c6_to_8(pThis->palette[v]),
+ c6_to_8(pThis->palette[v + 1]),
+ c6_to_8(pThis->palette[v + 2]));
if (col != palette[i]) {
full_update = true;
palette[i] = col;
@@ -1579,36 +1580,36 @@ static bool update_palette256(VGAState *s)
return full_update;
}
-static void vga_get_offsets(VGAState *s,
+static void vga_get_offsets(PVGASTATE pThis,
uint32_t *pline_offset,
uint32_t *pstart_addr,
uint32_t *pline_compare)
{
uint32_t start_addr, line_offset, line_compare;
#ifdef CONFIG_BOCHS_VBE
- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
- line_offset = s->vbe_line_offset;
- start_addr = s->vbe_start_addr;
+ if (pThis->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
+ line_offset = pThis->vbe_line_offset;
+ start_addr = pThis->vbe_start_addr;
line_compare = 65535;
} else
#endif
{
/* compute line_offset in bytes */
- line_offset = s->cr[0x13];
+ line_offset = pThis->cr[0x13];
line_offset <<= 3;
- if (!(s->cr[0x14] & 0x40) && !(s->cr[0x17] & 0x40))
+ if (!(pThis->cr[0x14] & 0x40) && !(pThis->cr[0x17] & 0x40))
{
/* Word mode. Used for odd/even modes. */
line_offset *= 2;
}
/* starting address */
- start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8);
+ start_addr = pThis->cr[0x0d] | (pThis->cr[0x0c] << 8);
/* line compare */
- line_compare = s->cr[0x18] |
- ((s->cr[0x07] & 0x10) << 4) |
- ((s->cr[0x09] & 0x40) << 3);
+ line_compare = pThis->cr[0x18] |
+ ((pThis->cr[0x07] & 0x10) << 4) |
+ ((pThis->cr[0x09] & 0x40) << 3);
}
*pline_offset = line_offset;
*pstart_addr = start_addr;
@@ -1616,19 +1617,19 @@ static void vga_get_offsets(VGAState *s,
}
/* update start_addr and line_offset. Return TRUE if modified */
-static bool update_basic_params(VGAState *s)
+static bool update_basic_params(PVGASTATE pThis)
{
bool full_update = false;
uint32_t start_addr, line_offset, line_compare;
- s->get_offsets(s, &line_offset, &start_addr, &line_compare);
+ pThis->get_offsets(pThis, &line_offset, &start_addr, &line_compare);
- if (line_offset != s->line_offset ||
- start_addr != s->start_addr ||
- line_compare != s->line_compare) {
- s->line_offset = line_offset;
- s->start_addr = start_addr;
- s->line_compare = line_compare;
+ if (line_offset != pThis->line_offset ||
+ start_addr != pThis->start_addr ||
+ line_compare != pThis->line_compare) {
+ pThis->line_offset = line_offset;
+ pThis->start_addr = start_addr;
+ pThis->line_compare = line_compare;
full_update = true;
}
return full_update;
@@ -1695,7 +1696,7 @@ static const uint8_t cursor_glyph[32 * 4] = {
* - underline
* - flashing
*/
-static int vga_draw_text(VGAState *s, bool full_update, bool fFailOnResize, bool reset_dirty)
+static int vga_draw_text(PVGASTATE pThis, bool full_update, bool fFailOnResize, bool reset_dirty)
{
int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
int cx_min, cx_max, linesize, x_incr;
@@ -1709,54 +1710,54 @@ static int vga_draw_text(VGAState *s, bool full_update, bool fFailOnResize, bool
vga_draw_glyph8_func *vga_draw_glyph8;
vga_draw_glyph9_func *vga_draw_glyph9;
- full_update |= update_palette16(s);
- palette = s->last_palette;
+ full_update |= update_palette16(pThis);
+ palette = pThis->last_palette;
/* compute font data address (in plane 2) */
- v = s->sr[3];
+ v = pThis->sr[3];
offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
- if (offset != s->font_offsets[0]) {
- s->font_offsets[0] = offset;
+ if (offset != pThis->font_offsets[0]) {
+ pThis->font_offsets[0] = offset;
full_update = true;
}
- font_base[0] = s->CTX_SUFF(vram_ptr) + offset;
+ font_base[0] = pThis->CTX_SUFF(vram_ptr) + offset;
offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
- font_base[1] = s->CTX_SUFF(vram_ptr) + offset;
- if (offset != s->font_offsets[1]) {
- s->font_offsets[1] = offset;
+ font_base[1] = pThis->CTX_SUFF(vram_ptr) + offset;
+ if (offset != pThis->font_offsets[1]) {
+ pThis->font_offsets[1] = offset;
full_update = true;
}
- if (s->plane_updated & (1 << 2)) {
+ if (pThis->plane_updated & (1 << 2)) {
/* if the plane 2 was modified since the last display, it
indicates the font may have been modified */
- s->plane_updated = 0;
+ pThis->plane_updated = 0;
full_update = true;
}
- full_update |= update_basic_params(s);
+ full_update |= update_basic_params(pThis);
- line_offset = s->line_offset;
- s1 = s->CTX_SUFF(vram_ptr) + (s->start_addr * 8); /** @todo r=bird: Add comment why we do *8 instead of *4, it's not so obvious... */
+ line_offset = pThis->line_offset;
+ s1 = pThis->CTX_SUFF(vram_ptr) + (pThis->start_addr * 8); /** @todo r=bird: Add comment why we do *8 instead of *4, it's not so obvious... */
/* double scanning - not for 9-wide modes */
- dscan = (s->cr[9] >> 7) & 1;
+ dscan = (pThis->cr[9] >> 7) & 1;
/* total width & height */
- cheight = (s->cr[9] & 0x1f) + 1;
+ cheight = (pThis->cr[9] & 0x1f) + 1;
cw = 8;
- if (!(s->sr[1] & 0x01))
+ if (!(pThis->sr[1] & 0x01))
cw = 9;
- if (s->sr[1] & 0x08)
+ if (pThis->sr[1] & 0x08)
cw = 16; /* NOTE: no 18 pixel wide */
- x_incr = cw * ((s->pDrv->cBits + 7) >> 3);
- width = (s->cr[0x01] + 1);
- if (s->cr[0x06] == 100) {
+ x_incr = cw * ((pThis->pDrv->cBits + 7) >> 3);
+ width = (pThis->cr[0x01] + 1);
+ if (pThis->cr[0x06] == 100) {
/* ugly hack for CGA 160x100x16 - explain me the logic */
height = 100;
} else {
- height = s->cr[0x12] |
- ((s->cr[0x07] & 0x02) << 7) |
- ((s->cr[0x07] & 0x40) << 3);
+ height = pThis->cr[0x12] |
+ ((pThis->cr[0x07] & 0x02) << 7) |
+ ((pThis->cr[0x07] & 0x40) << 3);
height = (height + 1) / cheight;
}
if ((height * width) > CH_ATTR_SIZE) {
@@ -1764,56 +1765,56 @@ static int vga_draw_text(VGAState *s, bool full_update, bool fFailOnResize, bool
return VINF_SUCCESS;
}
- if (width != (int)s->last_width || height != (int)s->last_height ||
- cw != s->last_cw || cheight != s->last_ch) {
+ if (width != (int)pThis->last_width || height != (int)pThis->last_height ||
+ cw != pThis->last_cw || cheight != pThis->last_ch) {
if (fFailOnResize)
{
/* The caller does not want to call the pfnResize. */
return VERR_TRY_AGAIN;
}
- s->last_scr_width = width * cw;
- s->last_scr_height = height * cheight;
+ pThis->last_scr_width = width * cw;
+ pThis->last_scr_height = height * cheight;
/* For text modes the direct use of guest VRAM is not implemented, so bpp and cbLine are 0 here. */
- int rc = s->pDrv->pfnResize(s->pDrv, 0, NULL, 0, s->last_scr_width, s->last_scr_height);
- s->last_width = width;
- s->last_height = height;
- s->last_ch = cheight;
- s->last_cw = cw;
+ int rc = pThis->pDrv->pfnResize(pThis->pDrv, 0, NULL, 0, pThis->last_scr_width, pThis->last_scr_height);
+ pThis->last_width = width;
+ pThis->last_height = height;
+ pThis->last_ch = cheight;
+ pThis->last_cw = cw;
full_update = true;
if (rc == VINF_VGA_RESIZE_IN_PROGRESS)
return rc;
AssertRC(rc);
}
- cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
- if (cursor_offset != s->cursor_offset ||
- s->cr[0xa] != s->cursor_start ||
- s->cr[0xb] != s->cursor_end) {
+ cursor_offset = ((pThis->cr[0x0e] << 8) | pThis->cr[0x0f]) - pThis->start_addr;
+ if (cursor_offset != pThis->cursor_offset ||
+ pThis->cr[0xa] != pThis->cursor_start ||
+ pThis->cr[0xb] != pThis->cursor_end) {
/* if the cursor position changed, we update the old and new
chars */
- if (s->cursor_offset < CH_ATTR_SIZE)
- s->last_ch_attr[s->cursor_offset] = ~0;
+ if (pThis->cursor_offset < CH_ATTR_SIZE)
+ pThis->last_ch_attr[pThis->cursor_offset] = ~0;
if (cursor_offset < CH_ATTR_SIZE)
- s->last_ch_attr[cursor_offset] = ~0;
- s->cursor_offset = cursor_offset;
- s->cursor_start = s->cr[0xa];
- s->cursor_end = s->cr[0xb];
+ pThis->last_ch_attr[cursor_offset] = ~0;
+ pThis->cursor_offset = cursor_offset;
+ pThis->cursor_start = pThis->cr[0xa];
+ pThis->cursor_end = pThis->cr[0xb];
}
- cursor_ptr = s->CTX_SUFF(vram_ptr) + (s->start_addr + cursor_offset) * 8;
- depth_index = get_depth_index(s->pDrv->cBits);
+ cursor_ptr = pThis->CTX_SUFF(vram_ptr) + (pThis->start_addr + cursor_offset) * 8;
+ depth_index = get_depth_index(pThis->pDrv->cBits);
if (cw == 16)
vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
else
vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];
vga_draw_glyph9 = vga_draw_glyph9_table[depth_index];
- dest = s->pDrv->pu8Data;
- linesize = s->pDrv->cbScanline;
- ch_attr_ptr = s->last_ch_attr;
+ dest = pThis->pDrv->pu8Data;
+ linesize = pThis->pDrv->cbScanline;
+ ch_attr_ptr = pThis->last_ch_attr;
cy_start = -1;
cx_max_upd = -1;
cx_min_upd = width;
- for(cy = 0; cy < height; cy = cy + (1 << dscan)) {
+ for(cy = 0; cy < (height - dscan); cy = cy + (1 << dscan)) {
d1 = dest;
src = s1;
cx_min = width;
@@ -1839,21 +1840,23 @@ static int vga_draw_text(VGAState *s, bool full_update, bool fFailOnResize, bool
bgcol = palette[cattr >> 4];
fgcol = palette[cattr & 0x0f];
if (cw != 9) {
- vga_draw_glyph8(d1, linesize,
- font_ptr, cheight, fgcol, bgcol, dscan);
+ if (pThis->fRenderVRAM)
+ vga_draw_glyph8(d1, linesize,
+ font_ptr, cheight, fgcol, bgcol, dscan);
} else {
dup9 = 0;
- if (ch >= 0xb0 && ch <= 0xdf && (s->ar[0x10] & 0x04))
+ if (ch >= 0xb0 && ch <= 0xdf && (pThis->ar[0x10] & 0x04))
dup9 = 1;
- vga_draw_glyph9(d1, linesize,
- font_ptr, cheight, fgcol, bgcol, dup9);
+ if (pThis->fRenderVRAM)
+ vga_draw_glyph9(d1, linesize,
+ font_ptr, cheight, fgcol, bgcol, dup9);
}
if (src == cursor_ptr &&
- !(s->cr[0x0a] & 0x20)) {
+ !(pThis->cr[0x0a] & 0x20)) {
int line_start, line_last, h;
/* draw the cursor */
- line_start = s->cr[0x0a] & 0x1f;
- line_last = s->cr[0x0b] & 0x1f;
+ line_start = pThis->cr[0x0a] & 0x1f;
+ line_last = pThis->cr[0x0b] & 0x1f;
/* XXX: check that */
if (line_last > cheight - 1)
line_last = cheight - 1;
@@ -1861,11 +1864,13 @@ static int vga_draw_text(VGAState *s, bool full_update, bool fFailOnResize, bool
h = line_last - line_start + 1;
d = d1 + (linesize * line_start << dscan);
if (cw != 9) {
- vga_draw_glyph8(d, linesize,
- cursor_glyph, h, fgcol, bgcol, dscan);
+ if (pThis->fRenderVRAM)
+ vga_draw_glyph8(d, linesize,
+ cursor_glyph, h, fgcol, bgcol, dscan);
} else {
- vga_draw_glyph9(d, linesize,
- cursor_glyph, h, fgcol, bgcol, 1);
+ if (pThis->fRenderVRAM)
+ vga_draw_glyph9(d, linesize,
+ cursor_glyph, h, fgcol, bgcol, 1);
}
}
}
@@ -1884,8 +1889,8 @@ static int vga_draw_text(VGAState *s, bool full_update, bool fFailOnResize, bool
cx_max_upd = cx_max;
} else if (cy_start >= 0) {
/* Flush updates to display. */
- s->pDrv->pfnUpdateRect(s->pDrv, cx_min_upd * cw, cy_start * cheight,
- (cx_max_upd - cx_min_upd + 1) * cw, (cy - cy_start) * cheight);
+ pThis->pDrv->pfnUpdateRect(pThis->pDrv, cx_min_upd * cw, cy_start * cheight,
+ (cx_max_upd - cx_min_upd + 1) * cw, (cy - cy_start) * cheight);
cy_start = -1;
cx_max_upd = -1;
cx_min_upd = width;
@@ -1895,8 +1900,8 @@ static int vga_draw_text(VGAState *s, bool full_update, bool fFailOnResize, bool
}
if (cy_start >= 0)
/* Flush any remaining changes to display. */
- s->pDrv->pfnUpdateRect(s->pDrv, cx_min_upd * cw, cy_start * cheight,
- (cx_max_upd - cx_min_upd + 1) * cw, (cy - cy_start) * cheight);
+ pThis->pDrv->pfnUpdateRect(pThis->pDrv, cx_min_upd * cw, cy_start * cheight,
+ (cx_max_upd - cx_min_upd + 1) * cw, (cy - cy_start) * cheight);
return VINF_SUCCESS;
}
@@ -1966,12 +1971,12 @@ static vga_draw_line_func *vga_draw_line_table[4 * VGA_DRAW_LINE_NB] = {
vga_draw_line32_32,
};
-static int vga_get_bpp(VGAState *s)
+static int vga_get_bpp(PVGASTATE pThis)
{
int ret;
#ifdef CONFIG_BOCHS_VBE
- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
- ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
+ if (pThis->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
+ ret = pThis->vbe_regs[VBE_DISPI_INDEX_BPP];
} else
#endif
{
@@ -1980,21 +1985,21 @@ static int vga_get_bpp(VGAState *s)
return ret;
}
-static void vga_get_resolution(VGAState *s, int *pwidth, int *pheight)
+static void vga_get_resolution(PVGASTATE pThis, int *pwidth, int *pheight)
{
int width, height;
#ifdef CONFIG_BOCHS_VBE
- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
- width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
- height = RT_MIN(s->vbe_regs[VBE_DISPI_INDEX_YRES],
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT]);
+ if (pThis->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
+ width = pThis->vbe_regs[VBE_DISPI_INDEX_XRES];
+ height = RT_MIN(pThis->vbe_regs[VBE_DISPI_INDEX_YRES],
+ pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT]);
} else
#endif
{
- width = (s->cr[0x01] + 1) * 8;
- height = s->cr[0x12] |
- ((s->cr[0x07] & 0x02) << 7) |
- ((s->cr[0x07] & 0x40) << 3);
+ width = (pThis->cr[0x01] + 1) * 8;
+ height = pThis->cr[0x12] |
+ ((pThis->cr[0x07] & 0x02) << 7) |
+ ((pThis->cr[0x07] & 0x40) << 3);
height = (height + 1);
}
*pwidth = width;
@@ -2009,19 +2014,19 @@ static void vga_get_resolution(VGAState *s, int *pwidth, int *pheight)
*
* @returns VINF_SUCCESS on success.
* @returns VINF_VGA_RESIZE_IN_PROGRESS if the operation wasn't complete.
- * @param s Pointer to the vga status.
+ * @param pThis Pointer to the vga state.
* @param cx The width.
* @param cy The height.
*/
-static int vga_resize_graphic(VGAState *s, int cx, int cy)
+static int vga_resize_graphic(PVGASTATE pThis, int cx, int cy)
{
- const unsigned cBits = s->get_bpp(s);
+ const unsigned cBits = pThis->get_bpp(pThis);
int rc;
AssertReturn(cx, VERR_INVALID_PARAMETER);
AssertReturn(cy, VERR_INVALID_PARAMETER);
- AssertPtrReturn(s, VERR_INVALID_POINTER);
- AssertReturn(s->line_offset, VERR_INTERNAL_ERROR);
+ AssertPtrReturn(pThis, VERR_INVALID_POINTER);
+ AssertReturn(pThis->line_offset, VERR_INTERNAL_ERROR);
#if 0 //def VBOX_WITH_VDMA
/* @todo: we get a second resize here when VBVA is on, while we actually should not */
@@ -2031,16 +2036,16 @@ static int vga_resize_graphic(VGAState *s, int cx, int cy)
* event and generally only pfnVBVAxxx calls should be used with HGSMI + VBVA
*
* The reason for doing this for WDDM driver only now is to avoid regressions of the current code */
- PVBOXVDMAHOST pVdma = s->pVdma;
+ PVBOXVDMAHOST pVdma = pThis->pVdma;
if (pVdma && vboxVDMAIsEnabled(pVdma))
rc = VINF_SUCCESS;
else
#endif
{
/* Skip the resize if the values are not valid. */
- if (s->start_addr * 4 + s->line_offset * cy < s->vram_size)
+ if (pThis->start_addr * 4 + pThis->line_offset * cy < pThis->vram_size)
/* Take into account the programmed start address (in DWORDs) of the visible screen. */
- rc = s->pDrv->pfnResize(s->pDrv, cBits, s->CTX_SUFF(vram_ptr) + s->start_addr * 4, s->line_offset, cx, cy);
+ rc = pThis->pDrv->pfnResize(pThis->pDrv, cBits, pThis->CTX_SUFF(vram_ptr) + pThis->start_addr * 4, pThis->line_offset, cx, cy);
else
{
/* Change nothing in the VGA state. Lets hope the guest will eventually programm correct values. */
@@ -2049,36 +2054,213 @@ static int vga_resize_graphic(VGAState *s, int cx, int cy)
}
/* last stuff */
- s->last_bpp = cBits;
- s->last_scr_width = cx;
- s->last_scr_height = cy;
- s->last_width = cx;
- s->last_height = cy;
+ pThis->last_bpp = cBits;
+ pThis->last_scr_width = cx;
+ pThis->last_scr_height = cy;
+ pThis->last_width = cx;
+ pThis->last_height = cy;
if (rc == VINF_VGA_RESIZE_IN_PROGRESS)
return rc;
AssertRC(rc);
/* update palette */
- switch (s->pDrv->cBits)
+ switch (pThis->pDrv->cBits)
{
- case 32: s->rgb_to_pixel = rgb_to_pixel32_dup; break;
+ case 32: pThis->rgb_to_pixel = rgb_to_pixel32_dup; break;
case 16:
- default: s->rgb_to_pixel = rgb_to_pixel16_dup; break;
- case 15: s->rgb_to_pixel = rgb_to_pixel15_dup; break;
- case 8: s->rgb_to_pixel = rgb_to_pixel8_dup; break;
- }
- if (s->shift_control == 0)
- update_palette16(s);
- else if (s->shift_control == 1)
- update_palette16(s);
+ default: pThis->rgb_to_pixel = rgb_to_pixel16_dup; break;
+ case 15: pThis->rgb_to_pixel = rgb_to_pixel15_dup; break;
+ case 8: pThis->rgb_to_pixel = rgb_to_pixel8_dup; break;
+ }
+ if (pThis->shift_control == 0)
+ update_palette16(pThis);
+ else if (pThis->shift_control == 1)
+ update_palette16(pThis);
+ return VINF_SUCCESS;
+}
+
+#ifdef VBOX_WITH_VMSVGA
+int vgaR3UpdateDisplay(VGAState *s, unsigned xStart, unsigned yStart, unsigned width, unsigned height)
+{
+ int bits;
+ uint32_t v;
+ vga_draw_line_func *vga_draw_line;
+
+ if (!s->fRenderVRAM)
+ {
+ s->pDrv->pfnUpdateRect(s->pDrv, xStart, yStart, width, height);
+ return VINF_SUCCESS;
+ }
+ /* @todo might crash if a blit follows a resolution change very quickly (seen this many times!) */
+
+ if ( s->svga.iWidth == -1
+ || s->svga.iHeight == -1
+ || s->svga.iBpp == UINT32_MAX)
+ {
+ /* Intermediate state; skip redraws. */
+ AssertFailed();
+ return VINF_SUCCESS;
+ }
+
+ switch(s->svga.iBpp) {
+ default:
+ case 0:
+ case 8:
+ AssertFailed();
+ return VERR_NOT_IMPLEMENTED;
+ case 15:
+ v = VGA_DRAW_LINE15;
+ bits = 16;
+ break;
+ case 16:
+ v = VGA_DRAW_LINE16;
+ bits = 16;
+ break;
+ case 24:
+ v = VGA_DRAW_LINE24;
+ bits = 24;
+ break;
+ case 32:
+ v = VGA_DRAW_LINE32;
+ bits = 32;
+ break;
+ }
+ vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->pDrv->cBits)];
+
+ unsigned offsetSource = (xStart * bits) / 8 + s->svga.cbScanline * yStart;
+ unsigned offsetDest = (xStart * RT_ALIGN(s->pDrv->cBits, 8)) / 8 + s->pDrv->cbScanline * yStart;
+
+ uint8_t *dest = s->pDrv->pu8Data + offsetDest;
+ uint8_t *src = s->CTX_SUFF(vram_ptr) + offsetSource;
+
+ for(unsigned y = yStart; y < yStart + height; y++)
+ {
+ vga_draw_line(s, dest, src, width);
+
+ dest += s->pDrv->cbScanline;
+ src += s->svga.cbScanline;
+ }
+ s->pDrv->pfnUpdateRect(s->pDrv, xStart, yStart, width, height);
+
+ return VINF_SUCCESS;
+}
+
+/*
+ * graphic modes
+ */
+static int vmsvga_draw_graphic(PVGASTATE pThis, bool full_update, bool fFailOnResize, bool reset_dirty)
+{
+ int y, page_min, page_max, linesize, y_start;
+ int width, height, page0, page1, bwidth, bits;
+ int disp_width;
+ uint8_t *d;
+ uint32_t v, addr1, addr;
+ vga_draw_line_func *vga_draw_line;
+
+ if ( pThis->svga.iWidth == -1
+ || pThis->svga.iHeight == -1
+ || pThis->svga.iBpp == UINT32_MAX)
+ {
+ /* Intermediate state; skip redraws. */
+ return VINF_SUCCESS;
+ }
+
+ width = pThis->svga.iWidth;
+ height = pThis->svga.iHeight;
+
+ disp_width = width;
+
+ switch(pThis->svga.iBpp) {
+ default:
+ case 0:
+ case 8:
+ AssertFailed();
+ return VERR_NOT_IMPLEMENTED;
+ case 15:
+ v = VGA_DRAW_LINE15;
+ bits = 16;
+ break;
+ case 16:
+ v = VGA_DRAW_LINE16;
+ bits = 16;
+ break;
+ case 24:
+ v = VGA_DRAW_LINE24;
+ bits = 24;
+ break;
+ case 32:
+ v = VGA_DRAW_LINE32;
+ bits = 32;
+ break;
+ }
+ vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(pThis->pDrv->cBits)];
+
+ if (pThis->cursor_invalidate)
+ pThis->cursor_invalidate(pThis);
+
+ addr1 = 0; /* always start at the beginning of the framebuffer */
+ bwidth = (width * bits + 7) / 8; /* The visible width of a scanline. */
+ y_start = -1;
+ page_min = 0x7fffffff;
+ page_max = -1;
+ d = pThis->pDrv->pu8Data;
+ linesize = pThis->pDrv->cbScanline;
+
+ for(y = 0; y < height; y++)
+ {
+ addr = addr1 + y * bwidth;
+
+ page0 = addr & ~PAGE_OFFSET_MASK;
+ page1 = (addr + bwidth - 1) & ~PAGE_OFFSET_MASK;
+ bool update = full_update | vga_is_dirty(pThis, page0) | vga_is_dirty(pThis, page1);
+ if (page1 - page0 > PAGE_SIZE)
+ /* if wide line, can use another page */
+ update |= vga_is_dirty(pThis, page0 + PAGE_SIZE);
+ /* explicit invalidation for the hardware cursor */
+ update |= (pThis->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
+ if (update)
+ {
+ if (y_start < 0)
+ y_start = y;
+ if (page0 < page_min)
+ page_min = page0;
+ if (page1 > page_max)
+ page_max = page1;
+ if (pThis->fRenderVRAM)
+ vga_draw_line(pThis, d, pThis->CTX_SUFF(vram_ptr) + addr, width);
+ if (pThis->cursor_draw_line)
+ pThis->cursor_draw_line(pThis, d, y);
+ } else
+ {
+ if (y_start >= 0)
+ {
+ /* flush to display */
+ Log(("Flush to display (%d,%d)(%d,%d)\n", 0, y_start, disp_width, y - y_start));
+ pThis->pDrv->pfnUpdateRect(pThis->pDrv, 0, y_start, disp_width, y - y_start);
+ y_start = -1;
+ }
+ }
+ d += linesize;
+ }
+ if (y_start >= 0)
+ {
+ /* flush to display */
+ Log(("Flush to display (%d,%d)(%d,%d)\n", 0, y_start, disp_width, y - y_start));
+ pThis->pDrv->pfnUpdateRect(pThis->pDrv, 0, y_start, disp_width, y - y_start);
+ }
+ /* reset modified pages */
+ if (page_max != -1 && reset_dirty)
+ vga_reset_dirty(pThis, page_min, page_max + PAGE_SIZE);
+ memset(pThis->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
return VINF_SUCCESS;
}
+#endif /* VBOX_WITH_VMSVGA */
/*
* graphic modes
*/
-static int vga_draw_graphic(VGAState *s, bool full_update, bool fFailOnResize, bool reset_dirty)
+static int vga_draw_graphic(PVGASTATE pThis, bool full_update, bool fFailOnResize, bool reset_dirty)
{
int y1, y2, y, page_min, page_max, linesize, y_start, double_scan;
int width, height, shift_control, line_offset, page0, page1, bwidth, bits;
@@ -2087,26 +2269,26 @@ static int vga_draw_graphic(VGAState *s, bool full_update, bool fFailOnResize, b
uint32_t v, addr1, addr;
vga_draw_line_func *vga_draw_line;
- bool offsets_changed = update_basic_params(s);
+ bool offsets_changed = update_basic_params(pThis);
full_update |= offsets_changed;
- s->get_resolution(s, &width, &height);
+ pThis->get_resolution(pThis, &width, &height);
disp_width = width;
- shift_control = (s->gr[0x05] >> 5) & 3;
- double_scan = (s->cr[0x09] >> 7);
+ shift_control = (pThis->gr[0x05] >> 5) & 3;
+ double_scan = (pThis->cr[0x09] >> 7);
multi_run = double_scan;
- if (shift_control != s->shift_control ||
- double_scan != s->double_scan) {
+ if (shift_control != pThis->shift_control ||
+ double_scan != pThis->double_scan) {
full_update = true;
- s->shift_control = shift_control;
- s->double_scan = double_scan;
+ pThis->shift_control = shift_control;
+ pThis->double_scan = double_scan;
}
if (shift_control == 0) {
- full_update |= update_palette16(s);
- if (s->sr[0x01] & 8) {
+ full_update |= update_palette16(pThis);
+ if (pThis->sr[0x01] & 8) {
v = VGA_DRAW_LINE4D2;
disp_width <<= 1;
} else {
@@ -2114,8 +2296,8 @@ static int vga_draw_graphic(VGAState *s, bool full_update, bool fFailOnResize, b
}
bits = 4;
} else if (shift_control == 1) {
- full_update |= update_palette16(s);
- if (s->sr[0x01] & 8) {
+ full_update |= update_palette16(pThis);
+ if (pThis->sr[0x01] & 8) {
v = VGA_DRAW_LINE2D2;
disp_width <<= 1;
} else {
@@ -2123,15 +2305,15 @@ static int vga_draw_graphic(VGAState *s, bool full_update, bool fFailOnResize, b
}
bits = 4;
} else {
- switch(s->get_bpp(s)) {
+ switch(pThis->get_bpp(pThis)) {
default:
case 0:
- full_update |= update_palette256(s);
+ full_update |= update_palette256(pThis);
v = VGA_DRAW_LINE8D2;
bits = 4;
break;
case 8:
- full_update |= update_palette256(s);
+ full_update |= update_palette256(pThis);
v = VGA_DRAW_LINE8;
bits = 8;
break;
@@ -2153,61 +2335,61 @@ static int vga_draw_graphic(VGAState *s, bool full_update, bool fFailOnResize, b
break;
}
}
- if ( disp_width != (int)s->last_width
- || height != (int)s->last_height
- || s->get_bpp(s) != (int)s->last_bpp
- || (offsets_changed && !s->fRenderVRAM))
+ if ( disp_width != (int)pThis->last_width
+ || height != (int)pThis->last_height
+ || pThis->get_bpp(pThis) != (int)pThis->last_bpp
+ || (offsets_changed && !pThis->fRenderVRAM))
{
if (fFailOnResize)
{
/* The caller does not want to call the pfnResize. */
return VERR_TRY_AGAIN;
}
- int rc = vga_resize_graphic(s, disp_width, height);
+ int rc = vga_resize_graphic(pThis, disp_width, height);
if (rc != VINF_SUCCESS) /* Return any rc, particularly VINF_VGA_RESIZE_IN_PROGRESS, to the caller. */
return rc;
full_update = true;
}
- vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->pDrv->cBits)];
+ vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(pThis->pDrv->cBits)];
- if (s->cursor_invalidate)
- s->cursor_invalidate(s);
+ if (pThis->cursor_invalidate)
+ pThis->cursor_invalidate(pThis);
- line_offset = s->line_offset;
+ line_offset = pThis->line_offset;
#if 0
Log(("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
- width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]));
+ width, height, v, line_offset, pThis->cr[9], pThis->cr[0x17], pThis->line_compare, pThis->sr[0x01]));
#endif
- addr1 = (s->start_addr * 4);
+ addr1 = (pThis->start_addr * 4);
bwidth = (width * bits + 7) / 8; /* The visible width of a scanline. */
y_start = -1;
page_min = 0x7fffffff;
page_max = -1;
- d = s->pDrv->pu8Data;
- linesize = s->pDrv->cbScanline;
+ d = pThis->pDrv->pu8Data;
+ linesize = pThis->pDrv->cbScanline;
y1 = 0;
- y2 = s->cr[0x09] & 0x1F; /* starting row scan count */
+ y2 = pThis->cr[0x09] & 0x1F; /* starting row scan count */
for(y = 0; y < height; y++) {
addr = addr1;
/* CGA/MDA compatibility. Note that these addresses are all
* shifted left by two compared to VGA specs.
*/
- if (!(s->cr[0x17] & 1)) {
+ if (!(pThis->cr[0x17] & 1)) {
addr = (addr & ~(1 << 15)) | ((y1 & 1) << 15);
}
- if (!(s->cr[0x17] & 2)) {
+ if (!(pThis->cr[0x17] & 2)) {
addr = (addr & ~(1 << 16)) | ((y1 & 2) << 15);
}
page0 = addr & TARGET_PAGE_MASK;
page1 = (addr + bwidth - 1) & TARGET_PAGE_MASK;
- bool update = full_update | vga_is_dirty(s, page0) | vga_is_dirty(s, page1);
+ bool update = full_update | vga_is_dirty(pThis, page0) | vga_is_dirty(pThis, page1);
if (page1 - page0 > TARGET_PAGE_SIZE) {
/* if wide line, can use another page */
- update |= vga_is_dirty(s, page0 + TARGET_PAGE_SIZE);
+ update |= vga_is_dirty(pThis, page0 + TARGET_PAGE_SIZE);
}
/* explicit invalidation for the hardware cursor */
- update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
+ update |= (pThis->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
if (update) {
if (y_start < 0)
y_start = y;
@@ -2215,14 +2397,14 @@ static int vga_draw_graphic(VGAState *s, bool full_update, bool fFailOnResize, b
page_min = page0;
if (page1 > page_max)
page_max = page1;
- if (s->fRenderVRAM)
- vga_draw_line(s, d, s->CTX_SUFF(vram_ptr) + addr, width);
- if (s->cursor_draw_line)
- s->cursor_draw_line(s, d, y);
+ if (pThis->fRenderVRAM)
+ vga_draw_line(pThis, d, pThis->CTX_SUFF(vram_ptr) + addr, width);
+ if (pThis->cursor_draw_line)
+ pThis->cursor_draw_line(pThis, d, y);
} else {
if (y_start >= 0) {
/* flush to display */
- s->pDrv->pfnUpdateRect(s->pDrv, 0, y_start, disp_width, y - y_start);
+ pThis->pDrv->pfnUpdateRect(pThis->pDrv, 0, y_start, disp_width, y - y_start);
y_start = -1;
}
}
@@ -2231,7 +2413,7 @@ static int vga_draw_graphic(VGAState *s, bool full_update, bool fFailOnResize, b
multi_run = double_scan;
if (y2 == 0) {
- y2 = s->cr[0x09] & 0x1F;
+ y2 = pThis->cr[0x09] & 0x1F;
addr1 += line_offset;
} else {
--y2;
@@ -2240,45 +2422,48 @@ static int vga_draw_graphic(VGAState *s, bool full_update, bool fFailOnResize, b
multi_run--;
}
/* line compare acts on the displayed lines */
- if ((uint32_t)y == s->line_compare)
+ if ((uint32_t)y == pThis->line_compare)
addr1 = 0;
d += linesize;
}
if (y_start >= 0) {
/* flush to display */
- s->pDrv->pfnUpdateRect(s->pDrv, 0, y_start, disp_width, y - y_start);
+ pThis->pDrv->pfnUpdateRect(pThis->pDrv, 0, y_start, disp_width, y - y_start);
}
/* reset modified pages */
if (page_max != -1 && reset_dirty) {
- vga_reset_dirty(s, page_min, page_max + TARGET_PAGE_SIZE);
+ vga_reset_dirty(pThis, page_min, page_max + TARGET_PAGE_SIZE);
}
- memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
+ memset(pThis->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
return VINF_SUCCESS;
}
-static void vga_draw_blank(VGAState *s, int full_update)
+static void vga_draw_blank(PVGASTATE pThis, int full_update)
{
int i, w, val;
uint8_t *d;
- uint32_t cbScanline = s->pDrv->cbScanline;
+ uint32_t cbScanline = pThis->pDrv->cbScanline;
- if (s->pDrv->pu8Data == s->vram_ptrR3) /* Do not clear the VRAM itself. */
+ if (pThis->pDrv->pu8Data == pThis->vram_ptrR3) /* Do not clear the VRAM itself. */
return;
if (!full_update)
return;
- if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
+ if (pThis->last_scr_width <= 0 || pThis->last_scr_height <= 0)
return;
- if (s->pDrv->cBits == 8)
- val = s->rgb_to_pixel(0, 0, 0);
+ if (pThis->pDrv->cBits == 8)
+ val = pThis->rgb_to_pixel(0, 0, 0);
else
val = 0;
- w = s->last_scr_width * ((s->pDrv->cBits + 7) >> 3);
- d = s->pDrv->pu8Data;
- for(i = 0; i < (int)s->last_scr_height; i++) {
- memset(d, val, w);
- d += cbScanline;
+ w = pThis->last_scr_width * ((pThis->pDrv->cBits + 7) >> 3);
+ d = pThis->pDrv->pu8Data;
+ if (pThis->fRenderVRAM)
+ {
+ for(i = 0; i < (int)pThis->last_scr_height; i++) {
+ memset(d, val, w);
+ d += cbScanline;
+ }
}
- s->pDrv->pfnUpdateRect(s->pDrv, 0, 0, s->last_scr_width, s->last_scr_height);
+ pThis->pDrv->pfnUpdateRect(pThis->pDrv, 0, 0, pThis->last_scr_width, pThis->last_scr_height);
}
static DECLCALLBACK(void) voidUpdateRect(PPDMIDISPLAYCONNECTOR pInterface, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy)
@@ -2290,28 +2475,31 @@ static DECLCALLBACK(void) voidUpdateRect(PPDMIDISPLAYCONNECTOR pInterface, uint3
#define GMODE_TEXT 0
#define GMODE_GRAPH 1
#define GMODE_BLANK 2
+#ifdef VBOX_WITH_VMSVGA
+#define GMODE_SVGA 3
+#endif
-static int vga_update_display(PVGASTATE s, bool fUpdateAll, bool fFailOnResize, bool reset_dirty)
+static int vga_update_display(PVGASTATE pThis, bool fUpdateAll, bool fFailOnResize, bool reset_dirty)
{
int rc = VINF_SUCCESS;
int graphic_mode;
- if (s->pDrv->cBits == 0) {
+ if (pThis->pDrv->cBits == 0) {
/* nothing to do */
} else {
- switch(s->pDrv->cBits) {
+ switch(pThis->pDrv->cBits) {
case 8:
- s->rgb_to_pixel = rgb_to_pixel8_dup;
+ pThis->rgb_to_pixel = rgb_to_pixel8_dup;
break;
case 15:
- s->rgb_to_pixel = rgb_to_pixel15_dup;
+ pThis->rgb_to_pixel = rgb_to_pixel15_dup;
break;
default:
case 16:
- s->rgb_to_pixel = rgb_to_pixel16_dup;
+ pThis->rgb_to_pixel = rgb_to_pixel16_dup;
break;
case 32:
- s->rgb_to_pixel = rgb_to_pixel32_dup;
+ pThis->rgb_to_pixel = rgb_to_pixel32_dup;
break;
}
@@ -2330,131 +2518,147 @@ static int vga_update_display(PVGASTATE s, bool fUpdateAll, bool fFailOnResize,
/* Detect the "screen blank" conditions. */
int fBlank = 0;
- if (!(s->ar_index & 0x20) || (s->sr[0x01] & 0x20)) {
+ if (!(pThis->ar_index & 0x20) || (pThis->sr[0x01] & 0x20)) {
fBlank = 1;
}
if (fBlank) {
/* Provide a void pfnUpdateRect callback. */
- if (s->pDrv) {
- pfnUpdateRect = s->pDrv->pfnUpdateRect;
- s->pDrv->pfnUpdateRect = voidUpdateRect;
+ if (pThis->pDrv) {
+ pfnUpdateRect = pThis->pDrv->pfnUpdateRect;
+ pThis->pDrv->pfnUpdateRect = voidUpdateRect;
}
}
/* Do a complete redraw, which will pick up a new screen resolution. */
- if (s->gr[6] & 1) {
- s->graphic_mode = GMODE_GRAPH;
- rc = vga_draw_graphic(s, 1, false, reset_dirty);
+#ifdef VBOX_WITH_VMSVGA
+ if (pThis->svga.fEnabled) {
+ pThis->graphic_mode = GMODE_SVGA;
+ rc = vmsvga_draw_graphic(pThis, 1, false, reset_dirty);
+ }
+ else
+#endif
+ if (pThis->gr[6] & 1) {
+ pThis->graphic_mode = GMODE_GRAPH;
+ rc = vga_draw_graphic(pThis, 1, false, reset_dirty);
} else {
- s->graphic_mode = GMODE_TEXT;
- rc = vga_draw_text(s, 1, false, reset_dirty);
+ pThis->graphic_mode = GMODE_TEXT;
+ rc = vga_draw_text(pThis, 1, false, reset_dirty);
}
if (fBlank) {
/* Set the current mode and restore the callback. */
- s->graphic_mode = GMODE_BLANK;
- if (s->pDrv) {
- s->pDrv->pfnUpdateRect = pfnUpdateRect;
+ pThis->graphic_mode = GMODE_BLANK;
+ if (pThis->pDrv) {
+ pThis->pDrv->pfnUpdateRect = pfnUpdateRect;
}
}
return rc;
}
- if (!(s->ar_index & 0x20) || (s->sr[0x01] & 0x20)) {
+#ifdef VBOX_WITH_VMSVGA
+ if (pThis->svga.fEnabled) {
+ graphic_mode = GMODE_SVGA;
+ }
+ else
+#endif
+ if (!(pThis->ar_index & 0x20) || (pThis->sr[0x01] & 0x20)) {
graphic_mode = GMODE_BLANK;
} else {
- graphic_mode = s->gr[6] & 1;
+ graphic_mode = pThis->gr[6] & 1;
}
- bool full_update = graphic_mode != s->graphic_mode;
+ bool full_update = graphic_mode != pThis->graphic_mode;
if (full_update) {
- s->graphic_mode = graphic_mode;
+ pThis->graphic_mode = graphic_mode;
}
switch(graphic_mode) {
case GMODE_TEXT:
- rc = vga_draw_text(s, full_update, fFailOnResize, reset_dirty);
+ rc = vga_draw_text(pThis, full_update, fFailOnResize, reset_dirty);
break;
case GMODE_GRAPH:
- rc = vga_draw_graphic(s, full_update, fFailOnResize, reset_dirty);
+ rc = vga_draw_graphic(pThis, full_update, fFailOnResize, reset_dirty);
+ break;
+#ifdef VBOX_WITH_VMSVGA
+ case GMODE_SVGA:
+ rc = vmsvga_draw_graphic(pThis, full_update, fFailOnResize, reset_dirty);
break;
+#endif
case GMODE_BLANK:
default:
- vga_draw_blank(s, full_update);
+ vga_draw_blank(pThis, full_update);
break;
}
}
return rc;
}
-static void vga_save(QEMUFile *f, void *opaque)
+static void vga_save(QEMUFile *f, PVGASTATE pThis)
{
- VGAState *s = (VGAState*)opaque;
int i;
- qemu_put_be32s(f, &s->latch);
- qemu_put_8s(f, &s->sr_index);
- qemu_put_buffer(f, s->sr, 8);
- qemu_put_8s(f, &s->gr_index);
- qemu_put_buffer(f, s->gr, 16);
- qemu_put_8s(f, &s->ar_index);
- qemu_put_buffer(f, s->ar, 21);
- qemu_put_be32s(f, &s->ar_flip_flop);
- qemu_put_8s(f, &s->cr_index);
- qemu_put_buffer(f, s->cr, 256);
- qemu_put_8s(f, &s->msr);
- qemu_put_8s(f, &s->fcr);
- qemu_put_8s(f, &s->st00);
- qemu_put_8s(f, &s->st01);
-
- qemu_put_8s(f, &s->dac_state);
- qemu_put_8s(f, &s->dac_sub_index);
- qemu_put_8s(f, &s->dac_read_index);
- qemu_put_8s(f, &s->dac_write_index);
- qemu_put_buffer(f, s->dac_cache, 3);
- qemu_put_buffer(f, s->palette, 768);
-
- qemu_put_be32s(f, &s->bank_offset);
+ qemu_put_be32s(f, &pThis->latch);
+ qemu_put_8s(f, &pThis->sr_index);
+ qemu_put_buffer(f, pThis->sr, 8);
+ qemu_put_8s(f, &pThis->gr_index);
+ qemu_put_buffer(f, pThis->gr, 16);
+ qemu_put_8s(f, &pThis->ar_index);
+ qemu_put_buffer(f, pThis->ar, 21);
+ qemu_put_be32s(f, &pThis->ar_flip_flop);
+ qemu_put_8s(f, &pThis->cr_index);
+ qemu_put_buffer(f, pThis->cr, 256);
+ qemu_put_8s(f, &pThis->msr);
+ qemu_put_8s(f, &pThis->fcr);
+ qemu_put_8s(f, &pThis->st00);
+ qemu_put_8s(f, &pThis->st01);
+
+ qemu_put_8s(f, &pThis->dac_state);
+ qemu_put_8s(f, &pThis->dac_sub_index);
+ qemu_put_8s(f, &pThis->dac_read_index);
+ qemu_put_8s(f, &pThis->dac_write_index);
+ qemu_put_buffer(f, pThis->dac_cache, 3);
+ qemu_put_buffer(f, pThis->palette, 768);
+
+ qemu_put_be32s(f, &pThis->bank_offset);
#ifdef CONFIG_BOCHS_VBE
qemu_put_byte(f, 1);
- qemu_put_be16s(f, &s->vbe_index);
+ qemu_put_be16s(f, &pThis->vbe_index);
for(i = 0; i < VBE_DISPI_INDEX_NB_SAVED; i++)
- qemu_put_be16s(f, &s->vbe_regs[i]);
- qemu_put_be32s(f, &s->vbe_start_addr);
- qemu_put_be32s(f, &s->vbe_line_offset);
+ qemu_put_be16s(f, &pThis->vbe_regs[i]);
+ qemu_put_be32s(f, &pThis->vbe_start_addr);
+ qemu_put_be32s(f, &pThis->vbe_line_offset);
#else
qemu_put_byte(f, 0);
#endif
}
-static int vga_load(QEMUFile *f, void *opaque, int version_id)
+static int vga_load(QEMUFile *f, PVGASTATE pThis, int version_id)
{
- VGAState *s = (VGAState*)opaque;
int is_vbe, i;
uint32_t u32Dummy;
- qemu_get_be32s(f, &s->latch);
- qemu_get_8s(f, &s->sr_index);
- qemu_get_buffer(f, s->sr, 8);
- qemu_get_8s(f, &s->gr_index);
- qemu_get_buffer(f, s->gr, 16);
- qemu_get_8s(f, &s->ar_index);
- qemu_get_buffer(f, s->ar, 21);
- qemu_get_be32s(f, (uint32_t *)&s->ar_flip_flop);
- qemu_get_8s(f, &s->cr_index);
- qemu_get_buffer(f, s->cr, 256);
- qemu_get_8s(f, &s->msr);
- qemu_get_8s(f, &s->fcr);
- qemu_get_8s(f, &s->st00);
- qemu_get_8s(f, &s->st01);
-
- qemu_get_8s(f, &s->dac_state);
- qemu_get_8s(f, &s->dac_sub_index);
- qemu_get_8s(f, &s->dac_read_index);
- qemu_get_8s(f, &s->dac_write_index);
- qemu_get_buffer(f, s->dac_cache, 3);
- qemu_get_buffer(f, s->palette, 768);
-
- qemu_get_be32s(f, (uint32_t *)&s->bank_offset);
+ qemu_get_be32s(f, &pThis->latch);
+ qemu_get_8s(f, &pThis->sr_index);
+ qemu_get_buffer(f, pThis->sr, 8);
+ qemu_get_8s(f, &pThis->gr_index);
+ qemu_get_buffer(f, pThis->gr, 16);
+ qemu_get_8s(f, &pThis->ar_index);
+ qemu_get_buffer(f, pThis->ar, 21);
+ qemu_get_be32s(f, (uint32_t *)&pThis->ar_flip_flop);
+ qemu_get_8s(f, &pThis->cr_index);
+ qemu_get_buffer(f, pThis->cr, 256);
+ qemu_get_8s(f, &pThis->msr);
+ qemu_get_8s(f, &pThis->fcr);
+ qemu_get_8s(f, &pThis->st00);
+ qemu_get_8s(f, &pThis->st01);
+
+ qemu_get_8s(f, &pThis->dac_state);
+ qemu_get_8s(f, &pThis->dac_sub_index);
+ qemu_get_8s(f, &pThis->dac_read_index);
+ qemu_get_8s(f, &pThis->dac_write_index);
+ qemu_get_buffer(f, pThis->dac_cache, 3);
+ qemu_get_buffer(f, pThis->palette, 768);
+
+ qemu_get_be32s(f, (uint32_t *)&pThis->bank_offset);
is_vbe = qemu_get_byte(f);
#ifdef CONFIG_BOCHS_VBE
if (!is_vbe)
@@ -2462,16 +2666,16 @@ static int vga_load(QEMUFile *f, void *opaque, int version_id)
Log(("vga_load: !is_vbe !!\n"));
return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
}
- qemu_get_be16s(f, &s->vbe_index);
+ qemu_get_be16s(f, &pThis->vbe_index);
for(i = 0; i < VBE_DISPI_INDEX_NB_SAVED; i++)
- qemu_get_be16s(f, &s->vbe_regs[i]);
+ qemu_get_be16s(f, &pThis->vbe_regs[i]);
if (version_id <= VGA_SAVEDSTATE_VERSION_INV_VHEIGHT)
- recalculate_data(s, false); /* <- re-calculate the s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] since it might be invalid */
- qemu_get_be32s(f, &s->vbe_start_addr);
- qemu_get_be32s(f, &s->vbe_line_offset);
+ recalculate_data(pThis, false); /* <- re-calculate the pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] since it might be invalid */
+ qemu_get_be32s(f, &pThis->vbe_start_addr);
+ qemu_get_be32s(f, &pThis->vbe_line_offset);
if (version_id < 2)
qemu_get_be32s(f, &u32Dummy);
- s->vbe_bank_max = (s->vram_size >> 16) - 1;
+ pThis->vbe_bank_max = (pThis->vram_size >> 16) - 1;
#else
if (is_vbe)
{
@@ -2481,7 +2685,7 @@ static int vga_load(QEMUFile *f, void *opaque, int version_id)
#endif
/* force refresh */
- s->graphic_mode = -1;
+ pThis->graphic_mode = -1;
return 0;
}
@@ -2521,92 +2725,53 @@ static void vga_init_expand(void)
/* -=-=-=-=-=- all contexts -=-=-=-=-=- */
/**
- * Port I/O Handler for VGA OUT operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param Port Port number used for the IN operation.
- * @param u32 The value to output.
- * @param cb The value size in bytes.
+ * @callback_method_impl{FNIOMIOPORTOUT,Generic VGA OUT dispatcher.}
*/
PDMBOTHCBDECL(int) vgaIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- VGAState *s = PDMINS_2_DATA(pDevIns, PVGASTATE);
-
- int rc = PDMCritSectEnter(&s->lock, VINF_IOM_R3_IOPORT_WRITE);
- if (rc != VINF_SUCCESS)
- return rc;
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
NOREF(pvUser);
if (cb == 1)
- vga_ioport_write(s, Port, u32);
+ vga_ioport_write(pThis, Port, u32);
else if (cb == 2)
{
- vga_ioport_write(s, Port, u32 & 0xff);
- vga_ioport_write(s, Port + 1, u32 >> 8);
+ vga_ioport_write(pThis, Port, u32 & 0xff);
+ vga_ioport_write(pThis, Port + 1, u32 >> 8);
}
- PDMCritSectLeave(&s->lock);
return VINF_SUCCESS;
}
/**
- * Port I/O Handler for VGA IN operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param Port Port number used for the IN operation.
- * @param pu32 Where to store the result.
- * @param cb Number of bytes read.
+ * @callback_method_impl{FNIOMIOPORTOUT,Generic VGA IN dispatcher.}
*/
PDMBOTHCBDECL(int) vgaIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
- VGAState *s = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
NOREF(pvUser);
- int rc = PDMCritSectEnter(&s->lock, VINF_IOM_R3_IOPORT_READ);
- if (rc != VINF_SUCCESS)
- return rc;
-
- rc = VERR_IOM_IOPORT_UNUSED;
+ int rc = VINF_SUCCESS;
if (cb == 1)
- {
- *pu32 = vga_ioport_read(s, Port);
- rc = VINF_SUCCESS;
- }
+ *pu32 = vga_ioport_read(pThis, Port);
else if (cb == 2)
- {
- *pu32 = vga_ioport_read(s, Port)
- | (vga_ioport_read(s, Port + 1) << 8);
- rc = VINF_SUCCESS;
- }
- PDMCritSectLeave(&s->lock);
+ *pu32 = vga_ioport_read(pThis, Port)
+ | (vga_ioport_read(pThis, Port + 1) << 8);
+ else
+ rc = VERR_IOM_IOPORT_UNUSED;
return rc;
}
/**
- * Port I/O Handler for VBE OUT operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param Port Port number used for the IN operation.
- * @param u32 The value to output.
- * @param cb The value size in bytes.
+ * @callback_method_impl{FNIOMIOPORTOUT,VBE Data Port OUT handler.}
*/
PDMBOTHCBDECL(int) vgaIOPortWriteVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- VGAState *s = PDMINS_2_DATA(pDevIns, PVGASTATE);
-
- int rc = PDMCritSectEnter(&s->lock, VINF_IOM_R3_IOPORT_WRITE);
- if (rc != VINF_SUCCESS)
- return rc;
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
NOREF(pvUser);
@@ -2614,41 +2779,33 @@ PDMBOTHCBDECL(int) vgaIOPortWriteVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOP
/*
* This has to be done on the host in order to execute the connector callbacks.
*/
- if ( s->vbe_index == VBE_DISPI_INDEX_ENABLE
- || s->vbe_index == VBE_DISPI_INDEX_VBOX_VIDEO)
+ if ( pThis->vbe_index == VBE_DISPI_INDEX_ENABLE
+ || pThis->vbe_index == VBE_DISPI_INDEX_VBOX_VIDEO)
{
Log(("vgaIOPortWriteVBEData: VBE_DISPI_INDEX_ENABLE - Switching to host...\n"));
- PDMCritSectLeave(&s->lock);
return VINF_IOM_R3_IOPORT_WRITE;
}
#endif
#ifdef VBE_BYTEWISE_IO
if (cb == 1)
{
- if (!s->fWriteVBEData)
+ if (!pThis->fWriteVBEData)
{
- if ( (s->vbe_index == VBE_DISPI_INDEX_ENABLE)
+ if ( (pThis->vbe_index == VBE_DISPI_INDEX_ENABLE)
&& (u32 & VBE_DISPI_ENABLED))
{
- s->fWriteVBEData = false;
- rc = vbe_ioport_write_data(s, Port, u32 & 0xFF);
- PDMCritSectLeave(&s->lock);
- return rc;
- }
- else
- {
- s->cbWriteVBEData = u32 & 0xFF;
- s->fWriteVBEData = true;
- PDMCritSectLeave(&s->lock);
- return VINF_SUCCESS;
+ pThis->fWriteVBEData = false;
+ return vbe_ioport_write_data(pThis, Port, u32 & 0xFF);
}
+
+ pThis->cbWriteVBEData = u32 & 0xFF;
+ pThis->fWriteVBEData = true;
+ return VINF_SUCCESS;
}
- else
- {
- u32 = (s->cbWriteVBEData << 8) | (u32 & 0xFF);
- s->fWriteVBEData = false;
- cb = 2;
- }
+
+ u32 = (pThis->cbWriteVBEData << 8) | (u32 & 0xFF);
+ pThis->fWriteVBEData = false;
+ cb = 2;
}
#endif
if (cb == 2 || cb == 4)
@@ -2659,205 +2816,134 @@ PDMBOTHCBDECL(int) vgaIOPortWriteVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOP
// * Since we're not mapping the entire framebuffer any longer that
// * has to be done on the host.
// */
-// if ( (s->vbe_index == VBE_DISPI_INDEX_ENABLE)
+// if ( (pThis->vbe_index == VBE_DISPI_INDEX_ENABLE)
// && (u32 & VBE_DISPI_ENABLED))
// {
// Log(("vgaIOPortWriteVBEData: VBE_DISPI_INDEX_ENABLE & VBE_DISPI_ENABLED - Switching to host...\n"));
// return VINF_IOM_R3_IOPORT_WRITE;
// }
//#endif
- rc = vbe_ioport_write_data(s, Port, u32);
- PDMCritSectLeave(&s->lock);
- return rc;
+ return vbe_ioport_write_data(pThis, Port, u32);
}
- else
- AssertMsgFailed(("vgaIOPortWriteVBEData: Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
+ AssertMsgFailed(("vgaIOPortWriteVBEData: Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
- PDMCritSectLeave(&s->lock);
return VINF_SUCCESS;
}
/**
- * Port I/O Handler for VBE OUT operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param Port Port number used for the IN operation.
- * @param u32 The value to output.
- * @param cb The value size in bytes.
+ * @callback_method_impl{FNIOMIOPORTOUT,VBE Index Port OUT handler.}
*/
PDMBOTHCBDECL(int) vgaIOPortWriteVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- NOREF(pvUser);
- VGAState *s = PDMINS_2_DATA(pDevIns, PVGASTATE);
-
- int rc = PDMCritSectEnter(&s->lock, VINF_IOM_R3_IOPORT_WRITE);
- if (rc != VINF_SUCCESS)
- return rc;
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE); NOREF(pvUser);
+ Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
#ifdef VBE_BYTEWISE_IO
if (cb == 1)
{
- if (!s->fWriteVBEIndex)
+ if (!pThis->fWriteVBEIndex)
{
- s->cbWriteVBEIndex = u32 & 0x00FF;
- s->fWriteVBEIndex = true;
- PDMCritSectLeave(&s->lock);
- return VINF_SUCCESS;
- }
- else
- {
- s->fWriteVBEIndex = false;
- vbe_ioport_write_index(s, Port, (s->cbWriteVBEIndex << 8) | (u32 & 0x00FF));
- PDMCritSectLeave(&s->lock);
+ pThis->cbWriteVBEIndex = u32 & 0x00FF;
+ pThis->fWriteVBEIndex = true;
return VINF_SUCCESS;
}
+ pThis->fWriteVBEIndex = false;
+ vbe_ioport_write_index(pThis, Port, (pThis->cbWriteVBEIndex << 8) | (u32 & 0x00FF));
+ return VINF_SUCCESS;
}
- else
#endif
+
if (cb == 2)
- vbe_ioport_write_index(s, Port, u32);
+ vbe_ioport_write_index(pThis, Port, u32);
else
AssertMsgFailed(("vgaIOPortWriteVBEIndex: Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
- PDMCritSectLeave(&s->lock);
return VINF_SUCCESS;
}
/**
- * Port I/O Handler for VBE IN operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param Port Port number used for the IN operation.
- * @param pu32 Where to store the result.
- * @param cb Number of bytes to read.
+ * @callback_method_impl{FNIOMIOPORTOUT,VBE Data Port IN handler.}
*/
PDMBOTHCBDECL(int) vgaIOPortReadVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
- NOREF(pvUser);
- VGAState *s = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE); NOREF(pvUser);
+ Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
- int rc = PDMCritSectEnter(&s->lock, VINF_IOM_R3_IOPORT_READ);
- if (rc != VINF_SUCCESS)
- return rc;
#ifdef VBE_BYTEWISE_IO
if (cb == 1)
{
- if (!s->fReadVBEData)
- {
- *pu32 = (vbe_ioport_read_data(s, Port) >> 8) & 0xFF;
- s->fReadVBEData = true;
- PDMCritSectLeave(&s->lock);
- return VINF_SUCCESS;
- }
- else
+ if (!pThis->fReadVBEData)
{
- *pu32 = vbe_ioport_read_data(s, Port) & 0xFF;
- s->fReadVBEData = false;
- PDMCritSectLeave(&s->lock);
+ *pu32 = (vbe_ioport_read_data(pThis, Port) >> 8) & 0xFF;
+ pThis->fReadVBEData = true;
return VINF_SUCCESS;
}
+ *pu32 = vbe_ioport_read_data(pThis, Port) & 0xFF;
+ pThis->fReadVBEData = false;
+ return VINF_SUCCESS;
}
- else
#endif
if (cb == 2)
{
- *pu32 = vbe_ioport_read_data(s, Port);
- PDMCritSectLeave(&s->lock);
+ *pu32 = vbe_ioport_read_data(pThis, Port);
return VINF_SUCCESS;
}
- else if (cb == 4)
+ if (cb == 4)
{
/* Quick hack for getting the vram size. */
- *pu32 = s->vram_size;
- PDMCritSectLeave(&s->lock);
+ *pu32 = pThis->vram_size;
return VINF_SUCCESS;
}
AssertMsgFailed(("vgaIOPortReadVBEData: Port=%#x cb=%d\n", Port, cb));
- PDMCritSectLeave(&s->lock);
return VERR_IOM_IOPORT_UNUSED;
}
/**
- * Port I/O Handler for VBE IN operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param Port Port number used for the IN operation.
- * @param pu32 Where to store the result.
- * @param cb Number of bytes to read.
+ * @callback_method_impl{FNIOMIOPORTOUT,VBE Index Port IN handler.}
*/
PDMBOTHCBDECL(int) vgaIOPortReadVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
NOREF(pvUser);
- VGAState *s = PDMINS_2_DATA(pDevIns, PVGASTATE);
-
- int rc = PDMCritSectEnter(&s->lock, VINF_IOM_R3_IOPORT_READ);
- if (rc != VINF_SUCCESS)
- return rc;
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
#ifdef VBE_BYTEWISE_IO
if (cb == 1)
{
- if (!s->fReadVBEIndex)
+ if (!pThis->fReadVBEIndex)
{
- *pu32 = (vbe_ioport_read_index(s, Port) >> 8) & 0xFF;
- s->fReadVBEIndex = true;
- PDMCritSectLeave(&s->lock);
- return VINF_SUCCESS;
- }
- else
- {
- *pu32 = vbe_ioport_read_index(s, Port) & 0xFF;
- s->fReadVBEIndex = false;
- PDMCritSectLeave(&s->lock);
+ *pu32 = (vbe_ioport_read_index(pThis, Port) >> 8) & 0xFF;
+ pThis->fReadVBEIndex = true;
return VINF_SUCCESS;
}
+ *pu32 = vbe_ioport_read_index(pThis, Port) & 0xFF;
+ pThis->fReadVBEIndex = false;
+ return VINF_SUCCESS;
}
- else
#endif
if (cb == 2)
{
- *pu32 = vbe_ioport_read_index(s, Port);
- PDMCritSectLeave(&s->lock);
+ *pu32 = vbe_ioport_read_index(pThis, Port);
return VINF_SUCCESS;
}
- PDMCritSectLeave(&s->lock);
AssertMsgFailed(("vgaIOPortReadVBEIndex: Port=%#x cb=%d\n", Port, cb));
return VERR_IOM_IOPORT_UNUSED;
}
#ifdef VBOX_WITH_HGSMI
-#ifdef IN_RING3
+# ifdef IN_RING3
/**
- * Port I/O Handler for HGSMI OUT operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param Port Port number used for the operation.
- * @param u32 The value to output.
- * @param cb The value size in bytes.
+ * @callback_method_impl{FNIOMIOPORTOUT,HGSMI OUT handler.}
*/
static DECLCALLBACK(int) vgaR3IOPortHGSMIWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
LogFlowFunc(("Port 0x%x, u32 0x%x, cb %d\n", Port, u32, cb));
- VGAState *s = PDMINS_2_DATA(pDevIns, PVGASTATE);
- int rc = PDMCritSectEnter(&s->lock, VERR_SEM_BUSY);
- if (rc != VINF_SUCCESS)
- return rc;
NOREF(pvUser);
@@ -2867,103 +2953,89 @@ static DECLCALLBACK(int) vgaR3IOPortHGSMIWrite(PPDMDEVINS pDevIns, void *pvUser,
{
case VGA_PORT_HGSMI_HOST: /* Host */
{
-#if defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_WITH_VDMA) || defined(VBOX_WITH_WDDM)
- if(u32 == HGSMIOFFSET_VOID)
+# if defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_WITH_VDMA) || defined(VBOX_WITH_WDDM)
+ if (u32 == HGSMIOFFSET_VOID)
{
PDMDevHlpPCISetIrq(pDevIns, 0, PDM_IRQ_LEVEL_LOW);
- HGSMIClearHostGuestFlags(s->pHGSMI, HGSMIHOSTFLAGS_IRQ
-#ifdef VBOX_VDMA_WITH_WATCHDOG
- | HGSMIHOSTFLAGS_WATCHDOG
-#endif
- | HGSMIHOSTFLAGS_VSYNC
- );
+ HGSMIClearHostGuestFlags(pThis->pHGSMI,
+ HGSMIHOSTFLAGS_IRQ
+# ifdef VBOX_VDMA_WITH_WATCHDOG
+ | HGSMIHOSTFLAGS_WATCHDOG
+# endif
+ | HGSMIHOSTFLAGS_VSYNC
+ );
}
else
-#endif
+# endif
{
- HGSMIHostWrite(s->pHGSMI, u32);
+ HGSMIHostWrite(pThis->pHGSMI, u32);
}
- } break;
+ break;
+ }
case VGA_PORT_HGSMI_GUEST: /* Guest */
- {
- HGSMIGuestWrite(s->pHGSMI, u32);
- } break;
+ HGSMIGuestWrite(pThis->pHGSMI, u32);
+ break;
default:
- {
-#ifdef DEBUG_sunlover
+# ifdef DEBUG_sunlover
AssertMsgFailed(("vgaR3IOPortHGSMIWrite: Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
-#endif
- } break;
+# endif
+ break;
}
}
else
{
-#ifdef DEBUG_sunlover
+# ifdef DEBUG_sunlover
AssertMsgFailed(("vgaR3IOPortHGSMIWrite: Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
-#endif
+# endif
}
- PDMCritSectLeave(&s->lock);
return VINF_SUCCESS;
}
+
/**
- * Port I/O Handler for HGSMI IN operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param Port Port number used for the operation.
- * @param pu32 Where to store the result.
- * @param cb Number of bytes to read.
+ * @callback_method_impl{FNIOMIOPORTOUT,HGSMI IN handler.}
*/
static DECLCALLBACK(int) vgaR3IOPortHGSMIRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
LogFlowFunc(("Port 0x%x, cb %d\n", Port, cb));
- VGAState *s = PDMINS_2_DATA(pDevIns, PVGASTATE);
-
- int rc = PDMCritSectEnter(&s->lock, VERR_SEM_BUSY);
- if (rc != VINF_SUCCESS)
- return rc;
NOREF(pvUser);
+ int rc = VINF_SUCCESS;
if (cb == 4)
{
switch (Port)
{
case VGA_PORT_HGSMI_HOST: /* Host */
- {
- *pu32 = HGSMIHostRead(s->pHGSMI);
- } break;
+ *pu32 = HGSMIHostRead(pThis->pHGSMI);
+ break;
case VGA_PORT_HGSMI_GUEST: /* Guest */
- {
- *pu32 = HGSMIGuestRead(s->pHGSMI);
- } break;
+ *pu32 = HGSMIGuestRead(pThis->pHGSMI);
+ break;
default:
- {
-#ifdef DEBUG_sunlover
+# ifdef DEBUG_sunlover
AssertMsgFailed(("vgaR3IOPortHGSMIRead: Port=%#x cb=%d\n", Port, cb));
-#endif
+# endif
rc = VERR_IOM_IOPORT_UNUSED;
- } break;
+ break;
}
}
else
{
-#ifdef DEBUG_sunlover
+# ifdef DEBUG_sunlover
Log(("vgaR3IOPortHGSMIRead: Port=%#x cb=%d\n", Port, cb));
-#endif
+# endif
rc = VERR_IOM_IOPORT_UNUSED;
}
- PDMCritSectLeave(&s->lock);
return rc;
}
-#endif /* IN_RING3 */
+# endif /* IN_RING3 */
#endif /* VBOX_WITH_HGSMI */
@@ -2971,13 +3043,13 @@ static DECLCALLBACK(int) vgaR3IOPortHGSMIRead(PPDMDEVINS pDevIns, void *pvUser,
/* -=-=-=-=-=- Guest Context -=-=-=-=-=- */
-/*
- * Internal. For use inside VGAGCMemoryFillWrite only.
+/**
+ * @internal. For use inside VGAGCMemoryFillWrite only.
* Macro for apply logical operation and bit mask.
*/
-#define APPLY_LOGICAL_AND_MASK(s, val, bit_mask) \
+#define APPLY_LOGICAL_AND_MASK(pThis, val, bit_mask) \
/* apply logical operation */ \
- switch(s->gr[3] >> 3) \
+ switch (pThis->gr[3] >> 3) \
{ \
case 0: \
default: \
@@ -2985,19 +3057,19 @@ static DECLCALLBACK(int) vgaR3IOPortHGSMIRead(PPDMDEVINS pDevIns, void *pvUser,
break; \
case 1: \
/* and */ \
- val &= s->latch; \
+ val &= pThis->latch; \
break; \
case 2: \
/* or */ \
- val |= s->latch; \
+ val |= pThis->latch; \
break; \
case 3: \
/* xor */ \
- val ^= s->latch; \
+ val ^= pThis->latch; \
break; \
} \
/* apply bit mask */ \
- val = (val & bit_mask) | (s->latch & ~bit_mask)
+ val = (val & bit_mask) | (pThis->latch & ~bit_mask)
/**
* Legacy VGA memory (0xa0000 - 0xbffff) write hook, to be called from IOM and from the inside of VGADeviceGC.cpp.
@@ -3179,57 +3251,40 @@ static int vgaInternalMMIOFill(PVGASTATE pThis, void *pvUser, RTGCPHYS GCPhysAdd
return VINF_SUCCESS;
}
+
/**
- * Legacy VGA memory (0xa0000 - 0xbffff) write hook, to be called from IOM and from the inside of VGADeviceGC.cpp.
- * This is the advanced version of vga_mem_writeb function.
- *
- * @returns VBox status code.
- * @param pDevIns Pointer device instance.
- * @param pvUser User argument - ignored.
- * @param GCPhysAddr Physical address of memory to write.
- * @param u32Item Data to write, up to 4 bytes.
- * @param cbItem Size of data Item, only 1/2/4 bytes is allowed for now.
- * @param cItems Number of data items to write.
+ * @callback_method_impl{FNIOMMMIOFILL,
+ * Legacy VGA memory (0xa0000 - 0xbffff) write hook, to be called from IOM and
+ * from the inside of VGADeviceGC.cpp. This is the advanced version of
+ * vga_mem_writeb function.}
*/
PDMBOTHCBDECL(int) vgaMMIOFill(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems)
{
PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
- int rc = PDMCritSectEnter(&pThis->lock, VINF_IOM_R3_MMIO_WRITE);
- if (rc != VINF_SUCCESS)
- return rc;
-
- rc = vgaInternalMMIOFill(pThis, pvUser, GCPhysAddr, u32Item, cbItem, cItems);
- PDMCritSectLeave(&pThis->lock);
- return rc;
+ return vgaInternalMMIOFill(pThis, pvUser, GCPhysAddr, u32Item, cbItem, cItems);
}
#undef APPLY_LOGICAL_AND_MASK
/**
- * Legacy VGA memory (0xa0000 - 0xbffff) read hook, to be called from IOM.
- *
- * @returns VBox status code.
- * @param pDevIns Pointer device instance.
- * @param pvUser User argument - ignored.
- * @param GCPhysAddr Physical address of memory to read.
- * @param pv Where to store read data.
- * @param cb Bytes to read.
+ * @callback_method_impl{FNIOMMMIOREAD, Legacy VGA memory (0xa0000 - 0xbffff)
+ * read hook, to be called from IOM.}
*/
PDMBOTHCBDECL(int) vgaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
{
PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
STAM_PROFILE_START(&pThis->CTX_MID_Z(Stat,MemoryRead), a);
+ Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
NOREF(pvUser);
- int rc = PDMCritSectEnter(&pThis->lock, VINF_IOM_R3_MMIO_READ);
- if (rc != VINF_SUCCESS)
- return rc;
-
+ int rc = VINF_SUCCESS;
switch (cb)
{
case 1:
- *(uint8_t *)pv = vga_mem_readb(pThis, GCPhysAddr, &rc); break;
+ *(uint8_t *)pv = vga_mem_readb(pThis, GCPhysAddr, &rc);
+ break;
case 2:
*(uint16_t *)pv = vga_mem_readb(pThis, GCPhysAddr, &rc)
| (vga_mem_readb(pThis, GCPhysAddr + 1, &rc) << 8);
@@ -3263,20 +3318,14 @@ PDMBOTHCBDECL(int) vgaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhys
}
}
}
+
STAM_PROFILE_STOP(&pThis->CTX_MID_Z(Stat,MemoryRead), a);
- PDMCritSectLeave(&pThis->lock);
return rc;
}
/**
- * Legacy VGA memory (0xa0000 - 0xbffff) write hook, to be called from IOM.
- *
- * @returns VBox status code.
- * @param pDevIns Pointer device instance.
- * @param pvUser User argument - ignored.
- * @param GCPhysAddr Physical address of memory to write.
- * @param pv Pointer to data.
- * @param cb Bytes to write.
+ * @callback_method_impl{FNIOMMMIOWRITE, Legacy VGA memory (0xa0000 - 0xbffff)
+ * write hook, to be called from IOM.}
*/
PDMBOTHCBDECL(int) vgaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
{
@@ -3284,11 +3333,9 @@ PDMBOTHCBDECL(int) vgaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhy
uint8_t *pu8 = (uint8_t *)pv;
NOREF(pvUser);
STAM_PROFILE_START(&pThis->CTX_MID_Z(Stat,MemoryWrite), a);
+ Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
- int rc = PDMCritSectEnter(&pThis->lock, VINF_IOM_R3_MMIO_WRITE);
- if (rc != VINF_SUCCESS)
- return rc;
-
+ int rc;
switch (cb)
{
case 1:
@@ -3338,13 +3385,13 @@ PDMBOTHCBDECL(int) vgaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhy
break;
#endif
default:
+ rc = VINF_SUCCESS;
while (cb-- > 0 && rc == VINF_SUCCESS)
rc = vga_mem_writeb(pThis, GCPhysAddr++, *pu8++);
break;
}
STAM_PROFILE_STOP(&pThis->CTX_MID_Z(Stat,MemoryWrite), a);
- PDMCritSectLeave(&pThis->lock);
return rc;
}
@@ -3359,7 +3406,7 @@ PDMBOTHCBDECL(int) vgaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhy
*/
static int vgaLFBAccess(PVM pVM, PVGASTATE pThis, RTGCPHYS GCPhys, RTGCPTR GCPtr)
{
- int rc = PDMCritSectEnter(&pThis->lock, VINF_EM_RAW_EMULATE_INSTR);
+ int rc = PDMCritSectEnter(&pThis->CritSect, VINF_EM_RAW_EMULATE_INSTR);
if (rc != VINF_SUCCESS)
return rc;
@@ -3380,7 +3427,7 @@ static int vgaLFBAccess(PVM pVM, PVGASTATE pThis, RTGCPHYS GCPhys, RTGCPTR GCPtr
#ifndef IN_RING3
rc = PGMShwMakePageWritable(PDMDevHlpGetVMCPU(pThis->CTX_SUFF(pDevIns)), GCPtr,
PGM_MK_PG_IS_MMIO2 | PGM_MK_PG_IS_WRITE_FAULT);
- PDMCritSectLeave(&pThis->lock);
+ PDMCritSectLeave(&pThis->CritSect);
AssertMsgReturn( rc == VINF_SUCCESS
/* In the SMP case the page table might be removed while we wait for the PGM lock in the trap handler. */
|| rc == VERR_PAGE_TABLE_NOT_PRESENT
@@ -3388,13 +3435,13 @@ static int vgaLFBAccess(PVM pVM, PVGASTATE pThis, RTGCPHYS GCPhys, RTGCPTR GCPtr
("PGMShwModifyPage -> GCPtr=%RGv rc=%d\n", GCPtr, rc),
rc);
#else /* IN_RING3 : We don't have any virtual page address of the access here. */
- PDMCritSectLeave(&pThis->lock);
+ PDMCritSectLeave(&pThis->CritSect);
Assert(GCPtr == 0);
#endif
return VINF_SUCCESS;
}
- PDMCritSectLeave(&pThis->lock);
+ PDMCritSectLeave(&pThis->CritSect);
AssertMsgFailed(("PGMHandlerPhysicalPageTempOff -> rc=%d\n", rc));
return rc;
}
@@ -3402,17 +3449,9 @@ static int vgaLFBAccess(PVM pVM, PVGASTATE pThis, RTGCPHYS GCPhys, RTGCPTR GCPtr
#ifdef IN_RC
/**
- * #PF Handler for VBE LFB access.
- *
- * @returns VBox status code (appropriate for GC return).
- * @param pVM VM Handle.
- * @param uErrorCode CPU Error code.
- * @param pRegFrame Trap register frame.
- * @param pvFault The fault address (cr2).
- * @param GCPhysFault The GC physical address corresponding to pvFault.
- * @param pvUser User argument, ignored.
+ * @callback_method_impl{FNPGMRCPHYSHANDLER, \#PF Handler for VBE LFB access.}
*/
-PDMBOTHCBDECL(int) vgaGCLFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser)
+PDMBOTHCBDECL(int) vgaRCLFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser)
{
PVGASTATE pThis = (PVGASTATE)pvUser;
AssertPtr(pThis);
@@ -3426,15 +3465,7 @@ PDMBOTHCBDECL(int) vgaGCLFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXC
#elif IN_RING0
/**
- * #PF Handler for VBE LFB access.
- *
- * @returns VBox status code (appropriate for GC return).
- * @param pVM VM Handle.
- * @param uErrorCode CPU Error code.
- * @param pRegFrame Trap register frame.
- * @param pvFault The fault address (cr2).
- * @param GCPhysFault The GC physical address corresponding to pvFault.
- * @param pvUser User argument, ignored.
+ * @callback_method_impl{FNPGMR0PHYSHANDLER, \#PF Handler for VBE LFB access.}
*/
PDMBOTHCBDECL(int) vgaR0LFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser)
{
@@ -3450,17 +3481,7 @@ PDMBOTHCBDECL(int) vgaR0LFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXC
#else /* IN_RING3 */
/**
- * HC access handler for the LFB.
- *
- * @returns VINF_SUCCESS if the handler have carried out the operation.
- * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
- * @param pVM VM Handle.
- * @param GCPhys The physical address the guest is writing to.
- * @param pvPhys The HC mapping of that address.
- * @param pvBuf What the guest is reading/writing.
- * @param cbBuf How much it's reading/writing.
- * @param enmAccessType The access type.
- * @param pvUser User argument.
+ * @callback_method_impl{FNPGMR3PHYSHANDLER, HC access handler for the LFB.}
*/
static DECLCALLBACK(int) vgaR3LFBAccessHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
{
@@ -3481,15 +3502,8 @@ static DECLCALLBACK(int) vgaR3LFBAccessHandler(PVM pVM, RTGCPHYS GCPhys, void *p
/* -=-=-=-=-=- All rings: VGA BIOS I/Os -=-=-=-=-=- */
/**
- * Port I/O Handler for VGA BIOS IN operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param Port Port number used for the IN operation.
- * @param pu32 Where to store the result.
- * @param cb Number of bytes read.
+ * @callback_method_impl{FNIOMIOPORTIN,
+ * Port I/O Handler for VGA BIOS IN operations.}
*/
PDMBOTHCBDECL(int) vgaIOPortReadBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
@@ -3502,25 +3516,15 @@ PDMBOTHCBDECL(int) vgaIOPortReadBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT
}
/**
- * Port I/O Handler for VGA BIOS OUT operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param Port Port number used for the IN operation.
- * @param u32 The value to output.
- * @param cb The value size in bytes.
+ * @callback_method_impl{FNIOMIOPORTOUT,
+ * Port I/O Handler for VGA BIOS IN operations.}
*/
PDMBOTHCBDECL(int) vgaIOPortWriteBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
static int lastWasNotNewline = 0; /* We are only called in a single-threaded way */
PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
NOREF(pvUser);
-
- int rc = PDMCritSectEnter(&pThis->lock, VINF_IOM_R3_IOPORT_WRITE);
- if (rc != VINF_SUCCESS)
- return rc;
+ Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
/*
* VGA BIOS char printing.
@@ -3547,11 +3551,9 @@ PDMBOTHCBDECL(int) vgaIOPortWriteBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT
else
lastWasNotNewline = 1;
#endif
- PDMCritSectLeave(&pThis->lock);
return VINF_SUCCESS;
}
- PDMCritSectLeave(&pThis->lock);
/* not in use. */
return VERR_IOM_IOPORT_UNUSED;
}
@@ -3563,25 +3565,14 @@ PDMBOTHCBDECL(int) vgaIOPortWriteBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT
# ifdef VBE_NEW_DYN_LIST
/**
- * Port I/O Handler for VBE Extra OUT operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param Port Port number used for the IN operation.
- * @param u32 The value to output.
- * @param cb The value size in bytes.
+ * @callback_method_impl{FNIOMIOPORTOUT,
+ * Port I/O Handler for VBE Extra OUT operations.}
*/
PDMBOTHCBDECL(int) vbeIOPortWriteVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
- NOREF(pvUser);
- NOREF(Port);
-
- int rc = PDMCritSectEnter(&pThis->lock, VINF_IOM_R3_IOPORT_WRITE);
- if (rc != VINF_SUCCESS)
- return rc;
+ Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
+ NOREF(pvUser); NOREF(Port);
if (cb == 2)
{
@@ -3590,64 +3581,46 @@ PDMBOTHCBDECL(int) vbeIOPortWriteVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIO
}
else
Log(("vbeIOPortWriteVBEExtra: Ignoring invalid cb=%d writes to the VBE Extra port!!!\n", cb));
- PDMCritSectLeave(&pThis->lock);
return VINF_SUCCESS;
}
/**
- * Port I/O Handler for VBE Extra IN operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param Port Port number used for the IN operation.
- * @param pu32 Where to store the result.
- * @param cb Number of bytes read.
+ * @callback_method_impl{FNIOMIOPORTIN,
+ * Port I/O Handler for VBE Extra IN operations.}
*/
PDMBOTHCBDECL(int) vbeIOPortReadVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
- NOREF(pvUser);
- NOREF(Port);
-
- int rc = PDMCritSectEnter(&pThis->lock, VINF_IOM_R3_IOPORT_READ);
- if (rc != VINF_SUCCESS)
- return rc;
+ NOREF(pvUser); NOREF(Port);
+ Assert(PDMCritSectIsOwner(pDevIns->CTX_SUFF(pCritSectRo)));
+ int rc = VINF_SUCCESS;
if (pThis->u16VBEExtraAddress == 0xffff)
{
Log(("vbeIOPortReadVBEExtra: Requested number of 64k video banks\n"));
*pu32 = pThis->vram_size / _64K;
- rc = VINF_SUCCESS;
}
- else
- if ( pThis->u16VBEExtraAddress >= pThis->cbVBEExtraData
- || pThis->u16VBEExtraAddress + cb > pThis->cbVBEExtraData)
+ else if ( pThis->u16VBEExtraAddress >= pThis->cbVBEExtraData
+ || pThis->u16VBEExtraAddress + cb > pThis->cbVBEExtraData)
{
*pu32 = 0;
Log(("vbeIOPortReadVBEExtra: Requested address is out of VBE data!!! Address=%#x(%d) cbVBEExtraData=%#x(%d)\n",
pThis->u16VBEExtraAddress, pThis->u16VBEExtraAddress, pThis->cbVBEExtraData, pThis->cbVBEExtraData));
- rc = VINF_SUCCESS;
}
- else
- if (cb == 1)
+ else if (cb == 1)
{
*pu32 = pThis->pu8VBEExtraData[pThis->u16VBEExtraAddress] & 0xFF;
Log(("vbeIOPortReadVBEExtra: cb=%#x %.*Rhxs\n", cb, cb, pu32));
- rc = VINF_SUCCESS;
}
- else
- if (cb == 2)
+ else if (cb == 2)
{
*pu32 = pThis->pu8VBEExtraData[pThis->u16VBEExtraAddress]
| pThis->pu8VBEExtraData[pThis->u16VBEExtraAddress + 1] << 8;
Log(("vbeIOPortReadVBEExtra: cb=%#x %.*Rhxs\n", cb, cb, pu32));
- rc = VINF_SUCCESS;
}
else
{
@@ -3655,7 +3628,6 @@ PDMBOTHCBDECL(int) vbeIOPortReadVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOP
rc = VERR_IOM_IOPORT_UNUSED;
}
- PDMCritSectLeave(&pThis->lock);
return rc;
}
# endif /* VBE_NEW_DYN_LIST */
@@ -3716,39 +3688,30 @@ static int vbeParseBitmap(PVGASTATE pThis)
break;
default:
- AssertMsgFailed(("Unsupported bitmap header.\n"));
+ AssertLogRelMsgFailedReturn(("Unsupported bitmap header size %u.\n", pWinHdr->Size),
+ VERR_INVALID_PARAMETER);
break;
}
- if (pThis->cxLogo > LOGO_MAX_WIDTH || pThis->cyLogo > LOGO_MAX_HEIGHT)
- {
- AssertMsgFailed(("Bitmap %ux%u is too big.\n", pThis->cxLogo, pThis->cyLogo));
- return VERR_INVALID_PARAMETER;
- }
+ AssertLogRelMsgReturn(pThis->cxLogo <= LOGO_MAX_WIDTH && pThis->cyLogo <= LOGO_MAX_HEIGHT,
+ ("Bitmap %ux%u is too big.\n", pThis->cxLogo, pThis->cyLogo),
+ VERR_INVALID_PARAMETER);
- if (pThis->cLogoPlanes != 1)
- {
- AssertMsgFailed(("Bitmap planes %u != 1.\n", pThis->cLogoPlanes));
- return VERR_INVALID_PARAMETER;
- }
+ AssertLogRelMsgReturn(pThis->cLogoPlanes == 1,
+ ("Bitmap planes %u != 1.\n", pThis->cLogoPlanes),
+ VERR_INVALID_PARAMETER);
- if (pThis->cLogoBits != 4 && pThis->cLogoBits != 8 && pThis->cLogoBits != 24)
- {
- AssertMsgFailed(("Unsupported %u depth.\n", pThis->cLogoBits));
- return VERR_INVALID_PARAMETER;
- }
+ AssertLogRelMsgReturn(pThis->cLogoBits == 4 || pThis->cLogoBits == 8 || pThis->cLogoBits == 24,
+ ("Unsupported %u depth.\n", pThis->cLogoBits),
+ VERR_INVALID_PARAMETER);
- if (pThis->cLogoUsedColors > 256)
- {
- AssertMsgFailed(("Unsupported %u colors.\n", pThis->cLogoUsedColors));
- return VERR_INVALID_PARAMETER;
- }
+ AssertLogRelMsgReturn(pThis->cLogoUsedColors <= 256,
+ ("Unsupported %u colors.\n", pThis->cLogoUsedColors),
+ VERR_INVALID_PARAMETER);
- if (pThis->LogoCompression != BMP_COMPRESS_NONE)
- {
- AssertMsgFailed(("Unsupported %u compression.\n", pThis->LogoCompression));
- return VERR_INVALID_PARAMETER;
- }
+ AssertLogRelMsgReturn(pThis->LogoCompression == BMP_COMPRESS_NONE,
+ ("Unsupported %u compression.\n", pThis->LogoCompression),
+ VERR_INVALID_PARAMETER);
/*
* Read bitmap palette
@@ -3784,6 +3747,8 @@ static int vbeParseBitmap(PVGASTATE pThis)
*/
pThis->pu8LogoBitmap = pThis->pu8Logo + sizeof(LOGOHDR) + bmpInfo->Offset;
}
+ else
+ AssertLogRelMsgFailedReturn(("Not a BMP file.\n"), VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
}
@@ -3931,18 +3896,9 @@ static void vbeShowBitmap(uint16_t cBits, uint16_t xLogo, uint16_t yLogo, uint16
}
-
-
/**
- * Port I/O Handler for BIOS Logo OUT operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param Port Port number used for the IN operation.
- * @param u32 The value to output.
- * @param cb The value size in bytes.
+ * @callback_method_impl{FNIOMIOPORTOUT,
+ * Port I/O Handler for BIOS Logo OUT operations.}
*/
PDMBOTHCBDECL(int) vbeIOPortWriteCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
@@ -4043,15 +3999,8 @@ PDMBOTHCBDECL(int) vbeIOPortWriteCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOP
/**
- * Port I/O Handler for BIOS Logo IN operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument - ignored.
- * @param Port Port number used for the IN operation.
- * @param pu32 Where to store the result.
- * @param cb Number of bytes read.
+ * @callback_method_impl{FNIOMIOPORTIN,
+ * Port I/O Handler for BIOS Logo IN operations.}
*/
PDMBOTHCBDECL(int) vbeIOPortReadCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
@@ -4085,52 +4034,52 @@ PDMBOTHCBDECL(int) vbeIOPortReadCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPO
return VINF_SUCCESS;
}
+
+/* -=-=-=-=-=- Ring 3: Debug Info Handlers -=-=-=-=-=- */
+
/**
- * Info handler, device version. Dumps several interesting bits of the
- * VGA state that are difficult to decode from the registers.
- *
- * @param pDevIns Device instance which registered the info.
- * @param pHlp Callback functions for doing output.
- * @param pszArgs Argument string. Optional and specific to the handler.
+ * @callback_method_impl{FNDBGFHANDLERDEV,
+ * Dumps several interesting bits of the VGA state that are difficult to
+ * decode from the registers.}
*/
static DECLCALLBACK(void) vgaInfoState(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
- PVGASTATE s = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
int is_graph, double_scan;
int w, h, char_height, char_dots;
int val, vfreq_hz, hfreq_hz;
- vga_retrace_s *r = &s->retrace_state;
+ vga_retrace_s *r = &pThis->retrace_state;
const char *clocks[] = { "25.175 MHz", "28.322 MHz", "External", "Reserved?!" };
NOREF(pszArgs);
- is_graph = s->gr[6] & 1;
- char_dots = (s->sr[0x01] & 1) ? 8 : 9;
- double_scan = s->cr[9] >> 7;
- pHlp->pfnPrintf(pHlp, "pixel clock: %s\n", clocks[(s->msr >> 2) & 3]);
+ is_graph = pThis->gr[6] & 1;
+ char_dots = (pThis->sr[0x01] & 1) ? 8 : 9;
+ double_scan = pThis->cr[9] >> 7;
+ pHlp->pfnPrintf(pHlp, "pixel clock: %s\n", clocks[(pThis->msr >> 2) & 3]);
pHlp->pfnPrintf(pHlp, "double scanning %s\n", double_scan ? "on" : "off");
- pHlp->pfnPrintf(pHlp, "double clocking %s\n", s->sr[1] & 0x08 ? "on" : "off");
- val = s->cr[0] + 5;
+ pHlp->pfnPrintf(pHlp, "double clocking %s\n", pThis->sr[1] & 0x08 ? "on" : "off");
+ val = pThis->cr[0] + 5;
pHlp->pfnPrintf(pHlp, "htotal: %d px (%d cclk)\n", val * char_dots, val);
- val = s->cr[6] + ((s->cr[7] & 1) << 8) + ((s->cr[7] & 0x20) << 4) + 2;
+ val = pThis->cr[6] + ((pThis->cr[7] & 1) << 8) + ((pThis->cr[7] & 0x20) << 4) + 2;
pHlp->pfnPrintf(pHlp, "vtotal: %d px\n", val);
- val = s->cr[1] + 1;
+ val = pThis->cr[1] + 1;
w = val * char_dots;
pHlp->pfnPrintf(pHlp, "hdisp : %d px (%d cclk)\n", w, val);
- val = s->cr[0x12] + ((s->cr[7] & 2) << 7) + ((s->cr[7] & 0x40) << 4) + 1;
+ val = pThis->cr[0x12] + ((pThis->cr[7] & 2) << 7) + ((pThis->cr[7] & 0x40) << 4) + 1;
h = val;
pHlp->pfnPrintf(pHlp, "vdisp : %d px\n", val);
- val = ((s->cr[9] & 0x40) << 3) + ((s->cr[7] & 0x10) << 4) + s->cr[0x18];
+ val = ((pThis->cr[9] & 0x40) << 3) + ((pThis->cr[7] & 0x10) << 4) + pThis->cr[0x18];
pHlp->pfnPrintf(pHlp, "split : %d ln\n", val);
- val = (s->cr[0xc] << 8) + s->cr[0xd];
+ val = (pThis->cr[0xc] << 8) + pThis->cr[0xd];
pHlp->pfnPrintf(pHlp, "start : %#x\n", val);
if (!is_graph)
{
- val = (s->cr[9] & 0x1f) + 1;
+ val = (pThis->cr[9] & 0x1f) + 1;
char_height = val;
pHlp->pfnPrintf(pHlp, "char height %d\n", val);
pHlp->pfnPrintf(pHlp, "text mode %dx%d\n", w / char_dots, h / (char_height << double_scan));
}
- if (s->fRealRetrace)
+ if (pThis->fRealRetrace)
{
val = r->hb_start;
pHlp->pfnPrintf(pHlp, "hblank start: %d px (%d cclk)\n", val * char_dots, val);
@@ -4145,7 +4094,7 @@ static DECLCALLBACK(void) vgaInfoState(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, c
pHlp->pfnPrintf(pHlp, "vfreq: %d Hz, hfreq: %d.%03d kHz\n",
vfreq_hz, hfreq_hz / 1000, hfreq_hz % 1000);
}
- pHlp->pfnPrintf(pHlp, "display refresh interval: %u ms\n", s->cMilliesRefreshInterval);
+ pHlp->pfnPrintf(pHlp, "display refresh interval: %u ms\n", pThis->cMilliesRefreshInterval);
}
@@ -4243,12 +4192,9 @@ static void vgaInfoTextWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp,
/**
- * Info handler, device version. Dumps VGA memory formatted as
- * ASCII text, no attributes. Only looks at the first page.
- *
- * @param pDevIns Device instance which registered the info.
- * @param pHlp Callback functions for doing output.
- * @param pszArgs Argument string. Optional and specific to the handler.
+ * @callback_method_impl{FNDBGFHANDLERDEV,
+ * Dumps VGA memory formatted as ASCII text, no attributes. Only looks at the
+ * first page.}
*/
static DECLCALLBACK(void) vgaInfoText(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
@@ -4321,198 +4267,162 @@ static DECLCALLBACK(void) vgaInfoText(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, co
/**
- * Info handler, device version. Dumps VGA Sequencer registers.
- *
- * @param pDevIns Device instance which registered the info.
- * @param pHlp Callback functions for doing output.
- * @param pszArgs Argument string. Optional and specific to the handler.
+ * @callback_method_impl{FNDBGFHANDLERDEV, Dumps VGA Sequencer registers.}
*/
static DECLCALLBACK(void) vgaInfoSR(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
- PVGASTATE s = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
unsigned i;
NOREF(pszArgs);
- pHlp->pfnPrintf(pHlp, "VGA Sequencer (3C5): SR index 3C4:%02X\n", s->sr_index);
- Assert(sizeof(s->sr) >= 8);
+ pHlp->pfnPrintf(pHlp, "VGA Sequencer (3C5): SR index 3C4:%02X\n", pThis->sr_index);
+ Assert(sizeof(pThis->sr) >= 8);
for (i = 0; i < 5; ++i)
- pHlp->pfnPrintf(pHlp, " SR%02X:%02X", i, s->sr[i]);
+ pHlp->pfnPrintf(pHlp, " SR%02X:%02X", i, pThis->sr[i]);
pHlp->pfnPrintf(pHlp, "\n");
}
/**
- * Info handler, device version. Dumps VGA CRTC registers.
- *
- * @param pDevIns Device instance which registered the info.
- * @param pHlp Callback functions for doing output.
- * @param pszArgs Argument string. Optional and specific to the handler.
+ * @callback_method_impl{FNDBGFHANDLERDEV, Dumps VGA CRTC registers.}
*/
static DECLCALLBACK(void) vgaInfoCR(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
- PVGASTATE s = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
unsigned i;
NOREF(pszArgs);
- pHlp->pfnPrintf(pHlp, "VGA CRTC (3D5): CRTC index 3D4:%02X\n", s->cr_index);
- Assert(sizeof(s->cr) >= 24);
+ pHlp->pfnPrintf(pHlp, "VGA CRTC (3D5): CRTC index 3D4:%02X\n", pThis->cr_index);
+ Assert(sizeof(pThis->cr) >= 24);
for (i = 0; i < 10; ++i)
- {
- pHlp->pfnPrintf(pHlp, " CR%02X:%02X", i, s->cr[i]);
- }
+ pHlp->pfnPrintf(pHlp, " CR%02X:%02X", i, pThis->cr[i]);
pHlp->pfnPrintf(pHlp, "\n");
for (i = 10; i < 20; ++i)
- {
- pHlp->pfnPrintf(pHlp, " CR%02X:%02X", i, s->cr[i]);
- }
+ pHlp->pfnPrintf(pHlp, " CR%02X:%02X", i, pThis->cr[i]);
pHlp->pfnPrintf(pHlp, "\n");
for (i = 20; i < 25; ++i)
- {
- pHlp->pfnPrintf(pHlp, " CR%02X:%02X", i, s->cr[i]);
- }
+ pHlp->pfnPrintf(pHlp, " CR%02X:%02X", i, pThis->cr[i]);
pHlp->pfnPrintf(pHlp, "\n");
}
/**
- * Info handler, device version. Dumps VGA Graphics Controller registers.
- *
- * @param pDevIns Device instance which registered the info.
- * @param pHlp Callback functions for doing output.
- * @param pszArgs Argument string. Optional and specific to the handler.
+ * @callback_method_impl{FNDBGFHANDLERDEV,
+ * Dumps VGA Graphics Controller registers.}
*/
static DECLCALLBACK(void) vgaInfoGR(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
- PVGASTATE s = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
unsigned i;
NOREF(pszArgs);
- pHlp->pfnPrintf(pHlp, "VGA Graphics Controller (3CF): GR index 3CE:%02X\n", s->gr_index);
- Assert(sizeof(s->gr) >= 9);
+ pHlp->pfnPrintf(pHlp, "VGA Graphics Controller (3CF): GR index 3CE:%02X\n", pThis->gr_index);
+ Assert(sizeof(pThis->gr) >= 9);
for (i = 0; i < 9; ++i)
{
- pHlp->pfnPrintf(pHlp, " GR%02X:%02X", i, s->gr[i]);
+ pHlp->pfnPrintf(pHlp, " GR%02X:%02X", i, pThis->gr[i]);
}
pHlp->pfnPrintf(pHlp, "\n");
}
/**
- * Info handler, device version. Dumps VGA Sequencer registers.
- *
- * @param pDevIns Device instance which registered the info.
- * @param pHlp Callback functions for doing output.
- * @param pszArgs Argument string. Optional and specific to the handler.
+ * @callback_method_impl{FNDBGFHANDLERDEV,
+ * Dumps VGA Attribute Controller registers.}
*/
static DECLCALLBACK(void) vgaInfoAR(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
- PVGASTATE s = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
unsigned i;
NOREF(pszArgs);
pHlp->pfnPrintf(pHlp, "VGA Attribute Controller (3C0): index reg %02X, flip-flop: %d (%s)\n",
- s->ar_index, s->ar_flip_flop, s->ar_flip_flop ? "data" : "index" );
- Assert(sizeof(s->ar) >= 0x14);
+ pThis->ar_index, pThis->ar_flip_flop, pThis->ar_flip_flop ? "data" : "index" );
+ Assert(sizeof(pThis->ar) >= 0x14);
pHlp->pfnPrintf(pHlp, " Palette:");
for (i = 0; i < 0x10; ++i)
- {
- pHlp->pfnPrintf(pHlp, " %02X", i, s->ar[i]);
- }
+ pHlp->pfnPrintf(pHlp, " %02X", pThis->ar[i]);
pHlp->pfnPrintf(pHlp, "\n");
for (i = 0x10; i <= 0x14; ++i)
- {
- pHlp->pfnPrintf(pHlp, " AR%02X:%02X", i, s->ar[i]);
- }
+ pHlp->pfnPrintf(pHlp, " AR%02X:%02X", i, pThis->ar[i]);
pHlp->pfnPrintf(pHlp, "\n");
}
+
/**
- * Info handler, device version. Dumps VGA DAC registers.
- *
- * @param pDevIns Device instance which registered the info.
- * @param pHlp Callback functions for doing output.
- * @param pszArgs Argument string. Optional and specific to the handler.
+ * @callback_method_impl{FNDBGFHANDLERDEV, Dumps VGA DAC registers.}
*/
static DECLCALLBACK(void) vgaInfoDAC(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
- PVGASTATE s = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
unsigned i;
NOREF(pszArgs);
pHlp->pfnPrintf(pHlp, "VGA DAC contents:\n");
for (i = 0; i < 0x100; ++i)
- {
pHlp->pfnPrintf(pHlp, " %02X: %02X %02X %02X\n",
- i, s->palette[i*3+0], s->palette[i*3+1], s->palette[i*3+2]);
- }
+ i, pThis->palette[i*3+0], pThis->palette[i*3+1], pThis->palette[i*3+2]);
}
/**
- * Info handler, device version. Dumps VBE registers.
- *
- * @param pDevIns Device instance which registered the info.
- * @param pHlp Callback functions for doing output.
- * @param pszArgs Argument string. Optional and specific to the handler.
+ * @callback_method_impl{FNDBGFHANDLERDEV, Dumps VBE registers.}
*/
static DECLCALLBACK(void) vgaInfoVBE(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
- PVGASTATE s = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
NOREF(pszArgs);
- pHlp->pfnPrintf(pHlp, "LFB at %RGp\n", s->GCPhysVRAM);
+ pHlp->pfnPrintf(pHlp, "LFB at %RGp\n", pThis->GCPhysVRAM);
- if (!(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED))
+ if (!(pThis->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED))
{
pHlp->pfnPrintf(pHlp, "VBE disabled\n");
return;
}
- pHlp->pfnPrintf(pHlp, "VBE state (chip ID 0x%04x):\n", s->vbe_regs[VBE_DISPI_INDEX_ID]);
+ pHlp->pfnPrintf(pHlp, "VBE state (chip ID 0x%04x):\n", pThis->vbe_regs[VBE_DISPI_INDEX_ID]);
pHlp->pfnPrintf(pHlp, " Display resolution: %d x %d @ %dbpp\n",
- s->vbe_regs[VBE_DISPI_INDEX_XRES], s->vbe_regs[VBE_DISPI_INDEX_YRES],
- s->vbe_regs[VBE_DISPI_INDEX_BPP]);
+ pThis->vbe_regs[VBE_DISPI_INDEX_XRES], pThis->vbe_regs[VBE_DISPI_INDEX_YRES],
+ pThis->vbe_regs[VBE_DISPI_INDEX_BPP]);
pHlp->pfnPrintf(pHlp, " Virtual resolution: %d x %d\n",
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH], s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT]);
+ pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH], pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT]);
pHlp->pfnPrintf(pHlp, " Display start addr: %d, %d\n",
- s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET], s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET]);
- pHlp->pfnPrintf(pHlp, " Linear scanline pitch: 0x%04x\n", s->vbe_line_offset);
- pHlp->pfnPrintf(pHlp, " Linear display start : 0x%04x\n", s->vbe_start_addr);
- pHlp->pfnPrintf(pHlp, " Selected bank: 0x%04x\n", s->vbe_regs[VBE_DISPI_INDEX_BANK]);
+ pThis->vbe_regs[VBE_DISPI_INDEX_X_OFFSET], pThis->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET]);
+ pHlp->pfnPrintf(pHlp, " Linear scanline pitch: 0x%04x\n", pThis->vbe_line_offset);
+ pHlp->pfnPrintf(pHlp, " Linear display start : 0x%04x\n", pThis->vbe_start_addr);
+ pHlp->pfnPrintf(pHlp, " Selected bank: 0x%04x\n", pThis->vbe_regs[VBE_DISPI_INDEX_BANK]);
}
/**
- * Info handler, device version. Dumps register state relevant
- * to 16-color planar graphics modes (GR/SR) in human-readable form.
- *
- * @param pDevIns Device instance which registered the info.
- * @param pHlp Callback functions for doing output.
- * @param pszArgs Argument string. Optional and specific to the handler.
+ * @callback_method_impl{FNDBGFHANDLERDEV,
+ * Dumps register state relevant to 16-color planar graphics modes (GR/SR)
+ * in human-readable form.}
*/
static DECLCALLBACK(void) vgaInfoPlanar(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
- PVGASTATE s = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
int val1, val2;
NOREF(pszArgs);
- val1 = (s->gr[5] >> 3) & 1;
- val2 = s->gr[5] & 3;
+ val1 = (pThis->gr[5] >> 3) & 1;
+ val2 = pThis->gr[5] & 3;
pHlp->pfnPrintf(pHlp, "read mode : %d write mode: %d\n", val1, val2);
- val1 = s->gr[0];
- val2 = s->gr[1];
+ val1 = pThis->gr[0];
+ val2 = pThis->gr[1];
pHlp->pfnPrintf(pHlp, "set/reset data: %02X S/R enable: %02X\n", val1, val2);
- val1 = s->gr[2];
- val2 = s->gr[4] & 3;
+ val1 = pThis->gr[2];
+ val2 = pThis->gr[4] & 3;
pHlp->pfnPrintf(pHlp, "color compare : %02X read map : %d\n", val1, val2);
- val1 = s->gr[3] & 7;
- val2 = (s->gr[3] >> 3) & 3;
+ val1 = pThis->gr[3] & 7;
+ val2 = (pThis->gr[3] >> 3) & 3;
pHlp->pfnPrintf(pHlp, "rotate : %d function : %d\n", val1, val2);
- val1 = s->gr[7];
- val2 = s->gr[8];
+ val1 = pThis->gr[7];
+ val2 = pThis->gr[8];
pHlp->pfnPrintf(pHlp, "don't care : %02X bit mask : %02X\n", val1, val2);
- val1 = s->sr[2];
- val2 = s->sr[4] & 8;
+ val1 = pThis->sr[2];
+ val2 = pThis->sr[4] & 8;
pHlp->pfnPrintf(pHlp, "seq plane mask: %02X chain-4 : %s\n", val1, val2 ? "on" : "off");
}
@@ -4607,15 +4517,25 @@ static DECLCALLBACK(int) vgaPortUpdateDisplay(PPDMIDISPLAYPORT pInterface)
PDMDEV_ASSERT_EMT(VGASTATE2DEVINS(pThis));
PPDMDEVINS pDevIns = pThis->CTX_SUFF(pDevIns);
- int rc = PDMCritSectEnter(&pThis->lock, VERR_SEM_BUSY);
+ int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
AssertRC(rc);
+#ifdef VBOX_WITH_VMSVGA
+ if ( pThis->svga.fEnabled
+ && !pThis->svga.fTraces)
+ {
+ /* Nothing to do as the guest will explicitely update us about frame buffer changes. */
+ PDMCritSectLeave(&pThis->CritSect);
+ return VINF_SUCCESS;
+ }
+#endif
+
#ifndef VBOX_WITH_HGSMI
/* This should be called only in non VBVA mode. */
#else
if (VBVAUpdateDisplay (pThis) == VINF_SUCCESS)
{
- PDMCritSectLeave(&pThis->lock);
+ PDMCritSectLeave(&pThis->CritSect);
return VINF_SUCCESS;
}
#endif /* VBOX_WITH_HGSMI */
@@ -4633,26 +4553,29 @@ static DECLCALLBACK(int) vgaPortUpdateDisplay(PPDMIDISPLAYPORT pInterface)
}
rc = vga_update_display(pThis, false, false, true);
- if (rc != VINF_SUCCESS)
- {
- PDMCritSectLeave(&pThis->lock);
- return rc;
- }
- PDMCritSectLeave(&pThis->lock);
- return VINF_SUCCESS;
+ PDMCritSectLeave(&pThis->CritSect);
+ return rc;
}
/**
- * Internal vgaPortUpdateDisplayAll worker called under pThis->lock.
+ * Internal vgaPortUpdateDisplayAll worker called under pThis->CritSect.
*/
static int updateDisplayAll(PVGASTATE pThis)
{
PPDMDEVINS pDevIns = pThis->CTX_SUFF(pDevIns);
+#ifdef VBOX_WITH_VMSVGA
+ if ( !pThis->svga.fEnabled
+ || pThis->svga.fTraces)
+ {
+#endif
/* The dirty bits array has been just cleared, reset handlers as well. */
if (pThis->GCPhysVRAM && pThis->GCPhysVRAM != NIL_RTGCPHYS)
PGMHandlerPhysicalReset(PDMDevHlpGetVM(pDevIns), pThis->GCPhysVRAM);
+#ifdef VBOX_WITH_VMSVGA
+ }
+#endif
if (pThis->fRemappedVGA)
{
IOMMMIOResetRegion(PDMDevHlpGetVM(pDevIns), 0x000a0000);
@@ -4682,12 +4605,12 @@ static DECLCALLBACK(int) vgaPortUpdateDisplayAll(PPDMIDISPLAYPORT pInterface)
LogFlow(("vgaPortUpdateDisplayAll\n"));
#endif /* DEBUG_sunlover */
- int rc = PDMCritSectEnter(&pThis->lock, VERR_SEM_BUSY);
+ int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
AssertRC(rc);
rc = updateDisplayAll(pThis);
- PDMCritSectLeave(&pThis->lock);
+ PDMCritSectLeave(&pThis->CritSect);
return rc;
}
@@ -4746,7 +4669,7 @@ static DECLCALLBACK(int) vgaPortTakeScreenshot(PPDMIDISPLAYPORT pInterface, uint
if (!RT_VALID_PTR(ppu8Data) || !RT_VALID_PTR(pcbData) || !RT_VALID_PTR(pcx) || !RT_VALID_PTR(pcy))
return VERR_INVALID_PARAMETER;
- int rc = PDMCritSectEnter(&pThis->lock, VERR_SEM_BUSY);
+ int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
AssertRCReturn(rc, rc);
/*
@@ -4833,7 +4756,7 @@ static DECLCALLBACK(int) vgaPortTakeScreenshot(PPDMIDISPLAYPORT pInterface, uint
else
rc = VERR_NOT_SUPPORTED;
- PDMCritSectLeave(&pThis->lock);
+ PDMCritSectLeave(&pThis->CritSect);
LogFlow(("vgaPortTakeScreenshot: returns %Rrc (cbData=%d cx=%d cy=%d)\n", rc, *pcbData, *pcx, *pcy));
return rc;
@@ -4873,7 +4796,7 @@ static DECLCALLBACK(int) vgaPortDisplayBlt(PPDMIDISPLAYPORT pInterface, const vo
PDMDEV_ASSERT_EMT(VGASTATE2DEVINS(pThis));
LogFlow(("vgaPortDisplayBlt: pvData=%p x=%d y=%d cx=%d cy=%d\n", pvData, x, y, cx, cy));
- rc = PDMCritSectEnter(&pThis->lock, VERR_SEM_BUSY);
+ rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
AssertRC(rc);
/*
@@ -4938,13 +4861,13 @@ static DECLCALLBACK(int) vgaPortDisplayBlt(PPDMIDISPLAYPORT pInterface, const vo
else
rc = VERR_INVALID_PARAMETER;
- PDMCritSectLeave(&pThis->lock);
+ PDMCritSectLeave(&pThis->CritSect);
LogFlow(("vgaPortDisplayBlt: returns %Rrc\n", rc));
return rc;
}
-static DECLCALLBACK(void) vgaPortUpdateDisplayRect (PPDMIDISPLAYPORT pInterface, int32_t x, int32_t y, uint32_t w, uint32_t h)
+static DECLCALLBACK(void) vgaPortUpdateDisplayRect(PPDMIDISPLAYPORT pInterface, int32_t x, int32_t y, uint32_t w, uint32_t h)
{
uint32_t v;
vga_draw_line_func *vga_draw_line;
@@ -4959,18 +4882,18 @@ static DECLCALLBACK(void) vgaPortUpdateDisplayRect (PPDMIDISPLAYPORT pInterface,
uint32_t u32OffsetSrc, u32Dummy;
- PVGASTATE s = IDISPLAYPORT_2_VGASTATE(pInterface);
+ PVGASTATE pThis = IDISPLAYPORT_2_VGASTATE(pInterface);
#ifdef DEBUG_sunlover
LogFlow(("vgaPortUpdateDisplayRect: %d,%d %dx%d\n", x, y, w, h));
#endif /* DEBUG_sunlover */
Assert(pInterface);
- Assert(s->pDrv);
- Assert(s->pDrv->pu8Data);
+ Assert(pThis->pDrv);
+ Assert(pThis->pDrv->pu8Data);
/* Check if there is something to do at all. */
- if (!s->fRenderVRAM)
+ if (!pThis->fRenderVRAM)
{
/* The framebuffer uses the guest VRAM directly. */
#ifdef DEBUG_sunlover
@@ -4979,7 +4902,7 @@ static DECLCALLBACK(void) vgaPortUpdateDisplayRect (PPDMIDISPLAYPORT pInterface,
return;
}
- int rc = PDMCritSectEnter(&s->lock, VERR_SEM_BUSY);
+ int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
AssertRC(rc);
/* Correct negative x and y coordinates. */
@@ -4998,16 +4921,16 @@ static DECLCALLBACK(void) vgaPortUpdateDisplayRect (PPDMIDISPLAYPORT pInterface,
}
/* Also check if coords are greater than the display resolution. */
- if (x + w > s->pDrv->cx)
+ if (x + w > pThis->pDrv->cx)
{
// x < 0 is not possible here
- w = s->pDrv->cx > (uint32_t)x? s->pDrv->cx - x: 0;
+ w = pThis->pDrv->cx > (uint32_t)x? pThis->pDrv->cx - x: 0;
}
- if (y + h > s->pDrv->cy)
+ if (y + h > pThis->pDrv->cy)
{
// y < 0 is not possible here
- h = s->pDrv->cy > (uint32_t)y? s->pDrv->cy - y: 0;
+ h = pThis->pDrv->cy > (uint32_t)y? pThis->pDrv->cy - y: 0;
}
#ifdef DEBUG_sunlover
@@ -5021,7 +4944,7 @@ static DECLCALLBACK(void) vgaPortUpdateDisplayRect (PPDMIDISPLAYPORT pInterface,
#ifdef DEBUG_sunlover
LogFlow(("vgaPortUpdateDisplayRect: nothing to do: %dx%d\n", w, h));
#endif /* DEBUG_sunlover */
- PDMCritSectLeave(&s->lock);
+ PDMCritSectLeave(&pThis->CritSect);
return;
}
@@ -5031,7 +4954,7 @@ static DECLCALLBACK(void) vgaPortUpdateDisplayRect (PPDMIDISPLAYPORT pInterface,
*/
/* Choose the rendering function. */
- switch(s->get_bpp(s))
+ switch(pThis->get_bpp(pThis))
{
default:
case 0:
@@ -5039,7 +4962,7 @@ static DECLCALLBACK(void) vgaPortUpdateDisplayRect (PPDMIDISPLAYPORT pInterface,
* by Display because VBVA buffer is being flushed.
* Nothing to do, just return.
*/
- PDMCritSectLeave(&s->lock);
+ PDMCritSectLeave(&pThis->CritSect);
return;
case 8:
v = VGA_DRAW_LINE8;
@@ -5058,20 +4981,20 @@ static DECLCALLBACK(void) vgaPortUpdateDisplayRect (PPDMIDISPLAYPORT pInterface,
break;
}
- vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->pDrv->cBits)];
+ vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(pThis->pDrv->cBits)];
/* Compute source and destination addresses and pitches. */
- cbPixelDst = (s->pDrv->cBits + 7) / 8;
- cbLineDst = s->pDrv->cbScanline;
- pu8Dst = s->pDrv->pu8Data + y * cbLineDst + x * cbPixelDst;
+ cbPixelDst = (pThis->pDrv->cBits + 7) / 8;
+ cbLineDst = pThis->pDrv->cbScanline;
+ pu8Dst = pThis->pDrv->pu8Data + y * cbLineDst + x * cbPixelDst;
- cbPixelSrc = (s->get_bpp(s) + 7) / 8;
- s->get_offsets(s, &cbLineSrc, &u32OffsetSrc, &u32Dummy);
+ cbPixelSrc = (pThis->get_bpp(pThis) + 7) / 8;
+ pThis->get_offsets(pThis, &cbLineSrc, &u32OffsetSrc, &u32Dummy);
/* Assume that rendering is performed only on visible part of VRAM.
* This is true because coordinates were verified.
*/
- pu8Src = s->vram_ptrR3;
+ pu8Src = pThis->vram_ptrR3;
pu8Src += u32OffsetSrc * 4 + y * cbLineSrc + x * cbPixelSrc;
/* Render VRAM to framebuffer. */
@@ -5082,12 +5005,12 @@ static DECLCALLBACK(void) vgaPortUpdateDisplayRect (PPDMIDISPLAYPORT pInterface,
while (h-- > 0)
{
- vga_draw_line (s, pu8Dst, pu8Src, w);
+ vga_draw_line (pThis, pu8Dst, pu8Src, w);
pu8Dst += cbLineDst;
pu8Src += cbLineSrc;
}
- PDMCritSectLeave(&s->lock);
+ PDMCritSectLeave(&pThis->CritSect);
#ifdef DEBUG_sunlover
LogFlow(("vgaPortUpdateDisplayRect: completed.\n"));
#endif /* DEBUG_sunlover */
@@ -5126,10 +5049,10 @@ static DECLCALLBACK(int) vgaPortCopyRect (PPDMIDISPLAYPORT pInterface,
LogFlow(("vgaPortCopyRect: %d,%d %dx%d -> %d,%d\n", xSrc, ySrc, w, h, xDst, yDst));
#endif /* DEBUG_sunlover */
- PVGASTATE s = IDISPLAYPORT_2_VGASTATE(pInterface);
+ PVGASTATE pThis = IDISPLAYPORT_2_VGASTATE(pInterface);
Assert(pInterface);
- Assert(s->pDrv);
+ Assert(pThis->pDrv);
int32_t xSrcCorrected = xSrc;
int32_t ySrcCorrected = ySrc;
@@ -5213,9 +5136,16 @@ static DECLCALLBACK(int) vgaPortCopyRect (PPDMIDISPLAYPORT pInterface,
break;
}
- int rc = PDMCritSectEnter(&s->lock, VERR_SEM_BUSY);
+ int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
AssertRC(rc);
+ /* This method only works if the VGA device is in a VBE mode. */
+ if ((pThis->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) == 0)
+ {
+ PDMCritSectLeave(&pThis->CritSect);
+ return VERR_INVALID_STATE;
+ }
+
vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(u32DstBitsPerPixel)];
/* Compute source and destination addresses and pitches. */
@@ -5233,12 +5163,12 @@ static DECLCALLBACK(int) vgaPortCopyRect (PPDMIDISPLAYPORT pInterface,
while (hCorrected-- > 0)
{
- vga_draw_line (s, pu8DstPtr, pu8SrcPtr, wCorrected);
+ vga_draw_line (pThis, pu8DstPtr, pu8SrcPtr, wCorrected);
pu8DstPtr += cbLineDst;
pu8SrcPtr += cbLineSrc;
}
- PDMCritSectLeave(&s->lock);
+ PDMCritSectLeave(&pThis->CritSect);
#ifdef DEBUG_sunlover
LogFlow(("vgaPortCopyRect: completed.\n"));
#endif /* DEBUG_sunlover */
@@ -5248,11 +5178,16 @@ static DECLCALLBACK(int) vgaPortCopyRect (PPDMIDISPLAYPORT pInterface,
static DECLCALLBACK(void) vgaPortSetRenderVRAM(PPDMIDISPLAYPORT pInterface, bool fRender)
{
- PVGASTATE s = IDISPLAYPORT_2_VGASTATE(pInterface);
+ PVGASTATE pThis = IDISPLAYPORT_2_VGASTATE(pInterface);
LogFlow(("vgaPortSetRenderVRAM: fRender = %d\n", fRender));
- s->fRenderVRAM = fRender;
+ int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
+ AssertRC(rc);
+
+ pThis->fRenderVRAM = fRender;
+
+ PDMCritSectLeave(&pThis->CritSect);
}
@@ -5271,8 +5206,42 @@ static DECLCALLBACK(void) vgaTimerRefresh(PPDMDEVINS pDevIns, PTMTIMER pTimer, v
if (pThis->cMilliesRefreshInterval)
TMTimerSetMillies(pTimer, pThis->cMilliesRefreshInterval);
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ vbvaTimerCb(pThis);
+#endif
+
+ vboxCmdVBVACmdTimer(pThis);
}
+#ifdef VBOX_WITH_VMSVGA
+int vgaR3RegisterVRAMHandler(PVGASTATE pVGAState, uint64_t cbFrameBuffer)
+{
+ PPDMDEVINS pDevIns = pVGAState->pDevInsR3;
+
+ Assert(pVGAState->GCPhysVRAM);
+
+ int rc = PGMR3HandlerPhysicalRegister(PDMDevHlpGetVM(pDevIns),
+ PGMPHYSHANDLERTYPE_PHYSICAL_WRITE,
+ pVGAState->GCPhysVRAM, pVGAState->GCPhysVRAM + (cbFrameBuffer - 1),
+ vgaR3LFBAccessHandler, pVGAState,
+ g_DeviceVga.szR0Mod, "vgaR0LFBAccessHandler", pDevIns->pvInstanceDataR0,
+ g_DeviceVga.szRCMod, "vgaGCLFBAccessHandler", pDevIns->pvInstanceDataRC,
+ "VGA LFB");
+ AssertRC(rc);
+ return rc;
+}
+
+int vgaR3UnregisterVRAMHandler(PVGASTATE pVGAState)
+{
+ PPDMDEVINS pDevIns = pVGAState->pDevInsR3;
+
+ Assert(pVGAState->GCPhysVRAM);
+ int rc = PGMHandlerPhysicalDeregister(PDMDevHlpGetVM(pDevIns), pVGAState->GCPhysVRAM);
+ AssertRC(rc);
+ return rc;
+}
+#endif
/* -=-=-=-=-=- Ring 3: PCI Device -=-=-=-=-=- */
@@ -5293,7 +5262,11 @@ static DECLCALLBACK(int) vgaR3IORegionMap(PPCIDEVICE pPciDev, /*unsigned*/ int i
PPDMDEVINS pDevIns = pPciDev->pDevIns;
PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
LogFlow(("vgaR3IORegionMap: iRegion=%d GCPhysAddress=%RGp cb=%#x enmType=%d\n", iRegion, GCPhysAddress, cb, enmType));
+#ifdef VBOX_WITH_VMSVGA
+ AssertReturn((iRegion == ((pThis->fVMSVGAEnabled) ? 1 : 0)) && (enmType == ((pThis->fVMSVGAEnabled) ? PCI_ADDRESS_SPACE_MEM : PCI_ADDRESS_SPACE_MEM_PREFETCH)), VERR_INTERNAL_ERROR);
+#else
AssertReturn(iRegion == 0 && enmType == PCI_ADDRESS_SPACE_MEM_PREFETCH, VERR_INTERNAL_ERROR);
+#endif
if (GCPhysAddress != NIL_RTGCPHYS)
{
@@ -5309,7 +5282,7 @@ static DECLCALLBACK(int) vgaR3IORegionMap(PPCIDEVICE pPciDev, /*unsigned*/ int i
GCPhysAddress, GCPhysAddress + (pThis->vram_size - 1),
vgaR3LFBAccessHandler, pThis,
g_DeviceVga.szR0Mod, "vgaR0LFBAccessHandler", pDevIns->pvInstanceDataR0,
- g_DeviceVga.szRCMod, "vgaGCLFBAccessHandler", pDevIns->pvInstanceDataRC,
+ g_DeviceVga.szRCMod, "vgaRCLFBAccessHandler", pDevIns->pvInstanceDataRC,
"VGA LFB");
AssertRC(rc);
if (RT_SUCCESS(rc))
@@ -5326,6 +5299,9 @@ static DECLCALLBACK(int) vgaR3IORegionMap(PPCIDEVICE pPciDev, /*unsigned*/ int i
* Deregister the access handler so PGM doesn't get upset.
*/
Assert(pThis->GCPhysVRAM);
+#ifdef VBOX_WITH_VMSVGA
+ Assert(!pThis->svga.fEnabled);
+#endif
rc = PGMHandlerPhysicalDeregister(PDMDevHlpGetVM(pDevIns), pThis->GCPhysVRAM);
AssertRC(rc);
pThis->GCPhysVRAM = 0;
@@ -5403,8 +5379,13 @@ static DECLCALLBACK(int) vgaR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
return rc;
#else
SSMR3PutBool(pSSM, false);
- return VINF_SUCCESS;
#endif
+#ifdef VBOX_WITH_VMSVGA
+ if ( rc == VINF_SUCCESS
+ && pThis->fVMSVGAEnabled)
+ rc = vmsvgaSaveExec(pDevIns, pSSM);
+#endif
+ return rc;
}
@@ -5455,6 +5436,14 @@ static DECLCALLBACK(int) vgaR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("HGSMI is not compiled in, but it is present in the saved state"));
#endif
}
+#ifdef VBOX_WITH_VMSVGA
+ if ( uVersion >= VGA_SAVEDSTATE_VERSION_VMSVGA_2D
+ && pThis->fVMSVGAEnabled)
+ {
+ rc = vmsvgaLoadExec(pDevIns, pSSM, uVersion, uPass);
+ AssertRCReturn(rc, rc);
+ }
+#endif
}
return VINF_SUCCESS;
}
@@ -5466,6 +5455,8 @@ static DECLCALLBACK(int) vgaR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint
static DECLCALLBACK(int) vgaR3LoadDone(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
{
#ifdef VBOX_WITH_HGSMI
+ PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+ VBVAPause(pThis, (pThis->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) == 0);
return vboxVBVALoadStateDone(pDevIns, pSSM);
#else
return VINF_SUCCESS;
@@ -5476,10 +5467,7 @@ static DECLCALLBACK(int) vgaR3LoadDone(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
/* -=-=-=-=-=- Ring 3: Device callbacks -=-=-=-=-=- */
/**
- * Reset notification.
- *
- * @returns VBox status.
- * @param pDevIns The device instance data.
+ * @interface_method_impl{PDMDEVREG,pfnReset}
*/
static DECLCALLBACK(void) vgaR3Reset(PPDMDEVINS pDevIns)
{
@@ -5488,6 +5476,9 @@ static DECLCALLBACK(void) vgaR3Reset(PPDMDEVINS pDevIns)
char *pchEnd;
LogFlow(("vgaReset\n"));
+ if (pThis->pVdma)
+ vboxVDMAReset(pThis->pVdma);
+
#ifdef VBOX_WITH_HGSMI
VBVAReset(pThis);
#endif /* VBOX_WITH_HGSMI */
@@ -5554,7 +5545,11 @@ static DECLCALLBACK(void) vgaR3Reset(PPDMDEVINS pDevIns)
/* notify port handler */
if (pThis->pDrv)
+ {
+ PDMCritSectLeave(&pThis->CritSect); /* hack around lock order issue. */
pThis->pDrv->pfnReset(pThis->pDrv);
+ PDMCritSectEnter(&pThis->CritSect, VERR_IGNORED);
+ }
/* Reset latched access mask. */
pThis->uMaskLatchAccess = 0x3ff;
@@ -5568,12 +5563,7 @@ static DECLCALLBACK(void) vgaR3Reset(PPDMDEVINS pDevIns)
/**
- * Device relocation callback.
- *
- * @param pDevIns Pointer to the device instance.
- * @param offDelta The relocation delta relative to the old location.
- *
- * @see FNPDMDEVRELOCATE for details.
+ * @interface_method_impl{PDMDEVREG,pfnRelocate}
*/
static DECLCALLBACK(void) vgaR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
{
@@ -5582,7 +5572,6 @@ static DECLCALLBACK(void) vgaR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
LogFlow(("vgaRelocate: offDelta = %08X\n", offDelta));
- pThis->RCPtrLFBHandler += offDelta;
pThis->vram_ptrRC += offDelta;
pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
}
@@ -5590,18 +5579,9 @@ static DECLCALLBACK(void) vgaR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
/**
- * Attach command.
- *
- * This is called to let the device attach to a driver for a specified LUN
- * during runtime. This is not called during VM construction, the device
- * constructor have to attach to all the available drivers.
+ * @interface_method_impl{PDMDEVREG,pfnAttach}
*
* This is like plugging in the monitor after turning on the PC.
- *
- * @returns VBox status code.
- * @param pDevIns The device instance.
- * @param iLUN The logical unit which is being detached.
- * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
*/
static DECLCALLBACK(int) vgaAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
{
@@ -5670,16 +5650,9 @@ static DECLCALLBACK(int) vgaAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t
/**
- * Detach notification.
- *
- * This is called when a driver is detaching itself from a LUN of the device.
- * The device should adjust it's state to reflect this.
+ * @interface_method_impl{PDMDEVREG,pfnDetach}
*
* This is like unplugging the monitor while the PC is still running.
- *
- * @param pDevIns The device instance.
- * @param iLUN The logical unit which is being detached.
- * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
*/
static DECLCALLBACK(void) vgaDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
{
@@ -5707,12 +5680,7 @@ static DECLCALLBACK(void) vgaDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t
/**
- * Destruct a device instance.
- *
- * Most VM resources are freed by the VM. This callback is provided so that any non-VM
- * resources can be freed correctly.
- *
- * @param pDevIns The device instance data.
+ * @interface_method_impl{PDMDEVREG,pfnDestruct}
*/
static DECLCALLBACK(int) vgaR3Destruct(PPDMDEVINS pDevIns)
{
@@ -5722,8 +5690,13 @@ static DECLCALLBACK(int) vgaR3Destruct(PPDMDEVINS pDevIns)
PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
LogFlow(("vgaR3Destruct:\n"));
-#ifdef VBOX_WITH_VDMA
+# ifdef VBOX_WITH_VDMA
vboxVDMADestruct(pThis->pVdma);
+# endif
+
+#ifdef VBOX_WITH_VMSVGA
+ if (pThis->fVMSVGAEnabled)
+ vmsvgaDestruct(pDevIns);
#endif
/*
@@ -5734,7 +5707,7 @@ static DECLCALLBACK(int) vgaR3Destruct(PPDMDEVINS pDevIns)
MMR3HeapFree(pThis->pu8VBEExtraData);
pThis->pu8VBEExtraData = NULL;
}
-#endif
+#endif /* VBE_NEW_DYN_LIST */
if (pThis->pu8VgaBios)
{
MMR3HeapFree(pThis->pu8VgaBios);
@@ -5753,10 +5726,11 @@ static DECLCALLBACK(int) vgaR3Destruct(PPDMDEVINS pDevIns)
pThis->pszLogoFile = NULL;
}
- PDMR3CritSectDelete(&pThis->lock);
+ PDMR3CritSectDelete(&pThis->CritSect);
return VINF_SUCCESS;
}
+
/**
* Adjust VBE mode information
*
@@ -5783,6 +5757,7 @@ static void vgaAdjustModeInfo(PVGASTATE pThis, ModeInfoListItem *pMode)
pMode->info.LinNumberOfPages = maxPage;
}
+
/**
* @interface_method_impl{PDMDEVREG,pfnConstruct}
*/
@@ -5849,7 +5824,15 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
"CustomVideoMode15\0"
"CustomVideoMode16\0"
"MaxBiosXRes\0"
- "MaxBiosYRes\0"))
+ "MaxBiosYRes\0"
+#ifdef VBOX_WITH_VMSVGA
+ "VMSVGAEnabled\0"
+#endif
+#ifdef VBOX_WITH_VMSVGA3D
+ "VMSVGA3dEnabled\0"
+ "HostWindowId\0"
+#endif
+ ))
return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
N_("Invalid configuration for vga device"));
@@ -5878,6 +5861,20 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
AssertLogRelRCReturn(rc, rc);
Log(("VGA: VRamSize=%#x fGCenabled=%RTbool fR0Enabled=%RTbool\n", pThis->vram_size, pThis->fGCEnabled, pThis->fR0Enabled));
+#ifdef VBOX_WITH_VMSVGA
+ rc = CFGMR3QueryBoolDef(pCfg, "VMSVGAEnabled", &pThis->fVMSVGAEnabled, false);
+ AssertLogRelRCReturn(rc, rc);
+ Log(("VMSVGA: VMSVGAEnabled = %d\n", pThis->fVMSVGAEnabled));
+#endif
+#ifdef VBOX_WITH_VMSVGA3D
+ rc = CFGMR3QueryBoolDef(pCfg, "VMSVGA3dEnabled", &pThis->svga.f3DEnabled, false);
+ AssertLogRelRCReturn(rc, rc);
+ rc = CFGMR3QueryU64Def(pCfg, "HostWindowId", &pThis->svga.u64HostWindowId, 0);
+ AssertLogRelRCReturn(rc, rc);
+ Log(("VMSVGA: VMSVGA3dEnabled = %d\n", pThis->svga.f3DEnabled));
+ Log(("VMSVGA: HostWindowId = 0x%x\n", pThis->svga.u64HostWindowId));
+#endif
+
pThis->pDevInsR3 = pDevIns;
pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
@@ -5885,8 +5882,23 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
vgaR3Reset(pDevIns);
/* The PCI devices configuration. */
+#ifdef VBOX_WITH_VMSVGA
+ if (pThis->fVMSVGAEnabled)
+ {
+ /* Extend our VGA device with VMWare SVGA functionality. */
+ PCIDevSetVendorId(&pThis->Dev, PCI_VENDOR_ID_VMWARE);
+ PCIDevSetDeviceId(&pThis->Dev, PCI_DEVICE_ID_VMWARE_SVGA2);
+ PCIDevSetSubSystemVendorId(&pThis->Dev, PCI_VENDOR_ID_VMWARE);
+ PCIDevSetSubSystemId(&pThis->Dev, PCI_DEVICE_ID_VMWARE_SVGA2);
+ }
+ else
+ {
+#endif /* VBOX_WITH_VMSVGA */
PCIDevSetVendorId( &pThis->Dev, 0x80ee); /* PCI vendor, just a free bogus value */
PCIDevSetDeviceId( &pThis->Dev, 0xbeef);
+#ifdef VBOX_WITH_VMSVGA
+ }
+#endif
PCIDevSetClassSub( &pThis->Dev, 0x00); /* VGA controller */
PCIDevSetClassBase( &pThis->Dev, 0x03);
PCIDevSetHeaderType(&pThis->Dev, 0x00);
@@ -5894,14 +5906,6 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
PCIDevSetInterruptPin(&pThis->Dev, 1);
#endif
- /* The LBF access handler - error handling is better here than in the map function. */
- rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pReg->szRCMod, NULL, "vgaGCLFBAccessHandler", &pThis->RCPtrLFBHandler);
- if (RT_FAILURE(rc))
- {
- AssertReleaseMsgFailed(("PDMR3LdrGetSymbolRC(, %s, \"vgaGCLFBAccessHandler\",) -> %Rrc\n", pDevIns->pReg->szRCMod, rc));
- return rc;
- }
-
/* the interfaces. */
pThis->IBase.pfnQueryInterface = vgaPortQueryInterface;
@@ -5925,34 +5929,74 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
pThis->IVBVACallbacks.pfnCrHgsmiControlCompleteAsync = vboxVDMACrHgsmiControlCompleteAsync;
# endif
#endif
+ pThis->IVBVACallbacks.pfnCrCtlSubmit = vboxCmdVBVACmdHostCtl;
+
+ /*
+ * We use our own critical section to avoid unncessary pointer indirections
+ * in interface methods (as we all as for historical reasons).
+ */
+ rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "VGA#%u", iInstance);
+ AssertRCReturn(rc, rc);
+ rc = PDMDevHlpSetDeviceCritSect(pDevIns, &pThis->CritSect);
+ AssertRCReturn(rc, rc);
/*
* Allocate the VRAM and map the first 512KB of it into GC so we can speed up VGA support.
*/
- rc = PDMDevHlpMMIO2Register(pDevIns, 0 /* iRegion */, pThis->vram_size, 0, (void **)&pThis->vram_ptrR3, "VRam");
+#ifdef VBOX_WITH_VMSVGA
+ int iPCIRegionVRAM = (pThis->fVMSVGAEnabled) ? 1 : 0;
+
+ if (pThis->fVMSVGAEnabled)
+ {
+ /*
+ * Allocate and initialize the FIFO MMIO2 memory.
+ */
+ rc = PDMDevHlpMMIO2Register(pDevIns, 2 /*iRegion*/, VMSVGA_FIFO_SIZE, 0 /*fFlags*/, (void **)&pThis->svga.pFIFOR3, "VMSVGA-FIFO");
+ if (RT_FAILURE(rc))
+ return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
+ N_("Failed to allocate %u bytes of memory for the VMSVGA device"), VMSVGA_FIFO_SIZE);
+ pThis->svga.pFIFOR0 = (RTR0PTR)pThis->svga.pFIFOR3;
+ pThis->svga.cbFIFO = VMSVGA_FIFO_SIZE;
+ }
+#else
+ int iPCIRegionVRAM = 0;
+#endif
+ rc = PDMDevHlpMMIO2Register(pDevIns, iPCIRegionVRAM, pThis->vram_size, 0, (void **)&pThis->vram_ptrR3, "VRam");
AssertLogRelMsgRCReturn(rc, ("PDMDevHlpMMIO2Register(%#x,) -> %Rrc\n", pThis->vram_size, rc), rc);
pThis->vram_ptrR0 = (RTR0PTR)pThis->vram_ptrR3; /** @todo @bugref{1865} Map parts into R0 or just use PGM access (Mac only). */
if (pThis->fGCEnabled)
{
RTRCPTR pRCMapping = 0;
- rc = PDMDevHlpMMHyperMapMMIO2(pDevIns, 0 /* iRegion */, 0 /* off */, VGA_MAPPING_SIZE, "VGA VRam", &pRCMapping);
+ rc = PDMDevHlpMMHyperMapMMIO2(pDevIns, iPCIRegionVRAM, 0 /* off */, VGA_MAPPING_SIZE, "VGA VRam", &pRCMapping);
AssertLogRelMsgRCReturn(rc, ("PDMDevHlpMMHyperMapMMIO2(%#x,) -> %Rrc\n", VGA_MAPPING_SIZE, rc), rc);
pThis->vram_ptrRC = pRCMapping;
+# ifdef VBOX_WITH_VMSVGA
+ /* Don't need a mapping in RC */
+# endif
}
#if defined(VBOX_WITH_2X_4GB_ADDR_SPACE)
if (pThis->fR0Enabled)
{
RTR0PTR pR0Mapping = 0;
- rc = PDMDevHlpMMIO2MapKernel(pDevIns, 0 /* iRegion */, 0 /* off */, VGA_MAPPING_SIZE, "VGA VRam", &pR0Mapping);
+ rc = PDMDevHlpMMIO2MapKernel(pDevIns, iPCIRegionVRAM, 0 /* off */, VGA_MAPPING_SIZE, "VGA VRam", &pR0Mapping);
AssertLogRelMsgRCReturn(rc, ("PDMDevHlpMapMMIO2IntoR0(%#x,) -> %Rrc\n", VGA_MAPPING_SIZE, rc), rc);
pThis->vram_ptrR0 = pR0Mapping;
+# ifdef VBOX_WITH_VMSVGA
+ if (pThis->fVMSVGAEnabled)
+ {
+ RTR0PTR pR0Mapping = 0;
+ rc = PDMDevHlpMMIO2MapKernel(pDevIns, 2 /* iRegion */, 0 /* off */, VMSVGA_FIFO_SIZE, "VMSVGA-FIFO", &pR0Mapping);
+ AssertLogRelMsgRCReturn(rc, ("PDMDevHlpMapMMIO2IntoR0(%#x,) -> %Rrc\n", VMSVGA_FIFO_SIZE, rc), rc);
+ pThis->svga.pFIFOR0 = pR0Mapping;
+ }
+# endif
}
#endif
/*
- * Register I/O ports, ROM and save state.
+ * Register I/O ports.
*/
rc = PDMDevHlpIOPortRegister(pDevIns, 0x3c0, 16, NULL, vgaIOPortWrite, vgaIOPortRead, NULL, NULL, "VGA - 3c0");
if (RT_FAILURE(rc))
@@ -6094,8 +6138,6 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
pThis->pszVgaBiosFile = NULL;
}
- const uint8_t *pu8VgaBiosBinary = NULL;
- uint64_t cbVgaBiosBinary;
/*
* Determine the VGA BIOS ROM size, open specified ROM file in the process.
*/
@@ -6160,7 +6202,9 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
/* If we were unable to get the data from file for whatever reason, fall
back to the built-in ROM image. */
- uint32_t fFlags = 0;
+ const uint8_t *pu8VgaBiosBinary;
+ uint64_t cbVgaBiosBinary;
+ uint32_t fFlags = 0;
if (pThis->pu8VgaBios == NULL)
{
pu8VgaBiosBinary = g_abVgaBiosBinary;
@@ -6181,7 +6225,9 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
if (RT_FAILURE(rc))
return rc;
- /* save */
+ /*
+ * Saved state.
+ */
rc = PDMDevHlpSSMRegisterEx(pDevIns, VGA_SAVEDSTATE_VERSION, sizeof(*pThis), NULL,
NULL, vgaR3LiveExec, NULL,
vgaR3SavePrep, vgaR3SaveExec, vgaR3SaveDone,
@@ -6189,7 +6235,9 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
if (RT_FAILURE(rc))
return rc;
- /* PCI */
+ /*
+ * PCI device registration.
+ */
rc = PDMDevHlpPCIRegister(pDevIns, &pThis->Dev);
if (RT_FAILURE(rc))
return rc;
@@ -6197,17 +6245,26 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
if (pThis->Dev.devfn != 16 && iInstance == 0)
Log(("!!WARNING!!: pThis->dev.devfn=%d (ignore if testcase or not started by Main)\n", pThis->Dev.devfn));
- rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0 /* iRegion */, pThis->vram_size, PCI_ADDRESS_SPACE_MEM_PREFETCH, vgaR3IORegionMap);
- if (RT_FAILURE(rc))
- return rc;
-
- /* Initialize the PDM lock. */
- rc = PDMDevHlpCritSectInit(pDevIns, &pThis->lock, RT_SRC_POS, "VGA#u", iInstance);
- if (RT_FAILURE(rc))
+#ifdef VBOX_WITH_VMSVGA
+ if (pThis->fVMSVGAEnabled)
{
- Log(("%s: Failed to create critical section.\n", __FUNCTION__));
- return rc;
+ /* Register the io command ports. */
+ rc = PDMDevHlpPCIIORegionRegister (pDevIns, 0 /* iRegion */, 0x10, PCI_ADDRESS_SPACE_IO, vmsvgaR3IORegionMap);
+ if (RT_FAILURE (rc))
+ return rc;
+ /* VMware's MetalKit doesn't like PCI_ADDRESS_SPACE_MEM_PREFETCH */
+ rc = PDMDevHlpPCIIORegionRegister(pDevIns, 1 /* iRegion */, pThis->vram_size, PCI_ADDRESS_SPACE_MEM /* PCI_ADDRESS_SPACE_MEM_PREFETCH */, vgaR3IORegionMap);
+ if (RT_FAILURE(rc))
+ return rc;
+ rc = PDMDevHlpPCIIORegionRegister(pDevIns, 2 /* iRegion */, VMSVGA_FIFO_SIZE, PCI_ADDRESS_SPACE_MEM /* PCI_ADDRESS_SPACE_MEM_PREFETCH */, vmsvgaR3IORegionMap);
+ if (RT_FAILURE(rc))
+ return rc;
}
+ else
+#endif /* VBOX_WITH_VMSVGA */
+ rc = PDMDevHlpPCIIORegionRegister(pDevIns, iPCIRegionVRAM, pThis->vram_size, PCI_ADDRESS_SPACE_MEM_PREFETCH, vgaR3IORegionMap);
+ if (RT_FAILURE(rc))
+ return rc;
/*
* Create the refresh timer.
@@ -6573,28 +6630,24 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
if (pThis->pszLogoFile)
{
rc = RTFileRead(FileLogo, pLogoHdr + 1, LogoHdr.cbLogo, NULL);
+ if (RT_SUCCESS(rc))
+ rc = vbeParseBitmap(pThis);
if (RT_FAILURE(rc))
{
- AssertMsgFailed(("RTFileRead(,,%d,NULL) -> %Rrc\n", LogoHdr.cbLogo, rc));
+ LogRel(("Error %Rrc reading logo file '%s', using internal logo\n",
+ rc, pThis->pszLogoFile));
pLogoHdr->cbLogo = LogoHdr.cbLogo = g_cbVgaDefBiosLogo;
- memcpy(pLogoHdr + 1, g_abVgaDefBiosLogo, LogoHdr.cbLogo);
}
}
- else
- memcpy(pLogoHdr + 1, g_abVgaDefBiosLogo, LogoHdr.cbLogo);
-
- rc = vbeParseBitmap(pThis);
- if (RT_FAILURE(rc))
+ if ( !pThis->pszLogoFile
+ || RT_FAILURE(rc))
{
- AssertMsgFailed(("vbeParseBitmap() -> %Rrc\n", rc));
- pLogoHdr->cbLogo = LogoHdr.cbLogo = g_cbVgaDefBiosLogo;
memcpy(pLogoHdr + 1, g_abVgaDefBiosLogo, LogoHdr.cbLogo);
+ rc = vbeParseBitmap(pThis);
+ if (RT_FAILURE(rc))
+ AssertReleaseMsgFailed(("Parsing of internal bitmap failed! vbeParseBitmap() -> %Rrc\n", rc));
}
- rc = vbeParseBitmap(pThis);
- if (RT_FAILURE(rc))
- AssertReleaseMsgFailed(("Internal bitmap failed! vbeParseBitmap() -> %Rrc\n", rc));
-
rc = VINF_SUCCESS;
}
else
@@ -6617,6 +6670,15 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
AssertRC(rc);
}
#endif
+
+#ifdef VBOX_WITH_VMSVGA
+ if ( rc == VINF_SUCCESS
+ && pThis->fVMSVGAEnabled)
+ {
+ rc = vmsvgaInit(pDevIns);
+ }
+#endif
+
/*
* Statistics.
*/
@@ -6662,10 +6724,14 @@ const PDMDEVREG g_DeviceVga =
vgaR3Destruct,
/* pfnRelocate */
vgaR3Relocate,
- /* pfnIOCtl */
+ /* pfnMemSetup */
NULL,
/* pfnPowerOn */
+#ifdef VBOX_WITH_VMSVGA
+ vmsvgaR3PowerOn,
+#else
NULL,
+#endif
/* pfnReset */
vgaR3Reset,
/* pfnSuspend */