]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c
Add PciBus Module
[mirror_edk2.git] / EdkNt32Pkg / Library / EdkGenericBdsLib / BdsMisc.c
index 576ae7237f721dd065cb7d383d1ef3d4da21ac55..b8be94e74ddde08f9121b9b3bc4b84281d921bca 100644 (file)
@@ -1,13 +1,13 @@
 /*++\r
 \r
-Copyright (c) 2006, 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
@@ -19,6 +19,9 @@ Abstract:
 \r
 --*/\r
 \r
+#define MAX_STRING_LEN        200\r
+static BOOLEAN   mFeaturerSwitch = TRUE;\r
+static BOOLEAN   mResetRequired  = FALSE;\r
 extern UINT16 gPlatformBootTimeOutDefault;\r
 \r
 UINT16\r
@@ -28,7 +31,7 @@ BdsLibGetTimeout (
 /*++\r
 \r
 Routine Description:\r
-  \r
+\r
   Return the default value for system Timeout variable.\r
 \r
 Arguments:\r
@@ -36,7 +39,7 @@ Arguments:
   None\r
 \r
 Returns:\r
-  \r
+\r
   Timeout value.\r
 \r
 --*/\r
@@ -82,7 +85,7 @@ BdsLibLoadDrivers (
 /*++\r
 \r
 Routine Description:\r
-  \r
+\r
   The function will go through the driver optoin link list, load and start\r
   every driver the driver optoin device path point to.\r
 \r
@@ -91,7 +94,7 @@ Arguments:
   BdsDriverLists   - The header of the current driver option link list\r
 \r
 Returns:\r
-  \r
+\r
   None\r
 \r
 --*/\r
@@ -195,7 +198,7 @@ BdsLibRegisterNewOption (
 /*++\r
 \r
 Routine Description:\r
-  \r
+\r
   This function will register the new boot#### or driver#### option base on\r
   the VariableName. The new registered boot#### or driver#### will be linked\r
   to BdsOptionList and also update to the VariableName. After the boot#### or\r
@@ -204,18 +207,18 @@ Routine Description:
 Arguments:\r
 \r
   BdsOptionList    - The header of the boot#### or driver#### link list\r
-  \r
+\r
   DevicePath       - The device path which the boot####\r
                      or driver#### option present\r
-                     \r
+\r
   String           - The description of the boot#### or driver####\r
-  \r
+\r
   VariableName     - Indicate if the boot#### or driver#### option\r
 \r
 Returns:\r
-  \r
+\r
   EFI_SUCCESS      - The boot#### or driver#### have been success registered\r
-  \r
+\r
   EFI_STATUS       - Return the status of gRT->SetVariable ().\r
 \r
 --*/\r
@@ -246,11 +249,13 @@ Returns:
   ZeroMem (OptionName, sizeof (OptionName));\r
 \r
   TempOptionSize = 0;\r
+\r
   TempOptionPtr = BdsLibGetVariableAndSize (\r
                     VariableName,\r
                     &gEfiGlobalVariableGuid,\r
                     &TempOptionSize\r
                     );\r
+\r
   //\r
   // Compare with current option variable\r
   //\r
@@ -287,8 +292,8 @@ Returns:
         //\r
         // Got the option, so just return\r
         //\r
-        gBS->FreePool (OptionPtr);\r
-        gBS->FreePool (TempOptionPtr);\r
+        FreePool (OptionPtr);\r
+        FreePool (TempOptionPtr);\r
         return EFI_SUCCESS;\r
       } else {\r
         //\r
@@ -299,7 +304,7 @@ Returns:
       }\r
     }\r
 \r
-    gBS->FreePool (OptionPtr);\r
+    FreePool (OptionPtr);\r
   }\r
 \r
   OptionSize          = sizeof (UINT32) + sizeof (UINT16) + StrSize (String) + GetDevicePathSize (DevicePath);\r
@@ -339,12 +344,12 @@ Returns:
                   OptionPtr\r
                   );\r
   if (EFI_ERROR (Status) || UpdateBootDevicePath) {\r
-    gBS->FreePool (OptionPtr);\r
-    gBS->FreePool (TempOptionPtr);\r
+    FreePool (OptionPtr);\r
+    FreePool (TempOptionPtr);\r
     return Status;\r
   }\r
 \r
