]>
Commit | Line | Data |
---|---|---|
5c08e117 | 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 | |
16e5944a | 6 | Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r |
180a5a35 | 7 | This program and the accompanying materials\r |
5c08e117 | 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 | |
16e5944a RN |
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 | |
5c08e117 | 25 | \r |
22d1f978 RN |
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 | |
22d1f978 RN |
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 | |
16e5944a | 35 | @param EnBootOption Callee allocated buffer containing the enabled Boot Option Numbers\r |
22d1f978 | 36 | @param EnBootOptionCount Count of the enabled Boot Option Numbers\r |
16e5944a | 37 | @param DisBootOption Callee allocated buffer containing the disabled Boot Option Numbers\r |
22d1f978 RN |
38 | @param DisBootOptionCount Count of the disabled Boot Option Numbers\r |
39 | **/\r | |
40 | VOID\r | |
41 | OrderLegacyBootOption4SameType (\r | |
22d1f978 RN |
42 | UINT16 *DevOrder,\r |
43 | UINTN DevOrderCount,\r | |
16e5944a | 44 | UINT16 **EnBootOption,\r |
22d1f978 | 45 | UINTN *EnBootOptionCount,\r |
16e5944a | 46 | UINT16 **DisBootOption,\r |
22d1f978 RN |
47 | UINTN *DisBootOptionCount\r |
48 | )\r | |
49 | {\r | |
16e5944a | 50 | EFI_STATUS Status;\r |
22d1f978 | 51 | UINT16 *NewBootOption;\r |
16e5944a RN |
52 | UINT16 *BootOrder;\r |
53 | UINTN BootOrderSize;\r | |
54 | UINTN Index;\r | |
55 | UINTN StartPosition;\r | |
56 | \r | |
57 | BDS_COMMON_OPTION *BootOption;\r | |
22d1f978 | 58 | \r |
16e5944a RN |
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 | |
22d1f978 RN |
75 | *DisBootOptionCount = 0;\r |
76 | *EnBootOptionCount = 0;\r | |
16e5944a RN |
77 | Index = 0;\r |
78 | \r | |
2d1f3dd4 RN |
79 | ASSERT (BbsIndexArray != NULL);\r |
80 | ASSERT (DeviceTypeArray != NULL);\r | |
16e5944a RN |
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 | |
2d1f3dd4 | 89 | ASSERT (BootOption != NULL);\r |
16e5944a RN |
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 | |
22d1f978 RN |
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 | |
16e5944a | 114 | StartPosition = BootOrderSize / sizeof (UINT16);\r |
22d1f978 | 115 | NewBootOption = AllocatePool (DevOrderCount * sizeof (UINT16));\r |
2d1f3dd4 | 116 | ASSERT (NewBootOption != NULL);\r |
22d1f978 | 117 | while (DevOrderCount-- != 0) {\r |
16e5944a RN |
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 | |
22d1f978 RN |
122 | \r |
123 | if ((DevOrder[DevOrderCount] & 0xFF00) == 0xFF00) {\r | |
16e5944a | 124 | (*DisBootOption)[*DisBootOptionCount] = BootOrder[Index];\r |
22d1f978 RN |
125 | (*DisBootOptionCount)++;\r |
126 | } else {\r | |
16e5944a | 127 | (*EnBootOption)[*EnBootOptionCount] = BootOrder[Index];\r |
22d1f978 RN |
128 | (*EnBootOptionCount)++;\r |
129 | }\r | |
130 | break;\r | |
131 | }\r | |
132 | }\r | |
133 | }\r | |
134 | \r | |
16e5944a RN |
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 | ASSERT_EFI_ERROR (Status);\r | |
22d1f978 | 147 | \r |
16e5944a RN |
148 | FreePool (NewBootOption);\r |
149 | FreePool (DeviceTypeArray);\r | |
150 | FreePool (BbsIndexArray);\r | |
22d1f978 RN |
151 | }\r |
152 | \r | |
153 | /**\r | |
154 | Group the legacy boot options in the BootOption.\r | |
155 | \r | |
156 | The routine assumes the boot options in the beginning that covers all the device \r | |
157 | types are ordered properly and re-position the following boot options just after\r | |
158 | the corresponding boot options with the same device type.\r | |
159 | For example:\r | |
160 | 1. Input = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0]\r | |
161 | Assuming [Harddisk1 CdRom2 Efi1] is ordered properly\r | |
162 | Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0]\r | |
163 | \r | |
164 | 2. Input = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2]\r | |
165 | Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly\r | |
166 | Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]\r | |
167 | \r | |
22d1f978 RN |
168 | **/\r |
169 | VOID\r | |
170 | GroupMultipleLegacyBootOption4SameType (\r | |
5c08e117 | 171 | VOID\r |
172 | )\r | |
173 | {\r | |
16e5944a RN |
174 | UINTN Index;\r |
175 | UINTN DeviceIndex;\r | |
176 | UINTN DeviceTypeIndex[7];\r | |
177 | UINTN *NextIndex;\r | |
178 | UINT16 OptionNumber;\r | |
179 | UINT16 *BootOrder;\r | |
180 | UINTN BootOrderSize;\r | |
181 | CHAR16 OptionName[sizeof ("Boot####")];\r | |
182 | BDS_COMMON_OPTION *BootOption;\r | |
183 | LIST_ENTRY List;\r | |
22d1f978 | 184 | \r |
16e5944a | 185 | SetMem (DeviceTypeIndex, sizeof (DeviceTypeIndex), 0xff);\r |
5c08e117 | 186 | \r |
187 | BootOrder = BdsLibGetVariableAndSize (\r | |
188 | L"BootOrder",\r | |
189 | &gEfiGlobalVariableGuid,\r | |
190 | &BootOrderSize\r | |
191 | );\r | |
5c08e117 | 192 | \r |
16e5944a RN |
193 | for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r |
194 | UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);\r | |
195 | InitializeListHead (&List);\r | |
196 | BootOption = BdsLibVariableToOption (&List, OptionName);\r | |
2d1f3dd4 | 197 | ASSERT (BootOption != NULL);\r |
22d1f978 | 198 | \r |
16e5944a RN |
199 | if ((DevicePathType (BootOption->DevicePath) == BBS_DEVICE_PATH) &&\r |
200 | (DevicePathSubType (BootOption->DevicePath) == BBS_BBS_DP)) {\r | |
22d1f978 | 201 | //\r |
16e5944a | 202 | // Legacy Boot Option\r |
22d1f978 | 203 | //\r |
16e5944a RN |
204 | ASSERT ((((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType & 0xF) < sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0]));\r |
205 | NextIndex = &DeviceTypeIndex[((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType & 0xF];\r | |
5c08e117 | 206 | \r |
16e5944a RN |
207 | if (*NextIndex == (UINTN) -1) {\r |
208 | //\r | |
209 | // *NextIndex is the Index in BootOrder to put the next Option Number for the same type\r | |
210 | //\r | |
211 | *NextIndex = Index + 1;\r | |
212 | } else {\r | |
213 | //\r | |
214 | // insert the current boot option before *NextIndex, causing [*Next .. Index] shift right one position\r | |
215 | //\r | |
216 | OptionNumber = BootOrder[Index];\r | |
217 | CopyMem (&BootOrder[*NextIndex + 1], &BootOrder[*NextIndex], (Index - *NextIndex) * sizeof (UINT16));\r | |
218 | BootOrder[*NextIndex] = OptionNumber;\r | |
5c08e117 | 219 | \r |
5c08e117 | 220 | //\r |
16e5944a | 221 | // Update the DeviceTypeIndex array to reflect the right shift operation\r |
5c08e117 | 222 | //\r |
16e5944a RN |
223 | for (DeviceIndex = 0; DeviceIndex < sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0]); DeviceIndex++) {\r |
224 | if (DeviceTypeIndex[DeviceIndex] != (UINTN) -1 && DeviceTypeIndex[DeviceIndex] >= *NextIndex) {\r | |
225 | DeviceTypeIndex[DeviceIndex]++;\r | |
22d1f978 | 226 | }\r |
5c08e117 | 227 | }\r |
228 | }\r | |
229 | }\r | |
16e5944a RN |
230 | FreePool (BootOption->DevicePath);\r |
231 | FreePool (BootOption->Description);\r | |
232 | FreePool (BootOption->LoadOptions);\r | |
233 | FreePool (BootOption);\r | |
5c08e117 | 234 | }\r |
235 | \r | |
16e5944a RN |
236 | gRT->SetVariable (\r |
237 | L"BootOrder",\r | |
238 | &gEfiGlobalVariableGuid,\r | |
239 | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r | |
240 | BootOrderSize,\r | |
241 | BootOrder\r | |
242 | );\r | |
243 | FreePool (BootOrder);\r | |
5c08e117 | 244 | }\r |
245 | \r |