VirtualBox

Changeset 27121 in vbox for trunk


Ignore:
Timestamp:
Mar 5, 2010 6:13:57 PM (15 years ago)
Author:
vboxsync
Message:

HPET, RTC, PIT, PDM: implement API to disable legacy devices from HPET legacy modes

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/pdmifs.h

    r26935 r27121  
    19371937#define PDMIVMMDEVPORT_IID                      "d7e52035-3b6c-422e-9215-2a75646a945d"
    19381938
     1939/** Pointer to a PIT port interface. */
     1940typedef struct PDMIPITPORT *PPDMIPITPORT;
     1941/**
     1942 * PIT port interface.
     1943 */
     1944typedef struct PDMIPITPORT
     1945{
     1946    /**
     1947     * Notify PIT about change of HPET legacy mode.
     1948     *
     1949     * @returns VBox status code
     1950     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
     1951     * @param   fActivate       If HPET legacy mode activated or deactivated.
     1952     */
     1953    DECLR3CALLBACKMEMBER(int, pfnNotifyHpetLegacy,(PPDMIPITPORT pInterface, bool fActivate));
     1954} PDMIPITPORT;
     1955/** PDMIPITPORT interface ID. */
     1956#define PDMIPITPORT_IID                        "06127207-3182-4394-b16e-0ecfeb5cbb27"
     1957
     1958/** Pointer to a RTC port interface. */
     1959typedef struct PDMIRTCPORT *PPDMIRTCPORT;
     1960/**
     1961 * RTC port interface.
     1962 */
     1963typedef struct PDMIRTCPORT
     1964{
     1965    /**
     1966     * Notify RTC about change of HPET legacy mode.
     1967     *
     1968     * @returns VBox status code
     1969     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
     1970     * @param   fActivate       If HPET legacy mode activated or deactivated.
     1971     */
     1972    DECLR3CALLBACKMEMBER(int, pfnNotifyHpetLegacy,(PPDMIRTCPORT pInterface, bool fActivate));
     1973} PDMIRTCPORT;
     1974/** PDMIRTCPORT interface ID. */
     1975#define PDMIRTCPORT_IID                        "b6af0d7c-56c7-4064-85aa-ba78b43a26e7"
     1976
     1977
    19391978/** @name Flags for PDMIVMMDEVPORT::pfnSetCredentials.
    19401979 * @{ */
  • trunk/src/VBox/Devices/PC/DevHPET.cpp

    r26939 r27121  
    3636 *   - not entirely correct time of interrupt, i.e. never
    3737 *     schedule interrupt earlier than in 1ms
    38  *   - interaction with RTC and PIT in legacy mode not yet fully implemented
    39  *     (HPET part OK, PDM and PIT/RTC to be done)
    4038 *   - statistics not implemented
    4139 */
     
    590588    rc =  VINF_IOM_HC_MMIO_WRITE;
    591589#else /* IN_RING3 */
    592     LogRel(("HPET: cannot update PIT/RTC in legacy mode yet"));
    593590    if (pThis->pHpetHlpR3)
    594591        rc = pThis->pHpetHlpR3->pfnSetLegacyMode(pThis->pDevInsR3, fActivate);
     
    618615
    619616            iOldValue = (uint32_t)(pThis->u64Config);
     617
     618            /**
     619             * This check must be here, before actual update, as hpetLegacyMode
     620             * may request retry in R3 - so we must keep state intact.
     621             */
     622            if (isBitJustSet(iOldValue, iNewValue, HPET_CFG_LEGACY))
     623            {
     624                rc = hpetLegacyMode(pThis, true);
     625            }
     626            else if (isBitJustCleared(iOldValue, iNewValue, HPET_CFG_LEGACY))
     627            {
     628                rc = hpetLegacyMode(pThis, false);
     629            }
     630            if (rc != VINF_SUCCESS)
     631                return rc;
     632
    620633            pThis->u64Config = updateMasked(iNewValue, iOldValue, HPET_CFG_WRITE_MASK);
    621634            if (isBitJustSet(iOldValue, iNewValue, HPET_CFG_ENABLE))
     
    635648                    TMTimerStop(pThis->aTimers[i].CTX_SUFF(pTimer));
    636649            }
    637             /** @todo: implement i8254 and RTC interaction */
    638             if (isBitJustSet(iNewValue, iOldValue, HPET_CFG_LEGACY))
    639             {               
    640                 rc = hpetLegacyMode(pThis, true);
    641             }
    642             else if (isBitJustCleared(iOldValue, iNewValue, HPET_CFG_LEGACY))
    643             {
    644                 rc = hpetLegacyMode(pThis, false);
    645             }
    646650            break;
    647651        }
     
    10771081
    10781082    LogFlow(("hpetReset:\n"));
     1083
     1084    pThis->u64Config = 0;
    10791085    for (i = 0; i < HPET_NUM_TIMERS; i++)
    10801086    {
  • trunk/src/VBox/Devices/PC/DevPit-i8254.cpp

    r26173 r27121  
    5555#include <iprt/asm.h>
    5656
     57#ifdef IN_RING3
     58# include <iprt/alloc.h>
     59# include <iprt/string.h>
     60# include <iprt/uuid.h>
     61#endif /* IN_RING3 */
     62
    5763#include "../Builtins.h"
    5864
     
    7076
    7177/** The current saved state version. */
    72 #define PIT_SAVED_STATE_VERSION             3
     78#define PIT_SAVED_STATE_VERSION             4
     79/** The saved state version used by VirtualBox 3.1 and earlier.
     80 * This did not include disable by HPET flag. */
     81#define PIT_SAVED_STATE_VERSION_VBOX_31     3
    7382/** The saved state version used by VirtualBox 3.0 and earlier.
    7483 * This did not include the config part. */
     
    147156    /** Config: Speaker enabled. */
    148157    bool                    fSpeakerCfg;
    149     bool                    afAlignment0[HC_ARCH_BITS == 32 ? 1 : 5];
     158    uint8_t                 fDisabledByHpet;
     159#if HC_ARCH_BITS == 64
     160    bool                    afAlignment0[4];
     161#endif
     162    /** PIT port interface. */
     163    PDMIPITPORT             IPITPort;
    150164    /** Pointer to the device instance. */
    151165    PPDMDEVINSR3            pDevIns;
     
    414428    /* We just flip-flop the irq level to save that extra timer call, which isn't generally required (we haven't served it for months). */
    415429    pDevIns = s->CTX_SUFF(pPit)->pDevIns;
    416     PDMDevHlpISASetIrq(pDevIns, s->irq, irq_level);
    417     if (irq_level)
    418         PDMDevHlpISASetIrq(pDevIns, s->irq, 0);
     430
     431    /* If PIT disabled by HPET - just disconnect ticks from interrupt controllers, and not modify
     432     * other moments of device functioning.
     433     * @todo: is it correct?
     434     */
     435    if (!s->pPitR3->fDisabledByHpet)
     436    {
     437        PDMDevHlpISASetIrq(pDevIns, s->irq, irq_level);
     438        if (irq_level)
     439            PDMDevHlpISASetIrq(pDevIns, s->irq, 0);
     440    }
     441
    419442    if (irq_level)
    420443    {
     
    763786
    764787    SSMR3PutS32(pSSM, pThis->speaker_data_on);
     788
     789
    765790#ifdef FAKE_REFRESH_CLOCK
    766     return SSMR3PutS32(pSSM, pThis->dummy_refresh_clock);
     791    SSMR3PutS32(pSSM, pThis->dummy_refresh_clock);
    767792#else
    768     return SSMR3PutS32(pSSM, 0);
     793    SSMR3PutS32(pSSM, 0);
    769794#endif
     795
     796    SSMR3PutU8(pSSM, pThis->fDisabledByHpet);
     797
     798    return 0;
    770799}
    771800
     
    780809
    781810    if (    uVersion != PIT_SAVED_STATE_VERSION
    782         &&  uVersion != PIT_SAVED_STATE_VERSION_VBOX_30)
     811        &&  uVersion != PIT_SAVED_STATE_VERSION_VBOX_30
     812        &&  uVersion != PIT_SAVED_STATE_VERSION_VBOX_31)
    783813        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    784814
     
    839869    SSMR3GetS32(pSSM, &pThis->speaker_data_on);
    840870#ifdef FAKE_REFRESH_CLOCK
    841     return SSMR3GetS32(pSSM, &pThis->dummy_refresh_clock);
     871    SSMR3GetS32(pSSM, &pThis->dummy_refresh_clock);
    842872#else
    843873    int32_t u32Dummy;
    844     return SSMR3GetS32(pSSM, &u32Dummy);
     874    SSMR3GetS32(pSSM, &u32Dummy);
    845875#endif
     876
     877    if (uVersion > PIT_SAVED_STATE_VERSION_VBOX_31)
     878        SSMR3GetU8(pSSM, &pThis->fDisabledByHpet);
     879
     880    return 0;
    846881}
    847882
     
    900935    unsigned i;
    901936    LogFlow(("pitReset: \n"));
     937
     938    pThis->fDisabledByHpet = false;
    902939
    903940    for (i = 0; i < RT_ELEMENTS(pThis->channels); i++)
     
    9631000    pHlp->pfnPrintf(pHlp, "speaker_data_on=%#x\n", pThis->speaker_data_on);
    9641001#endif
    965 }
    966 
     1002    if (pThis->fDisabledByHpet)
     1003        pHlp->pfnPrintf(pHlp, "Disabled by HPET\n");
     1004}
     1005
     1006/**
     1007 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
     1008 */
     1009static DECLCALLBACK(void *) pitQueryInterface(PPDMIBASE pInterface, const char *pszIID)
     1010{
     1011    PPDMDEVINS pDevIns = RT_FROM_MEMBER(pInterface, PDMDEVINS, IBase);
     1012    PITState *pThis = PDMINS_2_DATA(pDevIns, PITState *);
     1013    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE,    &pDevIns->IBase);
     1014    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIPITPORT, &pThis->IPITPort);
     1015    return NULL;
     1016}
     1017
     1018/**
     1019 * @interface_method_impl{PDMIPITPORT,pfnNotifyHpetLegacy}
     1020 *
     1021 * @returns VBox status code
     1022 * @param   pInterface      Pointer to the interface structure containing the called function pointer.
     1023 */
     1024static DECLCALLBACK(int) pitNotifyHpetLegacy(PPDMIPITPORT pInterface, bool fActivate)
     1025{
     1026    PITState *pThis = RT_FROM_MEMBER(pInterface, PITState, IPITPort);
     1027    pThis->fDisabledByHpet = fActivate;
     1028    return VINF_SUCCESS;
     1029}
    9671030
    9681031/**
     
    10691132    if (RT_FAILURE(rc))
    10701133        return rc;
     1134
     1135    /*
     1136     * Interfaces
     1137     */
     1138    /* IBase */
     1139    pDevIns->IBase.pfnQueryInterface            = pitQueryInterface;
     1140    /* IPITPort */
     1141    pThis->IPITPort.pfnNotifyHpetLegacy         = pitNotifyHpetLegacy;
    10711142
    10721143    /*
     
    11301201    /* pfnDetach */
    11311202    NULL,
    1132     /* pfnQueryInterface. */
     1203    /* pfnQueryInterface */
    11331204    NULL,
    11341205    /* pfnInitComplete */
  • trunk/src/VBox/Devices/PC/DevRTC.cpp

    r26173 r27121  
    5454#include <iprt/assert.h>
    5555#include <iprt/string.h>
     56
     57#ifdef IN_RING3
     58# include <iprt/alloc.h>
     59# include <iprt/uuid.h>
     60#endif /* IN_RING3 */
    5661
    5762#include "../Builtins.h"
     
    112117
    113118/** The saved state version. */
    114 #define RTC_SAVED_STATE_VERSION             2
     119#define RTC_SAVED_STATE_VERSION             3
     120/** The saved state version used by VirtualBox 3.1 and earlier.
     121 * This does not include disabled by HPET state.  */
     122#define RTC_SAVED_STATE_VERSION_VBOX_31     2
    115123/** The saved state version used by VirtualBox 3.0 and earlier.
    116124 * This does not include the configuration.  */
     
    138146    uint8_t cmos_data[128];
    139147    uint8_t cmos_index;
    140     uint8_t Alignment0[7];
     148    uint8_t fDisabledByHpet;
     149    uint8_t Alignment0[6];
    141150    struct my_tm current_tm;
    142151    /** The configured IRQ. */
     
    151160    int64_t next_second_time;
    152161
     162    /** RTC port interface. */
     163    PDMIRTCPORT  IRTCPort;
     164
    153165    /** Pointer to the device instance - R3 Ptr. */
    154166    PPDMDEVINSR3 pDevInsR3;
     
    226238}
    227239
     240
     241static void rtc_raise_irq(RTCState* pThis, uint32_t iLevel)
     242{
     243    if (!pThis->fDisabledByHpet)
     244        PDMDevHlpISASetIrq(pThis->CTX_SUFF(pDevIns), pThis->irq, iLevel);
     245}
     246
    228247static void rtc_periodic_timer(void *opaque)
    229248{
     
    232251    rtc_timer_update(s, s->next_periodic_time);
    233252    s->cmos_data[RTC_REG_C] |= 0xc0;
    234     PDMDevHlpISASetIrq(s->CTX_SUFF(pDevIns), s->irq, 1);
     253
     254    rtc_raise_irq(s, 1);
    235255}
    236256
     
    446466
    447467            s->cmos_data[RTC_REG_C] |= 0xa0;
    448             PDMDevHlpISASetIrq(s->CTX_SUFF(pDevIns), s->irq, 1);
     468            rtc_raise_irq(s, 1);
    449469        }
    450470    }
     
    453473    if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
    454474        s->cmos_data[RTC_REG_C] |= 0x90;
    455         PDMDevHlpISASetIrq(s->CTX_SUFF(pDevIns), s->irq, 1);
     475        rtc_raise_irq(s, 1);
    456476    }
    457477
     
    486506        case RTC_REG_C:
    487507            ret = s->cmos_data[s->cmos_index];
    488             PDMDevHlpISASetIrq(s->CTX_SUFF(pDevIns), s->irq, 0);
     508            rtc_raise_irq(s, 0);
    489509            s->cmos_data[RTC_REG_C] = 0x00;
    490510            break;
     
    643663    TMR3TimerSave(pThis->CTX_SUFF(pSecondTimer2), pSSM);
    644664
     665    SSMR3PutU8(pSSM, pThis->fDisabledByHpet);
     666
    645667    return VINF_SUCCESS;
    646668}
     
    656678
    657679    if (    uVersion != RTC_SAVED_STATE_VERSION
     680        &&  uVersion != RTC_SAVED_STATE_VERSION_VBOX_31
    658681        &&  uVersion != RTC_SAVED_STATE_VERSION_VBOX_30)
    659682        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
     
    714737    }
    715738    pThis->cRelLogEntries = 0;
     739
     740
     741    if (uVersion > RTC_SAVED_STATE_VERSION_VBOX_31)
     742         SSMR3GetU8(pSSM, &pThis->fDisabledByHpet);
     743
    716744    return VINF_SUCCESS;
    717745}
     
    846874}
    847875
     876/**
     877 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
     878 */
     879static DECLCALLBACK(void *) rtcQueryInterface(PPDMIBASE pInterface, const char *pszIID)
     880{
     881    PPDMDEVINS pDevIns = RT_FROM_MEMBER(pInterface, PDMDEVINS, IBase);
     882    RTCState *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
     883    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE,    &pDevIns->IBase);
     884    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIRTCPORT, &pThis->IRTCPort);
     885    return NULL;
     886}
     887
     888/**
     889 * @interface_method_impl{PDMIRTCPORT,pfnNotifyHpetLegacy}
     890 */
     891static DECLCALLBACK(int) rtcNotifyHpetLegacy(PPDMIRTCPORT pInterface, bool fActivate)
     892{
     893    RTCState *pThis = RT_FROM_MEMBER(pInterface, RTCState, IRTCPort);
     894    pThis->fDisabledByHpet = fActivate;
     895    return VINF_SUCCESS;
     896}
    848897
    849898/**
     
    913962    pThis->RtcReg.pfnRead       = rtcCMOSRead;
    914963    pThis->RtcReg.pfnWrite      = rtcCMOSWrite;
     964    pThis->fDisabledByHpet      = false;
    915965
    916966    /*
     
    9701020
    9711021    /*
     1022     * Interfaces
     1023     */
     1024    /* IBase */
     1025    pDevIns->IBase.pfnQueryInterface            = rtcQueryInterface;
     1026    /* IRTCPort */
     1027    pThis->IRTCPort.pfnNotifyHpetLegacy         = rtcNotifyHpetLegacy;
     1028
     1029    /*
    9721030     * Register ourselves as the RTC/CMOS with PDM.
     1031     * @todo: maybe use generic iface above?
    9731032     */
    9741033    rc = PDMDevHlpRTCRegister(pDevIns, &pThis->RtcReg, &pThis->pRtcHlpR3);
     
    10371096#endif /* IN_RING3 */
    10381097#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
    1039 
  • trunk/src/VBox/VMM/PDMDevMiscHlp.cpp

    r26939 r27121  
    561561    PDMDEV_ASSERT_DEVINS(pDevIns);
    562562    LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: fActivate=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, fActivate));
    563     return 0;
     563
     564    PPDMIBASE pBase;
     565    int rc;
     566
     567    rc = PDMR3QueryDevice(pDevIns->Internal.s.pVMR3, "i8254", 0, &pBase);
     568    /* No PIT - no problems too */
     569    if (RT_SUCCESS(rc))
     570    {
     571        Assert(pBase);
     572        PPDMIPITPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIPITPORT);
     573
     574        rc = pPort ? pPort->pfnNotifyHpetLegacy(pPort, fActivate) : VINF_SUCCESS;
     575    }
     576    else
     577        rc = VINF_SUCCESS;
     578
     579    if (RT_FAILURE(rc))
     580        return rc;
     581
     582    rc = PDMR3QueryDevice(pDevIns->Internal.s.pVMR3, "mc146818", 0, &pBase);
     583    /* No RTC - no problems too */
     584    if (RT_SUCCESS(rc))
     585    {
     586        Assert(pBase);
     587        PPDMIRTCPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIRTCPORT);
     588        rc = pPort ? pPort->pfnNotifyHpetLegacy(pPort, fActivate) : VINF_SUCCESS;
     589    }
     590    else
     591        rc = VINF_SUCCESS;
     592
     593    return rc;
    564594}
    565595
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