]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
Support RouteConfig function for BdsDxe driver.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / BootMaint.c
CommitLineData
5c08e117 1/** @file\r
2 The functions for Boot Maintainence Main menu.\r
3\r
69fc8f08 4Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
180a5a35 5This program and the accompanying materials\r
5c08e117 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 "BootMaint.h"\r
16#include "FormGuid.h"\r
17#include "Bds.h"\r
18#include "FrontPage.h"\r
19\r
20EFI_DEVICE_PATH_PROTOCOL EndDevicePath[] = {\r
21 {\r
22 END_DEVICE_PATH_TYPE,\r
23 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
24 {\r
25 END_DEVICE_PATH_LENGTH,\r
26 0\r
27 }\r
28 }\r
29};\r
30\r
f6f910dd 31HII_VENDOR_DEVICE_PATH mBmmHiiVendorDevicePath = {\r
32 {\r
33 {\r
34 HARDWARE_DEVICE_PATH,\r
35 HW_VENDOR_DP,\r
36 {\r
37 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
38 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
39 }\r
40 },\r
e24fc103 41 BOOT_MAINT_FORMSET_GUID\r
f6f910dd 42 },\r
43 {\r
44 END_DEVICE_PATH_TYPE,\r
45 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
46 { \r
47 (UINT8) (END_DEVICE_PATH_LENGTH),\r
48 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
49 }\r
50 }\r
51};\r
52\r
53HII_VENDOR_DEVICE_PATH mFeHiiVendorDevicePath = {\r
54 {\r
55 {\r
56 HARDWARE_DEVICE_PATH,\r
57 HW_VENDOR_DP,\r
58 {\r
59 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
60 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
61 }\r
62 },\r
e24fc103 63 FILE_EXPLORE_FORMSET_GUID\r
f6f910dd 64 },\r
65 {\r
66 END_DEVICE_PATH_TYPE,\r
67 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
68 { \r
69 (UINT8) (END_DEVICE_PATH_LENGTH),\r
70 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
71 }\r
72 }\r
73};\r
5c08e117 74\r
75bf9d0e 75CHAR16 mBootMaintStorageName[] = L"BmmData";\r
5c08e117 76CHAR16 mFileExplorerStorageName[] = L"FeData";\r
be9304f3 77BMM_CALLBACK_DATA *mBmmCallbackInfo = NULL;\r
5c08e117 78\r
79/**\r
80 Init all memu.\r
81\r
82 @param CallbackData The BMM context data.\r
83\r
84**/\r
85VOID\r
86InitAllMenu (\r
87 IN BMM_CALLBACK_DATA *CallbackData\r
88 );\r
89\r
90/**\r
91 Free up all Menu Option list.\r
92\r
93**/\r
94VOID\r
95FreeAllMenu (\r
96 VOID\r
97 );\r
98\r
be9304f3
ED
99/**\r
100 Initialize all of BMM configuration data in BmmFakeNvData and BmmOldFakeNVData member\r
101 in BMM context data and create all of dynamic OP code for BMM.\r
102\r
103 @param CallbackData The BMM context data.\r
104\r
105**/\r
106VOID\r
107InitializeBmmConfig (\r
108 IN BMM_CALLBACK_DATA *CallbackData\r
109 )\r
110{\r
111 BM_MENU_ENTRY *NewMenuEntry;\r
112 BM_LOAD_CONTEXT *NewLoadContext;\r
113 UINT16 Index;\r
114\r
115 ASSERT (CallbackData != NULL);\r
116\r
117 //\r
118 // Initialize data which located in BMM main page\r
119 //\r
120 CallbackData->BmmFakeNvData.BootNext = (UINT16) (BootOptionMenu.MenuNumber);\r
121 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
122 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
123 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
124\r
125 if (NewLoadContext->IsBootNext) {\r
126 CallbackData->BmmFakeNvData.BootNext = Index;\r
127 break;\r
128 }\r
129 }\r
130\r
131 CallbackData->BmmFakeNvData.BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut);\r
132\r
133 //\r
134 // Initialize data which located in Boot Options Menu\r
135 //\r
136 GetBootOrder (CallbackData);\r
137 GetLegacyDeviceOrder (CallbackData);\r
138\r
139 //\r
140 // Initialize data which located in Driver Options Menu\r
141 //\r
142 GetDriverOrder (CallbackData);\r
143\r
144 //\r
145 // Initialize data which located in Console Options Menu\r
146 // \r
147 GetConsoleOutMode (CallbackData); \r
148 GetConsoleInCheck (CallbackData);\r
149 GetConsoleOutCheck (CallbackData);\r
150 GetConsoleErrCheck (CallbackData);\r
151 GetTerminalAttribute (CallbackData);\r
152\r
153 //\r
154 // Backup Initialize BMM configuartion data to BmmOldFakeNVData\r
155 //\r
156 CopyMem (&CallbackData->BmmOldFakeNVData, &CallbackData->BmmFakeNvData, sizeof (BMM_FAKE_NV_DATA));\r
157}\r
158\r
5c08e117 159/**\r
160 Create string tokens for a menu from its help strings and display strings\r
161\r
162 @param CallbackData The BMM context data.\r
163 @param HiiHandle Hii Handle of the package to be updated.\r
164 @param MenuOption The Menu whose string tokens need to be created\r
165\r
166 @retval EFI_SUCCESS String tokens created successfully\r
167 @retval others contain some errors\r
168**/\r
169EFI_STATUS\r
170CreateMenuStringToken (\r
171 IN BMM_CALLBACK_DATA *CallbackData,\r
172 IN EFI_HII_HANDLE HiiHandle,\r
173 IN BM_MENU_OPTION *MenuOption\r
174 )\r
175{\r
176 BM_MENU_ENTRY *NewMenuEntry;\r
177 UINTN Index;\r
178\r
179 for (Index = 0; Index < MenuOption->MenuNumber; Index++) {\r
180 NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);\r
181\r
cb7d01c0 182 NewMenuEntry->DisplayStringToken = HiiSetString (\r
183 HiiHandle,\r
184 0,\r
185 NewMenuEntry->DisplayString,\r
186 NULL\r
187 );\r
5c08e117 188\r
189 if (NULL == NewMenuEntry->HelpString) {\r
190 NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;\r
191 } else {\r
cb7d01c0 192 NewMenuEntry->HelpStringToken = HiiSetString (\r
193 HiiHandle,\r
194 0,\r
195 NewMenuEntry->HelpString,\r
196 NULL\r
197 );\r
5c08e117 198 }\r
199 }\r
200\r
201 return EFI_SUCCESS;\r
202}\r
203\r
204/**\r
205 This function allows a caller to extract the current configuration for one\r
206 or more named elements from the target driver.\r
207\r
208\r
209 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
210 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
211 @param Progress On return, points to a character in the Request string.\r
212 Points to the string's null terminator if request was successful.\r
213 Points to the most recent '&' before the first failing name/value\r
214 pair (or the beginning of the string if the failure is in the\r
215 first name/value pair) if the request was not successful.\r
216 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
217 has all values filled in for the names in the Request string.\r
218 String to be allocated by the called function.\r
219\r
220 @retval EFI_SUCCESS The Results is filled with the requested values.\r
221 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
222 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
223 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
224\r
225**/\r
226EFI_STATUS\r
227EFIAPI\r
228BootMaintExtractConfig (\r
229 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
230 IN CONST EFI_STRING Request,\r
231 OUT EFI_STRING *Progress,\r
232 OUT EFI_STRING *Results\r
233 )\r
234{\r
235 EFI_STATUS Status;\r
236 UINTN BufferSize;\r
237 BMM_CALLBACK_DATA *Private;\r
59aefb7e
LG
238 EFI_STRING ConfigRequestHdr;\r
239 EFI_STRING ConfigRequest;\r
240 BOOLEAN AllocatedRequest;\r
241 UINTN Size;\r
5c08e117 242\r
59aefb7e 243 if (Progress == NULL || Results == NULL) {\r
5c08e117 244 return EFI_INVALID_PARAMETER;\r
245 }\r
246\r
59aefb7e 247 *Progress = Request;\r
e24fc103 248 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gBootMaintFormSetGuid, mBootMaintStorageName)) {\r
59aefb7e
LG
249 return EFI_NOT_FOUND;\r
250 }\r
5c08e117 251\r
59aefb7e
LG
252 ConfigRequestHdr = NULL;\r
253 ConfigRequest = NULL;\r
254 AllocatedRequest = FALSE;\r
255 Size = 0;\r
256\r
257 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
5c08e117 258 //\r
259 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
260 //\r
261 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
59aefb7e
LG
262 ConfigRequest = Request;\r
263 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
264 //\r
265 // Request has no request element, construct full request string.\r
266 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
267 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
268 //\r
e24fc103 269 ConfigRequestHdr = HiiConstructConfigHdr (&gBootMaintFormSetGuid, mBootMaintStorageName, Private->BmmDriverHandle);\r
59aefb7e
LG
270 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
271 ConfigRequest = AllocateZeroPool (Size);\r
272 ASSERT (ConfigRequest != NULL);\r
273 AllocatedRequest = TRUE;\r
274 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
275 FreePool (ConfigRequestHdr);\r
276 }\r
277\r
5c08e117 278 Status = gHiiConfigRouting->BlockToConfig (\r
279 gHiiConfigRouting,\r
59aefb7e 280 ConfigRequest,\r
5c08e117 281 (UINT8 *) &Private->BmmFakeNvData,\r
282 BufferSize,\r
283 Results,\r
284 Progress\r
285 );\r
59aefb7e
LG
286 //\r
287 // Free the allocated config request string.\r
288 //\r
289 if (AllocatedRequest) {\r
290 FreePool (ConfigRequest);\r
291 ConfigRequest = NULL;\r
292 }\r
293 //\r
294 // Set Progress string to the original request string.\r
295 //\r
296 if (Request == NULL) {\r
297 *Progress = NULL;\r
298 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
299 *Progress = Request + StrLen (Request);\r
300 }\r
301\r
5c08e117 302 return Status;\r
303}\r
304\r
be9304f3
ED
305/**\r
306 This function applies changes in a driver's configuration.\r
307 Input is a Configuration, which has the routing data for this\r
308 driver followed by name / value configuration pairs. The driver\r
309 must apply those pairs to its configurable storage. If the\r
310 driver's configuration is stored in a linear block of data\r
311 and the driver's name / value pairs are in <BlockConfig>\r
312 format, it may use the ConfigToBlock helper function (above) to\r
313 simplify the job. Currently not implemented.\r
314\r
315 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
316 @param[in] Configuration A null-terminated Unicode string in\r
317 <ConfigString> format. \r
318 @param[out] Progress A pointer to a string filled in with the\r
319 offset of the most recent '&' before the\r
320 first failing name / value pair (or the\r
321 beginn ing of the string if the failure\r
322 is in the first name / value pair) or\r
323 the terminating NULL if all was\r
324 successful.\r
325\r
326 @retval EFI_SUCCESS The results have been distributed or are\r
327 awaiting distribution. \r
328 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
329 parts of the results that must be\r
330 stored awaiting possible future\r
331 protocols.\r
332 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
333 Results parameter would result\r
334 in this type of error.\r
335 @retval EFI_NOT_FOUND Target for the specified routing data\r
336 was not found.\r
337**/\r
338EFI_STATUS\r
339EFIAPI\r
340BootMaintRouteConfig (\r
341 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
342 IN CONST EFI_STRING Configuration,\r
343 OUT EFI_STRING *Progress\r
344 )\r
345{\r
346 EFI_STATUS Status;\r
347 UINTN BufferSize;\r
348 EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;\r
349 BMM_FAKE_NV_DATA *NewBmmData;\r
350 BMM_FAKE_NV_DATA *OldBmmData;\r
351 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
352 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
353 BM_MENU_ENTRY *NewMenuEntry;\r
354 BM_LOAD_CONTEXT *NewLoadContext;\r
355 UINT16 Index; \r
356 BOOLEAN TerminalAttChange;\r
357 BMM_CALLBACK_DATA *Private; \r
358\r
359 if (Progress == NULL) {\r
360 return EFI_INVALID_PARAMETER;\r
361 }\r
362 *Progress = Configuration;\r
363\r
364 if (Configuration == NULL) {\r
365 return EFI_INVALID_PARAMETER;\r
366 }\r
367\r
368 //\r
369 // Check routing data in <ConfigHdr>.\r
370 // Note: there is no name for Name/Value storage, only GUID will be checked\r
371 //\r
372 if (!HiiIsConfigHdrMatch (Configuration, &gBootMaintFormSetGuid, mBootMaintStorageName)) {\r
373 return EFI_NOT_FOUND;\r
374 }\r
375\r
376 Status = gBS->LocateProtocol (\r
377 &gEfiHiiConfigRoutingProtocolGuid, \r
378 NULL, \r
379 &ConfigRouting\r
380 );\r
381 if (EFI_ERROR (Status)) {\r
382 return Status;\r
383 }\r
384\r
385 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
386 //\r
387 // Get Buffer Storage data from EFI variable\r
388 //\r
389 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
390 OldBmmData = &Private->BmmOldFakeNVData;\r
391 NewBmmData = &Private->BmmFakeNvData;\r
392 //\r
393 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
394 //\r
395 Status = ConfigRouting->ConfigToBlock (\r
396 ConfigRouting,\r
397 Configuration,\r
398 (UINT8 *) NewBmmData,\r
399 &BufferSize,\r
400 Progress\r
401 );\r
402 ASSERT_EFI_ERROR (Status);\r
403 //\r
404 // Compare new and old BMM configuration data and only do action for modified item to \r
405 // avoid setting unnecessary non-volatile variable\r
406 //\r
407\r
408 //\r
409 // Check data which located in BMM main page and save the settings if need\r
410 //\r
411 if (CompareMem (NewBmmData->LegacyFD, OldBmmData->LegacyFD, sizeof (NewBmmData->LegacyFD)) != 0) {\r
412 Var_UpdateBBSOption (Private, FORM_SET_FD_ORDER_ID);\r
413 }\r
414\r
415 if (CompareMem (NewBmmData->LegacyHD, OldBmmData->LegacyHD, sizeof (NewBmmData->LegacyHD)) != 0) {\r
416 Var_UpdateBBSOption (Private, FORM_SET_HD_ORDER_ID);\r
417 }\r
418\r
419 if (CompareMem (NewBmmData->LegacyCD, OldBmmData->LegacyCD, sizeof (NewBmmData->LegacyCD)) != 0) {\r
420 Var_UpdateBBSOption (Private, FORM_SET_CD_ORDER_ID);\r
421 }\r
422\r
423 if (CompareMem (NewBmmData->LegacyNET, OldBmmData->LegacyNET, sizeof (NewBmmData->LegacyNET)) != 0) {\r
424 Var_UpdateBBSOption (Private, FORM_SET_NET_ORDER_ID);\r
425 }\r
426\r
427 if (CompareMem (NewBmmData->LegacyBEV, OldBmmData->LegacyBEV, sizeof (NewBmmData->LegacyBEV)) != 0) {\r
428 Var_UpdateBBSOption (Private, FORM_SET_BEV_ORDER_ID);\r
429 }\r
430\r
431 //\r
432 // Check data which located in Boot Options Menu and save the settings if need\r
433 //\r
434 if (CompareMem (NewBmmData->BootOptionDel, OldBmmData->BootOptionDel, sizeof (NewBmmData->BootOptionDel)) != 0) { \r
435 for (Index = 0; \r
436 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->BootOptionDel) / sizeof (NewBmmData->BootOptionDel[0])))); \r
437 Index ++) {\r
438 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
439 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
440 NewLoadContext->Deleted = NewBmmData->BootOptionDel[Index];\r
441 }\r
442\r
443 Var_DelBootOption ();\r
444 }\r
445\r
446 //\r
447 // Check data which located in Driver Options Menu and save the settings if need\r
448 //\r
449 if (CompareMem (NewBmmData->DriverOptionDel, OldBmmData->DriverOptionDel, sizeof (NewBmmData->DriverOptionDel)) != 0) { \r
450 for (Index = 0; \r
451 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->DriverOptionDel) / sizeof (NewBmmData->DriverOptionDel[0])))); \r
452 Index++) {\r
453 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
454 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
455 NewLoadContext->Deleted = NewBmmData->DriverOptionDel[Index];\r
456 }\r
457 Var_DelDriverOption ();\r
458 }\r
459\r
460 if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) { \r
461 Status = Var_UpdateBootOrder (Private);\r
462 }\r
463\r
464 if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) { \r
465 Status = Var_UpdateDriverOrder (Private);\r
466 }\r
467\r
468 if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0) {\r
469 Status = gRT->SetVariable (\r
470 L"Timeout",\r
471 &gEfiGlobalVariableGuid,\r
472 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
473 sizeof (UINT16),\r
474 &(NewBmmData->BootTimeOut)\r
475 );\r
476 ASSERT_EFI_ERROR(Status);\r
477\r
478 //\r
479 // Bugbug: code not exit in UiApp but in IntelFrameworkModulePkg, need do more check.\r
480 //\r
481 Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut; \r
482 }\r
483\r
484 if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {\r
485 Status = Var_UpdateBootNext (Private);\r
486 }\r
487\r
488 if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0) { \r
489 Var_UpdateConMode (Private);\r
490 }\r
491\r
492 TerminalAttChange = FALSE;\r
493 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
494\r
495 //\r
496 // only need update modified items\r
497 //\r
498 if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) == 0 &&\r
499 CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) == 0 &&\r
500 CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) == 0 &&\r
501 CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) == 0 &&\r
502 CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) == 0 &&\r
503 CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) == 0) {\r
504 continue;\r
505 }\r
506\r
507 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
508 ASSERT (NewMenuEntry != NULL);\r
509 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
510 NewTerminalContext->BaudRateIndex = NewBmmData->COMBaudRate[Index];\r
511 ASSERT (NewBmmData->COMBaudRate[Index] < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));\r
512 NewTerminalContext->BaudRate = BaudRateList[NewBmmData->COMBaudRate[Index]].Value;\r
513 NewTerminalContext->DataBitsIndex = NewBmmData->COMDataRate[Index];\r
514 ASSERT (NewBmmData->COMDataRate[Index] < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));\r
515 NewTerminalContext->DataBits = (UINT8) DataBitsList[NewBmmData->COMDataRate[Index]].Value;\r
516 NewTerminalContext->StopBitsIndex = NewBmmData->COMStopBits[Index];\r
517 ASSERT (NewBmmData->COMStopBits[Index] < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));\r
518 NewTerminalContext->StopBits = (UINT8) StopBitsList[NewBmmData->COMStopBits[Index]].Value;\r
519 NewTerminalContext->ParityIndex = NewBmmData->COMParity[Index];\r
520 ASSERT (NewBmmData->COMParity[Index] < (sizeof (ParityList) / sizeof (ParityList[0])));\r
521 NewTerminalContext->Parity = (UINT8) ParityList[NewBmmData->COMParity[Index]].Value;\r
522 NewTerminalContext->TerminalType = NewBmmData->COMTerminalType[Index];\r
523 NewTerminalContext->FlowControl = NewBmmData->COMFlowControl[Index];\r
524 ChangeTerminalDevicePath (\r
525 &(NewTerminalContext->DevicePath),\r
526 FALSE\r
527 );\r
528 TerminalAttChange = TRUE;\r
529 }\r
530 if (TerminalAttChange) {\r
531 Var_UpdateConsoleInpOption ();\r
532 Var_UpdateConsoleOutOption ();\r
533 Var_UpdateErrorOutOption ();\r
534 }\r
535\r
536 //\r
537 // Check data which located in Console Options Menu and save the settings if need\r
538 //\r
539 if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, sizeof (NewBmmData->ConsoleInCheck)) != 0) {\r
540 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {\r
541 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);\r
542 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
543 ASSERT (Index < MAX_MENU_NUMBER);\r
544 NewConsoleContext->IsActive = NewBmmData->ConsoleInCheck[Index];\r
545 }\r
546\r
547 Var_UpdateConsoleInpOption ();\r
548 }\r
549\r
550 if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, sizeof (NewBmmData->ConsoleOutCheck)) != 0) {\r
551 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {\r
552 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);\r
553 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
554 ASSERT (Index < MAX_MENU_NUMBER);\r
555 NewConsoleContext->IsActive = NewBmmData->ConsoleOutCheck[Index];\r
556 }\r
557\r
558 Var_UpdateConsoleOutOption ();\r
559 }\r
560\r
561 if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, sizeof (NewBmmData->ConsoleErrCheck)) != 0) { \r
562 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {\r
563 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);\r
564 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
565 ASSERT (Index < MAX_MENU_NUMBER);\r
566 NewConsoleContext->IsActive = NewBmmData->ConsoleErrCheck[Index];\r
567 }\r
568\r
569 Var_UpdateErrorOutOption ();\r
570 }\r
571\r
572 //\r
573 // After user do the save action, need to update OldBmmData.\r
574 //\r
575 CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));\r
576\r
577 return EFI_SUCCESS;\r
578}\r
579\r
580/**\r
581 Create GoTo OP code into FORM_BOOT_LEGACY_DEVICE label for legacy boot option.\r
582\r
583**/\r
584EFI_STATUS\r
585InitializeLegacyBootOption (\r
586 VOID\r
587 )\r
588{\r
589 RefreshUpdateData ();\r
590 mStartLabel->Number = FORM_BOOT_LEGACY_DEVICE_ID;\r
591 \r
592 //\r
593 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option\r
594 // in BootOption form: legacy FD/HD/CD/NET/BEV\r
595 //\r
596 HiiCreateGotoOpCode (\r
597 mStartOpCodeHandle,\r
598 FORM_SET_FD_ORDER_ID,\r
599 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
600 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
601 EFI_IFR_FLAG_CALLBACK,\r
602 FORM_SET_FD_ORDER_ID\r
603 );\r
604\r
605 HiiCreateGotoOpCode (\r
606 mStartOpCodeHandle,\r
607 FORM_SET_HD_ORDER_ID,\r
608 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
609 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
610 EFI_IFR_FLAG_CALLBACK,\r
611 FORM_SET_HD_ORDER_ID\r
612 );\r
613\r
614 HiiCreateGotoOpCode (\r
615 mStartOpCodeHandle,\r
616 FORM_SET_CD_ORDER_ID,\r
617 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
618 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
619 EFI_IFR_FLAG_CALLBACK,\r
620 FORM_SET_CD_ORDER_ID\r
621 );\r
622\r
623 HiiCreateGotoOpCode (\r
624 mStartOpCodeHandle,\r
625 FORM_SET_NET_ORDER_ID,\r
626 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
627 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
628 EFI_IFR_FLAG_CALLBACK,\r
629 FORM_SET_NET_ORDER_ID\r
630 );\r
631\r
632 HiiCreateGotoOpCode (\r
633 mStartOpCodeHandle,\r
634 FORM_SET_BEV_ORDER_ID,\r
635 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
636 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
637 EFI_IFR_FLAG_CALLBACK,\r
638 FORM_SET_BEV_ORDER_ID\r
639 );\r
640 \r
641 HiiUpdateForm (\r
642 mBmmCallbackInfo->BmmHiiHandle,\r
643 &gBootMaintFormSetGuid,\r
644 FORM_BOOT_SETUP_ID,\r
645 mStartOpCodeHandle, // Label FORM_BOOT_LEGACY_DEVICE_ID\r
646 mEndOpCodeHandle // LABEL_END\r
647 );\r
648 \r
649 return EFI_SUCCESS;\r
650}\r
651\r
5c08e117 652/**\r
653 This function processes the results of changes in configuration.\r
654\r
655\r
656 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
657 @param Action Specifies the type of action taken by the browser.\r
658 @param QuestionId A unique value which is sent to the original exporting driver\r
659 so that it can identify the type of data to expect.\r
660 @param Type The type of value for the question.\r
661 @param Value A pointer to the data being sent to the original exporting driver.\r
662 @param ActionRequest On return, points to the action requested by the callback function.\r
663\r
664 @retval EFI_SUCCESS The callback successfully handled the action.\r
665 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
666 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
667 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
668 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.\r
669**/\r
670EFI_STATUS\r
671EFIAPI\r
672BootMaintCallback (\r
673 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
674 IN EFI_BROWSER_ACTION Action,\r
675 IN EFI_QUESTION_ID QuestionId,\r
676 IN UINT8 Type,\r
677 IN EFI_IFR_TYPE_VALUE *Value,\r
678 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
679 )\r
680{\r
681 BMM_CALLBACK_DATA *Private;\r
682 BM_MENU_ENTRY *NewMenuEntry;\r
683 BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
684 EFI_STATUS Status;\r
685 UINTN OldValue;\r
686 UINTN NewValue;\r
687 UINTN Number;\r
688 UINTN Pos;\r
689 UINTN Bit;\r
690 UINT16 NewValuePos;\r
98ba35a4 691 UINT16 Index3; \r
5c08e117 692 UINT16 Index2;\r
693 UINT16 Index;\r
694 UINT8 *OldLegacyDev;\r
695 UINT8 *NewLegacyDev;\r
696 UINT8 *DisMap;\r
be9304f3
ED
697 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
698\r
699 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
700 if (Action == EFI_BROWSER_ACTION_FORM_OPEN && QuestionId == FORM_BOOT_SETUP_ID) {\r
701 //\r
702 // Initilize Form for legacy boot option.\r
703 //\r
704 Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);\r
705 if (!EFI_ERROR (Status)) {\r
706 InitializeLegacyBootOption ();\r
707 }\r
708 \r
709 return EFI_SUCCESS;\r
710 }\r
d88f86f1 711\r
84724077
ED
712 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) { \r
713 //\r
714 // All other action return unsupported.\r
715 //\r
716 return EFI_UNSUPPORTED;\r
717 }\r
718 \r
719 Status = EFI_SUCCESS;\r
720 OldValue = 0;\r
721 NewValue = 0;\r
722 Number = 0;\r
723 OldLegacyDev = NULL;\r
724 NewLegacyDev = NULL;\r
725 NewValuePos = 0;\r
726 DisMap = NULL;\r
727\r
728 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
729 //\r
730 // Retrive uncommitted data from Form Browser\r
731 //\r
732 CurrentFakeNVMap = &Private->BmmFakeNvData;\r
733 HiiGetBrowserData (&gBootMaintFormSetGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);\r
d88f86f1 734 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
84724077 735 if (Value == NULL) {\r
d88f86f1
ED
736 return EFI_INVALID_PARAMETER;\r
737 }\r
84724077 738 \r
d88f86f1
ED
739 UpdatePageId (Private, QuestionId);\r
740\r
dc840773
ED
741 if (QuestionId < FILE_OPTION_OFFSET) {\r
742 if (QuestionId < CONFIG_OPTION_OFFSET) {\r
743 switch (QuestionId) {\r
744 case KEY_VALUE_BOOT_FROM_FILE:\r
745 Private->FeCurrentState = FileExplorerStateBootFromFile;\r
746 break;\r
747\r
748 case FORM_BOOT_ADD_ID:\r
749 Private->FeCurrentState = FileExplorerStateAddBootOption;\r
750 break;\r
751\r
752 case FORM_DRV_ADD_FILE_ID:\r
753 Private->FeCurrentState = FileExplorerStateAddDriverOptionState;\r
754 break;\r
755\r
756 case FORM_DRV_ADD_HANDLE_ID:\r
757 CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);\r
758 UpdateDrvAddHandlePage (Private);\r
759 break;\r
760\r
761 case FORM_BOOT_DEL_ID:\r
762 CleanUpPage (FORM_BOOT_DEL_ID, Private);\r
763 UpdateBootDelPage (Private);\r
764 break;\r
765\r
766 case FORM_BOOT_CHG_ID:\r
767 case FORM_DRV_CHG_ID:\r
768 UpdatePageBody (QuestionId, Private);\r
769 break;\r
770\r
771 case FORM_DRV_DEL_ID:\r
772 CleanUpPage (FORM_DRV_DEL_ID, Private);\r
773 UpdateDrvDelPage (Private);\r
774 break;\r
775\r
776 case FORM_BOOT_NEXT_ID:\r
777 CleanUpPage (FORM_BOOT_NEXT_ID, Private);\r
778 UpdateBootNextPage (Private);\r
779 break;\r
780\r
781 case FORM_TIME_OUT_ID:\r
782 CleanUpPage (FORM_TIME_OUT_ID, Private);\r
783 UpdateTimeOutPage (Private);\r
784 break;\r
785\r
786 case FORM_CON_IN_ID:\r
787 case FORM_CON_OUT_ID:\r
788 case FORM_CON_ERR_ID:\r
789 UpdatePageBody (QuestionId, Private);\r
790 break;\r
791\r
792 case FORM_CON_MODE_ID:\r
793 CleanUpPage (FORM_CON_MODE_ID, Private);\r
794 UpdateConModePage (Private);\r
795 break;\r
796\r
797 case FORM_CON_COM_ID:\r
798 CleanUpPage (FORM_CON_COM_ID, Private);\r
799 UpdateConCOMPage (Private);\r
800 break;\r
801\r
802 case FORM_SET_FD_ORDER_ID:\r
803 case FORM_SET_HD_ORDER_ID:\r
804 case FORM_SET_CD_ORDER_ID:\r
805 case FORM_SET_NET_ORDER_ID:\r
806 case FORM_SET_BEV_ORDER_ID:\r
807 CleanUpPage (QuestionId, Private);\r
808 UpdateSetLegacyDeviceOrderPage (QuestionId, Private);\r
809 break;\r
810\r
811 default:\r
812 break;\r
813 }\r
814 } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {\r
815 Index2 = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);\r
816 Private->CurrentTerminal = Index2;\r
817\r
818 CleanUpPage (FORM_CON_COM_SETUP_ID, Private);\r
819 UpdateTerminalPage (Private);\r
820\r
821 } else if (QuestionId >= HANDLE_OPTION_OFFSET) {\r
822 Index2 = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);\r
823\r
824 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index2);\r
825 ASSERT (NewMenuEntry != NULL);\r
826 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;\r
827\r
828 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);\r
829\r
830 Private->MenuEntry = NewMenuEntry;\r
831 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;\r
832\r
833 UpdateDriverAddHandleDescPage (Private);\r
834 }\r
835 }\r
836 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
837 if ((Value == NULL) || (ActionRequest == NULL)) {\r
838 return EFI_INVALID_PARAMETER;\r
839 }\r
840 \r
d88f86f1
ED
841 //\r
842 // need to be subtituded.\r
843 //\r
844 // Update Select FD/HD/CD/NET/BEV Order Form\r
845 //\r
98ba35a4 846 if ((QuestionId >= LEGACY_FD_QUESTION_ID) && (QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER)) {\r
d88f86f1
ED
847\r
848 DisMap = Private->BmmOldFakeNVData.DisableMap;\r
849\r
98ba35a4 850 if (QuestionId >= LEGACY_FD_QUESTION_ID && QuestionId < LEGACY_FD_QUESTION_ID + MAX_MENU_NUMBER) {\r
d88f86f1
ED
851 Number = (UINT16) LegacyFDMenu.MenuNumber;\r
852 OldLegacyDev = Private->BmmOldFakeNVData.LegacyFD;\r
853 NewLegacyDev = CurrentFakeNVMap->LegacyFD;\r
98ba35a4 854 } else if (QuestionId >= LEGACY_HD_QUESTION_ID && QuestionId < LEGACY_HD_QUESTION_ID + MAX_MENU_NUMBER) {\r
d88f86f1
ED
855 Number = (UINT16) LegacyHDMenu.MenuNumber;\r
856 OldLegacyDev = Private->BmmOldFakeNVData.LegacyHD;\r
857 NewLegacyDev = CurrentFakeNVMap->LegacyHD;\r
98ba35a4 858 } else if (QuestionId >= LEGACY_CD_QUESTION_ID && QuestionId < LEGACY_CD_QUESTION_ID + MAX_MENU_NUMBER) {\r
d88f86f1
ED
859 Number = (UINT16) LegacyCDMenu.MenuNumber;\r
860 OldLegacyDev = Private->BmmOldFakeNVData.LegacyCD;\r
861 NewLegacyDev = CurrentFakeNVMap->LegacyCD;\r
98ba35a4 862 } else if (QuestionId >= LEGACY_NET_QUESTION_ID && QuestionId < LEGACY_NET_QUESTION_ID + MAX_MENU_NUMBER) {\r
d88f86f1
ED
863 Number = (UINT16) LegacyNETMenu.MenuNumber;\r
864 OldLegacyDev = Private->BmmOldFakeNVData.LegacyNET;\r
865 NewLegacyDev = CurrentFakeNVMap->LegacyNET;\r
98ba35a4 866 } else if (QuestionId >= LEGACY_BEV_QUESTION_ID && QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER) {\r
d88f86f1
ED
867 Number = (UINT16) LegacyBEVMenu.MenuNumber;\r
868 OldLegacyDev = Private->BmmOldFakeNVData.LegacyBEV;\r
869 NewLegacyDev = CurrentFakeNVMap->LegacyBEV;\r
d88f86f1 870 }\r
5c08e117 871 //\r
d88f86f1
ED
872 // First, find the different position\r
873 // if there is change, it should be only one\r
5c08e117 874 //\r
d88f86f1
ED
875 for (Index = 0; Index < Number; Index++) {\r
876 if (OldLegacyDev[Index] != NewLegacyDev[Index]) {\r
877 OldValue = OldLegacyDev[Index];\r
878 NewValue = NewLegacyDev[Index];\r
879 break;\r
880 }\r
881 }\r
882\r
883 if (Index != Number) {\r
5c08e117 884 //\r
d88f86f1 885 // there is change, now process\r
5c08e117 886 //\r
d88f86f1
ED
887 if (0xFF == NewValue) {\r
888 //\r
889 // This item will be disable\r
890 // Just move the items behind this forward to overlap it\r
891 //\r
892 Pos = OldValue / 8;\r
893 Bit = 7 - (OldValue % 8);\r
894 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));\r
895 for (Index2 = Index; Index2 < Number - 1; Index2++) {\r
896 NewLegacyDev[Index2] = NewLegacyDev[Index2 + 1];\r
897 }\r
5c08e117 898\r
d88f86f1
ED
899 NewLegacyDev[Index2] = 0xFF;\r
900 } else {\r
901 for (Index2 = 0; Index2 < Number; Index2++) {\r
902 if (Index2 == Index) {\r
903 continue;\r
904 }\r
905\r
906 if (OldLegacyDev[Index2] == NewValue) {\r
907 //\r
908 // If NewValue is in OldLegacyDev array\r
909 // remember its old position\r
910 //\r
911 NewValuePos = Index2;\r
912 break;\r
913 }\r
5c08e117 914 }\r
915\r
d88f86f1 916 if (Index2 != Number) {\r
5c08e117 917 //\r
d88f86f1
ED
918 // We will change current item to an existing item\r
919 // (It's hard to describe here, please read code, it's like a cycle-moving)\r
5c08e117 920 //\r
d88f86f1
ED
921 for (Index2 = NewValuePos; Index2 != Index;) {\r
922 if (NewValuePos < Index) {\r
923 NewLegacyDev[Index2] = OldLegacyDev[Index2 + 1];\r
924 Index2++;\r
925 } else {\r
926 NewLegacyDev[Index2] = OldLegacyDev[Index2 - 1];\r
927 Index2--;\r
928 }\r
5c08e117 929 }\r
d88f86f1 930 } else {\r
5c08e117 931 //\r
d88f86f1
ED
932 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item\r
933 // so we should modify DisMap to reflect the change\r
5c08e117 934 //\r
d88f86f1
ED
935 Pos = NewValue / 8;\r
936 Bit = 7 - (NewValue % 8);\r
937 DisMap[Pos] = (UINT8) (DisMap[Pos] & (~ (UINT8) (1 << Bit)));\r
938 if (0xFF != OldValue) {\r
939 //\r
940 // Because NewValue is a item that was disabled before\r
941 // so after changing the OldValue should be disabled\r
942 // actually we are doing a swap of enable-disable states of two items\r
943 //\r
944 Pos = OldValue / 8;\r
945 Bit = 7 - (OldValue % 8);\r
946 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));\r
947 }\r
5c08e117 948 }\r
949 }\r
d88f86f1
ED
950 //\r
951 // To prevent DISABLE appears in the middle of the list\r
952 // we should perform a re-ordering\r
953 //\r
98ba35a4 954 Index3 = Index;\r
d88f86f1
ED
955 Index = 0;\r
956 while (Index < Number) {\r
957 if (0xFF != NewLegacyDev[Index]) {\r
958 Index++;\r
959 continue;\r
5c08e117 960 }\r
961\r
d88f86f1 962 Index2 = Index;\r
5c08e117 963 Index2++;\r
d88f86f1
ED
964 while (Index2 < Number) {\r
965 if (0xFF != NewLegacyDev[Index2]) {\r
966 break;\r
967 }\r
5c08e117 968\r
d88f86f1
ED
969 Index2++;\r
970 }\r
971\r
972 if (Index2 < Number) {\r
973 NewLegacyDev[Index] = NewLegacyDev[Index2];\r
974 NewLegacyDev[Index2] = 0xFF;\r
975 }\r
976\r
977 Index++;\r
5c08e117 978 }\r
979\r
d88f86f1
ED
980 CopyMem (\r
981 OldLegacyDev,\r
982 NewLegacyDev,\r
983 Number\r
984 );\r
98ba35a4
ED
985\r
986 //\r
987 // Return correct question value.\r
988 //\r
989 Value->u8 = NewLegacyDev[Index3];\r
5c08e117 990 }\r
dc840773
ED
991 } else {\r
992 switch (QuestionId) {\r
993 case KEY_VALUE_SAVE_AND_EXIT:\r
994 case KEY_VALUE_NO_SAVE_AND_EXIT:\r
995 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {\r
996 Status = ApplyChangeHandler (Private, CurrentFakeNVMap, Private->BmmPreviousPageId);\r
997 if (EFI_ERROR (Status)) {\r
998 return Status;\r
999 }\r
1000 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {\r
1001 DiscardChangeHandler (Private, CurrentFakeNVMap);\r
d88f86f1 1002 }\r
5c08e117 1003\r
dc840773
ED
1004 //\r
1005 // Tell browser not to ask for confirmation of changes,\r
1006 // since we have already applied or discarded.\r
1007 //\r
1008 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
1009 break; \r
5c08e117 1010\r
dc840773
ED
1011 case FORM_RESET:\r
1012 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
1013 return EFI_UNSUPPORTED;\r
5c08e117 1014\r
dc840773
ED
1015 default:\r
1016 break;\r
d88f86f1 1017 }\r
5c08e117 1018 }\r
1019 }\r
1020\r
1021 //\r
84724077 1022 // Pass changed uncommitted data back to Form Browser\r
5c08e117 1023 //\r
84724077
ED
1024 HiiSetBrowserData (&gBootMaintFormSetGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);\r
1025 return EFI_SUCCESS;\r
5c08e117 1026}\r
1027\r
1028/**\r
1029 Function handling request to apply changes for BMM pages.\r
1030\r
1031 @param Private Pointer to callback data buffer.\r
1032 @param CurrentFakeNVMap Pointer to buffer holding data of various values used by BMM\r
1033 @param FormId ID of the form which has sent the request to apply change.\r
1034\r
1035 @retval EFI_SUCCESS Change successfully applied.\r
1036 @retval Other Error occurs while trying to apply changes.\r
1037\r
1038**/\r
1039EFI_STATUS\r
1040ApplyChangeHandler (\r
1041 IN BMM_CALLBACK_DATA *Private,\r
1042 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap,\r
1043 IN EFI_FORM_ID FormId\r
1044 )\r
1045{\r
1046 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
1047 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
1048 BM_LOAD_CONTEXT *NewLoadContext;\r
1049 BM_MENU_ENTRY *NewMenuEntry;\r
1050 EFI_STATUS Status;\r
1051 UINT16 Index;\r
1052\r
1053 Status = EFI_SUCCESS;\r
1054\r
1055 switch (FormId) {\r
1056 case FORM_SET_FD_ORDER_ID:\r
1057 case FORM_SET_HD_ORDER_ID:\r
1058 case FORM_SET_CD_ORDER_ID:\r
1059 case FORM_SET_NET_ORDER_ID:\r
1060 case FORM_SET_BEV_ORDER_ID:\r
be9304f3 1061 Var_UpdateBBSOption (Private, FormId);\r
5c08e117 1062 break;\r
1063\r
1064 case FORM_BOOT_DEL_ID:\r
bd828c8e 1065 for (Index = 0; \r
be9304f3 1066 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])))); \r
bd828c8e 1067 Index ++) {\r
5c08e117 1068 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
1069 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
be9304f3 1070 NewLoadContext->Deleted = CurrentFakeNVMap->BootOptionDel[Index];\r
5c08e117 1071 }\r
1072\r
1073 Var_DelBootOption ();\r
1074 break;\r
1075\r
1076 case FORM_DRV_DEL_ID:\r
bd828c8e 1077 for (Index = 0; \r
be9304f3 1078 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])))); \r
bd828c8e 1079 Index++) {\r
5c08e117 1080 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
1081 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
be9304f3 1082 NewLoadContext->Deleted = CurrentFakeNVMap->DriverOptionDel[Index];\r
5c08e117 1083 }\r
1084\r
1085 Var_DelDriverOption ();\r
1086 break;\r
1087\r
1088 case FORM_BOOT_CHG_ID:\r
1089 Status = Var_UpdateBootOrder (Private);\r
1090 break;\r
1091\r
1092 case FORM_DRV_CHG_ID:\r
1093 Status = Var_UpdateDriverOrder (Private);\r
1094 break;\r
1095\r
1096 case FORM_TIME_OUT_ID:\r
69fc8f08
RN
1097 BdsDxeSetVariableAndReportStatusCodeOnError (\r
1098 L"Timeout",\r
1099 &gEfiGlobalVariableGuid,\r
1100 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
1101 sizeof (UINT16),\r
1102 &(CurrentFakeNVMap->BootTimeOut)\r
1103 );\r
5c08e117 1104\r
1105 Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;\r
1106 break;\r
1107\r
1108 case FORM_BOOT_NEXT_ID:\r
1109 Status = Var_UpdateBootNext (Private);\r
1110 break;\r
1111\r
1112 case FORM_CON_MODE_ID:\r
1113 Status = Var_UpdateConMode (Private);\r
1114 break;\r
1115\r
1116 case FORM_CON_COM_SETUP_ID:\r
be9304f3
ED
1117 Index = (UINT16)Private->CurrentTerminal;\r
1118 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
5c08e117 1119\r
1120 ASSERT (NewMenuEntry != NULL);\r
1121\r
1122 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
1123\r
be9304f3
ED
1124 NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate[Index];\r
1125 ASSERT (CurrentFakeNVMap->COMBaudRate[Index] < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));\r
1126 NewTerminalContext->BaudRate = BaudRateList[CurrentFakeNVMap->COMBaudRate[Index]].Value;\r
1127 NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate[Index];\r
1128 ASSERT (CurrentFakeNVMap->COMDataRate[Index] < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));\r
1129 NewTerminalContext->DataBits = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate[Index]].Value;\r
1130 NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits[Index];\r
1131 ASSERT (CurrentFakeNVMap->COMStopBits[Index] < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));\r
1132 NewTerminalContext->StopBits = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits[Index]].Value;\r
1133 NewTerminalContext->ParityIndex = CurrentFakeNVMap->COMParity[Index];\r
1134 ASSERT (CurrentFakeNVMap->COMParity[Index] < (sizeof (ParityList) / sizeof (ParityList[0])));\r
1135 NewTerminalContext->Parity = (UINT8) ParityList[CurrentFakeNVMap->COMParity[Index]].Value;\r
1136 NewTerminalContext->TerminalType = CurrentFakeNVMap->COMTerminalType[Index];\r
1137 NewTerminalContext->FlowControl = CurrentFakeNVMap->COMFlowControl[Index];\r
5c08e117 1138\r
1139 ChangeTerminalDevicePath (\r
8e491a81 1140 &(NewTerminalContext->DevicePath),\r
5c08e117 1141 FALSE\r
1142 );\r
1143\r
1144 Var_UpdateConsoleInpOption ();\r
1145 Var_UpdateConsoleOutOption ();\r
1146 Var_UpdateErrorOutOption ();\r
1147 break;\r
1148\r
1149 case FORM_CON_IN_ID:\r
b7b0dca2 1150 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {\r
5c08e117 1151 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);\r
1152 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
b452ca89 1153 ASSERT (Index < MAX_MENU_NUMBER);\r
be9304f3 1154 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleInCheck[Index];\r
5c08e117 1155 }\r
1156\r
b7b0dca2 1157 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
5c08e117 1158 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
1159 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
b452ca89 1160 ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);\r
be9304f3 1161 NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleInCheck[Index + ConsoleInpMenu.MenuNumber];\r
5c08e117 1162 }\r
1163\r
1164 Var_UpdateConsoleInpOption ();\r
1165 break;\r
1166\r
1167 case FORM_CON_OUT_ID:\r
b7b0dca2 1168 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {\r
5c08e117 1169 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);\r
1170 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
b452ca89 1171 ASSERT (Index < MAX_MENU_NUMBER);\r
be9304f3 1172 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleOutCheck[Index];\r
5c08e117 1173 }\r
1174\r
b7b0dca2 1175 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
5c08e117 1176 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
1177 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
b452ca89 1178 ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);\r
be9304f3 1179 NewTerminalContext->IsConOut = CurrentFakeNVMap->ConsoleOutCheck[Index + ConsoleOutMenu.MenuNumber];\r
5c08e117 1180 }\r
1181\r
1182 Var_UpdateConsoleOutOption ();\r
1183 break;\r
1184\r
1185 case FORM_CON_ERR_ID:\r
b7b0dca2 1186 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {\r
5c08e117 1187 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);\r
1188 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
b452ca89 1189 ASSERT (Index < MAX_MENU_NUMBER);\r
be9304f3 1190 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleErrCheck[Index];\r
5c08e117 1191 }\r
1192\r
b7b0dca2 1193 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
5c08e117 1194 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
1195 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
b452ca89 1196 ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);\r
be9304f3 1197 NewTerminalContext->IsStdErr = CurrentFakeNVMap->ConsoleErrCheck[Index + ConsoleErrMenu.MenuNumber];\r
5c08e117 1198 }\r
1199\r
1200 Var_UpdateErrorOutOption ();\r
1201 break;\r
1202\r
1203 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
1204 Status = Var_UpdateDriverOption (\r
1205 Private,\r
1206 Private->BmmHiiHandle,\r
1207 CurrentFakeNVMap->DriverAddHandleDesc,\r
1208 CurrentFakeNVMap->DriverAddHandleOptionalData,\r
1209 CurrentFakeNVMap->DriverAddForceReconnect\r
1210 );\r
1211 if (EFI_ERROR (Status)) {\r
1212 goto Error;\r
1213 }\r
1214\r
1215 BOpt_GetDriverOptions (Private);\r
1216 CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);\r
1217 break;\r
1218\r
1219 default:\r
1220 break;\r
1221 }\r
1222\r
1223Error:\r
1224 return Status;\r
1225}\r
1226\r
1227/**\r
1228 Discard all changes done to the BMM pages such as Boot Order change,\r
1229 Driver order change.\r
1230\r
1231 @param Private The BMM context data.\r
1232 @param CurrentFakeNVMap The current Fack NV Map.\r
1233\r
1234**/\r
1235VOID\r
1236DiscardChangeHandler (\r
1237 IN BMM_CALLBACK_DATA *Private,\r
1238 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap\r
1239 )\r
1240{\r
1241 UINT16 Index;\r
1242\r
1243 switch (Private->BmmPreviousPageId) {\r
1244 case FORM_BOOT_CHG_ID:\r
be9304f3
ED
1245 CopyMem (CurrentFakeNVMap->BootOptionOrder, Private->BmmOldFakeNVData.BootOptionOrder, sizeof (CurrentFakeNVMap->BootOptionOrder));\r
1246 break;\r
1247\r
5c08e117 1248 case FORM_DRV_CHG_ID:\r
be9304f3 1249 CopyMem (CurrentFakeNVMap->DriverOptionOrder, Private->BmmOldFakeNVData.DriverOptionOrder, sizeof (CurrentFakeNVMap->DriverOptionOrder));\r
5c08e117 1250 break;\r
1251\r
1252 case FORM_BOOT_DEL_ID:\r
be9304f3 1253 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));\r
5c08e117 1254 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
be9304f3 1255 CurrentFakeNVMap->BootOptionDel[Index] = FALSE;\r
5c08e117 1256 }\r
1257 break;\r
1258\r
1259 case FORM_DRV_DEL_ID:\r
be9304f3 1260 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));\r
5c08e117 1261 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
be9304f3 1262 CurrentFakeNVMap->DriverOptionDel[Index] = FALSE;\r
5c08e117 1263 }\r
1264 break;\r
1265\r
1266 case FORM_BOOT_NEXT_ID:\r
1267 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;\r
1268 break;\r
1269\r
1270 case FORM_TIME_OUT_ID:\r
1271 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;\r
1272 break;\r
1273\r
1274 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
1275 case FORM_DRV_ADD_FILE_ID:\r
1276 case FORM_DRV_ADD_HANDLE_ID:\r
1277 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;\r
1278 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;\r
1279 break;\r
1280\r
1281 default:\r
1282 break;\r
1283 }\r
1284}\r
1285\r
1286/**\r
1287 Initialize the Boot Maintenance Utitliy.\r
1288\r
1289\r
1290 @retval EFI_SUCCESS utility ended successfully\r
1291 @retval others contain some errors\r
1292\r
1293**/\r
1294EFI_STATUS\r
1295InitializeBM (\r
1296 VOID\r
1297 )\r
1298{\r
5c08e117 1299 BMM_CALLBACK_DATA *BmmCallbackInfo;\r
1300 EFI_STATUS Status;\r
be9304f3
ED
1301 EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
1302 UINT32 Length;\r
1303 UINT8 *Data;\r
5c08e117 1304\r
1305 Status = EFI_SUCCESS;\r
be9304f3
ED
1306 BmmCallbackInfo = mBmmCallbackInfo; \r
1307\r
1308 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;\r
1309 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;\r
1310 BmmCallbackInfo->FeCurrentState = FileExplorerStateInActive;\r
1311 BmmCallbackInfo->FeDisplayContext = FileExplorerDisplayUnknown;\r
5c08e117 1312\r
1313 //\r
be9304f3 1314 // Reinstall String packages to include more new strings.\r
5c08e117 1315 //\r
be9304f3 1316 \r
5c08e117 1317 //\r
be9304f3 1318 // String package size\r
5c08e117 1319 //\r
be9304f3 1320 Length = ReadUnaligned32 ((UINT32 *) BdsDxeStrings) - sizeof (UINT32);\r
5c08e117 1321\r
1322 //\r
be9304f3 1323 // Add the length of the Package List Header and the terminating Package Header \r
5c08e117 1324 //\r
be9304f3
ED
1325 Length += sizeof (EFI_HII_PACKAGE_LIST_HEADER) + sizeof (EFI_HII_PACKAGE_HEADER);\r
1326 \r
1327 //\r
1328 // Allocate the storage for the entire Package List\r
1329 //\r
1330 PackageListHeader = AllocateZeroPool (Length);\r
5c08e117 1331\r
1332 //\r
be9304f3 1333 // If the Package List can not be allocated, then return a NULL HII Handle\r
5c08e117 1334 //\r
be9304f3
ED
1335 if (PackageListHeader == NULL) {\r
1336 return EFI_OUT_OF_RESOURCES;\r
5c08e117 1337 }\r
1338\r
1339 //\r
be9304f3 1340 // Fill in the GUID and Length of the Package List Header\r
5c08e117 1341 //\r
be9304f3 1342 PackageListHeader->PackageLength = Length;\r
5c08e117 1343\r
1344 //\r
be9304f3 1345 // Copy String Data into Package list. \r
5c08e117 1346 //\r
be9304f3
ED
1347 Data = (UINT8 *)(PackageListHeader + 1);\r
1348 Length = ReadUnaligned32 ((UINT32 *) BdsDxeStrings) - sizeof (UINT32);\r
1349 CopyMem (Data, (UINT8 *) BdsDxeStrings + sizeof (UINT32), Length);\r
1350 \r
1351 //\r
1352 // Add End type HII package.\r
1353 //\r
1354 Data += Length;\r
1355 ((EFI_HII_PACKAGE_HEADER *) Data)->Type = EFI_HII_PACKAGE_END;\r
1356 ((EFI_HII_PACKAGE_HEADER *) Data)->Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
5c08e117 1357\r
1358 //\r
be9304f3 1359 // Update String package for BM\r
5c08e117 1360 //\r
be9304f3
ED
1361 CopyGuid (&PackageListHeader->PackageListGuid, &gBootMaintFormSetGuid);\r
1362 Status = gHiiDatabase->UpdatePackageList (gHiiDatabase, BmmCallbackInfo->BmmHiiHandle, PackageListHeader);\r
1363 \r
1364 //\r
1365 // Update String package for FE.\r
1366 //\r
1367 CopyGuid (&PackageListHeader->PackageListGuid, &gFileExploreFormSetGuid);\r
1368 Status = gHiiDatabase->UpdatePackageList (gHiiDatabase, BmmCallbackInfo->FeHiiHandle, PackageListHeader);\r
1369 \r
1370 FreePool (PackageListHeader);\r
5c08e117 1371\r
1372 //\r
75bf9d0e 1373 // Init OpCode Handle and Allocate space for creation of Buffer\r
5c08e117 1374 //\r
75bf9d0e
LG
1375 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1376 if (mStartOpCodeHandle == NULL) {\r
4376a6f2 1377 Status = EFI_OUT_OF_RESOURCES;\r
1378 goto Exit;\r
5c08e117 1379 }\r
1380\r
75bf9d0e
LG
1381 mEndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1382 if (mEndOpCodeHandle == NULL) {\r
1383 Status = EFI_OUT_OF_RESOURCES;\r
1384 goto Exit;\r
1385 }\r
1386\r
1387 //\r
1388 // Create Hii Extend Label OpCode as the start opcode\r
1389 //\r
1390 mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1391 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1392\r
1393 //\r
1394 // Create Hii Extend Label OpCode as the end opcode\r
1395 //\r
1396 mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mEndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1397 mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1398 mEndLabel->Number = LABEL_END;\r
1399\r
5c08e117 1400 InitializeStringDepository ();\r
1401\r
1402 InitAllMenu (BmmCallbackInfo);\r
1403\r
1404 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);\r
1405 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);\r
1406 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);\r
1407 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);\r
1408 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);\r
1409 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);\r
1410 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);\r
be9304f3
ED
1411 \r
1412 InitializeBmmConfig (BmmCallbackInfo);\r
5c08e117 1413\r
1414 //\r
1415 // Dispatch BMM main formset and File Explorer formset.\r
1416 //\r
1417 FormSetDispatcher (BmmCallbackInfo);\r
1418\r
1419 //\r
be9304f3 1420 // Clean up.\r
5c08e117 1421 //\r
5c08e117 1422 CleanUpStringDepository ();\r
be9304f3 1423 \r
5c08e117 1424 FreeAllMenu ();\r
1425\r
4376a6f2 1426Exit:\r
75bf9d0e
LG
1427 if (mStartOpCodeHandle != NULL) {\r
1428 HiiFreeOpCodeHandle (mStartOpCodeHandle);\r
1429 }\r
1430\r
1431 if (mEndOpCodeHandle != NULL) {\r
1432 HiiFreeOpCodeHandle (mEndOpCodeHandle);\r
1433 }\r
1434\r
5c08e117 1435 return Status;\r
1436}\r
1437\r
be9304f3 1438\r
5c08e117 1439/**\r
1440 Initialized all Menu Option List.\r
1441\r
1442 @param CallbackData The BMM context data.\r
1443\r
1444**/\r
1445VOID\r
1446InitAllMenu (\r
1447 IN BMM_CALLBACK_DATA *CallbackData\r
1448 )\r
1449{\r
1450 InitializeListHead (&BootOptionMenu.Head);\r
1451 InitializeListHead (&DriverOptionMenu.Head);\r
1452 BOpt_GetBootOptions (CallbackData);\r
1453 BOpt_GetDriverOptions (CallbackData);\r
1454 BOpt_GetLegacyOptions ();\r
1455 InitializeListHead (&FsOptionMenu.Head);\r
1456 BOpt_FindDrivers ();\r
1457 InitializeListHead (&DirectoryMenu.Head);\r
1458 InitializeListHead (&ConsoleInpMenu.Head);\r
1459 InitializeListHead (&ConsoleOutMenu.Head);\r
1460 InitializeListHead (&ConsoleErrMenu.Head);\r
1461 InitializeListHead (&TerminalMenu.Head);\r
1462 LocateSerialIo ();\r
1463 GetAllConsoles ();\r
1464}\r
1465\r
1466/**\r
1467 Free up all Menu Option list.\r
1468\r
1469**/\r
1470VOID\r
1471FreeAllMenu (\r
1472 VOID\r
1473 )\r
1474{\r
1475 BOpt_FreeMenu (&DirectoryMenu);\r
1476 BOpt_FreeMenu (&FsOptionMenu);\r
1477 BOpt_FreeMenu (&BootOptionMenu);\r
1478 BOpt_FreeMenu (&DriverOptionMenu);\r
1479 BOpt_FreeMenu (&DriverMenu);\r
1480 BOpt_FreeLegacyOptions ();\r
1481 FreeAllConsoles ();\r
1482}\r
1483\r
1484/**\r
baf46e70 1485 Initialize all the string depositories.\r
5c08e117 1486\r
1487**/\r
1488VOID\r
1489InitializeStringDepository (\r
1490 VOID\r
1491 )\r
1492{\r
1493 STRING_DEPOSITORY *StringDepository;\r
1494 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);\r
1495 FileOptionStrDepository = StringDepository++;\r
1496 ConsoleOptionStrDepository = StringDepository++;\r
1497 BootOptionStrDepository = StringDepository++;\r
1498 BootOptionHelpStrDepository = StringDepository++;\r
1499 DriverOptionStrDepository = StringDepository++;\r
1500 DriverOptionHelpStrDepository = StringDepository++;\r
1501 TerminalStrDepository = StringDepository;\r
1502}\r
1503\r
1504/**\r
1505 Fetch a usable string node from the string depository and return the string token.\r
1506\r
1507 @param CallbackData The BMM context data.\r
1508 @param StringDepository The string repository.\r
1509\r
1510 @retval EFI_STRING_ID String token.\r
1511\r
1512**/\r
1513EFI_STRING_ID\r
1514GetStringTokenFromDepository (\r
1515 IN BMM_CALLBACK_DATA *CallbackData,\r
1516 IN STRING_DEPOSITORY *StringDepository\r
1517 )\r
1518{\r
1519 STRING_LIST_NODE *CurrentListNode;\r
1520 STRING_LIST_NODE *NextListNode;\r
1521\r
1522 CurrentListNode = StringDepository->CurrentNode;\r
1523\r
1524 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {\r
1525 //\r
1526 // Fetch one reclaimed node from the list.\r
1527 //\r
1528 NextListNode = StringDepository->CurrentNode->Next;\r
1529 } else {\r
1530 //\r
1531 // If there is no usable node in the list, update the list.\r
1532 //\r
1533 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));\r
1534 ASSERT (NextListNode != NULL);\r
cb7d01c0 1535 NextListNode->StringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, L" ", NULL);\r
5c08e117 1536 ASSERT (NextListNode->StringToken != 0);\r
1537\r
1538 StringDepository->TotalNodeNumber++;\r
1539\r
1540 if (NULL == CurrentListNode) {\r
1541 StringDepository->ListHead = NextListNode;\r
1542 } else {\r
1543 CurrentListNode->Next = NextListNode;\r
1544 }\r
1545 }\r
1546\r
1547 StringDepository->CurrentNode = NextListNode;\r
1548\r
1549 return StringDepository->CurrentNode->StringToken;\r
1550}\r
1551\r
1552/**\r
1553 Reclaim string depositories by moving the current node pointer to list head..\r
1554\r
1555**/\r
1556VOID\r
1557ReclaimStringDepository (\r
1558 VOID\r
1559 )\r
1560{\r
1561 UINTN DepositoryIndex;\r
1562 STRING_DEPOSITORY *StringDepository;\r
1563\r
1564 StringDepository = FileOptionStrDepository;\r
1565 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1566 StringDepository->CurrentNode = StringDepository->ListHead;\r
1567 StringDepository++;\r
1568 }\r
1569}\r
1570\r
1571/**\r
1572 Release resource for all the string depositories.\r
1573\r
1574**/\r
1575VOID\r
1576CleanUpStringDepository (\r
1577 VOID\r
1578 )\r
1579{\r
1580 UINTN NodeIndex;\r
1581 UINTN DepositoryIndex;\r
1582 STRING_LIST_NODE *CurrentListNode;\r
1583 STRING_LIST_NODE *NextListNode;\r
1584 STRING_DEPOSITORY *StringDepository;\r
1585\r
1586 //\r
1587 // Release string list nodes.\r
1588 //\r
1589 StringDepository = FileOptionStrDepository;\r
1590 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1591 CurrentListNode = StringDepository->ListHead;\r
1592 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {\r
1593 NextListNode = CurrentListNode->Next;\r
1594 FreePool (CurrentListNode);\r
1595 CurrentListNode = NextListNode;\r
1596 }\r
1597\r
1598 StringDepository++;\r
1599 }\r
1600 //\r
1601 // Release string depository.\r
1602 //\r
1603 FreePool (FileOptionStrDepository);\r
1604}\r
1605\r
1606/**\r
1607 Start boot maintenance manager\r
1608\r
1609 @retval EFI_SUCCESS If BMM is invoked successfully.\r
1610 @return Other value if BMM return unsuccessfully.\r
1611\r
1612**/\r
1613EFI_STATUS\r
1614BdsStartBootMaint (\r
1615 VOID\r
1616 )\r
1617{\r
1618 EFI_STATUS Status;\r
1619 LIST_ENTRY BdsBootOptionList;\r
1620\r
1621 InitializeListHead (&BdsBootOptionList);\r
1622\r
1623 //\r
1624 // Connect all prior to entering the platform setup menu.\r
1625 //\r
1626 if (!gConnectAllHappened) {\r
1627 BdsLibConnectAllDriversToAllControllers ();\r
1628 gConnectAllHappened = TRUE;\r
1629 }\r
1630 //\r
1631 // Have chance to enumerate boot device\r
1632 //\r
1633 BdsLibEnumerateAllBootOption (&BdsBootOptionList);\r
1634\r
16e5944a
RN
1635 //\r
1636 // Group the legacy boot options for the same device type\r
1637 //\r
1638 GroupMultipleLegacyBootOption4SameType ();\r
1639\r
5c08e117 1640 //\r
1641 // Init the BMM\r
1642 //\r
1643 Status = InitializeBM ();\r
1644\r
1645 return Status;\r
1646}\r
1647\r
1648/**\r
1649 Dispatch BMM formset and FileExplorer formset.\r
1650\r
1651\r
1652 @param CallbackData The BMM context data.\r
1653\r
1654 @retval EFI_SUCCESS If function complete successfully.\r
1655 @return Other value if the Setup Browser process BMM's pages and\r
1656 return unsuccessfully.\r
1657\r
1658**/\r
1659EFI_STATUS\r
1660FormSetDispatcher (\r
1661 IN BMM_CALLBACK_DATA *CallbackData\r
1662 )\r
1663{\r
1664 EFI_STATUS Status;\r
1665 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
1666\r
1667 while (TRUE) {\r
1668 UpdatePageId (CallbackData, FORM_MAIN_ID);\r
1669\r
1670 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
1671 Status = gFormBrowser2->SendForm (\r
1672 gFormBrowser2,\r
1673 &CallbackData->BmmHiiHandle,\r
1674 1,\r
e24fc103 1675 &gBootMaintFormSetGuid,\r
5c08e117 1676 0,\r
1677 NULL,\r
1678 &ActionRequest\r
1679 );\r
1680 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
1681 EnableResetRequired ();\r
1682 }\r
1683\r
1684 ReclaimStringDepository ();\r
1685\r
1686 //\r
1687 // When this Formset returns, check if we are going to explore files.\r
1688 //\r
13078b3f 1689 if (FileExplorerStateInActive != CallbackData->FeCurrentState) {\r
5c08e117 1690 UpdateFileExplorer (CallbackData, 0);\r
1691\r
1692 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
1693 Status = gFormBrowser2->SendForm (\r
1694 gFormBrowser2,\r
1695 &CallbackData->FeHiiHandle,\r
1696 1,\r
e24fc103 1697 &gFileExploreFormSetGuid,\r
5c08e117 1698 0,\r
1699 NULL,\r
1700 &ActionRequest\r
1701 );\r
1702 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
1703 EnableResetRequired ();\r
1704 }\r
1705\r
13078b3f 1706 CallbackData->FeCurrentState = FileExplorerStateInActive;\r
1707 CallbackData->FeDisplayContext = FileExplorerDisplayUnknown;\r
5c08e117 1708 ReclaimStringDepository ();\r
1709 } else {\r
1710 break;\r
1711 }\r
1712 }\r
1713\r
1714 return Status;\r
1715}\r
1716\r
be9304f3
ED
1717/**\r
1718 Intall BootMaint and FileExplorer HiiPackages.\r
1719\r
1720**/\r
1721EFI_STATUS\r
1722InitBMPackage (\r
1723 VOID\r
1724 )\r
1725{\r
1726 BMM_CALLBACK_DATA *BmmCallbackInfo;\r
1727 EFI_STATUS Status;\r
1728 UINT8 *Ptr;\r
1729 \r
1730 //\r
1731 // Create CallbackData structures for Driver Callback\r
1732 //\r
1733 BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));\r
1734 if (BmmCallbackInfo == NULL) {\r
1735 return EFI_OUT_OF_RESOURCES;\r
1736 }\r
1737 \r
1738 //\r
1739 // Create LoadOption in BmmCallbackInfo for Driver Callback\r
1740 //\r
1741 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));\r
1742 if (Ptr == NULL) {\r
1743 FreePool (BmmCallbackInfo);\r
1744 BmmCallbackInfo = NULL;\r
1745 return EFI_OUT_OF_RESOURCES;\r
1746 }\r
1747 //\r
1748 // Initialize Bmm callback data.\r
1749 //\r
1750 BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;\r
1751 Ptr += sizeof (BM_LOAD_CONTEXT);\r
1752\r
1753 BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;\r
1754 Ptr += sizeof (BM_FILE_CONTEXT);\r
1755\r
1756 BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;\r
1757 Ptr += sizeof (BM_HANDLE_CONTEXT);\r
1758\r
1759 BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;\r
1760\r
1761 BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;\r
1762 BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;\r
1763 BmmCallbackInfo->BmmConfigAccess.RouteConfig = BootMaintRouteConfig;\r
1764 BmmCallbackInfo->BmmConfigAccess.Callback = BootMaintCallback;\r
1765 BmmCallbackInfo->FeConfigAccess.ExtractConfig = FakeExtractConfig;\r
1766 BmmCallbackInfo->FeConfigAccess.RouteConfig = FileExplorerRouteConfig;\r
1767 BmmCallbackInfo->FeConfigAccess.Callback = FileExplorerCallback;\r
1768\r
1769 //\r
1770 // Install Device Path Protocol and Config Access protocol to driver handle\r
1771 //\r
1772 Status = gBS->InstallMultipleProtocolInterfaces (\r
1773 &BmmCallbackInfo->BmmDriverHandle,\r
1774 &gEfiDevicePathProtocolGuid,\r
1775 &mBmmHiiVendorDevicePath,\r
1776 &gEfiHiiConfigAccessProtocolGuid,\r
1777 &BmmCallbackInfo->BmmConfigAccess,\r
1778 NULL\r
1779 );\r
1780 ASSERT_EFI_ERROR (Status);\r
1781\r
1782 //\r
1783 // Install Device Path Protocol and Config Access protocol to driver handle\r
1784 //\r
1785 Status = gBS->InstallMultipleProtocolInterfaces (\r
1786 &BmmCallbackInfo->FeDriverHandle,\r
1787 &gEfiDevicePathProtocolGuid,\r
1788 &mFeHiiVendorDevicePath,\r
1789 &gEfiHiiConfigAccessProtocolGuid,\r
1790 &BmmCallbackInfo->FeConfigAccess,\r
1791 NULL\r
1792 );\r
1793 ASSERT_EFI_ERROR (Status);\r
1794\r
1795 //\r
1796 // Post our Boot Maint VFR binary to the HII database.\r
1797 //\r
1798 BmmCallbackInfo->BmmHiiHandle = HiiAddPackages (\r
1799 &gBootMaintFormSetGuid,\r
1800 BmmCallbackInfo->BmmDriverHandle,\r
1801 BmBin,\r
1802 BdsDxeStrings,\r
1803 NULL\r
1804 );\r
1805 ASSERT (BmmCallbackInfo->BmmHiiHandle != NULL);\r
1806\r
1807 //\r
1808 // Post our File Explorer VFR binary to the HII database.\r
1809 //\r
1810 BmmCallbackInfo->FeHiiHandle = HiiAddPackages (\r
1811 &gFileExploreFormSetGuid,\r
1812 BmmCallbackInfo->FeDriverHandle,\r
1813 FEBin,\r
1814 BdsDxeStrings,\r
1815 NULL\r
1816 );\r
1817 ASSERT (BmmCallbackInfo->FeHiiHandle != NULL);\r
1818 \r
1819 mBmmCallbackInfo = BmmCallbackInfo;\r
1820 \r
1821 return EFI_SUCCESS; \r
1822}\r
1823\r
1824/**\r
1825 Remvoe the intalled BootMaint and FileExplorer HiiPackages.\r
1826\r
1827**/\r
1828VOID\r
1829FreeBMPackage (\r
1830 VOID\r
1831 )\r
1832{\r
1833 BMM_CALLBACK_DATA *BmmCallbackInfo;\r
1834\r
1835 BmmCallbackInfo = mBmmCallbackInfo;\r
1836\r
1837 //\r
1838 // Remove our IFR data from HII database\r
1839 //\r
1840 HiiRemovePackages (BmmCallbackInfo->BmmHiiHandle);\r
1841 HiiRemovePackages (BmmCallbackInfo->FeHiiHandle);\r
1842\r
1843 if (BmmCallbackInfo->FeDriverHandle != NULL) {\r
1844 gBS->UninstallMultipleProtocolInterfaces (\r
1845 BmmCallbackInfo->FeDriverHandle,\r
1846 &gEfiDevicePathProtocolGuid,\r
1847 &mFeHiiVendorDevicePath,\r
1848 &gEfiHiiConfigAccessProtocolGuid,\r
1849 &BmmCallbackInfo->FeConfigAccess,\r
1850 NULL\r
1851 );\r
1852 }\r
1853\r
1854 if (BmmCallbackInfo->BmmDriverHandle != NULL) {\r
1855 gBS->UninstallMultipleProtocolInterfaces (\r
1856 BmmCallbackInfo->BmmDriverHandle,\r
1857 &gEfiDevicePathProtocolGuid,\r
1858 &mBmmHiiVendorDevicePath,\r
1859 &gEfiHiiConfigAccessProtocolGuid,\r
1860 &BmmCallbackInfo->BmmConfigAccess,\r
1861 NULL\r
1862 );\r
1863 }\r
1864\r
1865 FreePool (BmmCallbackInfo->LoadContext);\r
1866 FreePool (BmmCallbackInfo);\r
1867\r
1868 mBmmCallbackInfo = NULL; \r
1869 \r
1870 return;\r
1871}\r
1872\r