]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
variable driver doesn't support EFI_AUTHENTICATED_WRITE_ACCESS. we use:
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / RuntimeDxe / Variable.c
index 611d1904ec968b44a53719feac9f470d4f0ac363..7edb2e5daa1fe1f73a1a72788cf1779aa758877f 100644 (file)
@@ -3,7 +3,7 @@
   Implement all four UEFI Runtime Variable services for the nonvolatile\r
   and volatile storage space and install variable architecture protocol.\r
   \r
-Copyright (c) 2006 - 2009, Intel Corporation                                                         \r
+Copyright (c) 2006 - 2010, 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
@@ -176,7 +176,7 @@ UpdateVariableInfo (
       ASSERT (gVariableInfo != NULL);\r
 \r
       CopyGuid (&gVariableInfo->VendorGuid, VendorGuid);\r
-      gVariableInfo->Name = AllocatePool (StrLen (VariableName));\r
+      gVariableInfo->Name = AllocatePool (StrSize (VariableName));\r
       ASSERT (gVariableInfo->Name != NULL);\r
       StrCpy (gVariableInfo->Name, VariableName);\r
       gVariableInfo->Volatile = Volatile;\r
@@ -214,7 +214,7 @@ UpdateVariableInfo (
         ASSERT (Entry->Next != NULL);\r
 \r
         CopyGuid (&Entry->Next->VendorGuid, VendorGuid);\r
-        Entry->Next->Name = AllocatePool (StrLen (VariableName));\r
+        Entry->Next->Name = AllocatePool (StrSize (VariableName));\r
         ASSERT (Entry->Next->Name != NULL);\r
         StrCpy (Entry->Next->Name, VariableName);\r
         Entry->Next->Volatile = Volatile;\r
@@ -1052,9 +1052,9 @@ FindVariable (
   Get index from supported language codes according to language string.\r
 \r
   This code is used to get corresponding index in supported language codes. It can handle\r
-  RFC3066 and ISO639 language tags.\r
+  RFC4646 and ISO639 language tags.\r
   In ISO639 language tags, take 3-characters as a delimitation to find matched string and calculate the index.\r
-  In RFC3066 language tags, take semicolon as a delimitation to find matched string and calculate the index.\r
+  In RFC4646 language tags, take semicolon as a delimitation to find matched string and calculate the index.\r
 \r
   For example:\r
     SupportedLang  = "engfraengfra"\r
@@ -1069,7 +1069,7 @@ FindVariable (
 \r
   @param  SupportedLang               Platform supported language codes.\r
   @param  Lang                        Configured language.\r
-  @param  Iso639Language              A bool value to signify if the handler is operated on ISO639 or RFC3066.\r
+  @param  Iso639Language              A bool value to signify if the handler is operated on ISO639 or RFC4646.\r
 \r
   @retval the index of language in the language codes.\r
 \r
@@ -1103,7 +1103,7 @@ GetIndexFromSupportedLangCodes(
     return 0;\r
   } else {\r
     //\r
-    // Compare RFC3066 language code\r
+    // Compare RFC4646 language code\r
     //\r
     while (*Supported != '\0') {\r
       //\r
@@ -1129,9 +1129,9 @@ GetIndexFromSupportedLangCodes(
   Get language string from supported language codes according to index.\r
 \r
   This code is used to get corresponding language string in supported language codes. It can handle\r
-  RFC3066 and ISO639 language tags.\r
+  RFC4646 and ISO639 language tags.\r
   In ISO639 language tags, take 3-characters as a delimitation. Find language string according to the index.\r
-  In RFC3066 language tags, take semicolon as a delimitation. Find language string according to the index.\r
+  In RFC4646 language tags, take semicolon as a delimitation. Find language string according to the index.\r
 \r
   For example:\r
     SupportedLang  = "engfraengfra"\r
@@ -1146,7 +1146,7 @@ GetIndexFromSupportedLangCodes(
 \r
   @param  SupportedLang               Platform supported language codes.\r
   @param  Index                       the index in supported language codes.\r
-  @param  Iso639Language              A bool value to signify if the handler is operated on ISO639 or RFC3066.\r
+  @param  Iso639Language              A bool value to signify if the handler is operated on ISO639 or RFC4646.\r
 \r
   @retval the language string in the language codes.\r
 \r
@@ -1254,13 +1254,13 @@ AutoUpdateLangVariable(
     // Therefore, in variable driver, only store the original value for other use.\r
     //\r
     AsciiStrnCpy (mVariableModuleGlobal->LangCodes, Data, DataSize);\r
-  } else if (StrCmp (VariableName, L"PlatformLang") == 0) {\r
+  } else if ((StrCmp (VariableName, L"PlatformLang") == 0) && (DataSize != 0)) {\r
     ASSERT (AsciiStrLen (mVariableModuleGlobal->PlatformLangCodes) != 0);\r
 \r
     //\r
     // When setting PlatformLang, firstly get most matched language string from supported language codes.\r
     //\r
-    BestPlatformLang = GetBestLanguage(mVariableModuleGlobal->PlatformLangCodes, FALSE, Data);\r
+    BestPlatformLang = GetBestLanguage(mVariableModuleGlobal->PlatformLangCodes, FALSE, Data, NULL);\r
 \r
     //\r
     // Get the corresponding index in language codes.\r
@@ -1268,7 +1268,7 @@ AutoUpdateLangVariable(
     Index = GetIndexFromSupportedLangCodes(mVariableModuleGlobal->PlatformLangCodes, BestPlatformLang, FALSE);\r
 \r
     //\r
-    // Get the corresponding ISO639 language tag according to RFC3066 language tag.\r
+    // Get the corresponding ISO639 language tag according to RFC4646 language tag.\r
     //\r
     BestLang = GetLangFromSupportedLangCodes(mVariableModuleGlobal->LangCodes, Index, TRUE);\r
 \r
@@ -1284,13 +1284,13 @@ AutoUpdateLangVariable(
 \r
     ASSERT_EFI_ERROR(Status);\r
     \r
-  } else if (StrCmp (VariableName, L"Lang") == 0) {\r
+  } else if ((StrCmp (VariableName, L"Lang") == 0) && (DataSize != 0)) {\r
     ASSERT (AsciiStrLen (mVariableModuleGlobal->LangCodes) != 0);\r
 \r
     //\r
     // When setting Lang, firstly get most matched language string from supported language codes.\r
     //\r
-    BestLang = GetBestLanguage(mVariableModuleGlobal->LangCodes, TRUE, Data);\r
+    BestLang = GetBestLanguage(mVariableModuleGlobal->LangCodes, TRUE, Data, NULL);\r
 \r
     //\r
     // Get the corresponding index in language codes.\r
@@ -1298,7 +1298,7 @@ AutoUpdateLangVariable(
     Index = GetIndexFromSupportedLangCodes(mVariableModuleGlobal->LangCodes, BestLang, TRUE);\r
 \r
     //\r
-    // Get the corresponding RFC3066 language tag according to ISO639 language tag.\r
+    // Get the corresponding RFC4646 language tag according to ISO639 language tag.\r
     //\r
     BestPlatformLang = GetLangFromSupportedLangCodes(mVariableModuleGlobal->PlatformLangCodes, Index, FALSE);\r
 \r
@@ -1308,7 +1308,7 @@ AutoUpdateLangVariable(
     FindVariable(L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, (VARIABLE_GLOBAL *)mVariableModuleGlobal);\r
 \r
     Status = UpdateVariable(L"PlatformLang", &gEfiGlobalVariableGuid, \r
-                    BestPlatformLang, AsciiStrLen (BestPlatformLang), Attributes, &Variable);\r
+                    BestPlatformLang, AsciiStrSize (BestPlatformLang), Attributes, &Variable);\r
 \r
     DEBUG((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a\n", BestLang, BestPlatformLang));\r
     ASSERT_EFI_ERROR(Status);\r
@@ -1475,7 +1475,7 @@ UpdateVariable (
   // as a temporary storage.\r
   //\r
   NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase));\r
-  ScratchSize = MAX(FixedPcdGet32(PcdMaxVariableSize), FixedPcdGet32(PcdMaxHardwareErrorVariableSize));\r
+  ScratchSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize));\r
 \r
   SetMem (NextVariable, ScratchSize, 0xff);\r
 \r
@@ -1519,9 +1519,9 @@ UpdateVariable (
     Volatile = FALSE;\r
     NonVolatileVarableStoreSize = ((VARIABLE_STORE_HEADER *)(UINTN)(mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase))->Size;\r
     if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) \r
-      && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > FixedPcdGet32(PcdHwErrStorageSize)))\r
+      && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize)))\r
       || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0) \r
-      && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - FixedPcdGet32(PcdHwErrStorageSize)))) {\r
+      && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize)))) {\r
       if (EfiAtRuntime ()) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
@@ -1538,9 +1538,9 @@ UpdateVariable (
       // If still no enough space, return out of resources\r
       //\r
       if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) \r
-        && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > FixedPcdGet32(PcdHwErrStorageSize)))\r
+        && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize)))\r
         || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0) \r
