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