Index: /trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
===================================================================
--- /trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c	(revision 81002)
+++ /trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c	(revision 81003)
@@ -92,4 +92,71 @@
 
 AUTH_VAR_LIB_CONTEXT_OUT mAuthContextOut;
+
+
+#ifdef VBOX
+# include <Library/PrintLib.h>
+# include <Library/TimerLib.h>
+# include "VBoxPkg.h"
+# include "DevEFI.h"
+# include "iprt/asm.h"
+
+
+static UINT32 VBoxReadNVRAM(UINT8 *pu8Buffer, UINT32 cbBuffer)
+{
+    UINT32 idxBuffer = 0;
+    for (idxBuffer = 0; idxBuffer < cbBuffer; ++idxBuffer)
+        pu8Buffer[idxBuffer] = ASMInU8(EFI_PORT_VARIABLE_OP);
+    return idxBuffer;
+}
+
+DECLINLINE(void) VBoxWriteNVRAMU32Param(UINT32 u32CodeParam, UINT32 u32Param)
+{
+    ASMOutU32(EFI_PORT_VARIABLE_OP, u32CodeParam);
+    ASMOutU32(EFI_PORT_VARIABLE_PARAM, u32Param);
+}
+
+static UINT32 VBoxWriteNVRAMByteArrayParam(const UINT8 *pbParam, UINT32 cbParam)
+{
+    UINT32 idxParam = 0;
+    for (idxParam = 0; idxParam < cbParam; ++idxParam)
+        ASMOutU8(EFI_PORT_VARIABLE_PARAM, pbParam[idxParam]);
+    return idxParam;
+}
+
+static void VBoxWriteNVRAMNameParam(const CHAR16 *pwszName)
+{
+    UINTN i;
+    UINTN cwcName = StrLen(pwszName);
+
+    ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_NAME_UTF16);
+    for (i = 0; i <= cwcName; i++)
+        ASMOutU16(EFI_PORT_VARIABLE_PARAM, pwszName[i]);
+}
+
+DECLINLINE(UINT32) VBoxWriteNVRAMGuidParam(const EFI_GUID *pGuid)
+{
+    ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_GUID);
+    return VBoxWriteNVRAMByteArrayParam((UINT8 *)pGuid, sizeof(EFI_GUID));
+}
+
+static UINT32 VBoxWriteNVRAMDoOp(UINT32 u32Operation)
+{
+    UINT32 u32Rc;
+    VBoxLogFlowFuncEnter();
+    VBoxLogFlowFuncMarkVar(u32Operation, "%x");
+    VBoxWriteNVRAMU32Param(EFI_VM_VARIABLE_OP_START, u32Operation);
+
+    while ((u32Rc = ASMInU32(EFI_PORT_VARIABLE_OP)) == EFI_VARIABLE_OP_STATUS_BSY)
+    {
+#if 0
+        MicroSecondDelay (400);
+#endif
+        /* @todo: sleep here. bird: won't ever happen, so don't bother. */
+    }
+    VBoxLogFlowFuncMarkVar(u32Rc, "%x");
+    VBoxLogFlowFuncLeave();
+    return u32Rc;
+}
+#endif
 
 /**
@@ -2834,4 +2901,5 @@
   )
 {
+#ifndef VBOX
   EFI_STATUS              Status;
   VARIABLE_POINTER_TRACK  Variable;
@@ -2884,4 +2952,59 @@
   ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
   return Status;
+#else
+    EFI_STATUS rc;
+    UINT32 u32Rc;
+
+    VBoxLogFlowFuncEnter();
+
+    /*
+     * Tell DevEFI to look for the specified variable.
+     */
+    VBoxWriteNVRAMGuidParam(VendorGuid);
+    VBoxWriteNVRAMNameParam(VariableName);
+    u32Rc = VBoxWriteNVRAMDoOp(EFI_VARIABLE_OP_QUERY);
+    if (u32Rc == EFI_VARIABLE_OP_STATUS_OK)
+    {
+        /*
+         * Check if we got enought space for the value.
+         */
+        UINT32 VarLen;
+        ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_VALUE_LENGTH);
+        VarLen = ASMInU32(EFI_PORT_VARIABLE_OP);
+        VBoxLogFlowFuncMarkVar(*DataSize, "%d");
+        VBoxLogFlowFuncMarkVar(VarLen, "%d");
+        if (   VarLen <= *DataSize
+            && Data)
+        {
+            /*
+             * We do, then read it and, if requrest, the attribute.
+             */
+            *DataSize = VarLen;
+            ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_VALUE);
+            VBoxReadNVRAM((UINT8 *)Data, VarLen);
+
+            if (Attributes)
+            {
+                ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_ATTRIBUTE);
+                *Attributes = ASMInU32(EFI_PORT_VARIABLE_OP);
+                VBoxLogFlowFuncMarkVar(Attributes, "%x");
+            }
+
+            rc = EFI_SUCCESS;
+        }
+        else
+        {
+            *DataSize = VarLen;
+            rc = EFI_BUFFER_TOO_SMALL;
+        }
+    }
+    else
+    {
+        rc = EFI_NOT_FOUND;
+    }
+
+    VBoxLogFlowFuncLeaveRC(rc);
+    return rc;
+#endif
 }
 
