DevVGA.cpp revision 37af8ceec260cf709f4091fdcae0a63db85060d0
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * DevVGA - VBox VGA/VESA device.
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * Copyright (C) 2006-2007 Oracle Corporation
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * available from http://www.virtualbox.org. This file is free software;
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * you can redistribute it and/or modify it under the terms of the GNU
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * General Public License (GPL) as published by the Free Software
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * --------------------------------------------------------------------
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * This code is based on:
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * QEMU VGA Emulator.
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * Copyright (c) 2003 Fabrice Bellard
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * Permission is hereby granted, free of charge, to any person obtaining a copy
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * of this software and associated documentation files (the "Software"), to deal
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * in the Software without restriction, including without limitation the rights
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * copies of the Software, and to permit persons to whom the Software is
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * furnished to do so, subject to the following conditions:
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * The above copyright notice and this permission notice shall be included in
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * all copies or substantial portions of the Software.
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * THE SOFTWARE.
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/*******************************************************************************
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync* Defined Constants And Macros *
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync*******************************************************************************/
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** The size of the VGA GC mapping.
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * This is supposed to be all the VGA memory accessible to the guest.
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * The initial value was 256KB but NTAllInOne.iso appears to access more
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * thus the limit was upped to 512KB.
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * @todo Someone with some VGA knowhow should make a better guess at this value.
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#define PCIDEV_2_VGASTATE(pPciDev) ((VGAState *)((uintptr_t)pPciDev - RT_OFFSETOF(VGAState, Dev)))
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#endif /* VBOX_WITH_HGSMI */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** Converts a vga adaptor state pointer to a device instance pointer. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#define VGASTATE2DEVINS(pVgaState) ((pVgaState)->CTX_SUFF(pDevIns))
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** Use VBE bytewise I/O. Only needed for Windows Longhorn/Vista betas and backwards compatibility. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** Use VBE new dynamic mode list.
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * If this is not defined, no checks are carried out to see if the modes all
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * fit into the framebuffer! See the VRAM_SIZE_FIX define. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** Check that the video modes fit into virtual video memory.
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * Only works when VBE_NEW_DYN_LIST is defined! */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** Some fixes to ensure that logical scan-line lengths are not overwritten. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** Check buffer if an VRAM offset is within the right range or not. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertMsgReturn((off) < (pThis)->vram_size, ("%RX32 !< %RX32\n", (uint32_t)(off), (pThis)->vram_size), VINF_SUCCESS); \
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Log2(("%Rfn[%d]: %RX32 -> R3\n", __PRETTY_FUNCTION__, __LINE__, (off))); \
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync } while (0)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertMsgReturn((off) < (pThis)->vram_size, ("%RX32 !< %RX32\n", (uint32_t)(off), (pThis)->vram_size), VINF_SUCCESS)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** Check buffer if an VRAM offset is within the right range or not. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync# define VERIFY_VRAM_READ_OFF_RETURN(pThis, off, rcVar) \
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertMsgReturn((off) < (pThis)->vram_size, ("%RX32 !< %RX32\n", (uint32_t)(off), (pThis)->vram_size), 0xff); \
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Log2(("%Rfn[%d]: %RX32 -> R3\n", __PRETTY_FUNCTION__, __LINE__, (off))); \
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync return 0; \
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync } while (0)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync# define VERIFY_VRAM_READ_OFF_RETURN(pThis, off, rcVar) \
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertMsgReturn((off) < (pThis)->vram_size, ("%RX32 !< %RX32\n", (uint32_t)(off), (pThis)->vram_size), 0xff)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/*******************************************************************************
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync* Header Files *
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync*******************************************************************************/
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#endif /* IN_RING3 */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#if defined(VBE_NEW_DYN_LIST) && defined(IN_RING3) && !defined(VBOX_DEVICE_STRUCT_TESTCASE)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/*******************************************************************************
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync* Structures and Typedefs *
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync*******************************************************************************/
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** BMP File Format Bitmap Header. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsynctypedef struct
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** Pointer to a bitmap header*/
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** OS/2 1.x Information Header Format. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsynctypedef struct
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** Pointer to a OS/2 1.x header format */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** OS/2 2.0 Information Header Format. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsynctypedef struct
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t Compression; /* Compression Scheme (0=none) */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t XPelsPerMeter; /* Horz. Resolution in Pixels/Meter */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync uint32_t YPelsPerMeter; /* Vert. Resolution in Pixels/Meter */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t ClrUsed; /* Number of Colors in Color Table */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync uint32_t ClrImportant; /* Number of Important Colors */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync uint16_t Reserved; /* Reserved FIelds (always 0) */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint16_t Rendering; /* Halftone Algorithm Used on Image */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t ColorEncoding; /* Color Table Format (always 0) */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t Identifier; /* Misc. Field for Application Use */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** Pointer to a OS/2 2.0 header format */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/** Windows 3.x Information Header Format. */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsynctypedef struct
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t Compression; /* Compression Scheme (0=none) */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t XPelsPerMeter; /* Horz. Resolution in Pixels/Meter */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t YPelsPerMeter; /* Vert. Resolution in Pixels/Meter */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync uint32_t ClrUsed; /* Number of Colors in Color Table */
82391de567696f10b21a762fde6a06fe3c266d28vboxsync uint32_t ClrImportant; /* Number of Important Colors */
82391de567696f10b21a762fde6a06fe3c266d28vboxsync/** Pointer to a Windows 3.x header format */
82391de567696f10b21a762fde6a06fe3c266d28vboxsync/** @name BMP compressions.
82391de567696f10b21a762fde6a06fe3c266d28vboxsync/** @name BMP header sizes.
82391de567696f10b21a762fde6a06fe3c266d28vboxsync/** The BIOS boot menu text position, X. */
82391de567696f10b21a762fde6a06fe3c266d28vboxsync/** The BIOS boot menu text position, Y. */
82391de567696f10b21a762fde6a06fe3c266d28vboxsync/** Width of the "Press F12 to select boot device." bitmap.
82391de567696f10b21a762fde6a06fe3c266d28vboxsync Anything that exceeds the limit of F12BootText below is filled with
82391de567696f10b21a762fde6a06fe3c266d28vboxsync background. */
82391de567696f10b21a762fde6a06fe3c266d28vboxsync/** Height of the boot device selection bitmap, see LOGO_F12TEXT_WIDTH. */
82391de567696f10b21a762fde6a06fe3c266d28vboxsync/** The BIOS logo delay time (msec). */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#define LOGO_MAX_SIZE LOGO_MAX_WIDTH * LOGO_MAX_HEIGHT * 4
82391de567696f10b21a762fde6a06fe3c266d28vboxsync/*******************************************************************************
82391de567696f10b21a762fde6a06fe3c266d28vboxsync* Global Variables *
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync*******************************************************************************/
82391de567696f10b21a762fde6a06fe3c266d28vboxsync/* "Press F12 to select boot device." bitmap. */
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x0F, 0x7C,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0xF8, 0xF0, 0x01, 0xE0, 0x81, 0x9F, 0x3F, 0x00, 0x70, 0xF8, 0x00, 0xE0, 0xC3,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x07, 0x0F, 0x1F, 0x3E, 0x70, 0x00, 0xF0, 0xE1, 0xC3, 0x07, 0x0E, 0x00, 0x6E,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x7C, 0x60, 0xE0, 0xE1, 0xC3, 0x07, 0xC6, 0x80, 0x81, 0x31, 0x63, 0xC6, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x30, 0x80, 0x61, 0x0C, 0x00, 0x36, 0x63, 0x00, 0x8C, 0x19, 0x83, 0x61, 0xCC,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x18, 0x36, 0x00, 0xCC, 0x8C, 0x19, 0xC3, 0x06, 0xC0, 0x8C, 0x31, 0x3C, 0x30,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x8C, 0x19, 0x83, 0x31, 0x60, 0x60, 0x00, 0x0C, 0x18, 0x00, 0x0C, 0x60, 0x18,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x00, 0x80, 0xC1, 0x18, 0x00, 0x30, 0x06, 0x60, 0x18, 0x30, 0x80, 0x01, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x33, 0x63, 0xC6, 0x30, 0x00, 0x30, 0x63, 0x80, 0x19, 0x0C, 0x03, 0x06, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x0C, 0x18, 0x18, 0xC0, 0x81, 0x03, 0x00, 0x03, 0x18, 0x0C, 0x00, 0x60, 0x30,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x06, 0x00, 0x87, 0x01, 0x18, 0x06, 0x0C, 0x60, 0x00, 0xC0, 0xCC, 0x98, 0x31,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x0C, 0x00, 0xCC, 0x18, 0x30, 0x0C, 0xC3, 0x80, 0x01, 0x00, 0x03, 0x66, 0xFE,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x18, 0x30, 0x00, 0xC0, 0x02, 0x06, 0x06, 0x00, 0x18, 0x8C, 0x01, 0x60, 0xE0,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x0F, 0x86, 0x3F, 0x03, 0x18, 0x00, 0x30, 0x33, 0x66, 0x0C, 0x03, 0x00, 0x33,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0xFE, 0x0C, 0xC3, 0x30, 0xE0, 0x0F, 0xC0, 0x87, 0x9B, 0x31, 0x63, 0xC6, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0xF0, 0x80, 0x01, 0x03, 0x00, 0x06, 0x63, 0x00, 0x8C, 0x19, 0x83, 0x61, 0xCC,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x18, 0x06, 0x00, 0x6C, 0x8C, 0x19, 0xC3, 0x00, 0x80, 0x8D, 0x31, 0xC3, 0x30,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x8C, 0x19, 0x03, 0x30, 0xB3, 0xC3, 0x87, 0x0F, 0x1F, 0x00, 0x2C, 0x60, 0x80,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x01, 0xE0, 0x87, 0x0F, 0x00, 0x3E, 0x7C, 0x60, 0xF0, 0xE1, 0xE3, 0x07, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x0F, 0x3E, 0x7C, 0xFC, 0x00, 0xC0, 0xC3, 0xC7, 0x30, 0x0E, 0x3E, 0x7C, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x1E, 0xC0, 0x00, 0x60, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x00, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x0C, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x00, 0x00, 0x00, 0xC0, 0x0C, 0x87, 0x31, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x00, 0x06, 0x00, 0x00, 0x18, 0x00, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x30,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0xF8, 0x83, 0xC1, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x30,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401ce2099f0ede0091ea3f661331c6f1dd117d28vboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82391de567696f10b21a762fde6a06fe3c266d28vboxsync 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
82391de567696f10b21a762fde6a06fe3c266d28vboxsync/*******************************************************************************
82391de567696f10b21a762fde6a06fe3c266d28vboxsync* Internal Functions *
82391de567696f10b21a762fde6a06fe3c266d28vboxsync*******************************************************************************/
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncPDMBOTHCBDECL(int) vgaIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncPDMBOTHCBDECL(int) vgaIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
401ce2099f0ede0091ea3f661331c6f1dd117d28vboxsyncPDMBOTHCBDECL(int) vgaIOPortWriteVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncPDMBOTHCBDECL(int) vgaIOPortWriteVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncPDMBOTHCBDECL(int) vgaIOPortReadVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncPDMBOTHCBDECL(int) vgaIOPortReadVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncPDMBOTHCBDECL(int) vgaMMIOFill(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems);
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncPDMBOTHCBDECL(int) vgaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncPDMBOTHCBDECL(int) vgaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncPDMBOTHCBDECL(int) vgaIOPortReadBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncPDMBOTHCBDECL(int) vgaIOPortWriteBIOS(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncPDMBOTHCBDECL(int) vgaGCLFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncPDMBOTHCBDECL(int) vgaR0LFBAccessHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncPDMBOTHCBDECL(int) vbeIOPortReadVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncPDMBOTHCBDECL(int) vbeIOPortWriteVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncPDMBOTHCBDECL(int) vbeIOPortReadCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncPDMBOTHCBDECL(int) vbeIOPortWriteCMDLogo(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
82391de567696f10b21a762fde6a06fe3c266d28vboxsync#endif /* IN_RING3 */
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * Set a VRAM page dirty.
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * @param pThis VGA instance data.
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * @param offVRAM The VRAM offset of the page to set.
82391de567696f10b21a762fde6a06fe3c266d28vboxsyncDECLINLINE(void) vga_set_dirty(VGAState *pThis, RTGCPHYS offVRAM)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync AssertMsg(offVRAM < pThis->vram_size, ("offVRAM = %p, pThis->vram_size = %p\n", offVRAM, pThis->vram_size));
82391de567696f10b21a762fde6a06fe3c266d28vboxsync ASMBitSet(&pThis->au32DirtyBitmap[0], offVRAM >> PAGE_SHIFT);
5bc51087a0577d3f18701d7ff0fdc253cbd6bbf6vboxsync * Tests if a VRAM page is dirty.
ebcdaa5077bc9189c419330b1c84880018e3db99vboxsync * @returns true if dirty.
ebcdaa5077bc9189c419330b1c84880018e3db99vboxsync * @returns false if clean.
ebcdaa5077bc9189c419330b1c84880018e3db99vboxsync * @param pThis VGA instance data.
ebcdaa5077bc9189c419330b1c84880018e3db99vboxsync * @param offVRAM The VRAM offset of the page to check.
ebcdaa5077bc9189c419330b1c84880018e3db99vboxsyncDECLINLINE(bool) vga_is_dirty(VGAState *pThis, RTGCPHYS offVRAM)
ebcdaa5077bc9189c419330b1c84880018e3db99vboxsync AssertMsg(offVRAM < pThis->vram_size, ("offVRAM = %p, pThis->vram_size = %p\n", offVRAM, pThis->vram_size));
ebcdaa5077bc9189c419330b1c84880018e3db99vboxsync return ASMBitTest(&pThis->au32DirtyBitmap[0], offVRAM >> PAGE_SHIFT);
ebcdaa5077bc9189c419330b1c84880018e3db99vboxsync * Reset dirty flags in a give range.
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * @param pThis VGA instance data.
ebcdaa5077bc9189c419330b1c84880018e3db99vboxsync * @param offVRAMStart Offset into the VRAM buffer of the first page.
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * @param offVRAMEnd Offset into the VRAM buffer of the last page - exclusive.
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncDECLINLINE(void) vga_reset_dirty(VGAState *pThis, RTGCPHYS offVRAMStart, RTGCPHYS offVRAMEnd)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync ASMBitClearRange(&pThis->au32DirtyBitmap[0], offVRAMStart >> PAGE_SHIFT, offVRAMEnd >> PAGE_SHIFT);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync/* force some bits to zero */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
82391de567696f10b21a762fde6a06fe3c266d28vboxsync (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
82391de567696f10b21a762fde6a06fe3c266d28vboxsync (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
82391de567696f10b21a762fde6a06fe3c266d28vboxsync (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#define PAT(x) (x)
82391de567696f10b21a762fde6a06fe3c266d28vboxsync#define GET_PLANE(data, p) (((data) >> (24 - (p) * 8)) & 0xff)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#define GET_PLANE(data, p) (((data) >> ((p) * 8)) & 0xff)
82391de567696f10b21a762fde6a06fe3c266d28vboxsync#define PAT(x) (x)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync#endif /* IN_RING3 */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncstatic uint32_t vga_ioport_read(void *opaque, uint32_t addr)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* check port range access depending on color/monochrome mode */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION)) ||
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync (addr >= 0x3d0 && addr <= 0x3df && !(s->msr & MSR_COLOR_EMULATION))) {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3c0:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (s->ar_flip_flop == 0) {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3c1:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3c2:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3c4:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3c5:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Log2(("vga: read SR%x = 0x%02x\n", s->sr_index, val));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3c7:
82391de567696f10b21a762fde6a06fe3c266d28vboxsync case 0x3c8:
82391de567696f10b21a762fde6a06fe3c266d28vboxsync case 0x3c9:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
82391de567696f10b21a762fde6a06fe3c266d28vboxsync case 0x3ca:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3cc:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3ce:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3cf:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Log2(("vga: read GR%x = 0x%02x\n", s->gr_index, val));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3b4:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3d4:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3b5:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3d5:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Log2(("vga: read CR%x = 0x%02x\n", s->cr_index, val));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3ba:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3da:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* just toggle to fool polling */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync Log(("VGA: read addr=0x%04x data=0x%02x\n", addr, val));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsyncstatic void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync Log(("VGA: write addr=0x%04x data=0x%02x\n", addr, val));
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* check port range access depending on color/monochrome mode */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION)) ||
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync (addr >= 0x3d0 && addr <= 0x3df && !(s->msr & MSR_COLOR_EMULATION))) {
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync case 0x3c0:
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (s->ar_flip_flop == 0) {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
#ifndef IN_RC
if (s->fRemappedVGA)
s->fRemappedVGA = false;
s->dac_sub_index = 0;
s->dac_sub_index = 0;
s->dac_state = 0;
s->dac_sub_index = 0;
s->dac_write_index++;
#ifndef IN_RC
if (s->fRemappedVGA)
s->fRemappedVGA = false;
switch(s->cr_index) {
#ifdef CONFIG_BOCHS_VBE
return val;
switch(s->vbe_index) {
case VBE_DISPI_INDEX_XRES:
case VBE_DISPI_INDEX_YRES:
case VBE_DISPI_INDEX_BPP:
switch(s->vbe_index) {
val = 0;
return val;
return aligned_pitch;
return width;
switch(s->vbe_index) {
case VBE_DISPI_INDEX_ID:
#ifdef VBOX_WITH_HGSMI
case VBE_DISPI_INDEX_XRES:
#ifdef KEEP_SCAN_LINE_LENGTH
s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = calc_line_width(s->vbe_regs[VBE_DISPI_INDEX_BPP], s->vbe_line_offset);
s->vbe_start_addr = 0;
case VBE_DISPI_INDEX_YRES:
#ifdef KEEP_SCAN_LINE_LENGTH
s->vbe_start_addr = 0;
case VBE_DISPI_INDEX_BPP:
if (val == 0)
#ifdef KEEP_SCAN_LINE_LENGTH
s->vbe_start_addr = 0;
case VBE_DISPI_INDEX_BANK:
#ifndef IN_RC
if (s->fRemappedVGA)
s->fRemappedVGA = false;
case VBE_DISPI_INDEX_ENABLE:
#ifndef IN_RING3
return VINF_IOM_HC_IOPORT_WRITE;
int h, shift_control;
#ifndef KEEP_SCAN_LINE_LENGTH
#ifndef KEEP_SCAN_LINE_LENGTH
s->vbe_start_addr = 0;
shift_control = 0;
s->bank_offset = 0;
if (s->fRemappedVGA)
s->fRemappedVGA = false;
int w, h, line_offset;
return VINF_SUCCESS;
w = val;
return VINF_SUCCESS;
case VBE_DISPI_INDEX_X_OFFSET:
case VBE_DISPI_INDEX_Y_OFFSET:
#ifndef IN_RING3
return VINF_IOM_HC_IOPORT_WRITE;
return VINF_SUCCESS;
switch(memory_map_mode) {
# ifndef IN_RC
IOMMMIOMapMMIO2Page(PDMDevHlpGetVM(s->CTX_SUFF(pDevIns)), GCPhys, s->GCPhysVRAM + addr, X86_PTE_RW|X86_PTE_P);
s->fRemappedVGA = true;
return ret;
switch(memory_map_mode) {
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
# ifndef IN_RC
IOMMMIOMapMMIO2Page(PDMDevHlpGetVM(s->CTX_SUFF(pDevIns)), GCPhys, s->GCPhysVRAM + addr, X86_PTE_RW | X86_PTE_P);
s->fRemappedVGA = true;
#ifdef IN_RING0
s->u64LastLatchedAccess = 0;
return VINF_EM_RAW_EMULATE_IO_BLOCK;
if (s->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->u64LastLatchedAccess = 0;
s->iMask = 0;
s->cLatchAccesses = 0;
switch(write_mode) {
goto do_write;
switch(func_select) {
return VINF_SUCCESS;
#if defined(IN_RING3)
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;
int full_update, i;
full_update = 0;
v = s->ar[i];
return full_update;
int full_update, i;
int wide_dac;
full_update = 0;
if (wide_dac)
return full_update;
#ifdef CONFIG_BOCHS_VBE
int full_update;
full_update = 0;
return full_update;
switch(depth) {
s->plane_updated = 0;
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... */
return VINF_SUCCESS;
if (fFailOnResize)
return VERR_TRY_AGAIN;
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 = s->pDrv->pfnResize(s->pDrv, cBits, s->CTX_SUFF(vram_ptr) + s->start_addr * 4, s->line_offset, cx, cy);
return rc;
if (s->shift_control == 0)
update_palette16(s);
update_palette16(s);
return VINF_SUCCESS;
uint8_t *d;
int offsets_changed;
if (shift_control == 0) {
v = VGA_DRAW_LINE4D2;
v = VGA_DRAW_LINE4;
v = VGA_DRAW_LINE2D2;
v = VGA_DRAW_LINE2;
switch(s->get_bpp(s)) {
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;
if (s->cursor_invalidate)
s->cursor_invalidate(s);
y1 = 0;
for(y = 0; y < height; y++) {
if (update) {
if (y_start < 0)
y_start = y;
if (s->fRenderVRAM)
if (s->cursor_draw_line)
s->cursor_draw_line(s, d, 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;
for(i = 0; i < (int)s->last_scr_height; i++) {
d += cbScanline;
static DECLCALLBACK(void) voidUpdateRect(PPDMIDISPLAYCONNECTOR pInterface, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy)
#define GMODE_TEXT 0
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 (s->pDrv) {
if (fBlank) {
if (s->pDrv) {
return rc;
full_update = 0;
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++)
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 rc;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vgaIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
return rc;
return rc;
PDMBOTHCBDECL(int) vgaIOPortWriteVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
return rc;
#ifndef IN_RING3
return VINF_IOM_HC_IOPORT_WRITE;
#ifdef VBE_BYTEWISE_IO
if (!s->fWriteVBEData)
s->fWriteVBEData = false;
return rc;
s->fWriteVBEData = true;
return VINF_SUCCESS;
s->fWriteVBEData = false;
// Log(("vgaIOPortWriteVBEData: VBE_DISPI_INDEX_ENABLE & VBE_DISPI_ENABLED - Switching to host...\n"));
return rc;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vgaIOPortWriteVBEIndex(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
return rc;
#ifdef VBE_BYTEWISE_IO
if (!s->fWriteVBEIndex)
s->fWriteVBEIndex = true;
return VINF_SUCCESS;
s->fWriteVBEIndex = false;
return VINF_SUCCESS;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vgaIOPortReadVBEData(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
return rc;
#ifdef VBE_BYTEWISE_IO
if (!s->fReadVBEData)
s->fReadVBEData = true;
return VINF_SUCCESS;
s->fReadVBEData = false;
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)
return rc;
#ifdef VBE_BYTEWISE_IO
if (!s->fReadVBEIndex)
s->fReadVBEIndex = true;
return VINF_SUCCESS;
s->fReadVBEIndex = false;
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)
return rc;
switch (Port)
#if defined(VBOX_WITH_VIDEOHWACCEL)
#ifdef DEBUG_sunlover
#ifdef DEBUG_sunlover
return VINF_SUCCESS;
static DECLCALLBACK(int) vgaR3IOPortHGSMIRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
return rc;
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;
* Legacy VGA memory (0xa0000 - 0xbffff) write hook, to be called from IOM and from the inside of VGADeviceGC.cpp.
PDMBOTHCBDECL(int) vgaMMIOFill(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems)
return rc;
return rc;
PDMBOTHCBDECL(int) vgaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
return rc;
switch (cb)
while (cb-- > 0)
return rc;
PDMBOTHCBDECL(int) vgaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
return 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) vgaGCLFBAccessHandler(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)
return rc;
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 rc;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) vbeIOPortReadVBEExtra(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
return rc;
*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:
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
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;
int is_graph;
int w, h, char_height;
int val;
h = val;
if (!is_graph)
if (pbSrc)
if (!cbLine)
return NULL;
static DECLCALLBACK(int) vgaDummyResize(PPDMIDISPLAYCONNECTOR pInterface, uint32_t bpp, void *pvVRAM, uint32_t cbLine, uint32_t cx, uint32_t cy)
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;
return VINF_SUCCESS;
#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;
if (cbRequired)
LogFlow(("vgaPortTakeScreenshot: returns %Rrc (cbData=%d cx=%d cy=%d)\n", rc, cbRequired, Connector.cx, Connector.cy));
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
if (!s->fRenderVRAM)
#ifdef DEBUG_sunlover
#ifdef DEBUG_sunlover
#ifdef DEBUG_sunlover
switch(s->get_bpp(s))
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;
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_HGSMI
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));
rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pReg->szRCMod, "vgaGCLFBAccessHandler", &pThis->RCPtrLFBHandler);
AssertReleaseMsgFailed(("PDMR3LdrGetSymbolRC(, %s, \"vgaGCLFBAccessHandler\",) -> %Rrc\n", pDevIns->pReg->szRCMod, rc));
return rc;
#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 #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, 0x3b0, 4, NULL, vgaR3IOPortHGSMIWrite, vgaR3IOPortHGSMIRead, NULL, NULL, "VGA - 3b0 (HGSMI host)");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0x3d0, 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;
rc = PDMDevHlpMMIORegister(pDevIns, 0x000a0000, 0x00020000, 0, vgaMMIOWrite, vgaMMIORead, vgaMMIOFill, "VGA - VGA Video Buffer");
return rc;
rc = PDMDevHlpMMIORegisterRC(pDevIns, 0x000a0000, 0x00020000, 0, "vgaMMIOWrite", "vgaMMIORead", "vgaMMIOFill");
return rc;
rc = PDMDevHlpMMIORegisterR0(pDevIns, 0x000a0000, 0x00020000, 0, "vgaMMIOWrite", "vgaMMIORead", "vgaMMIOFill");
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));
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;
pThis, TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo This needs to be fixed! We cannot take the I/O lock at this point! */
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,