+++ /dev/null
-/** @file\r
- This function deal with the legacy boot option, it create, delete\r
- and manage the legacy boot option, all legacy boot option is getting from\r
- the legacy BBS table.\r
-\r
-Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "BBSsupport.h"\r
-\r
-#pragma pack(1)\r
-typedef struct {\r
- BBS_TABLE BbsEntry;\r
- UINT16 BbsIndex;\r
-} LEGACY_BOOT_OPTION_BBS_DATA;\r
-#pragma pack()\r
-\r
-/**\r
- Re-order the Boot Option according to the DevOrder.\r
-\r
- The routine re-orders the Boot Option in BootOption array according to\r
- the order specified by DevOrder.\r
-\r
- @param DevOrder Pointer to buffer containing the BBS Index,\r
- high 8-bit value 0xFF indicating a disabled boot option\r
- @param DevOrderCount Count of the BBS Index\r
- @param EnBootOption Callee allocated buffer containing the enabled Boot Option Numbers\r
- @param EnBootOptionCount Count of the enabled Boot Option Numbers\r
- @param DisBootOption Callee allocated buffer containing the disabled Boot Option Numbers\r
- @param DisBootOptionCount Count of the disabled Boot Option Numbers\r
-**/\r
-VOID\r
-OrderLegacyBootOption4SameType (\r
- UINT16 *DevOrder,\r
- UINTN DevOrderCount,\r
- UINT16 **EnBootOption,\r
- UINTN *EnBootOptionCount,\r
- UINT16 **DisBootOption,\r
- UINTN *DisBootOptionCount\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT16 *NewBootOption;\r
- UINT16 *BootOrder;\r
- UINTN BootOrderSize;\r
- UINTN Index;\r
- UINTN StartPosition;\r
-\r
- BDS_COMMON_OPTION *BootOption;\r
-\r
- CHAR16 OptionName[sizeof ("Boot####")];\r
- UINT16 *BbsIndexArray;\r
- UINT16 *DeviceTypeArray;\r
- LIST_ENTRY List;\r
-\r
- BootOrder = BdsLibGetVariableAndSize (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- &BootOrderSize\r
- );\r
- ASSERT (BootOrder != NULL);\r
-\r
- BbsIndexArray = AllocatePool (BootOrderSize);\r
- DeviceTypeArray = AllocatePool (BootOrderSize);\r
- *EnBootOption = AllocatePool (BootOrderSize);\r
- *DisBootOption = AllocatePool (BootOrderSize);\r
- *DisBootOptionCount = 0;\r
- *EnBootOptionCount = 0;\r
- Index = 0;\r
-\r
- ASSERT (BbsIndexArray != NULL);\r
- ASSERT (DeviceTypeArray != NULL);\r
- ASSERT (*EnBootOption != NULL);\r
- ASSERT (*DisBootOption != NULL);\r
-\r
- for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
-\r
- UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);\r
- InitializeListHead (&List);\r
- BootOption = BdsLibVariableToOption (&List, OptionName);\r
- ASSERT (BootOption != NULL);\r
-\r
- if ((DevicePathType (BootOption->DevicePath) == BBS_DEVICE_PATH) &&\r
- (DevicePathSubType (BootOption->DevicePath) == BBS_BBS_DP)) {\r
- //\r
- // Legacy Boot Option\r
- //\r
- ASSERT (BootOption->LoadOptionsSize == sizeof (LEGACY_BOOT_OPTION_BBS_DATA));\r
-\r
- DeviceTypeArray[Index] = ((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType;\r
- BbsIndexArray [Index] = ((LEGACY_BOOT_OPTION_BBS_DATA *) BootOption->LoadOptions)->BbsIndex;\r
- } else {\r
- DeviceTypeArray[Index] = BBS_TYPE_UNKNOWN;\r
- BbsIndexArray [Index] = 0xFFFF;\r
- }\r
- FreePool (BootOption->DevicePath);\r
- FreePool (BootOption->Description);\r
- FreePool (BootOption->LoadOptions);\r
- FreePool (BootOption);\r
- }\r
-\r
- //\r
- // Record the corresponding Boot Option Numbers according to the DevOrder\r
- // Record the EnBootOption and DisBootOption according to the DevOrder\r
- //\r
- StartPosition = BootOrderSize / sizeof (UINT16);\r
- NewBootOption = AllocatePool (DevOrderCount * sizeof (UINT16));\r
- ASSERT (NewBootOption != NULL);\r
- while (DevOrderCount-- != 0) {\r
- for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
- if (BbsIndexArray[Index] == (DevOrder[DevOrderCount] & 0xFF)) {\r
- StartPosition = MIN (StartPosition, Index);\r
- NewBootOption[DevOrderCount] = BootOrder[Index];\r
-\r
- if ((DevOrder[DevOrderCount] & 0xFF00) == 0xFF00) {\r
- (*DisBootOption)[*DisBootOptionCount] = BootOrder[Index];\r
- (*DisBootOptionCount)++;\r
- } else {\r
- (*EnBootOption)[*EnBootOptionCount] = BootOrder[Index];\r
- (*EnBootOptionCount)++;\r
- }\r
- break;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Overwrite the old BootOption\r
- //\r
- CopyMem (&BootOrder[StartPosition], NewBootOption, (*DisBootOptionCount + *EnBootOptionCount) * sizeof (UINT16));\r
- Status = gRT->SetVariable (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- BootOrderSize,\r
- BootOrder\r
- );\r
- //\r
- // Changing content without increasing its size with current variable implementation shouldn't fail.\r
- //\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- FreePool (NewBootOption);\r
- FreePool (DeviceTypeArray);\r
- FreePool (BbsIndexArray);\r
- FreePool (BootOrder);\r
-}\r
-\r
-/**\r
- Group the legacy boot options in the BootOption.\r
-\r
- The routine assumes the boot options in the beginning that covers all the device\r
- types are ordered properly and re-position the following boot options just after\r
- the corresponding boot options with the same device type.\r
- For example:\r
- 1. Input = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0]\r
- Assuming [Harddisk1 CdRom2 Efi1] is ordered properly\r
- Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0]\r
-\r
- 2. Input = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2]\r
- Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly\r
- Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]\r
-\r
-**/\r
-VOID\r
-GroupMultipleLegacyBootOption4SameType (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- UINTN DeviceIndex;\r
- UINTN DeviceTypeIndex[7];\r
- UINTN *NextIndex;\r
- UINT16 OptionNumber;\r
- UINT16 *BootOrder;\r
- UINTN BootOrderSize;\r
- CHAR16 OptionName[sizeof ("Boot####")];\r
- BDS_COMMON_OPTION *BootOption;\r
- LIST_ENTRY List;\r
-\r
- SetMem (DeviceTypeIndex, sizeof (DeviceTypeIndex), 0xff);\r
-\r
- BootOrder = BdsLibGetVariableAndSize (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- &BootOrderSize\r
- );\r
-\r
- for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
- UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);\r
- InitializeListHead (&List);\r
- BootOption = BdsLibVariableToOption (&List, OptionName);\r
- ASSERT (BootOption != NULL);\r
-\r
- if ((DevicePathType (BootOption->DevicePath) == BBS_DEVICE_PATH) &&\r
- (DevicePathSubType (BootOption->DevicePath) == BBS_BBS_DP)) {\r
- //\r
- // Legacy Boot Option\r
- //\r
- ASSERT ((((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType & 0xF) < ARRAY_SIZE (DeviceTypeIndex));\r
- NextIndex = &DeviceTypeIndex[((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType & 0xF];\r
-\r
- if (*NextIndex == (UINTN) -1) {\r
- //\r
- // *NextIndex is the Index in BootOrder to put the next Option Number for the same type\r
- //\r
- *NextIndex = Index + 1;\r
- } else {\r
- //\r
- // insert the current boot option before *NextIndex, causing [*Next .. Index] shift right one position\r
- //\r
- OptionNumber = BootOrder[Index];\r
- CopyMem (&BootOrder[*NextIndex + 1], &BootOrder[*NextIndex], (Index - *NextIndex) * sizeof (UINT16));\r
- BootOrder[*NextIndex] = OptionNumber;\r
-\r
- //\r
- // Update the DeviceTypeIndex array to reflect the right shift operation\r
- //\r
- for (DeviceIndex = 0; DeviceIndex < ARRAY_SIZE (DeviceTypeIndex); DeviceIndex++) {\r
- if (DeviceTypeIndex[DeviceIndex] != (UINTN) -1 && DeviceTypeIndex[DeviceIndex] >= *NextIndex) {\r
- DeviceTypeIndex[DeviceIndex]++;\r
- }\r
- }\r
- }\r
- }\r
- FreePool (BootOption->DevicePath);\r
- FreePool (BootOption->Description);\r
- FreePool (BootOption->LoadOptions);\r
- FreePool (BootOption);\r
- }\r
-\r
- Status = gRT->SetVariable (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- BootOrderSize,\r
- BootOrder\r
- );\r
- //\r
- // Changing content without increasing its size with current variable implementation shouldn't fail.\r
- //\r
- ASSERT_EFI_ERROR (Status);\r
- FreePool (BootOrder);\r
-}\r
-\r