]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/BdsDxe/BootMngr/BootManager.c
Move BdsDxe and GenericBdsLib to IntelFrameworkModulePkg, these modules need dependen...
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMngr / BootManager.c
CommitLineData
5c08e117 1/** @file\r
2 The platform boot manager reference implementation\r
3\r
4Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "BootManager.h"\r
16\r
17UINT16 mKeyInput;\r
18EFI_GUID mBootManagerGuid = BOOT_MANAGER_FORMSET_GUID;\r
19LIST_ENTRY *mBootOptionsList;\r
20BDS_COMMON_OPTION *gOption;\r
21\r
22BOOT_MANAGER_CALLBACK_DATA gBootManagerPrivate = {\r
23 BOOT_MANAGER_CALLBACK_DATA_SIGNATURE,\r
24 NULL,\r
25 NULL,\r
26 {\r
27 FakeExtractConfig,\r
28 FakeRouteConfig,\r
29 BootManagerCallback\r
30 }\r
31};\r
32\r
33/**\r
34 This call back funtion is registered with Boot Manager formset.\r
35 When user selects a boot option, this call back function will\r
36 be triggered. The boot option is saved for later processing.\r
37\r
38\r
39 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
40 @param Action Specifies the type of action taken by the browser.\r
41 @param QuestionId A unique value which is sent to the original exporting driver\r
42 so that it can identify the type of data to expect.\r
43 @param Type The type of value for the question.\r
44 @param Value A pointer to the data being sent to the original exporting driver.\r
45 @param ActionRequest On return, points to the action requested by the callback function.\r
46\r
47 @retval EFI_SUCCESS The callback successfully handled the action.\r
48 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.\r
49\r
50**/\r
51EFI_STATUS\r
52EFIAPI\r
53BootManagerCallback (\r
54 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
55 IN EFI_BROWSER_ACTION Action,\r
56 IN EFI_QUESTION_ID QuestionId,\r
57 IN UINT8 Type,\r
58 IN EFI_IFR_TYPE_VALUE *Value,\r
59 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
60 )\r
61{\r
62 BDS_COMMON_OPTION *Option;\r
63 LIST_ENTRY *Link;\r
64 UINT16 KeyCount;\r
65\r
66 if ((Value == NULL) || (ActionRequest == NULL)) {\r
67 return EFI_INVALID_PARAMETER;\r
68 }\r
69\r
70 //\r
71 // Initialize the key count\r
72 //\r
73 KeyCount = 0;\r
74\r
75 for (Link = mBootOptionsList->ForwardLink; Link != mBootOptionsList; Link = Link->ForwardLink) {\r
76 Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
77\r
78 KeyCount++;\r
79\r
80 gOption = Option;\r
81\r
82 //\r
83 // Is this device the one chosen?\r
84 //\r
85 if (KeyCount == QuestionId) {\r
86 //\r
87 // Assigning the returned Key to a global allows the original routine to know what was chosen\r
88 //\r
89 mKeyInput = QuestionId;\r
90\r
91 //\r
92 // Request to exit SendForm(), so that we could boot the selected option\r
93 //\r
94 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
95 break;\r
96 }\r
97 }\r
98\r
99 return EFI_SUCCESS;\r
100}\r
101\r
102/**\r
103\r
104 Registers HII packages for the Boot Manger to HII Database.\r
105 It also registers the browser call back function.\r
106\r
107 @return Status of HiiLibCreateHiiDriverHandle() and gHiiDatabase->NewPackageList()\r
108\r
109**/\r
110EFI_STATUS\r
111InitializeBootManager (\r
112 VOID\r
113 )\r
114{\r
115 EFI_STATUS Status;\r
116 EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
117\r
118 //\r
119 // Create driver handle used by HII database\r
120 //\r
121 Status = HiiLibCreateHiiDriverHandle (&gBootManagerPrivate.DriverHandle);\r
122 if (EFI_ERROR (Status)) {\r
123 return Status;\r
124 }\r
125\r
126 //\r
127 // Install Config Access protocol to driver handle\r
128 //\r
129 Status = gBS->InstallProtocolInterface (\r
130 &gBootManagerPrivate.DriverHandle,\r
131 &gEfiHiiConfigAccessProtocolGuid,\r
132 EFI_NATIVE_INTERFACE,\r
133 &gBootManagerPrivate.ConfigAccess\r
134 );\r
135 ASSERT_EFI_ERROR (Status);\r
136\r
137 //\r
138 // Publish our HII data\r
139 //\r
140 PackageList = HiiLibPreparePackageList (2, &mBootManagerGuid, BootManagerVfrBin, BdsDxeStrings);\r
141 ASSERT (PackageList != NULL);\r
142\r
143 Status = gHiiDatabase->NewPackageList (\r
144 gHiiDatabase,\r
145 PackageList,\r
146 gBootManagerPrivate.DriverHandle,\r
147 &gBootManagerPrivate.HiiHandle\r
148 );\r
149 FreePool (PackageList);\r
150\r
151 return Status;\r
152}\r
153\r
154/**\r
155 This funtion invokees Boot Manager. If all devices have not a chance to be connected,\r
156 the connect all will be triggered. It then enumerate all boot options. If \r
157 a boot option from the Boot Manager page is selected, Boot Manager will boot\r
158 from this boot option.\r
159 \r
160**/\r
161VOID\r
162CallBootManager (\r
163 VOID\r
164 )\r
165{\r
166 EFI_STATUS Status;\r
167 BDS_COMMON_OPTION *Option;\r
168 LIST_ENTRY *Link;\r
169 EFI_HII_UPDATE_DATA UpdateData;\r
170 CHAR16 *ExitData;\r
171 UINTN ExitDataSize;\r
172 EFI_STRING_ID Token;\r
173 EFI_INPUT_KEY Key;\r
174 LIST_ENTRY BdsBootOptionList;\r
175 CHAR16 *HelpString;\r
176 EFI_STRING_ID HelpToken;\r
177 UINT16 *TempStr;\r
178 EFI_HII_HANDLE HiiHandle;\r
179 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
180 UINTN TempSize;\r
181\r
182 gOption = NULL;\r
183 InitializeListHead (&BdsBootOptionList);\r
184\r
185 //\r
186 // Connect all prior to entering the platform setup menu.\r
187 //\r
188 if (!gConnectAllHappened) {\r
189 BdsLibConnectAllDriversToAllControllers ();\r
190 gConnectAllHappened = TRUE;\r
191 }\r
192 //\r
193 // BugBug: Here we can not remove the legacy refresh macro, so we need\r
194 // get the boot order every time from "BootOrder" variable.\r
195 // Recreate the boot option list base on the BootOrder variable\r
196 //\r
197 BdsLibEnumerateAllBootOption (&BdsBootOptionList);\r
198\r
199 mBootOptionsList = &BdsBootOptionList;\r
200\r
201 HiiHandle = gBootManagerPrivate.HiiHandle;\r
202\r
203 //\r
204 // Allocate space for creation of UpdateData Buffer\r
205 //\r
206 UpdateData.BufferSize = 0x1000;\r
207 UpdateData.Offset = 0;\r
208 UpdateData.Data = AllocateZeroPool (0x1000);\r
209 ASSERT (UpdateData.Data != NULL);\r
210\r
211 mKeyInput = 0;\r
212\r
213 for (Link = BdsBootOptionList.ForwardLink; Link != &BdsBootOptionList; Link = Link->ForwardLink) {\r
214 Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
215\r
216 //\r
217 // At this stage we are creating a menu entry, thus the Keys are reproduceable\r
218 //\r
219 mKeyInput++;\r
220\r
221 //\r
222 // Don't display the boot option marked as LOAD_OPTION_HIDDEN\r
223 //\r
224 if (Option->Attribute & LOAD_OPTION_HIDDEN) {\r
225 continue;\r
226 }\r
227\r
228 HiiLibNewString (HiiHandle, &Token, Option->Description);\r
229\r
230 TempStr = DevicePathToStr (Option->DevicePath);\r
231 TempSize = StrSize (TempStr);\r
232 HelpString = AllocateZeroPool (TempSize + StrSize (L"Device Path : "));\r
233 ASSERT (HelpString != NULL);\r
234 StrCat (HelpString, L"Device Path : ");\r
235 StrCat (HelpString, TempStr);\r
236\r
237 HiiLibNewString (HiiHandle, &HelpToken, HelpString);\r
238\r
239 CreateActionOpCode (\r
240 mKeyInput,\r
241 Token,\r
242 HelpToken,\r
243 EFI_IFR_FLAG_CALLBACK,\r
244 0,\r
245 &UpdateData\r
246 );\r
247 }\r
248\r
249 IfrLibUpdateForm (\r
250 HiiHandle,\r
251 &mBootManagerGuid,\r
252 BOOT_MANAGER_FORM_ID,\r
253 LABEL_BOOT_OPTION,\r
254 FALSE,\r
255 &UpdateData\r
256 );\r
257 FreePool (UpdateData.Data);\r
258\r
259 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
260 Status = gFormBrowser2->SendForm (\r
261 gFormBrowser2,\r
262 &HiiHandle,\r
263 1,\r
264 NULL,\r
265 0,\r
266 NULL,\r
267 &ActionRequest\r
268 );\r
269 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
270 EnableResetRequired ();\r
271 }\r
272\r
273 if (gOption == NULL) {\r
274 return ;\r
275 }\r
276\r
277 //\r
278 //Will leave browser, check any reset required change is applied? if yes, reset system\r
279 //\r
280 SetupResetReminder ();\r
281\r
282 //\r
283 // parse the selected option\r
284 //\r
285 Status = BdsLibBootViaBootOption (gOption, gOption->DevicePath, &ExitDataSize, &ExitData);\r
286\r
287 if (!EFI_ERROR (Status)) {\r
288 gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));\r
289 PlatformBdsBootSuccess (gOption);\r
290 } else {\r
291 gOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));\r
292 PlatformBdsBootFail (gOption, Status, ExitData, ExitDataSize);\r
293 gST->ConOut->OutputString (\r
294 gST->ConOut,\r
295 GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))\r
296 );\r
297 gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
298 }\r
299}\r