]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Variable/Pei/Variable.c
add assertion to pass K8 check.
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / Pei / Variable.c
index 3a1ae4192820cc92ffbbfb5a455dc759cad8b89d..8ceebedd15bcde99af2a82e2ec452b6e506876f4 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 \r
   Implement ReadOnly Variable Services required by PEIM and install\r
-  PI ReadOnly Varaiable2 PPI. These services operates the non volatile storage space.\r
+  PEI ReadOnly Varaiable2 PPI. These services operates the non volatile storage space.\r
 \r
 Copyright (c) 2006 - 2008 Intel Corporation. <BR>\r
 All rights reserved. This program and the accompanying materials\r
@@ -38,8 +38,8 @@ EFI_GUID mEfiVariableIndexTableGuid = EFI_VARIABLE_INDEX_TABLE_GUID;
 /**\r
   Provide the functionality of the variable services.\r
   \r
-  @param  FileHandle  Handle of the file being invoked. \r
-                      Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextFile().\r
+  @param  FileHandle   Handle of the file being invoked. \r
+                       Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextFile().\r
   @param  PeiServices  General purpose services available to every PEIM.\r
 \r
   @retval EFI_SUCCESS  If the interface could be successfully installed\r
@@ -53,20 +53,32 @@ PeimInitializeVariableServices (
   IN CONST EFI_PEI_SERVICES          **PeiServices\r
   )\r
 {\r
+  EFI_BOOT_MODE BootMode;\r
+  EFI_STATUS    Status;\r
+\r
   //\r
-  // Publish the variable capability to other modules\r
-  //\r
+  // Check if this is recovery boot path. If no, publish the variable access capability\r
+  // to other modules. If yes, the content of variable area is not reliable. Therefore,\r
+  // in this case we should not provide variable service to other pei modules. \r
+  // \r
+  Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);\r
+  ASSERT_EFI_ERROR (Status);\r
+  \r
+  if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
   return PeiServicesInstallPpi (&mPpiListVariable);\r
 \r
 }\r
 \r
-\r
 /**\r
-  This code gets the pointer to the first variable memory pointer byte.\r
 \r
-  @param  VarStoreHeader   Pointer to the Variable Store Header.\r
+  Gets the pointer to the first variable header in given variable store area.\r
 \r
-  @return VARIABLE_HEADER* pointer to last unavailable Variable Header.\r
+  @param VarStoreHeader  Pointer to the Variable Store Header.\r
+\r
+  @return Pointer to the first variable header\r
 \r
 **/\r
 VARIABLE_HEADER *\r
