]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
Change C functions, xxxSizeOfVariable(), to MACRO, which can avoid the ICC compile...
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / RuntimeDxe / Variable.c
index 11a36ba8264959f6f27033b4fabf3355f41758fb..d7cb0cd71c1908c79f726b3732c4918a0b98c9cd 100644 (file)
@@ -152,7 +152,6 @@ UpdateVariableInfo (
 }\r
 \r
 \r
-\r
 BOOLEAN\r
 IsValidVariableHeader (\r
   IN  VARIABLE_HEADER   *Variable\r
@@ -172,10 +171,7 @@ Returns:
 \r
 --*/\r
 {\r
-  if (Variable == NULL ||\r
-      Variable->StartId != VARIABLE_DATA ||\r
-      (sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize) > MAX_VARIABLE_SIZE\r
-      ) {\r
+  if (Variable == NULL || Variable->StartId != VARIABLE_DATA) {\r
     return FALSE;\r
   }\r
 \r
@@ -371,7 +367,6 @@ Returns:
   }\r
 }\r
 \r
-\r
 UINT8 *\r
 GetVariableDataPtr (\r
   IN  VARIABLE_HEADER   *Variable\r
@@ -395,7 +390,7 @@ Returns:
   //\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
+  return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + NAMESIZE_OF_VARIABLE (Variable) + GET_PAD_SIZE (NAMESIZE_OF_VARIABLE (Variable)));\r
 }\r
 \r
 \r
@@ -425,9 +420,34 @@ Returns:
   //\r
   // Be careful about pad size for alignment\r
   //\r
-  return (VARIABLE_HEADER *) ((UINTN) GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));\r
+  return (VARIABLE_HEADER *) HEADER_ALIGN (((UINTN) GetVariableDataPtr (Variable) + DATASIZE_OF_VARIABLE (Variable) + GET_PAD_SIZE (DATASIZE_OF_VARIABLE (Variable))));\r
 }\r
 \r
+VARIABLE_HEADER *\r
+GetStartPointer (\r
+  IN VARIABLE_STORE_HEADER       *VarStoreHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This code gets the pointer to the first variable memory pointer byte\r
+\r
+Arguments:\r
+\r
+  VarStoreHeader        Pointer to the Variable Store 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 *) HEADER_ALIGN (VarStoreHeader + 1);\r
+}\r
 \r
 VARIABLE_HEADER *\r
 GetEndPointer (\r
@@ -452,7 +472,7 @@ Returns:
   //\r
   // The end of variable store\r
   //\r
-  return (VARIABLE_HEADER *) ((UINTN) VarStoreHeader + VarStoreHeader->Size);\r
+  return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size);\r
 }\r
 \r
 \r
@@ -495,8 +515,7 @@ Returns:
   //\r
   // Start Pointers for the variable.\r
   //\r
