]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c
Fix the issue that Windows Server 2003 installation fails on Tiger.
[mirror_edk2.git] / EdkModulePkg / Universal / Variable / RuntimeDxe / Variable.c
index a3992f7ebdfed988e802ec7b317936fac9b09a4c..cd38536836460ca85780c2e48e51d89aa7fcef18 100644 (file)
@@ -1,13 +1,13 @@
 /*++\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
+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
@@ -28,7 +28,7 @@ Revision History
 ESAL_VARIABLE_GLOBAL  *mVariableModuleGlobal;\r
 \r
 //\r
-// This is a temperary function which will be removed \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
@@ -44,7 +44,7 @@ AcquireLockOnlyAtBootTime (
 }\r
 \r
 //\r
-// This is a temperary function which will be removed \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
@@ -59,6 +59,39 @@ ReleaseLockOnlyAtBootTime (
   }\r
 }\r
 \r
+/**
+  A temparaty function that returns the size of a Null-terminated Unicode
+  string in bytes, including the Null terminator.
+
+  This function returns the size, in bytes, of the Null-terminated Unicode
+  string specified by String. It duplicates the functionality of StrSize()
+  in MDE library, but avoids using PCD, because IPF currently cannot convert
+  address of global variable for runtime.
+
+  If String is NULL, then ASSERT().
+  If String is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  String  Pointer to a Null-terminated Unicode string.
+
+  @return The size of String.
+
+**/
+STATIC
+UINTN
+StrSizeOfVariableName (
+  IN      CONST CHAR16              *String
+  )
+{
+  UINTN                             Length;
+
+  ASSERT (String != NULL);
+  ASSERT (((UINTN) String & 0x01) == 0);
+
+  for (Length = 0; *String != L'\0'; String++, Length++);
+
+  return (Length + 1) * sizeof (*String);
+}
+\r
 STATIC\r
 BOOLEAN\r
 EFIAPI\r
@@ -260,7 +293,7 @@ Returns:
 \r
   EfiRaw        Variable store status is raw\r
   EfiValid      Variable store status is valid\r
-  EfiInvalid    Variable store status is invalid  \r
+  EfiInvalid    Variable store status is invalid\r
 \r
 --*/\r
 {\r
@@ -424,13 +457,9 @@ Returns:
     Variable = NextVariable;\r
   }\r
 \r
-  Status = gBS->AllocatePool (\r
-                  EfiBootServicesData,\r
-                  ValidBufferSize,\r
-                  (VOID **) &ValidBuffer\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
+  ValidBuffer = AllocatePool (ValidBufferSize);\r
+  if (ValidBuffer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
   SetMem (ValidBuffer, ValidBufferSize, 0xff);\r
@@ -481,7 +510,7 @@ Returns:
     }\r
   }\r
 \r
-  gBS->FreePool (ValidBuffer);\r
+  FreePool (ValidBuffer);\r
 \r
   if (EFI_ERROR (Status)) {\r
     *LastVariableOffset = 0;\r
@@ -833,13 +862,13 @@ Returns:
     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
+    // 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
+  } else if (sizeof (VARIABLE_HEADER) + StrSizeOfVariableName (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
@@ -848,11 +877,11 @@ Returns:
     goto Done;\r
   } else if (Attributes == EFI_VARIABLE_NON_VOLATILE) {\r
     //\r
-    //  Make sure not only EFI_VARIABLE_NON_VOLATILE is set \r
+    //  Make sure not only EFI_VARIABLE_NON_VOLATILE is set\r
     //\r
     Status = EFI_INVALID_PARAMETER;\r
     goto Done;\r
-  } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == \r
+  } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) ==\r
                 EFI_VARIABLE_RUNTIME_ACCESS) {\r
     //\r
     //  Make sure if runtime bit is set, boot service bit is set also\r
@@ -948,7 +977,7 @@ Returns:
     //\r
     NextVariable->Reserved  = 0;\r
     VarNameOffset           = sizeof (VARIABLE_HEADER);\r
-    VarNameSize             = StrSize (VariableName);\r
+    VarNameSize             = StrSizeOfVariableName (VariableName);\r
     CopyMem (\r
       (UINT8 *) ((UINTN) NextVariable + VarNameOffset),\r
       VariableName,\r
@@ -998,7 +1027,7 @@ Returns:
           Status = EFI_OUT_OF_RESOURCES;\r
           goto Done;\r
         }\r
-        \r
+\r
         Reclaimed = TRUE;\r
       }\r
       //\r
@@ -1084,7 +1113,7 @@ Returns:
           Status = EFI_OUT_OF_RESOURCES;\r
           goto Done;\r
         }\r
-        \r
+\r
         Reclaimed = TRUE;\r
       }\r
 \r
@@ -1134,7 +1163,6 @@ Done:
   return Status;\r
 }\r
 \r
-#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
 EFI_STATUS\r
 EFIAPI\r
 QueryVariableInfo (\r
@@ -1153,11 +1181,11 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  Attributes                      Attributes bitmask to specify the type of variables \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
+  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
@@ -1200,12 +1228,12 @@ Returns:
   }\r
 \r
   AcquireLockOnlyAtBootTime(&Global->VariableServicesLock);\r
-  \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
+    VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);\r
   } else {\r
     //\r
     // Query is Non-Volatile related.\r
@@ -1214,7 +1242,7 @@ Returns:
   }\r
 \r
   //\r
