DevACPI.cpp revision 590bfe12ce22cd3716448fbb9f4dc51664bfe5e2
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * DevACPI - Advanced Configuration and Power Interface (ACPI) Device.
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * Copyright (C) 2006-2007 Sun Microsystems, Inc.
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * This file is part of VirtualBox Open Source Edition (OSE), as
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * available from http://www.virtualbox.org. This file is free software;
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * you can redistribute it and/or modify it under the terms of the GNU
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * General Public License (GPL) as published by the Free Software
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * Foundation, in version 2 as it comes in the "COPYING" file of the
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * Clara, CA 95054 USA or visit http://www.sun.com if you need
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * additional information or have any questions.
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely/*******************************************************************************
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely* Header Files *
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely*******************************************************************************/
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely#endif /* IN_RING3 */
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely/* the compiled DSL */
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely#if defined(IN_RING3) && !defined(VBOX_DEVICE_STRUCT_TESTCASE)
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely#endif /* !IN_RING3 */
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely/*******************************************************************************
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely* Defined Constants And Macros *
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely*******************************************************************************/
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely#define PM1b_EVT_BLK 0x00000000 /**< not supported */
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely#define PM1b_CTL_BLK 0x00000000 /**< not supported */
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely#define PM2_CTL_BLK 0x00000000 /**< not supported */
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely/* PM1x status register bits */
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely#define RSR1_STS (RT_BIT(1) | RT_BIT(2) | RT_BIT(3))
#define IGN_EN 0
#define AC_OFFLINE 0
typedef struct ACPIState
unsigned int uBatteryIndex;
unsigned int uSystemInfoIndex;
bool fUseFdc;
bool fUseHpet;
bool fUseSmc;
bool fPowerButtonHandled;
bool fShowCpu;
bool fShowRtc;
} ACPIState;
struct ACPIGENADDR
struct ACPITBLRSDP
struct ACPITBLHEADER
struct ACPITBLRSDT
struct ACPITBLXSDT
struct ACPITBLFADT
#define GPE1_BLK_LEN 0
#define GPE1_BASE 0
struct ACPITBLFACS
struct ACPITBLLAPIC
struct ACPITBLIOAPIC
class AcpiTableMADT
return m_pbData;
#pragma pack()
PDMBOTHCBDECL(int) acpiPMTmrRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
#ifdef IN_RING3
PDMBOTHCBDECL(int) acpiPm1aEnRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
PDMBOTHCBDECL(int) acpiPM1aEnWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
PDMBOTHCBDECL(int) acpiPm1aStsRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
PDMBOTHCBDECL(int) acpiPM1aStsWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
PDMBOTHCBDECL(int) acpiPm1aCtlRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
PDMBOTHCBDECL(int) acpiPM1aCtlWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
PDMBOTHCBDECL(int) acpiSmiWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
PDMBOTHCBDECL(int) acpiBatIndexWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
PDMBOTHCBDECL(int) acpiBatDataRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
PDMBOTHCBDECL(int) acpiSysInfoDataRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
PDMBOTHCBDECL(int) acpiSysInfoDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
PDMBOTHCBDECL(int) acpiGpe0EnRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
PDMBOTHCBDECL(int) acpiGpe0EnWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
PDMBOTHCBDECL(int) acpiGpe0StsRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
PDMBOTHCBDECL(int) acpiGpe0StsWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
PDMBOTHCBDECL(int) acpiResetWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
# ifdef DEBUG_ACPI
PDMBOTHCBDECL(int) acpiDhexWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
PDMBOTHCBDECL(int) acpiDchrWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
#ifdef IN_RING3
return -sum;
if (!rsdt)
for (unsigned int i = 0; i < nb_entries; ++i)
return VINF_SUCCESS;
if (!xsdt)
return VERR_NO_TMP_MEMORY;
for (unsigned int i = 0; i < nb_entries; ++i)
return VINF_SUCCESS;
lapic++;
if (gpe0_level(s))
if (pm1a_level(s))
return rc;
#define IACPIPORT_2_ACPISTATE(pInterface) ( (ACPIState*)((uintptr_t)pInterface - RT_OFFSETOF(ACPIState, IACPIPort)) )
s->fPowerButtonHandled = false;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return val;
return val;
return val;
switch (uSleepState)
return acpiPowerDown(s);
return VINF_SUCCESS;
return val;
return val;
# ifndef IN_RING3
return rc;
acpiPMTimerReset(s);
int rc;
if (!s->pDrv)
int rc;
if (!s->pDrv)
return fPresent
if (!s->pDrv)
return AC_ONLINE;
PDMBOTHCBDECL(int) acpiBatIndexWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (cb)
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiBatDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
switch (cb)
switch (s->uBatteryIndex)
case BAT_STATUS_STATE:
case BAT_STATUS_PRESENT_RATE:
case BAT_INFO_UNITS:
case BAT_INFO_DESIGN_CAPACITY:
case BAT_INFO_TECHNOLOGY:
case BAT_INFO_DESIGN_VOLTAGE:
case BAT_DEVICE_STATUS:
case BAT_POWER_SOURCE:
return VERR_IOM_IOPORT_UNUSED;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiSysInfoIndexWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (cb)
if (s->u8IndexShift == 0)
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiSysInfoDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
switch (cb)
switch (s->uSystemInfoIndex)
*pu32 = 0;
return VERR_IOM_IOPORT_UNUSED;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiSysInfoDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (s->uSystemInfoIndex)
s->u8IndexShift = 0;
case SYSTEM_INFO_INDEX_VALID:
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiPm1aEnRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
switch (cb)
return VERR_IOM_IOPORT_UNUSED;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiPm1aStsRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
switch (cb)
return VERR_IOM_IOPORT_UNUSED;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiPm1aCtlRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
switch (cb)
return VERR_IOM_IOPORT_UNUSED;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiPM1aEnWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (cb)
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiPM1aStsWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (cb)
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiPM1aCtlWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (cb)
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiPMTmrRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
return VINF_SUCCESS;
return VERR_IOM_IOPORT_UNUSED;
#ifdef IN_RING3
PDMBOTHCBDECL(int) acpiGpe0StsRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
switch (cb)
return VERR_IOM_IOPORT_UNUSED;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiGpe0EnRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
switch (cb)
return VERR_IOM_IOPORT_UNUSED;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiGpe0StsWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (cb)
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiGpe0EnWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (cb)
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiSmiWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (cb)
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiResetWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (cb)
return VINF_SUCCESS;
#ifdef DEBUG_ACPI
PDMBOTHCBDECL(int) acpiDhexWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (cb)
return VINF_SUCCESS;
PDMBOTHCBDECL(int) acpiDchrWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
switch (cb)
return VINF_SUCCESS;
int rc;
acpiPMTimerReset(s);
return rc;
switch (enmInterface)
case PDMINTERFACE_BASE:
case PDMINTERFACE_ACPI_PORT:
return NULL;
int rc;
if (s->u8UseIOApic)
rc = CFGMR3QueryU32Def(s->pDevIns->pCfgHandle, "RamHoleSize", &cbRamHole, MM_RAM_HOLE_SIZE_DEFAULT);
/* Note: This is also enforced by DevPcBios.cpp. */
rsdt_addr = 0;
if (s->u8UseIOApic)
if (s->u8UseIOApic)
return rc;
|| s->u8UseIOApic)
s->fShowCpu = true;
bool fGCEnabled;
fGCEnabled = true;
bool fR0Enabled;
fR0Enabled = true;
if (!rsdp_addr)
return rc;
return rc;
return rc; \
#ifdef DEBUG_ACPI
#undef L
#undef R
if (fGCEnabled)
if (fR0Enabled)
return rc;
acpiPMTimerReset(s);
return rc;
return rc;
s->pDrv = (PPDMIACPICONNECTOR)s->pDrvBase->pfnQueryInterface(s->pDrvBase, PDMINTERFACE_ACPI_CONNECTOR);
if (!s->pDrv)
return rc;
s->pm1a_en = 0;
s->pm1a_sts = 0;
s->pm1a_ctl = 0;
acpiPMTimerReset(s);
s->uBatteryIndex = 0;
s->uSystemInfoIndex = 0;
s->gpe0_en = 0;
s->gpe0_sts = 0;
s->uSleepState = 0;
acpiPlantTables(s);
sizeof(ACPIState),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,