-  gBS->FreePool (OptionPtr);\r
+  FreePool (OptionPtr);\r
 \r
   //\r
   // Update the option order variable\r
@@ -360,13 +365,15 @@ Returns:
                   OptionOrderPtr\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    gBS->FreePool (TempOptionPtr);\r
-    gBS->FreePool (OptionOrderPtr);\r
+    FreePool (TempOptionPtr);\r
+    FreePool (OptionOrderPtr);\r
     return Status;\r
   }\r
 \r
-  gBS->FreePool (TempOptionPtr);\r
-  gBS->FreePool (OptionOrderPtr);\r
+  if (TempOptionPtr != NULL) {\r
+    FreePool (TempOptionPtr);\r
+  }\r
+  FreePool (OptionOrderPtr);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -380,9 +387,9 @@ BdsLibVariableToOption (
 \r
 Routine Description:\r
 \r
-  Build the boot#### or driver#### option from the VariableName, the \r
+  Build the boot#### or driver#### option from the VariableName, the\r
   build boot#### or driver#### will also be linked to BdsCommonOptionList\r
-  \r
+\r
 Arguments:\r
 \r
   BdsCommonOptionList - The header of the boot#### or driver#### option link list\r
@@ -479,12 +486,12 @@ Returns:
   //\r
   if ((Option->Attribute & LOAD_OPTION_ACTIVE) == LOAD_OPTION_ACTIVE) {\r
     InsertTailList (BdsCommonOptionList, &Option->Link);\r
-    gBS->FreePool (Variable);\r
+    FreePool (Variable);\r
     return Option;\r
   }\r
 \r
-  gBS->FreePool (Variable);\r
-  gBS->FreePool (Option);\r
+  FreePool (Variable);\r
+  FreePool (Option);\r
   return NULL;\r
 \r
 }\r
@@ -550,38 +557,7 @@ Returns:
 \r
   }\r
 \r
