VirtualBox

Changeset 81003 in vbox


Ignore:
Timestamp:
Sep 25, 2019 10:00:39 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
133600
Message:

EFI/Firmware: Restore ability to store/access variables in DevEFI from the firmware

Location:
trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c

    r80721 r81003  
    9292
    9393AUTH_VAR_LIB_CONTEXT_OUT mAuthContextOut;
     94
     95
     96#ifdef VBOX
     97# include <Library/PrintLib.h>
     98# include <Library/TimerLib.h>
     99# include "VBoxPkg.h"
     100# include "DevEFI.h"
     101# include "iprt/asm.h"
     102
     103
     104static UINT32 VBoxReadNVRAM(UINT8 *pu8Buffer, UINT32 cbBuffer)
     105{
     106    UINT32 idxBuffer = 0;
     107    for (idxBuffer = 0; idxBuffer < cbBuffer; ++idxBuffer)
     108        pu8Buffer[idxBuffer] = ASMInU8(EFI_PORT_VARIABLE_OP);
     109    return idxBuffer;
     110}
     111
     112DECLINLINE(void) VBoxWriteNVRAMU32Param(UINT32 u32CodeParam, UINT32 u32Param)
     113{
     114    ASMOutU32(EFI_PORT_VARIABLE_OP, u32CodeParam);
     115    ASMOutU32(EFI_PORT_VARIABLE_PARAM, u32Param);
     116}
     117
     118static UINT32 VBoxWriteNVRAMByteArrayParam(const UINT8 *pbParam, UINT32 cbParam)
     119{
     120    UINT32 idxParam = 0;
     121    for (idxParam = 0; idxParam < cbParam; ++idxParam)
     122        ASMOutU8(EFI_PORT_VARIABLE_PARAM, pbParam[idxParam]);
     123    return idxParam;
     124}
     125
     126static void VBoxWriteNVRAMNameParam(const CHAR16 *pwszName)
     127{
     128    UINTN i;
     129    UINTN cwcName = StrLen(pwszName);
     130
     131    ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_NAME_UTF16);
     132    for (i = 0; i <= cwcName; i++)
     133        ASMOutU16(EFI_PORT_VARIABLE_PARAM, pwszName[i]);
     134}
     135
     136DECLINLINE(UINT32) VBoxWriteNVRAMGuidParam(const EFI_GUID *pGuid)
     137{
     138    ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_GUID);
     139    return VBoxWriteNVRAMByteArrayParam((UINT8 *)pGuid, sizeof(EFI_GUID));
     140}
     141
     142static UINT32 VBoxWriteNVRAMDoOp(UINT32 u32Operation)
     143{
     144    UINT32 u32Rc;
     145    VBoxLogFlowFuncEnter();
     146    VBoxLogFlowFuncMarkVar(u32Operation, "%x");
     147    VBoxWriteNVRAMU32Param(EFI_VM_VARIABLE_OP_START, u32Operation);
     148
     149    while ((u32Rc = ASMInU32(EFI_PORT_VARIABLE_OP)) == EFI_VARIABLE_OP_STATUS_BSY)
     150    {
     151#if 0
     152        MicroSecondDelay (400);
     153#endif
     154        /* @todo: sleep here. bird: won't ever happen, so don't bother. */
     155    }
     156    VBoxLogFlowFuncMarkVar(u32Rc, "%x");
     157    VBoxLogFlowFuncLeave();
     158    return u32Rc;
     159}
     160#endif
    94161
    95162/**
     
    28342901  )
    28352902{
     2903#ifndef VBOX
    28362904  EFI_STATUS              Status;
    28372905  VARIABLE_POINTER_TRACK  Variable;
     
    28842952  ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
    28852953  return Status;
     2954#else
     2955    EFI_STATUS rc;
     2956    UINT32 u32Rc;
     2957
     2958    VBoxLogFlowFuncEnter();
     2959
     2960    /*
     2961     * Tell DevEFI to look for the specified variable.
     2962     */
     2963    VBoxWriteNVRAMGuidParam(VendorGuid);
     2964    VBoxWriteNVRAMNameParam(VariableName);
     2965    u32Rc = VBoxWriteNVRAMDoOp(EFI_VARIABLE_OP_QUERY);
     2966    if (u32Rc == EFI_VARIABLE_OP_STATUS_OK)
     2967    {
     2968        /*
     2969         * Check if we got enought space for the value.
     2970         */
     2971        UINT32 VarLen;
     2972        ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_VALUE_LENGTH);
     2973        VarLen = ASMInU32(EFI_PORT_VARIABLE_OP);
     2974        VBoxLogFlowFuncMarkVar(*DataSize, "%d");
     2975        VBoxLogFlowFuncMarkVar(VarLen, "%d");
     2976        if (   VarLen <= *DataSize
     2977            && Data)
     2978        {
     2979            /*
     2980             * We do, then read it and, if requrest, the attribute.
     2981             */
     2982            *DataSize = VarLen;
     2983            ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_VALUE);
     2984            VBoxReadNVRAM((UINT8 *)Data, VarLen);
     2985
     2986            if (Attributes)
     2987            {
     2988                ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_ATTRIBUTE);
     2989                *Attributes = ASMInU32(EFI_PORT_VARIABLE_OP);
     2990                VBoxLogFlowFuncMarkVar(Attributes, "%x");
     2991            }
     2992
     2993            rc = EFI_SUCCESS;
     2994        }
     2995        else
     2996        {
     2997            *DataSize = VarLen;
     2998            rc = EFI_BUFFER_TOO_SMALL;
     2999        }
     3000    }
     3001    else
     3002    {
     3003        rc = EFI_NOT_FOUND;
     3004    }
     3005
     3006    VBoxLogFlowFuncLeaveRC(rc);
     3007    return rc;
     3008#endif
    28863009}
    28873010
     
    30793202  )
    30803203{
     3204#ifndef VBOX
    30813205  EFI_STATUS              Status;
    30823206  UINTN                   MaxLen;
     
    31193243  ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
    31203244  return Status;
     3245#else
     3246    uint32_t    u32Rc;
     3247    EFI_STATUS  rc;
     3248    VBoxLogFlowFuncEnter();
     3249
     3250    /*
     3251     * Validate inputs.
     3252     */
     3253    if (!VariableNameSize || !VariableName || !VendorGuid)
     3254    {
     3255        VBoxLogFlowFuncLeaveRC(EFI_INVALID_PARAMETER);
     3256        return EFI_INVALID_PARAMETER;
     3257    }
     3258
     3259    /*
     3260     * Tell DevEFI which the current variable is, then ask for the next one.
     3261     */
     3262    if (!VariableName[0])
     3263        u32Rc = VBoxWriteNVRAMDoOp(EFI_VARIABLE_OP_QUERY_REWIND);
     3264    else
     3265    {
     3266        VBoxWriteNVRAMGuidParam(VendorGuid);
     3267        VBoxWriteNVRAMNameParam(VariableName);
     3268        u32Rc = VBoxWriteNVRAMDoOp(EFI_VARIABLE_OP_QUERY);
     3269    }
     3270    if (u32Rc == EFI_VARIABLE_OP_STATUS_OK)
     3271        u32Rc = VBoxWriteNVRAMDoOp(EFI_VARIABLE_OP_QUERY_NEXT);
     3272    /** @todo We're supposed to skip stuff depending on attributes and
     3273     *        runtime/boottime, at least if EmuGetNextVariableName is something
     3274     *        to go by... */
     3275
     3276    if (u32Rc == EFI_VARIABLE_OP_STATUS_OK)
     3277    {
     3278        /*
     3279         * Output buffer check.
     3280         */
     3281        UINT32      cwcName;
     3282        ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_NAME_LENGTH_UTF16);
     3283        cwcName = ASMInU32(EFI_PORT_VARIABLE_OP);
     3284        if ((cwcName + 1) * 2 <= *VariableNameSize) /* ASSUMES byte size is specified */
     3285        {
     3286            UINT32 i;
     3287
     3288            /*
     3289             * Read back the result.
     3290             */
     3291            ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_GUID);
     3292            VBoxReadNVRAM((UINT8 *)VendorGuid, sizeof(EFI_GUID));
     3293
     3294            ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_NAME_UTF16);
     3295            for (i = 0; i < cwcName; i++)
     3296                VariableName[i] = ASMInU16(EFI_PORT_VARIABLE_OP);
     3297            VariableName[i] = '\0';
     3298
     3299            rc = EFI_SUCCESS;
     3300        }
     3301        else
     3302            rc = EFI_BUFFER_TOO_SMALL;
     3303        *VariableNameSize = (cwcName + 1) * 2;
     3304    }
     3305    else
     3306        rc = EFI_NOT_FOUND; /* whatever */
     3307
     3308    VBoxLogFlowFuncLeaveRC(rc);
     3309    return rc;
     3310#endif
    31213311}
    31223312
     
    31563346  )
    31573347{
     3348#ifndef VBOX
    31583349  VARIABLE_POINTER_TRACK              Variable;
    31593350  EFI_STATUS                          Status;
     
    34043595
    34053596  return Status;
     3597#else
     3598    UINT32 u32Rc;
     3599    VBoxLogFlowFuncEnter();
     3600    VBoxLogFlowFuncMarkVar(VendorGuid, "%g");
     3601    VBoxLogFlowFuncMarkVar(VariableName, "%s");
     3602    VBoxLogFlowFuncMarkVar(DataSize, "%d");
     3603    /* set guid */
     3604    VBoxWriteNVRAMGuidParam(VendorGuid);
     3605    /* set name */
     3606    VBoxWriteNVRAMNameParam(VariableName);
     3607    /* set attribute */
     3608    VBoxWriteNVRAMU32Param(EFI_VM_VARIABLE_OP_ATTRIBUTE, Attributes);
     3609    /* set value length */
     3610    VBoxWriteNVRAMU32Param(EFI_VM_VARIABLE_OP_VALUE_LENGTH, (UINT32)DataSize);
     3611    /* fill value bytes */
     3612    ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_VALUE);
     3613    VBoxWriteNVRAMByteArrayParam(Data, (UINT32)DataSize);
     3614    /* start fetch operation */
     3615    u32Rc = VBoxWriteNVRAMDoOp(EFI_VARIABLE_OP_ADD);
     3616    /* process errors */
     3617    VBoxLogFlowFuncLeave();
     3618    switch (u32Rc)
     3619    {
     3620        case EFI_VARIABLE_OP_STATUS_OK:
     3621            return EFI_SUCCESS;
     3622        case EFI_VARIABLE_OP_STATUS_WP:
     3623        default:
     3624            return EFI_WRITE_PROTECTED;
     3625    }
     3626#endif
    34063627}
    34073628
     
    36053826  )
    36063827{
     3828#ifndef VBOX
    36073829  EFI_STATUS             Status;
    36083830
     
    36653887  ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
    36663888  return Status;
     3889#else
     3890    *MaximumVariableStorageSize = 64 * 1024 * 1024;
     3891    *MaximumVariableSize = 1024;
     3892    *RemainingVariableStorageSize = 32 * 1024 * 1024;
     3893    return EFI_SUCCESS;
     3894#endif
    36673895}
    36683896
  • trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf

    r80721 r81003  
    4747  MdePkg/MdePkg.dec
    4848  MdeModulePkg/MdeModulePkg.dec
     49  VBoxPkg/VBoxPkg.dec
    4950
    5051[LibraryClasses]
  • trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf

    r80721 r81003  
    5656  MdePkg/MdePkg.dec
    5757  MdeModulePkg/MdeModulePkg.dec
     58  VBoxPkg/VBoxPkg.dec
    5859
    5960[LibraryClasses]
  • trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf

    r80721 r81003  
    4444  MdePkg/MdePkg.dec
    4545  MdeModulePkg/MdeModulePkg.dec
     46  VBoxPkg/VBoxPkg.dec
    4647
    4748[LibraryClasses]
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