DevPcBios.cpp revision 5630ce71579f0cbb75884b9871063e8765f9c0ad
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * PC BIOS Device.
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Copyright (C) 2006-2008 Sun Microsystems, Inc.
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * This file is part of VirtualBox Open Source Edition (OSE), as
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * available from http://www.virtualbox.org. This file is free software;
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * you can redistribute it and/or modify it under the terms of the GNU
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * General Public License (GPL) as published by the Free Software
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Foundation, in version 2 as it comes in the "COPYING" file of the
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Clara, CA 95054 USA or visit http://www.sun.com if you need
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * additional information or have any questions.
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL/*******************************************************************************
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL* Header Files *
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL*******************************************************************************/
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL/** @page pg_devbios_cmos_assign CMOS Assignments (BIOS)
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * The BIOS uses a CMOS to store configuration data.
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * It is currently used as follows:
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * @todo Mark which bits are compatible with which BIOSes and
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * which are our own definitions.
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Base memory:
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Extended memory:
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Amount of memory above 16M:
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Boot device (BOCHS bios specific):
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Floppy drive type:
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Equipment byte:
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * 0x1e - 0x25
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Second HDD:
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * 0x26 - 0x2d
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * 0x67 - 0x6e
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Fourth HDD:
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * 0x70 - 0x77
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * First Sata HDD:
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * 0x40 - 0x47
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Second Sata HDD:
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * 0x48 - 0x4f
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Third Sata HDD:
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * 0x50 - 0x57
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Fourth Sata HDD:
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * 0x58 - 0x5f
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Number of CPUs:
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * RAM above 4G (in 64M units):
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * 0x61 - 0x63
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * @todo r=bird: Is the 0x61 - 0x63 range defined by AMI,
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * PHOENIX or AWARD? If not I'd say 64MB units is a bit
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * too big, besides it forces unnecessary math stuff onto
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * nike: The way how values encoded are defined by Bochs/QEmu BIOS,
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * although for them position in CMOS is different:
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * 0x5b - 0x5c: RAM above 4G
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * 0x5f: number of CPUs
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * Unfortunately for us those positions in our CMOS are already taken
0f8e6a91301bd55c0b27889e849ac4e6ca905753Quentin CASTEL * by 4th SATA drive configuration.
typedef enum DEVPCBIOSBOOT
typedef struct DEVPCBIOS
char *pszFDDevice;
char *pszHDDevice;
char *pszSataDevice;
char *pszPcBiosFile;
char *pszLanBootFile;
typedef struct DMIHDR
} *PDMIHDR;
typedef struct DMIBIOSINF
} *PDMIBIOSINF;
typedef struct DMISYSTEMINF
} *PDMISYSTEMINF;
typedef struct MPSFLOATPTR
} *PMPSFLOATPTR;
typedef struct MPSCFGTBLHEADER
} *PMPSCFGTBLHEADER;
typedef struct MPSPROCENTRY
} *PMPSPROCENTRY;
typedef struct MPSBUSENTRY
} *PMPSBUSENTRY;
typedef struct MPSIOAPICENTRY
} *PMPSIOAPICENTRY;
/** MPS I/O-Interrupt entry */
typedef struct MPSIOINTERRUPTENTRY
} *PMPSIOIRQENTRY;
#pragma pack()
int rc;
if (!pBlock)
return VERR_INVALID_PARAMETER;
return rc;
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
return VERR_INVALID_PARAMETER;
/* -=-=-=-=-=-=- based on code from pc.c -=-=-=-=-=-=- */
static void pcbiosCmosInitHardDisk(PPDMDEVINS pDevIns, int offType, int offInfo, PCPDMMEDIAGEOMETRY pLCHSGeometry)
Log2(("%s: offInfo=%#x: LCHS=%d/%d/%d\n", __FUNCTION__, offInfo, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
if (offType)
static int setLogicalDiskGeometry(PPDMIBASE pBase, PPDMIBLOCKBIOS pHardDisk, PPDMMEDIAGEOMETRY pLCHSGeometry)
return rc;
case DEVPCBIOSBOOT_NONE:
case DEVPCBIOSBOOT_FLOPPY:
case DEVPCBIOSBOOT_HD:
case DEVPCBIOSBOOT_DVD:
case DEVPCBIOSBOOT_LAN:
if (cKBRam > UINT32_C(0xe0000000)) /** @todo this limit must be picked up from CFGM and coordinated with MM/PGM! */
cKBAbove4GB = 0;
u32 = 0;
u32 = pThis->cbRam > 640 ? 640 : (uint32_t)pThis->cbRam / _1K; /* <-- this test is wrong, but it doesn't matter since we never assign less than 1MB */
u32 = 0;
* See rombios.c line ~7215 (int19_function).
u32 = 0;
if (apFDs[0])
default: AssertFailed(); break;
default: AssertFailed(); break;
switch (u32)
if ( apHDs[i]
if (apHDs[i])
&LCHSGeometry);
LogRel(("DevPcBios: ATA LUN#%d LCHS=%u/%u/%u\n", i, LCHSGeometry.cCylinders, LCHSGeometry.cHeads, LCHSGeometry.cSectors));
if ( apHDs[i]
if (apHDs[i])
int offInfo;
&LCHSGeometry);
LogRel(("DevPcBios: SATA LUN#%d LCHS=%u/%u/%u\n", i, LCHSGeometry.cCylinders, LCHSGeometry.cHeads, LCHSGeometry.cSectors));
return VINF_SUCCESS;
static DECLCALLBACK(int) pcbiosIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
return VERR_IOM_IOPORT_UNUSED;
static DECLCALLBACK(int) pcbiosIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
return VERR_INTERNAL_ERROR;
switch (u32)
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
static int pcbiosPlantDMITable(PPDMDEVINS pDevIns, uint8_t *pTable, unsigned cbMax, PRTUUID pUuid, PCFGMNODE pCfgHandle)
int iStrNr;
int rc;
char *pszDmiSystemVendor, *pszDmiSystemProduct, *pszDmiSystemVersion, *pszDmiSystemSerial, *pszDmiSystemUuid, *pszDmiSystemFamily;
if (!str[0]) \
size_t _max = (size_t)(pszStr + _len - (char *)pTable) + 5; /* +1 for strtab terminator +4 for end-of-table entry */ \
N_("One of the DMI strings is too long. Check all bios/Dmi* configuration entries. At least %zu bytes are needed but there is no space for more than %d bytes"), _max, cbMax); \
if (pszDmiSystemUuid)
return VINF_SUCCESS;
return -u8Sum;
return VINF_SUCCESS;
static int pcbiosBootFromCfg(PPDMDEVINS pDevIns, PCFGMNODE pCfgHandle, const char *pszParam, DEVPCBIOSBOOT *penmBoot)
char *psz;
pszParam);
return rc;
int rc;
int cb;
#ifdef VBOX_WITH_SMP_GUESTS
static const char * const s_apszBootDevices[] = { "BootDevice0", "BootDevice1", "BootDevice2", "BootDevice3" };
return rc;
static const char * const s_apszSataDisks[] =
{ "SataPrimaryMasterLUN", "SataPrimarySlaveLUN", "SataSecondaryMasterLUN", "SataSecondarySlaveLUN" };
return rc;
return rc;
/* Convert the UUID to network byte order. Not entirely straightforward as parts are MSB already... */
return rc;
rc = PDMDevHlpROMRegister(pDevIns, VBOX_DMI_TABLE_BASE, _4K, pThis->au8DMIPage, false /* fShadow */, "DMI tables");
return rc;
Log(("pcbiosConstruct: Failed to open system BIOS ROM file '%s', rc=%Rrc!\n", pThis->pszPcBiosFile, rc));
return rc;
rc = PDMDevHlpROMRegister(pDevIns, (uint32_t)-(int32_t)cbPcBiosBinary, cbPcBiosBinary, pu8PcBiosBinary,
return rc;
#ifdef VBOX_WITH_VMI
rc = PDMDevHlpROMRegister(pDevIns, VBOX_VMI_BIOS_BASE, g_cbVmiBiosBinary, g_abVmiBiosBinary, false, "VMI BIOS");
return rc;
Log(("pcbiosConstruct: Failed to open LAN boot ROM file '%s', rc=%Rrc!\n", pThis->pszLanBootFile, rc));
if (pu8LanBootBinary)
return rc;
sizeof(DEVPCBIOS),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,