3 * CSM/legacy boot support functions
5 * Taken from Tianocore source code (mostly IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c)
7 * Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
8 * This program and the accompanying materials
9 * are licensed and made available under the terms and conditions of the BSD License
10 * which accompanies this distribution. The full text of the license may be found at
11 * http://opensource.org/licenses/bsd-license.php
13 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #ifdef __MAKEWITH_GNUEFI
21 #include "gnuefi-helper.h"
22 #define EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH
23 #define EfiReallocatePool ReallocatePool
24 #define EfiLibLocateProtocol LibLocateProtocol
26 #include "../include/tiano_includes.h"
29 #include "GenericBdsLib.h"
30 #include "../refind/global.h"
31 #include "../include/refit_call_wrapper.h"
33 BOOT_OPTION_BBS_MAPPING
*mBootOptionBbsMapping
= NULL
;
34 UINTN mBootOptionBbsMappingCount
= 0;
36 extern EFI_DEVICE_PATH EndDevicePath
[];
37 extern EFI_GUID gEfiLegacyBiosProtocolGuid
;
38 EFI_GUID gEfiLegacyDevOrderVariableGuid
= { 0xa56074db, 0x65fe, 0x45f7, {0xbd, 0x21, 0x2d, 0x2b, 0xdd, 0x8e, 0x96, 0x52 }};
42 Translate the first n characters of an Ascii string to
43 Unicode characters. The count n is indicated by parameter
44 Size. If Size is greater than the length of string, then
45 the entire string is translated.
48 @param AStr Pointer to input Ascii string.
49 @param Size The number of characters to translate.
50 @param UStr Pointer to output Unicode string buffer.
63 while (AStr
[Idx
] != 0) {
64 UStr
[Idx
] = (CHAR16
) AStr
[Idx
];
75 Build Legacy Device Name String according.
77 @param CurBBSEntry BBS Table.
79 @param BufSize The buffer size.
80 @param BootString The output string.
84 BdsBuildLegacyDevNameString (
85 IN BBS_TABLE
*CurBBSEntry
,
88 OUT CHAR16
*BootString
101 Fmt
= L
"Primary Master %s";
108 Fmt
= L
"Primary Slave %s";
115 Fmt
= L
"Secondary Master %s";
122 Fmt
= L
"Secondary Slave %s";
130 switch (CurBBSEntry
->DeviceType
) {
151 case BBS_EMBED_NETWORK
:
165 // If current BBS entry has its description then use it.
167 StringDesc
= (UINT8
*) (UINTN
) ((CurBBSEntry
->DescStringSegment
<< 4) + CurBBSEntry
->DescStringOffset
);
168 if (NULL
!= StringDesc
) {
170 // Only get fisrt 32 characters, this is suggested by BBS spec
172 AsciiToUnicodeSize (StringDesc
, 32, Temp
);
178 // BbsTable 16 entries are for onboard IDE.
179 // Set description string for SATA harddisks, Harddisk 0 ~ Harddisk 11
181 if (Index
>= 5 && Index
<= 16 && (CurBBSEntry
->DeviceType
== BBS_HARDDISK
|| CurBBSEntry
->DeviceType
== BBS_CDROM
)) {
183 UnicodeSPrint (BootString
, BufSize
, Fmt
, Type
, Index
- 5);
185 UnicodeSPrint (BootString
, BufSize
, Fmt
, Type
);
190 Check if the boot option is a legacy one.
192 @param BootOptionVar The boot option data payload.
193 @param BbsEntry The BBS Table.
194 @param BbsIndex The table index.
196 @retval TRUE It is a legacy boot option.
197 @retval FALSE It is not a legacy boot option.
201 BdsIsLegacyBootOption (
202 IN UINT8
*BootOptionVar
,
203 OUT BBS_TABLE
**BbsEntry
,
208 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
213 Ptr
+= sizeof (UINT32
);
214 DevPathLen
= *(UINT16
*) Ptr
;
215 Ptr
+= sizeof (UINT16
);
216 Ptr
+= StrSize ((UINT16
*) Ptr
);
217 DevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) Ptr
;
218 if ((BBS_DEVICE_PATH
== DevicePath
->Type
) && (BBS_BBS_DP
== DevicePath
->SubType
)) {
220 *BbsEntry
= (BBS_TABLE
*) Ptr
;
221 Ptr
+= sizeof (BBS_TABLE
);
222 *BbsIndex
= *(UINT16
*) Ptr
;
233 Find all legacy boot option by device type.
235 @param BootOrder The boot order array.
236 @param BootOptionNum The number of boot option.
237 @param DevType Device type.
238 @param DevName Device name.
239 @param Attribute The boot option attribute.
240 @param BbsIndex The BBS table index.
241 @param OptionNumber The boot option index.
243 @retval TRUE The Legacy boot option is found.
244 @retval FALSE The legacy boot option is not found.
248 BdsFindLegacyBootOptionByDevTypeAndName (
249 IN UINT16
*BootOrder
,
250 IN UINTN BootOptionNum
,
253 OUT UINT32
*Attribute
,
254 OUT UINT16
*BbsIndex
,
255 OUT UINT16
*OptionNumber
259 CHAR16 BootOption
[10];
260 UINTN BootOptionSize
;
261 UINT8
*BootOptionVar
;
268 if (NULL
== BootOrder
) {
273 // Loop all boot option from variable
275 for (Index
= 0; Index
< BootOptionNum
; Index
++) {
276 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", (UINTN
) BootOrder
[Index
]);
277 BootOptionVar
= BdsLibGetVariableAndSize (
279 &gEfiGlobalVariableGuid
,
282 if (NULL
== BootOptionVar
) {
287 // Skip Non-legacy boot option
289 if (!BdsIsLegacyBootOption (BootOptionVar
, &BbsEntry
, BbsIndex
)) {
290 FreePool (BootOptionVar
);
295 (BbsEntry
->DeviceType
!= DevType
) ||
296 (StrCmp (DevName
, (CHAR16
*)(BootOptionVar
+ sizeof (UINT32
) + sizeof (UINT16
))) != 0)
298 FreePool (BootOptionVar
);
302 *Attribute
= *(UINT32
*) BootOptionVar
;
303 *OptionNumber
= BootOrder
[Index
];
305 FreePool (BootOptionVar
);
314 Create a legacy boot option for the specified entry of
315 BBS table, save it as variable, and append it to the boot
319 @param CurrentBbsEntry Pointer to current BBS table.
320 @param CurrentBbsDevPath Pointer to the Device Path Protocol instance of BBS
321 @param Index Index of the specified entry in BBS table.
322 @param BootOrderList On input, the original boot order list.
323 On output, the new boot order list attached with the
325 @param BootOrderListSize On input, the original size of boot order list.
326 On output, the size of new boot order list.
328 @retval EFI_SUCCESS Boot Option successfully created.
329 @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory.
330 @retval Other Error occurs while setting variable.
334 BdsCreateLegacyBootOption (
335 IN BBS_TABLE
*CurrentBbsEntry
,
336 IN EFI_DEVICE_PATH_PROTOCOL
*CurrentBbsDevPath
,
338 IN OUT UINT16
**BootOrderList
,
339 IN OUT UINTN
*BootOrderListSize
343 UINT16 CurrentBootOptionNo
;
344 UINT16 BootString
[10];
345 CHAR16 BootDesc
[100];
346 CHAR8 HelpString
[100];
347 UINT16
*NewBootOrderList
;
352 UINT16 CurrentBbsDevPathSize
;
353 UINTN BootOrderIndex
;
354 UINTN BootOrderLastIndex
;
356 BOOLEAN IndexNotFound
;
357 BBS_BBS_DEVICE_PATH
*NewBbsDevPathNode
;
359 if ((*BootOrderList
) == NULL
) {
360 CurrentBootOptionNo
= 0;
362 for (ArrayIndex
= 0; ArrayIndex
< (UINTN
) (*BootOrderListSize
/ sizeof (UINT16
)); ArrayIndex
++) {
363 IndexNotFound
= TRUE
;
364 for (BootOrderIndex
= 0; BootOrderIndex
< (UINTN
) (*BootOrderListSize
/ sizeof (UINT16
)); BootOrderIndex
++) {
365 if ((*BootOrderList
)[BootOrderIndex
] == ArrayIndex
) {
366 IndexNotFound
= FALSE
;
371 if (!IndexNotFound
) {
378 CurrentBootOptionNo
= (UINT16
) ArrayIndex
;
388 BdsBuildLegacyDevNameString (CurrentBbsEntry
, Index
, sizeof (BootDesc
), BootDesc
);
391 // Create new BBS device path node with description string
393 UnicodeStrToAsciiStr (BootDesc
, HelpString
);
395 StringLen
= AsciiStrLen (HelpString
);
396 NewBbsDevPathNode
= AllocateZeroPool (sizeof (BBS_BBS_DEVICE_PATH
) + StringLen
);
397 if (NewBbsDevPathNode
== NULL
) {
398 return EFI_OUT_OF_RESOURCES
;
400 CopyMem (NewBbsDevPathNode
, CurrentBbsDevPath
, sizeof (BBS_BBS_DEVICE_PATH
));
401 CopyMem (NewBbsDevPathNode
->String
, HelpString
, StringLen
+ 1);
402 SetDevicePathNodeLength (&(NewBbsDevPathNode
->Header
), sizeof (BBS_BBS_DEVICE_PATH
) + StringLen
);
405 // Create entire new CurrentBbsDevPath with end node
407 CurrentBbsDevPath
= AppendDevicePathNode (
409 (EFI_DEVICE_PATH_PROTOCOL
*) NewBbsDevPathNode
411 if (CurrentBbsDevPath
== NULL
) {
412 FreePool (NewBbsDevPathNode
);
413 return EFI_OUT_OF_RESOURCES
;
416 CurrentBbsDevPathSize
= (UINT16
) (GetDevicePathSize (CurrentBbsDevPath
));
418 BufferSize
= sizeof (UINT32
) +
421 CurrentBbsDevPathSize
+
425 Buffer
= AllocateZeroPool (BufferSize
);
426 if (Buffer
== NULL
) {
427 FreePool (NewBbsDevPathNode
);
428 FreePool (CurrentBbsDevPath
);
429 return EFI_OUT_OF_RESOURCES
;
432 Ptr
= (UINT8
*) Buffer
;
434 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
435 Ptr
+= sizeof (UINT32
);
437 *((UINT16
*) Ptr
) = CurrentBbsDevPathSize
;
438 Ptr
+= sizeof (UINT16
);
445 Ptr
+= StrSize (BootDesc
);
450 CurrentBbsDevPathSize
452 Ptr
+= CurrentBbsDevPathSize
;
460 Ptr
+= sizeof (BBS_TABLE
);
461 *((UINT16
*) Ptr
) = (UINT16
) Index
;
463 Status
= refit_call5_wrapper(gRT
->SetVariable
,
465 &gEfiGlobalVariableGuid
,
475 NewBootOrderList
= AllocateZeroPool (*BootOrderListSize
+ sizeof (UINT16
));
476 if (NULL
== NewBootOrderList
) {
477 FreePool (NewBbsDevPathNode
);
478 FreePool (CurrentBbsDevPath
);
479 return EFI_OUT_OF_RESOURCES
;
482 if (*BootOrderList
!= NULL
) {
483 CopyMem (NewBootOrderList
, *BootOrderList
, *BootOrderListSize
);
484 FreePool (*BootOrderList
);
487 BootOrderLastIndex
= (UINTN
) (*BootOrderListSize
/ sizeof (UINT16
));
488 NewBootOrderList
[BootOrderLastIndex
] = CurrentBootOptionNo
;
489 *BootOrderListSize
+= sizeof (UINT16
);
490 *BootOrderList
= NewBootOrderList
;
492 FreePool (NewBbsDevPathNode
);
493 FreePool (CurrentBbsDevPath
);
498 Create a legacy boot option.
500 @param BbsItem The BBS Table entry.
501 @param Index Index of the specified entry in BBS table.
502 @param BootOrderList The boot order list.
503 @param BootOrderListSize The size of boot order list.
505 @retval EFI_OUT_OF_RESOURCE No enough memory.
506 @retval EFI_SUCCESS The function complete successfully.
507 @return Other value if the legacy boot option is not created.
511 BdsCreateOneLegacyBootOption (
512 IN BBS_TABLE
*BbsItem
,
514 IN OUT UINT16
**BootOrderList
,
515 IN OUT UINTN
*BootOrderListSize
518 BBS_BBS_DEVICE_PATH BbsDevPathNode
;
520 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
525 // Create device path node.
527 BbsDevPathNode
.Header
.Type
= BBS_DEVICE_PATH
;
528 BbsDevPathNode
.Header
.SubType
= BBS_BBS_DP
;
529 SetDevicePathNodeLength (&BbsDevPathNode
.Header
, sizeof (BBS_BBS_DEVICE_PATH
));
530 BbsDevPathNode
.DeviceType
= BbsItem
->DeviceType
;
531 CopyMem (&BbsDevPathNode
.StatusFlag
, &BbsItem
->StatusFlags
, sizeof (UINT16
));
533 DevPath
= AppendDevicePathNode (
535 (EFI_DEVICE_PATH_PROTOCOL
*) &BbsDevPathNode
537 if (NULL
== DevPath
) {
538 return EFI_OUT_OF_RESOURCES
;
541 Status
= BdsCreateLegacyBootOption (
548 BbsItem
->BootPriority
= 0x00;
556 Group the legacy boot options in the BootOption.
558 The routine assumes the boot options in the beginning that covers all the device
559 types are ordered properly and re-position the following boot options just after
560 the corresponding boot options with the same device type.
562 1. Input = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0]
563 Assuming [Harddisk1 CdRom2 Efi1] is ordered properly
564 Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0]
566 2. Input = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2]
567 Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly
568 Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]
570 @param BootOption Pointer to buffer containing Boot Option Numbers
571 @param BootOptionCount Count of the Boot Option Numbers
574 GroupMultipleLegacyBootOption4SameType (
576 UINTN BootOptionCount
579 UINTN DeviceTypeIndex
[7];
586 SetMem (DeviceTypeIndex
, sizeof (DeviceTypeIndex
), 0xFF);
588 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
591 // Find the DeviceType
593 for (MappingIndex
= 0; MappingIndex
< mBootOptionBbsMappingCount
; MappingIndex
++) {
594 if (mBootOptionBbsMapping
[MappingIndex
].BootOptionNumber
== BootOption
[Index
]) {
598 if (MappingIndex
== mBootOptionBbsMappingCount
) {
600 // Is not a legacy boot option
605 ASSERT ((mBootOptionBbsMapping
[MappingIndex
].BbsType
& 0xF) <
606 sizeof (DeviceTypeIndex
) / sizeof (DeviceTypeIndex
[0]));
607 NextIndex
= &DeviceTypeIndex
[mBootOptionBbsMapping
[MappingIndex
].BbsType
& 0xF];
608 if (*NextIndex
== (UINTN
) -1) {
610 // *NextIndex is the index in BootOption to put the next Option Number for the same type
612 *NextIndex
= Index
+ 1;
615 // insert the current boot option before *NextIndex, causing [*Next .. Index] shift right one position
617 OptionNumber
= BootOption
[Index
];
618 CopyMem (&BootOption
[*NextIndex
+ 1], &BootOption
[*NextIndex
], (Index
- *NextIndex
) * sizeof (UINT16
));
619 BootOption
[*NextIndex
] = OptionNumber
;
622 // Update the DeviceTypeIndex array to reflect the right shift operation
624 for (DeviceIndex
= 0; DeviceIndex
< sizeof (DeviceTypeIndex
) / sizeof (DeviceTypeIndex
[0]); DeviceIndex
++) {
625 if (DeviceTypeIndex
[DeviceIndex
] != (UINTN
) -1 && DeviceTypeIndex
[DeviceIndex
] >= *NextIndex
) {
626 DeviceTypeIndex
[DeviceIndex
]++;
634 Function returns the value of the specified variable.
637 @param Name A Null-terminated Unicode string that is
638 the name of the vendor's variable.
639 @param VendorGuid A unique identifier for the vendor.
641 @return The payload of the variable.
642 @retval NULL If the variable can't be read.
648 IN EFI_GUID
*VendorGuid
653 return BdsLibGetVariableAndSize (Name
, VendorGuid
, &VarSize
);
657 Function deletes the variable specified by VarName and VarGuid.
659 @param VarName A Null-terminated Unicode string that is
660 the name of the vendor's variable.
662 @param VarGuid A unique identifier for the vendor.
664 @retval EFI_SUCCESS The variable was found and removed
665 @retval EFI_UNSUPPORTED The variable store was inaccessible
666 @retval EFI_OUT_OF_RESOURCES The temporary buffer was not available
667 @retval EFI_NOT_FOUND The variable was not found
671 EfiLibDeleteVariable (
679 VarBuf
= EfiLibGetVariable (VarName
, VarGuid
);
680 Status
= EFI_NOT_FOUND
;
682 if (VarBuf
!= NULL
) {
684 // Delete variable from Storage
686 Status
= refit_call5_wrapper(gRT
->SetVariable
, VarName
, VarGuid
, VAR_FLAG
, 0, NULL
);
687 ASSERT (!EFI_ERROR (Status
));
695 Add the legacy boot options from BBS table if they do not exist.
697 @retval EFI_SUCCESS The boot options are added successfully
698 or they are already in boot options.
699 @retval EFI_NOT_FOUND No legacy boot options is found.
700 @retval EFI_OUT_OF_RESOURCE No enough memory.
701 @return Other value LegacyBoot options are not added.
704 BdsAddNonExistingLegacyBootOptions (
714 HDD_INFO
*LocalHddInfo
;
715 BBS_TABLE
*LocalBbsTable
;
717 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
726 LocalBbsTable
= NULL
;
728 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
729 if (EFI_ERROR (Status
)) {
733 if (mBootOptionBbsMapping
!= NULL
) {
734 FreePool (mBootOptionBbsMapping
);
736 mBootOptionBbsMapping
= NULL
;
737 mBootOptionBbsMappingCount
= 0;
740 refit_call5_wrapper(LegacyBios
->GetBbsInfo
,
748 BootOrder
= BdsLibGetVariableAndSize (
750 &gEfiGlobalVariableGuid
,
753 if (BootOrder
== NULL
) {
757 for (Index
= 0; Index
< BbsCount
; Index
++) {
758 if ((LocalBbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) ||
759 (LocalBbsTable
[Index
].BootPriority
== BBS_DO_NOT_BOOT_FROM
)
764 BdsBuildLegacyDevNameString (&LocalBbsTable
[Index
], Index
, sizeof (Desc
), Desc
);
766 Exist
= BdsFindLegacyBootOptionByDevTypeAndName (
768 BootOrderSize
/ sizeof (UINT16
),
769 LocalBbsTable
[Index
].DeviceType
,
777 // Not found such type of legacy device in boot options or we found but it's disabled
778 // so we have to create one and put it to the tail of boot order list
780 Status
= BdsCreateOneLegacyBootOption (
781 &LocalBbsTable
[Index
],
786 if (EFI_ERROR (Status
)) {
790 OptionNumber
= BootOrder
[BootOrderSize
/ sizeof (UINT16
) - 1];
793 ASSERT (BbsIndex
== Index
);
797 mBootOptionBbsMapping
= EfiReallocatePool (
798 mBootOptionBbsMapping
,
799 mBootOptionBbsMappingCount
* sizeof (BOOT_OPTION_BBS_MAPPING
),
800 (mBootOptionBbsMappingCount
+ 1) * sizeof (BOOT_OPTION_BBS_MAPPING
)
802 ASSERT (mBootOptionBbsMapping
!= NULL
);
803 mBootOptionBbsMapping
[mBootOptionBbsMappingCount
].BootOptionNumber
= OptionNumber
;
804 mBootOptionBbsMapping
[mBootOptionBbsMappingCount
].BbsIndex
= Index
;
805 mBootOptionBbsMapping
[mBootOptionBbsMappingCount
].BbsType
= LocalBbsTable
[Index
].DeviceType
;
806 mBootOptionBbsMappingCount
++;
810 // Group the Boot Option Number in BootOrder for the same type devices
812 GroupMultipleLegacyBootOption4SameType (
814 BootOrderSize
/ sizeof (UINT16
)
817 if (BootOrderSize
> 0) {
818 Status
= refit_call5_wrapper(gRT
->SetVariable
,
820 &gEfiGlobalVariableGuid
,
826 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
829 if (BootOrder
!= NULL
) {
830 FreePool (BootOrder
);
837 Deletete the Boot Option from EFI Variable. The Boot Order Arrray
840 @param OptionNumber The number of Boot option want to be deleted.
841 @param BootOrder The Boot Order array.
842 @param BootOrderSize The size of the Boot Order Array.
844 @retval EFI_SUCCESS The Boot Option Variable was found and removed
845 @retval EFI_UNSUPPORTED The Boot Option Variable store was inaccessible
846 @retval EFI_NOT_FOUND The Boot Option Variable was not found
849 BdsDeleteBootOption (
850 IN UINTN OptionNumber
,
851 IN OUT UINT16
*BootOrder
,
852 IN OUT UINTN
*BootOrderSize
855 UINT16 BootOption
[100];
860 Status
= EFI_SUCCESS
;
863 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", OptionNumber
);
864 Status
= EfiLibDeleteVariable (BootOption
, &gEfiGlobalVariableGuid
);
867 // adjust boot order array
869 for (Index
= 0; Index
< *BootOrderSize
/ sizeof (UINT16
); Index
++) {
870 if (BootOrder
[Index
] == OptionNumber
) {
876 if (Index
!= *BootOrderSize
/ sizeof (UINT16
)) {
877 for (Index
= 0; Index
< *BootOrderSize
/ sizeof (UINT16
) - 1; Index
++) {
878 if (Index
>= Index2Del
) {
879 BootOrder
[Index
] = BootOrder
[Index
+ 1];
883 *BootOrderSize
-= sizeof (UINT16
);
891 Delete all the invalid legacy boot options.
893 @retval EFI_SUCCESS All invalide legacy boot options are deleted.
894 @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory.
895 @retval EFI_NOT_FOUND Fail to retrive variable of boot order.
898 BdsDeleteAllInvalidLegacyBootOptions (
903 UINT8
*BootOptionVar
;
905 UINTN BootOptionSize
;
909 HDD_INFO
*LocalHddInfo
;
910 BBS_TABLE
*LocalBbsTable
;
913 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
915 UINT16 BootOption
[10];
916 UINT16 BootDesc
[100];
917 BOOLEAN DescStringMatch
;
919 Status
= EFI_SUCCESS
;
925 LocalBbsTable
= NULL
;
928 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
929 if (EFI_ERROR (Status
)) {
933 refit_call5_wrapper(LegacyBios
->GetBbsInfo
,
941 BootOrder
= BdsLibGetVariableAndSize (
943 &gEfiGlobalVariableGuid
,
946 if (BootOrder
== NULL
) {
951 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
952 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
953 BootOptionVar
= BdsLibGetVariableAndSize (
955 &gEfiGlobalVariableGuid
,
958 if (NULL
== BootOptionVar
) {
960 Status
= refit_call5_wrapper(gRT
->GetVariable
,
962 &gEfiGlobalVariableGuid
,
967 if (Status
== EFI_NOT_FOUND
) {
971 BdsDeleteBootOption (
978 FreePool (BootOrder
);
979 return EFI_OUT_OF_RESOURCES
;
984 // Skip Non-Legacy boot option
986 if (!BdsIsLegacyBootOption (BootOptionVar
, &BbsEntry
, &BbsIndex
)) {
987 if (BootOptionVar
!= NULL
) {
988 FreePool (BootOptionVar
);
994 if (BbsIndex
< BbsCount
) {
996 // Check if BBS Description String is changed
998 DescStringMatch
= FALSE
;
999 BdsBuildLegacyDevNameString (
1000 &LocalBbsTable
[BbsIndex
],
1006 if (StrCmp (BootDesc
, (UINT16
*)(BootOptionVar
+ sizeof (UINT32
) + sizeof (UINT16
))) == 0) {
1007 DescStringMatch
= TRUE
;
1010 if (!((LocalBbsTable
[BbsIndex
].BootPriority
== BBS_IGNORE_ENTRY
) ||
1011 (LocalBbsTable
[BbsIndex
].BootPriority
== BBS_DO_NOT_BOOT_FROM
)) &&
1012 (LocalBbsTable
[BbsIndex
].DeviceType
== BbsEntry
->DeviceType
) &&
1019 if (BootOptionVar
!= NULL
) {
1020 FreePool (BootOptionVar
);
1025 BdsDeleteBootOption (
1033 // Adjust the number of boot options.
1035 if (BootOrderSize
!= 0) {
1036 Status
= refit_call5_wrapper(gRT
->SetVariable
,
1038 &gEfiGlobalVariableGuid
,
1044 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
1047 if (BootOrder
!= NULL
) {
1048 FreePool (BootOrder
);
1055 Fill the device order buffer.
1057 @param BbsTable The BBS table.
1058 @param BbsType The BBS Type.
1059 @param BbsCount The BBS Count.
1060 @param Buf device order buffer.
1062 @return The device order buffer.
1066 BdsFillDevOrderBuf (
1067 IN BBS_TABLE
*BbsTable
,
1068 IN BBS_TYPE BbsType
,
1075 for (Index
= 0; Index
< BbsCount
; Index
++) {
1076 if (BbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) {
1080 if (BbsTable
[Index
].DeviceType
!= BbsType
) {
1084 *Buf
= (UINT16
) (Index
& 0xFF);