2 This function deal with the legacy boot option, it create, delete
3 and manage the legacy boot option, all legacy boot option is getting from
6 Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "BBSsupport.h"
19 BOOT_OPTION_BBS_MAPPING
*mBootOptionBbsMapping
= NULL
;
20 UINTN mBootOptionBbsMappingCount
= 0;
24 Translate the first n characters of an Ascii string to
25 Unicode characters. The count n is indicated by parameter
26 Size. If Size is greater than the length of string, then
27 the entire string is translated.
30 @param AStr Pointer to input Ascii string.
31 @param Size The number of characters to translate.
32 @param UStr Pointer to output Unicode string buffer.
45 while (AStr
[Idx
] != 0) {
46 UStr
[Idx
] = (CHAR16
) AStr
[Idx
];
57 Build Legacy Device Name String according.
59 @param CurBBSEntry BBS Table.
61 @param BufSize The buffer size.
62 @param BootString The output string.
66 BdsBuildLegacyDevNameString (
67 IN BBS_TABLE
*CurBBSEntry
,
70 OUT CHAR16
*BootString
83 Fmt
= L
"Primary Master %s";
90 Fmt
= L
"Primary Slave %s";
97 Fmt
= L
"Secondary Master %s";
104 Fmt
= L
"Secondary Slave %s";
112 switch (CurBBSEntry
->DeviceType
) {
133 case BBS_EMBED_NETWORK
:
147 // If current BBS entry has its description then use it.
149 StringDesc
= (UINT8
*) (UINTN
) ((CurBBSEntry
->DescStringSegment
<< 4) + CurBBSEntry
->DescStringOffset
);
150 if (NULL
!= StringDesc
) {
152 // Only get fisrt 32 characters, this is suggested by BBS spec
154 AsciiToUnicodeSize (StringDesc
, 32, Temp
);
160 // BbsTable 16 entries are for onboard IDE.
161 // Set description string for SATA harddisks, Harddisk 0 ~ Harddisk 11
163 if (Index
>= 5 && Index
<= 16 && (CurBBSEntry
->DeviceType
== BBS_HARDDISK
|| CurBBSEntry
->DeviceType
== BBS_CDROM
)) {
165 UnicodeSPrint (BootString
, BufSize
, Fmt
, Type
, Index
- 5);
167 UnicodeSPrint (BootString
, BufSize
, Fmt
, Type
);
173 Create a legacy boot option for the specified entry of
174 BBS table, save it as variable, and append it to the boot
178 @param CurrentBbsEntry Pointer to current BBS table.
179 @param CurrentBbsDevPath Pointer to the Device Path Protocol instance of BBS
180 @param Index Index of the specified entry in BBS table.
181 @param BootOrderList On input, the original boot order list.
182 On output, the new boot order list attached with the
184 @param BootOrderListSize On input, the original size of boot order list.
185 On output, the size of new boot order list.
187 @retval EFI_SUCCESS Boot Option successfully created.
188 @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory.
189 @retval Other Error occurs while setting variable.
193 BdsCreateLegacyBootOption (
194 IN BBS_TABLE
*CurrentBbsEntry
,
195 IN EFI_DEVICE_PATH_PROTOCOL
*CurrentBbsDevPath
,
197 IN OUT UINT16
**BootOrderList
,
198 IN OUT UINTN
*BootOrderListSize
202 UINT16 CurrentBootOptionNo
;
203 UINT16 BootString
[10];
204 CHAR16 BootDesc
[100];
205 CHAR8 HelpString
[100];
206 UINT16
*NewBootOrderList
;
211 UINT16 CurrentBbsDevPathSize
;
212 UINTN BootOrderIndex
;
213 UINTN BootOrderLastIndex
;
215 BOOLEAN IndexNotFound
;
216 BBS_BBS_DEVICE_PATH
*NewBbsDevPathNode
;
218 if ((*BootOrderList
) == NULL
) {
219 CurrentBootOptionNo
= 0;
221 for (ArrayIndex
= 0; ArrayIndex
< (UINTN
) (*BootOrderListSize
/ sizeof (UINT16
)); ArrayIndex
++) {
222 IndexNotFound
= TRUE
;
223 for (BootOrderIndex
= 0; BootOrderIndex
< (UINTN
) (*BootOrderListSize
/ sizeof (UINT16
)); BootOrderIndex
++) {
224 if ((*BootOrderList
)[BootOrderIndex
] == ArrayIndex
) {
225 IndexNotFound
= FALSE
;
230 if (!IndexNotFound
) {
237 CurrentBootOptionNo
= (UINT16
) ArrayIndex
;
247 BdsBuildLegacyDevNameString (CurrentBbsEntry
, Index
, sizeof (BootDesc
), BootDesc
);
250 // Create new BBS device path node with description string
252 UnicodeStrToAsciiStr (BootDesc
, HelpString
);
254 StringLen
= AsciiStrLen (HelpString
);
255 NewBbsDevPathNode
= AllocateZeroPool (sizeof (BBS_BBS_DEVICE_PATH
) + StringLen
);
256 if (NewBbsDevPathNode
== NULL
) {
257 return EFI_OUT_OF_RESOURCES
;
259 CopyMem (NewBbsDevPathNode
, CurrentBbsDevPath
, sizeof (BBS_BBS_DEVICE_PATH
));
260 CopyMem (NewBbsDevPathNode
->String
, HelpString
, StringLen
+ 1);
261 SetDevicePathNodeLength (&(NewBbsDevPathNode
->Header
), sizeof (BBS_BBS_DEVICE_PATH
) + StringLen
);
264 // Create entire new CurrentBbsDevPath with end node
266 CurrentBbsDevPath
= AppendDevicePathNode (
268 (EFI_DEVICE_PATH_PROTOCOL
*) NewBbsDevPathNode
270 if (CurrentBbsDevPath
== NULL
) {
271 FreePool (NewBbsDevPathNode
);
272 return EFI_OUT_OF_RESOURCES
;
275 CurrentBbsDevPathSize
= (UINT16
) (GetDevicePathSize (CurrentBbsDevPath
));
277 BufferSize
= sizeof (UINT32
) +
280 CurrentBbsDevPathSize
+
284 Buffer
= AllocateZeroPool (BufferSize
);
285 if (Buffer
== NULL
) {
286 FreePool (NewBbsDevPathNode
);
287 FreePool (CurrentBbsDevPath
);
288 return EFI_OUT_OF_RESOURCES
;
291 Ptr
= (UINT8
*) Buffer
;
293 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
294 Ptr
+= sizeof (UINT32
);
296 *((UINT16
*) Ptr
) = CurrentBbsDevPathSize
;
297 Ptr
+= sizeof (UINT16
);
304 Ptr
+= StrSize (BootDesc
);
309 CurrentBbsDevPathSize
311 Ptr
+= CurrentBbsDevPathSize
;
319 Ptr
+= sizeof (BBS_TABLE
);
320 *((UINT16
*) Ptr
) = (UINT16
) Index
;
322 Status
= gRT
->SetVariable (
324 &gEfiGlobalVariableGuid
,
334 NewBootOrderList
= AllocateZeroPool (*BootOrderListSize
+ sizeof (UINT16
));
335 if (NULL
== NewBootOrderList
) {
336 FreePool (NewBbsDevPathNode
);
337 FreePool (CurrentBbsDevPath
);
338 return EFI_OUT_OF_RESOURCES
;
341 if (*BootOrderList
!= NULL
) {
342 CopyMem (NewBootOrderList
, *BootOrderList
, *BootOrderListSize
);
343 FreePool (*BootOrderList
);
346 BootOrderLastIndex
= (UINTN
) (*BootOrderListSize
/ sizeof (UINT16
));
347 NewBootOrderList
[BootOrderLastIndex
] = CurrentBootOptionNo
;
348 *BootOrderListSize
+= sizeof (UINT16
);
349 *BootOrderList
= NewBootOrderList
;
351 FreePool (NewBbsDevPathNode
);
352 FreePool (CurrentBbsDevPath
);
357 Check if the boot option is a legacy one.
359 @param BootOptionVar The boot option data payload.
360 @param BbsEntry The BBS Table.
361 @param BbsIndex The table index.
363 @retval TRUE It is a legacy boot option.
364 @retval FALSE It is not a legacy boot option.
368 BdsIsLegacyBootOption (
369 IN UINT8
*BootOptionVar
,
370 OUT BBS_TABLE
**BbsEntry
,
375 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
380 Ptr
+= sizeof (UINT32
);
381 DevPathLen
= *(UINT16
*) Ptr
;
382 Ptr
+= sizeof (UINT16
);
383 Ptr
+= StrSize ((UINT16
*) Ptr
);
384 DevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) Ptr
;
385 if ((BBS_DEVICE_PATH
== DevicePath
->Type
) && (BBS_BBS_DP
== DevicePath
->SubType
)) {
387 *BbsEntry
= (BBS_TABLE
*) Ptr
;
388 Ptr
+= sizeof (BBS_TABLE
);
389 *BbsIndex
= *(UINT16
*) Ptr
;
400 Re-order the Boot Option according to the DevOrder.
402 The routine re-orders the Boot Option in BootOption array according to
403 the order specified by DevOrder.
405 @param BootOption Pointer to buffer containing the Boot Option Numbers
406 @param BootOptionCount Count of the Boot Option Numbers
407 @param DevOrder Pointer to buffer containing the BBS Index,
408 high 8-bit value 0xFF indicating a disabled boot option
409 @param DevOrderCount Count of the BBS Index
410 @param EnBootOption Pointer to buffer receiving the enabled Boot Option Numbers
411 @param EnBootOptionCount Count of the enabled Boot Option Numbers
412 @param DisBootOption Pointer to buffer receiving the disabled Boot Option Numbers
413 @param DisBootOptionCount Count of the disabled Boot Option Numbers
416 OrderLegacyBootOption4SameType (
418 UINTN BootOptionCount
,
421 UINT16
*EnBootOption
,
422 UINTN
*EnBootOptionCount
,
423 UINT16
*DisBootOption
,
424 UINTN
*DisBootOptionCount
429 UINT16
*NewBootOption
;
432 *DisBootOptionCount
= 0;
433 *EnBootOptionCount
= 0;
437 // Record the corresponding Boot Option Numbers according to the DevOrder
438 // Record the EnBootOption and DisBootOption according to the DevOrder
440 NewBootOption
= AllocatePool (DevOrderCount
* sizeof (UINT16
));
441 ASSERT (NewBootOption
!= NULL
);
443 while (DevOrderCount
-- != 0) {
444 for (Index
= 0; Index
< mBootOptionBbsMappingCount
; Index
++) {
445 if (mBootOptionBbsMapping
[Index
].BbsIndex
== (DevOrder
[DevOrderCount
] & 0xFF)) {
446 BbsType
= mBootOptionBbsMapping
[Index
].BbsType
;
447 NewBootOption
[DevOrderCount
] = mBootOptionBbsMapping
[Index
].BootOptionNumber
;
449 if ((DevOrder
[DevOrderCount
] & 0xFF00) == 0xFF00) {
450 DisBootOption
[*DisBootOptionCount
] = NewBootOption
[DevOrderCount
];
451 (*DisBootOptionCount
)++;
453 EnBootOption
[*EnBootOptionCount
] = NewBootOption
[DevOrderCount
];
454 (*EnBootOptionCount
)++;
461 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
463 // Find the start position for the BbsType in BootOption
465 for (MappingIndex
= 0; MappingIndex
< mBootOptionBbsMappingCount
; MappingIndex
++) {
466 if (mBootOptionBbsMapping
[MappingIndex
].BbsType
== BbsType
&& mBootOptionBbsMapping
[MappingIndex
].BootOptionNumber
== BootOption
[Index
]) {
472 // Overwrite the old BootOption
474 if (MappingIndex
< mBootOptionBbsMappingCount
) {
475 CopyMem (&BootOption
[Index
], NewBootOption
, (*DisBootOptionCount
+ *EnBootOptionCount
) * sizeof (UINT16
));
482 Group the legacy boot options in the BootOption.
484 The routine assumes the boot options in the beginning that covers all the device
485 types are ordered properly and re-position the following boot options just after
486 the corresponding boot options with the same device type.
488 1. Input = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0]
489 Assuming [Harddisk1 CdRom2 Efi1] is ordered properly
490 Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0]
492 2. Input = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2]
493 Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly
494 Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]
496 @param BootOption Pointer to buffer containing Boot Option Numbers
497 @param BootOptionCount Count of the Boot Option Numbers
500 GroupMultipleLegacyBootOption4SameType (
502 UINTN BootOptionCount
505 UINTN DeviceTypeIndex
[7];
512 SetMem (DeviceTypeIndex
, sizeof (DeviceTypeIndex
), 0xFF);
514 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
517 // Find the DeviceType
519 for (MappingIndex
= 0; MappingIndex
< mBootOptionBbsMappingCount
; MappingIndex
++) {
520 if (mBootOptionBbsMapping
[MappingIndex
].BootOptionNumber
== BootOption
[Index
]) {
524 if (MappingIndex
== mBootOptionBbsMappingCount
) {
526 // Is not a legacy boot option
531 ASSERT ((mBootOptionBbsMapping
[MappingIndex
].BbsType
& 0xF) <
532 sizeof (DeviceTypeIndex
) / sizeof (DeviceTypeIndex
[0]));
533 NextIndex
= &DeviceTypeIndex
[mBootOptionBbsMapping
[MappingIndex
].BbsType
& 0xF];
534 if (*NextIndex
== (UINTN
) -1) {
536 // *NextIndex is the index in BootOption to put the next Option Number for the same type
538 *NextIndex
= Index
+ 1;
541 // insert the current boot option before *NextIndex, causing [*Next .. Index] shift right one position
543 OptionNumber
= BootOption
[Index
];
544 CopyMem (&BootOption
[*NextIndex
+ 1], &BootOption
[*NextIndex
], (Index
- *NextIndex
) * sizeof (UINT16
));
545 BootOption
[*NextIndex
] = OptionNumber
;
548 // Update the DeviceTypeIndex array to reflect the right shift operation
550 for (DeviceIndex
= 0; DeviceIndex
< sizeof (DeviceTypeIndex
) / sizeof (DeviceTypeIndex
[0]); DeviceIndex
++) {
551 if (DeviceTypeIndex
[DeviceIndex
] != (UINTN
) -1 && DeviceTypeIndex
[DeviceIndex
] >= *NextIndex
) {
552 DeviceTypeIndex
[DeviceIndex
]++;
560 Delete all the invalid legacy boot options.
562 @retval EFI_SUCCESS All invalide legacy boot options are deleted.
563 @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory.
564 @retval EFI_NOT_FOUND Fail to retrive variable of boot order.
568 BdsDeleteAllInvalidLegacyBootOptions (
573 UINT8
*BootOptionVar
;
575 UINTN BootOptionSize
;
579 HDD_INFO
*LocalHddInfo
;
580 BBS_TABLE
*LocalBbsTable
;
583 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
585 UINT16 BootOption
[10];
586 UINT16 BootDesc
[100];
587 BOOLEAN DescStringMatch
;
589 Status
= EFI_SUCCESS
;
595 LocalBbsTable
= NULL
;
598 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
599 if (EFI_ERROR (Status
)) {
603 LegacyBios
->GetBbsInfo (
611 BootOrder
= BdsLibGetVariableAndSize (
613 &gEfiGlobalVariableGuid
,
616 if (BootOrder
== NULL
) {
621 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
622 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
623 BootOptionVar
= BdsLibGetVariableAndSize (
625 &gEfiGlobalVariableGuid
,
628 if (NULL
== BootOptionVar
) {
630 Status
= gRT
->GetVariable (
632 &gEfiGlobalVariableGuid
,
637 if (Status
== EFI_NOT_FOUND
) {
641 BdsDeleteBootOption (
648 FreePool (BootOrder
);
649 return EFI_OUT_OF_RESOURCES
;
654 // Skip Non-Legacy boot option
656 if (!BdsIsLegacyBootOption (BootOptionVar
, &BbsEntry
, &BbsIndex
)) {
657 if (BootOptionVar
!= NULL
) {
658 FreePool (BootOptionVar
);
664 if (BbsIndex
< BbsCount
) {
666 // Check if BBS Description String is changed
668 DescStringMatch
= FALSE
;
669 BdsBuildLegacyDevNameString (
670 &LocalBbsTable
[BbsIndex
],
676 if (StrCmp (BootDesc
, (UINT16
*)(BootOptionVar
+ sizeof (UINT32
) + sizeof (UINT16
))) == 0) {
677 DescStringMatch
= TRUE
;
680 if (!((LocalBbsTable
[BbsIndex
].BootPriority
== BBS_IGNORE_ENTRY
) ||
681 (LocalBbsTable
[BbsIndex
].BootPriority
== BBS_DO_NOT_BOOT_FROM
)) &&
682 (LocalBbsTable
[BbsIndex
].DeviceType
== BbsEntry
->DeviceType
) &&
689 if (BootOptionVar
!= NULL
) {
690 FreePool (BootOptionVar
);
695 BdsDeleteBootOption (
703 // Adjust the number of boot options.
705 if (BootOrderSize
!= 0) {
706 Status
= gRT
->SetVariable (
708 &gEfiGlobalVariableGuid
,
714 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
717 if (BootOrder
!= NULL
) {
718 FreePool (BootOrder
);
725 Find all legacy boot option by device type.
727 @param BootOrder The boot order array.
728 @param BootOptionNum The number of boot option.
729 @param DevType Device type.
730 @param DevName Device name.
731 @param Attribute The boot option attribute.
732 @param BbsIndex The BBS table index.
733 @param OptionNumber The boot option index.
735 @retval TRUE The Legacy boot option is found.
736 @retval FALSE The legacy boot option is not found.
740 BdsFindLegacyBootOptionByDevTypeAndName (
741 IN UINT16
*BootOrder
,
742 IN UINTN BootOptionNum
,
745 OUT UINT32
*Attribute
,
746 OUT UINT16
*BbsIndex
,
747 OUT UINT16
*OptionNumber
751 CHAR16 BootOption
[9];
752 UINTN BootOptionSize
;
753 UINT8
*BootOptionVar
;
760 if (NULL
== BootOrder
) {
765 // Loop all boot option from variable
767 for (Index
= 0; Index
< BootOptionNum
; Index
++) {
768 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", (UINTN
) BootOrder
[Index
]);
769 BootOptionVar
= BdsLibGetVariableAndSize (
771 &gEfiGlobalVariableGuid
,
774 if (NULL
== BootOptionVar
) {
779 // Skip Non-legacy boot option
781 if (!BdsIsLegacyBootOption (BootOptionVar
, &BbsEntry
, BbsIndex
)) {
782 FreePool (BootOptionVar
);
787 (BbsEntry
->DeviceType
!= DevType
) ||
788 (StrCmp (DevName
, (CHAR16
*)(BootOptionVar
+ sizeof (UINT32
) + sizeof (UINT16
))) != 0)
790 FreePool (BootOptionVar
);
794 *Attribute
= *(UINT32
*) BootOptionVar
;
795 *OptionNumber
= BootOrder
[Index
];
797 FreePool (BootOptionVar
);
805 Create a legacy boot option.
807 @param BbsItem The BBS Table entry.
808 @param Index Index of the specified entry in BBS table.
809 @param BootOrderList The boot order list.
810 @param BootOrderListSize The size of boot order list.
812 @retval EFI_OUT_OF_RESOURCE No enough memory.
813 @retval EFI_SUCCESS The function complete successfully.
814 @return Other value if the legacy boot option is not created.
818 BdsCreateOneLegacyBootOption (
819 IN BBS_TABLE
*BbsItem
,
821 IN OUT UINT16
**BootOrderList
,
822 IN OUT UINTN
*BootOrderListSize
825 BBS_BBS_DEVICE_PATH BbsDevPathNode
;
827 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
832 // Create device path node.
834 BbsDevPathNode
.Header
.Type
= BBS_DEVICE_PATH
;
835 BbsDevPathNode
.Header
.SubType
= BBS_BBS_DP
;
836 SetDevicePathNodeLength (&BbsDevPathNode
.Header
, sizeof (BBS_BBS_DEVICE_PATH
));
837 BbsDevPathNode
.DeviceType
= BbsItem
->DeviceType
;
838 CopyMem (&BbsDevPathNode
.StatusFlag
, &BbsItem
->StatusFlags
, sizeof (UINT16
));
840 DevPath
= AppendDevicePathNode (
842 (EFI_DEVICE_PATH_PROTOCOL
*) &BbsDevPathNode
844 if (NULL
== DevPath
) {
845 return EFI_OUT_OF_RESOURCES
;
848 Status
= BdsCreateLegacyBootOption (
855 BbsItem
->BootPriority
= 0x00;
863 Add the legacy boot options from BBS table if they do not exist.
865 @retval EFI_SUCCESS The boot options are added successfully
866 or they are already in boot options.
867 @retval EFI_NOT_FOUND No legacy boot options is found.
868 @retval EFI_OUT_OF_RESOURCE No enough memory.
869 @return Other value LegacyBoot options are not added.
873 BdsAddNonExistingLegacyBootOptions (
883 HDD_INFO
*LocalHddInfo
;
884 BBS_TABLE
*LocalBbsTable
;
886 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
895 LocalBbsTable
= NULL
;
897 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
898 if (EFI_ERROR (Status
)) {
902 if (mBootOptionBbsMapping
!= NULL
) {
903 FreePool (mBootOptionBbsMapping
);
905 mBootOptionBbsMapping
= NULL
;
906 mBootOptionBbsMappingCount
= 0;
909 LegacyBios
->GetBbsInfo (
917 BootOrder
= BdsLibGetVariableAndSize (
919 &gEfiGlobalVariableGuid
,
922 if (BootOrder
== NULL
) {
926 for (Index
= 0; Index
< BbsCount
; Index
++) {
927 if ((LocalBbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) ||
928 (LocalBbsTable
[Index
].BootPriority
== BBS_DO_NOT_BOOT_FROM
)
933 BdsBuildLegacyDevNameString (&LocalBbsTable
[Index
], Index
, sizeof (Desc
), Desc
);
935 Exist
= BdsFindLegacyBootOptionByDevTypeAndName (
937 BootOrderSize
/ sizeof (UINT16
),
938 LocalBbsTable
[Index
].DeviceType
,
946 // Not found such type of legacy device in boot options or we found but it's disabled
947 // so we have to create one and put it to the tail of boot order list
949 Status
= BdsCreateOneLegacyBootOption (
950 &LocalBbsTable
[Index
],
955 if (EFI_ERROR (Status
)) {
959 OptionNumber
= BootOrder
[BootOrderSize
/ sizeof (UINT16
) - 1];
962 ASSERT (BbsIndex
== Index
);
966 mBootOptionBbsMapping
= ReallocatePool (
967 mBootOptionBbsMappingCount
* sizeof (BOOT_OPTION_BBS_MAPPING
),
968 (mBootOptionBbsMappingCount
+ 1) * sizeof (BOOT_OPTION_BBS_MAPPING
),
969 mBootOptionBbsMapping
971 ASSERT (mBootOptionBbsMapping
!= NULL
);
972 mBootOptionBbsMapping
[mBootOptionBbsMappingCount
].BootOptionNumber
= OptionNumber
;
973 mBootOptionBbsMapping
[mBootOptionBbsMappingCount
].BbsIndex
= Index
;
974 mBootOptionBbsMapping
[mBootOptionBbsMappingCount
].BbsType
= LocalBbsTable
[Index
].DeviceType
;
975 mBootOptionBbsMappingCount
++;
979 // Group the Boot Option Number in BootOrder for the same type devices
981 GroupMultipleLegacyBootOption4SameType (
983 BootOrderSize
/ sizeof (UINT16
)
986 if (BootOrderSize
> 0) {
987 Status
= gRT
->SetVariable (
989 &gEfiGlobalVariableGuid
,
995 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
998 if (BootOrder
!= NULL
) {
999 FreePool (BootOrder
);
1006 Fill the device order buffer.
1008 @param BbsTable The BBS table.
1009 @param BbsType The BBS Type.
1010 @param BbsCount The BBS Count.
1011 @param Buf device order buffer.
1013 @return The device order buffer.
1017 BdsFillDevOrderBuf (
1018 IN BBS_TABLE
*BbsTable
,
1019 IN BBS_TYPE BbsType
,
1026 for (Index
= 0; Index
< BbsCount
; Index
++) {
1027 if (BbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) {
1031 if (BbsTable
[Index
].DeviceType
!= BbsType
) {
1035 *Buf
= (UINT16
) (Index
& 0xFF);
1043 Create the device order buffer.
1045 @param BbsTable The BBS table.
1046 @param BbsCount The BBS Count.
1048 @retval EFI_SUCCES The buffer is created and the EFI variable named
1049 VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid is
1051 @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough.
1052 @retval EFI_DEVICE_ERROR Fail to add the device order into EFI variable fail
1053 because of hardware error.
1057 IN BBS_TABLE
*BbsTable
,
1069 LEGACY_DEV_ORDER_ENTRY
*DevOrder
;
1070 LEGACY_DEV_ORDER_ENTRY
*DevOrderPtr
;
1079 HeaderSize
= sizeof (BBS_TYPE
) + sizeof (UINT16
);
1081 Status
= EFI_SUCCESS
;
1084 // Count all boot devices
1086 for (Index
= 0; Index
< BbsCount
; Index
++) {
1087 if (BbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) {
1091 switch (BbsTable
[Index
].DeviceType
) {
1104 case BBS_EMBED_NETWORK
:
1108 case BBS_BEV_DEVICE
:
1117 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * FDCount
);
1118 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * HDCount
);
1119 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * CDCount
);
1120 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * NETCount
);
1121 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * BEVCount
);
1124 // Create buffer to hold all boot device order
1126 DevOrder
= AllocateZeroPool (TotalSize
);
1127 if (NULL
== DevOrder
) {
1128 return EFI_OUT_OF_RESOURCES
;
1130 DevOrderPtr
= DevOrder
;
1132 DevOrderPtr
->BbsType
= BBS_FLOPPY
;
1133 DevOrderPtr
->Length
= (UINT16
) (sizeof (DevOrderPtr
->Length
) + FDCount
* sizeof (UINT16
));
1134 DevOrderPtr
= (LEGACY_DEV_ORDER_ENTRY
*) BdsFillDevOrderBuf (BbsTable
, BBS_FLOPPY
, BbsCount
, DevOrderPtr
->Data
);
1136 DevOrderPtr
->BbsType
= BBS_HARDDISK
;
1137 DevOrderPtr
->Length
= (UINT16
) (sizeof (UINT16
) + HDCount
* sizeof (UINT16
));
1138 DevOrderPtr
= (LEGACY_DEV_ORDER_ENTRY
*) BdsFillDevOrderBuf (BbsTable
, BBS_HARDDISK
, BbsCount
, DevOrderPtr
->Data
);
1140 DevOrderPtr
->BbsType
= BBS_CDROM
;
1141 DevOrderPtr
->Length
= (UINT16
) (sizeof (UINT16
) + CDCount
* sizeof (UINT16
));
1142 DevOrderPtr
= (LEGACY_DEV_ORDER_ENTRY
*) BdsFillDevOrderBuf (BbsTable
, BBS_CDROM
, BbsCount
, DevOrderPtr
->Data
);
1144 DevOrderPtr
->BbsType
= BBS_EMBED_NETWORK
;
1145 DevOrderPtr
->Length
= (UINT16
) (sizeof (UINT16
) + NETCount
* sizeof (UINT16
));
1146 DevOrderPtr
= (LEGACY_DEV_ORDER_ENTRY
*) BdsFillDevOrderBuf (BbsTable
, BBS_EMBED_NETWORK
, BbsCount
, DevOrderPtr
->Data
);
1148 DevOrderPtr
->BbsType
= BBS_BEV_DEVICE
;
1149 DevOrderPtr
->Length
= (UINT16
) (sizeof (UINT16
) + BEVCount
* sizeof (UINT16
));
1150 DevOrderPtr
= (LEGACY_DEV_ORDER_ENTRY
*) BdsFillDevOrderBuf (BbsTable
, BBS_BEV_DEVICE
, BbsCount
, DevOrderPtr
->Data
);
1152 ASSERT (TotalSize
== (UINTN
) ((UINT8
*) DevOrderPtr
- (UINT8
*) DevOrder
));
1155 // Save device order for legacy boot device to variable.
1157 Status
= gRT
->SetVariable (
1158 VAR_LEGACY_DEV_ORDER
,
1159 &gEfiLegacyDevOrderVariableGuid
,
1164 FreePool (DevOrder
);
1170 Add the legacy boot devices from BBS table into
1171 the legacy device boot order.
1173 @retval EFI_SUCCESS The boot devices are added successfully.
1174 @retval EFI_NOT_FOUND The legacy boot devices are not found.
1175 @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough.
1176 @retval EFI_DEVICE_ERROR Fail to add the legacy device boot order into EFI variable
1177 because of hardware error.
1181 BdsUpdateLegacyDevOrder (
1185 LEGACY_DEV_ORDER_ENTRY
*DevOrder
;
1186 LEGACY_DEV_ORDER_ENTRY
*NewDevOrder
;
1187 LEGACY_DEV_ORDER_ENTRY
*Ptr
;
1188 LEGACY_DEV_ORDER_ENTRY
*NewPtr
;
1190 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
1194 HDD_INFO
*LocalHddInfo
;
1195 BBS_TABLE
*LocalBbsTable
;
1225 HeaderSize
= sizeof (BBS_TYPE
) + sizeof (UINT16
);
1233 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
1234 if (EFI_ERROR (Status
)) {
1238 Status
= LegacyBios
->GetBbsInfo (
1245 if (EFI_ERROR (Status
)) {
1249 DevOrder
= BdsLibGetVariableAndSize (
1250 VAR_LEGACY_DEV_ORDER
,
1251 &gEfiLegacyDevOrderVariableGuid
,
1254 if (NULL
== DevOrder
) {
1255 return BdsCreateDevOrder (LocalBbsTable
, BbsCount
);
1258 // First we figure out how many boot devices with same device type respectively
1260 for (Index
= 0; Index
< BbsCount
; Index
++) {
1261 if ((LocalBbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) ||
1262 (LocalBbsTable
[Index
].BootPriority
== BBS_DO_NOT_BOOT_FROM
)
1267 switch (LocalBbsTable
[Index
].DeviceType
) {
1280 case BBS_EMBED_NETWORK
:
1284 case BBS_BEV_DEVICE
:
1293 TotalSize
+= (HeaderSize
+ FDCount
* sizeof (UINT16
));
1294 TotalSize
+= (HeaderSize
+ HDCount
* sizeof (UINT16
));
1295 TotalSize
+= (HeaderSize
+ CDCount
* sizeof (UINT16
));
1296 TotalSize
+= (HeaderSize
+ NETCount
* sizeof (UINT16
));
1297 TotalSize
+= (HeaderSize
+ BEVCount
* sizeof (UINT16
));
1299 NewDevOrder
= AllocateZeroPool (TotalSize
);
1300 if (NULL
== NewDevOrder
) {
1301 return EFI_OUT_OF_RESOURCES
;
1310 NewPtr
= NewDevOrder
;
1311 NewPtr
->BbsType
= Ptr
->BbsType
;
1312 NewPtr
->Length
= (UINT16
) (sizeof (UINT16
) + FDCount
* sizeof (UINT16
));
1313 for (Index
= 0; Index
< Ptr
->Length
/ sizeof (UINT16
) - 1; Index
++) {
1314 if (LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_IGNORE_ENTRY
||
1315 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1316 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].DeviceType
!= BBS_FLOPPY
1321 NewPtr
->Data
[FDIndex
] = Ptr
->Data
[Index
];
1324 NewFDPtr
= NewPtr
->Data
;
1329 Ptr
= (LEGACY_DEV_ORDER_ENTRY
*) (&Ptr
->Data
[Ptr
->Length
/ sizeof (UINT16
) - 1]);
1330 NewPtr
= (LEGACY_DEV_ORDER_ENTRY
*) (&NewPtr
->Data
[NewPtr
->Length
/ sizeof (UINT16
) -1]);
1331 NewPtr
->BbsType
= Ptr
->BbsType
;
1332 NewPtr
->Length
= (UINT16
) (sizeof (UINT16
) + HDCount
* sizeof (UINT16
));
1333 for (Index
= 0; Index
< Ptr
->Length
/ sizeof (UINT16
) - 1; Index
++) {
1334 if (LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_IGNORE_ENTRY
||
1335 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1336 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_LOWEST_PRIORITY
||
1337 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].DeviceType
!= BBS_HARDDISK
1342 NewPtr
->Data
[HDIndex
] = Ptr
->Data
[Index
];
1345 NewHDPtr
= NewPtr
->Data
;
1350 Ptr
= (LEGACY_DEV_ORDER_ENTRY
*) (&Ptr
->Data
[Ptr
->Length
/ sizeof (UINT16
) - 1]);
1351 NewPtr
= (LEGACY_DEV_ORDER_ENTRY
*) (&NewPtr
->Data
[NewPtr
->Length
/ sizeof (UINT16
) -1]);
1352 NewPtr
->BbsType
= Ptr
->BbsType
;
1353 NewPtr
->Length
= (UINT16
) (sizeof (UINT16
) + CDCount
* sizeof (UINT16
));
1354 for (Index
= 0; Index
< Ptr
->Length
/ sizeof (UINT16
) - 1; Index
++) {
1355 if (LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_IGNORE_ENTRY
||
1356 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1357 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_LOWEST_PRIORITY
||
1358 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].DeviceType
!= BBS_CDROM
1363 NewPtr
->Data
[CDIndex
] = Ptr
->Data
[Index
];
1366 NewCDPtr
= NewPtr
->Data
;
1371 Ptr
= (LEGACY_DEV_ORDER_ENTRY
*) (&Ptr
->Data
[Ptr
->Length
/ sizeof (UINT16
) - 1]);
1372 NewPtr
= (LEGACY_DEV_ORDER_ENTRY
*) (&NewPtr
->Data
[NewPtr
->Length
/ sizeof (UINT16
) -1]);
1373 NewPtr
->BbsType
= Ptr
->BbsType
;
1374 NewPtr
->Length
= (UINT16
) (sizeof (UINT16
) + NETCount
* sizeof (UINT16
));
1375 for (Index
= 0; Index
< Ptr
->Length
/ sizeof (UINT16
) - 1; Index
++) {
1376 if (LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_IGNORE_ENTRY
||
1377 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1378 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_LOWEST_PRIORITY
||
1379 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].DeviceType
!= BBS_EMBED_NETWORK
1384 NewPtr
->Data
[NETIndex
] = Ptr
->Data
[Index
];
1387 NewNETPtr
= NewPtr
->Data
;
1392 Ptr
= (LEGACY_DEV_ORDER_ENTRY
*) (&Ptr
->Data
[Ptr
->Length
/ sizeof (UINT16
) - 1]);
1393 NewPtr
= (LEGACY_DEV_ORDER_ENTRY
*) (&NewPtr
->Data
[NewPtr
->Length
/ sizeof (UINT16
) -1]);
1394 NewPtr
->BbsType
= Ptr
->BbsType
;
1395 NewPtr
->Length
= (UINT16
) (sizeof (UINT16
) + BEVCount
* sizeof (UINT16
));
1396 for (Index
= 0; Index
< Ptr
->Length
/ sizeof (UINT16
) - 1; Index
++) {
1397 if (LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_IGNORE_ENTRY
||
1398 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1399 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_LOWEST_PRIORITY
||
1400 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].DeviceType
!= BBS_BEV_DEVICE
1405 NewPtr
->Data
[BEVIndex
] = Ptr
->Data
[Index
];
1408 NewBEVPtr
= NewPtr
->Data
;
1410 for (Index
= 0; Index
< BbsCount
; Index
++) {
1411 if ((LocalBbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) ||
1412 (LocalBbsTable
[Index
].BootPriority
== BBS_DO_NOT_BOOT_FROM
)
1417 switch (LocalBbsTable
[Index
].DeviceType
) {
1420 NewDevPtr
= NewFDPtr
;
1425 NewDevPtr
= NewHDPtr
;
1430 NewDevPtr
= NewCDPtr
;
1433 case BBS_EMBED_NETWORK
:
1435 NewDevPtr
= NewNETPtr
;
1438 case BBS_BEV_DEVICE
:
1440 NewDevPtr
= NewBEVPtr
;
1448 // at this point we have copied those valid indexes to new buffer
1449 // and we should check if there is any new appeared boot device
1452 for (Index2
= 0; Index2
< *Idx
; Index2
++) {
1453 if ((NewDevPtr
[Index2
] & 0xFF) == (UINT16
) Index
) {
1458 if (Index2
== *Idx
) {
1460 // Index2 == *Idx means we didn't find Index
1461 // so Index is a new appeared device's index in BBS table
1462 // insert it before disabled indexes.
1464 for (Index2
= 0; Index2
< *Idx
; Index2
++) {
1465 if ((NewDevPtr
[Index2
] & 0xFF00) == 0xFF00) {
1469 CopyMem (&NewDevPtr
[Index2
+ 1], &NewDevPtr
[Index2
], (*Idx
- Index2
) * sizeof (UINT16
));
1470 NewDevPtr
[Index2
] = (UINT16
) (Index
& 0xFF);
1476 FreePool (DevOrder
);
1478 Status
= gRT
->SetVariable (
1479 VAR_LEGACY_DEV_ORDER
,
1480 &gEfiLegacyDevOrderVariableGuid
,
1485 FreePool (NewDevOrder
);
1491 Set Boot Priority for specified device type.
1493 @param DeviceType The device type.
1494 @param BbsIndex The BBS index to set the highest priority. Ignore when -1.
1495 @param LocalBbsTable The BBS table.
1496 @param Priority The prority table.
1498 @retval EFI_SUCCESS The function completes successfully.
1499 @retval EFI_NOT_FOUND Failed to find device.
1500 @retval EFI_OUT_OF_RESOURCES Failed to get the efi variable of device order.
1504 BdsSetBootPriority4SameTypeDev (
1505 IN UINT16 DeviceType
,
1507 IN OUT BBS_TABLE
*LocalBbsTable
,
1508 IN OUT UINT16
*Priority
1511 LEGACY_DEV_ORDER_ENTRY
*DevOrder
;
1512 LEGACY_DEV_ORDER_ENTRY
*DevOrderPtr
;
1516 DevOrder
= BdsLibGetVariableAndSize (
1517 VAR_LEGACY_DEV_ORDER
,
1518 &gEfiLegacyDevOrderVariableGuid
,
1521 if (NULL
== DevOrder
) {
1522 return EFI_OUT_OF_RESOURCES
;
1525 DevOrderPtr
= DevOrder
;
1526 while ((UINT8
*) DevOrderPtr
< (UINT8
*) DevOrder
+ DevOrderSize
) {
1527 if (DevOrderPtr
->BbsType
== DeviceType
) {
1531 DevOrderPtr
= (LEGACY_DEV_ORDER_ENTRY
*) ((UINT8
*) DevOrderPtr
+ sizeof (BBS_TYPE
) + DevOrderPtr
->Length
);
1534 if ((UINT8
*) DevOrderPtr
>= (UINT8
*) DevOrder
+ DevOrderSize
) {
1535 FreePool (DevOrder
);
1536 return EFI_NOT_FOUND
;
1539 if (BbsIndex
!= (UINTN
) -1) {
1540 LocalBbsTable
[BbsIndex
].BootPriority
= *Priority
;
1544 // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled.
1546 for (Index
= 0; Index
< DevOrderPtr
->Length
/ sizeof (UINT16
) - 1; Index
++) {
1547 if ((DevOrderPtr
->Data
[Index
] & 0xFF00) == 0xFF00) {
1549 // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY;
1551 } else if (DevOrderPtr
->Data
[Index
] != BbsIndex
) {
1552 LocalBbsTable
[DevOrderPtr
->Data
[Index
]].BootPriority
= *Priority
;
1557 FreePool (DevOrder
);
1562 Print the BBS Table.
1564 @param LocalBbsTable The BBS table.
1565 @param BbsCount The count of entry in BBS table.
1569 IN BBS_TABLE
*LocalBbsTable
,
1575 DEBUG ((DEBUG_ERROR
, "\n"));
1576 DEBUG ((DEBUG_ERROR
, " NO Prio bb/dd/ff cl/sc Type Stat segm:offs\n"));
1577 DEBUG ((DEBUG_ERROR
, "=============================================\n"));
1578 for (Idx
= 0; Idx
< BbsCount
; Idx
++) {
1579 if ((LocalBbsTable
[Idx
].BootPriority
== BBS_IGNORE_ENTRY
) ||
1580 (LocalBbsTable
[Idx
].BootPriority
== BBS_DO_NOT_BOOT_FROM
) ||
1581 (LocalBbsTable
[Idx
].BootPriority
== BBS_LOWEST_PRIORITY
)
1588 " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n",
1590 (UINTN
) LocalBbsTable
[Idx
].BootPriority
,
1591 (UINTN
) LocalBbsTable
[Idx
].Bus
,
1592 (UINTN
) LocalBbsTable
[Idx
].Device
,
1593 (UINTN
) LocalBbsTable
[Idx
].Function
,
1594 (UINTN
) LocalBbsTable
[Idx
].Class
,
1595 (UINTN
) LocalBbsTable
[Idx
].SubClass
,
1596 (UINTN
) LocalBbsTable
[Idx
].DeviceType
,
1597 (UINTN
) * (UINT16
*) &LocalBbsTable
[Idx
].StatusFlags
,
1598 (UINTN
) LocalBbsTable
[Idx
].BootHandlerSegment
,
1599 (UINTN
) LocalBbsTable
[Idx
].BootHandlerOffset
,
1600 (UINTN
) ((LocalBbsTable
[Idx
].MfgStringSegment
<< 4) + LocalBbsTable
[Idx
].MfgStringOffset
),
1601 (UINTN
) ((LocalBbsTable
[Idx
].DescStringSegment
<< 4) + LocalBbsTable
[Idx
].DescStringOffset
))
1605 DEBUG ((DEBUG_ERROR
, "\n"));
1609 Set the boot priority for BBS entries based on boot option entry and boot order.
1611 @param Entry The boot option is to be checked for refresh BBS table.
1613 @retval EFI_SUCCESS The boot priority for BBS entries is refreshed successfully.
1614 @retval EFI_NOT_FOUND BBS entries can't be found.
1615 @retval EFI_OUT_OF_RESOURCES Failed to get the legacy device boot order.
1619 BdsRefreshBbsTableForBoot (
1620 IN BDS_COMMON_OPTION
*Entry
1627 HDD_INFO
*LocalHddInfo
;
1628 BBS_TABLE
*LocalBbsTable
;
1630 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
1634 UINTN BootOrderSize
;
1635 UINT8
*BootOptionVar
;
1636 UINTN BootOptionSize
;
1637 CHAR16 BootOption
[9];
1640 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
1642 UINTN DeviceTypeCount
;
1643 UINTN DeviceTypeIndex
;
1647 LocalHddInfo
= NULL
;
1648 LocalBbsTable
= NULL
;
1649 DevType
= BBS_UNKNOWN
;
1651 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
1652 if (EFI_ERROR (Status
)) {
1656 LegacyBios
->GetBbsInfo (
1664 // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY
1665 // We will set them according to the settings setup by user
1667 for (Index
= 0; Index
< BbsCount
; Index
++) {
1668 if (!((BBS_IGNORE_ENTRY
== LocalBbsTable
[Index
].BootPriority
) ||
1669 (BBS_DO_NOT_BOOT_FROM
== LocalBbsTable
[Index
].BootPriority
) ||
1670 (BBS_LOWEST_PRIORITY
== LocalBbsTable
[Index
].BootPriority
))) {
1671 LocalBbsTable
[Index
].BootPriority
= BBS_UNPRIORITIZED_ENTRY
;
1675 // boot priority always starts at 0
1678 if (Entry
->LoadOptionsSize
== sizeof (BBS_TABLE
) + sizeof (UINT16
)) {
1680 // If Entry stands for a legacy boot option, we prioritize the devices with the same type first.
1682 DevType
= ((BBS_TABLE
*) Entry
->LoadOptions
)->DeviceType
;
1683 BbsIndex
= *(UINT16
*) ((BBS_TABLE
*) Entry
->LoadOptions
+ 1);
1684 Status
= BdsSetBootPriority4SameTypeDev (
1690 if (EFI_ERROR (Status
)) {
1695 // we have to set the boot priority for other BBS entries with different device types
1697 BootOrder
= BdsLibGetVariableAndSize (
1699 &gEfiGlobalVariableGuid
,
1702 DeviceType
= AllocatePool (BootOrderSize
+ sizeof (UINT16
));
1703 ASSERT (DeviceType
!= NULL
);
1705 DeviceType
[0] = DevType
;
1706 DeviceTypeCount
= 1;
1707 for (Index
= 0; ((BootOrder
!= NULL
) && (Index
< BootOrderSize
/ sizeof (UINT16
))); Index
++) {
1708 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
1709 BootOptionVar
= BdsLibGetVariableAndSize (
1711 &gEfiGlobalVariableGuid
,
1714 if (NULL
== BootOptionVar
) {
1718 Ptr
= BootOptionVar
;
1720 Ptr
+= sizeof (UINT32
);
1721 DevPathLen
= *(UINT16
*) Ptr
;
1722 Ptr
+= sizeof (UINT16
);
1723 Ptr
+= StrSize ((UINT16
*) Ptr
);
1724 DevPath
= (EFI_DEVICE_PATH_PROTOCOL
*) Ptr
;
1725 if (BBS_DEVICE_PATH
!= DevPath
->Type
|| BBS_BBS_DP
!= DevPath
->SubType
) {
1726 FreePool (BootOptionVar
);
1731 DevType
= ((BBS_TABLE
*) Ptr
)->DeviceType
;
1732 for (DeviceTypeIndex
= 0; DeviceTypeIndex
< DeviceTypeCount
; DeviceTypeIndex
++) {
1733 if (DeviceType
[DeviceTypeIndex
] == DevType
) {
1737 if (DeviceTypeIndex
< DeviceTypeCount
) {
1739 // We don't want to process twice for a device type
1741 FreePool (BootOptionVar
);
1745 DeviceType
[DeviceTypeCount
] = DevType
;
1748 Status
= BdsSetBootPriority4SameTypeDev (
1754 FreePool (BootOptionVar
);
1755 if (EFI_ERROR (Status
)) {
1760 if (BootOrder
!= NULL
) {
1761 FreePool (BootOrder
);
1765 PrintBbsTable (LocalBbsTable
, BbsCount
);