VirtualBox

Changeset 100762 in vbox for trunk


Ignore:
Timestamp:
Aug 1, 2023 8:35:20 AM (19 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
158633
Message:

Devices/Misc/DevFlashCFI: Add saved state support, bugref:10434

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Misc/DevFlashCFI.cpp

    r99943 r100762  
    4949*   Defined Constants And Macros                                                                                                 *
    5050*********************************************************************************************************************************/
     51
     52/** Saved state version. */
     53#define FLASH_SAVED_STATE_VERSION               1
     54
    5155/** @name CFI (Command User Interface) Commands.
    5256 *  @{ */
     
    319323
    320324
    321 #if 0 /** @todo Later */
     325/**
     326 * Saves the flash content to NVRAM storage.
     327 *
     328 * @returns VBox status code.
     329 * @param   pDevIns             The device instance.
     330 */
     331static int flashR3SaveToNvram(PPDMDEVINS pDevIns)
     332{
     333    PDEVFLASHCFI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVFLASHCFI);
     334    int          rc    = VINF_SUCCESS;
     335
     336    if (!pThis->fStateSaved)
     337    {
     338        if (pThis->Lun0.pDrvVfs)
     339        {
     340            AssertPtr(pThis->pszFlashFile);
     341            rc = pThis->Lun0.pDrvVfs->pfnWriteAll(pThis->Lun0.pDrvVfs, FLASH_CFI_VFS_NAMESPACE, pThis->pszFlashFile,
     342                                                  pThis->pbFlash, pThis->cbFlashSize);
     343            if (RT_FAILURE(rc))
     344                LogRel(("FlashCFI: Failed to save flash file to NVRAM store: %Rrc\n", rc));
     345        }
     346        else if (pThis->pszFlashFile)
     347        {
     348            RTFILE hFlashFile = NIL_RTFILE;
     349
     350            rc = RTFileOpen(&hFlashFile, pThis->pszFlashFile, RTFILE_O_READWRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE);
     351            if (RT_SUCCESS(rc))
     352            {
     353                rc = RTFileWrite(hFlashFile, pThis->pbFlash, pThis->cbFlashSize, NULL);
     354                RTFileClose(hFlashFile);
     355                if (RT_FAILURE(rc))
     356                    PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to write flash file"));
     357            }
     358            else
     359                PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to open flash file"));
     360        }
     361    }
     362
     363    return rc;
     364}
     365
     366
     367/* -=-=-=-=-=-=-=-=- Saved State -=-=-=-=-=-=-=-=- */
     368
     369/**
     370 * @callback_method_impl{FNSSMDEVLIVEEXEC}
     371 */
     372static DECLCALLBACK(int) flashR3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
     373{
     374    PDEVFLASHCFI    pThis = PDMDEVINS_2_DATA(pDevIns, PDEVFLASHCFI);
     375    PCPDMDEVHLPR3   pHlp  = pDevIns->pHlpR3;
     376    RT_NOREF(uPass);
     377
     378    pHlp->pfnSSMPutGCPhys(pSSM, pThis->GCPhysFlashBase);
     379    pHlp->pfnSSMPutU32(   pSSM, pThis->cbFlashSize);
     380    pHlp->pfnSSMPutU16(   pSSM, pThis->u16FlashId);
     381    pHlp->pfnSSMPutU16(   pSSM, pThis->cbBlockSize);
     382    return VINF_SSM_DONT_CALL_AGAIN;
     383}
     384
     385
    322386/**
    323387 * @callback_method_impl{FNSSMDEVSAVEEXEC}
    324388 */
    325 static DECLCALLBACK(int) flashSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
    326 {
    327     PDEVFLASH pThis = PDMDEVINS_2_DATA(pDevIns, PDEVFLASH);
    328     return flashR3SaveExec(&pThis->Core, pDevIns, pSSM);
     389static DECLCALLBACK(int) flashR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     390{
     391    PDEVFLASHCFI    pThis = PDMDEVINS_2_DATA(pDevIns, PDEVFLASHCFI);
     392    PCPDMDEVHLPR3   pHlp  = pDevIns->pHlpR3;
     393
     394    /* The config. */
     395    flashR3LiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
     396
     397    /* The state. */
     398    pHlp->pfnSSMPutU16(pSSM, pThis->u16Cmd);
     399    pHlp->pfnSSMPutU8( pSSM, pThis->bStatus);
     400    pHlp->pfnSSMPutU8( pSSM, pThis->cBusCycle);
     401    pHlp->pfnSSMPutU8( pSSM, pThis->cWordsTransfered);
     402    pHlp->pfnSSMPutMem(pSSM, pThis->pbFlash, pThis->cbFlashSize);
     403    pHlp->pfnSSMPutU32(pSSM, pThis->offBlock);
     404    pHlp->pfnSSMPutU32(pSSM, pThis->cbWrite);
     405    pHlp->pfnSSMPutMem(pSSM, &pThis->abProgramBuf[0], sizeof(pThis->abProgramBuf));
     406
     407    pThis->fStateSaved = true;
     408    return pHlp->pfnSSMPutU32(pSSM, UINT32_MAX); /* sanity/terminator */
    329409}
    330410
     
    333413 * @callback_method_impl{FNSSMDEVLOADEXEC}
    334414 */
    335 static DECLCALLBACK(int) flashLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
    336 {
    337     PDEVFLASH pThis = PDMDEVINS_2_DATA(pDevIns, PDEVFLASH);
    338     Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
     415static DECLCALLBACK(int) flashR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     416{
     417    PDEVFLASHCFI    pThis = PDMDEVINS_2_DATA(pDevIns, PDEVFLASHCFI);
     418    PCPDMDEVHLPR3   pHlp  = pDevIns->pHlpR3;
    339419
    340420    /* Fend off unsupported versions. */
     
    342422        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    343423
    344     return flashR3LoadExec(&pThis->Core, pDevIns, pSSM);
    345 }
    346 #endif
     424    /* The config. */
     425    RTGCPHYS GCPhysFlashBase;
     426    int rc = pHlp->pfnSSMGetGCPhys(pSSM, &GCPhysFlashBase);
     427    AssertRCReturn(rc, rc);
     428    if (GCPhysFlashBase != pThis->GCPhysFlashBase)
     429        return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - GCPhysFlashBase: saved=%RGp config=%RGp"),
     430                                       GCPhysFlashBase, pThis->GCPhysFlashBase);
     431
     432    uint32_t cbFlashSize;
     433    rc = pHlp->pfnSSMGetU32(pSSM, &cbFlashSize);
     434    AssertRCReturn(rc, rc);
     435    if (cbFlashSize != pThis->cbFlashSize)
     436        return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - cbFlashSize: saved=%#x config=%#x"),
     437                                       cbFlashSize, pThis->cbFlashSize);
     438
     439    uint16_t u16FlashId;
     440    rc = pHlp->pfnSSMGetU16(pSSM, &u16FlashId);
     441    AssertRCReturn(rc, rc);
     442    if (u16FlashId != pThis->u16FlashId)
     443        return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - u16FlashId: saved=%#x config=%#x"),
     444                                       u16FlashId, pThis->u16FlashId);
     445
     446    uint16_t cbBlockSize;
     447    rc = pHlp->pfnSSMGetU16(pSSM, &cbBlockSize);
     448    AssertRCReturn(rc, rc);
     449    if (cbBlockSize != pThis->cbBlockSize)
     450        return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - cbBlockSize: saved=%#x config=%#x"),
     451                                       cbBlockSize, pThis->cbBlockSize);
     452
     453    if (uPass != SSM_PASS_FINAL)
     454        return VINF_SUCCESS;
     455
     456    /* The state. */
     457    pHlp->pfnSSMGetU16(pSSM, &pThis->u16Cmd);
     458    pHlp->pfnSSMGetU8( pSSM, &pThis->bStatus);
     459    pHlp->pfnSSMGetU8( pSSM, &pThis->cBusCycle);
     460    pHlp->pfnSSMGetU8( pSSM, &pThis->cWordsTransfered);
     461    pHlp->pfnSSMGetMem(pSSM, pThis->pbFlash, pThis->cbFlashSize);
     462    pHlp->pfnSSMGetU32(pSSM, &pThis->offBlock);
     463    pHlp->pfnSSMGetU32(pSSM, &pThis->cbWrite);
     464    pHlp->pfnSSMGetMem(pSSM, &pThis->abProgramBuf[0], sizeof(pThis->abProgramBuf));
     465
     466    /* The marker. */
     467    uint32_t u32;
     468    rc = pHlp->pfnSSMGetU32(pSSM, &u32);
     469    AssertRCReturn(rc, rc);
     470    AssertMsgReturn(u32 == UINT32_MAX, ("%#x\n", u32), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
     471
     472    return VINF_SUCCESS;
     473}
     474
    347475
    348476/**
     
    367495static DECLCALLBACK(void) flashR3PowerOff(PPDMDEVINS pDevIns)
    368496{
    369     PDEVFLASHCFI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVFLASHCFI);
    370 
    371     if (pThis->Lun0.pDrvVfs)
    372     {
    373         AssertPtr(pThis->pszFlashFile);
    374         int rc = pThis->Lun0.pDrvVfs->pfnWriteAll(pThis->Lun0.pDrvVfs, FLASH_CFI_VFS_NAMESPACE, pThis->pszFlashFile,
    375                                                   pThis->pbFlash, pThis->cbFlashSize);
    376         if (RT_FAILURE(rc))
    377             LogRel(("EFI: Failed to save flash file to NVRAM store: %Rrc\n", rc));
    378     }
    379     else if (pThis->pszFlashFile)
    380     {
    381         RTFILE hFlashFile = NIL_RTFILE;
    382 
    383         int rc = RTFileOpen(&hFlashFile, pThis->pszFlashFile, RTFILE_O_READWRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE);
    384         if (RT_SUCCESS(rc))
    385         {
    386             rc = RTFileWrite(hFlashFile, pThis->pbFlash, pThis->cbFlashSize, NULL);
    387             RTFileClose(hFlashFile);
    388             if (RT_FAILURE(rc))
    389                 PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to write flash file"));
    390         }
    391         else
    392             PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to open flash file"));
    393     }
     497    int rc = flashR3SaveToNvram(pDevIns);
     498    AssertRC(rc);
    394499}
    395500
     
    403508    PDEVFLASHCFI pThis   = PDMDEVINS_2_DATA(pDevIns, PDEVFLASHCFI);
    404509
    405     if (pThis->pszFlashFile)
    406     {
    407         RTFILE hFlashFile = NIL_RTFILE;
    408 
    409         int rc = RTFileOpen(&hFlashFile, pThis->pszFlashFile, RTFILE_O_READWRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE);
    410         if (RT_FAILURE(rc))
    411             return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to open flash file"));
    412 
    413         rc = RTFileWrite(hFlashFile, pThis->pbFlash, pThis->cbFlashSize, NULL);
    414         RTFileClose(hFlashFile);
    415         if (RT_FAILURE(rc))
    416             return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to write flash file"));
    417 
    418         PDMDevHlpMMHeapFree(pDevIns, pThis->pszFlashFile);
    419         pThis->pszFlashFile = NULL;
    420     }
     510    int rc = flashR3SaveToNvram(pDevIns);
     511    AssertRCReturn(rc, rc);
    421512
    422513    if (pThis->pbFlash)
     
    558649    LogRel(("Registered %uKB flash at %RGp\n", pThis->cbFlashSize / _1K, pThis->GCPhysFlashBase));
    559650
    560 #if 0 /** @todo Later */
    561651    /*
    562652     * Register saved state.
    563653     */
    564     rc = PDMDevHlpSSMRegister(pDevIns, FLASH_SAVED_STATE_VERSION, sizeof(*pThis), flashSaveExec, flashLoadExec);
     654    rc = PDMDevHlpSSMRegisterEx(pDevIns, FLASH_SAVED_STATE_VERSION, sizeof(*pThis), NULL,
     655                                NULL, flashR3LiveExec, NULL,
     656                                NULL, flashR3SaveExec, NULL,
     657                                NULL, flashR3LoadExec, NULL);
    565658    AssertRCReturn(rc, rc);
    566 #endif
    567659
    568660    return VINF_SUCCESS;
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