4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function deal with the legacy boot option, it create, delete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and manage the legacy boot option, all legacy boot option is getting from
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the legacy BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncare licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhich accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOT_OPTION_BBS_MAPPING *mBootOptionBbsMapping = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Translate the first n characters of an Ascii string to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Unicode characters. The count n is indicated by parameter
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Size. If Size is greater than the length of string, then
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the entire string is translated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param AStr Pointer to input Ascii string.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Size The number of characters to translate.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param UStr Pointer to output Unicode string buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Build Legacy Device Name String according.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param CurBBSEntry BBS Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Index Index.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BufSize The buffer size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootString The output string.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Primary Master
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Primary Slave
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Secondary Master
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Secondary Slave
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If current BBS entry has its description then use it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StringDesc = (UINT8 *) (UINTN) ((CurBBSEntry->DescStringSegment << 4) + CurBBSEntry->DescStringOffset);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Only get fisrt 32 characters, this is suggested by BBS spec
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // BbsTable 16 entries are for onboard IDE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set description string for SATA harddisks, Harddisk 0 ~ Harddisk 11
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Index >= 5 && Index <= 16 && (CurBBSEntry->DeviceType == BBS_HARDDISK || CurBBSEntry->DeviceType == BBS_CDROM)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UnicodeSPrint (BootString, BufSize, Fmt, Type, Index - 5);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create a legacy boot option for the specified entry of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BBS table, save it as variable, and append it to the boot
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync order list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param CurrentBbsEntry Pointer to current BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param CurrentBbsDevPath Pointer to the Device Path Protocol instance of BBS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Index Index of the specified entry in BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOrderList On input, the original boot order list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync On output, the new boot order list attached with the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync created node.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOrderListSize On input, the original size of boot order list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync On output, the size of new boot order list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Boot Option successfully created.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Other Error occurs while setting variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (ArrayIndex = 0; ArrayIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); ArrayIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (BootOrderIndex = 0; BootOrderIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); BootOrderIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((*BootOrderList)[BootOrderIndex] == ArrayIndex) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L"Boot%04x",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BdsBuildLegacyDevNameString (CurrentBbsEntry, Index, sizeof (BootDesc), BootDesc);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create new BBS device path node with description string
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewBbsDevPathNode = AllocateZeroPool (sizeof (BBS_BBS_DEVICE_PATH) + StringLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (NewBbsDevPathNode, CurrentBbsDevPath, sizeof (BBS_BBS_DEVICE_PATH));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (NewBbsDevPathNode->String, HelpString, StringLen + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetDevicePathNodeLength (&(NewBbsDevPathNode->Header), sizeof (BBS_BBS_DEVICE_PATH) + StringLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create entire new CurrentBbsDevPath with end node
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentBbsDevPathSize = (UINT16) (GetDevicePathSize (CurrentBbsDevPath));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewBootOrderList = AllocateZeroPool (*BootOrderListSize + sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (NewBootOrderList, *BootOrderList, *BootOrderListSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BootOrderLastIndex = (UINTN) (*BootOrderListSize / sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewBootOrderList[BootOrderLastIndex] = CurrentBootOptionNo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check if the boot option is a legacy one.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOptionVar The boot option data payload.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsEntry The BBS Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsIndex The table index.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE It is a legacy boot option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE It is not a legacy boot option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Re-order the Boot Option according to the DevOrder.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The routine re-orders the Boot Option in BootOption array according to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the order specified by DevOrder.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOption Pointer to buffer containing the Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOptionCount Count of the Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DevOrder Pointer to buffer containing the BBS Index,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync high 8-bit value 0xFF indicating a disabled boot option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DevOrderCount Count of the BBS Index
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param EnBootOption Pointer to buffer receiving the enabled Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param EnBootOptionCount Count of the enabled Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DisBootOption Pointer to buffer receiving the disabled Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DisBootOptionCount Count of the disabled Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Record the corresponding Boot Option Numbers according to the DevOrder
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Record the EnBootOption and DisBootOption according to the DevOrder
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewBootOption = AllocatePool (DevOrderCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (DevOrderCount-- != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < mBootOptionBbsMappingCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mBootOptionBbsMapping[Index].BbsIndex == (DevOrder[DevOrderCount] & 0xFF)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewBootOption[DevOrderCount] = mBootOptionBbsMapping[Index].BootOptionNumber;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((DevOrder[DevOrderCount] & 0xFF00) == 0xFF00) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DisBootOption[*DisBootOptionCount] = NewBootOption[DevOrderCount];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EnBootOption[*EnBootOptionCount] = NewBootOption[DevOrderCount];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < BootOptionCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Find the start position for the BbsType in BootOption
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (MappingIndex = 0; MappingIndex < mBootOptionBbsMappingCount; MappingIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mBootOptionBbsMapping[MappingIndex].BbsType == BbsType && mBootOptionBbsMapping[MappingIndex].BootOptionNumber == BootOption[Index]) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Overwrite the old BootOption
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&BootOption[Index], NewBootOption, (*DisBootOptionCount + *EnBootOptionCount) * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Group the legacy boot options in the BootOption.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The routine assumes the boot options in the beginning that covers all the device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync types are ordered properly and re-position the following boot options just after
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the corresponding boot options with the same device type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync For example:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 1. Input = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Assuming [Harddisk1 CdRom2 Efi1] is ordered properly
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 2. Input = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOption Pointer to buffer containing Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOptionCount Count of the Boot Option Numbers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem (DeviceTypeIndex, sizeof (DeviceTypeIndex), 0xFF);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < BootOptionCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Find the DeviceType
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (MappingIndex = 0; MappingIndex < mBootOptionBbsMappingCount; MappingIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mBootOptionBbsMapping[MappingIndex].BootOptionNumber == BootOption[Index]) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Is not a legacy boot option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((mBootOptionBbsMapping[MappingIndex].BbsType & 0xF) <
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0]));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NextIndex = &DeviceTypeIndex[mBootOptionBbsMapping[MappingIndex].BbsType & 0xF];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // *NextIndex is the index in BootOption to put the next Option Number for the same type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // insert the current boot option before *NextIndex, causing [*Next .. Index] shift right one position
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&BootOption[*NextIndex + 1], &BootOption[*NextIndex], (Index - *NextIndex) * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the DeviceTypeIndex array to reflect the right shift operation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (DeviceIndex = 0; DeviceIndex < sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0]); DeviceIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DeviceTypeIndex[DeviceIndex] != (UINTN) -1 && DeviceTypeIndex[DeviceIndex] >= *NextIndex) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delete all the invalid legacy boot options.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS All invalide legacy boot options are deleted.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND Fail to retrive variable of boot order.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L"BootOrder",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update BootOrder
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Skip Non-Legacy boot option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, &BbsIndex)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check if BBS Description String is changed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (StrCmp (BootDesc, (UINT16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!((LocalBbsTable[BbsIndex].BootPriority == BBS_IGNORE_ENTRY) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LocalBbsTable[BbsIndex].BootPriority == BBS_DO_NOT_BOOT_FROM)) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LocalBbsTable[BbsIndex].DeviceType == BbsEntry->DeviceType) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // should delete
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Adjust the number of boot options.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L"BootOrder",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Find all legacy boot option by device type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOrder The boot order array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOptionNum The number of boot option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DevType Device type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DevName Device name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Attribute The boot option attribute.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsIndex The BBS table index.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param OptionNumber The boot option index.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE The Legacy boot option is found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE The legacy boot option is not found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Loop all boot option from variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", (UINTN) BootOrder[Index]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Skip Non-legacy boot option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, BbsIndex)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (StrCmp (DevName, (CHAR16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) != 0)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create a legacy boot option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsItem The BBS Table entry.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Index Index of the specified entry in BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOrderList The boot order list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BootOrderListSize The size of boot order list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCE No enough memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The function complete successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Other value if the legacy boot option is not created.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create device path node.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetDevicePathNodeLength (&BbsDevPathNode.Header, sizeof (BBS_BBS_DEVICE_PATH));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&BbsDevPathNode.StatusFlag, &BbsItem->StatusFlags, sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Add the legacy boot options from BBS table if they do not exist.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The boot options are added successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync or they are already in boot options.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND No legacy boot options is found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCE No enough memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Other value LegacyBoot options are not added.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L"BootOrder",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BdsBuildLegacyDevNameString (&LocalBbsTable[Index], Index, sizeof (Desc), Desc);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Not found such type of legacy device in boot options or we found but it's disabled
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // so we have to create one and put it to the tail of boot order list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OptionNumber = BootOrder[BootOrderSize / sizeof (UINT16) - 1];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save the BbsIndex
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootOptionBbsMappingCount * sizeof (BOOT_OPTION_BBS_MAPPING),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (mBootOptionBbsMappingCount + 1) * sizeof (BOOT_OPTION_BBS_MAPPING),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootOptionBbsMapping[mBootOptionBbsMappingCount].BootOptionNumber = OptionNumber;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootOptionBbsMapping[mBootOptionBbsMappingCount].BbsIndex = Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootOptionBbsMapping[mBootOptionBbsMappingCount].BbsType = LocalBbsTable[Index].DeviceType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Group the Boot Option Number in BootOrder for the same type devices
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L"BootOrder",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fill the device order buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsTable The BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsType The BBS Type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsCount The BBS Count.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Buf device order buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The device order buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create the device order buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsTable The BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsCount The BBS Count.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCES The buffer is created and the EFI variable named
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync set correctly.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Fail to add the device order into EFI variable fail
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync because of hardware error.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Count all boot devices
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + sizeof (UINT16) * FDCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + sizeof (UINT16) * HDCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + sizeof (UINT16) * CDCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + sizeof (UINT16) * NETCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create buffer to hold all boot device order
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->Length = (UINT16) (sizeof (DevOrderPtr->Length) + FDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, DevOrderPtr->Data);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, DevOrderPtr->Data);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, DevOrderPtr->Data);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, DevOrderPtr->Data);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, DevOrderPtr->Data);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (TotalSize == (UINTN) ((UINT8 *) DevOrderPtr - (UINT8 *) DevOrder));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save device order for legacy boot device to variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Add the legacy boot devices from BBS table into
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the legacy device boot order.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The boot devices are added successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The legacy boot devices are not found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Fail to add the legacy device boot order into EFI variable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync because of hardware error.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return BdsCreateDevOrder (LocalBbsTable, BbsCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // First we figure out how many boot devices with same device type respectively
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + FDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + HDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + CDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + NETCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TotalSize += (HeaderSize + BEVCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Length = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_FLOPPY
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Length = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_HARDDISK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Length = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_CDROM
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // copy NET
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Length = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_EMBED_NETWORK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // copy BEV
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewPtr->Length = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_BEV_DEVICE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // at this point we have copied those valid indexes to new buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // and we should check if there is any new appeared boot device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Index2 == *Idx means we didn't find Index
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // so Index is a new appeared device's index in BBS table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // insert it before disabled indexes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&NewDevPtr[Index2 + 1], &NewDevPtr[Index2], (*Idx - Index2) * sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Set Boot Priority for specified device type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param DeviceType The device type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsIndex The BBS index to set the highest priority. Ignore when -1.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param LocalBbsTable The BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Priority The prority table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The function completes successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND Failed to find device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to get the efi variable of device order.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((UINT8 *) DevOrderPtr < (UINT8 *) DevOrder + DevOrderSize) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) ((UINT8 *) DevOrderPtr + sizeof (BBS_TYPE) + DevOrderPtr->Length);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((UINT8 *) DevOrderPtr >= (UINT8 *) DevOrder + DevOrderSize) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < DevOrderPtr->Length / sizeof (UINT16) - 1; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((DevOrderPtr->Data[Index] & 0xFF00) == 0xFF00) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[DevOrderPtr->Data[Index]].BootPriority = *Priority;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Print the BBS Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param LocalBbsTable The BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BbsCount The count of entry in BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((DEBUG_ERROR, " NO Prio bb/dd/ff cl/sc Type Stat segm:offs\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((DEBUG_ERROR, "=============================================\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((LocalBbsTable[Idx].BootPriority == BBS_IGNORE_ENTRY) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LocalBbsTable[Idx].BootPriority == BBS_DO_NOT_BOOT_FROM) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LocalBbsTable[Idx].BootPriority == BBS_LOWEST_PRIORITY)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Set the boot priority for BBS entries based on boot option entry and boot order.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Entry The boot option is to be checked for refresh BBS table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The boot priority for BBS entries is refreshed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND BBS entries can't be found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to get the legacy device boot order.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // We will set them according to the settings setup by user
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!((BBS_IGNORE_ENTRY == LocalBbsTable[Index].BootPriority) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (BBS_DO_NOT_BOOT_FROM == LocalBbsTable[Index].BootPriority) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (BBS_LOWEST_PRIORITY == LocalBbsTable[Index].BootPriority))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LocalBbsTable[Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // boot priority always starts at 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Entry->LoadOptionsSize == sizeof (BBS_TABLE) + sizeof (UINT16)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If Entry stands for a legacy boot option, we prioritize the devices with the same type first.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevType = ((BBS_TABLE *) Entry->LoadOptions)->DeviceType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BbsIndex = *(UINT16 *) ((BBS_TABLE *) Entry->LoadOptions + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // we have to set the boot priority for other BBS entries with different device types
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync L"BootOrder",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeviceType = AllocatePool (BootOrderSize + sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; ((BootOrder != NULL) && (Index < BootOrderSize / sizeof (UINT16))); Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BBS_DEVICE_PATH != DevPath->Type || BBS_BBS_DP != DevPath->SubType) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (DeviceTypeIndex = 0; DeviceTypeIndex < DeviceTypeCount; DeviceTypeIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // We don't want to process twice for a device type