VirtualBox

Changeset 24089 in vbox for trunk/src


Ignore:
Timestamp:
Oct 26, 2009 4:14:52 PM (15 years ago)
Author:
vboxsync
Message:

DevRTC: Added UseUTC config options (default is false). Save and verify the configuration.

Location:
trunk/src/VBox/Devices
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevRTC.cpp

    r22793 r24089  
    111111
    112112
     113/** The saved state version. */
     114#define RTC_SAVED_STATE_VERSION             2
     115/** The saved state version used by VirtualBox 3.0 and earlier.
     116 * This does not include the configuration.  */
     117#define RTC_SAVED_STATE_VERSION_VBOX_30     1
     118
     119
    113120/*******************************************************************************
    114121*   Structures and Typedefs                                                    *
     
    133140    uint8_t Alignment0[7];
    134141    struct my_tm current_tm;
     142    /** The configured IRQ. */
    135143    int32_t irq;
     144    /** The configured I/O port base. */
     145    RTIOPORT IOPortBase;
    136146    /** Use UTC or local time initially. */
    137147    bool fUTC;
     
    586596}
    587597
    588 
    589598#ifdef IN_RING3
    590 /**
    591  * Saves a state of the programmable interval timer device.
    592  *
    593  * @returns VBox status code.
    594  * @param   pDevIns     The device instance.
    595  * @param   pSSMHandle  The handle to save the state to.
    596  */
    597 static DECLCALLBACK(int) rtcSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
     599
     600/**
     601 * @copydoc FNSSMDEVLIVEEXEC
     602 */
     603static DECLCALLBACK(int) rtcLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
    598604{
    599605    RTCState *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
    600606
    601     SSMR3PutMem(pSSMHandle, pThis->cmos_data, 128);
    602     SSMR3PutU8(pSSMHandle, pThis->cmos_index);
    603 
    604     SSMR3PutS32(pSSMHandle, pThis->current_tm.tm_sec);
    605     SSMR3PutS32(pSSMHandle, pThis->current_tm.tm_min);
    606     SSMR3PutS32(pSSMHandle, pThis->current_tm.tm_hour);
    607     SSMR3PutS32(pSSMHandle, pThis->current_tm.tm_wday);
    608     SSMR3PutS32(pSSMHandle, pThis->current_tm.tm_mday);
    609     SSMR3PutS32(pSSMHandle, pThis->current_tm.tm_mon);
    610     SSMR3PutS32(pSSMHandle, pThis->current_tm.tm_year);
    611 
    612     TMR3TimerSave(pThis->CTX_SUFF(pPeriodicTimer), pSSMHandle);
    613 
    614     SSMR3PutS64(pSSMHandle, pThis->next_periodic_time);
    615 
    616     SSMR3PutS64(pSSMHandle, pThis->next_second_time);
    617     TMR3TimerSave(pThis->CTX_SUFF(pSecondTimer), pSSMHandle);
    618     TMR3TimerSave(pThis->CTX_SUFF(pSecondTimer2), pSSMHandle);
     607    SSMR3PutU8(    pSSM, pThis->irq);
     608    SSMR3PutIOPort(pSSM, pThis->IOPortBase);
     609    SSMR3PutBool(  pSSM, pThis->fUTC);
     610
     611    return VINF_SSM_DONT_CALL_AGAIN;
     612}
     613
     614
     615/**
     616 * @copydoc FNSSMDEVSAVEEXEC
     617 */
     618static DECLCALLBACK(int) rtcSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     619{
     620    RTCState *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
     621
     622    /* The config. */
     623    rtcLiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
     624
     625    /* The state. */
     626    SSMR3PutMem(pSSM, pThis->cmos_data, 128);
     627    SSMR3PutU8(pSSM, pThis->cmos_index);
     628
     629    SSMR3PutS32(pSSM, pThis->current_tm.tm_sec);
     630    SSMR3PutS32(pSSM, pThis->current_tm.tm_min);
     631    SSMR3PutS32(pSSM, pThis->current_tm.tm_hour);
     632    SSMR3PutS32(pSSM, pThis->current_tm.tm_wday);
     633    SSMR3PutS32(pSSM, pThis->current_tm.tm_mday);
     634    SSMR3PutS32(pSSM, pThis->current_tm.tm_mon);
     635    SSMR3PutS32(pSSM, pThis->current_tm.tm_year);
     636
     637    TMR3TimerSave(pThis->CTX_SUFF(pPeriodicTimer), pSSM);
     638
     639    SSMR3PutS64(pSSM, pThis->next_periodic_time);
     640
     641    SSMR3PutS64(pSSM, pThis->next_second_time);
     642    TMR3TimerSave(pThis->CTX_SUFF(pSecondTimer), pSSM);
     643    TMR3TimerSave(pThis->CTX_SUFF(pSecondTimer2), pSSM);
    619644
    620645    return VINF_SUCCESS;
     
    623648
    624649/**
    625  * Loads a saved programmable interval timer device state.
    626  *
    627  * @returns VBox status code.
    628  * @param   pDevIns     The device instance.
    629  * @param   pSSMHandle  The handle to the saved state.
    630  * @param   uVersion    The data unit version number.
    631  * @param   uPass       The data pass.
    632  */
    633 static DECLCALLBACK(int) rtcLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t uVersion, uint32_t uPass)
    634 {
    635     RTCState *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
    636 
    637     if (uVersion != 1)
     650 * @copydoc FNSSMDEVLOADEXEC
     651 */
     652static DECLCALLBACK(int) rtcLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     653{
     654    RTCState   *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
     655    int         rc;
     656
     657    if (    uVersion != RTC_SAVED_STATE_VERSION
     658        &&  uVersion != RTC_SAVED_STATE_VERSION_VBOX_30)
    638659        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    639     Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
    640 
    641     SSMR3GetMem(pSSMHandle, pThis->cmos_data, 128);
    642     SSMR3GetU8(pSSMHandle, &pThis->cmos_index);
    643 
    644     SSMR3GetS32(pSSMHandle, &pThis->current_tm.tm_sec);
    645     SSMR3GetS32(pSSMHandle, &pThis->current_tm.tm_min);
    646     SSMR3GetS32(pSSMHandle, &pThis->current_tm.tm_hour);
    647     SSMR3GetS32(pSSMHandle, &pThis->current_tm.tm_wday);
    648     SSMR3GetS32(pSSMHandle, &pThis->current_tm.tm_mday);
    649     SSMR3GetS32(pSSMHandle, &pThis->current_tm.tm_mon);
    650     SSMR3GetS32(pSSMHandle, &pThis->current_tm.tm_year);
    651 
    652     TMR3TimerLoad(pThis->CTX_SUFF(pPeriodicTimer), pSSMHandle);
    653 
    654     SSMR3GetS64(pSSMHandle, &pThis->next_periodic_time);
    655 
    656     SSMR3GetS64(pSSMHandle, &pThis->next_second_time);
    657     TMR3TimerLoad(pThis->CTX_SUFF(pSecondTimer), pSSMHandle);
    658     TMR3TimerLoad(pThis->CTX_SUFF(pSecondTimer2), pSSMHandle);
     660
     661    /* The config. */
     662    if (uVersion > RTC_SAVED_STATE_VERSION_VBOX_30)
     663    {
     664        uint8_t u8Irq;
     665        rc = SSMR3GetU8(pSSM, &u8Irq);          AssertRCReturn(rc, rc);
     666        if (u8Irq != pThis->irq)
     667        {
     668            LogRel(("RTC: Config mismatch - u8Irq: saved=%#x config=%#x\n", u8Irq, pThis->irq));
     669            return VERR_SSM_LOAD_CONFIG_MISMATCH;
     670        }
     671
     672        RTIOPORT IOPortBase;
     673        rc = SSMR3GetIOPort(pSSM, &IOPortBase); AssertRCReturn(rc, rc);
     674        if (IOPortBase != pThis->IOPortBase)
     675        {
     676            LogRel(("RTC: Config mismatch - IOPortBase: saved=%RTiop config=%RTiop\n", IOPortBase, pThis->IOPortBase));
     677            return VERR_SSM_LOAD_CONFIG_MISMATCH;
     678        }
     679
     680        bool fUTC;
     681        rc = SSMR3GetBool(pSSM, &fUTC);         AssertRCReturn(rc, rc);
     682        if (fUTC != pThis->fUTC)
     683            LogRel(("RTC: Config mismatch - fUTC: saved=%RTbool config=%RTbool\n", fUTC, pThis->fUTC));
     684    }
     685
     686    if (uPass != SSM_PASS_FINAL)
     687        return VINF_SUCCESS;
     688
     689    /* The state. */
     690    SSMR3GetMem(pSSM, pThis->cmos_data, 128);
     691    SSMR3GetU8(pSSM, &pThis->cmos_index);
     692
     693    SSMR3GetS32(pSSM, &pThis->current_tm.tm_sec);
     694    SSMR3GetS32(pSSM, &pThis->current_tm.tm_min);
     695    SSMR3GetS32(pSSM, &pThis->current_tm.tm_hour);
     696    SSMR3GetS32(pSSM, &pThis->current_tm.tm_wday);
     697    SSMR3GetS32(pSSM, &pThis->current_tm.tm_mday);
     698    SSMR3GetS32(pSSM, &pThis->current_tm.tm_mon);
     699    SSMR3GetS32(pSSM, &pThis->current_tm.tm_year);
     700
     701    TMR3TimerLoad(pThis->CTX_SUFF(pPeriodicTimer), pSSM);
     702
     703    SSMR3GetS64(pSSM, &pThis->next_periodic_time);
     704
     705    SSMR3GetS64(pSSM, &pThis->next_second_time);
     706    TMR3TimerLoad(pThis->CTX_SUFF(pSecondTimer), pSSM);
     707    TMR3TimerLoad(pThis->CTX_SUFF(pSecondTimer2), pSSM);
    659708
    660709    int period_code = pThis->cmos_data[RTC_REG_A] & 0x0f;
     
    821870    RTCState   *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
    822871    int         rc;
    823     uint8_t     u8Irq;
    824     uint16_t    u16Base;
    825     bool        fGCEnabled;
    826     bool        fR0Enabled;
    827872    Assert(iInstance == 0);
    828873
     
    830875     * Validate configuration.
    831876     */
    832     if (!CFGMR3AreValuesValid(pCfgHandle, "Irq\0" "Base\0" "GCEnabled\0" "R0Enabled\0"))
     877    if (!CFGMR3AreValuesValid(pCfgHandle,
     878                              "Irq\0"
     879                              "Base\0"
     880                              "UseUTC\0"
     881                              "GCEnabled\0"
     882                              "R0Enabled\0"))
    833883        return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
    834884
     
    836886     * Init the data.
    837887     */
     888    uint8_t u8Irq;
    838889    rc = CFGMR3QueryU8Def(pCfgHandle, "Irq", &u8Irq, 8);
    839890    if (RT_FAILURE(rc))
    840891        return PDMDEV_SET_ERROR(pDevIns, rc,
    841892                                N_("Configuration error: Querying \"Irq\" as a uint8_t failed"));
    842 
    843     rc = CFGMR3QueryU16Def(pCfgHandle, "Base", &u16Base, 0x70);
     893    pThis->irq = u8Irq;
     894
     895    rc = CFGMR3QueryPortDef(pCfgHandle, "Base", &pThis->IOPortBase, 0x70);
    844896    if (RT_FAILURE(rc))
    845897        return PDMDEV_SET_ERROR(pDevIns, rc,
    846                                 N_("Configuration error: Querying \"Base\" as a uint16_t failed"));
    847 
     898                                N_("Configuration error: Querying \"Base\" as a RTIOPORT failed"));
     899
     900    rc = CFGMR3QueryBoolDef(pCfgHandle, "UseUTC", &pThis->fUTC, false);
     901    if (RT_FAILURE(rc))
     902        return PDMDEV_SET_ERROR(pDevIns, rc,
     903                                N_("Configuration error: Querying \"UseUTC\" as a bool failed"));
     904
     905    bool fGCEnabled;
    848906    rc = CFGMR3QueryBoolDef(pCfgHandle, "GCEnabled", &fGCEnabled, true);
    849907    if (RT_FAILURE(rc))
     
    851909                                N_("Configuration error: failed to read GCEnabled as boolean"));
    852910
     911    bool fR0Enabled;
    853912    rc = CFGMR3QueryBoolDef(pCfgHandle, "R0Enabled", &fR0Enabled, true);
    854913    if (RT_FAILURE(rc))
     
    856915                                N_("Configuration error: failed to read R0Enabled as boolean"));
    857916
    858     Log(("RTC: Irq=%#x Base=%#x fGCEnabled=%RTbool fR0Enabled=%RTbool\n", u8Irq, u16Base, fGCEnabled, fR0Enabled));
     917    Log(("RTC: Irq=%#x Base=%#x fGCEnabled=%RTbool fR0Enabled=%RTbool\n",
     918         u8Irq, pThis->IOPortBase, fGCEnabled, fR0Enabled));
    859919
    860920
     
    862922    pThis->pDevInsR0            = PDMDEVINS_2_R0PTR(pDevIns);
    863923    pThis->pDevInsRC            = PDMDEVINS_2_RCPTR(pDevIns);
    864     pThis->irq                  = u8Irq;
    865924    pThis->cmos_data[RTC_REG_A] = 0x26;
    866925    pThis->cmos_data[RTC_REG_B] = 0x02;
     
    895954    if (RT_FAILURE(rc))
    896955        return rc;
    897     pThis->pSecondTimer2R0 = TMTimerR0Ptr(pThis->pSecondTimer2R3);
    898     pThis->pSecondTimer2RC = TMTimerRCPtr(pThis->pSecondTimer2R3);
    899     pThis->next_second_time = TMTimerGet(pThis->CTX_SUFF(pSecondTimer2)) + (TMTimerGetFreq(pThis->CTX_SUFF(pSecondTimer2)) * 99) / 100;
     956    pThis->pSecondTimer2R0  = TMTimerR0Ptr(pThis->pSecondTimer2R3);
     957    pThis->pSecondTimer2RC  = TMTimerRCPtr(pThis->pSecondTimer2R3);
     958    pThis->next_second_time = TMTimerGet(pThis->CTX_SUFF(pSecondTimer2))
     959                            + (TMTimerGetFreq(pThis->CTX_SUFF(pSecondTimer2)) * 99) / 100;
    900960    rc = TMTimerSet(pThis->CTX_SUFF(pSecondTimer2), pThis->next_second_time);
    901961    if (RT_FAILURE(rc))
    902962        return rc;
    903963
    904     rc = PDMDevHlpIOPortRegister(pDevIns, u16Base, 2, NULL, rtcIOPortWrite, rtcIOPortRead, NULL, NULL, "MC146818 RTC/CMOS");
     964    rc = PDMDevHlpIOPortRegister(pDevIns, pThis->IOPortBase, 2, NULL,
     965                                 rtcIOPortWrite, rtcIOPortRead, NULL, NULL, "MC146818 RTC/CMOS");
    905966    if (RT_FAILURE(rc))
    906967        return rc;
    907968    if (fGCEnabled)
    908969    {
    909         rc = PDMDevHlpIOPortRegisterGC(pDevIns, u16Base, 2, 0, "rtcIOPortWrite", "rtcIOPortRead", NULL, NULL, "MC146818 RTC/CMOS");
     970        rc = PDMDevHlpIOPortRegisterGC(pDevIns, pThis->IOPortBase, 2, 0,
     971                                       "rtcIOPortWrite", "rtcIOPortRead", NULL, NULL, "MC146818 RTC/CMOS");
    910972        if (RT_FAILURE(rc))
    911973            return rc;
     
    913975    if (fR0Enabled)
    914976    {
    915         rc = PDMDevHlpIOPortRegisterR0(pDevIns, u16Base, 2, 0, "rtcIOPortWrite", "rtcIOPortRead", NULL, NULL, "MC146818 RTC/CMOS");
     977        rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->IOPortBase, 2, 0,
     978                                       "rtcIOPortWrite", "rtcIOPortRead", NULL, NULL, "MC146818 RTC/CMOS");
    916979        if (RT_FAILURE(rc))
    917980            return rc;
    918981    }
    919982
    920     rc = PDMDevHlpSSMRegister(pDevIns, 1 /* version */, sizeof(*pThis), rtcSaveExec, rtcLoadExec);
     983    rc = PDMDevHlpSSMRegister3(pDevIns, RTC_SAVED_STATE_VERSION, sizeof(*pThis), rtcLiveExec, rtcSaveExec, rtcLoadExec);
    921984    if (RT_FAILURE(rc))
    922985        return rc;
     
    9871050    PDM_DEVREG_VERSION
    9881051};
     1052
    9891053#endif /* IN_RING3 */
    9901054#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeGC.cpp

    r24087 r24089  
    555555    GEN_CHECK_OFF(RTCState, current_tm.tm_yday);
    556556    GEN_CHECK_OFF(RTCState, irq);
     557    GEN_CHECK_OFF(RTCState, fUTC);
     558    GEN_CHECK_OFF(RTCState, IOPortBase);
    557559    GEN_CHECK_OFF(RTCState, pPeriodicTimerR0);
    558560    GEN_CHECK_OFF(RTCState, pPeriodicTimerR3);
     
    569571    GEN_CHECK_OFF(RTCState, pDevInsR3);
    570572    GEN_CHECK_OFF(RTCState, pDevInsRC);
    571     GEN_CHECK_OFF(RTCState, fUTC);
    572573    GEN_CHECK_OFF(RTCState, RtcReg);
    573574    GEN_CHECK_OFF(RTCState, pRtcHlpR3);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette