VirtualBox

Changeset 60404 in vbox


Ignore:
Timestamp:
Apr 9, 2016 11:45:55 PM (8 years ago)
Author:
vboxsync
Message:

VMM,Devices,Main: Implemented soft/warm reset for shutdown status codes 05h, 09h and 0Ah.

This is a shot at adjusting our VM reset handling to handle the ancient way of
getting a 286 out of protected mode and back to real mode. Our exiting reset
code (XXXR3Reset, PDMDEVREG::pfnReset, and so on) is doing a cold reset of the
system and then some additional device & memory initialization that the firmware
is usually responsible for doing. When the guest triggers a reset via the
keyboard controller, system control port A, CPU triple fault, and possibly ACPI,
only the CPU is supposed to be reset. The BIOS would then decide whether memory
and devices needed resetting as well, or if the resetter justed wanted to get out
protected mode and resume executing some real mode code pointed to by 467h.

  • New states SOFT_RESETTING and SOFT_RESETTING_LS. The latter returns to RUNNING_LS, not SUSPENDED_LS like for hard reset.
  • Added a firmware interface so the VMM/PDM can ask it whether we're supposed to do a hard reset or a soft(/warm) one.
  • Implemented firmware interface for the PC BIOS (but not EFI). It indicates soft(/warm) reset when CMOS[0xf] is 5, 9 or 10.
  • Moved the CMOS[0xf] resetting from the RTC device to the PC BIOS since it's firmware thing, not RTC.
  • Added a flag parameter to PDMDevHlpVMReset for specifying the source of the reset operation. One class of sources (GIM) will always trigger hard resets, whereas the others will check with the firmware first.
  • Added PDMR3GetResetInfo for query the flags passed to PDMDevHlpVMReset and for asking the firmware whether it's a hard or soft reset. The latter, however, is only done if only CPU 0 is active. Systems with more than one CPU in a state other than EMSTATE_WAIT_SIPI status will always be hard reset.
  • Added internal VMR3ResetFF and VMR3ResetTripleFault APIs for handling the VM_FF_RESET and VINF_EM_TRIPLE_FAULT conditions.
  • Added PMDR3ResetSoft and had it call pfnSoftReset (which is now defined).

Warning! Major PDM_DEVHLPR3_VERSION change, minor PDM_DEVREG_VERSION change.

Location:
trunk
Files:
20 edited

Legend:

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

    r58111 r60404  
    163163    /** Live save: The VM is being reset and immediately suspended. */
    164164    VMSTATE_RESETTING_LS,
     165    /** The VM is being soft/warm reset. */
     166    VMSTATE_SOFT_RESETTING,
     167    /** Live save: The VM is being soft/warm reset (not suspended afterwards). */
     168    VMSTATE_SOFT_RESETTING_LS,
    165169    /** The VM is being suspended. */
    166170    VMSTATE_SUSPENDING,
  • trunk/include/VBox/vmm/pdmapi.h

    r60396 r60404  
    8585VMMR3_INT_DECL(int)     PDMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
    8686VMMR3DECL(void)         PDMR3PowerOn(PVM pVM);
     87VMMR3_INT_DECL(bool)    PDMR3GetResetInfo(PVM pVM, uint32_t fOverride, uint32_t *pfResetFlags);
    8788VMMR3_INT_DECL(void)    PDMR3ResetCpu(PVMCPU pVCpu);
    8889VMMR3_INT_DECL(void)    PDMR3Reset(PVM pVM);
    8990VMMR3_INT_DECL(void)    PDMR3MemSetup(PVM pVM, bool fAtReset);
     91VMMR3_INT_DECL(void)    PDMR3SoftReset(PVM pVM, uint32_t fResetFlags);
    9092VMMR3_INT_DECL(void)    PDMR3Suspend(PVM pVM);
    9193VMMR3_INT_DECL(void)    PDMR3Resume(PVM pVM);
  • trunk/include/VBox/vmm/pdmdev.h

    r60396 r60404  
    132132/** Pointer to a FNPDMDEVRESET() function. */
    133133typedef FNPDMDEVRESET *PFNPDMDEVRESET;
     134
     135/**
     136 * Soft reset notification.
     137 *
     138 * This is mainly for emulating the 286 style protected mode exits, in which
     139 * most devices should remain in their current state.
     140 *
     141 * @returns VBox status.
     142 * @param   pDevIns     The device instance data.
     143 * @param   fFlags      PDMVMRESET_F_XXX (only bits relevant to soft resets).
     144 *
     145 * @remarks Caller enters the device critical section.
     146 */
     147typedef DECLCALLBACK(void)  FNPDMDEVSOFTRESET(PPDMDEVINS pDevIns, uint32_t fFlags);
     148/** Pointer to a FNPDMDEVSOFTRESET() function. */
     149typedef FNPDMDEVSOFTRESET *PFNPDMDEVSOFTRESET;
     150
     151/** @name PDMVMRESET_F_XXX - VM reset flags.
     152 * These flags are used both for FNPDMDEVSOFTRESET and for hardware signalling
     153 * reset via PDMDevHlpVMReset.
     154 * @{ */
     155/** Unknown reason. */
     156#define PDMVMRESET_F_UNKNOWN            UINT32_C(0x00000000)
     157/** GIM triggered reset. */
     158#define PDMVMRESET_F_GIM                UINT32_C(0x00000001)
     159/** The last source always causing hard resets. */
     160#define PDMVMRESET_F_LAST_ALWAYS_HARD   PDMVMRESET_F_GIM
     161/** ACPI triggered reset. */
     162#define PDMVMRESET_F_ACPI               UINT32_C(0x0000000c)
     163/** PS/2 system port A (92h) reset. */
     164#define PDMVMRESET_F_PORT_A             UINT32_C(0x0000000d)
     165/** Keyboard reset. */
     166#define PDMVMRESET_F_KBD                UINT32_C(0x0000000e)
     167/** Tripple fault. */
     168#define PDMVMRESET_F_TRIPLE_FAULT       UINT32_C(0x0000000f)
     169/** Reset source mask. */
     170#define PDMVMRESET_F_SRC_MASK           UINT32_C(0x0000000f)
     171/** @} */
    134172
    135173/**
     
    334372     * Critical section is entered. */
    335373    PFNPDMDEVPOWEROFF   pfnPowerOff;
    336     /** @todo */
    337     PFNRT               pfnSoftReset;
     374    /** Software system reset notification - optional.
     375     * Critical section is entered. */
     376    PFNPDMDEVSOFTRESET  pfnSoftReset;
    338377    /** Initialization safty marker. */
    339378    uint32_t            u32VersionEnd;
     
    345384
    346385/** Current DEVREG version number. */
    347 #define PDM_DEVREG_VERSION                      PDM_VERSION_MAKE(0xffff, 2, 0)
     386#define PDM_DEVREG_VERSION                      PDM_VERSION_MAKE(0xffff, 2, 1)
    348387
    349388/** PDM Device Flags.
     
    10531092
    10541093/**
     1094 * Firmware registration structure.
     1095 */
     1096typedef struct PDMFWREG
     1097{
     1098    /** Struct version+magic number (PDM_FWREG_VERSION). */
     1099    uint32_t                u32Version;
     1100
     1101    /**
     1102     * Checks whether this is a hard or soft reset.
     1103     *
     1104     * The current definition of soft reset is what the PC BIOS does when CMOS[0xF]
     1105     * is 5, 9 or 0xA.
     1106     *
     1107     * @returns true if hard reset, false if soft.
     1108     * @param   pDevIns         Device instance of the firmware.
     1109     * @param   fFlags          PDMRESET_F_XXX passed to the PDMDevHlpVMReset API.
     1110     */
     1111    DECLR3CALLBACKMEMBER(bool, pfnIsHardReset,(PPDMDEVINS pDevIns, uint32_t fFlags));
     1112
     1113    /** Just a safety precaution. */
     1114    uint32_t                u32TheEnd;
     1115} PDMFWREG;
     1116/** Pointer to a FW registration structure. */
     1117typedef PDMFWREG *PPDMFWREG;
     1118/** Pointer to a const FW registration structure. */
     1119typedef PDMFWREG const *PCPDMFWREG;
     1120
     1121/** Current PDMFWREG version number. */
     1122#define PDM_FWREG_VERSION                       PDM_VERSION_MAKE(0xffdd, 1, 0)
     1123
     1124/**
     1125 * Firmware R3 helpers.
     1126 */
     1127typedef struct PDMFWHLPR3
     1128{
     1129    /** Structure version. PDM_FWHLP_VERSION defines the current version. */
     1130    uint32_t                u32Version;
     1131
     1132    /** Just a safety precaution. */
     1133    uint32_t                u32TheEnd;
     1134} PDMFWHLPR3;
     1135
     1136/** Pointer to FW R3 helpers. */
     1137typedef R3PTRTYPE(PDMFWHLPR3 *) PPDMFWHLPR3;
     1138/** Pointer to const FW R3 helpers. */
     1139typedef R3PTRTYPE(const PDMFWHLPR3 *) PCPDMFWHLPR3;
     1140
     1141/** Current PDMFWHLPR3 version number. */
     1142#define PDM_FWHLPR3_VERSION                     PDM_VERSION_MAKE(0xffdb, 1, 0)
     1143
     1144
     1145/**
    10551146 * Advanced Programmable Interrupt Controller registration structure.
    10561147 */
     
    35743665
    35753666    /**
    3576      * Unregisters the VMM device heap - OBSOLETE.
    3577      *
    3578      * This entry can be reused.
    3579      * This entry can be reused.
    3580      * This entry can be reused.
     3667     * Registers the firmware (BIOS, EFI) device with PDM.
     3668     *
     3669     * The firmware provides a callback table and gets a special PDM helper table.
     3670     * There can only be one firmware device for a VM.
    35813671     *
    35823672     * @returns VBox status code.
    35833673     * @param   pDevIns             The device instance.
    3584      * @param   GCPhys              The physical address.
    3585      * @thread  EMT.
    3586      * @obsolete
    3587      */
    3588     DECLR3CALLBACKMEMBER(int, pfnUnregisterVMMDevHeap,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys));
     3674     * @param   pFwReg              Firmware registration structure.
     3675     * @param   ppFwHlp             Where to return the firmware helper structure.
     3676     * @remarks Only valid during device construction.
     3677     * @thread  EMT(0)
     3678     */
     3679    DECLR3CALLBACKMEMBER(int, pfnFirmwareRegister,(PPDMDEVINS pDevIns, PCPDMFWREG pFwReg, PCPDMFWHLPR3 *ppFwHlpR3));
    35893680
    35903681    /**
     
    35933684     * @returns The appropriate VBox status code to pass around on reset.
    35943685     * @param   pDevIns             The device instance.
     3686     * @param   fFlags              PDMVMRESET_F_XXX flags.
    35953687     * @thread  The emulation thread.
    35963688     */
    3597     DECLR3CALLBACKMEMBER(int, pfnVMReset,(PPDMDEVINS pDevIns));
     3689    DECLR3CALLBACKMEMBER(int, pfnVMReset,(PPDMDEVINS pDevIns, uint32_t fFlags));
    35983690
    35993691    /**
     
    37053797
    37063798/** Current PDMDEVHLPR3 version number. */
    3707 #define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE(0xffe7, 15, 1)
     3799#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE(0xffe7, 16, 0)
    37083800
    37093801
     
    52985390
    52995391/**
     5392 * @copydoc PDMDEVHLPR3::pfnFirmwareRegister
     5393 */
     5394DECLINLINE(int) PDMDevHlpFirmwareRegister(PPDMDEVINS pDevIns, PCPDMFWREG pFwReg, PCPDMFWHLPR3 *ppFwHlpR3)
     5395{
     5396    return pDevIns->pHlpR3->pfnFirmwareRegister(pDevIns, pFwReg, ppFwHlpR3);
     5397}
     5398
     5399/**
    53005400 * @copydoc PDMDEVHLPR3::pfnVMReset
    53015401 */
    5302 DECLINLINE(int) PDMDevHlpVMReset(PPDMDEVINS pDevIns)
    5303 {
    5304     return pDevIns->pHlpR3->pfnVMReset(pDevIns);
     5402DECLINLINE(int) PDMDevHlpVMReset(PPDMDEVINS pDevIns, uint32_t fFlags)
     5403{
     5404    return pDevIns->pHlpR3->pfnVMReset(pDevIns, fFlags);
    53055405}
    53065406
  • trunk/include/VBox/vmm/vmapi.h

    r58125 r60404  
    412412VMMR3DECL(VMRESUMEREASON) VMR3GetResumeReason(PUVM);
    413413VMMR3DECL(int)          VMR3Reset(PUVM pUVM);
     414VMMR3_INT_DECL(VBOXSTRICTRC) VMR3ResetFF(PVM pVM);
     415VMMR3_INT_DECL(VBOXSTRICTRC) VMR3ResetTripleFault(PVM pVM);
    414416VMMR3DECL(int)          VMR3Save(PUVM pUVM, const char *pszFilename, bool fContinueAfterwards, PFNVMPROGRESS pfnProgress, void *pvUser, bool *pfSuspended);
    415417VMMR3_INT_DECL(int)     VMR3SaveFT(PUVM pUVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, bool *pfSuspended, bool fSkipStateChanges);
  • trunk/src/VBox/Devices/Input/DevPS2.cpp

    r58170 r60404  
    548548#else /* IN_RING3 */
    549549        LogRel(("Reset initiated by keyboard controller\n"));
    550         rc = PDMDevHlpVMReset(s->CTX_SUFF(pDevIns));
     550        rc = PDMDevHlpVMReset(s->CTX_SUFF(pDevIns), PDMVMRESET_F_KBD);
    551551#endif /* !IN_RING3 */
    552552        break;
     
    556556    /* Make OS/2 happy. */
    557557    /* The 8042 RAM is readable using commands 0x20 thru 0x3f, and writable
    558        by 0x60 thru 0x7f. Now days only the firs byte, the mode, is used.
     558       by 0x60 thru 0x7f. Now days only the first byte, the mode, is used.
    559559       We'll ignore the writes (0x61..7f) and return 0 for all the reads
    560560       just to make some OS/2 debug stuff a bit happier. */
     
    10161016            rc = VINF_IOM_R3_IOPORT_WRITE;
    10171017# else
    1018             rc = PDMDevHlpVMReset(s->CTX_SUFF(pDevIns));
     1018            rc = PDMDevHlpVMReset(s->CTX_SUFF(pDevIns), PDMVMRESET_F_KBD);
    10191019# endif
    10201020        }
  • trunk/src/VBox/Devices/PC/DevACPI.cpp

    r59919 r60404  
    17531753    {
    17541754        LogRel(("ACPI: Reset initiated by ACPI\n"));
    1755         rc = PDMDevHlpVMReset(pDevIns);
     1755        rc = PDMDevHlpVMReset(pDevIns, PDMVMRESET_F_ACPI);
    17561756    }
    17571757    else
  • trunk/src/VBox/Devices/PC/DevPcArch.cpp

    r57358 r60404  
    171171        {
    172172            LogRel(("Reset initiated by system port A\n"));
    173             return PDMDevHlpVMReset(pDevIns);
     173            return PDMDevHlpVMReset(pDevIns, PDMVMRESET_F_PORT_A);
    174174        }
    175175
  • trunk/src/VBox/Devices/PC/DevPcBios.cpp

    r59253 r60404  
    199199    uint32_t        u32McfgBase;
    200200    uint32_t        cbMcfgLength;
     201
     202    /** Firmware registration structure.   */
     203    PDMFWREG        FwReg;
     204    /** Dummy. */
     205    PCPDMFWHLPR3    pFwHlpR3;
     206    /** Whether to consult the shutdown status (CMOS[0xf]) for deciding upon soft
     207     * or hard reset. */
     208    bool            fCheckShutdownStatusForSoftReset;
     209    /** Whether to clear the shutdown status on hard reset. */
     210    bool            fClearShutdownStatusOnHardReset;
     211    /** Number of soft resets we've logged. */
     212    uint32_t        cLoggedSoftResets;
    201213} DEVPCBIOS;
    202214/** Pointer to the BIOS device state. */
     
    281293    /* not in use. */
    282294    return VINF_SUCCESS;
     295}
     296
     297
     298/**
     299 * Write to CMOS memory.
     300 * This is used by the init complete code.
     301 */
     302static void pcbiosCmosWrite(PPDMDEVINS pDevIns, int off, uint32_t u32Val)
     303{
     304    Assert(off < 256);
     305    Assert(u32Val < 256);
     306
     307    int rc = PDMDevHlpCMOSWrite(pDevIns, off, u32Val);
     308    AssertRC(rc);
     309}
     310
     311
     312/**
     313 * Read from CMOS memory.
     314 * This is used by the init complete code.
     315 */
     316static uint8_t pcbiosCmosRead(PPDMDEVINS pDevIns, unsigned off)
     317{
     318    Assert(off < 256);
     319
     320    uint8_t u8val;
     321    int rc = PDMDevHlpCMOSRead(pDevIns, off, &u8val);
     322    AssertRC(rc);
     323
     324    return u8val;
     325}
     326
     327
     328/**
     329 * @interface_method_impl{PDMFWREG,pfnIsHardReset}
     330 */
     331static DECLCALLBACK(bool) pcbiosFw_IsHardReset(PPDMDEVINS pDevIns, uint32_t fFlags)
     332{
     333    PDEVPCBIOS pThis = PDMINS_2_DATA(pDevIns, PDEVPCBIOS);
     334    if (pThis->fCheckShutdownStatusForSoftReset)
     335    {
     336        uint8_t bShutdownStatus = pcbiosCmosRead(pDevIns, 0xf);
     337        if (   bShutdownStatus == 0x5
     338            || bShutdownStatus == 0x9
     339            || bShutdownStatus == 0xa)
     340        {
     341            const uint32_t cMaxLogged = 10;
     342            if (pThis->cLoggedSoftResets < cMaxLogged)
     343            {
     344                RTFAR16 Far16 = { 0xfeed, 0xface };
     345                PDMDevHlpPhysRead(pDevIns, 0x467, &Far16, sizeof(Far16));
     346                pThis->cLoggedSoftResets++;
     347                LogRel(("PcBios: Soft reset #%u - shutdown status %#x, warm reset vector (0040:0067) is %04x:%04x%s\n",
     348                        pThis->cLoggedSoftResets, bShutdownStatus, Far16.sel, Far16.sel,
     349                        pThis->cLoggedSoftResets < cMaxLogged ? "." : " - won't log any more!"));
     350            }
     351            return false;
     352        }
     353    }
     354    return true;
     355}
     356
     357
     358/**
     359 * @interface_method_impl{PDMDEVREG,pfnReset}
     360 */
     361static DECLCALLBACK(void) pcbiosReset(PPDMDEVINS pDevIns)
     362{
     363    PDEVPCBIOS pThis = PDMINS_2_DATA(pDevIns, PDEVPCBIOS);
     364
     365    if (pThis->fClearShutdownStatusOnHardReset)
     366    {
     367        uint8_t bShutdownStatus = pcbiosCmosRead(pDevIns, 0xf);
     368        if (bShutdownStatus != 0)
     369        {
     370            LogRel(("PcBios: Clearing shutdown status code %02x.\n", bShutdownStatus));
     371            pcbiosCmosWrite(pDevIns, 0xf, 0);
     372        }
     373    }
    283374}
    284375
     
    329420    }
    330421    return VERR_INVALID_PARAMETER;
    331 }
    332 
    333 
    334 /**
    335  * Write to CMOS memory.
    336  * This is used by the init complete code.
    337  */
    338 static void pcbiosCmosWrite(PPDMDEVINS pDevIns, int off, uint32_t u32Val)
    339 {
    340     Assert(off < 256);
    341     Assert(u32Val < 256);
    342 
    343     int rc = PDMDevHlpCMOSWrite(pDevIns, off, u32Val);
    344     AssertRC(rc);
    345 }
    346 
    347 
    348 /**
    349  * Read from CMOS memory.
    350  * This is used by the init complete code.
    351  */
    352 static uint8_t pcbiosCmosRead(PPDMDEVINS pDevIns, int off)
    353 {
    354     uint8_t     u8val;
    355 
    356     Assert(off < 256);
    357 
    358     int rc = PDMDevHlpCMOSRead(pDevIns, off, &u8val);
    359     AssertRC(rc);
    360 
    361     return u8val;
    362422}
    363423
     
    10751135                              "DmiExposeMemoryTable\0"
    10761136                              "DmiExposeProcInf\0"
     1137                              "CheckShutdownStatusForSoftReset\0"
     1138                              "ClearShutdownStatusOnHardReset\0"
    10771139                              ))
    10781140        return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
     
    15291591    /*
    15301592     * Map the Network Boot ROM into memory.
     1593     *
    15311594     * Currently there is a fixed mapping: 0x000e2000 to 0x000effff contains
    15321595     * the (up to) 56 kb ROM image.  The mapping size is fixed to trouble with
     
    15501613    if (pThis->uBootDelay > 15)
    15511614        pThis->uBootDelay = 15;
     1615
     1616
     1617    /*
     1618     * Read shutdown status code config and register ourselves as the firmware device.
     1619     */
     1620
     1621    /** @cfgm{CheckShutdownStatusForSoftReset, boolean, true}
     1622     * Whether to consult the shutdown status code (CMOS register 0Fh) to
     1623     * determine whether the guest intended a soft or hard reset.  Currently only
     1624     * shutdown status codes 05h, 09h and 0Ah are considered soft reset. */
     1625    rc = CFGMR3QueryBoolDef(pCfg, "CheckShutdownStatusForSoftReset", &pThis->fCheckShutdownStatusForSoftReset, true);
     1626    AssertLogRelRCReturn(rc, rc);
     1627
     1628    /** @cfgm{ClearShutdownStatusOnHardReset, boolean, true}
     1629     * Whether to clear the shutdown status code (CMOS register 0Fh) on hard reset. */
     1630    rc = CFGMR3QueryBoolDef(pCfg, "ClearShutdownStatusOnHardReset", &pThis->fClearShutdownStatusOnHardReset, true);
     1631    AssertLogRelRCReturn(rc, rc);
     1632
     1633    LogRel(("PcBios: fCheckShutdownStatusForSoftReset=%RTbool  fClearShutdownStatusOnHardReset=%RTbool\n",
     1634            pThis->fCheckShutdownStatusForSoftReset, pThis->fClearShutdownStatusOnHardReset));
     1635
     1636    static PDMFWREG const s_FwReg = { PDM_FWREG_VERSION, pcbiosFw_IsHardReset, PDM_FWREG_VERSION };
     1637    rc = PDMDevHlpFirmwareRegister(pDevIns, &s_FwReg, &pThis->pFwHlpR3);
     1638    AssertLogRelRCReturn(rc, rc);
    15521639
    15531640    return VINF_SUCCESS;
     
    15891676    NULL,
    15901677    /* pfnReset */
    1591     NULL,
     1678    pcbiosReset,
    15921679    /* pfnSuspend */
    15931680    NULL,
  • trunk/src/VBox/Devices/PC/DevRTC.cpp

    r57358 r60404  
    10541054    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
    10551055
    1056     /* If shutdown status is non-zero, log its value. */
    1057     if (pThis->cmos_data[0xF])
    1058     {
    1059         LogRel(("CMOS shutdown status byte is %02X\n", pThis->cmos_data[0xF]));
    1060 
    1061 #if 0   /* It would be nice to log the warm reboot vector but alas, we already trashed it. */
    1062         uint32_t u32WarmVector;
    1063         int rc;
    1064         rc = PDMDevHlpPhysRead(pDevIns, 0x467, &u32WarmVector, sizeof(u32WarmVector));
    1065         AssertRC(rc);
    1066         LogRel((", 40:67 contains %04X:%04X\n", u32WarmVector >> 16, u32WarmVector & 0xFFFF));
    1067 #endif
    1068         /* If we're going to trash the VM's memory, we also have to clear this. */
    1069         pThis->cmos_data[0xF] = 0;
    1070     }
    1071 
    10721056    /* Reset index values (important for second bank). */
    1073     pThis->cmos_index[0]        = 0;
    1074     pThis->cmos_index[1]        = CMOS_BANK_SIZE;   /* Point to start of second bank. */
     1057    pThis->cmos_index[0] = 0;
     1058    pThis->cmos_index[1] = CMOS_BANK_SIZE;   /* Point to start of second bank. */
    10751059}
    10761060
     
    10921076                              "Base\0"
    10931077                              "UseUTC\0"
    1094                               "GCEnabled\0"
     1078                              "RCEnabled\0"
    10951079                              "R0Enabled\0"))
    10961080        return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
     
    11161100                                N_("Configuration error: Querying \"UseUTC\" as a bool failed"));
    11171101
    1118     bool fGCEnabled;
    1119     rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fGCEnabled, true);
     1102    bool fRCEnabled;
     1103    rc = CFGMR3QueryBoolDef(pCfg, "RCEnabled", &fRCEnabled, true);
    11201104    if (RT_FAILURE(rc))
    11211105        return PDMDEV_SET_ERROR(pDevIns, rc,
     
    11281112                                N_("Configuration error: failed to read R0Enabled as boolean"));
    11291113
    1130     Log(("RTC: Irq=%#x Base=%#x fGCEnabled=%RTbool fR0Enabled=%RTbool\n",
    1131          u8Irq, pThis->IOPortBase, fGCEnabled, fR0Enabled));
     1114    Log(("RTC: Irq=%#x Base=%#x fRCEnabled=%RTbool fR0Enabled=%RTbool\n",
     1115         u8Irq, pThis->IOPortBase, fRCEnabled, fR0Enabled));
    11321116
    11331117
     
    11991183    if (RT_FAILURE(rc))
    12001184        return rc;
    1201     if (fGCEnabled)
     1185    if (fRCEnabled)
    12021186    {
    12031187        rc = PDMDevHlpIOPortRegisterRC(pDevIns, pThis->IOPortBase, 4, NIL_RTRCPTR,
  • trunk/src/VBox/Devices/Storage/DrvVD.cpp

    r60179 r60404  
    31403140        || enmVmState == VMSTATE_RESETTING
    31413141        || enmVmState == VMSTATE_RESETTING_LS
     3142        || enmVmState == VMSTATE_SOFT_RESETTING
     3143        || enmVmState == VMSTATE_SOFT_RESETTING_LS
    31423144        || enmVmState == VMSTATE_SUSPENDING
    31433145        || enmVmState == VMSTATE_SUSPENDING_LS
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r59996 r60404  
    33033303    switch (enmVMState)
    33043304    {
     3305        case VMSTATE_RUNNING:
    33053306        case VMSTATE_RESETTING:
    3306         case VMSTATE_RUNNING:
     3307        case VMSTATE_SOFT_RESETTING:
    33073308        {
    33083309            LogFlowFunc(("Suspending the VM...\n"));
     
    65556556        case VMSTATE_RESETTING:
    65566557        case VMSTATE_RESETTING_LS:
     6558        case VMSTATE_SOFT_RESETTING:
     6559        case VMSTATE_SOFT_RESETTING_LS:
    65576560        case VMSTATE_DEBUGGING:
    65586561        case VMSTATE_DEBUGGING_LS:
     
    83468349
    83478350        case VMSTATE_RESETTING:
     8351        /** @todo shouldn't VMSTATE_RESETTING_LS be here?   */
    83488352        {
    83498353#ifdef VBOX_WITH_GUEST_PROPS
     
    83538357            break;
    83548358        }
     8359
     8360        case VMSTATE_SOFT_RESETTING:
     8361        case VMSTATE_SOFT_RESETTING_LS:
     8362            /* Shouldn't do anything here! */
     8363            break;
    83558364
    83568365        case VMSTATE_SUSPENDED:
  • trunk/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp

    r57358 r60404  
    863863                case VMSTATE_RESETTING:
    864864                case VMSTATE_RESETTING_LS:
     865                case VMSTATE_SOFT_RESETTING:
     866                case VMSTATE_SOFT_RESETTING_LS:
    865867                    Assert(!pState->mfSuspendedByUs);
    866868                    Assert(!pState->mfUnlockedMedia);
  • trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp

    r60356 r60404  
    695695            {
    696696                LogRel(("GIM: HyperV: Reset initiated through MSR\n"));
    697                 int rc = PDMDevHlpVMReset(pVM->gim.s.pDevInsR3);
    698                 AssertRC(rc);
     697                int rc = PDMDevHlpVMReset(pVM->gim.s.pDevInsR3, PDMVMRESET_F_GIM);
     698                AssertRC(rc); /* Note! Not allowed to return VINF_EM_RESET / VINF_EM_HALT here, so ignore them. */
    699699            }
    700700            /* else: Ignore writes to other bits. */
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r59674 r60404  
    477477    pVCpu->em.s.fForceRAW = false;
    478478
    479     /* VMR3Reset may return VINF_EM_RESET or VINF_EM_SUSPEND, so transition
     479    /* VMR3ResetFF may return VINF_EM_RESET or VINF_EM_SUSPEND, so transition
    480480       out of the HALTED state here so that enmPrevState doesn't end up as
    481481       HALTED when EMR3Execute returns. */
     
    17011701        if (VM_FF_TEST_AND_CLEAR(pVM, VM_FF_RESET))
    17021702        {
    1703             rc2 = VMR3Reset(pVM->pUVM);
     1703            rc2 = VBOXSTRICTRC_TODO(VMR3ResetFF(pVM));
    17041704            UPDATE_RC();
    17051705        }
     
    24042404                    {
    24052405                        Log(("EMR3ExecuteVM: VINF_EM_TRIPLE_FAULT: CPU reset...\n"));
    2406                         Assert(pVM->cCpus == 1);
    2407 #ifdef VBOX_WITH_REM
    2408                         REMR3Reset(pVM);
    2409 #endif
    2410                         PGMR3ResetCpu(pVM, pVCpu);
    2411                         TRPMR3ResetCpu(pVCpu);
    2412                         CPUMR3ResetCpu(pVM, pVCpu);
    2413                         EMR3ResetCpu(pVCpu);
    2414                         HMR3ResetCpu(pVCpu);
    2415                         pVCpu->em.s.enmState = emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx);
    2416                         Log2(("EMR3ExecuteVM: VINF_EM_TRIPLE_FAULT: %d -> %d\n", enmOldState, pVCpu->em.s.enmState));
    2417                         break;
     2406                        rc = VBOXSTRICTRC_TODO(VMR3ResetTripleFault(pVM));
     2407                        Log2(("EMR3ExecuteVM: VINF_EM_TRIPLE_FAULT: %d -> %d (rc=%Rrc)\n", enmOldState, pVCpu->em.s.enmState, rc));
     2408                        continue;
    24182409                    }
    24192410                    /* Else fall through and trigger a guru. */
  • trunk/src/VBox/VMM/VMMR3/PDM.cpp

    r60396 r60404  
    256256#include "PDMInternal.h"
    257257#include <VBox/vmm/pdm.h>
     258#include <VBox/vmm/em.h>
    258259#include <VBox/vmm/mm.h>
    259260#include <VBox/vmm/pgm.h>
     
    16201621
    16211622    LogFlow(("PDMR3MemSetup: returns void\n"));
     1623}
     1624
     1625
     1626/**
     1627 * Retrieves and resets the info left behind by PDMDevHlpVMReset.
     1628 *
     1629 * @returns True if hard reset, false if soft reset.
     1630 * @param   pVM             The cross context VM structure.
     1631 * @param   fOverride       If non-zero, the override flags will be used instead
     1632 *                          of the reset flags kept by PDM. (For triple faults.)
     1633 * @param   pfResetFlags    Where to return the reset flags (PDMVMRESET_F_XXX).
     1634 * @thread  EMT
     1635 */
     1636VMMR3_INT_DECL(bool) PDMR3GetResetInfo(PVM pVM, uint32_t fOverride, uint32_t *pfResetFlags)
     1637{
     1638    VM_ASSERT_EMT(pVM);
     1639
     1640    /*
     1641     * Get the reset flags.
     1642     */
     1643    uint32_t fResetFlags;
     1644    fResetFlags = ASMAtomicXchgU32(&pVM->pdm.s.fResetFlags, 0);
     1645    if (fOverride)
     1646        fResetFlags = fOverride;
     1647    *pfResetFlags = fResetFlags;
     1648
     1649    /*
     1650     * To try avoid trouble, we never ever do soft/warm resets on SMP systems
     1651     * with more than CPU #0 active.  However, if only one CPU is active we
     1652     * will ask the firmware what it wants us to do (because the firmware may
     1653     * depend on the VMM doing a lot of what is normally its responsibility,
     1654     * like clearing memory).
     1655     */
     1656    bool     fOtherCpusActive = false;
     1657    VMCPUID  iCpu             = pVM->cCpus;
     1658    while (iCpu-- > 1)
     1659    {
     1660        EMSTATE enmState = EMGetState(&pVM->aCpus[iCpu]);
     1661        if (   enmState != EMSTATE_WAIT_SIPI
     1662            && enmState != EMSTATE_NONE)
     1663        {
     1664            fOtherCpusActive = true;
     1665            break;
     1666        }
     1667    }
     1668
     1669    bool fHardReset = fOtherCpusActive
     1670                   || (fResetFlags & PDMVMRESET_F_SRC_MASK) < PDMVMRESET_F_LAST_ALWAYS_HARD
     1671                   || !pVM->pdm.s.pFirmware
     1672                   || pVM->pdm.s.pFirmware->Reg.pfnIsHardReset(pVM->pdm.s.pFirmware->pDevIns, fResetFlags);
     1673
     1674    Log(("PDMR3GetResetInfo: returns fHardReset=%RTbool fResetFlags=%#x\n", fHardReset, fResetFlags));
     1675    return fHardReset;
     1676}
     1677
     1678
     1679/**
     1680 * Performs a soft reset of devices.
     1681 *
     1682 * @param   pVM             The cross context VM structure.
     1683 * @param   fResetFlags     PDMVMRESET_F_XXX.
     1684 */
     1685VMMR3_INT_DECL(void) PDMR3SoftReset(PVM pVM, uint32_t fResetFlags)
     1686{
     1687    LogFlow(("PDMR3SoftReset: fResetFlags=%#x\n", fResetFlags));
     1688
     1689    /*
     1690     * Iterate thru the device instances and work the callback.
     1691     */
     1692    for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3)
     1693        if (pDevIns->pReg->pfnSoftReset)
     1694        {
     1695            PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED);
     1696            pDevIns->pReg->pfnSoftReset(pDevIns, fResetFlags);
     1697            PDMCritSectLeave(pDevIns->pCritSectRoR3);
     1698        }
     1699
     1700    LogFlow(("PDMR3SoftReset: returns void\n"));
    16221701}
    16231702
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp

    r60396 r60404  
    33073307
    33083308/**
    3309  * @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap
     3309 * @interface_method_impl{PDMDEVHLPR3,pfnFirmwareRegister}
    33103310 */
    3311 static DECLCALLBACK(int) pdmR3DevHlp_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
    3312 {
    3313     /* Free to replace this interface. */
    3314     AssertFailedReturn(VERR_NOT_IMPLEMENTED);
     3311static DECLCALLBACK(int) pdmR3DevHlp_FirmwareRegister(PPDMDEVINS pDevIns, PCPDMFWREG pFwReg, PCPDMFWHLPR3 *ppFwHlp)
     3312{
     3313    PDMDEV_ASSERT_DEVINS(pDevIns);
     3314    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
     3315    LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: pFWReg=%p:{.u32Version=%#x, .pfnIsHardReset=%p, .u32TheEnd=%#x} ppFwHlp=%p\n",
     3316             pDevIns->pReg->szName, pDevIns->iInstance, pFwReg, pFwReg->u32Version, pFwReg->pfnIsHardReset, pFwReg->u32TheEnd, ppFwHlp));
     3317
     3318    /*
     3319     * Validate input.
     3320     */
     3321    if (pFwReg->u32Version != PDM_FWREG_VERSION)
     3322    {
     3323        AssertMsgFailed(("u32Version=%#x expected %#x\n", pFwReg->u32Version, PDM_FWREG_VERSION));
     3324        LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc (version)\n",
     3325                 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
     3326        return VERR_INVALID_PARAMETER;
     3327    }
     3328    if (!pFwReg->pfnIsHardReset)
     3329    {
     3330        Assert(pFwReg->pfnIsHardReset);
     3331        LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc (callbacks)\n",
     3332                 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
     3333        return VERR_INVALID_PARAMETER;
     3334    }
     3335
     3336    if (!ppFwHlp)
     3337    {
     3338        Assert(ppFwHlp);
     3339        LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc (ppFwHlp)\n",
     3340                 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
     3341        return VERR_INVALID_PARAMETER;
     3342    }
     3343
     3344    /*
     3345     * Only one DMA device.
     3346     */
     3347    PVM pVM = pDevIns->Internal.s.pVMR3;
     3348    if (pVM->pdm.s.pFirmware)
     3349    {
     3350        AssertMsgFailed(("Only one firmware device is supported!\n"));
     3351        LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc\n",
     3352                 pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
     3353        return VERR_INVALID_PARAMETER;
     3354    }
     3355
     3356    /*
     3357     * Allocate and initialize pci bus structure.
     3358     */
     3359    int rc = VINF_SUCCESS;
     3360    PPDMFW pFirmware = (PPDMFW)MMR3HeapAlloc(pDevIns->Internal.s.pVMR3, MM_TAG_PDM_DEVICE, sizeof(*pFirmware));
     3361    if (pFirmware)
     3362    {
     3363        pFirmware->pDevIns   = pDevIns;
     3364        pFirmware->Reg       = *pFwReg;
     3365        pVM->pdm.s.pFirmware = pFirmware;
     3366
     3367        /* set the helper pointer. */
     3368        *ppFwHlp = &g_pdmR3DevFirmwareHlp;
     3369        Log(("PDM: Registered firmware device '%s'/%d pDevIns=%p\n",
     3370             pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
     3371    }
     3372    else
     3373        rc = VERR_NO_MEMORY;
     3374
     3375    LogFlow(("pdmR3DevHlp_FirmwareRegister: caller='%s'/%d: returns %Rrc\n",
     3376             pDevIns->pReg->szName, pDevIns->iInstance, rc));
     3377    return rc;
    33153378}
    33163379
    33173380
    33183381/** @interface_method_impl{PDMDEVHLPR3,pfnVMReset} */
    3319 static DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns)
    3320 {
    3321     PDMDEV_ASSERT_DEVINS(pDevIns);
    3322     PVM pVM = pDevIns->Internal.s.pVMR3;
    3323     VM_ASSERT_EMT(pVM);
    3324     LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: VM_FF_RESET %d -> 1\n",
    3325              pDevIns->pReg->szName, pDevIns->iInstance, VM_FF_IS_SET(pVM, VM_FF_RESET)));
     3382static DECLCALLBACK(int) pdmR3DevHlp_VMReset(PPDMDEVINS pDevIns, uint32_t fFlags)
     3383{
     3384    PDMDEV_ASSERT_DEVINS(pDevIns);
     3385    PVM pVM = pDevIns->Internal.s.pVMR3;
     3386    VM_ASSERT_EMT(pVM);
     3387    LogFlow(("pdmR3DevHlp_VMReset: caller='%s'/%d: fFlags=%#x VM_FF_RESET %d -> 1\n",
     3388             pDevIns->pReg->szName, pDevIns->iInstance, fFlags, VM_FF_IS_SET(pVM, VM_FF_RESET)));
    33263389
    33273390    /*
     
    33393402    else
    33403403    {
     3404        pVM->pdm.s.fResetFlags = fFlags;
    33413405        VM_FF_SET(pVM, VM_FF_RESET);
    33423406        rc = VINF_EM_RESET;
     
    36153679    pdmR3DevHlp_GetCurrentCpuId,
    36163680    pdmR3DevHlp_RegisterVMMDevHeap,
    3617     pdmR3DevHlp_UnregisterVMMDevHeap,
     3681    pdmR3DevHlp_FirmwareRegister,
    36183682    pdmR3DevHlp_VMReset,
    36193683    pdmR3DevHlp_VMSuspend,
     
    36793743
    36803744
    3681 /** @interface_method_impl{PDMDEVHLPR3,pfnUnregisterVMMDevHeap} */
    3682 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_UnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
    3683 {
    3684     PDMDEV_ASSERT_DEVINS(pDevIns);
    3685     NOREF(GCPhys);
     3745/** @interface_method_impl{PDMDEVHLPR3,pfnFirmwareRegister} */
     3746static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_FirmwareRegister(PPDMDEVINS pDevIns, PCPDMFWREG pFwReg, PCPDMFWHLPR3 *ppFwHlpR3)
     3747{
     3748    PDMDEV_ASSERT_DEVINS(pDevIns);
     3749    NOREF(pFwReg); NOREF(ppFwHlpR3);
    36863750    AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
    36873751    return VERR_ACCESS_DENIED;
     
    36903754
    36913755/** @interface_method_impl{PDMDEVHLPR3,pfnVMReset} */
    3692 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns)
    3693 {
    3694     PDMDEV_ASSERT_DEVINS(pDevIns);
     3756static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_VMReset(PPDMDEVINS pDevIns, uint32_t fFlags)
     3757{
     3758    PDMDEV_ASSERT_DEVINS(pDevIns); NOREF(fFlags);
    36953759    AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
    36963760    return VERR_ACCESS_DENIED;
     
    38673931    pdmR3DevHlp_Untrusted_GetCurrentCpuId,
    38683932    pdmR3DevHlp_Untrusted_RegisterVMMDevHeap,
    3869     pdmR3DevHlp_Untrusted_UnregisterVMMDevHeap,
     3933    pdmR3DevHlp_Untrusted_FirmwareRegister,
    38703934    pdmR3DevHlp_Untrusted_VMReset,
    38713935    pdmR3DevHlp_Untrusted_VMSuspend,
  • trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp

    r60340 r60404  
    823823
    824824/**
     825 * Firmware Device Helpers.
     826 */
     827const PDMFWHLPR3 g_pdmR3DevFirmwareHlp =
     828{
     829    PDM_FWHLPR3_VERSION,
     830    PDM_FWHLPR3_VERSION
     831};
     832
     833/**
    825834 * DMAC Device Helpers.
    826835 */
     
    842851    PDM_RTCHLP_VERSION
    843852};
     853
  • trunk/src/VBox/VMM/VMMR3/VM.cpp

    r60398 r60404  
    5454#include <VBox/vmm/pgm.h>
    5555#include <VBox/vmm/pdmapi.h>
     56#include <VBox/vmm/pdmdev.h>
    5657#include <VBox/vmm/pdmcritsect.h>
    5758#include <VBox/vmm/em.h>
     
    27402741
    27412742/**
    2742  * EMT rendezvous worker for VMR3Reset.
     2743 * EMT rendezvous worker for VMR3ResetFF for doing soft/warm reset.
     2744 *
     2745 * @returns VERR_VM_INVALID_VM_STATE, VINF_EM_RESCHEDULE.
     2746 *          (This is a strict return code, see FNVMMEMTRENDEZVOUS.)
     2747 *
     2748 * @param   pVM             The cross context VM structure.
     2749 * @param   pVCpu           The cross context virtual CPU structure of the calling EMT.
     2750 * @param   pvUser          The reset flags.
     2751 */
     2752static DECLCALLBACK(VBOXSTRICTRC) vmR3SoftReset(PVM pVM, PVMCPU pVCpu, void *pvUser)
     2753{
     2754    uint32_t fResetFlags = *(uint32_t *)pvUser;
     2755
     2756
     2757    /*
     2758     * The first EMT will try change the state to resetting.  If this fails,
     2759     * we won't get called for the other EMTs.
     2760     */
     2761    if (pVCpu->idCpu == pVM->cCpus - 1)
     2762    {
     2763        int rc = vmR3TrySetState(pVM, "vmR3ResetSoft", 3,
     2764                                 VMSTATE_SOFT_RESETTING,     VMSTATE_RUNNING,
     2765                                 VMSTATE_SOFT_RESETTING,     VMSTATE_SUSPENDED,
     2766                                 VMSTATE_SOFT_RESETTING_LS,  VMSTATE_RUNNING_LS);
     2767        if (RT_FAILURE(rc))
     2768            return rc;
     2769    }
     2770
     2771    /*
     2772     * Check the state.
     2773     */
     2774    VMSTATE enmVMState = VMR3GetState(pVM);
     2775    AssertLogRelMsgReturn(   enmVMState == VMSTATE_SOFT_RESETTING
     2776                          || enmVMState == VMSTATE_SOFT_RESETTING_LS,
     2777                          ("%s\n", VMR3GetStateName(enmVMState)),
     2778                          VERR_VM_UNEXPECTED_UNSTABLE_STATE);
     2779
     2780    /*
     2781     * EMT(0) does the full cleanup *after* all the other EMTs has been
     2782     * thru here and been told to enter the EMSTATE_WAIT_SIPI state.
     2783     *
     2784     * Because there are per-cpu reset routines and order may/is important,
     2785     * the following sequence looks a bit ugly...
     2786     */
     2787
     2788    /* Reset the VCpu state. */
     2789    VMCPU_ASSERT_STATE(pVCpu, VMCPUSTATE_STARTED);
     2790
     2791    /*
     2792     * Soft reset the VM components.
     2793     */
     2794    if (pVCpu->idCpu == 0)
     2795    {
     2796#ifdef VBOX_WITH_REM
     2797        REMR3Reset(pVM);
     2798#endif
     2799        PDMR3SoftReset(pVM, fResetFlags);
     2800        TRPMR3Reset(pVM);
     2801        CPUMR3Reset(pVM);               /* This must come *after* PDM (due to APIC base MSR caching). */
     2802        EMR3Reset(pVM);
     2803        HMR3Reset(pVM);                 /* This must come *after* PATM, CSAM, CPUM, SELM and TRPM. */
     2804
     2805        /*
     2806         * Since EMT(0) is the last to go thru here, it will advance the state.
     2807         * (Unlike vmR3HardReset we won't be doing any suspending of live
     2808         * migration VMs here since memory is unchanged.)
     2809         */
     2810        PUVM pUVM = pVM->pUVM;
     2811        RTCritSectEnter(&pUVM->vm.s.AtStateCritSect);
     2812        enmVMState = pVM->enmVMState;
     2813        if (enmVMState == VMSTATE_SOFT_RESETTING)
     2814        {
     2815            if (pUVM->vm.s.enmPrevVMState == VMSTATE_SUSPENDED)
     2816                vmR3SetStateLocked(pVM, pUVM, VMSTATE_SUSPENDED, VMSTATE_SOFT_RESETTING);
     2817            else
     2818                vmR3SetStateLocked(pVM, pUVM, VMSTATE_RUNNING,   VMSTATE_SOFT_RESETTING);
     2819        }
     2820        else
     2821            vmR3SetStateLocked(pVM, pUVM, VMSTATE_RUNNING_LS, VMSTATE_SOFT_RESETTING_LS);
     2822        RTCritSectLeave(&pUVM->vm.s.AtStateCritSect);
     2823    }
     2824
     2825    return VINF_EM_RESCHEDULE;
     2826}
     2827
     2828
     2829/**
     2830 * EMT rendezvous worker for VMR3Reset and VMR3ResetFF.
    27432831 *
    27442832 * This is called by the emulation threads as a response to the reset request
     
    27522840 * @param   pvUser          Ignored.
    27532841 */
    2754 static DECLCALLBACK(VBOXSTRICTRC) vmR3Reset(PVM pVM, PVMCPU pVCpu, void *pvUser)
     2842static DECLCALLBACK(VBOXSTRICTRC) vmR3HardReset(PVM pVM, PVMCPU pVCpu, void *pvUser)
    27552843{
    27562844    Assert(!pvUser); NOREF(pvUser);
     
    27622850    if (pVCpu->idCpu == pVM->cCpus - 1)
    27632851    {
    2764         int rc = vmR3TrySetState(pVM, "VMR3Reset", 3,
     2852        int rc = vmR3TrySetState(pVM, "vmR3HardReset", 3,
    27652853                                 VMSTATE_RESETTING,     VMSTATE_RUNNING,
    27662854                                 VMSTATE_RESETTING,     VMSTATE_SUSPENDED,
     
    28712959
    28722960/**
     2961 * Internal worker for VMR3Reset, VMR3ResetFF, VMR3TripleFault.
     2962 *
     2963 * @returns VBox status code.
     2964 * @param   pVM             The cross context VM structure.
     2965 * @param   fHardReset      Whether it's a hard reset or not.
     2966 * @param   fResetFlags     The reset flags (PDMVMRESET_F_XXX).
     2967 */
     2968static VBOXSTRICTRC vmR3ResetCommon(PVM pVM, bool fHardReset, uint32_t fResetFlags)
     2969{
     2970    LogFlow(("vmR3ResetCommon: fHardReset=%RTbool fResetFlags=%#x\n", fHardReset, fResetFlags));
     2971    int rc;
     2972    if (fHardReset)
     2973    {
     2974        /*
     2975         * Hard reset.
     2976         */
     2977        /* Check whether we're supposed to power off instead of resetting. */
     2978        if (pVM->vm.s.fPowerOffInsteadOfReset)
     2979        {
     2980            PUVM pUVM = pVM->pUVM;
     2981            if (   pUVM->pVmm2UserMethods
     2982                && pUVM->pVmm2UserMethods->pfnNotifyResetTurnedIntoPowerOff)
     2983                pUVM->pVmm2UserMethods->pfnNotifyResetTurnedIntoPowerOff(pUVM->pVmm2UserMethods, pUVM);
     2984            return VMR3PowerOff(pUVM);
     2985        }
     2986
     2987        /* Gather all the EMTs to make sure there are no races before changing
     2988           the VM state. */
     2989        rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING | VMMEMTRENDEZVOUS_FLAGS_STOP_ON_ERROR,
     2990                                vmR3HardReset, NULL);
     2991    }
     2992    else
     2993    {
     2994        /*
     2995         * Soft reset. Since we only support this with a single CPU active,
     2996         * we must be on EMT #0 here.
     2997         */
     2998        VM_ASSERT_EMT0(pVM);
     2999        rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING | VMMEMTRENDEZVOUS_FLAGS_STOP_ON_ERROR,
     3000                                vmR3SoftReset, &fResetFlags);
     3001    }
     3002
     3003    LogFlow(("vmR3ResetCommon: returns %Rrc\n", rc));
     3004    return rc;
     3005}
     3006
     3007
     3008
     3009/**
    28733010 * Reset the current VM.
    28743011 *
     
    28833020    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
    28843021
    2885     if (pVM->vm.s.fPowerOffInsteadOfReset)
    2886     {
    2887         if (   pUVM->pVmm2UserMethods
    2888             && pUVM->pVmm2UserMethods->pfnNotifyResetTurnedIntoPowerOff)
    2889             pUVM->pVmm2UserMethods->pfnNotifyResetTurnedIntoPowerOff(pUVM->pVmm2UserMethods, pUVM);
    2890         return VMR3PowerOff(pUVM);
    2891     }
    2892 
    2893     /*
    2894      * Gather all the EMTs to make sure there are no races before
    2895      * changing the VM state.
    2896      */
    2897     int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING | VMMEMTRENDEZVOUS_FLAGS_STOP_ON_ERROR,
    2898                                 vmR3Reset, NULL);
    2899     LogFlow(("VMR3Reset: returns %Rrc\n", rc));
    2900     return rc;
     3022    return VBOXSTRICTRC_VAL(vmR3ResetCommon(pVM, true, 0));
     3023}
     3024
     3025
     3026/**
     3027 * Handle the reset force flag or triple fault.
     3028 *
     3029 * This handles both soft and hard resets (see PDMVMRESET_F_XXX).
     3030 *
     3031 * @returns VBox status code.
     3032 * @param   pUVM    The VM to reset.
     3033 * @thread  EMT
     3034 *
     3035 * @remarks Caller is expected to clear the reset FF.
     3036 */
     3037VMMR3_INT_DECL(VBOXSTRICTRC) VMR3ResetFF(PVM pVM)
     3038{
     3039    LogFlow(("VMR3ResetFF:\n"));
     3040
     3041    /*
     3042     * First consult the firmware on whether this is a hard or soft reset.
     3043     */
     3044    uint32_t fResetFlags;
     3045    bool fHardReset = PDMR3GetResetInfo(pVM, 0 /*fOverride*/, &fResetFlags);
     3046    return vmR3ResetCommon(pVM, fHardReset, fResetFlags);
     3047}
     3048
     3049
     3050/**
     3051 * For handling a CPU reset on triple fault.
     3052 *
     3053 * According to one mainboard manual, a CPU triple fault causes the 286 CPU to
     3054 * send a SHUTDOWN signal to the chipset.  The chipset responds by sending a
     3055 * RESET signal to the CPU.  So, it should be very similar to a soft/warm reset.
     3056 *
     3057 * @returns VBox status code.
     3058 * @param   pUVM    The VM to reset.
     3059 * @thread  EMT
     3060 */
     3061VMMR3_INT_DECL(VBOXSTRICTRC) VMR3ResetTripleFault(PVM pVM)
     3062{
     3063    LogFlow(("VMR3ResetTripleFault:\n"));
     3064
     3065    /*
     3066     * First consult the firmware on whether this is a hard or soft reset.
     3067     */
     3068    uint32_t fResetFlags;
     3069    bool fHardReset = PDMR3GetResetInfo(pVM, PDMVMRESET_F_TRIPLE_FAULT, &fResetFlags);
     3070    return vmR3ResetCommon(pVM, fHardReset, fResetFlags);
    29013071}
    29023072
     
    30783248        case VMSTATE_RESETTING:         return "RESETTING";
    30793249        case VMSTATE_RESETTING_LS:      return "RESETTING_LS";
     3250        case VMSTATE_SOFT_RESETTING:    return "SOFT_RESETTING";
     3251        case VMSTATE_SOFT_RESETTING_LS: return "SOFT_RESETTING_LS";
    30803252        case VMSTATE_SUSPENDED:         return "SUSPENDED";
    30813253        case VMSTATE_SUSPENDED_LS:      return "SUSPENDED_LS";
     
    31553327                            || enmStateNew == VMSTATE_SUSPENDING
    31563328                            || enmStateNew == VMSTATE_RESETTING
     3329                            || enmStateNew == VMSTATE_SOFT_RESETTING
    31573330                            || enmStateNew == VMSTATE_RUNNING_LS
    31583331                            || enmStateNew == VMSTATE_RUNNING_FT
     
    31683341                            || enmStateNew == VMSTATE_SUSPENDING_EXT_LS
    31693342                            || enmStateNew == VMSTATE_RESETTING_LS
     3343                            || enmStateNew == VMSTATE_SOFT_RESETTING_LS
    31703344                            || enmStateNew == VMSTATE_RUNNING
    31713345                            || enmStateNew == VMSTATE_DEBUGGING_LS
     
    31863360            break;
    31873361
     3362        case VMSTATE_SOFT_RESETTING:
     3363            AssertMsgReturn(enmStateNew == VMSTATE_RUNNING, ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
     3364            break;
     3365
    31883366        case VMSTATE_RESETTING_LS:
    31893367            AssertMsgReturn(   enmStateNew == VMSTATE_SUSPENDING_LS
     3368                            , ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
     3369            break;
     3370
     3371        case VMSTATE_SOFT_RESETTING_LS:
     3372            AssertMsgReturn(   enmStateNew == VMSTATE_RUNNING_LS
    31903373                            , ("%s -> %s\n", VMR3GetStateName(enmStateOld), VMR3GetStateName(enmStateNew)), false);
    31913374            break;
     
    32113394                            || enmStateNew == VMSTATE_SAVING
    32123395                            || enmStateNew == VMSTATE_RESETTING
     3396                            || enmStateNew == VMSTATE_SOFT_RESETTING
    32133397                            || enmStateNew == VMSTATE_RESUMING
    32143398                            || enmStateNew == VMSTATE_LOADING
  • trunk/src/VBox/VMM/VMMR3/VMEmt.cpp

    r58126 r60404  
    195195                 * Service a delayed reset request.
    196196                 */
    197                 rc = VMR3Reset(pVM->pUVM);
     197                rc = VBOXSTRICTRC_VAL(VMR3ResetFF(pVM));
    198198                VM_FF_CLEAR(pVM, VM_FF_RESET);
    199199                Log(("vmR3EmulationThread: Reset rc=%Rrc, VM state %s -> %s\n", rc, VMR3GetStateName(enmBefore), VMR3GetStateName(pVM->enmVMState)));
  • trunk/src/VBox/VMM/include/PDMInternal.h

    r60399 r60404  
    676676/** Maximum number of PCI busses for a VM. */
    677677#define PDM_PCI_BUSSES_MAX 8
     678
     679
     680#ifdef IN_RING3
     681/**
     682 * PDM registered firmware device.
     683 */
     684typedef struct PDMFW
     685{
     686    /** Pointer to the firmware device instance. */
     687    PPDMDEVINSR3                    pDevIns;
     688    /** Copy of the registration structure. */
     689    PDMFWREG                        Reg;
     690} PDMFW;
     691/** Pointer to a firmware instance. */
     692typedef PDMFW *PPDMFW;
     693#endif
     694
    678695
    679696/**
     
    10851102    /** List of registered drivers. (FIFO) */
    10861103    R3PTRTYPE(PPDMDRV)              pDrvs;
    1087 #if HC_ARCH_BITS == 32
    1088     RTR3PTR                         uPadding0; /**< Alignment padding. */
    1089 #endif
     1104    /** The registered firmware device (can be NULL). */
     1105    R3PTRTYPE(PPDMFW)               pFirmware;
    10901106    /** PCI Buses. */
    10911107    PDMPCIBUS                       aPciBuses[PDM_PCI_BUSSES_MAX];
     
    11221138    uint32_t volatile               uIrqTag;
    11231139
     1140    /** Pending reset flags (PDMVMRESET_F_XXX). */
     1141    uint32_t volatile               fResetFlags;
     1142    /** Alignment padding. */
     1143    uint32_t volatile               u32Padding;
     1144
    11241145    /** The tracing ID of the next device instance.
    11251146     *
     
    12171238extern const PDMAPICHLPR3   g_pdmR3DevApicHlp;
    12181239extern const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp;
     1240extern const PDMFWHLPR3     g_pdmR3DevFirmwareHlp;
    12191241extern const PDMPCIHLPR3    g_pdmR3DevPciHlp;
    12201242extern const PDMDMACHLP     g_pdmR3DevDmacHlp;
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