-  gBS->FreePool (OptionOrder);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-BdsLibGetBootMode (\r
-  OUT EFI_BOOT_MODE       *BootMode\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Get boot mode by looking up configuration table and parsing HOB list\r
-\r
-Arguments:\r
-\r
-  BootMode - Boot mode from PEI handoff HOB.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS - Successfully get boot mode\r
-  \r
-  EFI_NOT_FOUND - Can not find the current system boot mode\r
-\r
---*/\r
-{\r
-  EFI_HOB_HANDOFF_INFO_TABLE        *HobList;\r
-\r
-  HobList = GetHobList ();\r
-  ASSERT (HobList->Header.HobType == EFI_HOB_TYPE_HANDOFF);\r
-  *BootMode = HobList->BootMode;\r
+  FreePool (OptionOrder);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -648,6 +624,95 @@ Returns:
   return Buffer;\r
 }\r
 \r
+VOID\r
+BdsLibSafeFreePool (\r
+  IN  VOID             *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Free pool safely.\r
+\r
+Arguments:\r
+\r
+  Buffer          - The allocated pool entry to free\r
+\r
+Returns:\r
+\r
+  Pointer of the buffer allocated.\r
+\r
+--*/\r
+{\r
+  if (Buffer != NULL) {\r
+    FreePool (Buffer);\r
+    Buffer = NULL;\r
+  }\r
+}\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+BdsLibDelPartMatchInstance (\r
+  IN     EFI_DEVICE_PATH_PROTOCOL  *Multi,\r
+  IN     EFI_DEVICE_PATH_PROTOCOL  *Single\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Delete the instance in Multi which matches partly with Single instance\r
+\r
+Arguments:\r
+\r
+  Multi        - A pointer to a multi-instance device path data structure.\r
+\r
+  Single       - A pointer to a single-instance device path data structure.\r
+\r
+Returns:\r
+\r
+  This function will remove the device path instances in Multi which partly\r
+  match with the Single, and return the result device path. If there is no\r
+  remaining device path as a result, this function will return NULL.\r
+\r
+--*/\r
+{\r
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;\r
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *TempNewDevicePath;\r
+  UINTN                     InstanceSize;\r
+  UINTN                     SingleDpSize;\r
+  UINTN                     Size;\r
+\r
+  NewDevicePath     = NULL;\r
+  TempNewDevicePath = NULL;\r
+\r
+  if (Multi == NULL || Single == NULL) {\r
+    return Multi;\r
+  }\r
+\r
+  Instance        =  GetNextDevicePathInstance (&Multi, &InstanceSize);\r
+  SingleDpSize    =  GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH;\r
+  InstanceSize    -= END_DEVICE_PATH_LENGTH;\r
+\r
+  while (Instance != NULL) {\r
+\r
+    Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize;\r
+\r
+    if ((CompareMem (Instance, Single, Size) != 0)) {\r
+      //\r
+      // Append the device path instance which does not match with Single\r
+      //\r
+      TempNewDevicePath = NewDevicePath;\r
+      NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);\r
+      BdsLibSafeFreePool(TempNewDevicePath);\r
+    }\r
+    BdsLibSafeFreePool(Instance);\r
+    Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);\r
+    InstanceSize  -= END_DEVICE_PATH_LENGTH;\r
+  }\r
+\r
+  return NewDevicePath;\r
+}\r
+\r
 BOOLEAN\r
 BdsLibMatchDevicePaths (\r
   IN  EFI_DEVICE_PATH_PROTOCOL  *Multi,\r
@@ -669,9 +734,9 @@ Arguments:
 Returns:\r
 \r
   TRUE   - If the Single is contained within Multi\r
-  \r
+\r
   FALSE  - The Single is not match within Multi\r
-  \r
+\r
 \r
 --*/\r
 {\r
@@ -685,7 +750,6 @@ Returns:
 \r
   DevicePath      = Multi;\r
   DevicePathInst  = GetNextDevicePathInstance (&DevicePath, &Size);\r
-  Size -= sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
 \r
   //\r
   // Search for the match of 'Single' in 'Multi'\r
@@ -695,17 +759,13 @@ Returns:
     // If the single device path is found in multiple device paths,\r
     // return success\r
     //\r
-    if (Size == 0) {\r
-      return FALSE;\r
-    }\r
-\r
     if (CompareMem (Single, DevicePathInst, Size) == 0) {\r
+      FreePool (DevicePathInst);\r
       return TRUE;\r
     }\r
 \r
-    gBS->FreePool (DevicePathInst);\r
+    FreePool (DevicePathInst);\r
     DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);\r
-    Size -= sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
   }\r
 \r
   return FALSE;\r
@@ -732,7 +792,7 @@ Arguments:
 Returns:\r
 \r
   EFI_SUCCESS          - Success print out the string using ConOut.\r
-  \r
+\r
   EFI_STATUS           - Return the status of the ConOut->OutputString ().\r
 \r
 --*/\r
@@ -762,3 +822,273 @@ Returns:
 \r
   return Status;\r
 }\r