@@ -137,9 +149,9 @@ NameSizeOfVariable (
   )\r
 {\r
   if (Variable->State    == (UINT8) (-1) ||\r
-      Variable->DataSize == (UINT32) -1 ||\r
-      Variable->NameSize == (UINT32) -1 ||\r
-      Variable->Attributes == (UINT32) -1) {\r
+      Variable->DataSize == (UINT32) (-1) ||\r
+      Variable->NameSize == (UINT32) (-1) ||\r
+      Variable->Attributes == (UINT32) (-1)) {\r
     return 0;\r
   }\r
   return (UINTN) Variable->NameSize;\r
@@ -159,10 +171,10 @@ DataSizeOfVariable (
   IN  VARIABLE_HEADER   *Variable\r
   )\r
 {\r
-  if (Variable->State    == (UINT8)  -1 ||\r
-      Variable->DataSize == (UINT32) -1 ||\r
-      Variable->NameSize == (UINT32) -1 ||\r
-      Variable->Attributes == (UINT32) -1) {\r
+  if (Variable->State    == (UINT8)  (-1) ||\r
+      Variable->DataSize == (UINT32) (-1) ||\r
+      Variable->NameSize == (UINT32) (-1) ||\r
+      Variable->Attributes == (UINT32) (-1)) {\r
     return 0;\r
   }\r
   return (UINTN) Variable->DataSize;\r
@@ -256,7 +268,8 @@ GetVariableStoreStatus (
   IN VARIABLE_STORE_HEADER *VarStoreHeader\r
   )\r
 {\r
-  if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&\r
+       \r
+  if (CompareGuid (&VarStoreHeader->Signature, &gEfiVariableGuid) &&\r
       VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&\r
       VarStoreHeader->State == VARIABLE_STORE_HEALTHY\r
       ) {\r
@@ -264,7 +277,10 @@ GetVariableStoreStatus (
     return EfiValid;\r
   }\r
 \r
-  if (VarStoreHeader->Signature == 0xffffffff &&\r
+  if (((UINT32 *)(&VarStoreHeader->Signature))[0] == 0xffffffff &&\r
+      ((UINT32 *)(&VarStoreHeader->Signature))[1] == 0xffffffff &&\r
+      ((UINT32 *)(&VarStoreHeader->Signature))[2] == 0xffffffff &&\r
+      ((UINT32 *)(&VarStoreHeader->Signature))[3] == 0xffffffff &&\r
       VarStoreHeader->Size == 0xffffffff &&\r
       VarStoreHeader->Format == 0xff &&\r
       VarStoreHeader->State == 0xff\r
@@ -350,21 +366,31 @@ FindVariable (
   EFI_HOB_GUID_TYPE       *GuidHob;\r
   VARIABLE_STORE_HEADER   *VariableStoreHeader;\r
   VARIABLE_HEADER         *Variable;\r
+  VARIABLE_HEADER         *LastVariable;\r
   VARIABLE_HEADER         *MaxIndex;\r
   VARIABLE_INDEX_TABLE    *IndexTable;\r
   UINT32                  Count;\r
+  UINT32                  Offset;\r
   UINT8                   *VariableBase;\r
+  BOOLEAN                 StopRecord;\r
 \r
-  if (VariableName != 0 && VendorGuid == NULL) {\r
+  if (VariableName[0] != 0 && VendorGuid == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   //\r
   // No Variable Address equals zero, so 0 as initial value is safe.\r
   //\r
   MaxIndex = 0;\r
+  StopRecord = FALSE;\r
 \r
   GuidHob = GetFirstGuidHob (&mEfiVariableIndexTableGuid);\r
   if (GuidHob == NULL) {\r
+    //\r
+    // If it's the first time to access variable region in flash, create a guid hob to record\r
+    // VAR_ADDED type variable info.\r
+    // Note that as the resource of PEI phase is limited, only store the number of \r
+    // VARIABLE_INDEX_TABLE_VOLUME of VAR_ADDED type variables to reduce access time.\r
+    //\r
     IndexTable = BuildGuidHob (&mEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE));\r
     IndexTable->Length      = 0;\r
     IndexTable->StartPtr    = NULL;\r
@@ -372,9 +398,14 @@ FindVariable (
     IndexTable->GoneThrough = 0;\r
   } else {\r
     IndexTable = GET_GUID_HOB_DATA (GuidHob);\r
-    for (Count = 0; Count < IndexTable->Length; Count++) {\r
-      MaxIndex = GetVariableByIndex (IndexTable, Count);\r
-\r
+    for (Offset = 0, Count = 0; Count < IndexTable->Length; Count++) {\r
+      //\r
+      // traverse the variable info list to look for varible.\r
+      // The IndexTable->Index[Count] records the distance of two neighbouring VAR_ADDED type variables.\r
+      //\r
+      ASSERT (Count < VARIABLE_INDEX_TABLE_VOLUME);\r
+      Offset   += IndexTable->Index[Count];\r
+      MaxIndex  = (VARIABLE_HEADER *)((CHAR8 *)(IndexTable->StartPtr) + Offset);\r
       if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {\r
         PtrTrack->StartPtr  = IndexTable->StartPtr;\r
         PtrTrack->EndPtr    = IndexTable->EndPtr;\r
@@ -391,7 +422,8 @@ FindVariable (
   // If not found in HOB, then let's start from the MaxIndex we've found.\r
   //\r
   if (MaxIndex != NULL) {\r
-    Variable = GetNextVariablePtr (MaxIndex);\r
+    Variable     = GetNextVariablePtr (MaxIndex);\r
+    LastVariable = MaxIndex;\r
   } else {\r
     if ((IndexTable->StartPtr != NULL) || (IndexTable->EndPtr != NULL)) {\r
       Variable = IndexTable->StartPtr;\r
@@ -419,6 +451,8 @@ FindVariable (
       //\r
       Variable = IndexTable->StartPtr;\r
     }\r
+\r
+    LastVariable = IndexTable->StartPtr;\r
   }\r
   //\r
   // Find the variable by walk through non-volatile variable store\r
@@ -426,13 +460,26 @@ FindVariable (
   PtrTrack->StartPtr  = IndexTable->StartPtr;\r
   PtrTrack->EndPtr    = IndexTable->EndPtr;\r
 \r
-  while (IsValidVariableHeader (Variable) && (Variable <= IndexTable->EndPtr)) {\r
+  while ((Variable < IndexTable->EndPtr) && IsValidVariableHeader (Variable)) {\r
     if (Variable->State == VAR_ADDED) {\r
       //\r
       // Record Variable in VariableIndex HOB\r
       //\r
-      if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) {\r
-        VariableIndexTableUpdate (IndexTable, Variable);\r
+      if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME && StopRecord != TRUE) {\r
+        Offset = (UINT32)((UINTN)Variable - (UINTN)LastVariable);\r
+        //\r
+        // The distance of two neighbouring VAR_ADDED variable is larger than 2^16, \r
+        // which is beyond the allowable scope(UINT16) of record. In such case, need not to\r
+        // record the subsequent VAR_ADDED type variables again.\r
+        //\r
+        if ((Offset & 0xFFFF0000UL) != 0) {\r
+          StopRecord = TRUE;\r
+        }\r
+\r
+        if (StopRecord != TRUE) {\r
+          IndexTable->Index[IndexTable->Length++] = (UINT16) Offset;\r
+        }\r
+        LastVariable = Variable;\r
       }\r
 \r
       if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {\r