DevVGA.cpp revision cba5eb8e90e85817deba82116989681d45bc9638
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * DevVGA - VBox VGA/VESA device.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Copyright (C) 2006-2013 Oracle Corporation
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * available from http://www.virtualbox.org. This file is free software;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * you can redistribute it and/or modify it under the terms of the GNU
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * General Public License (GPL) as published by the Free Software
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * --------------------------------------------------------------------
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * This code is based on:
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * QEMU VGA Emulator.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Copyright (c) 2003 Fabrice Bellard
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Permission is hereby granted, free of charge, to any person obtaining a copy
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * of this software and associated documentation files (the "Software"), to deal
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * in the Software without restriction, including without limitation the rights
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * copies of the Software, and to permit persons to whom the Software is
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * furnished to do so, subject to the following conditions:
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * The above copyright notice and this permission notice shall be included in
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * all copies or substantial portions of the Software.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * THE SOFTWARE.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/*******************************************************************************
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync* Defined Constants And Macros *
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync*******************************************************************************/
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/* WARNING!!! All defines that affect VGAState should be placed to DevVGA.h !!!
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * NEVER place them here as this would lead to VGASTATE inconsistency
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * across different .cpp files !!!
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** The size of the VGA GC mapping.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * This is supposed to be all the VGA memory accessible to the guest.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * The initial value was 256KB but NTAllInOne.iso appears to access more
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * thus the limit was upped to 512KB.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * @todo Someone with some VGA knowhow should make a better guess at this value.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync#define PCIDEV_2_VGASTATE(pPciDev) ((PVGASTATE)((uintptr_t)pPciDev - RT_OFFSETOF(VGASTATE, Dev)))
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync#endif /* VBOX_WITH_HGSMI */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Converts a vga adaptor state pointer to a device instance pointer. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync#define VGASTATE2DEVINS(pVgaState) ((pVgaState)->CTX_SUFF(pDevIns))
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Check that the video modes fit into virtual video memory.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Only works when VBE_NEW_DYN_LIST is defined! */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Check buffer if an VRAM offset is within the right range or not. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync AssertMsgReturn((off) < (pThis)->vram_size, ("%RX32 !< %RX32\n", (uint32_t)(off), (pThis)->vram_size), VINF_SUCCESS); \
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync Log2(("%Rfn[%d]: %RX32 -> R3\n", __PRETTY_FUNCTION__, __LINE__, (off))); \
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync } while (0)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync AssertMsgReturn((off) < (pThis)->vram_size, ("%RX32 !< %RX32\n", (uint32_t)(off), (pThis)->vram_size), VINF_SUCCESS)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Check buffer if an VRAM offset is within the right range or not. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync# define VERIFY_VRAM_READ_OFF_RETURN(pThis, off, rcVar) \
b99f0de5e39a13eccabef8390e94db39f6f0cd47vboxsync AssertMsgReturn((off) < (pThis)->vram_size, ("%RX32 !< %RX32\n", (uint32_t)(off), (pThis)->vram_size), 0xff); \
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync Log2(("%Rfn[%d]: %RX32 -> R3\n", __PRETTY_FUNCTION__, __LINE__, (off))); \
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync return 0; \
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync } while (0)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync# define VERIFY_VRAM_READ_OFF_RETURN(pThis, off, rcVar) \
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync AssertMsgReturn((off) < (pThis)->vram_size, ("%RX32 !< %RX32\n", (uint32_t)(off), (pThis)->vram_size), 0xff); \
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync } while (0)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/*******************************************************************************
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync* Header Files *
3e1eea35864d1b77d479643ae5790a1084f29793vboxsync*******************************************************************************/
3e1eea35864d1b77d479643ae5790a1084f29793vboxsync#endif /* IN_RING3 */
3e1eea35864d1b77d479643ae5790a1084f29793vboxsync/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
3e1eea35864d1b77d479643ae5790a1084f29793vboxsync#if defined(VBE_NEW_DYN_LIST) && defined(IN_RING3) && !defined(VBOX_DEVICE_STRUCT_TESTCASE)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/*******************************************************************************
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync* Structures and Typedefs *
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync*******************************************************************************/
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** BMP File Format Bitmap Header. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsynctypedef struct
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Pointer to a bitmap header*/
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** OS/2 1.x Information Header Format. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsynctypedef struct
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Pointer to a OS/2 1.x header format */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** OS/2 2.0 Information Header Format. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsynctypedef struct
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint32_t Compression; /* Compression Scheme (0=none) */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint32_t XPelsPerMeter; /* Horz. Resolution in Pixels/Meter */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint32_t YPelsPerMeter; /* Vert. Resolution in Pixels/Meter */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint32_t ClrUsed; /* Number of Colors in Color Table */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint32_t ClrImportant; /* Number of Important Colors */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint16_t Reserved; /* Reserved FIelds (always 0) */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint16_t Rendering; /* Halftone Algorithm Used on Image */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint32_t ColorEncoding; /* Color Table Format (always 0) */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint32_t Identifier; /* Misc. Field for Application Use */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Pointer to a OS/2 2.0 header format */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Windows 3.x Information Header Format. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsynctypedef struct
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint32_t Compression; /* Compression Scheme (0=none) */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint32_t XPelsPerMeter; /* Horz. Resolution in Pixels/Meter */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint32_t YPelsPerMeter; /* Vert. Resolution in Pixels/Meter */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint32_t ClrUsed; /* Number of Colors in Color Table */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint32_t ClrImportant; /* Number of Important Colors */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/** Pointer to a Windows 3.x header format */
#define BMP_COMPRESS_NONE 0
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
AssertMsg(offVRAM < pThis->vram_size, ("offVRAM = %p, pThis->vram_size = %p\n", offVRAM, pThis->vram_size));
AssertMsg(offVRAM < pThis->vram_size, ("offVRAM = %p, pThis->vram_size = %p\n", offVRAM, pThis->vram_size));
((uint32_t)( \
#ifdef WORDS_BIGENDIAN
#define PAT(x) (x)
#ifdef WORDS_BIGENDIAN
#define BIG 0
#ifdef WORDS_BIGENDIAN
#ifdef WORDS_BIGENDIAN
#define PAT(x) (x)
#if defined(IN_RING3)
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);
vsync_start_line = pThis->cr[0x10] + ((pThis->cr[0x07] & 4) << 6) + ((pThis->cr[0x07] & 0x80) << 2);
if (r->frame_ns) {
return val;
/* check port range access depending on color/monochrome mode */
switch(addr) {
val = 0;
val = 0;
return val;
int index;
/* check port range access depending on color/monochrome mode */
switch(addr) {
switch(index) {
#ifndef IN_RC
#ifndef IN_RC
#ifdef CONFIG_BOCHS_VBE
return val;
case VBE_DISPI_INDEX_XRES:
case VBE_DISPI_INDEX_YRES:
case VBE_DISPI_INDEX_BPP:
val = 0;
return val;
return aligned_pitch;
#ifdef SOME_UNUSED_FUNCTION
return width;
if (!cbLinePitch)
if (!fVirtHeightOnly)
pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = (cVirtHeight >= (uint32_t)pThis->vbe_regs[VBE_DISPI_INDEX_YRES])
bool fRecalculate = false;
case VBE_DISPI_INDEX_ID:
#ifdef VBOX_WITH_HGSMI
case VBE_DISPI_INDEX_XRES:
fRecalculate = true;
case VBE_DISPI_INDEX_YRES:
case VBE_DISPI_INDEX_BPP:
if (val == 0)
fRecalculate = true;
case VBE_DISPI_INDEX_BANK:
#ifndef IN_RC
case VBE_DISPI_INDEX_ENABLE:
#ifndef IN_RING3
return VINF_IOM_R3_IOPORT_WRITE;
int h, shift_control;
if (!cVirtWidth)
if ( !cVirtWidth
pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH], pThis->vbe_regs[VBE_DISPI_INDEX_YRES], cb, pThis->vram_size));
fRecalculate = true;
shift_control = 0;
#ifdef VBOX_WITH_HGSMI
case VBE_DISPI_INDEX_X_OFFSET:
case VBE_DISPI_INDEX_Y_OFFSET:
fRecalculate = true;
#ifndef IN_RING3
return VINF_IOM_R3_IOPORT_WRITE;
if (fRecalculate)
return VINF_SUCCESS;
#ifndef IN_RC
switch(memory_map_mode) {
# ifndef IN_RC
return ret;
#ifndef IN_RC
switch(memory_map_mode) {
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
# ifndef IN_RC
#ifdef IN_RING0
return VINF_EM_RAW_EMULATE_IO_BLOCK;
Log2(("Reset mask (was %d) delta %RX64 (limit %x)\n", pThis->iMask, u64CurTime - pThis->u64LastLatchedAccess, s_aDelta[pThis->iMask]));
switch(write_mode) {
goto do_write;
switch(func_select) {
return VINF_SUCCESS;
#if defined(IN_RING3)
int dscan);
static inline unsigned int rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
static inline unsigned int rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
static inline unsigned int rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
#include "DevVGATmpl.h"
#include "DevVGATmpl.h"
#include "DevVGATmpl.h"
#include "DevVGATmpl.h"
static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
unsigned int col;
return col;
static unsigned int rgb_to_pixel15_dup(unsigned int r, unsigned int g, unsigned b)
unsigned int col;
return col;
static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b)
unsigned int col;
return col;
static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b)
unsigned int col;
return col;
bool full_update = false;
full_update = true;
return full_update;
bool full_update = false;
int wide_dac;
if (wide_dac)
full_update = true;
return full_update;
#ifdef CONFIG_BOCHS_VBE
bool full_update = false;
full_update = true;
return full_update;
switch(depth) {
full_update = true;
full_update = true;
full_update = true;
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... */
return VINF_SUCCESS;
if (fFailOnResize)
return VERR_TRY_AGAIN;
int rc = pThis->pDrv->pfnResize(pThis->pDrv, 0, NULL, 0, pThis->last_scr_width, pThis->last_scr_height);
full_update = true;
return rc;
if (reset_dirty)
#ifdef WORDS_BIGENDIAN
dup9 = 0;
ch_attr_ptr++;
} else if (cy_start >= 0) {
if (cy_start >= 0)
return VINF_SUCCESS;
int ret;
#ifdef CONFIG_BOCHS_VBE
ret = 0;
return ret;
#ifdef CONFIG_BOCHS_VBE
int rc;
* although we should avoid calling pfnResize for XPDM as well, since pfnResize is actually an extra resize
rc = pThis->pDrv->pfnResize(pThis->pDrv, cBits, pThis->CTX_SUFF(vram_ptr) + pThis->start_addr * 4, pThis->line_offset, cx, cy);
return VERR_TRY_AGAIN;
return rc;
return VINF_SUCCESS;
static int vga_draw_graphic(PVGASTATE pThis, bool full_update, bool fFailOnResize, bool reset_dirty)
uint8_t *d;
full_update = true;
if (shift_control == 0) {
v = VGA_DRAW_LINE4D2;
v = VGA_DRAW_LINE4;
v = VGA_DRAW_LINE2D2;
v = VGA_DRAW_LINE2;
v = VGA_DRAW_LINE8D2;
v = VGA_DRAW_LINE8;
v = VGA_DRAW_LINE15;
v = VGA_DRAW_LINE16;
v = VGA_DRAW_LINE24;
v = VGA_DRAW_LINE32;
if (fFailOnResize)
return VERR_TRY_AGAIN;
if (rc != VINF_SUCCESS) /* Return any rc, particularly VINF_VGA_RESIZE_IN_PROGRESS, to the caller. */
return rc;
full_update = true;
width, height, v, line_offset, pThis->cr[9], pThis->cr[0x17], pThis->line_compare, pThis->sr[0x01]));
y1 = 0;
for(y = 0; y < height; y++) {
if (update) {
if (y_start < 0)
y_start = y;
if (y_start >= 0) {
if (!multi_run) {
y1++;
if (y2 == 0) {
--y2;
multi_run--;
addr1 = 0;
d += linesize;
if (y_start >= 0) {
return VINF_SUCCESS;
int i, w, val;
uint8_t *d;
if (!full_update)
val = 0;
d += cbScanline;
static DECLCALLBACK(void) voidUpdateRect(PPDMIDISPLAYCONNECTOR pInterface, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy)
#define GMODE_TEXT 0
static int vga_update_display(PVGASTATE pThis, bool fUpdateAll, bool fFailOnResize, bool reset_dirty)
int graphic_mode;
if (fUpdateAll) {
typedef DECLCALLBACK(void) FNUPDATERECT(PPDMIDISPLAYCONNECTOR pInterface, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy);
int fBlank = 0;
if (fBlank) {
if (fBlank) {
return rc;
if (full_update) {
switch(graphic_mode) {
case GMODE_TEXT:
case GMODE_GRAPH:
case GMODE_BLANK:
return rc;
#ifdef CONFIG_BOCHS_VBE
for(i = 0; i < VBE_DISPI_INDEX_NB_SAVED; i++)
qemu_put_byte(f, 0);
int is_vbe, i;
#ifdef CONFIG_BOCHS_VBE
if (!is_vbe)
for(i = 0; i < VBE_DISPI_INDEX_NB_SAVED; i++)
recalculate_data(pThis, false); /* <- re-calculate the pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] since it might be invalid */
if (is_vbe)
static void vga_init_expand(void)
expand4[i] = v;
expand2[i] = v;
expand4to8[i] = v;
PDMBOTHCBDECL(int) vgaIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vgaIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
return rc;
PDMBOTHCBDECL(int) vgaIOPortWriteVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
#ifndef IN_RING3
return VINF_IOM_R3_IOPORT_WRITE;
#ifdef VBE_BYTEWISE_IO
return VINF_SUCCESS;
// Log(("vgaIOPortWriteVBEData: VBE_DISPI_INDEX_ENABLE & VBE_DISPI_ENABLED - Switching to host...\n"));
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vgaIOPortWriteVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
#ifdef VBE_BYTEWISE_IO
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vgaIOPortReadVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
#ifdef VBE_BYTEWISE_IO
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_IOM_IOPORT_UNUSED;
PDMBOTHCBDECL(int) vgaIOPortReadVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
#ifdef VBE_BYTEWISE_IO
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_IOM_IOPORT_UNUSED;
#ifdef VBOX_WITH_HGSMI
# ifdef IN_RING3
static DECLCALLBACK(int) vgaR3IOPortHGSMIWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (Port)
# ifdef VBOX_VDMA_WITH_WATCHDOG
# ifdef DEBUG_sunlover
# ifdef DEBUG_sunlover
return VINF_SUCCESS;
static DECLCALLBACK(int) vgaR3IOPortHGSMIRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
switch (Port)
# ifdef DEBUG_sunlover
# ifdef DEBUG_sunlover
return rc;
* Legacy VGA memory (0xa0000 - 0xbffff) write hook, to be called from IOM and from the inside of VGADeviceGC.cpp.
static int vgaInternalMMIOFill(PVGASTATE pThis, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems)
uint32_t b;
for (i = 0; i < cbItem; i++)
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
while (cItems-- > 0)
for (i = 0; i < cbItem; i++)
GCPhysAddr++;
while (cItems-- > 0)
for (i = 0; i < cbItem; i++)
GCPhysAddr++;
for (i = 0; i < cbItem; i++)
for (i = 0; i < cbItem; i++)
for (i = 0; i < cbItem; i++)
for (i = 0; i < cbItem; i++)
while (cItems-- > 0)
((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] = (((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] & ~write_mask) | (aVal[0] & write_mask);
GCPhysAddr++;
while (cItems-- > 0)
((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] = (((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] & ~write_mask) | (aVal[0] & write_mask);
GCPhysAddr++;
((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] = (((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] & ~write_mask) | (aVal[1] & write_mask);
GCPhysAddr++;
while (cItems-- > 0)
for (i = 0; i < cbItem; i++)
((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] = (((uint32_t *)pThis->CTX_SUFF(vram_ptr))[GCPhysAddr] & ~write_mask) | (aVal[i] & write_mask);
GCPhysAddr++;
return VINF_SUCCESS;
* from the inside of VGADeviceGC.cpp. This is the advanced version of
PDMBOTHCBDECL(int) vgaMMIOFill(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems)
PDMBOTHCBDECL(int) vgaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
switch (cb)
while (cb-- > 0)
return rc;
PDMBOTHCBDECL(int) vgaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
int rc;
switch (cb)
return rc;
return rc;
#ifndef IN_RING3
/* In the SMP case the page table might be removed while we wait for the PGM lock in the trap handler. */
rc);
return VINF_SUCCESS;
return rc;
#ifdef IN_RC
PDMBOTHCBDECL(int) vgaRCLFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser)
PDMBOTHCBDECL(int) vgaR0LFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser)
static DECLCALLBACK(int) vgaR3LFBAccessHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
int rc;
return VINF_PGM_HANDLER_DO_DEFAULT;
return rc;
PDMBOTHCBDECL(int) vgaIOPortReadBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
return VERR_IOM_IOPORT_UNUSED;
PDMBOTHCBDECL(int) vgaIOPortWriteBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (u32)
if (lastWasNotNewline == 0)
lastWasNotNewline = 0;
return VINF_SUCCESS;
return VERR_IOM_IOPORT_UNUSED;
#ifdef IN_RING3
# ifdef VBE_NEW_DYN_LIST
PDMBOTHCBDECL(int) vbeIOPortWriteVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vbeIOPortReadVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
*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));
return rc;
uint16_t i;
case BMP_HEADER_OS21:
case BMP_HEADER_OS22:
case BMP_HEADER_WIN3:
const uint8_t *pu8Pal = pThis->pu8Logo + sizeof(LOGOHDR) + sizeof(BMPINFO) + pWinHdr->Size; /* ASSUMES Size location (safe) */
uint16_t j;
u32Pal |= b;
return VINF_SUCCESS;
static void vbeShowBitmap(uint16_t cBits, uint16_t xLogo, uint16_t yLogo, uint16_t cxLogo, uint16_t cyLogo, uint8_t iStep,
uint16_t i;
switch (cBits)
cbPadBytes = 0;
cbPadBytes = 0;
uint8_t j = 0, c = 0;
while (cyLeft-- > 0)
for (i = 0; i < cxLogo; i++)
switch (cBits)
c = *pu8Src++;
if (pix)
*pu8TmpPtr++;
c = *pu8Src++;
*pu8TmpPtr++;
*pu8TmpPtr++;
*pu8TmpPtr++;
PDMBOTHCBDECL(int) vbeIOPortWriteCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
case LOGO_CMD_SET_OFFSET:
case LOGO_CMD_SHOW_BMP:
for (int i = 0; i < LOGO_MAX_WIDTH; i++)
for (int j = 0; j < LOGO_MAX_HEIGHT; j++)
*pu32TmpPtr++ = 0;
for (int i = 0; i < LOGO_MAX_WIDTH; i++)
for (int j = 0; j < LOGO_MAX_HEIGHT; j++)
return VINF_SUCCESS;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vbeIOPortReadCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
PRTUINT64U p;
Log(("vbeIOPortReadCMDLogo: Requested address is out of Logo data!!! offLogoData=%#x(%d) cbLogo=%#x(%d)\n",
return VINF_SUCCESS;
switch (cb)
default: AssertFailed(); break;
Log(("vbeIOPortReadCMDLogo: LogoOffset=%#x(%d) cb=%#x %.*Rhxs\n", pThis->offLogoData, pThis->offLogoData, cb, cb, pu32));
return VINF_SUCCESS;
h = val;
if (!is_graph)
if (pszTitle)
cCols = 0;
while (cchLeft-- > 0)
while (cCols-- > 0)
if (iRow == 0)
bool fAll = true;
fAll = true;
fAll = false;
if (pbSrc)
if (!cbLine)
if (fAll) {
static DECLCALLBACK(void) vgaInfoPlanar(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
return NULL;
static DECLCALLBACK(int) vgaDummyResize(PPDMIDISPLAYCONNECTOR pInterface, uint32_t bpp, void *pvVRAM,
return VINF_SUCCESS;
static DECLCALLBACK(void) vgaDummyUpdateRect(PPDMIDISPLAYCONNECTOR pInterface, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy)
#define IDISPLAYPORT_2_VGASTATE(pInterface) ( (PVGASTATE)((uintptr_t)pInterface - RT_OFFSETOF(VGASTATE, IPort)) )
#ifndef VBOX_WITH_HGSMI
return VINF_SUCCESS;
return rc;
#ifdef DEBUG_sunlover
return rc;
static DECLCALLBACK(int) vgaPortSetRefreshRate(PPDMIDISPLAYPORT pInterface, uint32_t cMilliesInterval)
if (cMilliesInterval)
if (!pcBits)
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
static DECLCALLBACK(int) vgaPortTakeScreenshot(PPDMIDISPLAYPORT pInterface, uint8_t **ppu8Data, size_t *pcbData, uint32_t *pcx, uint32_t *pcy)
LogFlow(("vgaPortTakeScreenshot: ppu8Data=%p pcbData=%p pcx=%p pcy=%p\n", ppu8Data, pcbData, pcx, pcy));
return VERR_INVALID_PARAMETER;
LogFlow(("vgaPortTakeScreenshot: returns %Rrc (cbData=%d cx=%d cy=%d)\n", rc, *pcbData, *pcx, *pcy));
return rc;
static DECLCALLBACK(int) vgaPortDisplayBlt(PPDMIDISPLAYPORT pInterface, const void *pvData, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy)
if ( pvData
vga_draw_line_func *pfnVgaDrawLine = vga_draw_line_table[VGA_DRAW_LINE32 * 4 + get_depth_index(pThis->pDrv->cBits)];
while (cyLeft-- > 0)
return rc;
static DECLCALLBACK(void) vgaPortUpdateDisplayRect(PPDMIDISPLAYPORT pInterface, int32_t x, int32_t y, uint32_t w, uint32_t h)
uint32_t v;
#ifdef DEBUG_sunlover
#ifdef DEBUG_sunlover
#ifdef DEBUG_sunlover
#ifdef DEBUG_sunlover
v = VGA_DRAW_LINE8;
v = VGA_DRAW_LINE15;
v = VGA_DRAW_LINE16;
v = VGA_DRAW_LINE24;
v = VGA_DRAW_LINE32;
#ifdef DEBUG_sunlover
LogFlow(("vgaPortUpdateDisplayRect: dst: %p, %d, %d. src: %p, %d, %d\n", pu8Dst, cbLineDst, cbPixelDst, pu8Src, cbLineSrc, cbPixelSrc));
#ifdef DEBUG_sunlover
uint32_t w,
uint32_t h,
uint32_t v;
#ifdef DEBUG_sunlover
if (xSrcCorrected < 0)
xSrcCorrected = 0;
if (ySrcCorrected < 0)
ySrcCorrected = 0;
#ifdef DEBUG_sunlover
LogFlow(("vgaPortCopyRect: %d,%d %dx%d (corrected coords)\n", xSrcCorrected, ySrcCorrected, wCorrected, hCorrected));
#ifdef DEBUG_sunlover
return VINF_SUCCESS;
if ( xDst < 0
|| yDst < 0
return VERR_INVALID_PARAMETER;
switch(u32SrcBitsPerPixel)
return VINF_SUCCESS;
v = VGA_DRAW_LINE8;
v = VGA_DRAW_LINE15;
v = VGA_DRAW_LINE16;
v = VGA_DRAW_LINE24;
v = VGA_DRAW_LINE32;
#ifdef DEBUG_sunlover
LogFlow(("vgaPortCopyRect: dst: %p, %d, %d. src: %p, %d, %d\n", pu8DstPtr, cbLineDst, cbPixelDst, pu8SrcPtr, cbLineSrc, cbPixelSrc));
while (hCorrected-- > 0)
#ifdef DEBUG_sunlover
return VINF_SUCCESS;
#ifdef VBOX_WITH_VIDEOHWACCEL
static DECLCALLBACK(int) vgaR3IORegionMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
int rc;
LogFlow(("vgaR3IORegionMap: iRegion=%d GCPhysAddress=%RGp cb=%#x enmType=%d\n", iRegion, GCPhysAddress, cb, enmType));
return rc;
return VINF_SSM_DONT_CALL_AGAIN;
#ifdef VBOX_WITH_VIDEOHWACCEL
return VINF_SUCCESS;
#ifdef VBOX_WITH_VIDEOHWACCEL
return VINF_SUCCESS;
#ifdef VBOX_WITH_VDMA
#ifdef VBOX_WITH_HGSMI
# ifdef VBOX_WITH_VDMA
return rc;
return VINF_SUCCESS;
static DECLCALLBACK(int) vgaR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
int rc;
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("VRAM size changed: config=%#x state=%#x"), pThis->vram_size, cbVRam);
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Monitor count changed: config=%u state=%u"), pThis->cMonitors, cMonitors);
return rc;
if (fWithHgsmi)
#ifdef VBOX_WITH_HGSMI
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("HGSMI is not compiled in, but it is present in the saved state"));
return VINF_SUCCESS;
#ifdef VBOX_WITH_HGSMI
return VINF_SUCCESS;
char *pchStart;
char *pchEnd;
#ifdef VBOX_WITH_HGSMI
#ifdef CONFIG_BOCHS_VBE
if (offDelta)
switch (iLUN)
#ifdef VBOX_WITH_VIDEOHWACCEL
Log(("%s/%d: warning: no driver attached to LUN #0!\n", pDevIns->pReg->szName, pDevIns->iInstance));
return rc;
return VERR_PDM_NO_SUCH_LUN;
switch (iLUN)
#ifdef VBE_NEW_DYN_LIST
# ifdef VBOX_WITH_VDMA
return VINF_SUCCESS;
int maxPage;
int bpl;
static bool s_fExpandDone = false;
int rc;
#ifdef VBE_NEW_DYN_LIST
unsigned cb;
if (!s_fExpandDone)
s_fExpandDone = true;
if (pThis->vram_size & (_256K - 1)) /* Make sure there are no partial banks even in planar modes. */
Log(("VGA: VRamSize=%#x fGCenabled=%RTbool fR0Enabled=%RTbool\n", pThis->vram_size, pThis->fGCEnabled, pThis->fR0Enabled));
#if defined(VBOX_WITH_HGSMI) && (defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_WITH_VDMA) || defined(VBOX_WITH_WDDM))
#if defined(VBOX_WITH_HGSMI)
# if defined(VBOX_WITH_VIDEOHWACCEL)
#if defined(VBOX_WITH_CRHGSMI)
rc = PDMDevHlpMMIO2Register(pDevIns, 0 /* iRegion */, pThis->vram_size, 0, (void **)&pThis->vram_ptrR3, "VRam");
pThis->vram_ptrR0 = (RTR0PTR)pThis->vram_ptrR3; /** @todo @bugref{1865} Map parts into R0 or just use PGM access (Mac only). */
rc = PDMDevHlpMMHyperMapMMIO2(pDevIns, 0 /* iRegion */, 0 /* off */, VGA_MAPPING_SIZE, "VGA VRam", &pRCMapping);
AssertLogRelMsgRCReturn(rc, ("PDMDevHlpMMHyperMapMMIO2(%#x,) -> %Rrc\n", VGA_MAPPING_SIZE, rc), rc);
#if defined(VBOX_WITH_2X_4GB_ADDR_SPACE)
rc = PDMDevHlpMMIO2MapKernel(pDevIns, 0 /* iRegion */, 0 /* off */, VGA_MAPPING_SIZE, "VGA VRam", &pR0Mapping);
rc = PDMDevHlpIOPortRegister(pDevIns, 0x3c0, 16, NULL, vgaIOPortWrite, vgaIOPortRead, NULL, NULL, "VGA - 3c0");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0x3b4, 2, NULL, vgaIOPortWrite, vgaIOPortRead, NULL, NULL, "VGA - 3b4");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0x3ba, 1, NULL, vgaIOPortWrite, vgaIOPortRead, NULL, NULL, "VGA - 3ba");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0x3d4, 2, NULL, vgaIOPortWrite, vgaIOPortRead, NULL, NULL, "VGA - 3d4");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0x3da, 1, NULL, vgaIOPortWrite, vgaIOPortRead, NULL, NULL, "VGA - 3da");
return rc;
#ifdef VBOX_WITH_HGSMI
rc = PDMDevHlpIOPortRegister(pDevIns, VGA_PORT_HGSMI_HOST, 4, NULL, vgaR3IOPortHGSMIWrite, vgaR3IOPortHGSMIRead, NULL, NULL, "VGA - 3b0 (HGSMI host)");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, VGA_PORT_HGSMI_GUEST, 4, NULL, vgaR3IOPortHGSMIWrite, vgaR3IOPortHGSMIRead, NULL, NULL, "VGA - 3d0 (HGSMI guest)");
return rc;
#ifdef CONFIG_BOCHS_VBE
rc = PDMDevHlpIOPortRegister(pDevIns, 0x1ce, 1, NULL, vgaIOPortWriteVBEIndex, vgaIOPortReadVBEIndex, NULL, NULL, "VGA/VBE - Index");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0x1cf, 1, NULL, vgaIOPortWriteVBEData, vgaIOPortReadVBEData, NULL, NULL, "VGA/VBE - Data");
return rc;
rc = PDMDevHlpIOPortRegisterRC(pDevIns, 0x3c0, 16, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3c0 (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterRC(pDevIns, 0x3b4, 2, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3b4 (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterRC(pDevIns, 0x3ba, 1, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3ba (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterRC(pDevIns, 0x3d4, 2, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3d4 (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterRC(pDevIns, 0x3da, 1, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3da (GC)");
return rc;
#ifdef CONFIG_BOCHS_VBE
rc = PDMDevHlpIOPortRegisterRC(pDevIns, 0x1ce, 1, 0, "vgaIOPortWriteVBEIndex", "vgaIOPortReadVBEIndex", NULL, NULL, "VGA/VBE - Index (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterRC(pDevIns, 0x1cf, 1, 0, "vgaIOPortWriteVBEData", "vgaIOPortReadVBEData", NULL, NULL, "VGA/VBE - Data (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x3c0, 16, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3c0 (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x3b4, 2, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3b4 (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x3ba, 1, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3ba (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x3d4, 2, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3d4 (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x3da, 1, 0, "vgaIOPortWrite", "vgaIOPortRead", NULL, NULL, "VGA - 3da (GC)");
return rc;
#ifdef CONFIG_BOCHS_VBE
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x1ce, 1, 0, "vgaIOPortWriteVBEIndex", "vgaIOPortReadVBEIndex", NULL, NULL, "VGA/VBE - Index (GC)");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x1cf, 1, 0, "vgaIOPortWriteVBEData", "vgaIOPortReadVBEData", NULL, NULL, "VGA/VBE - Data (GC)");
return rc;
return rc;
return rc;
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, VBE_PRINTF_PORT, 1, NULL, vgaIOPortWriteBIOS, vgaIOPortReadBIOS, NULL, NULL, "VGA BIOS debug/panic");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, VBE_PRINTF_PORT, 1, 0, "vgaIOPortWriteBIOS", "vgaIOPortReadBIOS", NULL, NULL, "VGA BIOS debug/panic");
return rc;
Log(("vgaConstruct: Failed to open VGA BIOS ROM file '%s', rc=%Rrc!\n", pThis->pszVgaBiosFile, rc));
AssertReleaseMsg(g_cbVgaBiosBinary <= _64K && g_cbVgaBiosBinary >= 32*_1K, ("g_cbVgaBiosBinary=%#x\n", g_cbVgaBiosBinary));
AssertReleaseMsg(RT_ALIGN_Z(g_cbVgaBiosBinary, PAGE_SIZE) == g_cbVgaBiosBinary, ("g_cbVgaBiosBinary=%#x\n", g_cbVgaBiosBinary));
rc = PDMDevHlpROMRegister(pDevIns, 0x000c0000, RT_MAX(cbVgaBiosBinary, 36*_1K), pu8VgaBiosBinary, cbVgaBiosBinary,
return rc;
return rc;
return rc;
/*AssertMsg(pThis->Dev.devfn == 16 || iInstance != 0, ("pThis->Dev.devfn=%d\n", pThis->Dev.devfn));*/
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);
return rc;
return rc;
return rc;
#ifdef VBE_NEW_DYN_LIST
cyReduction = 0;
cCustomModes = 0;
return VERR_NO_MEMORY;
# ifndef VRAM_SIZE_FIX
for (i = 0; i < MODE_INFO_SIZE; i++)
* pixelWidth;
pCurMode++;
if (cyReduction)
# ifndef VRAM_SIZE_FIX
pCurMode++;
if (cCustomModes)
AssertMsgFailed(("Configuration error: Invalid mode data '%s' for '%s'! cBits=%d\n", pszExtraData, szExtraDataKey, cBits));
return VERR_VGA_INVALID_CUSTOM_MODE;
# ifdef VRAM_SIZE_FIX
AssertMsgFailed(("Configuration error: custom video mode %dx%dx%dbits is too large for the virtual video memory of %dMb. Please increase the video memory size.\n",
return VERR_VGA_INVALID_CUSTOM_MODE;
switch (cBits)
pDefMode++;
pCurMode++;
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, VBE_EXTRA_PORT, 1, NULL, vbeIOPortWriteVBEExtra, vbeIOPortReadVBEExtra, NULL, NULL, "VBE BIOS Extra Data");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, LOGO_IO_PORT, 1, NULL, vbeIOPortWriteCMDLogo, vbeIOPortReadCMDLogo, NULL, NULL, "BIOS Logo");
return rc;
PDMDevHlpDBGFInfoRegister(pDevIns, "vgatext", "Display VGA memory formatted as text.", vgaInfoText);
pThis->pu8Logo = (uint8_t *)PDMDevHlpMMHeapAlloc(pDevIns, RT_MAX(pThis->cbLogo, g_cbVgaDefBiosLogo + sizeof(LogoHdr)));
#ifdef VBOX_WITH_HGSMI
#ifdef VBOX_WITH_VDMA
STAM_REG(pVM, &pThis->StatRZMemoryRead, STAMTYPE_PROFILE, "/Devices/VGA/RZ/MMIO-Read", STAMUNIT_TICKS_PER_CALL, "Profiling of the VGAGCMemoryRead() body.");
STAM_REG(pVM, &pThis->StatR3MemoryRead, STAMTYPE_PROFILE, "/Devices/VGA/R3/MMIO-Read", STAMUNIT_TICKS_PER_CALL, "Profiling of the VGAGCMemoryRead() body.");
STAM_REG(pVM, &pThis->StatRZMemoryWrite, STAMTYPE_PROFILE, "/Devices/VGA/RZ/MMIO-Write", STAMUNIT_TICKS_PER_CALL, "Profiling of the VGAGCMemoryWrite() body.");
STAM_REG(pVM, &pThis->StatR3MemoryWrite, STAMTYPE_PROFILE, "/Devices/VGA/R3/MMIO-Write", STAMUNIT_TICKS_PER_CALL, "Profiling of the VGAGCMemoryWrite() body.");
STAM_REG(pVM, &pThis->StatMapPage, STAMTYPE_COUNTER, "/Devices/VGA/MapPageCalls", STAMUNIT_OCCURENCES, "Calls to IOMMMIOMapMMIO2Page.");
STAM_REG(pVM, &pThis->StatUpdateDisp, STAMTYPE_COUNTER, "/Devices/VGA/UpdateDisplay", STAMUNIT_OCCURENCES, "Calls to vgaPortUpdateDisplay().");
return rc;
sizeof(VGASTATE),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,