-  // Now let's fill *MaximumVariableStorageSize *RemainingVariableStorageSize \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
@@ -1239,32 +1267,31 @@ Returns:
 \r
     if (EfiAtRuntime ()) {\r
       //\r
-      // we don't take the state of the variables in mind \r
+      // we don't take the state of the variables in mind\r
       // when calculating RemainingVariableStorageSize,\r
-      // since the space occupied by variables not marked with \r
+      // since the space occupied by variables not marked with\r
       // VAR_ADDED is not allowed to be reclaimed in Runtime.\r
       //\r
       *RemainingVariableStorageSize -= VariableSize;\r
     } else {\r
       //\r
-      // Only care about Variables with State VAR_ADDED,because \r
+      // Only care about Variables with State VAR_ADDED,because\r
       // the space not marked as VAR_ADDED is reclaimable now.\r
       //\r
       if (Variable->State == VAR_ADDED) {\r
         *RemainingVariableStorageSize -= VariableSize;\r
       }\r
     }\r
-    \r
+\r
     //\r
     // Go to the next one\r
     //\r
     Variable = NextVariable;\r
   }\r
\r
+\r
   ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock);\r
   return EFI_SUCCESS;\r
 }\r
-#endif\r
 \r
 EFI_STATUS\r
 EFIAPI\r
@@ -1283,9 +1310,9 @@ Arguments:
   SystemTable   - A pointer to the EFI System Table.\r
 \r
 Returns:\r
-  \r
+\r
   Status code.\r
-  \r
+\r
   EFI_NOT_FOUND     - Variable store area not found.\r
   EFI_UNSUPPORTED   - Currently only one non-volatile variable store is supported.\r
   EFI_SUCCESS       - Variable services successfully initialized.\r
@@ -1310,30 +1337,20 @@ Returns:
   UINTN                           Index;\r
   UINT8                           Data;\r
 \r
-  Status = gBS->AllocatePool (\r
-                  EfiRuntimeServicesData,\r
-                  sizeof (ESAL_VARIABLE_GLOBAL),\r
-                  (VOID **) &mVariableModuleGlobal\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
+  mVariableModuleGlobal = AllocateRuntimePool (sizeof (ESAL_VARIABLE_GLOBAL));\r
+  if (mVariableModuleGlobal == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  EfiInitializeLock(&mVariableModuleGlobal->VariableGlobal[Physical].VariableServicesLock, EFI_TPL_CALLBACK);\r
-  \r
+  EfiInitializeLock(&mVariableModuleGlobal->VariableGlobal[Physical].VariableServicesLock, EFI_TPL_NOTIFY);\r
+\r
   //\r
   // Allocate memory for volatile variable store\r
   //\r
-  Status = gBS->AllocatePool (\r
-                  EfiRuntimeServicesData,\r
-                  VARIABLE_STORE_SIZE + SCRATCH_SIZE,\r
-                  (VOID **) &VolatileVariableStore\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->FreePool (mVariableModuleGlobal);\r
-    return Status;\r
+  VolatileVariableStore = AllocateRuntimePool (VARIABLE_STORE_SIZE + SCRATCH_SIZE);\r
+  if (VolatileVariableStore == NULL) {\r
+    FreePool (mVariableModuleGlobal);\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
   SetMem (VolatileVariableStore, VARIABLE_STORE_SIZE + SCRATCH_SIZE, 0xff);\r
@@ -1369,8 +1386,8 @@ Returns:
 \r
   Status      = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor);\r
   if (EFI_ERROR (Status)) {\r
-    gBS->FreePool (mVariableModuleGlobal);\r
-    gBS->FreePool (VolatileVariableStore);\r
+    FreePool (mVariableModuleGlobal);\r
+    FreePool (VolatileVariableStore);\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -1380,8 +1397,8 @@ Returns:
                   GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    gBS->FreePool (mVariableModuleGlobal);\r
-    gBS->FreePool (VolatileVariableStore);\r
+    FreePool (mVariableModuleGlobal);\r
+    FreePool (VolatileVariableStore);\r
     return EFI_UNSUPPORTED;\r
   }\r
   //\r
@@ -1419,6 +1436,15 @@ Returns:
                 sizeof (UINT32),\r
                 (UINT8 *) &VariableStoreEntry.Length\r
                 );\r
+      // \r
+      // As Variables are stored in NV storage, which are slow devices,such as flash.\r
+      // Variable operation may skip checking variable program result to improve performance,\r
+      // We can assume Variable program is OK through some check point.\r
+      // Variable Store Size Setting should be the first Variable write operation,\r
+      // We can assume all Read/Write is OK if we can set Variable store size successfully.\r
+      // If write fail, we will assert here\r
+      //\r
+      ASSERT(VariableStoreHeader->Size == VariableStoreEntry.Length);\r
 \r
       if (EFI_ERROR (Status)) {\r
         return Status;\r
@@ -1450,8 +1476,8 @@ Returns:
     }\r
 \r
     if (EFI_ERROR (Status)) {\r
-      gBS->FreePool (mVariableModuleGlobal);\r
-      gBS->FreePool (VolatileVariableStore);\r
+      FreePool (mVariableModuleGlobal);\r
+      FreePool (VolatileVariableStore);\r
       return Status;\r
     }\r
 \r
@@ -1475,8 +1501,8 @@ Returns:
   }\r
 \r
   if (EFI_ERROR (Status)) {\r
-    gBS->FreePool (mVariableModuleGlobal);\r
-    gBS->FreePool (VolatileVariableStore);\r
+    FreePool (mVariableModuleGlobal);\r
+    FreePool (VolatileVariableStore);\r
   }\r
 \r
   return Status;\r