@@ -3079,4 +3202,5 @@
   )
 {
+#ifndef VBOX
   EFI_STATUS              Status;
   UINTN                   MaxLen;
@@ -3119,4 +3243,70 @@
   ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
   return Status;
+#else
+    uint32_t    u32Rc;
+    EFI_STATUS  rc;
+    VBoxLogFlowFuncEnter();
+
+    /*
+     * Validate inputs.
+     */
+    if (!VariableNameSize || !VariableName || !VendorGuid)
+    {
+        VBoxLogFlowFuncLeaveRC(EFI_INVALID_PARAMETER);
+        return EFI_INVALID_PARAMETER;
+    }
+
+    /*
+     * Tell DevEFI which the current variable is, then ask for the next one.
+     */
+    if (!VariableName[0])
+        u32Rc = VBoxWriteNVRAMDoOp(EFI_VARIABLE_OP_QUERY_REWIND);
+    else
+    {
+        VBoxWriteNVRAMGuidParam(VendorGuid);
+        VBoxWriteNVRAMNameParam(VariableName);
+        u32Rc = VBoxWriteNVRAMDoOp(EFI_VARIABLE_OP_QUERY);
+    }
+    if (u32Rc == EFI_VARIABLE_OP_STATUS_OK)
+        u32Rc = VBoxWriteNVRAMDoOp(EFI_VARIABLE_OP_QUERY_NEXT);
+    /** @todo We're supposed to skip stuff depending on attributes and
+     *        runtime/boottime, at least if EmuGetNextVariableName is something
+     *        to go by... */
+
+    if (u32Rc == EFI_VARIABLE_OP_STATUS_OK)
+    {
+        /*
+         * Output buffer check.
+         */
+        UINT32      cwcName;
+        ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_NAME_LENGTH_UTF16);
+        cwcName = ASMInU32(EFI_PORT_VARIABLE_OP);
+        if ((cwcName + 1) * 2 <= *VariableNameSize) /* ASSUMES byte size is specified */
+        {
+            UINT32 i;
+
+            /*
+             * Read back the result.
+             */
+            ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_GUID);
+            VBoxReadNVRAM((UINT8 *)VendorGuid, sizeof(EFI_GUID));
+
+            ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_NAME_UTF16);
+            for (i = 0; i < cwcName; i++)
+                VariableName[i] = ASMInU16(EFI_PORT_VARIABLE_OP);
+            VariableName[i] = '\0';
+
+            rc = EFI_SUCCESS;
+        }
+        else
+            rc = EFI_BUFFER_TOO_SMALL;
+        *VariableNameSize = (cwcName + 1) * 2;
+    }
+    else
+        rc = EFI_NOT_FOUND; /* whatever */
+
+    VBoxLogFlowFuncLeaveRC(rc);
+    return rc;
+#endif
 }
 
@@ -3156,4 +3346,5 @@
   )
 {
+#ifndef VBOX
   VARIABLE_POINTER_TRACK              Variable;
   EFI_STATUS                          Status;
@@ -3404,4 +3595,34 @@
 
   return Status;
+#else
+    UINT32 u32Rc;
+    VBoxLogFlowFuncEnter();
+    VBoxLogFlowFuncMarkVar(VendorGuid, "%g");
+    VBoxLogFlowFuncMarkVar(VariableName, "%s");
+    VBoxLogFlowFuncMarkVar(DataSize, "%d");
+    /* set guid */
+    VBoxWriteNVRAMGuidParam(VendorGuid);
+    /* set name */
+    VBoxWriteNVRAMNameParam(VariableName);
+    /* set attribute */
+    VBoxWriteNVRAMU32Param(EFI_VM_VARIABLE_OP_ATTRIBUTE, Attributes);
+    /* set value length */
+    VBoxWriteNVRAMU32Param(EFI_VM_VARIABLE_OP_VALUE_LENGTH, (UINT32)DataSize);
+    /* fill value bytes */
+    ASMOutU32(EFI_PORT_VARIABLE_OP, EFI_VM_VARIABLE_OP_VALUE);
+    VBoxWriteNVRAMByteArrayParam(Data, (UINT32)DataSize);
+    /* start fetch operation */
+    u32Rc = VBoxWriteNVRAMDoOp(EFI_VARIABLE_OP_ADD);
+    /* process errors */
+    VBoxLogFlowFuncLeave();
+    switch (u32Rc)
+    {
+        case EFI_VARIABLE_OP_STATUS_OK:
+            return EFI_SUCCESS;
+        case EFI_VARIABLE_OP_STATUS_WP:
+        default:
+            return EFI_WRITE_PROTECTED;
+    }
+#endif
 }
 
@@ -3605,4 +3826,5 @@
   )
 {
+#ifndef VBOX
   EFI_STATUS             Status;
 
@@ -3665,4 +3887,10 @@
   ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
   return Status;
+#else
+    *MaximumVariableStorageSize = 64 * 1024 * 1024;
+    *MaximumVariableSize = 1024;
+    *RemainingVariableStorageSize = 32 * 1024 * 1024;
+    return EFI_SUCCESS;
+#endif
 }
 
Index: /trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
===================================================================
--- /trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf	(revision 81002)
+++ /trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf	(revision 81003)
@@ -47,4 +47,5 @@
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
+  VBoxPkg/VBoxPkg.dec
 
 [LibraryClasses]
Index: /trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
===================================================================
--- /trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf	(revision 81002)
+++ /trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf	(revision 81003)
@@ -56,4 +56,5 @@
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
+  VBoxPkg/VBoxPkg.dec
 
 [LibraryClasses]
Index: /trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
===================================================================
--- /trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf	(revision 81002)
+++ /trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf	(revision 81003)
@@ -44,4 +44,5 @@
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
+  VBoxPkg/VBoxPkg.dec
 
 [LibraryClasses]
