]>
Commit | Line | Data |
---|---|---|
1 | /** @file\r | |
2 | This function deal with the legacy boot option, it create, delete\r | |
3 | and manage the legacy boot option, all legacy boot option is getting from\r | |
4 | the legacy BBS table.\r | |
5 | \r | |
6 | Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r | |
7 | This program and the accompanying materials\r | |
8 | are licensed and made available under the terms and conditions of the BSD License\r | |
9 | which accompanies this distribution. The full text of the license may be found at\r | |
10 | http://opensource.org/licenses/bsd-license.php\r | |
11 | \r | |
12 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
13 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
14 | \r | |
15 | **/\r | |
16 | \r | |
17 | #include "BBSsupport.h"\r | |
18 | \r | |
19 | #pragma pack(1)\r | |
20 | typedef struct {\r | |
21 | BBS_TABLE BbsEntry;\r | |
22 | UINT16 BbsIndex;\r | |
23 | } LEGACY_BOOT_OPTION_BBS_DATA;\r | |
24 | #pragma pack()\r | |
25 | \r | |
26 | /**\r | |
27 | Re-order the Boot Option according to the DevOrder.\r | |
28 | \r | |
29 | The routine re-orders the Boot Option in BootOption array according to\r | |
30 | the order specified by DevOrder.\r | |
31 | \r | |
32 | @param DevOrder Pointer to buffer containing the BBS Index,\r | |
33 | high 8-bit value 0xFF indicating a disabled boot option\r | |
34 | @param DevOrderCount Count of the BBS Index\r | |
35 | @param EnBootOption Callee allocated buffer containing the enabled Boot Option Numbers\r | |
36 | @param EnBootOptionCount Count of the enabled Boot Option Numbers\r | |
37 | @param DisBootOption Callee allocated buffer containing the disabled Boot Option Numbers\r | |
38 | @param DisBootOptionCount Count of the disabled Boot Option Numbers\r | |
39 | **/\r | |
40 | VOID\r | |
41 | OrderLegacyBootOption4SameType (\r | |
42 | UINT16 *DevOrder,\r | |
43 | UINTN DevOrderCount,\r | |
44 | UINT16 **EnBootOption,\r | |
45 | UINTN *EnBootOptionCount,\r | |
46 | UINT16 **DisBootOption,\r | |
47 | UINTN *DisBootOptionCount\r | |
48 | )\r | |
49 | {\r | |
50 | EFI_STATUS Status;\r | |
51 | UINT16 *NewBootOption;\r | |
52 | UINT16 *BootOrder;\r | |
53 | UINTN BootOrderSize;\r | |
54 | UINTN Index;\r | |
55 | UINTN StartPosition;\r | |
56 | \r | |
57 | BDS_COMMON_OPTION *BootOption;\r | |
58 | \r | |
59 | CHAR16 OptionName[sizeof ("Boot####")];\r | |
60 | UINT16 *BbsIndexArray;\r | |
61 | UINT16 *DeviceTypeArray;\r | |
62 | LIST_ENTRY List;\r | |
63 | \r | |
64 | BootOrder = BdsLibGetVariableAndSize (\r | |
65 | L"BootOrder",\r | |
66 | &gEfiGlobalVariableGuid,\r | |
67 | &BootOrderSize\r | |
68 | );\r | |
69 | ASSERT (BootOrder != NULL);\r | |
70 | \r | |
71 | BbsIndexArray = AllocatePool (BootOrderSize);\r | |
72 | DeviceTypeArray = AllocatePool (BootOrderSize);\r | |
73 | *EnBootOption = AllocatePool (BootOrderSize);\r | |
74 | *DisBootOption = AllocatePool (BootOrderSize);\r | |
75 | *DisBootOptionCount = 0;\r | |
76 | *EnBootOptionCount = 0;\r | |
77 | Index = 0;\r | |
78 | \r | |
79 | ASSERT (BbsIndexArray != NULL);\r | |
80 | ASSERT (DeviceTypeArray != NULL);\r | |
81 | ASSERT (*EnBootOption != NULL);\r | |
82 | ASSERT (*DisBootOption != NULL);\r | |
83 | \r | |
84 | for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r | |
85 | \r | |
86 | UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);\r | |
87 | InitializeListHead (&List);\r | |
88 | BootOption = BdsLibVariableToOption (&List, OptionName);\r | |
89 | ASSERT (BootOption != NULL);\r | |
90 | \r | |
91 | if ((DevicePathType (BootOption->DevicePath) == BBS_DEVICE_PATH) &&\r | |
92 | (DevicePathSubType (BootOption->DevicePath) == BBS_BBS_DP)) {\r | |
93 | //\r | |
94 | // Legacy Boot Option\r | |
95 | //\r | |
96 | ASSERT (BootOption->LoadOptionsSize == sizeof (LEGACY_BOOT_OPTION_BBS_DATA));\r | |
97 | \r | |
98 | DeviceTypeArray[Index] = ((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType;\r | |
99 | BbsIndexArray [Index] = ((LEGACY_BOOT_OPTION_BBS_DATA *) BootOption->LoadOptions)->BbsIndex;\r | |
100 | } else {\r | |
101 | DeviceTypeArray[Index] = BBS_TYPE_UNKNOWN;\r | |
102 | BbsIndexArray [Index] = 0xFFFF;\r | |
103 | }\r | |
104 | FreePool (BootOption->DevicePath);\r | |
105 | FreePool (BootOption->Description);\r | |
106 | FreePool (BootOption->LoadOptions);\r | |
107 | FreePool (BootOption);\r | |
108 | }\r | |
109 | \r | |
110 | //\r | |
111 | // Record the corresponding Boot Option Numbers according to the DevOrder\r | |
112 | // Record the EnBootOption and DisBootOption according to the DevOrder\r | |
113 | //\r | |
114 | StartPosition = BootOrderSize / sizeof (UINT16);\r | |
115 | NewBootOption = AllocatePool (DevOrderCount * sizeof (UINT16));\r | |
116 | ASSERT (NewBootOption != NULL);\r | |
117 | while (DevOrderCount-- != 0) {\r | |
118 | for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r | |
119 | if (BbsIndexArray[Index] == (DevOrder[DevOrderCount] & 0xFF)) {\r | |
120 | StartPosition = MIN (StartPosition, Index);\r | |
121 | NewBootOption[DevOrderCount] = BootOrder[Index];\r | |
122 | \r | |
123 | if ((DevOrder[DevOrderCount] & 0xFF00) == 0xFF00) {\r | |
124 | (*DisBootOption)[*DisBootOptionCount] = BootOrder[Index];\r | |
125 | (*DisBootOptionCount)++;\r | |
126 | } else {\r | |
127 | (*EnBootOption)[*EnBootOptionCount] = BootOrder[Index];\r | |
128 | (*EnBootOptionCount)++;\r | |
129 | }\r | |
130 | break;\r | |
131 | }\r | |
132 | }\r | |
133 | }\r | |
134 | \r | |
135 | //\r | |
136 | // Overwrite the old BootOption\r | |
137 | //\r | |
138 | CopyMem (&BootOrder[StartPosition], NewBootOption, (*DisBootOptionCount + *EnBootOptionCount) * sizeof (UINT16));\r | |
139 | Status = gRT->SetVariable (\r | |
140 | L"BootOrder",\r | |
141 | &gEfiGlobalVariableGuid,\r | |
142 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r | |
143 | BootOrderSize,\r | |
144 | BootOrder\r | |
145 | );\r | |
146 | //\r | |
147 | // Changing content without increasing its size with current variable implementation shouldn't fail.\r | |
148 | //\r | |
149 | ASSERT_EFI_ERROR (Status);\r | |
150 | \r | |
151 | FreePool (NewBootOption);\r | |
152 | FreePool (DeviceTypeArray);\r | |
153 | FreePool (BbsIndexArray);\r | |
154 | FreePool (BootOrder);\r | |
155 | }\r | |
156 | \r | |
157 | /**\r | |
158 | Group the legacy boot options in the BootOption.\r | |
159 | \r | |
160 | The routine assumes the boot options in the beginning that covers all the device\r | |
161 | types are ordered properly and re-position the following boot options just after\r | |
162 | the corresponding boot options with the same device type.\r | |
163 | For example:\r | |
164 | 1. Input = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0]\r | |
165 | Assuming [Harddisk1 CdRom2 Efi1] is ordered properly\r | |
166 | Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0]\r | |
167 | \r | |
168 | 2. Input = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2]\r | |
169 | Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly\r | |
170 | Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]\r | |
171 | \r | |
172 | **/\r | |
173 | VOID\r | |
174 | GroupMultipleLegacyBootOption4SameType (\r | |
175 | VOID\r | |
176 | )\r | |
177 | {\r | |
178 | EFI_STATUS Status;\r | |
179 | UINTN Index;\r | |
180 | UINTN DeviceIndex;\r | |
181 | UINTN DeviceTypeIndex[7];\r | |
182 | UINTN *NextIndex;\r | |
183 | UINT16 OptionNumber;\r | |
184 | UINT16 *BootOrder;\r | |
185 | UINTN BootOrderSize;\r | |
186 | CHAR16 OptionName[sizeof ("Boot####")];\r | |
187 | BDS_COMMON_OPTION *BootOption;\r | |
188 | LIST_ENTRY List;\r | |
189 | \r | |
190 | SetMem (DeviceTypeIndex, sizeof (DeviceTypeIndex), 0xff);\r | |
191 | \r | |
192 | BootOrder = BdsLibGetVariableAndSize (\r | |
193 | L"BootOrder",\r | |
194 | &gEfiGlobalVariableGuid,\r | |
195 | &BootOrderSize\r | |
196 | );\r | |
197 | \r | |
198 | for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r | |
199 | UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);\r | |
200 | InitializeListHead (&List);\r | |
201 | BootOption = BdsLibVariableToOption (&List, OptionName);\r | |
202 | ASSERT (BootOption != NULL);\r | |
203 | \r | |
204 | if ((DevicePathType (BootOption->DevicePath) == BBS_DEVICE_PATH) &&\r | |
205 | (DevicePathSubType (BootOption->DevicePath) == BBS_BBS_DP)) {\r | |
206 | //\r | |
207 | // Legacy Boot Option\r | |
208 | //\r | |
209 | ASSERT ((((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType & 0xF) < ARRAY_SIZE (DeviceTypeIndex));\r | |
210 | NextIndex = &DeviceTypeIndex[((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType & 0xF];\r | |
211 | \r | |
212 | if (*NextIndex == (UINTN) -1) {\r | |
213 | //\r | |
214 | // *NextIndex is the Index in BootOrder to put the next Option Number for the same type\r | |
215 | //\r | |
216 | *NextIndex = Index + 1;\r | |
217 | } else {\r | |
218 | //\r | |
219 | // insert the current boot option before *NextIndex, causing [*Next .. Index] shift right one position\r | |
220 | //\r | |
221 | OptionNumber = BootOrder[Index];\r | |
222 | CopyMem (&BootOrder[*NextIndex + 1], &BootOrder[*NextIndex], (Index - *NextIndex) * sizeof (UINT16));\r | |
223 | BootOrder[*NextIndex] = OptionNumber;\r | |
224 | \r | |
225 | //\r | |
226 | // Update the DeviceTypeIndex array to reflect the right shift operation\r | |
227 | //\r | |
228 | for (DeviceIndex = 0; DeviceIndex < ARRAY_SIZE (DeviceTypeIndex); DeviceIndex++) {\r | |
229 | if (DeviceTypeIndex[DeviceIndex] != (UINTN) -1 && DeviceTypeIndex[DeviceIndex] >= *NextIndex) {\r | |
230 | DeviceTypeIndex[DeviceIndex]++;\r | |
231 | }\r | |
232 | }\r | |
233 | }\r | |
234 | }\r | |
235 | FreePool (BootOption->DevicePath);\r | |
236 | FreePool (BootOption->Description);\r | |
237 | FreePool (BootOption->LoadOptions);\r | |
238 | FreePool (BootOption);\r | |
239 | }\r | |
240 | \r | |
241 | Status = gRT->SetVariable (\r | |
242 | L"BootOrder",\r | |
243 | &gEfiGlobalVariableGuid,\r | |
244 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r | |
245 | BootOrderSize,\r | |
246 | BootOrder\r | |
247 | );\r | |
248 | //\r | |
249 | // Changing content without increasing its size with current variable implementation shouldn't fail.\r | |
250 | //\r | |
251 | ASSERT_EFI_ERROR (Status);\r | |
252 | FreePool (BootOrder);\r | |
253 | }\r | |
254 | \r |