]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add in EmuVariableRuntimeDxe
authorqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 6 Jul 2007 10:39:15 +0000 (10:39 +0000)
committerqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 6 Jul 2007 10:39:15 +0000 (10:39 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3123 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.c [new file with mode: 0644]
MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.infa [new file with mode: 0644]
MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.msa [new file with mode: 0644]
MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariableIpf.inf [new file with mode: 0644]
MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariableIpf.msa [new file with mode: 0644]
MdeModulePkg/Universal/EmuVariableRuntimeDxe/InitVariable.c [new file with mode: 0644]
MdeModulePkg/Universal/EmuVariableRuntimeDxe/Ipf/InitVariable.c [new file with mode: 0644]
MdeModulePkg/Universal/EmuVariableRuntimeDxe/Variable.h [new file with mode: 0644]

diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.c b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.c
new file mode 100644 (file)
index 0000000..f56cf04
--- /dev/null
@@ -0,0 +1,849 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+    EmuVariable.c\r
+\r
+Abstract:\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "Variable.h"\r
+\r
+//\r
+// Don't use module globals after the SetVirtualAddress map is signaled\r
+//\r
+ESAL_VARIABLE_GLOBAL  *mVariableModuleGlobal;\r
+\r
+//\r
+// This is a temperary function which will be removed\r
+// when EfiAcquireLock in UefiLib can handle the\r
+// the call in UEFI Runtimer driver in RT phase.\r
+//\r
+STATIC\r
+VOID\r
+AcquireLockOnlyAtBootTime (\r
+  IN EFI_LOCK  *Lock\r
+  )\r
+{\r
+  if (!EfiAtRuntime ()) {\r
+    EfiAcquireLock (Lock);\r
+  }\r
+}\r
+\r
+//\r
+// This is a temperary function which will be removed\r
+// when EfiAcquireLock in UefiLib can handle the\r
+// the call in UEFI Runtimer driver in RT phase.\r
+//\r
+STATIC\r
+VOID\r
+ReleaseLockOnlyAtBootTime (\r
+  IN EFI_LOCK  *Lock\r
+  )\r
+{\r
+  if (!EfiAtRuntime ()) {\r
+    EfiReleaseLock (Lock);\r
+  }\r
+}\r
+\r
+STATIC\r
+UINT8 *\r
+EFIAPI\r
+GetVariableDataPtr (\r
+  IN  VARIABLE_HEADER   *Variable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This code gets the pointer to the variable data.\r
+\r
+Arguments:\r
+\r
+  Variable            Pointer to the Variable Header.\r
+\r
+Returns:\r
+\r
+  UINT8*              Pointer to Variable Data\r
+\r
+--*/\r
+{\r
+  if (Variable->StartId != VARIABLE_DATA) {\r
+    return NULL;\r
+  }\r
+  //\r
+  // Be careful about pad size for alignment\r
+  //\r
+  return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize));\r
+}\r
+\r
+STATIC\r
+VARIABLE_HEADER *\r
+EFIAPI\r
+GetNextVariablePtr (\r
+  IN  VARIABLE_HEADER   *Variable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This code gets the pointer to the next variable header.\r
+\r
+Arguments:\r
+\r
+  Variable                  Pointer to the Variable Header.\r
+\r
+Returns:\r
+\r
+  VARIABLE_HEADER*      Pointer to next variable header.\r
+\r
+--*/\r
+{\r
+  VARIABLE_HEADER *VarHeader;\r
+\r
+  if (Variable->StartId != VARIABLE_DATA) {\r
+    return NULL;\r
+  }\r
+  //\r
+  // Be careful about pad size for alignment\r
+  //\r
+  VarHeader = (VARIABLE_HEADER *) (GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));\r
+\r
+  if (VarHeader->StartId != VARIABLE_DATA ||\r
+      (sizeof (VARIABLE_HEADER) + VarHeader->DataSize + VarHeader->NameSize) > MAX_VARIABLE_SIZE\r
+      ) {\r
+    return NULL;\r
+  }\r
+\r
+  return VarHeader;\r
+}\r
+\r
+STATIC\r
+VARIABLE_HEADER *\r
+EFIAPI\r
+GetEndPointer (\r
+  IN VARIABLE_STORE_HEADER       *VolHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This code gets the pointer to the last variable memory pointer byte\r
+\r
+Arguments:\r
+\r
+  Variable                  Pointer to the Variable Header.\r
+\r
+Returns:\r
+\r
+  VARIABLE_HEADER*      Pointer to last unavailable Variable Header\r
+\r
+--*/\r
+{\r
+  //\r
+  // The end of variable store\r
+  //\r
+  return (VARIABLE_HEADER *) ((UINTN) VolHeader + VolHeader->Size);\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+FindVariable (\r
+  IN  CHAR16                  *VariableName,\r
+  IN  EFI_GUID                *VendorGuid,\r
+  OUT VARIABLE_POINTER_TRACK  *PtrTrack,\r
+  IN  VARIABLE_GLOBAL         *Global\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This code finds variable in storage blocks (Volatile or Non-Volatile)\r
+\r
+Arguments:\r
+\r
+  VariableName                Name of the variable to be found\r
+  VendorGuid                  Vendor GUID to be found.\r
+  PtrTrack                    Variable Track Pointer structure that contains\r
+                              Variable Information.\r
+                              Contains the pointer of Variable header.\r
+  Global                      VARIABLE_GLOBAL pointer\r
+\r
+Returns:\r
+\r
+  EFI STATUS\r
+\r
+--*/\r
+{\r
+  VARIABLE_HEADER       *Variable[2];\r
+  VARIABLE_STORE_HEADER *VariableStoreHeader[2];\r
+  UINTN                 Index;\r
+\r
+  //\r
+  // We aquire the lock at the entry of FindVariable as GetVariable, GetNextVariableName\r
+  // SetVariable all call FindVariable at entry point. Please move "Aquire Lock" to\r
+  // the correct places if this assumption does not hold TRUE anymore.\r
+  //\r
+  AcquireLockOnlyAtBootTime(&Global->VariableServicesLock);\r
+\r
+  //\r
+  // 0: Non-Volatile, 1: Volatile\r
+  //\r
+  VariableStoreHeader[0]  = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase);\r
+  VariableStoreHeader[1]  = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);\r
+\r
+  //\r
+  // Start Pointers for the variable.\r
+  // Actual Data Pointer where data can be written.\r
+  //\r
+  Variable[0] = (VARIABLE_HEADER *) (VariableStoreHeader[0] + 1);\r
+  Variable[1] = (VARIABLE_HEADER *) (VariableStoreHeader[1] + 1);\r
+\r
+  if (VariableName[0] != 0 && VendorGuid == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Find the variable by walk through non-volatile and volatile variable store\r
+  //\r
+  for (Index = 0; Index < 2; Index++) {\r
+    PtrTrack->StartPtr  = (VARIABLE_HEADER *) (VariableStoreHeader[Index] + 1);\r
+    PtrTrack->EndPtr    = GetEndPointer (VariableStoreHeader[Index]);\r
+\r
+    while ((Variable[Index] != NULL) && (Variable[Index] <= GetEndPointer (VariableStoreHeader[Index]))) {\r
+      if (Variable[Index]->StartId == VARIABLE_DATA && Variable[Index]->State == VAR_ADDED) {\r
+        if (!(EfiAtRuntime () && !(Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {\r
+          if (VariableName[0] == 0) {\r
+            PtrTrack->CurrPtr   = Variable[Index];\r
+            PtrTrack->Volatile  = (BOOLEAN) Index;\r
+            return EFI_SUCCESS;\r
+          } else {\r
+            if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) {\r
+              if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable[Index]), Variable[Index]->NameSize)) {\r
+                PtrTrack->CurrPtr   = Variable[Index];\r
+                PtrTrack->Volatile  = (BOOLEAN) Index;\r
+                return EFI_SUCCESS;\r
+              }\r
+            }\r
+          }\r
+        }\r
+      }\r
+\r
+      Variable[Index] = GetNextVariablePtr (Variable[Index]);\r
+    }\r
+  }\r
+  PtrTrack->CurrPtr = NULL;\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetVariable (\r
+  IN      CHAR16            *VariableName,\r
+  IN      EFI_GUID          * VendorGuid,\r
+  OUT     UINT32            *Attributes OPTIONAL,\r
+  IN OUT  UINTN             *DataSize,\r
+  OUT     VOID              *Data,\r
+  IN      VARIABLE_GLOBAL   * Global,\r
+  IN      UINT32            Instance\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This code finds variable in storage blocks (Volatile or Non-Volatile)\r
+\r
+Arguments:\r
+\r
+  VariableName                    Name of Variable to be found\r
+  VendorGuid                      Variable vendor GUID\r
+  Attributes OPTIONAL             Attribute value of the variable found\r
+  DataSize                        Size of Data found. If size is less than the\r
+                                  data, this value contains the required size.\r
+  Data                            Data pointer\r
+  Global                          Pointer to VARIABLE_GLOBAL structure\r
+  Instance                        Instance of the Firmware Volume.\r
+\r
+Returns:\r
+\r
+  EFI STATUS\r
+\r
+--*/\r
+{\r
+  VARIABLE_POINTER_TRACK  Variable;\r
+  UINTN                   VarDataSize;\r
+  EFI_STATUS              Status;\r
+\r
+  if (VariableName == NULL || VendorGuid == NULL || DataSize == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Find existing variable\r
+  //\r
+  Status = FindVariable (VariableName, VendorGuid, &Variable, Global);\r
+\r
+  if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+  //\r
+  // Get data size\r
+  //\r
+  VarDataSize = Variable.CurrPtr->DataSize;\r
+  if (*DataSize >= VarDataSize) {\r
+    if (Data == NULL) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);\r
+    if (Attributes != NULL) {\r
+      *Attributes = Variable.CurrPtr->Attributes;\r
+    }\r
+\r
+    *DataSize = VarDataSize;\r
+    Status = EFI_SUCCESS;\r
+    goto Done;\r
+  } else {\r
+    *DataSize = VarDataSize;\r
+    Status = EFI_BUFFER_TOO_SMALL;\r
+    goto Done;\r
+  }\r
+\r
+Done:\r
+  ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock);\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetNextVariableName (\r
+  IN OUT  UINTN             *VariableNameSize,\r
+  IN OUT  CHAR16            *VariableName,\r
+  IN OUT  EFI_GUID          *VendorGuid,\r
+  IN      VARIABLE_GLOBAL   *Global,\r
+  IN      UINT32            Instance\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This code Finds the Next available variable\r
+\r
+Arguments:\r
+\r
+  VariableNameSize            Size of the variable\r
+  VariableName                Pointer to variable name\r
+  VendorGuid                  Variable Vendor Guid\r
+  Global                      VARIABLE_GLOBAL structure pointer.\r
+  Instance                    FV instance\r
+\r
+Returns:\r
+\r
+  EFI STATUS\r
+\r
+--*/\r
+{\r
+  VARIABLE_POINTER_TRACK  Variable;\r
+  UINTN                   VarNameSize;\r
+  EFI_STATUS              Status;\r
+\r
+  if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = FindVariable (VariableName, VendorGuid, &Variable, Global);\r
+\r
+  if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  while (TRUE) {\r
+    if (VariableName[0] != 0) {\r
+      //\r
+      // If variable name is not NULL, get next variable\r
+      //\r
+      Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);\r
+    }\r
+    //\r
+    // If both volatile and non-volatile variable store are parsed,\r
+    // return not found\r
+    //\r
+    if (Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL) {\r
+      Variable.Volatile = (BOOLEAN) (Variable.Volatile ^ ((BOOLEAN) 0x1));\r
+      if (Variable.Volatile) {\r
+        Variable.StartPtr = (VARIABLE_HEADER *) ((UINTN) (Global->VolatileVariableBase + sizeof (VARIABLE_STORE_HEADER)));\r
+        Variable.EndPtr = (VARIABLE_HEADER *) GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase));\r
+      } else {\r
+        Status = EFI_NOT_FOUND;\r
+        goto Done;\r
+      }\r
+\r
+      Variable.CurrPtr = Variable.StartPtr;\r
+      if (Variable.CurrPtr->StartId != VARIABLE_DATA) {\r
+        continue;\r
+      }\r
+    }\r
+    //\r
+    // Variable is found\r
+    //\r
+    if (Variable.CurrPtr->StartId == VARIABLE_DATA && Variable.CurrPtr->State == VAR_ADDED) {\r
+      if (!(EfiAtRuntime () && !(Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {\r
+        VarNameSize = Variable.CurrPtr->NameSize;\r
+        if (VarNameSize <= *VariableNameSize) {\r
+          CopyMem (\r
+            VariableName,\r
+            GET_VARIABLE_NAME_PTR (Variable.CurrPtr),\r
+            VarNameSize\r
+            );\r
+          CopyMem (\r
+            VendorGuid,\r
+            &Variable.CurrPtr->VendorGuid,\r
+            sizeof (EFI_GUID)\r
+            );\r
+          Status = EFI_SUCCESS;\r
+        } else {\r
+          Status = EFI_BUFFER_TOO_SMALL;\r
+        }\r
+\r
+        *VariableNameSize = VarNameSize;\r
+        goto Done;\r
+      }\r
+    }\r
+  }\r
+\r
+Done:\r
+  ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock);\r
+  return Status;\r
+\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+SetVariable (\r
+  IN CHAR16                  *VariableName,\r
+  IN EFI_GUID                *VendorGuid,\r
+  IN UINT32                  Attributes,\r
+  IN UINTN                   DataSize,\r
+  IN VOID                    *Data,\r
+  IN VARIABLE_GLOBAL         *Global,\r
+  IN UINTN                   *VolatileOffset,\r
+  IN UINTN                   *NonVolatileOffset,\r
+  IN UINT32                  Instance\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This code sets variable in storage blocks (Volatile or Non-Volatile)\r
+\r
+Arguments:\r
+\r
+  VariableName                    Name of Variable to be found\r
+  VendorGuid                      Variable vendor GUID\r
+  Attributes                      Attribute value of the variable found\r
+  DataSize                        Size of Data found. If size is less than the\r
+                                  data, this value contains the required size.\r
+  Data                            Data pointer\r
+  Global                          Pointer to VARIABLE_GLOBAL structure\r
+  VolatileOffset                  The offset of last volatile variable\r
+  NonVolatileOffset               The offset of last non-volatile variable\r
+  Instance                        Instance of the Firmware Volume.\r
+\r
+Returns:\r
+\r
+  EFI STATUS\r
+\r
+--*/\r
+{\r
+  VARIABLE_POINTER_TRACK  Variable;\r
+  EFI_STATUS              Status;\r
+  VARIABLE_HEADER         *NextVariable;\r
+  UINTN                   VarNameSize;\r
+  UINTN                   VarNameOffset;\r
+  UINTN                   VarDataOffset;\r
+  UINTN                   VarSize;\r
+\r
+  if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = FindVariable (VariableName, VendorGuid, &Variable, Global);\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    goto Done;\r
+  } else if (!EFI_ERROR (Status) && Variable.Volatile && EfiAtRuntime()) {\r
+    //\r
+    // If EfiAtRuntime and the variable is Volatile and Runtime Access,\r
+    // the volatile is ReadOnly, and SetVariable should be aborted and\r
+    // return EFI_WRITE_PROTECTED.\r
+    //\r
+    Status = EFI_WRITE_PROTECTED;\r
+    goto Done;\r
+  } else if (sizeof (VARIABLE_HEADER) + (StrSize (VariableName) + DataSize) > MAX_VARIABLE_SIZE) {\r
+    //\r
+    //  The size of the VariableName, including the Unicode Null in bytes plus\r
+    //  the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes.\r
+    //\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Done;\r
+  } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS\r
+          ) {\r
+    //\r
+    //  Make sure if runtime bit is set, boot service bit is set also\r
+    //\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Done;\r
+  } else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {\r
+    //\r
+    // Runtime but Attribute is not Runtime\r
+    //\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Done;\r
+  } else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) {\r
+    //\r
+    // Cannot set volatile variable in Runtime\r
+    //\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Done;\r
+  } else if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) {\r
+    //\r
+    // Setting a data variable with no access, or zero DataSize attributes\r
+    // specified causes it to be deleted.\r
+    //\r
+    if (!EFI_ERROR (Status)) {\r
+      Variable.CurrPtr->State &= VAR_DELETED;\r
+      Status = EFI_SUCCESS;\r
+      goto Done;\r
+    }\r
+\r
+    Status = EFI_NOT_FOUND;\r
+    goto Done;\r
+  } else {\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // If the variable is marked valid and the same data has been passed in\r
+      // then return to the caller immediately.\r
+      //\r
+      if (Variable.CurrPtr->DataSize == DataSize &&\r
+          !CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize)\r
+            ) {\r
+        Status = EFI_SUCCESS;\r
+        goto Done;\r
+      } else if (Variable.CurrPtr->State == VAR_ADDED) {\r
+        //\r
+        // Mark the old variable as in delete transition\r
+        //\r
+        Variable.CurrPtr->State &= VAR_IN_DELETED_TRANSITION;\r
+      }\r
+    }\r
+    //\r
+    // Create a new variable and copy the data.\r
+    //\r
+    VarNameOffset = sizeof (VARIABLE_HEADER);\r
+    VarNameSize   = StrSize (VariableName);\r
+    VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize);\r
+    VarSize       = VarDataOffset + DataSize + GET_PAD_SIZE (DataSize);\r
+\r
+    if (Attributes & EFI_VARIABLE_NON_VOLATILE) {\r
+      if ((UINT32) (VarSize +*NonVolatileOffset) >\r
+            ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size\r
+            ) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+\r
+      NextVariable        = (VARIABLE_HEADER *) (UINT8 *) (*NonVolatileOffset + (UINTN) Global->NonVolatileVariableBase);\r
+      *NonVolatileOffset  = *NonVolatileOffset + VarSize;\r
+    } else {\r
+      if (EfiAtRuntime ()) {\r
+        Status = EFI_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+\r
+      if ((UINT32) (VarSize +*VolatileOffset) >\r
+            ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size\r
+            ) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+\r
+      NextVariable    = (VARIABLE_HEADER *) (UINT8 *) (*VolatileOffset + (UINTN) Global->VolatileVariableBase);\r
+      *VolatileOffset = *VolatileOffset + VarSize;\r
+    }\r
+\r
+    NextVariable->StartId     = VARIABLE_DATA;\r
+    NextVariable->Attributes  = Attributes;\r
+    NextVariable->State       = VAR_ADDED;\r
+    NextVariable->Reserved    = 0;\r
+\r
+    //\r
+    // There will be pad bytes after Data, the NextVariable->NameSize and\r
+    // NextVariable->NameSize should not include pad size so that variable\r
+    // service can get actual size in GetVariable\r
+    //\r
+    NextVariable->NameSize  = (UINT32)VarNameSize;\r
+    NextVariable->DataSize  = (UINT32)DataSize;\r
+\r
+    CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID));\r
+    CopyMem (\r
+      (UINT8 *) ((UINTN) NextVariable + VarNameOffset),\r
+      VariableName,\r
+      VarNameSize\r
+      );\r
+    CopyMem (\r
+      (UINT8 *) ((UINTN) NextVariable + VarDataOffset),\r
+      Data,\r
+      DataSize\r
+      );\r
+\r
+    //\r
+    // Mark the old variable as deleted\r
+    //\r
+    if (!EFI_ERROR (Status)) {\r
+      Variable.CurrPtr->State &= VAR_DELETED;\r
+    }\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
+Done:\r
+  ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock);\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+QueryVariableInfo (\r
+  IN  UINT32                 Attributes,\r
+  OUT UINT64                 *MaximumVariableStorageSize,\r
+  OUT UINT64                 *RemainingVariableStorageSize,\r
+  OUT UINT64                 *MaximumVariableSize,\r
+  IN  VARIABLE_GLOBAL        *Global,\r
+  IN  UINT32                 Instance\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This code returns information about the EFI variables.\r
+\r
+Arguments:\r
+\r
+  Attributes                      Attributes bitmask to specify the type of variables\r
+                                  on which to return information.\r
+  MaximumVariableStorageSize      Pointer to the maximum size of the storage space available\r
+                                  for the EFI variables associated with the attributes specified.\r
+  RemainingVariableStorageSize    Pointer to the remaining size of the storage space available\r
+                                  for the EFI variables associated with the attributes specified.\r
+  MaximumVariableSize             Pointer to the maximum size of the individual EFI variables\r
+                                  associated with the attributes specified.\r
+  Global                          Pointer to VARIABLE_GLOBAL structure.\r
+  Instance                        Instance of the Firmware Volume.\r
+\r
+Returns:\r
+\r
+  EFI STATUS\r
+  EFI_INVALID_PARAMETER           - An invalid combination of attribute bits was supplied.\r
+  EFI_SUCCESS                     - Query successfully.\r
+  EFI_UNSUPPORTED                 - The attribute is not supported on this platform.\r
+\r
+--*/\r
+{\r
+  VARIABLE_HEADER        *Variable;\r
+  VARIABLE_HEADER        *NextVariable;\r
+  UINT64                 VariableSize;\r
+  VARIABLE_STORE_HEADER  *VariableStoreHeader;\r
+\r
+  if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)) == 0) {\r
+    //\r
+    // Make sure the Attributes combination is supported by the platform.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {\r
+    //\r
+    // Make sure if runtime bit is set, boot service bit is set also.\r
+    //\r
+    return EFI_INVALID_PARAMETER;\r
+  } else if (EfiAtRuntime () && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {\r
+    //\r
+    //   Make sure RT Attribute is set if we are in Runtime phase.\r
+    //\r
+    return EFI_INVALID_PARAMETER;\r
+  } else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) {\r
+    //\r
+    // Cannot Query volatile variable in Runtime\r
+    //\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  AcquireLockOnlyAtBootTime(&Global->VariableServicesLock);\r
+\r
+  if((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {\r
+    //\r
+    // Query is Volatile related.\r
+    //\r
+    VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);\r
+  } else {\r
+    //\r
+    // Query is Non-Volatile related.\r
+    //\r
+    VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase);\r
+  }\r
+\r
+  //\r
+  // Now let's fill *MaximumVariableStorageSize *RemainingVariableStorageSize\r
+  // with the storage size (excluding the storage header size)\r
+  //\r
+  *MaximumVariableStorageSize   = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER);\r
+  *RemainingVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER);\r
+\r
+  //\r
+  // Let *MaximumVariableSize be MAX_VARIABLE_SIZE\r
+  //\r
+  *MaximumVariableSize = MAX_VARIABLE_SIZE;\r
+\r
+  //\r
+  // Point to the starting address of the variables.\r
+  //\r
+  Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);\r
+\r
+  //\r
+  // Now walk through the related variable store.\r
+  //\r
+  while (Variable < GetEndPointer (VariableStoreHeader)) {\r
+    if (Variable->StartId != VARIABLE_DATA) {\r
+      break;\r
+    }\r
+\r
+    NextVariable = (VARIABLE_HEADER *) (GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));\r
+    VariableSize = (UINT64) (UINTN) NextVariable - (UINT64) (UINTN) Variable;\r
+\r
+    if (Variable->State == VAR_ADDED) {\r
+      *RemainingVariableStorageSize -= VariableSize;\r
+    }\r
+\r
+    //\r
+    // Go to the next one.\r
+    //\r
+    Variable = NextVariable;\r
+  }\r
+\r
+  ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeVariableStore (\r
+  OUT EFI_PHYSICAL_ADDRESS  *VariableBase,\r
+  OUT UINTN                 *LastVariableOffset\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  This function initializes variable store\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  VARIABLE_STORE_HEADER *VariableStore;\r
+\r
+  //\r
+  // Allocate memory for volatile variable store\r
+  //\r
+  VariableStore = (VARIABLE_STORE_HEADER *) AllocateRuntimePool (\r
+                                              VARIABLE_STORE_SIZE\r
+                                              );\r
+  if (NULL == VariableStore) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  SetMem (VariableStore, VARIABLE_STORE_SIZE, 0xff);\r
+\r
+  //\r
+  // Variable Specific Data\r
+  //\r
+  *VariableBase             = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore;\r
+  *LastVariableOffset       = sizeof (VARIABLE_STORE_HEADER);\r
+\r
+  VariableStore->Signature  = VARIABLE_STORE_SIGNATURE;\r
+  VariableStore->Size       = VARIABLE_STORE_SIZE;\r
+  VariableStore->Format     = VARIABLE_STORE_FORMATTED;\r
+  VariableStore->State      = VARIABLE_STORE_HEALTHY;\r
+  VariableStore->Reserved   = 0;\r
+  VariableStore->Reserved1  = 0;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+VariableCommonInitialize (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  This function does common initialization for variable services\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Allocate memory for mVariableModuleGlobal\r
+  //\r
+  mVariableModuleGlobal = (ESAL_VARIABLE_GLOBAL *) AllocateRuntimePool (\r
+                                                    sizeof (ESAL_VARIABLE_GLOBAL)\r
+                                                   );\r
+  if (NULL == mVariableModuleGlobal) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  EfiInitializeLock(&mVariableModuleGlobal->VariableGlobal[Physical].VariableServicesLock, TPL_NOTIFY);\r
+\r
+  //\r
+  // Intialize volatile variable store\r
+  //\r
+  Status = InitializeVariableStore (\r
+            &mVariableModuleGlobal->VariableGlobal[Physical].VolatileVariableBase,\r
+            &mVariableModuleGlobal->VolatileLastVariableOffset\r
+            );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Intialize non volatile variable store\r
+  //\r
+  Status = InitializeVariableStore (\r
+            &mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase,\r
+            &mVariableModuleGlobal->NonVolatileLastVariableOffset\r
+            );\r
+\r
+  return Status;\r
+}\r
diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.infa b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.infa
new file mode 100644 (file)
index 0000000..a22d48b
--- /dev/null
@@ -0,0 +1,106 @@
+#/** @file\r
+# Emulation Variable for EFI_RUNTIME_SERVICES.\r
+#\r
+# This module provides three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = EmuVariable\r
+  FILE_GUID                      = CBD2E4D5-7068-4FF5-B866-9822B4AD8D61\r
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = VariableServiceInitialize\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 EBC\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  InitVariable.c\r
+  EmuVariable.c\r
+  Variable.h\r
+\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  UefiLib\r
+  UefiBootServicesTableLib\r
+  UefiDriverEntryPoint\r
+  UefiRuntimeLib\r
+  DebugLib\r
+  MemoryAllocationLib\r
+  BaseMemoryLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+#                           that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols.IA32]\r
+  gEfiVariableArchProtocolGuid                  # PROTOCOL ALWAYS_PRODUCED\r
+  gEfiVariableWriteArchProtocolGuid             # PROTOCOL ALWAYS_PRODUCED\r
+\r
+[Protocols.X64]\r
+  gEfiVariableArchProtocolGuid                  # PROTOCOL ALWAYS_PRODUCED\r
+  gEfiVariableWriteArchProtocolGuid             # PROTOCOL ALWAYS_PRODUCED\r
+\r
+\r
+################################################################################\r
+#\r
+# Dependency Expression Section - list of Dependency expressions that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Depex]\r
+  TRUE\r
+\r
diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.msa b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.msa
new file mode 100644 (file)
index 0000000..6e769aa
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+  <MsaHeader>\r
+    <ModuleName>EmuVariable</ModuleName>\r
+    <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>\r
+    <GuidValue>CBD2E4D5-7068-4FF5-B866-9822B4AD8D61</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Emulation Variable for EFI_RUNTIME_SERVICES.</Abstract>\r
+    <Description>This module provides three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+    <License>All rights reserved. This program and the accompanying materials
+      are licensed and made available under the terms and conditions of the BSD License
+      which accompanies this distribution.  The full text of the license may be found at
+      http://opensource.org/licenses/bsd-license.php
+      THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+      WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>EmuVariable</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>MemoryAllocationLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DebugLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiRuntimeLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>Variable.h</Filename>\r
+    <Filename>EmuVariable.c</Filename>\r
+    <Filename>EmuVariable.dxs</Filename>\r
+    <Filename>InitVariable.c</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="ALWAYS_PRODUCED" SupArchList="IA32 X64">\r
+      <ProtocolCName>gEfiVariableWriteArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_PRODUCED" SupArchList="IA32 X64">\r
+      <ProtocolCName>gEfiVariableArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <ModuleEntryPoint>VariableServiceInitialize</ModuleEntryPoint>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file
diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariableIpf.inf b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariableIpf.inf
new file mode 100644 (file)
index 0000000..b80c814
--- /dev/null
@@ -0,0 +1,102 @@
+#/** @file\r
+# Emulation Variable for EFI_RUNTIME_SERVICES.\r
+#\r
+# This module provides three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = EmuVariableIpf\r
+  FILE_GUID                      = A46320E8-0514-489a-BC4E-481624D9CE33\r
+  MODULE_TYPE                    = DXE_SAL_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = VariableServiceInitialize\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IPF\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  Ipf/InitVariable.c\r
+  EmuVariable.c\r
+  Variable.h\r
+\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  ExtendedSalLib\r
+  BaseLib\r
+  UefiLib\r
+  UefiBootServicesTableLib\r
+  UefiDriverEntryPoint\r
+  UefiRuntimeLib\r
+  DebugLib\r
+  MemoryAllocationLib\r
+  BaseMemoryLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+#                           that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+  gEfiExtendedSalVariableServicesProtocolGuid   # PROTOCOL ALWAYS_CONSUMED\r
+\r
+\r
+################################################################################\r
+#\r
+# Dependency Expression Section - list of Dependency expressions that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Depex]\r
+  TRUE\r
+\r
diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariableIpf.msa b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariableIpf.msa
new file mode 100644 (file)
index 0000000..d4102d2
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+  <MsaHeader>\r
+    <ModuleName>EmuVariableIpf</ModuleName>\r
+    <ModuleType>DXE_SAL_DRIVER</ModuleType>\r
+    <GuidValue>A46320E8-0514-489a-BC4E-481624D9CE33</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Emulation Variable for EFI_RUNTIME_SERVICES.</Abstract>\r
+    <Description>This module provides three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+    <License>All rights reserved. This program and the accompanying materials
+      are licensed and made available under the terms and conditions of the BSD License
+      which accompanies this distribution.  The full text of the license may be found at
+      http://opensource.org/licenses/bsd-license.php
+      THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+      WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IPF</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>EmuVariableIpf</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>MemoryAllocationLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DebugLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiRuntimeLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>ExtendedSalLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>Variable.h</Filename>\r
+    <Filename>EmuVariable.c</Filename>\r
+    <Filename>EmuVariable.dxs</Filename>\r
+    <Filename>Ipf/InitVariable.c</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiExtendedSalVariableServicesProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <ModuleEntryPoint>VariableServiceInitialize</ModuleEntryPoint>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file
diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/InitVariable.c b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/InitVariable.c
new file mode 100644 (file)
index 0000000..efff41c
--- /dev/null
@@ -0,0 +1,214 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  InitVariable.c\r
+\r
+Abstract:\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "Variable.h"\r
+\r
+//\r
+// Don't use module globals after the SetVirtualAddress map is signaled\r
+//\r
+extern ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+RuntimeServiceGetVariable (\r
+  IN CHAR16        *VariableName,\r
+  IN EFI_GUID      * VendorGuid,\r
+  OUT UINT32       *Attributes OPTIONAL,\r
+  IN OUT UINTN     *DataSize,\r
+  OUT VOID         *Data\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  return GetVariable (\r
+          VariableName,\r
+          VendorGuid,\r
+          Attributes OPTIONAL,\r
+          DataSize,\r
+          Data,\r
+          &mVariableModuleGlobal->VariableGlobal[Physical],\r
+          mVariableModuleGlobal->FvbInstance\r
+          );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+RuntimeServiceGetNextVariableName (\r
+  IN OUT UINTN     *VariableNameSize,\r
+  IN OUT CHAR16    *VariableName,\r
+  IN OUT EFI_GUID  *VendorGuid\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  return GetNextVariableName (\r
+          VariableNameSize,\r
+          VariableName,\r
+          VendorGuid,\r
+          &mVariableModuleGlobal->VariableGlobal[Physical],\r
+          mVariableModuleGlobal->FvbInstance\r
+          );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+RuntimeServiceSetVariable (\r
+  IN CHAR16        *VariableName,\r
+  IN EFI_GUID      *VendorGuid,\r
+  IN UINT32        Attributes,\r
+  IN UINTN         DataSize,\r
+  IN VOID          *Data\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  return SetVariable (\r
+          VariableName,\r
+          VendorGuid,\r
+          Attributes,\r
+          DataSize,\r
+          Data,\r
+          &mVariableModuleGlobal->VariableGlobal[Physical],\r
+          &mVariableModuleGlobal->VolatileLastVariableOffset,\r
+          &mVariableModuleGlobal->NonVolatileLastVariableOffset,\r
+          mVariableModuleGlobal->FvbInstance\r
+          );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+RuntimeServiceQueryVariableInfo (\r
+  IN  UINT32                 Attributes,\r
+  OUT UINT64                 *MaximumVariableStorageSize,\r
+  OUT UINT64                 *RemainingVariableStorageSize,\r
+  OUT UINT64                 *MaximumVariableSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  return QueryVariableInfo (\r
+          Attributes,\r
+          MaximumVariableStorageSize,\r
+          RemainingVariableStorageSize,\r
+          MaximumVariableSize,\r
+          &mVariableModuleGlobal->VariableGlobal[Physical],\r
+          mVariableModuleGlobal->FvbInstance\r
+          );\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+VariableClassAddressChangeEvent (\r
+  IN EFI_EVENT        Event,\r
+  IN VOID             *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  EfiConvertPointer (\r
+    0x0,\r
+    (VOID **) &mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase\r
+    );\r
+  EfiConvertPointer (\r
+    0x0,\r
+    (VOID **) &mVariableModuleGlobal->VariableGlobal[Physical].VolatileVariableBase\r
+    );\r
+  EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+VariableServiceInitialize (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  EFI_HANDLE  NewHandle;\r
+  EFI_STATUS  Status;\r
+\r
+  Status = VariableCommonInitialize (ImageHandle, SystemTable);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  SystemTable->RuntimeServices->GetVariable         = RuntimeServiceGetVariable;\r
+  SystemTable->RuntimeServices->GetNextVariableName = RuntimeServiceGetNextVariableName;\r
+  SystemTable->RuntimeServices->SetVariable         = RuntimeServiceSetVariable;\r
+  SystemTable->RuntimeServices->QueryVariableInfo   = RuntimeServiceQueryVariableInfo;\r
+\r
+  //\r
+  // Now install the Variable Runtime Architectural Protocol on a new handle\r
+  //\r
+  NewHandle = NULL;\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &NewHandle,\r
+                  &gEfiVariableArchProtocolGuid,\r
+                  NULL,\r
+                  &gEfiVariableWriteArchProtocolGuid,\r
+                  NULL,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/Ipf/InitVariable.c b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/Ipf/InitVariable.c
new file mode 100644 (file)
index 0000000..1b81dd6
--- /dev/null
@@ -0,0 +1,181 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  IpfVariable.c\r
+\r
+Abstract:\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "Variable.h"\r
+#include <IndustryStandard/Sal.h>\r
+\r
+//\r
+// Don't use module globals after the SetVirtualAddress map is signaled\r
+//\r
+\r
+STATIC\r
+SAL_RETURN_REGS\r
+EsalVariableCommonEntry (\r
+  IN  UINT64                                      FunctionId,\r
+  IN  UINT64                                      Arg2,\r
+  IN  UINT64                                      Arg3,\r
+  IN  UINT64                                      Arg4,\r
+  IN  UINT64                                      Arg5,\r
+  IN  UINT64                                      Arg6,\r
+  IN  UINT64                                      Arg7,\r
+  IN  UINT64                                      Arg8,\r
+  IN  SAL_EXTENDED_SAL_PROC                       ExtendedSalProc,\r
+  IN  BOOLEAN                                     VirtualMode,\r
+  IN  ESAL_VARIABLE_GLOBAL                        *Global\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  SAL_RETURN_REGS ReturnVal;\r
+\r
+  switch (FunctionId) {\r
+  case EsalGetVariable:\r
+    ReturnVal.Status = GetVariable (\r
+                        (CHAR16 *) Arg2,\r
+                        (EFI_GUID *) Arg3,\r
+                        (UINT32 *) Arg4,\r
+                        (UINTN *) Arg5,\r
+                        (VOID *) Arg6,\r
+                        &Global->VariableGlobal[VirtualMode],\r
+                        Global->FvbInstance\r
+                        );\r
+    return ReturnVal;\r
+\r
+  case EsalGetNextVariableName:\r
+    ReturnVal.Status = GetNextVariableName (\r
+                        (UINTN *) Arg2,\r
+                        (CHAR16 *) Arg3,\r
+                        (EFI_GUID *) Arg4,\r
+                        &Global->VariableGlobal[VirtualMode],\r
+                        Global->FvbInstance\r
+                        );\r
+    return ReturnVal;\r
+\r
+  case EsalSetVariable:\r
+    ReturnVal.Status = SetVariable (\r
+                        (CHAR16 *) Arg2,\r
+                        (EFI_GUID *) Arg3,\r
+                        (UINT32) Arg4,\r
+                        (UINTN) Arg5,\r
+                        (VOID *) Arg6,\r
+                        &Global->VariableGlobal[VirtualMode],\r
+                        (UINTN *) &Global->VolatileLastVariableOffset,\r
+                        (UINTN *) &Global->NonVolatileLastVariableOffset,\r
+                        Global->FvbInstance\r
+                        );\r
+    return ReturnVal;\r
+\r
+  case EsalQueryVariableInfo:\r
+    ReturnVal.Status = QueryVariableInfo (\r
+                        (UINT32) Arg2,\r
+                        (UINT64 *) Arg3,\r
+                        (UINT64 *) Arg4,\r
+                        (UINT64 *) Arg5,\r
+                        &Global->VariableGlobal[VirtualMode],\r
+                        Global->FvbInstance\r
+                        );\r
+    return ReturnVal;\r
+\r
+  default:\r
+    ReturnVal.Status = EFI_SAL_INVALID_ARGUMENT;\r
+    return ReturnVal;\r
+  }\r
+}\r
+\r
+\r
+VOID\r
+VariableClassAddressChangeEvent (\r
+  IN EFI_EVENT        Event,\r
+  IN VOID             *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  CopyMem (\r
+    &mVariableModuleGlobal->VariableGlobal[Virtual],\r
+    &mVariableModuleGlobal->VariableGlobal[Physical],\r
+    sizeof (VARIABLE_GLOBAL)\r
+    );\r
+\r
+  EfiConvertPointer (\r
+    0x0,\r
+    (VOID **) &mVariableModuleGlobal->VariableGlobal[Virtual].NonVolatileVariableBase\r
+    );\r
+  EfiConvertPointer (\r
+    0x0,\r
+    (VOID **) &mVariableModuleGlobal->VariableGlobal[Virtual].VolatileVariableBase\r
+    );\r
+  EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);\r
+}\r
+\r
+EFI_STATUS\r
+VariableServiceInitialize (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = VariableCommonInitialize (ImageHandle, SystemTable);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  //  Register All the Functions with Extended Sal.\r
+  //\r
+  RegisterEsalClass (\r
+    &gEfiExtendedSalVariableServicesProtocolGuid,\r
+    mVariableModuleGlobal,\r
+    EsalVariableCommonEntry,\r
+    EsalGetVariable,\r
+    EsalVariableCommonEntry,\r
+    EsalGetNextVariableName,\r
+    EsalVariableCommonEntry,\r
+    EsalSetVariable,\r
+    EsalVariableCommonEntry,\r
+    EsalQueryVariableInfo,\r
+    NULL\r
+    );\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/Variable.h b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/Variable.h
new file mode 100644 (file)
index 0000000..1e445c5
--- /dev/null
@@ -0,0 +1,171 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  Variable.h\r
+\r
+Abstract:\r
+\r
+--*/\r
+\r
+#ifndef _VARIABLE_H\r
+#define _VARIABLE_H\r
+\r
+//\r
+// Statements that include other header files\r
+//\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <PiDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Protocol/VariableWrite.h>\r
+#include <Protocol/Variable.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiRuntimeLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseLib.h>\r
+\r
+//\r
+// BugBug: We need relcate the head file.\r
+//\r
+#include <Common/Variable.h>\r
+\r
+#define VARIABLE_STORE_SIZE (64 * 1024)\r
+#define SCRATCH_SIZE        (4 * 1024)\r
+\r
+//\r
+// Define GET_PAD_SIZE to optimize compiler\r
+//\r
+#if ((ALIGNMENT == 0) || (ALIGNMENT == 1))\r
+#define GET_PAD_SIZE(a) (0)\r
+#else\r
+#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1))\r
+#endif\r
+\r
+#define GET_VARIABLE_NAME_PTR(a)  (CHAR16 *) ((UINTN) (a) + sizeof (VARIABLE_HEADER))\r
+\r
+typedef enum {\r
+  Physical,\r
+  Virtual\r
+} VARIABLE_POINTER_TYPE;\r
+\r
+typedef struct {\r
+  VARIABLE_HEADER *CurrPtr;\r
+  VARIABLE_HEADER *EndPtr;\r
+  VARIABLE_HEADER *StartPtr;\r
+  BOOLEAN         Volatile;\r
+} VARIABLE_POINTER_TRACK;\r
+\r
+typedef struct {\r
+  EFI_PHYSICAL_ADDRESS  VolatileVariableBase;\r
+  EFI_PHYSICAL_ADDRESS  NonVolatileVariableBase;\r
+  EFI_LOCK              VariableServicesLock;\r
+} VARIABLE_GLOBAL;\r
+\r
+typedef struct {\r
+  VARIABLE_GLOBAL VariableGlobal[2];\r
+  UINTN           VolatileLastVariableOffset;\r
+  UINTN           NonVolatileLastVariableOffset;\r
+  UINT32          FvbInstance;\r
+} ESAL_VARIABLE_GLOBAL;\r
+\r
+extern ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal;\r
+\r
+//\r
+// Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+VariableCommonInitialize (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+VariableServiceInitialize (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  )\r
+;\r
+\r
+VOID\r
+EFIAPI\r
+VariableClassAddressChangeEvent (\r
+  IN EFI_EVENT        Event,\r
+  IN VOID             *Context\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetVariable (\r
+  IN      CHAR16            *VariableName,\r
+  IN      EFI_GUID          * VendorGuid,\r
+  OUT     UINT32            *Attributes OPTIONAL,\r
+  IN OUT  UINTN             *DataSize,\r
+  OUT     VOID              *Data,\r
+  IN      VARIABLE_GLOBAL   * Global,\r
+  IN      UINT32            Instance\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetNextVariableName (\r
+  IN OUT  UINTN             *VariableNameSize,\r
+  IN OUT  CHAR16            *VariableName,\r
+  IN OUT  EFI_GUID          *VendorGuid,\r
+  IN      VARIABLE_GLOBAL   *Global,\r
+  IN      UINT32            Instance\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+SetVariable (\r
+  IN CHAR16                  *VariableName,\r
+  IN EFI_GUID                *VendorGuid,\r
+  IN UINT32                  Attributes,\r
+  IN UINTN                   DataSize,\r
+  IN VOID                    *Data,\r
+  IN VARIABLE_GLOBAL         *Global,\r
+  IN UINTN                   *VolatileOffset,\r
+  IN UINTN                   *NonVolatileOffset,\r
+  IN UINT32                  Instance\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+QueryVariableInfo (\r
+  IN  UINT32                 Attributes,\r
+  OUT UINT64                 *MaximumVariableStorageSize,\r
+  OUT UINT64                 *RemainingVariableStorageSize,\r
+  OUT UINT64                 *MaximumVariableSize,\r
+  IN  VARIABLE_GLOBAL        *Global,\r
+  IN  UINT32                 Instance\r
+  )\r
+;\r
+\r
+#endif\r