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 - 2008, Intel Corporation. <BR>
7 All rights reserved. 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 EFI_DEVICE_PATH_PROTOCOL EndDevicePath
[] = {
21 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
22 END_DEVICE_PATH_LENGTH
,
28 Translate the first n characters of an Ascii string to
29 Unicode characters. The count n is indicated by parameter
30 Size. If Size is greater than the length of string, then
31 the entire string is translated.
34 @param a Pointer to input Ascii string.
35 @param Size The number of characters to translate.
36 @param u Pointer to output Unicode string buffer.
64 change a Unicode string t ASCII string
67 @param UStr Unicode string
68 Lenght - most possible length of AStr
69 @param Length The length of UStr.
70 @param AStr ASCII string to pass out
85 // just buffer copy, not character copy
87 for (Index
= 0; Index
< Length
; Index
++) {
88 *AStr
++ = (CHAR8
) *UStr
++;
95 EDES_TODO: Add function description.
97 @param CurBBSEntry EDES_TODO: Add parameter description
98 @param Index EDES_TODO: Add parameter description
99 @param BufSize EDES_TODO: Add parameter description
100 @param BootString EDES_TODO: Add parameter description
102 @return EDES_TODO: Add description for return value
106 BdsBuildLegacyDevNameString (
107 IN BBS_TABLE
*CurBBSEntry
,
110 OUT CHAR16
*BootString
123 Fmt
= L
"Primary Master %s";
130 Fmt
= L
"Primary Slave %s";
137 Fmt
= L
"Secondary Master %s";
144 Fmt
= L
"Secondary Slave %s";
152 switch (CurBBSEntry
->DeviceType
) {
173 case BBS_EMBED_NETWORK
:
187 // If current BBS entry has its description then use it.
189 StringDesc
= (UINT8
*) (UINTN
) ((CurBBSEntry
->DescStringSegment
<< 4) + CurBBSEntry
->DescStringOffset
);
190 if (NULL
!= StringDesc
) {
192 // Only get fisrt 32 characters, this is suggested by BBS spec
194 AsciiToUnicodeSize (StringDesc
, 32, temp
);
200 // BbsTable 16 entries are for onboard IDE.
201 // Set description string for SATA harddisks, Harddisk 0 ~ Harddisk 11
203 if (Index
>= 5 && Index
<= 16 && CurBBSEntry
->DeviceType
== BBS_HARDDISK
) {
205 UnicodeSPrint (BootString
, BufSize
, Fmt
, Type
, Index
- 5);
207 UnicodeSPrint (BootString
, BufSize
, Fmt
, Type
);
213 Create a legacy boot option for the specified entry of
214 BBS table, save it as variable, and append it to the boot
218 @param CurrentBbsEntry Pointer to current BBS table.
219 @param CurrentBbsDevPath Pointer to the Device Path Protocol instance of BBS
220 @param Index Index of the specified entry in BBS table.
221 @param BootOrderList On input, the original boot order list.
222 On output, the new boot order list attached with the
224 @param BootOrderListSize On input, the original size of boot order list.
225 - On output, the size of new boot order list.
227 @retval EFI_SUCCESS Boot Option successfully created.
228 @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory.
229 @retval Other Error occurs while setting variable.
233 BdsCreateLegacyBootOption (
234 IN BBS_TABLE
*CurrentBbsEntry
,
235 IN EFI_DEVICE_PATH_PROTOCOL
*CurrentBbsDevPath
,
237 IN OUT UINT16
**BootOrderList
,
238 IN OUT UINTN
*BootOrderListSize
242 UINT16 CurrentBootOptionNo
;
243 UINT16 BootString
[10];
244 UINT16 BootDesc
[100];
245 CHAR8 HelpString
[100];
246 UINT16
*NewBootOrderList
;
251 UINT16 CurrentBbsDevPathSize
;
252 UINTN BootOrderIndex
;
253 UINTN BootOrderLastIndex
;
255 BOOLEAN IndexNotFound
;
256 BBS_BBS_DEVICE_PATH
*NewBbsDevPathNode
;
258 if (NULL
== (*BootOrderList
)) {
259 CurrentBootOptionNo
= 0;
261 for (ArrayIndex
= 0; ArrayIndex
< (UINTN
) (*BootOrderListSize
/ sizeof (UINT16
)); ArrayIndex
++) {
262 IndexNotFound
= TRUE
;
263 for (BootOrderIndex
= 0; BootOrderIndex
< (UINTN
) (*BootOrderListSize
/ sizeof (UINT16
)); BootOrderIndex
++) {
264 if ((*BootOrderList
)[BootOrderIndex
] == ArrayIndex
) {
265 IndexNotFound
= FALSE
;
270 if (!IndexNotFound
) {
277 CurrentBootOptionNo
= (UINT16
) ArrayIndex
;
287 BdsBuildLegacyDevNameString (CurrentBbsEntry
, Index
, sizeof (BootDesc
), BootDesc
);
290 // Create new BBS device path node with description string
292 UnicodeToAscii (BootDesc
, StrSize (BootDesc
), HelpString
);
293 StringLen
= AsciiStrLen (HelpString
);
294 NewBbsDevPathNode
= EfiAllocateZeroPool (sizeof (BBS_BBS_DEVICE_PATH
) + StringLen
);
295 if (NewBbsDevPathNode
== NULL
) {
296 return EFI_OUT_OF_RESOURCES
;
298 CopyMem (NewBbsDevPathNode
, CurrentBbsDevPath
, sizeof (BBS_BBS_DEVICE_PATH
));
299 CopyMem (NewBbsDevPathNode
->String
, HelpString
, StringLen
+ 1);
300 SetDevicePathNodeLength (&(NewBbsDevPathNode
->Header
), sizeof (BBS_BBS_DEVICE_PATH
) + StringLen
);
303 // Create entire new CurrentBbsDevPath with end node
305 CurrentBbsDevPath
= AppendDevicePathNode (
307 (EFI_DEVICE_PATH_PROTOCOL
*) NewBbsDevPathNode
309 if (CurrentBbsDevPath
== NULL
) {
310 FreePool (NewBbsDevPathNode
);
311 return EFI_OUT_OF_RESOURCES
;
314 CurrentBbsDevPathSize
= (UINT16
) (GetDevicePathSize (CurrentBbsDevPath
));
316 BufferSize
= sizeof (UINT32
) +
319 CurrentBbsDevPathSize
+
323 Buffer
= EfiAllocateZeroPool (BufferSize
);
324 if (Buffer
== NULL
) {
325 FreePool (NewBbsDevPathNode
);
326 FreePool (CurrentBbsDevPath
);
327 return EFI_OUT_OF_RESOURCES
;
330 Ptr
= (UINT8
*) Buffer
;
332 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
333 Ptr
+= sizeof (UINT32
);
335 *((UINT16
*) Ptr
) = CurrentBbsDevPathSize
;
336 Ptr
+= sizeof (UINT16
);
343 Ptr
+= StrSize (BootDesc
);
348 CurrentBbsDevPathSize
350 Ptr
+= CurrentBbsDevPathSize
;
358 Ptr
+= sizeof (BBS_TABLE
);
359 *((UINT16
*) Ptr
) = (UINT16
) Index
;
361 Status
= gRT
->SetVariable (
363 &gEfiGlobalVariableGuid
,
369 SafeFreePool (Buffer
);
372 NewBootOrderList
= EfiAllocateZeroPool (*BootOrderListSize
+ sizeof (UINT16
));
373 if (NULL
== NewBootOrderList
) {
374 FreePool (NewBbsDevPathNode
);
375 FreePool (CurrentBbsDevPath
);
376 return EFI_OUT_OF_RESOURCES
;
379 if (NULL
!= *BootOrderList
) {
380 CopyMem (NewBootOrderList
, *BootOrderList
, *BootOrderListSize
);
383 SafeFreePool (*BootOrderList
);
385 BootOrderLastIndex
= (UINTN
) (*BootOrderListSize
/ sizeof (UINT16
));
386 NewBootOrderList
[BootOrderLastIndex
] = CurrentBootOptionNo
;
387 *BootOrderListSize
+= sizeof (UINT16
);
388 *BootOrderList
= NewBootOrderList
;
390 FreePool (NewBbsDevPathNode
);
391 FreePool (CurrentBbsDevPath
);
396 EDES_TODO: Add function description.
398 @param BootOptionVar EDES_TODO: Add parameter description
399 @param BbsEntry EDES_TODO: Add parameter description
400 @param BbsIndex EDES_TODO: Add parameter description
402 @return EDES_TODO: Add description for return value
406 BdsIsLegacyBootOption (
407 IN UINT8
*BootOptionVar
,
408 OUT BBS_TABLE
**BbsEntry
,
413 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
418 Ptr
+= sizeof (UINT32
);
419 DevPathLen
= *(UINT16
*) Ptr
;
420 Ptr
+= sizeof (UINT16
);
421 Ptr
+= StrSize ((UINT16
*) Ptr
);
422 DevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) Ptr
;
423 if ((BBS_DEVICE_PATH
== DevicePath
->Type
) && (BBS_BBS_DP
== DevicePath
->SubType
)) {
425 *BbsEntry
= (BBS_TABLE
*) Ptr
;
426 Ptr
+= sizeof (BBS_TABLE
);
427 *BbsIndex
= *(UINT16
*) Ptr
;
438 EDES_TODO: Add function description.
440 @param OptionNumber EDES_TODO: Add parameter description
441 @param BootOrder EDES_TODO: Add parameter description
442 @param BootOrderSize EDES_TODO: Add parameter description
444 @return EDES_TODO: Add description for return value
448 BdsDeleteBootOption (
449 IN UINTN OptionNumber
,
450 IN OUT UINT16
*BootOrder
,
451 IN OUT UINTN
*BootOrderSize
454 UINT16 BootOption
[100];
459 Status
= EFI_SUCCESS
;
462 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", OptionNumber
);
463 Status
= EfiLibDeleteVariable (BootOption
, &gEfiGlobalVariableGuid
);
465 // adjust boot order array
467 for (Index
= 0; Index
< *BootOrderSize
/ sizeof (UINT16
); Index
++) {
468 if (BootOrder
[Index
] == OptionNumber
) {
474 if (Index
!= *BootOrderSize
/ sizeof (UINT16
)) {
475 for (Index
= 0; Index
< *BootOrderSize
/ sizeof (UINT16
) - 1; Index
++) {
476 if (Index
>= Index2Del
) {
477 BootOrder
[Index
] = BootOrder
[Index
+ 1];
481 *BootOrderSize
-= sizeof (UINT16
);
490 Delete all the invalid legacy boot options.
493 @param VOID EDES_TODO: Add parameter description
495 @retval EFI_SUCCESS All invalide legacy boot options are deleted.
496 @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory.
497 @retval EFI_NOT_FOUND Fail to retrive variable of boot order.
498 @retval Other Error occurs while setting variable or locating
503 BdsDeleteAllInvalidLegacyBootOptions (
508 UINT8
*BootOptionVar
;
510 UINTN BootOptionSize
;
514 HDD_INFO
*LocalHddInfo
;
515 BBS_TABLE
*LocalBbsTable
;
518 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
520 UINT16 BootOption
[10];
521 UINT16 BootDesc
[100];
522 BOOLEAN DescStringMatch
;
524 Status
= EFI_SUCCESS
;
530 LocalBbsTable
= NULL
;
533 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
534 if (EFI_ERROR (Status
)) {
538 LegacyBios
->GetBbsInfo (
546 BootOrder
= BdsLibGetVariableAndSize (
548 &gEfiGlobalVariableGuid
,
551 if (NULL
== BootOrder
) {
552 return EFI_NOT_FOUND
;
556 while (Index
< BootOrderSize
/ sizeof (UINT16
)) {
557 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
558 BootOptionVar
= BdsLibGetVariableAndSize (
560 &gEfiGlobalVariableGuid
,
563 if (NULL
== BootOptionVar
) {
564 SafeFreePool (BootOrder
);
565 return EFI_OUT_OF_RESOURCES
;
568 if (!BdsIsLegacyBootOption (BootOptionVar
, &BbsEntry
, &BbsIndex
)) {
569 SafeFreePool (BootOptionVar
);
575 // Check if BBS Description String is changed
577 DescStringMatch
= FALSE
;
579 BdsBuildLegacyDevNameString (
580 &LocalBbsTable
[BbsIndex
],
586 if (StrCmp (BootDesc
, (UINT16
*)(BootOptionVar
+ sizeof (UINT32
) + sizeof (UINT16
))) == 0) {
587 DescStringMatch
= TRUE
;
590 if (!((LocalBbsTable
[BbsIndex
].BootPriority
== BBS_IGNORE_ENTRY
) ||
591 (LocalBbsTable
[BbsIndex
].BootPriority
== BBS_DO_NOT_BOOT_FROM
)) &&
592 (LocalBbsTable
[BbsIndex
].DeviceType
== BbsEntry
->DeviceType
) &&
598 SafeFreePool (BootOptionVar
);
602 BdsDeleteBootOption (
609 if (BootOrderSize
!= 0) {
610 Status
= gRT
->SetVariable (
612 &gEfiGlobalVariableGuid
,
618 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
621 SafeFreePool (BootOrder
);
627 EDES_TODO: Add function description.
629 @param BootOrder EDES_TODO: Add parameter description
630 @param BootOptionNum EDES_TODO: Add parameter description
631 @param DevType EDES_TODO: Add parameter description
632 @param Attribute EDES_TODO: Add parameter description
633 @param BbsIndex EDES_TODO: Add parameter description
634 @param OptionNumber EDES_TODO: Add parameter description
636 @return EDES_TODO: Add description for return value
640 BdsFindLegacyBootOptionByDevType (
641 IN UINT16
*BootOrder
,
642 IN UINTN BootOptionNum
,
644 OUT UINT32
*Attribute
,
645 OUT UINT16
*BbsIndex
,
646 OUT UINTN
*OptionNumber
650 UINTN BootOrderIndex
;
651 UINT16 BootOption
[100];
652 UINTN BootOptionSize
;
653 UINT8
*BootOptionVar
;
660 if (NULL
== BootOrder
) {
664 for (BootOrderIndex
= 0; BootOrderIndex
< BootOptionNum
; BootOrderIndex
++) {
665 Index
= (UINTN
) BootOrder
[BootOrderIndex
];
666 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", Index
);
667 BootOptionVar
= BdsLibGetVariableAndSize (
669 &gEfiGlobalVariableGuid
,
672 if (NULL
== BootOptionVar
) {
676 if (!BdsIsLegacyBootOption (BootOptionVar
, &BbsEntry
, BbsIndex
)) {
677 SafeFreePool (BootOptionVar
);
681 if (BbsEntry
->DeviceType
!= DevType
) {
682 SafeFreePool (BootOptionVar
);
686 *Attribute
= *(UINT32
*) BootOptionVar
;
687 *OptionNumber
= Index
;
689 SafeFreePool (BootOptionVar
);
697 EDES_TODO: Add function description.
699 @param BbsItem EDES_TODO: Add parameter description
700 @param Index EDES_TODO: Add parameter description
701 @param BootOrderList EDES_TODO: Add parameter description
702 @param BootOrderListSize EDES_TODO: Add parameter description
704 @return EDES_TODO: Add description for return value
708 BdsCreateOneLegacyBootOption (
709 IN BBS_TABLE
*BbsItem
,
711 IN OUT UINT16
**BootOrderList
,
712 IN OUT UINTN
*BootOrderListSize
715 BBS_BBS_DEVICE_PATH BbsDevPathNode
;
717 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
721 BbsDevPathNode
.Header
.Type
= BBS_DEVICE_PATH
;
722 BbsDevPathNode
.Header
.SubType
= BBS_BBS_DP
;
723 SetDevicePathNodeLength (&BbsDevPathNode
.Header
, sizeof (BBS_BBS_DEVICE_PATH
));
724 BbsDevPathNode
.DeviceType
= BbsItem
->DeviceType
;
725 CopyMem (&BbsDevPathNode
.StatusFlag
, &BbsItem
->StatusFlags
, sizeof (UINT16
));
727 DevPath
= AppendDevicePathNode (
729 (EFI_DEVICE_PATH_PROTOCOL
*) &BbsDevPathNode
731 if (NULL
== DevPath
) {
732 return EFI_OUT_OF_RESOURCES
;
735 Status
= BdsCreateLegacyBootOption (
742 BbsItem
->BootPriority
= 0x00;
751 Add the legacy boot options from BBS table if they do not exist.
754 @param VOID EDES_TODO: Add parameter description
756 @retval EFI_SUCCESS The boot options are added successfully or they are already in boot options.
757 @retval others An error occurred when creating legacy boot options.
761 BdsAddNonExistingLegacyBootOptions (
770 HDD_INFO
*LocalHddInfo
;
771 BBS_TABLE
*LocalBbsTable
;
773 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
783 LocalBbsTable
= NULL
;
785 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
786 if (EFI_ERROR (Status
)) {
790 LegacyBios
->GetBbsInfo (
798 BootOrder
= BdsLibGetVariableAndSize (
800 &gEfiGlobalVariableGuid
,
803 if (NULL
== BootOrder
) {
807 for (Index
= 0; Index
< BbsCount
; Index
++) {
808 if ((LocalBbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) ||
809 (LocalBbsTable
[Index
].BootPriority
== BBS_DO_NOT_BOOT_FROM
)
814 Ret
= BdsFindLegacyBootOptionByDevType (
816 BootOrderSize
/ sizeof (UINT16
),
817 LocalBbsTable
[Index
].DeviceType
,
827 // Not found such type of legacy device in boot options or we found but it's disabled
828 // so we have to create one and put it to the tail of boot order list
830 Status
= BdsCreateOneLegacyBootOption (
831 &LocalBbsTable
[Index
],
836 if (EFI_ERROR (Status
)) {
841 if (BootOrderSize
> 0) {
842 Status
= gRT
->SetVariable (
844 &gEfiGlobalVariableGuid
,
850 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
853 if (BootOrder
!= NULL
) {
854 SafeFreePool (BootOrder
);
861 EDES_TODO: Add function description.
863 @param BbsTable EDES_TODO: Add parameter description
864 @param BbsType EDES_TODO: Add parameter description
865 @param BbsCount EDES_TODO: Add parameter description
866 @param Buf EDES_TODO: Add parameter description
868 @return EDES_TODO: Add description for return value
873 IN BBS_TABLE
*BbsTable
,
881 for (Index
= 0; Index
< BbsCount
; Index
++) {
882 if (BbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) {
886 if (BbsTable
[Index
].DeviceType
!= BbsType
) {
890 *Buf
= (UINT16
) (Index
& 0xFF);
898 EDES_TODO: Add function description.
900 @param BbsTable EDES_TODO: Add parameter description
901 @param BbsCount EDES_TODO: Add parameter description
903 @return EDES_TODO: Add description for return value
908 IN BBS_TABLE
*BbsTable
,
930 HeaderSize
= sizeof (BBS_TYPE
) + sizeof (UINT16
);
933 Status
= EFI_SUCCESS
;
935 for (Index
= 0; Index
< BbsCount
; Index
++) {
936 if (BbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) {
940 switch (BbsTable
[Index
].DeviceType
) {
953 case BBS_EMBED_NETWORK
:
966 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * FDCount
);
967 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * HDCount
);
968 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * CDCount
);
969 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * NETCount
);
970 TotalSize
+= (HeaderSize
+ sizeof (UINT16
) * BEVCount
);
972 DevOrder
= EfiAllocateZeroPool (TotalSize
);
973 if (NULL
== DevOrder
) {
974 return EFI_OUT_OF_RESOURCES
;
979 *((BBS_TYPE
*) Ptr
) = BBS_FLOPPY
;
980 Ptr
+= sizeof (BBS_TYPE
);
981 *((UINT16
*) Ptr
) = (UINT16
) (sizeof (UINT16
) + FDCount
* sizeof (UINT16
));
982 Ptr
+= sizeof (UINT16
);
984 Ptr
= (UINT8
*) BdsFillDevOrderBuf (BbsTable
, BBS_FLOPPY
, BbsCount
, (UINT16
*) Ptr
);
987 *((BBS_TYPE
*) Ptr
) = BBS_HARDDISK
;
988 Ptr
+= sizeof (BBS_TYPE
);
989 *((UINT16
*) Ptr
) = (UINT16
) (sizeof (UINT16
) + HDCount
* sizeof (UINT16
));
990 Ptr
+= sizeof (UINT16
);
992 Ptr
= (UINT8
*) BdsFillDevOrderBuf (BbsTable
, BBS_HARDDISK
, BbsCount
, (UINT16
*) Ptr
);
995 *((BBS_TYPE
*) Ptr
) = BBS_CDROM
;
996 Ptr
+= sizeof (BBS_TYPE
);
997 *((UINT16
*) Ptr
) = (UINT16
) (sizeof (UINT16
) + CDCount
* sizeof (UINT16
));
998 Ptr
+= sizeof (UINT16
);
1000 Ptr
= (UINT8
*) BdsFillDevOrderBuf (BbsTable
, BBS_CDROM
, BbsCount
, (UINT16
*) Ptr
);
1003 *((BBS_TYPE
*) Ptr
) = BBS_EMBED_NETWORK
;
1004 Ptr
+= sizeof (BBS_TYPE
);
1005 *((UINT16
*) Ptr
) = (UINT16
) (sizeof (UINT16
) + NETCount
* sizeof (UINT16
));
1006 Ptr
+= sizeof (UINT16
);
1007 if (NETCount
!= 0) {
1008 Ptr
= (UINT8
*) BdsFillDevOrderBuf (BbsTable
, BBS_EMBED_NETWORK
, BbsCount
, (UINT16
*) Ptr
);
1011 *((BBS_TYPE
*) Ptr
) = BBS_BEV_DEVICE
;
1012 Ptr
+= sizeof (BBS_TYPE
);
1013 *((UINT16
*) Ptr
) = (UINT16
) (sizeof (UINT16
) + BEVCount
* sizeof (UINT16
));
1014 Ptr
+= sizeof (UINT16
);
1015 if (BEVCount
!= 0) {
1016 Ptr
= (UINT8
*) BdsFillDevOrderBuf (BbsTable
, BBS_BEV_DEVICE
, BbsCount
, (UINT16
*) Ptr
);
1019 Status
= gRT
->SetVariable (
1021 &EfiLegacyDevOrderGuid
,
1026 SafeFreePool (DevOrder
);
1032 EDES_TODO: Add function description.
1034 @param VOID EDES_TODO: Add parameter description
1036 @return EDES_TODO: Add description for return value
1040 BdsUpdateLegacyDevOrder (
1047 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
1051 HDD_INFO
*LocalHddInfo
;
1052 BBS_TABLE
*LocalBbsTable
;
1079 LocalHddInfo
= NULL
;
1080 LocalBbsTable
= NULL
;
1088 HeaderSize
= sizeof (BBS_TYPE
) + sizeof (UINT16
);
1096 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
1097 if (EFI_ERROR (Status
)) {
1101 LegacyBios
->GetBbsInfo (
1109 DevOrder
= (UINT8
*) BdsLibGetVariableAndSize (
1111 &EfiLegacyDevOrderGuid
,
1114 if (NULL
== DevOrder
) {
1115 return BdsCreateDevOrder (LocalBbsTable
, BbsCount
);
1118 // First we figure out how many boot devices with same device type respectively
1120 for (Index
= 0; Index
< BbsCount
; Index
++) {
1121 if ((LocalBbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) ||
1122 (LocalBbsTable
[Index
].BootPriority
== BBS_DO_NOT_BOOT_FROM
)
1127 switch (LocalBbsTable
[Index
].DeviceType
) {
1140 case BBS_EMBED_NETWORK
:
1144 case BBS_BEV_DEVICE
:
1153 TotalSize
+= (HeaderSize
+ FDCount
* sizeof (UINT16
));
1154 TotalSize
+= (HeaderSize
+ HDCount
* sizeof (UINT16
));
1155 TotalSize
+= (HeaderSize
+ CDCount
* sizeof (UINT16
));
1156 TotalSize
+= (HeaderSize
+ NETCount
* sizeof (UINT16
));
1157 TotalSize
+= (HeaderSize
+ BEVCount
* sizeof (UINT16
));
1159 NewDevOrder
= EfiAllocateZeroPool (TotalSize
);
1160 if (NULL
== NewDevOrder
) {
1161 return EFI_OUT_OF_RESOURCES
;
1164 NewFDPtr
= (UINT16
*) (NewDevOrder
+ HeaderSize
);
1165 NewHDPtr
= (UINT16
*) ((UINT8
*) NewFDPtr
+ FDCount
* sizeof (UINT16
) + HeaderSize
);
1166 NewCDPtr
= (UINT16
*) ((UINT8
*) NewHDPtr
+ HDCount
* sizeof (UINT16
) + HeaderSize
);
1167 NewNETPtr
= (UINT16
*) ((UINT8
*) NewCDPtr
+ CDCount
* sizeof (UINT16
) + HeaderSize
);
1168 NewBEVPtr
= (UINT16
*) ((UINT8
*) NewNETPtr
+ NETCount
* sizeof (UINT16
) + HeaderSize
);
1174 NewPtr
= NewDevOrder
;
1175 *((BBS_TYPE
*) NewPtr
) = *((BBS_TYPE
*) Ptr
);
1176 Ptr
+= sizeof (BBS_TYPE
);
1177 NewPtr
+= sizeof (BBS_TYPE
);
1178 Length
= *((UINT16
*) Ptr
);
1179 *((UINT16
*) NewPtr
) = (UINT16
) (sizeof (UINT16
) + FDCount
* sizeof (UINT16
));
1180 Ptr
+= sizeof (UINT16
);
1182 for (Index
= 0; Index
< Length
/ sizeof (UINT16
) - 1; Index
++) {
1183 if (LocalBbsTable
[*Ptr
].BootPriority
== BBS_IGNORE_ENTRY
||
1184 LocalBbsTable
[*Ptr
].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1185 LocalBbsTable
[*Ptr
].DeviceType
!= BBS_FLOPPY
1187 Ptr
+= sizeof (UINT16
);
1191 NewFDPtr
[FDIndex
] = *(UINT16
*) Ptr
;
1193 Ptr
+= sizeof (UINT16
);
1198 NewPtr
= (UINT8
*) NewHDPtr
- HeaderSize
;
1199 *((BBS_TYPE
*) NewPtr
) = *((BBS_TYPE
*) Ptr
);
1200 Ptr
+= sizeof (BBS_TYPE
);
1201 NewPtr
+= sizeof (BBS_TYPE
);
1202 Length
= *((UINT16
*) Ptr
);
1203 *((UINT16
*) NewPtr
) = (UINT16
) (sizeof (UINT16
) + HDCount
* sizeof (UINT16
));
1204 Ptr
+= sizeof (UINT16
);
1206 for (Index
= 0; Index
< Length
/ sizeof (UINT16
) - 1; Index
++) {
1207 if (LocalBbsTable
[*Ptr
].BootPriority
== BBS_IGNORE_ENTRY
||
1208 LocalBbsTable
[*Ptr
].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1209 LocalBbsTable
[*Ptr
].BootPriority
== BBS_LOWEST_PRIORITY
||
1210 LocalBbsTable
[*Ptr
].DeviceType
!= BBS_HARDDISK
1212 Ptr
+= sizeof (UINT16
);
1216 NewHDPtr
[HDIndex
] = *(UINT16
*) Ptr
;
1218 Ptr
+= sizeof (UINT16
);
1223 NewPtr
= (UINT8
*) NewCDPtr
- HeaderSize
;
1224 *((BBS_TYPE
*) NewPtr
) = *((BBS_TYPE
*) Ptr
);
1225 Ptr
+= sizeof (BBS_TYPE
);
1226 NewPtr
+= sizeof (BBS_TYPE
);
1227 Length
= *((UINT16
*) Ptr
);
1228 *((UINT16
*) NewPtr
) = (UINT16
) (sizeof (UINT16
) + CDCount
* sizeof (UINT16
));
1229 Ptr
+= sizeof (UINT16
);
1231 for (Index
= 0; Index
< Length
/ sizeof (UINT16
) - 1; Index
++) {
1232 if (LocalBbsTable
[*Ptr
].BootPriority
== BBS_IGNORE_ENTRY
||
1233 LocalBbsTable
[*Ptr
].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1234 LocalBbsTable
[*Ptr
].BootPriority
== BBS_LOWEST_PRIORITY
||
1235 LocalBbsTable
[*Ptr
].DeviceType
!= BBS_CDROM
1237 Ptr
+= sizeof (UINT16
);
1241 NewCDPtr
[CDIndex
] = *(UINT16
*) Ptr
;
1243 Ptr
+= sizeof (UINT16
);
1248 NewPtr
= (UINT8
*) NewNETPtr
- HeaderSize
;
1249 *((BBS_TYPE
*) NewPtr
) = *((BBS_TYPE
*) Ptr
);
1250 Ptr
+= sizeof (BBS_TYPE
);
1251 NewPtr
+= sizeof (BBS_TYPE
);
1252 Length
= *((UINT16
*) Ptr
);
1253 *((UINT16
*) NewPtr
) = (UINT16
) (sizeof (UINT16
) + NETCount
* sizeof (UINT16
));
1254 Ptr
+= sizeof (UINT16
);
1256 for (Index
= 0; Index
< Length
/ sizeof (UINT16
) - 1; Index
++) {
1257 if (LocalBbsTable
[*Ptr
].BootPriority
== BBS_IGNORE_ENTRY
||
1258 LocalBbsTable
[*Ptr
].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1259 LocalBbsTable
[*Ptr
].BootPriority
== BBS_LOWEST_PRIORITY
||
1260 LocalBbsTable
[*Ptr
].DeviceType
!= BBS_EMBED_NETWORK
1262 Ptr
+= sizeof (UINT16
);
1266 NewNETPtr
[NETIndex
] = *(UINT16
*) Ptr
;
1268 Ptr
+= sizeof (UINT16
);
1273 NewPtr
= (UINT8
*) NewBEVPtr
- HeaderSize
;
1274 *((BBS_TYPE
*) NewPtr
) = *((BBS_TYPE
*) Ptr
);
1275 Ptr
+= sizeof (BBS_TYPE
);
1276 NewPtr
+= sizeof (BBS_TYPE
);
1277 Length
= *((UINT16
*) Ptr
);
1278 *((UINT16
*) NewPtr
) = (UINT16
) (sizeof (UINT16
) + BEVCount
* sizeof (UINT16
));
1279 Ptr
+= sizeof (UINT16
);
1281 for (Index
= 0; Index
< Length
/ sizeof (UINT16
) - 1; Index
++) {
1282 if (LocalBbsTable
[*Ptr
].BootPriority
== BBS_IGNORE_ENTRY
||
1283 LocalBbsTable
[*Ptr
].BootPriority
== BBS_DO_NOT_BOOT_FROM
||
1284 LocalBbsTable
[*Ptr
].BootPriority
== BBS_LOWEST_PRIORITY
||
1285 LocalBbsTable
[*Ptr
].DeviceType
!= BBS_BEV_DEVICE
1287 Ptr
+= sizeof (UINT16
);
1291 NewBEVPtr
[BEVIndex
] = *(UINT16
*) Ptr
;
1293 Ptr
+= sizeof (UINT16
);
1296 for (Index
= 0; Index
< BbsCount
; Index
++) {
1297 if ((LocalBbsTable
[Index
].BootPriority
== BBS_IGNORE_ENTRY
) ||
1298 (LocalBbsTable
[Index
].BootPriority
== BBS_DO_NOT_BOOT_FROM
)
1303 switch (LocalBbsTable
[Index
].DeviceType
) {
1306 NewDevPtr
= NewFDPtr
;
1311 NewDevPtr
= NewHDPtr
;
1316 NewDevPtr
= NewCDPtr
;
1319 case BBS_EMBED_NETWORK
:
1321 NewDevPtr
= NewNETPtr
;
1324 case BBS_BEV_DEVICE
:
1326 NewDevPtr
= NewBEVPtr
;
1334 // at this point we have copied those valid indexes to new buffer
1335 // and we should check if there is any new appeared boot device
1338 for (Index2
= 0; Index2
< *Idx
; Index2
++) {
1339 if ((NewDevPtr
[Index2
] & 0xFF) == (UINT16
) Index
) {
1344 if (Index2
== *Idx
) {
1346 // Index2 == *Idx means we didn't find Index
1347 // so Index is a new appeared device's index in BBS table
1350 NewDevPtr
[*Idx
] = (UINT16
) (Index
& 0xFF);
1358 // Just to make sure that disabled indexes are all at the end of the array
1360 for (Index
= 0; Index
< FDIndex
- 1; Index
++) {
1361 if (0xFF00 != (NewFDPtr
[Index
] & 0xFF00)) {
1365 for (Index2
= Index
+ 1; Index2
< FDIndex
; Index2
++) {
1366 if (0 == (NewFDPtr
[Index2
] & 0xFF00)) {
1367 tmp
= NewFDPtr
[Index
];
1368 NewFDPtr
[Index
] = NewFDPtr
[Index2
];
1369 NewFDPtr
[Index2
] = tmp
;
1378 // Just to make sure that disabled indexes are all at the end of the array
1380 for (Index
= 0; Index
< HDIndex
- 1; Index
++) {
1381 if (0xFF00 != (NewHDPtr
[Index
] & 0xFF00)) {
1385 for (Index2
= Index
+ 1; Index2
< HDIndex
; Index2
++) {
1386 if (0 == (NewHDPtr
[Index2
] & 0xFF00)) {
1387 tmp
= NewHDPtr
[Index
];
1388 NewHDPtr
[Index
] = NewHDPtr
[Index2
];
1389 NewHDPtr
[Index2
] = tmp
;
1398 // Just to make sure that disabled indexes are all at the end of the array
1400 for (Index
= 0; Index
< CDIndex
- 1; Index
++) {
1401 if (0xFF00 != (NewCDPtr
[Index
] & 0xFF00)) {
1405 for (Index2
= Index
+ 1; Index2
< CDIndex
; Index2
++) {
1406 if (0 == (NewCDPtr
[Index2
] & 0xFF00)) {
1407 tmp
= NewCDPtr
[Index
];
1408 NewCDPtr
[Index
] = NewCDPtr
[Index2
];
1409 NewCDPtr
[Index2
] = tmp
;
1416 if (NETCount
!= 0) {
1418 // Just to make sure that disabled indexes are all at the end of the array
1420 for (Index
= 0; Index
< NETIndex
- 1; Index
++) {
1421 if (0xFF00 != (NewNETPtr
[Index
] & 0xFF00)) {
1425 for (Index2
= Index
+ 1; Index2
< NETIndex
; Index2
++) {
1426 if (0 == (NewNETPtr
[Index2
] & 0xFF00)) {
1427 tmp
= NewNETPtr
[Index
];
1428 NewNETPtr
[Index
] = NewNETPtr
[Index2
];
1429 NewNETPtr
[Index2
] = tmp
;
1438 // Just to make sure that disabled indexes are all at the end of the array
1440 for (Index
= 0; Index
< BEVIndex
- 1; Index
++) {
1441 if (0xFF00 != (NewBEVPtr
[Index
] & 0xFF00)) {
1445 for (Index2
= Index
+ 1; Index2
< BEVIndex
; Index2
++) {
1446 if (0 == (NewBEVPtr
[Index2
] & 0xFF00)) {
1447 tmp
= NewBEVPtr
[Index
];
1448 NewBEVPtr
[Index
] = NewBEVPtr
[Index2
];
1449 NewBEVPtr
[Index2
] = tmp
;
1456 SafeFreePool (DevOrder
);
1458 Status
= gRT
->SetVariable (
1460 &EfiLegacyDevOrderGuid
,
1465 SafeFreePool (NewDevOrder
);
1471 EDES_TODO: Add function description.
1473 @param DeviceType EDES_TODO: Add parameter description
1474 @param LocalBbsTable EDES_TODO: Add parameter description
1475 @param Priority EDES_TODO: Add parameter description
1477 @return EDES_TODO: Add description for return value
1481 BdsSetBootPriority4SameTypeDev (
1482 IN UINT16 DeviceType
,
1483 IN OUT BBS_TABLE
*LocalBbsTable
,
1484 IN OUT UINT16
*Priority
1495 DevOrder
= BdsLibGetVariableAndSize (
1497 &EfiLegacyDevOrderGuid
,
1500 if (NULL
== DevOrder
) {
1501 return EFI_OUT_OF_RESOURCES
;
1504 OrigBuffer
= DevOrder
;
1505 while (DevOrder
< OrigBuffer
+ DevOrderSize
) {
1506 if (DeviceType
== * (BBS_TYPE
*) DevOrder
) {
1510 DevOrder
+= sizeof (BBS_TYPE
);
1511 DevOrder
+= *(UINT16
*) DevOrder
;
1514 if (DevOrder
>= OrigBuffer
+ DevOrderSize
) {
1515 SafeFreePool (OrigBuffer
);
1516 return EFI_NOT_FOUND
;
1519 DevOrder
+= sizeof (BBS_TYPE
);
1520 DevCount
= (*((UINT16
*) DevOrder
) - sizeof (UINT16
)) / sizeof (UINT16
);
1521 DevIndex
= (UINT16
*) (DevOrder
+ sizeof (UINT16
));
1523 // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled.
1525 for (Index
= 0; Index
< DevCount
; Index
++) {
1526 if ((DevIndex
[Index
] & 0xFF00) == 0xFF00) {
1528 // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY;
1531 LocalBbsTable
[DevIndex
[Index
] & 0xFF].BootPriority
= *Priority
;
1536 SafeFreePool (OrigBuffer
);
1541 EDES_TODO: Add function description.
1543 @param LocalBbsTable EDES_TODO: Add parameter description
1545 @return EDES_TODO: Add description for return value
1550 IN BBS_TABLE
*LocalBbsTable
1555 DEBUG ((DEBUG_ERROR
, "\n"));
1556 DEBUG ((DEBUG_ERROR
, " NO Prio bb/dd/ff cl/sc Type Stat segm:offs\n"));
1557 DEBUG ((DEBUG_ERROR
, "=============================================\n"));
1558 for (Idx
= 0; Idx
< MAX_BBS_ENTRIES
; Idx
++) {
1559 if ((LocalBbsTable
[Idx
].BootPriority
== BBS_IGNORE_ENTRY
) ||
1560 (LocalBbsTable
[Idx
].BootPriority
== BBS_DO_NOT_BOOT_FROM
) ||
1561 (LocalBbsTable
[Idx
].BootPriority
== BBS_LOWEST_PRIORITY
)
1568 " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n",
1570 (UINTN
) LocalBbsTable
[Idx
].BootPriority
,
1571 (UINTN
) LocalBbsTable
[Idx
].Bus
,
1572 (UINTN
) LocalBbsTable
[Idx
].Device
,
1573 (UINTN
) LocalBbsTable
[Idx
].Function
,
1574 (UINTN
) LocalBbsTable
[Idx
].Class
,
1575 (UINTN
) LocalBbsTable
[Idx
].SubClass
,
1576 (UINTN
) LocalBbsTable
[Idx
].DeviceType
,
1577 (UINTN
) * (UINT16
*) &LocalBbsTable
[Idx
].StatusFlags
,
1578 (UINTN
) LocalBbsTable
[Idx
].BootHandlerSegment
,
1579 (UINTN
) LocalBbsTable
[Idx
].BootHandlerOffset
,
1580 (UINTN
) ((LocalBbsTable
[Idx
].MfgStringSegment
<< 4) + LocalBbsTable
[Idx
].MfgStringOffset
),
1581 (UINTN
) ((LocalBbsTable
[Idx
].DescStringSegment
<< 4) + LocalBbsTable
[Idx
].DescStringOffset
))
1585 DEBUG ((DEBUG_ERROR
, "\n"));
1589 EDES_TODO: Add function description.
1591 @param Entry EDES_TODO: Add parameter description
1593 @return EDES_TODO: Add description for return value
1597 BdsRefreshBbsTableForBoot (
1598 IN BDS_COMMON_OPTION
*Entry
1604 HDD_INFO
*LocalHddInfo
;
1605 BBS_TABLE
*LocalBbsTable
;
1607 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
1611 UINTN BootOrderSize
;
1612 UINT8
*BootOptionVar
;
1613 UINTN BootOptionSize
;
1614 UINT16 BootOption
[100];
1617 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
1621 LocalHddInfo
= NULL
;
1622 LocalBbsTable
= NULL
;
1623 DevType
= BBS_UNKNOWN
;
1625 Status
= EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid
, (VOID
**) &LegacyBios
);
1626 if (EFI_ERROR (Status
)) {
1630 LegacyBios
->GetBbsInfo (
1638 // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY
1639 // We will set them according to the settings setup by user
1641 for (Index
= 0; Index
< BbsCount
; Index
++) {
1642 if (!((BBS_IGNORE_ENTRY
== LocalBbsTable
[Index
].BootPriority
) ||
1643 (BBS_DO_NOT_BOOT_FROM
== LocalBbsTable
[Index
].BootPriority
) ||
1644 (BBS_LOWEST_PRIORITY
== LocalBbsTable
[Index
].BootPriority
))) {
1645 LocalBbsTable
[Index
].BootPriority
= BBS_UNPRIORITIZED_ENTRY
;
1649 // boot priority always starts at 0
1652 if (Entry
->LoadOptionsSize
== sizeof (BBS_TABLE
) + sizeof (UINT16
)) {
1654 // If Entry stands for a legacy boot option, we prioritize the devices with the same type first.
1656 DevType
= ((BBS_TABLE
*) Entry
->LoadOptions
)->DeviceType
;
1657 Status
= BdsSetBootPriority4SameTypeDev (
1662 if (EFI_ERROR (Status
)) {
1667 // we have to set the boot priority for other BBS entries with different device types
1669 BootOrder
= (UINT16
*) BdsLibGetVariableAndSize (
1671 &gEfiGlobalVariableGuid
,
1674 for (Index
= 0; ((BootOrder
!= NULL
) && (Index
< BootOrderSize
/ sizeof (UINT16
))); Index
++) {
1675 UnicodeSPrint (BootOption
, sizeof (BootOption
), L
"Boot%04x", BootOrder
[Index
]);
1676 BootOptionVar
= BdsLibGetVariableAndSize (
1678 &gEfiGlobalVariableGuid
,
1681 if (NULL
== BootOptionVar
) {
1685 Ptr
= BootOptionVar
;
1687 Ptr
+= sizeof (UINT32
);
1688 DevPathLen
= *(UINT16
*) Ptr
;
1689 Ptr
+= sizeof (UINT16
);
1690 Ptr
+= StrSize ((UINT16
*) Ptr
);
1691 DevPath
= (EFI_DEVICE_PATH_PROTOCOL
*) Ptr
;
1692 if (BBS_DEVICE_PATH
!= DevPath
->Type
|| BBS_BBS_DP
!= DevPath
->SubType
) {
1693 SafeFreePool (BootOptionVar
);
1698 if (DevType
== ((BBS_TABLE
*) Ptr
)->DeviceType
) {
1700 // We don't want to process twice for a device type
1702 SafeFreePool (BootOptionVar
);
1706 Status
= BdsSetBootPriority4SameTypeDev (
1707 ((BBS_TABLE
*) Ptr
)->DeviceType
,
1711 SafeFreePool (BootOptionVar
);
1712 if (EFI_ERROR (Status
)) {
1717 if (BootOrder
!= NULL
) {
1718 SafeFreePool (BootOrder
);
1723 PrintBbsTable (LocalBbsTable
);