]> git.proxmox.com Git - mirror_edk2.git/blame - Nt32Pkg/PlatformBdsDxe/Generic/BootMngr/BootManager.c
Cleanups in PlatformBds.c. BDS will get rewritten, but his makes it easier to look...
[mirror_edk2.git] / Nt32Pkg / PlatformBdsDxe / Generic / BootMngr / BootManager.c
CommitLineData
bc11b829 1/*++\r
2\r
3Copyright (c) 2006 - 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 BootManager.c\r
15\r
16Abstract:\r
17\r
18 The platform boot manager reference implement\r
19\r
20--*/\r
21//\r
22// Include common header file for this module.\r
23//\r
24#include "CommonHeader.h"\r
25\r
26#include "BootManager.h"\r
27\r
28UINT16 mKeyInput;\r
29LIST_ENTRY *mBootOptionsList;\r
30BDS_COMMON_OPTION *gOption;\r
31EFI_HII_HANDLE gBootManagerHandle;\r
32EFI_HANDLE BootManagerCallbackHandle;\r
33EFI_FORM_CALLBACK_PROTOCOL BootManagerCallback;\r
34EFI_GUID gBmGuid = BOOT_MANAGER_GUID;\r
35\r
36extern EFI_FORM_BROWSER_PROTOCOL *gBrowser;\r
37extern UINT8 BootManagerVfrBin[];\r
bc11b829 38extern BOOLEAN gConnectAllHappened;\r
39\r
40EFI_STATUS\r
41EFIAPI\r
42BootManagerCallbackRoutine (\r
43 IN EFI_FORM_CALLBACK_PROTOCOL *This,\r
44 IN UINT16 KeyValue,\r
45 IN EFI_IFR_DATA_ARRAY *DataArray,\r
46 OUT EFI_HII_CALLBACK_PACKET **Packet\r
47 )\r
48/*++\r
49\r
50Routine Description:\r
51\r
52 This is the function that is called to provide results data to the driver. This data\r
53 consists of a unique key which is used to identify what data is either being passed back\r
54 or being asked for.\r
55\r
56Arguments:\r
57\r
58 KeyValue - A unique value which is sent to the original exporting driver so that it\r
59 can identify the type of data to expect. The format of the data tends to\r
60 vary based on the op-code that geerated the callback.\r
61\r
62 Data - A pointer to the data being sent to the original exporting driver.\r
63\r
64Returns:\r
65\r
66--*/\r
67{\r
68 BDS_COMMON_OPTION *Option;\r
69 LIST_ENTRY *Link;\r
70 UINT16 KeyCount;\r
71 EFI_HII_CALLBACK_PACKET *DataPacket;\r
72\r
73 //\r
74 // Initialize the key count\r
75 //\r
76 KeyCount = 0;\r
77\r
78 for (Link = mBootOptionsList->ForwardLink; Link != mBootOptionsList; Link = Link->ForwardLink) {\r
79 Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
80\r
81 KeyCount++;\r
82\r
83 gOption = Option;\r
84\r
85 //\r
86 // Is this device the one chosen?\r
87 //\r
88 if (KeyCount == KeyValue) {\r
89 //\r
90 // Assigning the returned Key to a global allows the original routine to know what was chosen\r
91 //\r
92 mKeyInput = KeyValue;\r
93\r
94 *Packet = AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET) + 2);\r
95 ASSERT (*Packet != NULL);\r
96\r
97 //\r
98 // Assign the buffer address to DataPacket\r
99 //\r
100 DataPacket = *Packet;\r
101\r
102 DataPacket->DataArray.EntryCount = 1;\r
103 DataPacket->DataArray.NvRamMap = NULL;\r
104 ((EFI_IFR_DATA_ENTRY *) (((EFI_IFR_DATA_ARRAY *)DataPacket) + 1))->Flags = EXIT_REQUIRED | NV_NOT_CHANGED;\r
105 return EFI_SUCCESS;\r
106 } else {\r
107 continue;\r
108 }\r
109 }\r
110\r
111 return EFI_SUCCESS;\r
112}\r
113\r
114VOID\r
115CallBootManager (\r
116 VOID\r
117 )\r
118/*++\r
119\r
120Routine Description:\r
121 Hook to enable UI timeout override behavior.\r
122\r
123Arguments:\r
124 BdsDeviceList - Device List that BDS needs to connect.\r
125\r
126 Entry - Pointer to current Boot Entry.\r
127\r
128Returns:\r
129 NONE\r
130\r
131--*/\r
132{\r
133 EFI_STATUS Status;\r
134 EFI_HII_PACKAGES *PackageList;\r
135 BDS_COMMON_OPTION *Option;\r
136 LIST_ENTRY *Link;\r
137 EFI_HII_UPDATE_DATA *UpdateData;\r
138 CHAR16 *ExitData;\r
139 UINTN ExitDataSize;\r
140 STRING_REF Token;\r
141 STRING_REF LastToken;\r
142 EFI_INPUT_KEY Key;\r
143 UINT8 *Location;\r
144 EFI_GUID BmGuid;\r
145 LIST_ENTRY BdsBootOptionList;\r
146 BOOLEAN BootMngrMenuResetRequired;\r
147\r
148 gOption = NULL;\r
149 InitializeListHead (&BdsBootOptionList);\r
150\r
151 //\r
152 // Connect all prior to entering the platform setup menu.\r
153 //\r
154 if (!gConnectAllHappened) {\r
155 BdsLibConnectAllDriversToAllControllers ();\r
156 gConnectAllHappened = TRUE;\r
157 }\r
158 //\r
159 // BugBug: Here we can not remove the legacy refresh macro, so we need\r
160 // get the boot order every time from "BootOrder" variable.\r
161 // Recreate the boot option list base on the BootOrder variable\r
162 //\r
163 BdsLibEnumerateAllBootOption (&BdsBootOptionList);\r
164\r
165 //\r
166 // This GUID must be the same as what is defined in BootManagerVfr.vfr\r
167 //\r
168 BmGuid = gBmGuid;\r
169\r
170 mBootOptionsList = &BdsBootOptionList;\r
171\r
172 //\r
173 // Post our VFR to the HII database\r
174 //\r
851d410b 175 PackageList = PreparePackages (2, &BmGuid, BootManagerVfrBin, PlatformBdsStrings);\r
d1477e4d 176 Status = gHii->NewPack (gHii, PackageList, &gBootManagerHandle);\r
bc11b829 177 FreePool (PackageList);\r
178\r
179 //\r
180 // This example does not implement worker functions\r
181 // for the NV accessor functions. Only a callback evaluator\r
182 //\r
183 BootManagerCallback.NvRead = NULL;\r
184 BootManagerCallback.NvWrite = NULL;\r
185 BootManagerCallback.Callback = BootManagerCallbackRoutine;\r
186\r
187 //\r
188 // Install protocol interface\r
189 //\r
190 BootManagerCallbackHandle = NULL;\r
191 Status = gBS->InstallProtocolInterface (\r
192 &BootManagerCallbackHandle,\r
193 &gEfiFormCallbackProtocolGuid,\r
194 EFI_NATIVE_INTERFACE,\r
195 &BootManagerCallback\r
196 );\r
197 ASSERT_EFI_ERROR (Status);\r
198\r
199 LastToken = 0;\r
d1477e4d 200 gHii->NewString (gHii, NULL, gBootManagerHandle, &LastToken, L" ");\r
bc11b829 201\r
202 //\r
203 // Allocate space for creation of UpdateData Buffer\r
204 //\r
205 UpdateData = AllocateZeroPool (0x1000);\r
206 ASSERT (UpdateData != NULL);\r
207\r
208 //\r
209 // Flag update pending in FormSet\r
210 //\r
211 UpdateData->FormSetUpdate = TRUE;\r
212 //\r
213 // Register CallbackHandle data for FormSet\r
214 //\r
215 UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) BootManagerCallbackHandle;\r
216 UpdateData->FormUpdate = FALSE;\r
217 UpdateData->FormTitle = 0;\r
218 UpdateData->DataCount = 1;\r
219\r
220 //\r
221 // Create blank space. Since when we update the contents of IFR data at a label, it is\r
222 // inserted at the location of the label. So if you want to add a string with an empty\r
223 // space afterwards, you need to add the space first and then the string like below.\r
224 //\r
225 Status = CreateSubTitleOpCode (\r
226 LastToken, // Token Value for the string\r
227 &UpdateData->Data // Buffer containing created op-code\r
228 );\r
229\r
d1477e4d 230 gHii->UpdateForm (gHii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0000, TRUE, UpdateData);\r
bc11b829 231\r
232 //\r
233 // Create "Boot Option Menu" title\r
234 //\r
235 Status = CreateSubTitleOpCode (\r
236 STRING_TOKEN (STR_BOOT_OPTION_BANNER), // Token Value for the string\r
237 &UpdateData->Data // Buffer containing created op-code\r
238 );\r
239\r
d1477e4d 240 gHii->UpdateForm (gHii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0000, TRUE, UpdateData);\r
bc11b829 241\r
242 Token = LastToken;\r
243 mKeyInput = 0;\r
244\r
245 UpdateData->DataCount = 0;\r
246 Location = (UINT8 *) &UpdateData->Data;\r
247\r
248 for (Link = BdsBootOptionList.ForwardLink; Link != &BdsBootOptionList; Link = Link->ForwardLink) {\r
249 Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
250\r
251 //\r
252 // At this stage we are creating a menu entry, thus the Keys are reproduceable\r
253 //\r
254 mKeyInput++;\r
255 Token++;\r
256\r
d1477e4d 257 Status = gHii->NewString (gHii, NULL, gBootManagerHandle, &Token, Option->Description);\r
bc11b829 258\r
259 //\r
260 // If we got an error it is almost certainly due to the token value being invalid.\r
261 // Therefore we will set the Token to 0 to automatically add a token.\r
262 //\r
263 if (EFI_ERROR (Status)) {\r
264 Token = 0;\r
d1477e4d 265 Status = gHii->NewString (gHii, NULL, gBootManagerHandle, &Token, Option->Description);\r
bc11b829 266 }\r
267\r
268 Status = CreateGotoOpCode (\r
269 0x1000, // Form ID\r
270 Token, // Token Value for the string\r
271 0, // Help String (none)\r
272 EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS, // The Op-Code flags\r
273 mKeyInput, // The Key to get a callback on\r
274 Location // Buffer containing created op-code\r
275 );\r
276\r
277 UpdateData->DataCount++;\r
278 Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
279\r
280 }\r
281\r
d1477e4d 282 gHii->UpdateForm (gHii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0001, TRUE, UpdateData);\r
bc11b829 283\r
284 UpdateData->DataCount = 1;\r
285\r
286 //\r
287 // Create "Boot Option Menu" title\r
288 //\r
289 Status = CreateSubTitleOpCode (\r
290 STRING_TOKEN (STR_HELP_FOOTER), // Token Value for the string\r
291 &UpdateData->Data // Buffer containing created op-code\r
292 );\r
293\r
d1477e4d 294 gHii->UpdateForm (gHii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);\r
bc11b829 295\r
296 Status = CreateSubTitleOpCode (\r
297 LastToken, // Token Value for the string\r
298 &UpdateData->Data // Buffer containing created op-code\r
299 );\r
300\r
d1477e4d 301 gHii->UpdateForm (gHii, gBootManagerHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);\r
bc11b829 302\r
303 FreePool (UpdateData);\r
304\r
305 ASSERT (gBrowser);\r
306\r
307 BootMngrMenuResetRequired = FALSE;\r
308 gBrowser->SendForm (\r
309 gBrowser,\r
310 TRUE,\r
311 &gBootManagerHandle,\r
312 1,\r
313 NULL,\r
314 NULL,\r
315 NULL,\r
316 NULL,\r
317 &BootMngrMenuResetRequired\r
318 );\r
319\r
320 if (BootMngrMenuResetRequired) {\r
321 EnableResetRequired ();\r
322 }\r
323\r
d1477e4d 324 gHii->ResetStrings (gHii, gBootManagerHandle);\r
bc11b829 325\r
326 if (gOption == NULL) {\r
327 return ;\r
328 }\r
329\r
330 //\r
331 //Will leave browser, check any reset required change is applied? if yes, reset system\r
332 //\r
333 SetupResetReminder ();\r
334\r
335 //\r
336 // BugBug: This code looks repeated from the BDS. Need to save code space.\r
337 //\r
338\r
339 //\r
340 // parse the selected option\r
341 //\r
342 Status = BdsLibBootViaBootOption (gOption, gOption->DevicePath, &ExitDataSize, &ExitData);\r
343\r
344 if (!EFI_ERROR (Status)) {\r
345 PlatformBdsBootSuccess (gOption);\r
346 } else {\r
347 PlatformBdsBootFail (gOption, Status, ExitData, ExitDataSize);\r
348 gST->ConOut->OutputString (\r
349 gST->ConOut,\r
350 GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE))\r
351 );\r
352\r
353 //\r
354 // BdsLibUiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);\r
355 //\r
356\r
357 gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
358 }\r
359}\r