]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c
Only use ports with a network connection (media present) when connecting to a remote...
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / BBSsupport.c
CommitLineData
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 6Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
180a5a35 7This program and the accompanying materials\r
5c08e117 8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT 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
20typedef 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
40VOID\r
41OrderLegacyBootOption4SameType (\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
79 ASSERT (*EnBootOption != NULL);\r
80 ASSERT (*DisBootOption != NULL);\r
81\r
82 for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
83 \r
84 UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);\r
85 InitializeListHead (&List);\r
86 BootOption = BdsLibVariableToOption (&List, OptionName);\r
87 ASSERT_EFI_ERROR (BootOption != NULL);\r
88 \r
89 if ((DevicePathType (BootOption->DevicePath) == BBS_DEVICE_PATH) &&\r
90 (DevicePathSubType (BootOption->DevicePath) == BBS_BBS_DP)) {\r
91 //\r
92 // Legacy Boot Option\r
93 //\r
94 ASSERT (BootOption->LoadOptionsSize == sizeof (LEGACY_BOOT_OPTION_BBS_DATA));\r
95\r
96 DeviceTypeArray[Index] = ((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType;\r
97 BbsIndexArray [Index] = ((LEGACY_BOOT_OPTION_BBS_DATA *) BootOption->LoadOptions)->BbsIndex;\r
98 } else {\r
99 DeviceTypeArray[Index] = BBS_TYPE_UNKNOWN;\r
100 BbsIndexArray [Index] = 0xFFFF;\r
101 }\r
102 FreePool (BootOption->DevicePath);\r
103 FreePool (BootOption->Description);\r
104 FreePool (BootOption->LoadOptions);\r
105 FreePool (BootOption);\r
106 }\r
22d1f978
RN
107\r
108 //\r
109 // Record the corresponding Boot Option Numbers according to the DevOrder\r
110 // Record the EnBootOption and DisBootOption according to the DevOrder\r
111 //\r
16e5944a 112 StartPosition = BootOrderSize / sizeof (UINT16);\r
22d1f978
RN
113 NewBootOption = AllocatePool (DevOrderCount * sizeof (UINT16));\r
114 while (DevOrderCount-- != 0) {\r
16e5944a
RN
115 for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
116 if (BbsIndexArray[Index] == (DevOrder[DevOrderCount] & 0xFF)) {\r
117 StartPosition = MIN (StartPosition, Index);\r
118 NewBootOption[DevOrderCount] = BootOrder[Index];\r
22d1f978
RN
119 \r
120 if ((DevOrder[DevOrderCount] & 0xFF00) == 0xFF00) {\r
16e5944a 121 (*DisBootOption)[*DisBootOptionCount] = BootOrder[Index];\r
22d1f978
RN
122 (*DisBootOptionCount)++;\r
123 } else {\r
16e5944a 124 (*EnBootOption)[*EnBootOptionCount] = BootOrder[Index];\r
22d1f978
RN
125 (*EnBootOptionCount)++;\r
126 }\r
127 break;\r
128 }\r
129 }\r
130 }\r
131\r
16e5944a
RN
132 //\r
133 // Overwrite the old BootOption\r
134 //\r
135 CopyMem (&BootOrder[StartPosition], NewBootOption, (*DisBootOptionCount + *EnBootOptionCount) * sizeof (UINT16));\r
136 Status = gRT->SetVariable (\r
137 L"BootOrder",\r
138 &gEfiGlobalVariableGuid,\r
139 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
140 BootOrderSize,\r
141 BootOrder\r
142 );\r
143 ASSERT_EFI_ERROR (Status);\r
22d1f978 144\r
16e5944a
RN
145 FreePool (NewBootOption);\r
146 FreePool (DeviceTypeArray);\r
147 FreePool (BbsIndexArray);\r
22d1f978
RN
148}\r
149\r
150/**\r
151 Group the legacy boot options in the BootOption.\r
152\r
153 The routine assumes the boot options in the beginning that covers all the device \r
154 types are ordered properly and re-position the following boot options just after\r
155 the corresponding boot options with the same device type.\r
156 For example:\r
157 1. Input = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0]\r
158 Assuming [Harddisk1 CdRom2 Efi1] is ordered properly\r
159 Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0]\r
160\r
161 2. Input = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2]\r
162 Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly\r
163 Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]\r
164\r
22d1f978
RN
165**/\r
166VOID\r
167GroupMultipleLegacyBootOption4SameType (\r
5c08e117 168 VOID\r
169 )\r
170{\r
16e5944a
RN
171 UINTN Index;\r
172 UINTN DeviceIndex;\r
173 UINTN DeviceTypeIndex[7];\r
174 UINTN *NextIndex;\r
175 UINT16 OptionNumber;\r
176 UINT16 *BootOrder;\r
177 UINTN BootOrderSize;\r
178 CHAR16 OptionName[sizeof ("Boot####")];\r
179 BDS_COMMON_OPTION *BootOption;\r
180 LIST_ENTRY List;\r
22d1f978 181\r
16e5944a 182 SetMem (DeviceTypeIndex, sizeof (DeviceTypeIndex), 0xff);\r
5c08e117 183\r
184 BootOrder = BdsLibGetVariableAndSize (\r
185 L"BootOrder",\r
186 &gEfiGlobalVariableGuid,\r
187 &BootOrderSize\r
188 );\r
5c08e117 189\r
16e5944a
RN
190 for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
191 UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);\r
192 InitializeListHead (&List);\r
193 BootOption = BdsLibVariableToOption (&List, OptionName);\r
194 ASSERT_EFI_ERROR (BootOption != NULL);\r
22d1f978 195\r
16e5944a
RN
196 if ((DevicePathType (BootOption->DevicePath) == BBS_DEVICE_PATH) &&\r
197 (DevicePathSubType (BootOption->DevicePath) == BBS_BBS_DP)) {\r
22d1f978 198 //\r
16e5944a 199 // Legacy Boot Option\r
22d1f978 200 //\r
16e5944a
RN
201 ASSERT ((((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType & 0xF) < sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0]));\r
202 NextIndex = &DeviceTypeIndex[((BBS_BBS_DEVICE_PATH *) BootOption->DevicePath)->DeviceType & 0xF];\r
5c08e117 203\r
16e5944a
RN
204 if (*NextIndex == (UINTN) -1) {\r
205 //\r
206 // *NextIndex is the Index in BootOrder to put the next Option Number for the same type\r
207 //\r
208 *NextIndex = Index + 1;\r
209 } else {\r
210 //\r
211 // insert the current boot option before *NextIndex, causing [*Next .. Index] shift right one position\r
212 //\r
213 OptionNumber = BootOrder[Index];\r
214 CopyMem (&BootOrder[*NextIndex + 1], &BootOrder[*NextIndex], (Index - *NextIndex) * sizeof (UINT16));\r
215 BootOrder[*NextIndex] = OptionNumber;\r
5c08e117 216\r
5c08e117 217 //\r
16e5944a 218 // Update the DeviceTypeIndex array to reflect the right shift operation\r
5c08e117 219 //\r
16e5944a
RN
220 for (DeviceIndex = 0; DeviceIndex < sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0]); DeviceIndex++) {\r
221 if (DeviceTypeIndex[DeviceIndex] != (UINTN) -1 && DeviceTypeIndex[DeviceIndex] >= *NextIndex) {\r
222 DeviceTypeIndex[DeviceIndex]++;\r
22d1f978 223 }\r
5c08e117 224 }\r
225 }\r
226 }\r
16e5944a
RN
227 FreePool (BootOption->DevicePath);\r
228 FreePool (BootOption->Description);\r
229 FreePool (BootOption->LoadOptions);\r
230 FreePool (BootOption);\r
5c08e117 231 }\r
232\r
16e5944a
RN
233 gRT->SetVariable (\r
234 L"BootOrder",\r
235 &gEfiGlobalVariableGuid,\r
236 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
237 BootOrderSize,\r
238 BootOrder\r
239 );\r
240 FreePool (BootOrder);\r
5c08e117 241}\r
242\r