+\r
+//\r
+//  Following are BDS Lib functions which  contain all the code about setup browser reset reminder feature.\r
+//  Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser  if\r
+//  user change any option setting which needs a reset to be effective, and  the reset will be applied according to  the user selection.\r
+//\r
+\r
+VOID\r
+EnableResetReminderFeature (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Enable the setup browser reset reminder feature.\r
+  This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it.\r
+\r
+Arguments:\r
+\r
+  VOID\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  mFeaturerSwitch = TRUE;\r
+}\r
+\r
+VOID\r
+DisableResetReminderFeature (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Disable the setup browser reset reminder feature.\r
+  This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it.\r
+\r
+Arguments:\r
+\r
+  VOID\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  mFeaturerSwitch = FALSE;\r
+}\r
+\r
+VOID\r
+EnableResetRequired (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+   Record the info that  a reset is required.\r
+   A  module boolean variable is used to record whether a reset is required.\r
+\r
+Arguments:\r
+\r
+  VOID\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  mResetRequired = TRUE;\r
+}\r
+\r
+VOID\r
+DisableResetRequired (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+   Record the info that  no reset is required.\r
+   A  module boolean variable is used to record whether a reset is required.\r
+\r
+Arguments:\r
+\r
+  VOID\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  mResetRequired = FALSE;\r
+}\r
+\r
+BOOLEAN\r
+IsResetReminderFeatureEnable (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check whether platform policy enable the reset reminder feature. The default is enabled.\r
+\r
+Arguments:\r
+\r
+  VOID\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  return mFeaturerSwitch;\r
+}\r
+\r
+BOOLEAN\r
+IsResetRequired (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check if  user changed any option setting which needs a system reset to be effective.\r
+\r
+Arguments:\r
+\r
+  VOID\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  return mResetRequired;\r
+}\r
+\r
+VOID\r
+SetupResetReminder (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check whether a reset is needed, and finish the reset reminder feature.\r
+  If a reset is needed, Popup a menu to notice user, and finish the feature\r
+  according to the user selection.\r
+\r
+Arguments:\r
+\r
+  VOID\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_FORM_BROWSER_PROTOCOL     *Browser;\r
+  EFI_INPUT_KEY                 Key;\r
+  CHAR16                        *StringBuffer1;\r
+  CHAR16                        *StringBuffer2;\r
+\r
+\r
+  //\r
+  //check any reset required change is applied? if yes, reset system\r
+  //\r
+  if (IsResetReminderFeatureEnable ()) {\r
+    if (IsResetRequired ()) {\r
+\r
+      Status = gBS->LocateProtocol (\r
+                      &gEfiFormBrowserProtocolGuid,\r
+                      NULL,\r
+                      &Browser\r
+                      );\r
+\r
+      ASSERT (Status != EFI_SUCCESS);\r
+\r
+      StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));\r
+      ASSERT (StringBuffer1 != NULL);\r
+      StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));\r
+      ASSERT (StringBuffer2 != NULL);\r
+      StrCpy (StringBuffer1, L"Configuration changed. Reset to apply it Now ? ");\r
+      StrCpy (StringBuffer2, L"Enter (YES)  /   Esc (NO)");\r
+      //\r
+      // Popup a menu to notice user\r
+      //\r
+      do {\r
+        Browser->CreatePopUp (2, TRUE, 0, NULL, &Key, StringBuffer1, StringBuffer2);\r
+      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
+\r
+      FreePool (StringBuffer1);\r
+      FreePool (StringBuffer2);\r
+      //\r
+      // If the user hits the YES Response key, reset\r
+      //\r
+      if ((Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) {\r
+        gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
+      }\r
+      gST->ConOut->ClearScreen (gST->ConOut);\r
+    }\r
+  }\r
+}\r
+\r
+EFI_STATUS\r
+BdsLibGetHiiHandles (\r
+  IN     EFI_HII_PROTOCOL *Hii,\r
+  IN OUT UINT16           *HandleBufferLength,\r
+  OUT    EFI_HII_HANDLE   **HiiHandleBuffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Determines the handles that are currently active in the database.\r
+  It's the caller's responsibility to free handle buffer.\r
+\r
+Arguments:\r
+\r
+  This                  - A pointer to the EFI_HII_PROTOCOL instance.\r
+  HandleBufferLength    - On input, a pointer to the length of the handle buffer. On output,\r
+                          the length of the handle buffer that is required for the handles found.\r
+  HiiHandleBuffer       - Pointer to an array of EFI_HII_PROTOCOL instances returned.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - Get an array of EFI_HII_PROTOCOL instances successfully.\r
+  EFI_INVALID_PARAMETER - Hii is NULL.\r
+  EFI_NOT_FOUND         - Database not found.\r
+\r
+--*/\r
+{\r
+  UINT16      TempBufferLength;\r
+  EFI_STATUS  Status;\r
+\r
+  TempBufferLength = 0;\r
+\r
+  //\r
+  // Try to find the actual buffer size for HiiHandle Buffer.\r
+  //\r
+  Status = Hii->FindHandles (Hii, &TempBufferLength, *HiiHandleBuffer);\r
+\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    *HiiHandleBuffer = AllocateZeroPool (TempBufferLength);\r
+    Status = Hii->FindHandles (Hii, &TempBufferLength, *HiiHandleBuffer);\r
+    //\r
+    // we should not fail here.\r
+    //\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  *HandleBufferLength = TempBufferLength;\r
+\r
+  return Status;\r
+\r
+}\r