DevHPET.cpp revision 1e9e76e4273dcc2e3d560a0f3605c46f0013eb7b
df717630fe580e7c753ac381f197e901885985b9tavmjong-free * HPET virtual device - High Precision Event Timer emulation.
03919b7845e461f72fa5d954b8124d27481c46b0JazzyNico * Copyright (C) 2009-2013 Oracle Corporation
2041edc9e0c8a75ae1ee22aec3d0fb66e1cc16a1Martin Owens * This file is part of VirtualBox Open Source Edition (OSE), as
03919b7845e461f72fa5d954b8124d27481c46b0JazzyNico * available from http://www.virtualbox.org. This file is free software;
03919b7845e461f72fa5d954b8124d27481c46b0JazzyNico * you can redistribute it and/or modify it under the terms of the GNU
03919b7845e461f72fa5d954b8124d27481c46b0JazzyNico * General Public License (GPL) as published by the Free Software
53eed655608a45ab528115d4225ad6e8e2c5641csuv-lp * Foundation, in version 2 as it comes in the "COPYING" file of the
03919b7845e461f72fa5d954b8124d27481c46b0JazzyNico * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
03919b7845e461f72fa5d954b8124d27481c46b0JazzyNico * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#include "VBoxDD.h"
#define HPET_TIMER_TYPE_EDGE 0
return rcLock; \
return rcLock; \
return rcLock; \
typedef struct HPETTIMER
/** Configuration/capabilities. */
} HPETTIMER;
typedef struct HPET
bool fIch9;
} HPET;
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
return u64NewValue;
return u64Diff;
if (u64Diff == 0)
Log4(("HPET: next IRQ in %lld ticks (%lld ns)\n", u64Diff, hpetTicksToNs(pHpetTimer->CTX_SUFF(pHpet), u64Diff)));
static int hpetTimerRegRead32(HPET const *pThis, uint32_t iTimerNo, uint32_t iTimerReg, uint32_t *pu32Value)
if ( iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u32Capabilities) /* The second check is only to satisfy Parfait; */
static unsigned s_cOccurences = 0;
*pu32Value = 0;
return VINF_SUCCESS;
switch (iTimerReg)
case HPET_TN_CFG:
case HPET_TN_CMP:
Log(("read HPET_TN_CMP+4 on %d: %#x (%#llx)\n", pHpetTimer->idxTimer, u32Value, pHpetTimer->u64Cmp));
case HPET_TN_ROUTE:
u32Value = (uint32_t)(pHpetTimer->u64Fsb >> 32); /** @todo Looks wrong, but since it's not supported, who cares. */
static unsigned s_cOccurences = 0;
u32Value = 0;
return VINF_SUCCESS;
static int hpetTimerRegWrite32(HPET *pThis, uint32_t iTimerNo, uint32_t iTimerReg, uint32_t u32NewValue)
Assert(!PDMCritSectIsOwner(&pThis->CritSect) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer)));
static unsigned s_cOccurences = 0;
return VINF_SUCCESS;
switch (iTimerReg)
case HPET_TN_CFG:
static unsigned s_cOccurences = 0;
AssertFailed();
Log2(("after HPET_TN_CMP+4 cmp=%llx per=%llx tmr=%d\n", pHpetTimer->u64Cmp, pHpetTimer->u64Period, iTimerNo));
case HPET_TN_ROUTE:
static unsigned s_cOccurences = 0;
return VINF_SUCCESS;
Assert(!PDMCritSectIsOwner(&pThis->CritSect) || (idxReg != HPET_COUNTER && idxReg != HPET_COUNTER + 4));
switch (idxReg)
case HPET_ID:
case HPET_PERIOD:
case HPET_CFG:
case HPET_COUNTER:
case HPET_STATUS:
u32Value = 0;
return VINF_SUCCESS;
Assert(!PDMCritSectIsOwner(&pThis->CritSect) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer)));
switch (idxReg)
case HPET_ID:
case HPET_CFG:
#ifdef IN_RING3
case HPET_STATUS:
if (u32NewValue != 0)
static unsigned s_cOccurrences = 0;
case HPET_COUNTER:
static unsigned s_cOccurences = 0;
return rc;
PDMBOTHCBDECL(int) hpetMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
int rc;
return rc;
PDMBOTHCBDECL(int) hpetMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
int rc;
return rc;
#ifdef IN_RING3
AssertFailed();
if (u64Period) {
return VINF_SSM_DONT_CALL_AGAIN;
static DECLCALLBACK(int) hpetR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
return VINF_SUCCESS;
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - too many timers: saved=%#x config=%#x"),
return VINF_SUCCESS;
return rc;
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Capabilities does not match timer count: cTimers=%#x caps=%#x"),
return VINF_SUCCESS;
bool fRCEnabled;
bool fR0Enabled;
if (fRCEnabled)
rc = PDMDevHlpMMIORegisterRC(pDevIns, HPET_BASE, HPET_BAR_SIZE, NIL_RTRCPTR /*pvUser*/, "hpetMMIOWrite", "hpetMMIORead");
if (fR0Enabled)
rc = PDMDevHlpSSMRegister3(pDevIns, HPET_SAVED_STATE_VERSION, sizeof(*pThis), hpetR3LiveExec, hpetR3SaveExec, hpetR3LoadExec);
return VINF_SUCCESS;
sizeof(HPET),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,