VirtualBox

Changeset 100039 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Jun 1, 2023 6:19:52 PM (18 months ago)
Author:
vboxsync
Message:

Devices/DevEFI-armv8.cpp: Implement ability to inject the FDT for the VM into the guest RAM, bugref:10400

File:
1 edited

Legend:

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

    r99927 r100039  
    9090    /** EFI firmware physical load address. */
    9191    RTGCPHYS                GCPhysLoadAddress;
     92    /** The FDT load address, RTGCPHYS_MAX if not configured to be loaded. */
     93    RTGCPHYS                GCPhysFdtAddress;
     94    /** The FDT id used to load from the resource store driver below. */
     95    char                   *pszFdtId;
     96
     97    /**
     98     * Resource port - LUN\#0.
     99     */
     100    struct
     101    {
     102        /** The base interface we provide the resource driver. */
     103        PDMIBASE            IBase;
     104        /** The resource driver base interface. */
     105        PPDMIBASE           pDrvBase;
     106        /** The VFS interface of the driver below for resource state loading and storing. */
     107        PPDMIVFSCONNECTOR   pDrvVfs;
     108    } Lun0;
    92109} DEVEFIR3;
    93110/** Pointer to the ring-3 EFI state. */
     
    159176
    160177/**
     178 * @copydoc(PDMIBASE::pfnQueryInterface)
     179 */
     180static DECLCALLBACK(void *) devR3EfiQueryInterface(PPDMIBASE pInterface, const char *pszIID)
     181{
     182    LogFlowFunc(("ENTER: pIBase=%p pszIID=%p\n", pInterface, pszIID));
     183    PDEVEFIR3 pThisCC = RT_FROM_MEMBER(pInterface, DEVEFIR3, Lun0.IBase);
     184
     185    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThisCC->Lun0.IBase);
     186    return NULL;
     187}
     188
     189
     190/**
     191 * @interface_method_impl{PDMDEVREG,pfnReset}
     192 */
     193static DECLCALLBACK(void) efiR3Reset(PPDMDEVINS pDevIns)
     194{
     195    PDEVEFIR3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVEFIR3);
     196    LogFlow(("efiR3Reset\n"));
     197
     198    if (pThisCC->GCPhysFdtAddress != RTGCPHYS_MAX)
     199    {
     200        AssertPtr(pThisCC->Lun0.pDrvVfs);
     201
     202        uint64_t cbFdt = 0;
     203        int rc = pThisCC->Lun0.pDrvVfs->pfnQuerySize(pThisCC->Lun0.pDrvVfs, pThisCC->pszFdtId, pThisCC->pszFdtId, &cbFdt);
     204        if (RT_SUCCESS(rc))
     205        {
     206            /** @todo Need to add a proper read callback to avoid allocating temporary memory. */
     207            void *pvFdt = RTMemAllocZ(cbFdt);
     208            if (pvFdt)
     209            {
     210                rc = pThisCC->Lun0.pDrvVfs->pfnReadAll(pThisCC->Lun0.pDrvVfs, pThisCC->pszFdtId, pThisCC->pszFdtId, pvFdt, cbFdt);
     211                if (RT_SUCCESS(rc))
     212                    rc = PDMDevHlpPhysWrite(pDevIns, pThisCC->GCPhysFdtAddress, pvFdt, cbFdt);
     213
     214                RTMemFree(pvFdt);
     215            }
     216            else
     217                rc = VERR_NO_MEMORY;
     218        }
     219        AssertLogRelRC(rc);
     220    }
     221}
     222
     223
     224/**
    161225 * Destruct a device instance.
    162226 *
     
    184248        PDMDevHlpMMHeapFree(pDevIns, pThisCC->pszEfiRomFile);
    185249        pThisCC->pszEfiRomFile = NULL;
     250    }
     251
     252    if (pThisCC->pszFdtId)
     253    {
     254        PDMDevHlpMMHeapFree(pDevIns, pThisCC->pszFdtId);
     255        pThisCC->pszFdtId = NULL;
    186256    }
    187257
     
    263333     * Initalize the basic variables so that the destructor always works.
    264334     */
    265     pThisCC->pDevIns = pDevIns;
     335    pThisCC->pDevIns                        = pDevIns;
     336    pThisCC->pszFdtId                       = NULL;
     337    pThisCC->GCPhysFdtAddress               = RTGCPHYS_MAX;
     338    pThisCC->Lun0.IBase.pfnQueryInterface   = devR3EfiQueryInterface;
    266339
    267340    /*
    268341     * Validate and read the configuration.
    269342     */
    270     PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "EfiRom|GCPhysLoadAddress", "");
     343    PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "EfiRom|GCPhysLoadAddress|GCPhysFdtAddress|FdtId", "");
    271344
    272345    rc = pHlp->pfnCFGMQueryU64(pCfg, "GCPhysLoadAddress", &pThisCC->GCPhysLoadAddress);
     
    274347        return PDMDEV_SET_ERROR(pDevIns, rc,
    275348                                N_("Configuration error: Querying \"GCPhysLoadAddress\" as integer failed"));
     349
     350    rc = pHlp->pfnCFGMQueryU64Def(pCfg, "GCPhysFdtAddress", &pThisCC->GCPhysFdtAddress, RTGCPHYS_MAX);
     351    if (RT_FAILURE(rc))
     352        return PDMDEV_SET_ERROR(pDevIns, rc,
     353                                N_("Configuration error: Querying \"GCPhysFdtAddress\" as integer failed"));
     354
     355    if (pThisCC->GCPhysFdtAddress != RTGCPHYS_MAX)
     356    {
     357        rc = pHlp->pfnCFGMQueryStringAlloc(pCfg, "FdtId", &pThisCC->pszFdtId);
     358        if (RT_FAILURE(rc))
     359            return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
     360                                       N_("Configuration error: Querying \"FdtId\" as a string failed"));
     361    }
    276362
    277363    /*
     
    304390        return rc;
    305391
     392    /*
     393     * Resource storage.
     394     */
     395    rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThisCC->Lun0.IBase, &pThisCC->Lun0.pDrvBase, "ResourceStorage");
     396    if (RT_SUCCESS(rc))
     397    {
     398        pThisCC->Lun0.pDrvVfs = PDMIBASE_QUERY_INTERFACE(pThisCC->Lun0.pDrvBase, PDMIVFSCONNECTOR);
     399        if (!pThisCC->Lun0.pDrvVfs)
     400            return PDMDevHlpVMSetError(pDevIns, VERR_PDM_MISSING_INTERFACE_BELOW, RT_SRC_POS, N_("Resource storage driver is missing VFS interface below"));
     401    }
     402    else if (   rc == VERR_PDM_NO_ATTACHED_DRIVER
     403             && pThisCC->GCPhysFdtAddress == RTGCPHYS_MAX)
     404        rc = VINF_SUCCESS; /* Missing driver is no error condition if no FDT is going to be loaded. */
     405    else
     406        return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_("Can't attach resource Storage driver"));
     407
     408    efiR3Reset(pDevIns);
    306409    return VINF_SUCCESS;
    307410}
     
    350453    /* .pfnMemSetup = */            NULL,
    351454    /* .pfnPowerOn = */             NULL,
    352     /* .pfnReset = */               NULL,
     455    /* .pfnReset = */               efiR3Reset,
    353456    /* .pfnSuspend = */             NULL,
    354457    /* .pfnResume = */              NULL,
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