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 - 2012, 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"
23 } LEGACY_BOOT_OPTION_BBS_DATA
;
27 Re-order the Boot Option according to the DevOrder.
29 The routine re-orders the Boot Option in BootOption array according to
30 the order specified by DevOrder.
32 @param DevOrder Pointer to buffer containing the BBS Index,
33 high 8-bit value 0xFF indicating a disabled boot option
34 @param DevOrderCount Count of the BBS Index
35 @param EnBootOption Callee allocated buffer containing the enabled Boot Option Numbers
36 @param EnBootOptionCount Count of the enabled Boot Option Numbers
37 @param DisBootOption Callee allocated buffer containing the disabled Boot Option Numbers
38 @param DisBootOptionCount Count of the disabled Boot Option Numbers
41 OrderLegacyBootOption4SameType (
44 UINT16
**EnBootOption
,
45 UINTN
*EnBootOptionCount
,
46 UINT16
**DisBootOption
,
47 UINTN
*DisBootOptionCount
51 UINT16
*NewBootOption
;
57 BDS_COMMON_OPTION
*BootOption
;
59 CHAR16 OptionName
[sizeof ("Boot####")];
60 UINT16
*BbsIndexArray
;
61 UINT16
*DeviceTypeArray
;
64 BootOrder
= BdsLibGetVariableAndSize (
66 &gEfiGlobalVariableGuid
,
69 ASSERT (BootOrder
!= NULL
);
71 BbsIndexArray
= AllocatePool (BootOrderSize
);
72 DeviceTypeArray
= AllocatePool (BootOrderSize
);
73 *EnBootOption
= AllocatePool (BootOrderSize
);
74 *DisBootOption
= AllocatePool (BootOrderSize
);
75 *DisBootOptionCount
= 0;
76 *EnBootOptionCount
= 0;
79 ASSERT (*EnBootOption
!= NULL
);
80 ASSERT (*DisBootOption
!= NULL
);
82 for (Index
= 0; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
84 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Boot%04x", BootOrder
[Index
]);
85 InitializeListHead (&List
);
86 BootOption
= BdsLibVariableToOption (&List
, OptionName
);
87 ASSERT_EFI_ERROR (BootOption
!= NULL
);
89 if ((DevicePathType (BootOption
->DevicePath
) == BBS_DEVICE_PATH
) &&
90 (DevicePathSubType (BootOption
->DevicePath
) == BBS_BBS_DP
)) {
94 ASSERT (BootOption
->LoadOptionsSize
== sizeof (LEGACY_BOOT_OPTION_BBS_DATA
));
96 DeviceTypeArray
[Index
] = ((BBS_BBS_DEVICE_PATH
*) BootOption
->DevicePath
)->DeviceType
;
97 BbsIndexArray
[Index
] = ((LEGACY_BOOT_OPTION_BBS_DATA
*) BootOption
->LoadOptions
)->BbsIndex
;
99 DeviceTypeArray
[Index
] = BBS_TYPE_UNKNOWN
;
100 BbsIndexArray
[Index
] = 0xFFFF;
102 FreePool (BootOption
->DevicePath
);
103 FreePool (BootOption
->Description
);
104 FreePool (BootOption
->LoadOptions
);
105 FreePool (BootOption
);
109 // Record the corresponding Boot Option Numbers according to the DevOrder
110 // Record the EnBootOption and DisBootOption according to the DevOrder
112 StartPosition
= BootOrderSize
/ sizeof (UINT16
);
113 NewBootOption
= AllocatePool (DevOrderCount
* sizeof (UINT16
));
114 while (DevOrderCount
-- != 0) {
115 for (Index
= 0; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
116 if (BbsIndexArray
[Index
] == (DevOrder
[DevOrderCount
] & 0xFF)) {
117 StartPosition
= MIN (StartPosition
, Index
);
118 NewBootOption
[DevOrderCount
] = BootOrder
[Index
];
120 if ((DevOrder
[DevOrderCount
] & 0xFF00) == 0xFF00) {
121 (*DisBootOption
)[*DisBootOptionCount
] = BootOrder
[Index
];
122 (*DisBootOptionCount
)++;
124 (*EnBootOption
)[*EnBootOptionCount
] = BootOrder
[Index
];
125 (*EnBootOptionCount
)++;
133 // Overwrite the old BootOption
135 CopyMem (&BootOrder
[StartPosition
], NewBootOption
, (*DisBootOptionCount
+ *EnBootOptionCount
) * sizeof (UINT16
));
136 Status
= gRT
->SetVariable (
138 &gEfiGlobalVariableGuid
,
139 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
143 ASSERT_EFI_ERROR (Status
);
145 FreePool (NewBootOption
);
146 FreePool (DeviceTypeArray
);
147 FreePool (BbsIndexArray
);
151 Group the legacy boot options in the BootOption.
153 The routine assumes the boot options in the beginning that covers all the device
154 types are ordered properly and re-position the following boot options just after
155 the corresponding boot options with the same device type.
157 1. Input = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0]
158 Assuming [Harddisk1 CdRom2 Efi1] is ordered properly
159 Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0]
161 2. Input = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2]
162 Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly
163 Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]
167 GroupMultipleLegacyBootOption4SameType (
173 UINTN DeviceTypeIndex
[7];
178 CHAR16 OptionName
[sizeof ("Boot####")];
179 BDS_COMMON_OPTION
*BootOption
;
182 SetMem (DeviceTypeIndex
, sizeof (DeviceTypeIndex
), 0xff);
184 BootOrder
= BdsLibGetVariableAndSize (
186 &gEfiGlobalVariableGuid
,
190 for (Index
= 0; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
191 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Boot%04x", BootOrder
[Index
]);
192 InitializeListHead (&List
);
193 BootOption
= BdsLibVariableToOption (&List
, OptionName
);
194 ASSERT_EFI_ERROR (BootOption
!= NULL
);
196 if ((DevicePathType (BootOption
->DevicePath
) == BBS_DEVICE_PATH
) &&
197 (DevicePathSubType (BootOption
->DevicePath
) == BBS_BBS_DP
)) {
199 // Legacy Boot Option
201 ASSERT ((((BBS_BBS_DEVICE_PATH
*) BootOption
->DevicePath
)->DeviceType
& 0xF) < sizeof (DeviceTypeIndex
) / sizeof (DeviceTypeIndex
[0]));
202 NextIndex
= &DeviceTypeIndex
[((BBS_BBS_DEVICE_PATH
*) BootOption
->DevicePath
)->DeviceType
& 0xF];
204 if (*NextIndex
== (UINTN
) -1) {
206 // *NextIndex is the Index in BootOrder to put the next Option Number for the same type
208 *NextIndex
= Index
+ 1;
211 // insert the current boot option before *NextIndex, causing [*Next .. Index] shift right one position
213 OptionNumber
= BootOrder
[Index
];
214 CopyMem (&BootOrder
[*NextIndex
+ 1], &BootOrder
[*NextIndex
], (Index
- *NextIndex
) * sizeof (UINT16
));
215 BootOrder
[*NextIndex
] = OptionNumber
;
218 // Update the DeviceTypeIndex array to reflect the right shift operation
220 for (DeviceIndex
= 0; DeviceIndex
< sizeof (DeviceTypeIndex
) / sizeof (DeviceTypeIndex
[0]); DeviceIndex
++) {
221 if (DeviceTypeIndex
[DeviceIndex
] != (UINTN
) -1 && DeviceTypeIndex
[DeviceIndex
] >= *NextIndex
) {
222 DeviceTypeIndex
[DeviceIndex
]++;
227 FreePool (BootOption
->DevicePath
);
228 FreePool (BootOption
->Description
);
229 FreePool (BootOption
->LoadOptions
);
230 FreePool (BootOption
);
235 &gEfiGlobalVariableGuid
,
236 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
240 FreePool (BootOrder
);