-  Variable        = (VARIABLE_HEADER *) (VariableStoreHeader + 1);\r
-\r
+  Variable        = GetStartPointer (VariableStoreHeader);\r
   ValidBufferSize = sizeof (VARIABLE_STORE_HEADER);\r
 \r
   while (IsValidVariableHeader (Variable)) {\r
@@ -522,12 +541,12 @@ Returns:
   // Copy variable store header\r
   //\r
   CopyMem (CurrPtr, VariableStoreHeader, sizeof (VARIABLE_STORE_HEADER));\r
-  CurrPtr += sizeof (VARIABLE_STORE_HEADER);\r
+  CurrPtr = (UINT8 *) GetStartPointer (VariableStoreHeader);\r
 \r
   //\r
   // Start Pointers for the variable.\r
   //\r
-  Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);\r
+  Variable = GetStartPointer (VariableStoreHeader);\r
 \r
   while (IsValidVariableHeader (Variable)) {\r
     NextVariable = GetNextVariablePtr (Variable);\r
@@ -676,11 +695,12 @@ FindVariableInCache (
         if (Entry->DataSize == 0) {\r
           // Variable was deleted so return not found\r
           return EFI_NOT_FOUND;\r
-        } else if (Entry->DataSize != *DataSize) {\r
+        } else if (Entry->DataSize > *DataSize) {\r
           // If the buffer is too small return correct size\r
           *DataSize = Entry->DataSize;\r
           return EFI_BUFFER_TOO_SMALL;\r
         } else {\r
+          *DataSize = Entry->DataSize;\r
           // Return the data\r
           CopyMem (Data, Entry->Data, Entry->DataSize);\r
           if (Attributes != NULL) {\r
@@ -728,15 +748,10 @@ Returns:
   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(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
-\r
   //\r
   // 0: Volatile, 1: Non-Volatile\r
+  // The index and attributes mapping must be kept in this order as RuntimeServiceGetNextVariableName\r
+  // make use of this mapping to implement search algorithme.\r
   //\r
   VariableStoreHeader[0]  = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);\r
   VariableStoreHeader[1]  = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
@@ -745,8 +760,8 @@ Returns:
   // 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
+  Variable[0] = GetStartPointer (VariableStoreHeader[0]);\r
+  Variable[1] = GetStartPointer (VariableStoreHeader[1]);\r
 \r
   if (VariableName[0] != 0 && VendorGuid == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -755,7 +770,7 @@ Returns:
   // Find the variable by walk through volatile and then non-volatile variable store\r
   //\r
   for (Index = 0; Index < 2; Index++) {\r
-    PtrTrack->StartPtr  = (VARIABLE_HEADER *) (VariableStoreHeader[Index] + 1);\r
+    PtrTrack->StartPtr  = GetStartPointer (VariableStoreHeader[Index]);\r
     PtrTrack->EndPtr    = GetEndPointer (VariableStoreHeader[Index]);\r
 \r
     while (IsValidVariableHeader (Variable[Index]) && (Variable[Index] <= GetEndPointer (VariableStoreHeader[Index]))) {\r
@@ -767,7 +782,8 @@ Returns:
             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
+              ASSERT (NAMESIZE_OF_VARIABLE (Variable[Index]) != 0);\r
+              if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable[Index]), NAMESIZE_OF_VARIABLE (Variable[Index]))) {\r
                 PtrTrack->CurrPtr   = Variable[Index];\r
                 PtrTrack->Volatile  = (BOOLEAN)(Index == 0);\r
                 return EFI_SUCCESS;\r
@@ -830,6 +846,8 @@ RuntimeServiceGetVariable (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
   //\r
   // Find existing variable\r
   //\r
@@ -837,7 +855,7 @@ RuntimeServiceGetVariable (
   if ((Status == EFI_BUFFER_TOO_SMALL) || (Status == EFI_SUCCESS)){\r
     // Hit in the Cache\r
     UpdateVariableInfo (VariableName, VendorGuid, FALSE, TRUE, FALSE, FALSE, TRUE);\r
-    return Status;\r
+    goto Done;\r
   }\r
   \r
   Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
@@ -848,7 +866,9 @@ RuntimeServiceGetVariable (
   //\r
   // Get data size\r
   //\r
-  VarDataSize = Variable.CurrPtr->DataSize;\r
+  VarDataSize = DATASIZE_OF_VARIABLE (Variable.CurrPtr);\r
+  ASSERT (VarDataSize != 0);\r
+\r
   if (*DataSize >= VarDataSize) {\r
     if (Data == NULL) {\r
       Status = EFI_INVALID_PARAMETER;\r
@@ -914,6 +934,8 @@ RuntimeServiceGetNextVariableName (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
   Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
   if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {\r
     goto Done;\r
@@ -933,9 +955,9 @@ RuntimeServiceGetNextVariableName (
     //\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) (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase + sizeof (VARIABLE_STORE_HEADER)));\r
-        Variable.EndPtr = (VARIABLE_HEADER *) GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase));\r
+      if (!Variable.Volatile) {\r
+        Variable.StartPtr = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
+        Variable.EndPtr   = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase));\r
       } else {\r
         Status = EFI_NOT_FOUND;\r
         goto Done;\r
@@ -951,7 +973,9 @@ RuntimeServiceGetNextVariableName (
     //\r
     if (IsValidVariableHeader (Variable.CurrPtr) && Variable.CurrPtr->State == VAR_ADDED) {\r
       if (!(EfiAtRuntime () && !(Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {\r
-        VarNameSize = Variable.CurrPtr->NameSize;\r
+        VarNameSize = NAMESIZE_OF_VARIABLE (Variable.CurrPtr);\r
+        ASSERT (VarNameSize != 0);\r
+\r
         if (VarNameSize <= *VariableNameSize) {\r
           CopyMem (\r
             VariableName,\r
@@ -1034,11 +1058,7 @@ RuntimeServiceSetVariable (
   UINTN                   *NonVolatileOffset;\r
   UINT32                  Instance;\r
   BOOLEAN                 Volatile;\r
-\r
-  Reclaimed         = FALSE;\r
-  VolatileOffset    = &mVariableModuleGlobal->VolatileLastVariableOffset;\r
-  NonVolatileOffset = &mVariableModuleGlobal->NonVolatileLastVariableOffset;\r
-  Instance          = mVariableModuleGlobal->FvbInstance;\r
+  EFI_PHYSICAL_ADDRESS    Point;\r
 \r
   //\r
   // Check input parameters\r
@@ -1052,6 +1072,7 @@ RuntimeServiceSetVariable (
   if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   //\r
   //  The size of the VariableName, including the Unicode Null in bytes plus\r
   //  the DataSize is limited to maximum size of MAX_HARDWARE_ERROR_VARIABLE_SIZE (32K)\r
@@ -1072,6 +1093,31 @@ RuntimeServiceSetVariable (
       return EFI_INVALID_PARAMETER;\r
     }  \r
   }  \r
+\r
+  AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
+  Reclaimed         = FALSE;\r
+  Instance          = mVariableModuleGlobal->FvbInstance;\r
+  VolatileOffset    = &mVariableModuleGlobal->VolatileLastVariableOffset;\r
+\r
+  //\r
+  // Consider reentrant in MCA/INIT/NMI. It needs be reupdated;\r
+  //\r
+  if (1 < InterlockedIncrement (&mVariableModuleGlobal->VariableGlobal.ReentrantState)) {\r
+    Point = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;;\r
+    //\r
+    // Parse non-volatile variable data and get last variable offset\r
+    //\r
+    NextVariable  = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) Point);\r
+    while (IsValidVariableHeader (NextVariable)) {\r
+      NextVariable = GetNextVariablePtr (NextVariable);\r
+    }\r
+    mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) Point;\r
+  }\r
+\r
+  NonVolatileOffset = &mVariableModuleGlobal->NonVolatileLastVariableOffset;\r
+  \r
+\r
   //\r
   // Check whether the input variable is already existed\r
   //\r
@@ -1128,7 +1174,7 @@ RuntimeServiceSetVariable (
     // 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
+    if (DATASIZE_OF_VARIABLE (Variable.CurrPtr) == DataSize &&\r
         (CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize) == 0)) {\r
       \r
       UpdateVariableInfo (VariableName, VendorGuid, Volatile, FALSE, TRUE, FALSE, FALSE);\r
@@ -1317,7 +1363,7 @@ RuntimeServiceSetVariable (
       goto Done;\r
     }\r
 \r
-    *NonVolatileOffset = *NonVolatileOffset + VarSize;\r
+    *NonVolatileOffset = HEADER_ALIGN (*NonVolatileOffset + VarSize);\r
 \r
   } else {\r
     //\r
@@ -1362,7 +1408,7 @@ RuntimeServiceSetVariable (
       goto Done;\r
     }\r
 \r
-    *VolatileOffset = *VolatileOffset + VarSize;\r
+    *VolatileOffset = HEADER_ALIGN (*VolatileOffset + VarSize);\r
   }\r
   //\r
   // Mark the old variable as deleted\r
@@ -1393,7 +1439,9 @@ RuntimeServiceSetVariable (
   UpdateVariableCache (VariableName, VendorGuid, Attributes, DataSize, Data);\r
 \r
 Done:\r
+  InterlockedDecrement (&mVariableModuleGlobal->VariableGlobal.ReentrantState);\r
   ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
   return Status;\r
 }\r
 \r
@@ -1496,7 +1544,7 @@ RuntimeServiceQueryVariableInfo (
   //\r
   // Point to the starting address of the variables.\r
   //\r
-  Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);\r
+  Variable = GetStartPointer (VariableStoreHeader);\r
 \r
   //\r
   // Now walk through the related variable store.\r
@@ -1583,6 +1631,7 @@ Returns:
 \r
 \r
   EfiInitializeLock(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock, TPL_NOTIFY);\r
+  mVariableModuleGlobal->VariableGlobal.ReentrantState = 0;\r
 \r
   //\r
   // Allocate memory for volatile variable store\r
@@ -1599,7 +1648,7 @@ Returns:
   //  Variable Specific Data\r
   //\r
   mVariableModuleGlobal->VariableGlobal.VolatileVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VolatileVariableStore;\r
-  mVariableModuleGlobal->VolatileLastVariableOffset = sizeof (VARIABLE_STORE_HEADER);\r
+  mVariableModuleGlobal->VolatileLastVariableOffset = (UINTN) GetStartPointer (VolatileVariableStore) - (UINTN) VolatileVariableStore;\r
 \r
   VolatileVariableStore->Signature                  = VARIABLE_STORE_SIGNATURE;\r
   VolatileVariableStore->Size                       = VARIABLE_STORE_SIZE;\r
@@ -1695,7 +1744,7 @@ Returns:
     //\r
     // Parse non-volatile variable data and get last variable offset\r
     //\r
-    NextVariable  = (VARIABLE_HEADER *) (CurrPtr + sizeof (VARIABLE_STORE_HEADER));\r
+    NextVariable  = GetStartPointer ((VARIABLE_STORE_HEADER *) CurrPtr);\r
     Status        = EFI_SUCCESS;\r
 \r
     while (IsValidVariableHeader (NextVariable)) {\r