VirtualBox

Changeset 81267 in vbox


Ignore:
Timestamp:
Oct 14, 2019 5:59:01 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
133962
Message:

Devices/EFI: Integrate NVRAM flash device into the EFI "device", can be configured using the NvmamFile CFGM key. Saved state support still missing, bugref:6940

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/DevEFI.cpp

    r81264 r81267  
    5050
    5151#include "DevEFI.h"
     52#include "FlashCore.h"
    5253#include "VBoxDD.h"
    5354#include "VBoxDD2.h"
     
    202203    uint8_t                 au8DMIPage[0x1000];
    203204
    204     /** Should NVRAM range be reserved for flash? */
    205     bool                    fSkipNvramRange;
    206 
    207205    /** I/O-APIC enabled? */
    208206    uint8_t                 u8IOAPIC;
     
    238236    /** Length of PCI config space MMIO region */
    239237    uint64_t                cbMcfgLength;
    240 
     238    /** Size of the configured NVRAM device. */
     239    uint32_t                cbNvram;
     240    /** Start address of the NVRAM flash. */
     241    RTGCPHYS                GCPhysNvram;
    241242
    242243    /** NVRAM state variables. */
    243244    NVRAMDESC               NVRAM;
     245    /** The flash device containing the NVRAM. */
     246    FLASHCORE               Flash;
     247    /** Filename of the file containing the NVRAM store. */
     248    char                    *pszNvramFile;
     249    /** Flag whether the NVRAM state was saved using SSM. */
     250    bool                    fNvramStateSaved;
    244251
    245252    /**
     
    305312};
    306313
     314/** The EfiSystemNvDataFv GUID for NVRAM storage. */
     315static const RTUUID g_UuidNvDataFv = { { 0x8d, 0x2b, 0xf1, 0xff, 0x96, 0x76, 0x8b, 0x4c, 0xa9, 0x85, 0x27, 0x47, 0x07, 0x5b, 0x4f, 0x50} };
    307316
    308317
     
    16061615}
    16071616
     1617
     1618#ifdef IN_RING3 /* for now */
     1619/** @callback_method_impl{FNIOMMIWRITE, Flash memory write} */
     1620PDMBOTHCBDECL(int) efiR3NvMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
     1621{
     1622    PDEVEFI pThis = PDMINS_2_DATA(pDevIns, PDEVEFI);
     1623    RT_NOREF1(pvUser);
     1624
     1625    return flashWrite(&pThis->Flash, GCPhysAddr - pThis->GCPhysNvram, pv, cb);
     1626}
     1627
     1628
     1629/** @callback_method_impl{FNIOMMIOREAD, Flash memory read} */
     1630PDMBOTHCBDECL(int) efiR3NvMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
     1631{
     1632    PDEVEFI pThis = PDMINS_2_DATA(pDevIns, PDEVEFI);
     1633    RT_NOREF1(pvUser);
     1634
     1635    return flashRead(&pThis->Flash, GCPhysAddr - pThis->GCPhysNvram, pv, cb);
     1636}
     1637#endif /* IN_RING3 for now */
     1638
     1639
    16081640static DECLCALLBACK(int) efiSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
    16091641{
     
    18551887    pThis->szPanicMsg[0] = '\0';
    18561888
     1889    flashR3Reset(&pThis->Flash);
     1890
    18571891#ifdef DEVEFI_WITH_VBOXDBG_SCRIPT
    18581892    /*
     
    18911925
    18921926    nvramFlushDeviceVariableList(pThis);
     1927
     1928    if (   !pThis->fNvramStateSaved
     1929        && pThis->pszNvramFile)
     1930    {
     1931        int rc = flashR3SaveToFile(&pThis->Flash, pThis->pszNvramFile);
     1932        if (RT_FAILURE(rc))
     1933            LogRel(("EFI: Failed to save flash file to '%s' -> %Rrc\n", pThis->pszNvramFile, rc));
     1934    }
     1935
     1936    flashR3Destruct(&pThis->Flash);
     1937
     1938    if (pThis->pszNvramFile)
     1939    {
     1940        PDMDevHlpMMHeapFree(pDevIns, pThis->pszNvramFile);
     1941        pThis->pszNvramFile = NULL;
     1942    }
    18931943
    18941944    if (pThis->pu8EfiRom)
     
    19872037    LogRel(("Found EFI FW Volume, %u bytes (%u %u-byte blocks)\n", pFwVolHdr->FvLength, pFwVolHdr->BlockMap[0].NumBlocks, pFwVolHdr->BlockMap[0].Length));
    19882038
    1989     /* Adjust the FW variables to skip the NVRAM volume. */
    1990     if (pThis->fSkipNvramRange)
    1991     {
    1992         pThis->cbEfiRom  -= pFwVolHdr->FvLength;
    1993         pThis->uEfiRomOfs = pFwVolHdr->FvLength;
    1994     }
    1995 
    1996     pThis->GCLoadAddress = UINT32_C(0xfffff000) - pThis->cbEfiRom + PAGE_SIZE;
     2039    /** @todo Make this more dynamic, this assumes that the NV storage area comes first (always the case for our builds). */
     2040    AssertLogRelMsgReturn(!memcmp(&pFwVolHdr->FileSystemGuid, &g_UuidNvDataFv, sizeof(g_UuidNvDataFv)),
     2041                          ("Expected EFI_SYSTEM_NV_DATA_FV_GUID as an identifier"),
     2042                          VERR_INVALID_MAGIC);
     2043
     2044    /* Found NVRAM storage, configure flash device. */
     2045    pThis->uEfiRomOfs  = pFwVolHdr->FvLength;
     2046    pThis->cbNvram     = pFwVolHdr->FvLength;
     2047    pThis->GCPhysNvram = UINT32_C(0xfffff000) - pThis->cbEfiRom + PAGE_SIZE;
     2048    pThis->cbEfiRom   -= pThis->cbNvram;
     2049
     2050    int rc = flashR3Init(&pThis->Flash, pThis->pDevIns, 0xA289 /*Intel*/, pThis->cbNvram, pFwVolHdr->BlockMap[0].Length);
     2051    if (RT_FAILURE(rc))
     2052        return rc;
     2053
     2054    /* If the file does not exist we initialize the NVRAM from the loaded ROM file. */
     2055    if (!pThis->pszNvramFile || !RTPathExists(pThis->pszNvramFile))
     2056        rc = flashR3LoadFromBuf(&pThis->Flash, pThis->pu8EfiRom, pThis->cbNvram);
     2057    else
     2058        rc = flashR3LoadFromFile(&pThis->Flash, pThis->pszNvramFile);
     2059    if (RT_FAILURE(rc))
     2060        return rc;
     2061
     2062    pThis->GCLoadAddress = pThis->GCPhysNvram + pThis->cbNvram;
    19972063
    19982064    return VINF_SUCCESS;
     
    20792145    if (RT_FAILURE(rc))
    20802146        return rc;
     2147
     2148    /*
     2149     * Register MMIO region for flash device.
     2150     */
     2151    rc = PDMDevHlpMMIORegister(pThis->pDevIns, pThis->GCPhysNvram, pThis->cbNvram, NULL /*pvUser*/,
     2152                               IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
     2153                               efiR3NvMmioWrite, efiR3NvMmioRead,
     2154                               "Flash Memory");
     2155    AssertRCReturn(rc, rc);
     2156    LogRel(("EFI: Registered %uKB flash at %RGp\n", pThis->cbNvram / _1K, pThis->GCPhysNvram));
     2157
    20812158    return VINF_SUCCESS;
    20822159}
     
    22072284                              "BootArgs\0"
    22082285                              "DeviceProps\0"
    2209                               "SkipNvramRange\0"            // legacy
    22102286                              "GopMode\0"                   // legacy
    22112287                              "GraphicsMode\0"
    22122288                              "UgaHorizontalResolution\0"   // legacy
    22132289                              "UgaVerticalResolution\0"     // legacy
    2214                               "GraphicsResolution\0"))
     2290                              "GraphicsResolution\0"
     2291                              "NvramFile\0"))
    22152292        return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
    22162293                                N_("Configuration error: Invalid config value(s) for the EFI device"));
     
    22812358    }
    22822359
    2283     rc = CFGMR3QueryBoolDef(pCfg, "SkipNvramRange", &pThis->fSkipNvramRange, false);
    2284     if (RT_FAILURE(rc))
    2285         return PDMDEV_SET_ERROR(pDevIns, rc,
    2286                                 N_("Configuration error: Querying \"SkipNvramRange\" as integer failed"));
    2287 
    22882360
    22892361    /*
     
    24022474        pThis->u32VerticalResolution = 768;
    24032475    }
     2476
     2477    pThis->pszNvramFile = NULL;
     2478    rc = CFGMR3QueryStringAlloc(pCfg, "NvramFile", &pThis->pszNvramFile);
     2479    if (RT_FAILURE(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND)
     2480        return PDMDEV_SET_ERROR(pDevIns, rc,
     2481                                N_("Configuration error: Querying \"NvramFile\" as a string failed"));
    24042482
    24052483    /*
Note: See TracChangeset for help on using the changeset viewer.

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