]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c
Originally BDS only creates boot options for removable media, the patch creates boot...
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / GenericBdsLib / BdsMisc.c
index 487807b3018f2a394bbdf0c13c91e32d236428cc..cc86908530c18d71c4d3144907da2c2e05f90f1b 100644 (file)
@@ -79,7 +79,7 @@ BdsLibLoadDrivers (
     //\r
     Status = gBS->LoadImage (\r
                     FALSE,\r
-                    mBdsImageHandle,\r
+                    gImageHandle,\r
                     Option->DevicePath,\r
                     NULL,\r
                     0,\r
@@ -499,7 +499,7 @@ BdsLibVariableToOption (
   // Unicode stream to ASCII without any loss in meaning.\r
   //\r
   if (*VariableName == 'B') {\r
-    NumOff = sizeof (L"Boot")/sizeof(CHAR16) -1 ;\r
+    NumOff = (UINT8) (sizeof (L"Boot") / sizeof(CHAR16) - 1);\r
     Option->BootCurrent = (UINT16) ((VariableName[NumOff]  -'0') * 0x1000);\r
     Option->BootCurrent = (UINT16) (Option->BootCurrent + ((VariableName[NumOff+1]-'0') * 0x100));\r
     Option->BootCurrent = (UINT16) (Option->BootCurrent +  ((VariableName[NumOff+2]-'0') * 0x10));\r
@@ -1096,36 +1096,58 @@ BdsLibGetImageHeader (
 }\r
 \r
 /**\r
-\r
-  This routine is a notification function for legayc boot or exit boot\r
-  service event. It will adjust the memory information for different\r
-  memory type and save them into the variables for next boot.\r
-\r
-\r
-  @param Event           The event that triggered this notification function.\r
-  @param Context         Pointer to the notification functions context.\r
-\r
+  This routine adjust the memory information for different memory type and \r
+  save them into the variables for next boot.\r
 **/\r
 VOID\r
-EFIAPI\r
 BdsSetMemoryTypeInformationVariable (\r
-  EFI_EVENT  Event,\r
-  VOID       *Context\r
+  VOID\r
   )\r
 {\r
   EFI_STATUS                   Status;\r
   EFI_MEMORY_TYPE_INFORMATION  *PreviousMemoryTypeInformation;\r
   EFI_MEMORY_TYPE_INFORMATION  *CurrentMemoryTypeInformation;\r
   UINTN                        VariableSize;\r
-  BOOLEAN                      UpdateRequired;\r
   UINTN                        Index;\r
   UINTN                        Index1;\r
   UINT32                       Previous;\r
   UINT32                       Current;\r
   UINT32                       Next;\r
   EFI_HOB_GUID_TYPE            *GuidHob;\r
+  BOOLEAN                      MemoryTypeInformationModified;\r
+  BOOLEAN                      MemoryTypeInformationVariableExists;\r
+  EFI_BOOT_MODE                BootMode;\r
+\r
+  MemoryTypeInformationModified       = FALSE;\r
+  MemoryTypeInformationVariableExists = FALSE;\r
+\r
 \r
-  UpdateRequired = FALSE;\r
+  BootMode = GetBootModeHob ();\r
+  //\r
+  // In BOOT_IN_RECOVERY_MODE, Variable region is not reliable.\r
+  //\r
+  if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Only get the the Memory Type Information variable in the boot mode \r
+  // other than BOOT_WITH_DEFAULT_SETTINGS because the Memory Type\r
+  // Information is not valid in this boot mode.\r
+  //\r
+  if (BootMode != BOOT_WITH_DEFAULT_SETTINGS) {\r
+    VariableSize = 0;\r
+    Status = gRT->GetVariable (\r
+                    EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,\r
+                    &gEfiMemoryTypeInformationGuid,\r
+                    NULL, \r
+                    &VariableSize, \r
+                    NULL\r
+                    );\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+      MemoryTypeInformationVariableExists = TRUE;\r
+    }\r
+  }\r
 \r
   //\r
   // Retrieve the current memory usage statistics.  If they are not found, then\r
@@ -1157,6 +1179,10 @@ BdsSetMemoryTypeInformationVariable (
   //\r
   // Use a heuristic to adjust the Memory Type Information for the next boot\r
   //\r
+  DEBUG ((EFI_D_INFO, "Memory  Previous  Current    Next   \n"));\r
+  DEBUG ((EFI_D_INFO, " Type    Pages     Pages     Pages  \n"));\r
+  DEBUG ((EFI_D_INFO, "======  ========  ========  ========\n"));\r
+\r
   for (Index = 0; PreviousMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {\r
 \r
     Current = 0;\r
@@ -1176,7 +1202,9 @@ BdsSetMemoryTypeInformationVariable (
     //\r
     // Write next varible to 125% * current and Inconsistent Memory Reserved across bootings may lead to S4 fail\r
     //\r
-    if (Current > Previous) {\r
+    if (!MemoryTypeInformationVariableExists && Current < Previous) {\r
+      Next = Current + (Current >> 2);\r
+    } else if (Current > Previous) {\r
       Next = Current + (Current >> 2);\r
     } else {\r
       Next = Previous;\r
@@ -1187,31 +1215,39 @@ BdsSetMemoryTypeInformationVariable (
 \r
     if (Next != Previous) {\r
       PreviousMemoryTypeInformation[Index].NumberOfPages = Next;\r
-      UpdateRequired = TRUE;\r
+      MemoryTypeInformationModified = TRUE;\r
     }\r
 \r
+    DEBUG ((EFI_D_INFO, "  %02x    %08x  %08x  %08x\n", PreviousMemoryTypeInformation[Index].Type, Previous, Current, Next));\r
   }\r
 \r
   //\r
-  // If any changes were made to the Memory Type Information settings, then set the new variable value\r
+  // If any changes were made to the Memory Type Information settings, then set the new variable value;\r
+  // Or create the variable in first boot.\r
   //\r
-  if (UpdateRequired) {\r
+  if (MemoryTypeInformationModified || !MemoryTypeInformationVariableExists) {\r
     Status = gRT->SetVariable (\r
-          EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,\r
-          &gEfiMemoryTypeInformationGuid,\r
-          EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
-          VariableSize,\r
-          PreviousMemoryTypeInformation\r
-          );\r
-  }\r
+                    EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,\r
+                    &gEfiMemoryTypeInformationGuid,\r
+                    EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                    VariableSize,\r
+                    PreviousMemoryTypeInformation\r
+                    );\r
 \r
-  return;\r
+    //\r
+    // If the Memory Type Information settings have been modified, then reset the platform\r
+    // so the new Memory Type Information setting will be used to guarantee that an S4\r
+    // entry/resume cycle will not fail.\r
+    //\r
+    if (MemoryTypeInformationModified && PcdGetBool (PcdResetOnMemoryTypeInformationChange)) {\r
+      DEBUG ((EFI_D_INFO, "Memory Type Information settings change. Warm Reset!!!\n"));\r
+      gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
+    }\r
+  }\r
 }\r
 \r
 /**\r
-  This routine register a function to adjust the different type memory page number\r
-  just before booting and save the updated info into the variable for next boot to use.\r
-\r
+  This routine is kept for backward compatibility.\r
 **/\r
 VOID\r
 EFIAPI\r
@@ -1219,19 +1255,6 @@ BdsLibSaveMemoryTypeInformation (
   VOID\r
   )\r
 {\r
-  EFI_STATUS                   Status;\r
-  EFI_EVENT                    ReadyToBootEvent;\r
-\r
-  Status = EfiCreateEventReadyToBootEx (\r
-           TPL_CALLBACK,\r
-           BdsSetMemoryTypeInformationVariable,\r
-           NULL,\r
-           &ReadyToBootEvent\r
-           );\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((DEBUG_ERROR,"Bds Set Memory Type Informationa Variable Fails\n"));\r
-  }\r
-\r
 }\r
 \r
 \r