-        && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - FixedPcdGet32(PcdHwErrStorageSize)))) {\r
+        && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize)))) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
       }\r
@@ -1928,7 +1928,19 @@ RuntimeServiceSetVariable (
   //\r
   if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
-  }  \r
+  }\r
+\r
+  if (DataSize != 0 && Data == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Not support authenticated variable write yet.\r
+  //\r
+  if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   //\r
   //  Make sure if runtime bit is set, boot service bit is set also\r
   //\r
@@ -1938,12 +1950,12 @@ RuntimeServiceSetVariable (
 \r
   //\r
   //  The size of the VariableName, including the Unicode Null in bytes plus\r
-  //  the DataSize is limited to maximum size of FixedPcdGet32(PcdMaxHardwareErrorVariableSize)\r
-  //  bytes for HwErrRec, and FixedPcdGet32(PcdMaxVariableSize) bytes for the others.\r
+  //  the DataSize is limited to maximum size of PcdGet32 (PcdMaxHardwareErrorVariableSize)\r
+  //  bytes for HwErrRec, and PcdGet32 (PcdMaxVariableSize) bytes for the others.\r
   //\r
   if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
-    if ((DataSize > FixedPcdGet32(PcdMaxHardwareErrorVariableSize)) ||\r
-        (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > FixedPcdGet32(PcdMaxHardwareErrorVariableSize))) {\r
+    if ((DataSize > PcdGet32 (PcdMaxHardwareErrorVariableSize)) ||\r
+        (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > PcdGet32 (PcdMaxHardwareErrorVariableSize))) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
     //\r
@@ -1955,10 +1967,10 @@ RuntimeServiceSetVariable (
   } else {\r
     //\r
     //  The size of the VariableName, including the Unicode Null in bytes plus\r
-    //  the DataSize is limited to maximum size of FixedPcdGet32(PcdMaxVariableSize) bytes.\r
+    //  the DataSize is limited to maximum size of PcdGet32 (PcdMaxVariableSize) bytes.\r
     //\r
-    if ((DataSize > FixedPcdGet32(PcdMaxVariableSize)) ||\r
-        (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > FixedPcdGet32(PcdMaxVariableSize))) {\r
+    if ((DataSize > PcdGet32 (PcdMaxVariableSize)) ||\r
+        (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > PcdGet32 (PcdMaxVariableSize))) {\r
       return EFI_INVALID_PARAMETER;\r
     }  \r
   }  \r
@@ -2060,6 +2072,11 @@ RuntimeServiceQueryVariableInfo (
     // Make sure Hw Attribute is set with NV.\r
     //\r
     return EFI_INVALID_PARAMETER;\r
+  } else if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+    //\r
+    // Not support authentiated variable write yet.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
   }\r
 \r
   AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
@@ -2086,18 +2103,18 @@ RuntimeServiceQueryVariableInfo (
   // Harware error record variable needs larger size.\r
   //\r
   if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {\r
-    *MaximumVariableStorageSize = FixedPcdGet32(PcdHwErrStorageSize);\r
-    *MaximumVariableSize = FixedPcdGet32(PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER);\r
+    *MaximumVariableStorageSize = PcdGet32 (PcdHwErrStorageSize);\r
+    *MaximumVariableSize = PcdGet32 (PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER);\r
   } else {\r
     if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
-      ASSERT (FixedPcdGet32(PcdHwErrStorageSize) < VariableStoreHeader->Size);\r
-      *MaximumVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - FixedPcdGet32(PcdHwErrStorageSize);\r
+      ASSERT (PcdGet32 (PcdHwErrStorageSize) < VariableStoreHeader->Size);\r
+      *MaximumVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize);\r
     }\r
 \r
     //\r
-    // Let *MaximumVariableSize be FixedPcdGet32(PcdMaxVariableSize) with the exception of the variable header size.\r
+    // Let *MaximumVariableSize be PcdGet32 (PcdMaxVariableSize) with the exception of the variable header size.\r
     //\r
-    *MaximumVariableSize = FixedPcdGet32(PcdMaxVariableSize) - sizeof (VARIABLE_HEADER);\r
+    *MaximumVariableSize = PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER);\r
   }\r
 \r
   //\r
@@ -2179,7 +2196,7 @@ ReclaimForOS(
   VOID       *Context\r
   )\r
 {\r
-  EFI_STATUS                      Status;\r
+  EFI_STATUS                     Status;\r
   UINTN                          CommonVariableSpace;\r
   UINTN                          RemainingCommonVariableSpace;\r
   UINTN                          RemainingHwErrVariableSpace;\r
@@ -2192,10 +2209,11 @@ ReclaimForOS(
 \r
   RemainingHwErrVariableSpace = PcdGet32 (PcdHwErrStorageSize) - mVariableModuleGlobal->HwErrVariableTotalSize;\r
   //\r
-  // Check if the free area is blow a threshold\r
+  // Check if the free area is blow a threshold.\r
   //\r
   if ((RemainingCommonVariableSpace < PcdGet32 (PcdMaxVariableSize))\r
-    || (RemainingHwErrVariableSpace < PcdGet32 (PcdMaxHardwareErrorVariableSize))){\r
+    || ((PcdGet32 (PcdHwErrStorageSize) != 0) && \r
+       (RemainingHwErrVariableSpace < PcdGet32 (PcdMaxHardwareErrorVariableSize)))){\r
     Status = Reclaim (\r
             mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,\r
             &mVariableModuleGlobal->NonVolatileLastVariableOffset,\r
@@ -2209,7 +2227,7 @@ ReclaimForOS(
 /**\r
   Initializes variable store area for non-volatile and volatile variable.\r
 \r
-  @param  SystemTable           The pointer of EFI_SYSTEM_TABLE.\r
+  @param  FvbProtocol           Pointer to an instance of EFI Firmware Volume Block Protocol.\r
 \r
   @retval EFI_SUCCESS           Function successfully executed.\r
   @retval EFI_OUT_OF_RESOURCES  Fail to allocate enough memory resource.\r
@@ -2234,6 +2252,7 @@ VariableCommonInitialize (
   UINT64                          VariableStoreLength;\r
   EFI_EVENT                       ReadyToBootEvent;\r
   UINTN                           ScratchSize;\r
+  UINTN                           VariableSize;\r
 \r
   Status = EFI_SUCCESS;\r
   //\r
@@ -2246,17 +2265,25 @@ VariableCommonInitialize (
 \r
   EfiInitializeLock(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock, TPL_NOTIFY);\r
 \r
+  //\r
+  // Note that in EdkII variable driver implementation, Hardware Error Record type variable\r
+  // is stored with common variable in the same NV region. So the platform integrator should\r
+  // ensure that the value of PcdHwErrStorageSize is less than or equal to the value of \r
+  // PcdFlashNvStorageVariableSize.\r
+  //\r
+  ASSERT (PcdGet32 (PcdHwErrStorageSize) <= PcdGet32 (PcdFlashNvStorageVariableSize));\r
+\r
   //\r
   // Allocate memory for volatile variable store, note that there is a scratch space to store scratch data.\r
   //\r
-  ScratchSize = MAX(FixedPcdGet32(PcdMaxVariableSize), FixedPcdGet32(PcdMaxHardwareErrorVariableSize));\r
-  VolatileVariableStore = AllocateRuntimePool (FixedPcdGet32(PcdVariableStoreSize) + ScratchSize);\r
+  ScratchSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize));\r
+  VolatileVariableStore = AllocateRuntimePool (PcdGet32 (PcdVariableStoreSize) + ScratchSize);\r
   if (VolatileVariableStore == NULL) {\r
     FreePool (mVariableModuleGlobal);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  SetMem (VolatileVariableStore, FixedPcdGet32(PcdVariableStoreSize) + ScratchSize, 0xff);\r
+  SetMem (VolatileVariableStore, PcdGet32 (PcdVariableStoreSize) + ScratchSize, 0xff);\r
 \r
   //\r
   //  Variable Specific Data\r
@@ -2266,7 +2293,7 @@ VariableCommonInitialize (
   mVariableModuleGlobal->FvbInstance = FvbProtocol;\r
 \r
   CopyGuid (&VolatileVariableStore->Signature, &gEfiVariableGuid);\r
-  VolatileVariableStore->Size                       = FixedPcdGet32(PcdVariableStoreSize);\r
+  VolatileVariableStore->Size                       = PcdGet32 (PcdVariableStoreSize);\r
   VolatileVariableStore->Format                     = VARIABLE_STORE_FORMATTED;\r
   VolatileVariableStore->State                      = VARIABLE_STORE_HEALTHY;\r
   VolatileVariableStore->Reserved                   = 0;\r
@@ -2339,7 +2366,6 @@ VariableCommonInitialize (
     Status        = EFI_SUCCESS;\r
 \r
     while (IsValidVariableHeader (NextVariable)) {\r
-      UINTN VariableSize = 0;\r
       VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER);\r
       if ((NextVariable->Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {\r
         mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize);\r
@@ -2435,6 +2461,14 @@ VariableClassAddressChangeEvent (
   EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);\r
 }\r
 \r
+/**\r
+  Firmware Volume Block Protocol notification event handler.\r
+\r
+  Discover NV Variable Store and install Variable Arch Protocol.\r
+\r
+  @param[in] Event    Event whose notification function is being invoked.\r
+  @param[in] Context  Pointer to the notification function's context.\r
+**/\r
 VOID\r
 EFIAPI\r
 FvbNotificationEvent (\r