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 while (DevOrderCount
-- != 0) {
442 for (Index
= 0; Index
< mBootOptionBbsMappingCount
; Index
++) {
443 if (mBootOptionBbsMapping
[Index
].BbsIndex
== (DevOrder
[DevOrderCount
] & 0xFF)) {
444 BbsType
= mBootOptionBbsMapping
[Index
].BbsType
;
445 NewBootOption
[DevOrderCount
] = mBootOptionBbsMapping
[Index
].BootOptionNumber
;
447 if ((DevOrder
[DevOrderCount
] & 0xFF00) == 0xFF00) {
448 DisBootOption
[*DisBootOptionCount
] = NewBootOption
[DevOrderCount
];
449 (*DisBootOptionCount
)++;
451 EnBootOption
[*EnBootOptionCount
] = NewBootOption
[DevOrderCount
];
452 (*EnBootOptionCount
)++;
459 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
461 // Find the start position for the BbsType in BootOption
463 for (MappingIndex
= 0; MappingIndex
< mBootOptionBbsMappingCount
; MappingIndex
++) {
464 if (mBootOptionBbsMapping
[MappingIndex
].BbsType
== BbsType
&& mBootOptionBbsMapping
[MappingIndex
].BootOptionNumber
== BootOption
[Index
]) {
470 // Overwrite the old BootOption
472 if (MappingIndex
< mBootOptionBbsMappingCount
) {
473 CopyMem (&BootOption
[Index
], NewBootOption
, (*DisBootOptionCount
+ *EnBootOptionCount
) * sizeof (UINT16
));
480 Group the legacy boot options in the BootOption.
482 The routine assumes the boot options in the beginning that covers all the device
483 types are ordered properly and re-position the following boot options just after
484 the corresponding boot options with the same device type.
486 1. Input = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0]
487 Assuming [Harddisk1 CdRom2 Efi1] is ordered properly
488 Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0]
490 2. Input = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2]
491 Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly
492 Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]
494 @param BootOption Pointer to buffer containing Boot Option Numbers
495 @param BootOptionCount Count of the Boot Option Numbers
498 GroupMultipleLegacyBootOption4SameType (
500 UINTN BootOptionCount
503 UINTN DeviceTypeIndex
[7];
510 SetMem (DeviceTypeIndex
, sizeof (DeviceTypeIndex
), 0xFF);
512 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
515 // Find the DeviceType
517 for (MappingIndex
= 0; MappingIndex
< mBootOptionBbsMappingCount
; MappingIndex
++) {
518 if (mBootOptionBbsMapping
[MappingIndex
].BootOptionNumber
== BootOption
[Index
]) {
522 if (MappingIndex
== mBootOptionBbsMappingCount
) {
524 // Is not a legacy boot option
529 ASSERT ((mBootOptionBbsMapping
[MappingIndex
].BbsType
& 0xF) <
530 sizeof (DeviceTypeIndex
) / sizeof (DeviceTypeIndex
[0]));
531 NextIndex
= &DeviceTypeIndex
[mBootOptionBbsMapping
[MappingIndex
].BbsType
& 0xF];
532 if (*NextIndex
== (UINTN
) -1) {
534 // *NextIndex is the index in BootOption to put the next Option Number for the same type
536 *NextIndex
= Index
+ 1;
539 // insert the current boot option before *NextIndex, causing [*Next .. Index] shift right one position
541 OptionNumber
= BootOption
[Index
];
542 CopyMem (&BootOption
[*NextIndex
+ 1], &BootOption
[*NextIndex
], (Index
- *NextIndex
) * sizeof (UINT16
));
543 BootOption
[*NextIndex
] = OptionNumber
;
546 // Update the DeviceTypeIndex array to reflect the right shift operation
548 for (DeviceIndex
= 0; DeviceIndex
< sizeof (DeviceTypeIndex
) / sizeof (DeviceTypeIndex
[0]); DeviceIndex
++) {
549 if (DeviceTypeIndex
[DeviceIndex
] != (UINTN
) -1 && DeviceTypeIndex
[DeviceIndex
] >= *NextIndex
) {
550 DeviceTypeIndex
[DeviceIndex
]++;
558 Delete all the invalid legacy boot options.
560 @retval EFI_SUCCESS All invalide legacy boot options are deleted.
561 @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory.
562 @retval EFI_NOT_FOUND Fail to retrive variable of boot order.
566 BdsDeleteAllInvalidLegacyBootOptions (
571 UINT8
*BootOptionVar
;
573 UINTN BootOptionSize
;
577 HDD_INFO
*LocalHddInfo
;
578 BBS_TABLE
*LocalBbsTable
;
581 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
583 UINT16 BootOption
[10];
584 UINT16 BootDesc
[100];
585 BOOLEAN DescStringMatch
;
587 Status
= EFI_SUCCESS
;
593 LocalBbsTable
= NULL
;
596 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
597 if (EFI_ERROR (Status
)) {
601 LegacyBios
->GetBbsInfo (
609 BootOrder
= BdsLibGetVariableAndSize (
611 &gEfiGlobalVariableGuid
,
614 if (BootOrder
== NULL
) {
619 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
620 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
621 BootOptionVar
= BdsLibGetVariableAndSize (
623 &gEfiGlobalVariableGuid
,
626 if (NULL
== BootOptionVar
) {
628 Status
= gRT
->GetVariable (
630 &gEfiGlobalVariableGuid
,
635 if (Status
== EFI_NOT_FOUND
) {
639 BdsDeleteBootOption (
646 FreePool (BootOrder
);
647 return EFI_OUT_OF_RESOURCES
;
652 // Skip Non-Legacy boot option
654 if (!BdsIsLegacyBootOption (BootOptionVar
, &BbsEntry
, &BbsIndex
)) {
655 if (BootOptionVar
!= NULL
) {
656 FreePool (BootOptionVar
);
662 if (BbsIndex
< BbsCount
) {
664 // Check if BBS Description String is changed
666 DescStringMatch
= FALSE
;
667 BdsBuildLegacyDevNameString (
668 &LocalBbsTable
[BbsIndex
],
674 if (StrCmp (BootDesc
, (UINT16
*)(BootOptionVar
+ sizeof (UINT32
) + sizeof (UINT16
))) == 0) {
675 DescStringMatch
= TRUE
;
678 if (!((LocalBbsTable
[BbsIndex
].BootPriority
== BBS_IGNORE_ENTRY
) ||
679 (LocalBbsTable
[BbsIndex
].BootPriority
== BBS_DO_NOT_BOOT_FROM
)) &&
680 (LocalBbsTable
[BbsIndex
].DeviceType
== BbsEntry
->DeviceType
) &&
687 if (BootOptionVar
!= NULL
) {
688 FreePool (BootOptionVar
);
693 BdsDeleteBootOption (
701 // Adjust the number of boot options.
703 if (BootOrderSize
!= 0) {
704 Status
= gRT
->SetVariable (
706 &gEfiGlobalVariableGuid
,
712 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
715 if (BootOrder
!= NULL
) {
716 FreePool (BootOrder
);
723 Find all legacy boot option by device type.
725 @param BootOrder The boot order array.
726 @param BootOptionNum The number of boot option.
727 @param DevType Device type.
728 @param DevName Device name.
729 @param Attribute The boot option attribute.
730 @param BbsIndex The BBS table index.
731 @param OptionNumber The boot option index.
733 @retval TRUE The Legacy boot option is found.
734 @retval FALSE The legacy boot option is not found.
738 BdsFindLegacyBootOptionByDevTypeAndName (
739 IN UINT16
*BootOrder
,
740 IN UINTN BootOptionNum
,
743 OUT UINT32
*Attribute
,
744 OUT UINT16
*BbsIndex
,
745 OUT UINT16
*OptionNumber
749 CHAR16 BootOption
[9];
750 UINTN BootOptionSize
;
751 UINT8
*BootOptionVar
;
758 if (NULL
== BootOrder
) {
763 // Loop all boot option from variable
765 for (Index
= 0; Index
< BootOptionNum
; Index
++) {
766 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", (UINTN
) BootOrder
[Index
]);
767 BootOptionVar
= BdsLibGetVariableAndSize (
769 &gEfiGlobalVariableGuid
,
772 if (NULL
== BootOptionVar
) {
777 // Skip Non-legacy boot option
779 if (!BdsIsLegacyBootOption (BootOptionVar
, &BbsEntry
, BbsIndex
)) {
780 FreePool (BootOptionVar
);
785 (BbsEntry
->DeviceType
!= DevType
) ||
786 (StrCmp (DevName
, (CHAR16
*)(BootOptionVar
+ sizeof (UINT32
) + sizeof (UINT16
))) != 0)
788 FreePool (BootOptionVar
);
792 *Attribute
= *(UINT32
*) BootOptionVar
;
793 *OptionNumber
= BootOrder
[Index
];
795 FreePool (BootOptionVar
);
803 Create a legacy boot option.
805 @param BbsItem The BBS Table entry.
806 @param Index Index of the specified entry in BBS table.
807 @param BootOrderList The boot order list.
808 @param BootOrderListSize The size of boot order list.
810 @retval EFI_OUT_OF_RESOURCE No enough memory.
811 @retval EFI_SUCCESS The function complete successfully.
812 @return Other value if the legacy boot option is not created.
816 BdsCreateOneLegacyBootOption (
817 IN BBS_TABLE
*BbsItem
,
819 IN OUT UINT16
**BootOrderList
,
820 IN OUT UINTN
*BootOrderListSize
823 BBS_BBS_DEVICE_PATH BbsDevPathNode
;
825 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
830 // Create device path node.
832 BbsDevPathNode
.Header
.Type
= BBS_DEVICE_PATH
;
833 BbsDevPathNode
.Header
.SubType
= BBS_BBS_DP
;
834 SetDevicePathNodeLength (&BbsDevPathNode
.Header
, sizeof (BBS_BBS_DEVICE_PATH
));
835 BbsDevPathNode
.DeviceType
= BbsItem
->DeviceType
;
836 CopyMem (&BbsDevPathNode
.StatusFlag
, &BbsItem
->StatusFlags
, sizeof (UINT16
));
838 DevPath
= AppendDevicePathNode (
840 (EFI_DEVICE_PATH_PROTOCOL
*) &BbsDevPathNode
842 if (NULL
== DevPath
) {
843 return EFI_OUT_OF_RESOURCES
;
846 Status
= BdsCreateLegacyBootOption (
853 BbsItem
->BootPriority
= 0x00;
861 Add the legacy boot options from BBS table if they do not exist.
863 @retval EFI_SUCCESS The boot options are added successfully
864 or they are already in boot options.
865 @retval EFI_NOT_FOUND No legacy boot options is found.
866 @retval EFI_OUT_OF_RESOURCE No enough memory.
867 @return Other value LegacyBoot options are not added.
871 BdsAddNonExistingLegacyBootOptions (
881 HDD_INFO
*LocalHddInfo
;
882 BBS_TABLE
*LocalBbsTable
;
884 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
893 LocalBbsTable
= NULL
;
895 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
896 if (EFI_ERROR (Status
)) {
900 if (mBootOptionBbsMapping
!= NULL
) {
901 FreePool (mBootOptionBbsMapping
);
903 mBootOptionBbsMapping
= NULL
;
904 mBootOptionBbsMappingCount
= 0;
907 LegacyBios
->GetBbsInfo (
915 BootOrder
= BdsLibGetVariableAndSize (
917 &gEfiGlobalVariableGuid
,
920 if (BootOrder
== NULL
) {
924 for (Index
= 0; Index
< BbsCount
; Index
++) {
925 if ((LocalBbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) ||
926 (LocalBbsTable
[Index
].BootPriority
== BBS_DO_NOT_BOOT_FROM
)
931 BdsBuildLegacyDevNameString (&LocalBbsTable
[Index
], Index
, sizeof (Desc
), Desc
);
933 Exist
= BdsFindLegacyBootOptionByDevTypeAndName (
935 BootOrderSize
/ sizeof (UINT16
),
936 LocalBbsTable
[Index
].DeviceType
,
944 // Not found such type of legacy device in boot options or we found but it's disabled
945 // so we have to create one and put it to the tail of boot order list
947 Status
= BdsCreateOneLegacyBootOption (
948 &LocalBbsTable
[Index
],
953 if (EFI_ERROR (Status
)) {
957 OptionNumber
= BootOrder
[BootOrderSize
/ sizeof (UINT16
) - 1];
960 ASSERT (BbsIndex
== Index
);
964 mBootOptionBbsMapping
= ReallocatePool (
965 mBootOptionBbsMappingCount
* sizeof (BOOT_OPTION_BBS_MAPPING
),
966 (mBootOptionBbsMappingCount
+ 1) * sizeof (BOOT_OPTION_BBS_MAPPING
),
967 mBootOptionBbsMapping
969 ASSERT (mBootOptionBbsMapping
!= NULL
);
970 mBootOptionBbsMapping
[mBootOptionBbsMappingCount
].BootOptionNumber
= OptionNumber
;
971 mBootOptionBbsMapping
[mBootOptionBbsMappingCount
].BbsIndex
= Index
;
972 mBootOptionBbsMapping
[mBootOptionBbsMappingCount
].BbsType
= LocalBbsTable
[Index
].DeviceType
;
973 mBootOptionBbsMappingCount
++;
977 // Group the Boot Option Number in BootOrder for the same type devices
979 GroupMultipleLegacyBootOption4SameType (
981 BootOrderSize
/ sizeof (UINT16
)
984 if (BootOrderSize
> 0) {
985 Status
= gRT
->SetVariable (
987 &gEfiGlobalVariableGuid
,
993 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
996 if (BootOrder
!= NULL
) {
997 FreePool (BootOrder
);
1004 Fill the device order buffer.
1006 @param BbsTable The BBS table.
1007 @param BbsType The BBS Type.
1008 @param BbsCount The BBS Count.
1009 @param Buf device order buffer.
1011 @return The device order buffer.
1015 BdsFillDevOrderBuf (
1016 IN BBS_TABLE
*BbsTable
,
1017 IN BBS_TYPE BbsType
,
1024 for (Index
= 0; Index
< BbsCount
; Index
++) {
1025 if (BbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) {
1029 if (BbsTable
[Index
].DeviceType
!= BbsType
) {
1033 *Buf
= (UINT16
) (Index
& 0xFF);
1041 Create the device order buffer.
1043 @param BbsTable The BBS table.
1044 @param BbsCount The BBS Count.
1046 @retval EFI_SUCCES The buffer is created and the EFI variable named
1047 VAR_LEGACY_DEV_ORDER and EfiLegacyDevOrderGuid is
1049 @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough.
1050 @retval EFI_DEVICE_ERROR Fail to add the device order into EFI variable fail
1051 because of hardware error.
1055 IN BBS_TABLE
*BbsTable
,
1067 BM_LEGACY_DEV_ORDER_CONTEXT
*DevOrder
;
1068 BM_LEGACY_DEV_ORDER_CONTEXT
*DevOrderPtr
;
1077 HeaderSize
= sizeof (BBS_TYPE
) + sizeof (UINT16
);
1079 Status
= EFI_SUCCESS
;
1082 // Count all boot devices
1084 for (Index
= 0; Index
< BbsCount
; Index
++) {
1085 if (BbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) {
1089 switch (BbsTable
[Index
].DeviceType
) {
1102 case BBS_EMBED_NETWORK
:
1106 case BBS_BEV_DEVICE
:
1115 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * FDCount
);
1116 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * HDCount
);
1117 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * CDCount
);
1118 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * NETCount
);
1119 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * BEVCount
);
1122 // Create buffer to hold all boot device order
1124 DevOrder
= AllocateZeroPool (TotalSize
);
1125 if (NULL
== DevOrder
) {
1126 return EFI_OUT_OF_RESOURCES
;
1128 DevOrderPtr
= DevOrder
;
1130 DevOrderPtr
->BbsType
= BBS_FLOPPY
;
1131 DevOrderPtr
->Length
= (UINT16
) (sizeof (DevOrderPtr
->Length
) + FDCount
* sizeof (UINT16
));
1132 DevOrderPtr
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) BdsFillDevOrderBuf (BbsTable
, BBS_FLOPPY
, BbsCount
, DevOrderPtr
->Data
);
1134 DevOrderPtr
->BbsType
= BBS_HARDDISK
;
1135 DevOrderPtr
->Length
= (UINT16
) (sizeof (UINT16
) + HDCount
* sizeof (UINT16
));
1136 DevOrderPtr
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) BdsFillDevOrderBuf (BbsTable
, BBS_HARDDISK
, BbsCount
, DevOrderPtr
->Data
);
1138 DevOrderPtr
->BbsType
= BBS_CDROM
;
1139 DevOrderPtr
->Length
= (UINT16
) (sizeof (UINT16
) + CDCount
* sizeof (UINT16
));
1140 DevOrderPtr
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) BdsFillDevOrderBuf (BbsTable
, BBS_CDROM
, BbsCount
, DevOrderPtr
->Data
);
1142 DevOrderPtr
->BbsType
= BBS_EMBED_NETWORK
;
1143 DevOrderPtr
->Length
= (UINT16
) (sizeof (UINT16
) + NETCount
* sizeof (UINT16
));
1144 DevOrderPtr
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) BdsFillDevOrderBuf (BbsTable
, BBS_EMBED_NETWORK
, BbsCount
, DevOrderPtr
->Data
);
1146 DevOrderPtr
->BbsType
= BBS_BEV_DEVICE
;
1147 DevOrderPtr
->Length
= (UINT16
) (sizeof (UINT16
) + BEVCount
* sizeof (UINT16
));
1148 DevOrderPtr
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) BdsFillDevOrderBuf (BbsTable
, BBS_BEV_DEVICE
, BbsCount
, DevOrderPtr
->Data
);
1150 ASSERT (TotalSize
== (UINTN
) ((UINT8
*) DevOrderPtr
- (UINT8
*) DevOrder
));
1153 // Save device order for legacy boot device to variable.
1155 Status
= gRT
->SetVariable (
1156 VAR_LEGACY_DEV_ORDER
,
1157 &EfiLegacyDevOrderGuid
,
1162 FreePool (DevOrder
);
1168 Add the legacy boot devices from BBS table into
1169 the legacy device boot order.
1171 @retval EFI_SUCCESS The boot devices are added successfully.
1172 @retval EFI_NOT_FOUND The legacy boot devices are not found.
1173 @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough.
1174 @retval EFI_DEVICE_ERROR Fail to add the legacy device boot order into EFI variable
1175 because of hardware error.
1179 BdsUpdateLegacyDevOrder (
1183 BM_LEGACY_DEV_ORDER_CONTEXT
*DevOrder
;
1184 BM_LEGACY_DEV_ORDER_CONTEXT
*NewDevOrder
;
1185 BM_LEGACY_DEV_ORDER_CONTEXT
*Ptr
;
1186 BM_LEGACY_DEV_ORDER_CONTEXT
*NewPtr
;
1188 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
1192 HDD_INFO
*LocalHddInfo
;
1193 BBS_TABLE
*LocalBbsTable
;
1223 HeaderSize
= sizeof (BBS_TYPE
) + sizeof (UINT16
);
1231 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
1232 if (EFI_ERROR (Status
)) {
1236 Status
= LegacyBios
->GetBbsInfo (
1243 if (EFI_ERROR (Status
)) {
1247 DevOrder
= BdsLibGetVariableAndSize (
1248 VAR_LEGACY_DEV_ORDER
,
1249 &EfiLegacyDevOrderGuid
,
1252 if (NULL
== DevOrder
) {
1253 return BdsCreateDevOrder (LocalBbsTable
, BbsCount
);
1256 // First we figure out how many boot devices with same device type respectively
1258 for (Index
= 0; Index
< BbsCount
; Index
++) {
1259 if ((LocalBbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) ||
1260 (LocalBbsTable
[Index
].BootPriority
== BBS_DO_NOT_BOOT_FROM
)
1265 switch (LocalBbsTable
[Index
].DeviceType
) {
1278 case BBS_EMBED_NETWORK
:
1282 case BBS_BEV_DEVICE
:
1291 TotalSize
+= (HeaderSize
+ FDCount
* sizeof (UINT16
));
1292 TotalSize
+= (HeaderSize
+ HDCount
* sizeof (UINT16
));
1293 TotalSize
+= (HeaderSize
+ CDCount
* sizeof (UINT16
));
1294 TotalSize
+= (HeaderSize
+ NETCount
* sizeof (UINT16
));
1295 TotalSize
+= (HeaderSize
+ BEVCount
* sizeof (UINT16
));
1297 NewDevOrder
= AllocateZeroPool (TotalSize
);
1298 if (NULL
== NewDevOrder
) {
1299 return EFI_OUT_OF_RESOURCES
;
1308 NewPtr
= NewDevOrder
;
1309 NewPtr
->BbsType
= Ptr
->BbsType
;
1310 NewPtr
->Length
= (UINT16
) (sizeof (UINT16
) + FDCount
* sizeof (UINT16
));
1311 for (Index
= 0; Index
< Ptr
->Length
/ sizeof (UINT16
) - 1; Index
++) {
1312 if (LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_IGNORE_ENTRY
||
1313 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1314 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].DeviceType
!= BBS_FLOPPY
1319 NewPtr
->Data
[FDIndex
] = Ptr
->Data
[Index
];
1322 NewFDPtr
= NewPtr
->Data
;
1327 Ptr
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) (&Ptr
->Data
[Ptr
->Length
/ sizeof (UINT16
) - 1]);
1328 NewPtr
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) (&NewPtr
->Data
[NewPtr
->Length
/ sizeof (UINT16
) -1]);
1329 NewPtr
->BbsType
= Ptr
->BbsType
;
1330 NewPtr
->Length
= (UINT16
) (sizeof (UINT16
) + HDCount
* sizeof (UINT16
));
1331 for (Index
= 0; Index
< Ptr
->Length
/ sizeof (UINT16
) - 1; Index
++) {
1332 if (LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_IGNORE_ENTRY
||
1333 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1334 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_LOWEST_PRIORITY
||
1335 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].DeviceType
!= BBS_HARDDISK
1340 NewPtr
->Data
[HDIndex
] = Ptr
->Data
[Index
];
1343 NewHDPtr
= NewPtr
->Data
;
1348 Ptr
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) (&Ptr
->Data
[Ptr
->Length
/ sizeof (UINT16
) - 1]);
1349 NewPtr
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) (&NewPtr
->Data
[NewPtr
->Length
/ sizeof (UINT16
) -1]);
1350 NewPtr
->BbsType
= Ptr
->BbsType
;
1351 NewPtr
->Length
= (UINT16
) (sizeof (UINT16
) + CDCount
* sizeof (UINT16
));
1352 for (Index
= 0; Index
< Ptr
->Length
/ sizeof (UINT16
) - 1; Index
++) {
1353 if (LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_IGNORE_ENTRY
||
1354 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1355 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_LOWEST_PRIORITY
||
1356 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].DeviceType
!= BBS_CDROM
1361 NewPtr
->Data
[CDIndex
] = Ptr
->Data
[Index
];
1364 NewCDPtr
= NewPtr
->Data
;
1369 Ptr
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) (&Ptr
->Data
[Ptr
->Length
/ sizeof (UINT16
) - 1]);
1370 NewPtr
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) (&NewPtr
->Data
[NewPtr
->Length
/ sizeof (UINT16
) -1]);
1371 NewPtr
->BbsType
= Ptr
->BbsType
;
1372 NewPtr
->Length
= (UINT16
) (sizeof (UINT16
) + NETCount
* sizeof (UINT16
));
1373 for (Index
= 0; Index
< Ptr
->Length
/ sizeof (UINT16
) - 1; Index
++) {
1374 if (LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_IGNORE_ENTRY
||
1375 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1376 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_LOWEST_PRIORITY
||
1377 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].DeviceType
!= BBS_EMBED_NETWORK
1382 NewPtr
->Data
[NETIndex
] = Ptr
->Data
[Index
];
1385 NewNETPtr
= NewPtr
->Data
;
1390 Ptr
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) (&Ptr
->Data
[Ptr
->Length
/ sizeof (UINT16
) - 1]);
1391 NewPtr
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) (&NewPtr
->Data
[NewPtr
->Length
/ sizeof (UINT16
) -1]);
1392 NewPtr
->BbsType
= Ptr
->BbsType
;
1393 NewPtr
->Length
= (UINT16
) (sizeof (UINT16
) + BEVCount
* sizeof (UINT16
));
1394 for (Index
= 0; Index
< Ptr
->Length
/ sizeof (UINT16
) - 1; Index
++) {
1395 if (LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_IGNORE_ENTRY
||
1396 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1397 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].BootPriority
== BBS_LOWEST_PRIORITY
||
1398 LocalBbsTable
[Ptr
->Data
[Index
] & 0xFF].DeviceType
!= BBS_BEV_DEVICE
1403 NewPtr
->Data
[BEVIndex
] = Ptr
->Data
[Index
];
1406 NewBEVPtr
= NewPtr
->Data
;
1408 for (Index
= 0; Index
< BbsCount
; Index
++) {
1409 if ((LocalBbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) ||
1410 (LocalBbsTable
[Index
].BootPriority
== BBS_DO_NOT_BOOT_FROM
)
1415 switch (LocalBbsTable
[Index
].DeviceType
) {
1418 NewDevPtr
= NewFDPtr
;
1423 NewDevPtr
= NewHDPtr
;
1428 NewDevPtr
= NewCDPtr
;
1431 case BBS_EMBED_NETWORK
:
1433 NewDevPtr
= NewNETPtr
;
1436 case BBS_BEV_DEVICE
:
1438 NewDevPtr
= NewBEVPtr
;
1446 // at this point we have copied those valid indexes to new buffer
1447 // and we should check if there is any new appeared boot device
1450 for (Index2
= 0; Index2
< *Idx
; Index2
++) {
1451 if ((NewDevPtr
[Index2
] & 0xFF) == (UINT16
) Index
) {
1456 if (Index2
== *Idx
) {
1458 // Index2 == *Idx means we didn't find Index
1459 // so Index is a new appeared device's index in BBS table
1460 // insert it before disabled indexes.
1462 for (Index2
= 0; Index2
< *Idx
; Index2
++) {
1463 if ((NewDevPtr
[Index2
] & 0xFF00) == 0xFF00) {
1467 CopyMem (&NewDevPtr
[Index2
+ 1], &NewDevPtr
[Index2
], (*Idx
- Index2
) * sizeof (UINT16
));
1468 NewDevPtr
[Index2
] = (UINT16
) (Index
& 0xFF);
1474 FreePool (DevOrder
);
1476 Status
= gRT
->SetVariable (
1477 VAR_LEGACY_DEV_ORDER
,
1478 &EfiLegacyDevOrderGuid
,
1483 FreePool (NewDevOrder
);
1489 Set Boot Priority for specified device type.
1491 @param DeviceType The device type.
1492 @param BbsIndex The BBS index to set the highest priority. Ignore when -1.
1493 @param LocalBbsTable The BBS table.
1494 @param Priority The prority table.
1496 @retval EFI_SUCCESS The function completes successfully.
1497 @retval EFI_NOT_FOUND Failed to find device.
1498 @retval EFI_OUT_OF_RESOURCES Failed to get the efi variable of device order.
1502 BdsSetBootPriority4SameTypeDev (
1503 IN UINT16 DeviceType
,
1505 IN OUT BBS_TABLE
*LocalBbsTable
,
1506 IN OUT UINT16
*Priority
1509 BM_LEGACY_DEV_ORDER_CONTEXT
*DevOrder
;
1510 BM_LEGACY_DEV_ORDER_CONTEXT
*DevOrderPtr
;
1514 DevOrder
= BdsLibGetVariableAndSize (
1515 VAR_LEGACY_DEV_ORDER
,
1516 &EfiLegacyDevOrderGuid
,
1519 if (NULL
== DevOrder
) {
1520 return EFI_OUT_OF_RESOURCES
;
1523 DevOrderPtr
= DevOrder
;
1524 while ((UINT8
*) DevOrderPtr
< (UINT8
*) DevOrder
+ DevOrderSize
) {
1525 if (DevOrderPtr
->BbsType
== DeviceType
) {
1529 DevOrderPtr
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) ((UINT8
*) DevOrderPtr
+ sizeof (BBS_TYPE
) + DevOrderPtr
->Length
);
1532 if ((UINT8
*) DevOrderPtr
>= (UINT8
*) DevOrder
+ DevOrderSize
) {
1533 FreePool (DevOrder
);
1534 return EFI_NOT_FOUND
;
1537 if (BbsIndex
!= (UINTN
) -1) {
1538 LocalBbsTable
[BbsIndex
].BootPriority
= *Priority
;
1542 // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled.
1544 for (Index
= 0; Index
< DevOrderPtr
->Length
/ sizeof (UINT16
) - 1; Index
++) {
1545 if ((DevOrderPtr
->Data
[Index
] & 0xFF00) == 0xFF00) {
1547 // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY;
1549 } else if (DevOrderPtr
->Data
[Index
] != BbsIndex
) {
1550 LocalBbsTable
[DevOrderPtr
->Data
[Index
]].BootPriority
= *Priority
;
1555 FreePool (DevOrder
);
1560 Print the BBS Table.
1562 @param LocalBbsTable The BBS table.
1563 @param BbsCount The count of entry in BBS table.
1567 IN BBS_TABLE
*LocalBbsTable
,
1573 DEBUG ((DEBUG_ERROR
, "\n"));
1574 DEBUG ((DEBUG_ERROR
, " NO Prio bb/dd/ff cl/sc Type Stat segm:offs\n"));
1575 DEBUG ((DEBUG_ERROR
, "=============================================\n"));
1576 for (Idx
= 0; Idx
< BbsCount
; Idx
++) {
1577 if ((LocalBbsTable
[Idx
].BootPriority
== BBS_IGNORE_ENTRY
) ||
1578 (LocalBbsTable
[Idx
].BootPriority
== BBS_DO_NOT_BOOT_FROM
) ||
1579 (LocalBbsTable
[Idx
].BootPriority
== BBS_LOWEST_PRIORITY
)
1586 " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n",
1588 (UINTN
) LocalBbsTable
[Idx
].BootPriority
,
1589 (UINTN
) LocalBbsTable
[Idx
].Bus
,
1590 (UINTN
) LocalBbsTable
[Idx
].Device
,
1591 (UINTN
) LocalBbsTable
[Idx
].Function
,
1592 (UINTN
) LocalBbsTable
[Idx
].Class
,
1593 (UINTN
) LocalBbsTable
[Idx
].SubClass
,
1594 (UINTN
) LocalBbsTable
[Idx
].DeviceType
,
1595 (UINTN
) * (UINT16
*) &LocalBbsTable
[Idx
].StatusFlags
,
1596 (UINTN
) LocalBbsTable
[Idx
].BootHandlerSegment
,
1597 (UINTN
) LocalBbsTable
[Idx
].BootHandlerOffset
,
1598 (UINTN
) ((LocalBbsTable
[Idx
].MfgStringSegment
<< 4) + LocalBbsTable
[Idx
].MfgStringOffset
),
1599 (UINTN
) ((LocalBbsTable
[Idx
].DescStringSegment
<< 4) + LocalBbsTable
[Idx
].DescStringOffset
))
1603 DEBUG ((DEBUG_ERROR
, "\n"));
1607 Set the boot priority for BBS entries based on boot option entry and boot order.
1609 @param Entry The boot option is to be checked for refresh BBS table.
1611 @retval EFI_SUCCESS The boot priority for BBS entries is refreshed successfully.
1612 @retval EFI_NOT_FOUND BBS entries can't be found.
1613 @retval EFI_OUT_OF_RESOURCES Failed to get the legacy device boot order.
1617 BdsRefreshBbsTableForBoot (
1618 IN BDS_COMMON_OPTION
*Entry
1625 HDD_INFO
*LocalHddInfo
;
1626 BBS_TABLE
*LocalBbsTable
;
1628 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
1632 UINTN BootOrderSize
;
1633 UINT8
*BootOptionVar
;
1634 UINTN BootOptionSize
;
1635 CHAR16 BootOption
[9];
1638 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
1640 UINTN DeviceTypeCount
;
1641 UINTN DeviceTypeIndex
;
1645 LocalHddInfo
= NULL
;
1646 LocalBbsTable
= NULL
;
1647 DevType
= BBS_UNKNOWN
;
1649 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
1650 if (EFI_ERROR (Status
)) {
1654 LegacyBios
->GetBbsInfo (
1662 // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY
1663 // We will set them according to the settings setup by user
1665 for (Index
= 0; Index
< BbsCount
; Index
++) {
1666 if (!((BBS_IGNORE_ENTRY
== LocalBbsTable
[Index
].BootPriority
) ||
1667 (BBS_DO_NOT_BOOT_FROM
== LocalBbsTable
[Index
].BootPriority
) ||
1668 (BBS_LOWEST_PRIORITY
== LocalBbsTable
[Index
].BootPriority
))) {
1669 LocalBbsTable
[Index
].BootPriority
= BBS_UNPRIORITIZED_ENTRY
;
1673 // boot priority always starts at 0
1676 if (Entry
->LoadOptionsSize
== sizeof (BBS_TABLE
) + sizeof (UINT16
)) {
1678 // If Entry stands for a legacy boot option, we prioritize the devices with the same type first.
1680 DevType
= ((BBS_TABLE
*) Entry
->LoadOptions
)->DeviceType
;
1681 BbsIndex
= *(UINT16
*) ((BBS_TABLE
*) Entry
->LoadOptions
+ 1);
1682 Status
= BdsSetBootPriority4SameTypeDev (
1688 if (EFI_ERROR (Status
)) {
1693 // we have to set the boot priority for other BBS entries with different device types
1695 BootOrder
= BdsLibGetVariableAndSize (
1697 &gEfiGlobalVariableGuid
,
1700 DeviceType
= AllocatePool (BootOrderSize
+ sizeof (UINT16
));
1701 ASSERT (DeviceType
!= NULL
);
1703 DeviceType
[0] = DevType
;
1704 DeviceTypeCount
= 1;
1705 for (Index
= 0; ((BootOrder
!= NULL
) && (Index
< BootOrderSize
/ sizeof (UINT16
))); Index
++) {
1706 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
1707 BootOptionVar
= BdsLibGetVariableAndSize (
1709 &gEfiGlobalVariableGuid
,
1712 if (NULL
== BootOptionVar
) {
1716 Ptr
= BootOptionVar
;
1718 Ptr
+= sizeof (UINT32
);
1719 DevPathLen
= *(UINT16
*) Ptr
;
1720 Ptr
+= sizeof (UINT16
);
1721 Ptr
+= StrSize ((UINT16
*) Ptr
);
1722 DevPath
= (EFI_DEVICE_PATH_PROTOCOL
*) Ptr
;
1723 if (BBS_DEVICE_PATH
!= DevPath
->Type
|| BBS_BBS_DP
!= DevPath
->SubType
) {
1724 FreePool (BootOptionVar
);
1729 DevType
= ((BBS_TABLE
*) Ptr
)->DeviceType
;
1730 for (DeviceTypeIndex
= 0; DeviceTypeIndex
< DeviceTypeCount
; DeviceTypeIndex
++) {
1731 if (DeviceType
[DeviceTypeIndex
] == DevType
) {
1735 if (DeviceTypeIndex
< DeviceTypeCount
) {
1737 // We don't want to process twice for a device type
1739 FreePool (BootOptionVar
);
1743 DeviceType
[DeviceTypeCount
] = DevType
;
1746 Status
= BdsSetBootPriority4SameTypeDev (
1752 FreePool (BootOptionVar
);
1753 if (EFI_ERROR (Status
)) {
1758 if (BootOrder
!= NULL
) {
1759 FreePool (BootOrder
);
1763 PrintBbsTable (LocalBbsTable
, BbsCount
);