+++ /dev/null
-/*++\r
-\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
- BdsMisc.c\r
-\r
-Abstract:\r
-\r
- Misc BDS library function\r
-\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
-BdsLibGetTimeout (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- \r
- Return the default value for system Timeout variable.\r
-\r
-Arguments:\r
-\r
- None\r
-\r
-Returns:\r
- \r
- Timeout value.\r
-\r
---*/\r
-{\r
- UINT16 Timeout;\r
- UINTN Size;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Return Timeout variable or 0xffff if no valid\r
- // Timeout variable exists.\r
- //\r
- Size = sizeof (UINT16);\r
- Status = gRT->GetVariable (L"Timeout", &gEfiGlobalVariableGuid, NULL, &Size, &Timeout);\r
- if (!EFI_ERROR (Status)) {\r
- return Timeout;\r
- }\r
- //\r
- // To make the current EFI Automatic-Test activity possible, just add\r
- // following code to make AutoBoot enabled when this variable is not\r
- // present.\r
- // This code should be removed later.\r
- //\r
- Timeout = gPlatformBootTimeOutDefault;\r
-\r
- //\r
- // Notes: Platform should set default variable if non exists on all error cases!!!\r
- //\r
- Status = gRT->SetVariable (\r
- L"Timeout",\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- sizeof (UINT16),\r
- &Timeout\r
- );\r
- return Timeout;\r
-}\r
-\r
-VOID\r
-BdsLibLoadDrivers (\r
- IN LIST_ENTRY *BdsDriverLists\r
- )\r
-/*++\r
-\r
-Routine Description:\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
-Arguments:\r
-\r
- BdsDriverLists - The header of the current driver option link list\r
-\r
-Returns:\r
- \r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *Link;\r
- BDS_COMMON_OPTION *Option;\r
- EFI_HANDLE ImageHandle;\r
- EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;\r
- UINTN ExitDataSize;\r
- CHAR16 *ExitData;\r
- BOOLEAN ReconnectAll;\r
-\r
- ReconnectAll = FALSE;\r
-\r
- //\r
- // Process the driver option\r
- //\r
- for (Link = BdsDriverLists->ForwardLink; Link != BdsDriverLists; Link = Link->ForwardLink) {\r
- Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
- //\r
- // If a load option is not marked as LOAD_OPTION_ACTIVE,\r
- // the boot manager will not automatically load the option.\r
- //\r
- if (!IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_ACTIVE)) {\r
- continue;\r
- }\r
- //\r
- // If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,\r
- // then all of the EFI drivers in the system will be disconnected and\r
- // reconnected after the last driver load option is processed.\r
- //\r
- if (IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_FORCE_RECONNECT)) {\r
- ReconnectAll = TRUE;\r
- }\r
- //\r
- // Make sure the driver path is connected.\r
- //\r
- BdsLibConnectDevicePath (Option->DevicePath);\r
-\r
- //\r
- // Load and start the image that Driver#### describes\r
- //\r
- Status = gBS->LoadImage (\r
- FALSE,\r
- mBdsImageHandle,\r
- Option->DevicePath,\r
- NULL,\r
- 0,\r
- &ImageHandle\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid,\r
- (VOID **)&ImageInfo);\r
-\r
- //\r
- // Verify whether this image is a driver, if not,\r
- // exit it and continue to parse next load option\r
- //\r
- if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo->ImageCodeType != EfiRuntimeServicesCode) {\r
- gBS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL);\r
- continue;\r
- }\r
-\r
- if (Option->LoadOptionsSize != 0) {\r
- ImageInfo->LoadOptionsSize = Option->LoadOptionsSize;\r
- ImageInfo->LoadOptions = Option->LoadOptions;\r
- }\r
- //\r
- // Before calling the image, enable the Watchdog Timer for\r
- // the 5 Minute period\r
- //\r
- gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);\r
-\r
- Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);\r
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Driver Return Status = %r\n", Status));\r
-\r
- //\r
- // Clear the Watchdog Timer after the image returns\r
- //\r
- gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);\r
- }\r
- }\r
- //\r
- // Process the LOAD_OPTION_FORCE_RECONNECT driver option\r
- //\r
- if (ReconnectAll) {\r
- BdsLibDisconnectAllEfi ();\r
- BdsLibConnectAll ();\r
- }\r
-\r
-}\r
-\r
-EFI_STATUS\r
-BdsLibRegisterNewOption (\r
- IN LIST_ENTRY *BdsOptionList,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
- IN CHAR16 *String,\r
- IN CHAR16 *VariableName\r
- )\r
-/*++\r
-\r
-Routine Description:\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
- driver#### updated, the BootOrder or DriverOrder will also be updated.\r
-\r
-Arguments:\r
-\r
- BdsOptionList - The header of the boot#### or driver#### link list\r
- \r
- DevicePath - The device path which the boot####\r
- or driver#### option present\r
- \r
- String - The description of the boot#### or driver####\r
- \r
- VariableName - Indicate if the boot#### or driver#### option\r
-\r
-Returns:\r
- \r
- EFI_SUCCESS - The boot#### or driver#### have been success registered\r
- \r
- EFI_STATUS - Return the status of gRT->SetVariable ().\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- UINT16 MaxOptionNumber;\r
- UINT16 RegisterOptionNumber;\r
- UINT16 *TempOptionPtr;\r
- UINTN TempOptionSize;\r
- UINT16 *OptionOrderPtr;\r
- VOID *OptionPtr;\r
- UINTN OptionSize;\r
- UINT8 *TempPtr;\r
- EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath;\r
- CHAR16 *Description;\r
- CHAR16 OptionName[10];\r
- BOOLEAN UpdateBootDevicePath;\r
-\r
- OptionPtr = NULL;\r
- OptionSize = 0;\r
- TempPtr = NULL;\r
- OptionDevicePath = NULL;\r
- Description = NULL;\r
- MaxOptionNumber = 0;\r
- OptionOrderPtr = NULL;\r
- UpdateBootDevicePath = FALSE;\r
- ZeroMem (OptionName, sizeof (OptionName));\r
-\r
- TempOptionSize = 0;\r
- TempOptionPtr = BdsLibGetVariableAndSize (\r
- VariableName,\r
- &gEfiGlobalVariableGuid,\r
- &TempOptionSize\r
- );\r
- //\r
- // Compare with current option variable\r
- //\r
- for (Index = 0; Index < TempOptionSize / sizeof (UINT16); Index++) {\r
- //\r
- // Got the max option#### number\r
- //\r
- if (MaxOptionNumber < TempOptionPtr[Index]) {\r
- MaxOptionNumber = TempOptionPtr[Index];\r
- }\r
-\r
- if (*VariableName == 'B') {\r
- UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", TempOptionPtr[Index]);\r
- } else {\r
- UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", TempOptionPtr[Index]);\r
- }\r
-\r
- OptionPtr = BdsLibGetVariableAndSize (\r
- OptionName,\r
- &gEfiGlobalVariableGuid,\r
- &OptionSize\r
- );\r
- TempPtr = OptionPtr;\r
- TempPtr += sizeof (UINT32) + sizeof (UINT16);\r
- Description = (CHAR16 *) TempPtr;\r
- TempPtr += StrSize ((CHAR16 *) TempPtr);\r
- OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;\r
-\r
- //\r
- // Notes: the description may will change base on the GetStringToken\r
- //\r
- if (CompareMem (Description, String, StrSize (Description)) == 0) {\r
- if (CompareMem (OptionDevicePath, DevicePath, GetDevicePathSize (OptionDevicePath)) == 0) {\r
- //\r
- // Got the option, so just return\r
- //\r
- gBS->FreePool (OptionPtr);\r
- gBS->FreePool (TempOptionPtr);\r
- return EFI_SUCCESS;\r
- } else {\r
- //\r
- // Boot device path changed, need update.\r
- //\r
- UpdateBootDevicePath = TRUE;\r
- break;\r
- }\r
- }\r
-\r
- gBS->FreePool (OptionPtr);\r
- }\r
-\r
- OptionSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (String) + GetDevicePathSize (DevicePath);\r
- OptionPtr = AllocateZeroPool (OptionSize);\r
- TempPtr = OptionPtr;\r
- *(UINT32 *) TempPtr = LOAD_OPTION_ACTIVE;\r
- TempPtr += sizeof (UINT32);\r
- *(UINT16 *) TempPtr = (UINT16) GetDevicePathSize (DevicePath);\r
- TempPtr += sizeof (UINT16);\r
- CopyMem (TempPtr, String, StrSize (String));\r
- TempPtr += StrSize (String);\r
- CopyMem (TempPtr, DevicePath, GetDevicePathSize (DevicePath));\r
-\r
- if (UpdateBootDevicePath) {\r
- //\r
- // The number in option#### to be updated\r
- //\r
- RegisterOptionNumber = TempOptionPtr[Index];\r
- } else {\r
- //\r
- // The new option#### number\r
- //\r
- RegisterOptionNumber = MaxOptionNumber + 1;\r
- }\r
-\r
- if (*VariableName == 'B') {\r
- UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", RegisterOptionNumber);\r
- } else {\r
- UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", RegisterOptionNumber);\r
- }\r
-\r
- Status = gRT->SetVariable (\r
- OptionName,\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- OptionSize,\r
- OptionPtr\r
- );\r
- if (EFI_ERROR (Status) || UpdateBootDevicePath) {\r
- gBS->FreePool (OptionPtr);\r
- gBS->FreePool (TempOptionPtr);\r
- return Status;\r
- }\r
-\r
- gBS->FreePool (OptionPtr);\r
-\r
- //\r
- // Update the option order variable\r
- //\r
- OptionOrderPtr = AllocateZeroPool ((Index + 1) * sizeof (UINT16));\r
- CopyMem (OptionOrderPtr, TempOptionPtr, Index * sizeof (UINT16));\r
- OptionOrderPtr[Index] = RegisterOptionNumber;\r
- Status = gRT->SetVariable (\r
- VariableName,\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- (Index + 1) * sizeof (UINT16),\r
- OptionOrderPtr\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (TempOptionPtr);\r
- gBS->FreePool (OptionOrderPtr);\r
- return Status;\r
- }\r
-\r
- gBS->FreePool (TempOptionPtr);\r
- gBS->FreePool (OptionOrderPtr);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-BDS_COMMON_OPTION *\r
-BdsLibVariableToOption (\r
- IN OUT LIST_ENTRY *BdsCommonOptionList,\r
- IN CHAR16 *VariableName\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Build the boot#### or driver#### option from the VariableName, the \r
- build boot#### or driver#### will also be linked to BdsCommonOptionList\r
- \r
-Arguments:\r
-\r
- BdsCommonOptionList - The header of the boot#### or driver#### option link list\r
-\r
- VariableName - EFI Variable name indicate if it is boot#### or driver####\r
-\r
-Returns:\r
-\r
- BDS_COMMON_OPTION - Get the option just been created\r
-\r
- NULL - Failed to get the new option\r
-\r
---*/\r
-{\r
- UINT32 Attribute;\r
- UINT16 FilePathSize;\r
- UINT8 *Variable;\r
- UINT8 *TempPtr;\r
- UINTN VariableSize;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
- BDS_COMMON_OPTION *Option;\r
- VOID *LoadOptions;\r
- UINT32 LoadOptionsSize;\r
- CHAR16 *Description;\r
-\r
- //\r
- // Read the variable. We will never free this data.\r
- //\r
- Variable = BdsLibGetVariableAndSize (\r
- VariableName,\r
- &gEfiGlobalVariableGuid,\r
- &VariableSize\r
- );\r
- if (Variable == NULL) {\r
- return NULL;\r
- }\r
- //\r
- // Notes: careful defined the variable of Boot#### or\r
- // Driver####, consider use some macro to abstract the code\r
- //\r
- //\r
- // Get the option attribute\r
- //\r
- TempPtr = Variable;\r
- Attribute = *(UINT32 *) Variable;\r
- TempPtr += sizeof (UINT32);\r
-\r
- //\r
- // Get the option's device path size\r
- //\r
- FilePathSize = *(UINT16 *) TempPtr;\r
- TempPtr += sizeof (UINT16);\r
-\r
- //\r
- // Get the option's description string\r
- //\r
- Description = (CHAR16 *) TempPtr;\r
-\r
- //\r
- // Get the option's description string size\r
- //\r
- TempPtr += StrSize ((CHAR16 *) TempPtr);\r
-\r
- //\r
- // Get the option's device path\r
- //\r
- DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;\r
- TempPtr += FilePathSize;\r
-\r
- LoadOptions = TempPtr;\r
- LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable));\r
-\r
- //\r
- // The Console variables may have multiple device paths, so make\r
- // an Entry for each one.\r
- //\r
- Option = AllocateZeroPool (sizeof (BDS_COMMON_OPTION));\r
- if (Option == NULL) {\r
- return NULL;\r
- }\r
-\r
- Option->Signature = BDS_LOAD_OPTION_SIGNATURE;\r
- Option->DevicePath = AllocateZeroPool (GetDevicePathSize (DevicePath));\r
- CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));\r
- Option->Attribute = Attribute;\r
- Option->Description = AllocateZeroPool (StrSize (Description));\r
- CopyMem (Option->Description, Description, StrSize (Description));\r
- Option->LoadOptions = AllocateZeroPool (LoadOptionsSize);\r
- CopyMem (Option->LoadOptions, LoadOptions, LoadOptionsSize);\r
- Option->LoadOptionsSize = LoadOptionsSize;\r
-\r
- //\r
- // Insert active entry to BdsDeviceList\r
- //\r
- if ((Option->Attribute & LOAD_OPTION_ACTIVE) == LOAD_OPTION_ACTIVE) {\r
- InsertTailList (BdsCommonOptionList, &Option->Link);\r
- gBS->FreePool (Variable);\r
- return Option;\r
- }\r
-\r
- gBS->FreePool (Variable);\r
- gBS->FreePool (Option);\r
- return NULL;\r
-\r
-}\r
-\r
-EFI_STATUS\r
-BdsLibBuildOptionFromVar (\r
- IN LIST_ENTRY *BdsCommonOptionList,\r
- IN CHAR16 *VariableName\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Process BootOrder, or DriverOrder variables, by calling\r
- BdsLibVariableToOption () for each UINT16 in the variables.\r
-\r
-Arguments:\r
-\r
- BdsCommonOptionList - The header of the option list base on variable\r
- VariableName\r
-\r
- VariableName - EFI Variable name indicate the BootOrder or DriverOrder\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Success create the boot option or driver option list\r
-\r
- EFI_OUT_OF_RESOURCES - Failed to get the boot option or driver option list\r
-\r
---*/\r
-{\r
- UINT16 *OptionOrder;\r
- UINTN OptionOrderSize;\r
- UINTN Index;\r
- BDS_COMMON_OPTION *Option;\r
- CHAR16 OptionName[20];\r
-\r
- //\r
- // Zero Buffer in order to get all BOOT#### variables\r
- //\r
- ZeroMem (OptionName, sizeof (OptionName));\r
-\r
- //\r
- // Read the BootOrder, or DriverOrder variable.\r
- //\r
- OptionOrder = BdsLibGetVariableAndSize (\r
- VariableName,\r
- &gEfiGlobalVariableGuid,\r
- &OptionOrderSize\r
- );\r
- if (OptionOrder == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) {\r
- if (*VariableName == 'B') {\r
- UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionOrder[Index]);\r
- } else {\r
- UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", OptionOrder[Index]);\r
- }\r
- Option = BdsLibVariableToOption (BdsCommonOptionList, OptionName);\r
- Option->BootCurrent = OptionOrder[Index];\r
-\r
- }\r
-\r
- gBS->FreePool (OptionOrder);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID *\r
-BdsLibGetVariableAndSize (\r
- IN CHAR16 *Name,\r
- IN EFI_GUID *VendorGuid,\r
- OUT UINTN *VariableSize\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Read the EFI variable (VendorGuid/Name) and return a dynamically allocated\r
- buffer, and the size of the buffer. If failure return NULL.\r
-\r
-Arguments:\r
-\r
- Name - String part of EFI variable name\r
-\r
- VendorGuid - GUID part of EFI variable name\r
-\r
- VariableSize - Returns the size of the EFI variable that was read\r
-\r
-Returns:\r
-\r
- Dynamically allocated memory that contains a copy of the EFI variable.\r
- Caller is responsible freeing the buffer.\r
-\r
- NULL - Variable was not read\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINTN BufferSize;\r
- VOID *Buffer;\r
-\r
- Buffer = NULL;\r
-\r
- //\r
- // Pass in a zero size buffer to find the required buffer size.\r
- //\r
- BufferSize = 0;\r
- Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- //\r
- // Allocate the buffer to return\r
- //\r
- Buffer = AllocateZeroPool (BufferSize);\r
- if (Buffer == NULL) {\r
- return NULL;\r
- }\r
- //\r
- // Read variable into the allocated buffer.\r
- //\r
- Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
- if (EFI_ERROR (Status)) {\r
- BufferSize = 0;\r
- }\r
- }\r
-\r
- *VariableSize = BufferSize;\r
- 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
- gBS->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
- IN EFI_DEVICE_PATH_PROTOCOL *Single\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Function compares a device path data structure to that of all the nodes of a\r
- second device path 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
- TRUE - If the Single is contained within Multi\r
- \r
- FALSE - The Single is not match within Multi\r
- \r
-\r
---*/\r
-{\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;\r
- UINTN Size;\r
-\r
- if (!Multi || !Single) {\r
- return FALSE;\r
- }\r
-\r
- DevicePath = Multi;\r
- DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);\r
-\r
- //\r
- // Search for the match of 'Single' in 'Multi'\r
- //\r
- while (DevicePathInst != NULL) {\r
- //\r
- // If the single device path is found in multiple device paths,\r
- // return success\r
- //\r
- if (CompareMem (Single, DevicePathInst, Size) == 0) {\r
- gBS->FreePool (DevicePathInst);\r
- return TRUE;\r
- }\r
-\r
- gBS->FreePool (DevicePathInst);\r
- DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-BdsLibOutputStrings (\r
- IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *ConOut,\r
- ...\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function prints a series of strings.\r
-\r
-Arguments:\r
-\r
- ConOut - Pointer to EFI_SIMPLE_TEXT_OUT_PROTOCOL\r
-\r
- ... - A variable argument list containing series of strings,\r
- the last string must be NULL.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Success print out the string using ConOut.\r
- \r
- EFI_STATUS - Return the status of the ConOut->OutputString ().\r
-\r
---*/\r
-{\r
- VA_LIST args;\r
- EFI_STATUS Status;\r
- CHAR16 *String;\r
-\r
- Status = EFI_SUCCESS;\r
- VA_START (args, ConOut);\r
-\r
- while (!EFI_ERROR (Status)) {\r
- //\r
- // If String is NULL, then it's the end of the list\r
- //\r
- String = VA_ARG (args, CHAR16 *);\r
- if (!String) {\r
- break;\r
- }\r
-\r
- Status = ConOut->OutputString (ConOut, String);\r
-\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
- }\r
-\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
- (VOID **)&Browser\r
- ); \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
- gBS->FreePool (StringBuffer1); \r
- gBS->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