]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Application/UiApp/BootMaint/BootMaint.c
UiApp code split from IntelFrameworkModulePkg/Universal/BdsDxe driver.
[mirror_edk2.git] / MdeModulePkg / Application / UiApp / BootMaint / BootMaint.c
CommitLineData
143f0b1d
ED
1/** @file\r
2 The functions for Boot Maintainence Main menu.\r
3\r
4Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
5This 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 "BootMaint.h"\r
16\r
17EFI_DEVICE_PATH_PROTOCOL EndDevicePath[] = {\r
18 {\r
19 END_DEVICE_PATH_TYPE,\r
20 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
21 {\r
22 END_DEVICE_PATH_LENGTH,\r
23 0\r
24 }\r
25 }\r
26};\r
27\r
28HII_VENDOR_DEVICE_PATH mBmmHiiVendorDevicePath = {\r
29 {\r
30 {\r
31 HARDWARE_DEVICE_PATH,\r
32 HW_VENDOR_DP,\r
33 {\r
34 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
35 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
36 }\r
37 },\r
38 //\r
39 // {165A028F-0BB2-4b5f-8747-77592E3F6499}\r
40 //\r
41 { 0x165a028f, 0xbb2, 0x4b5f, { 0x87, 0x47, 0x77, 0x59, 0x2e, 0x3f, 0x64, 0x99 } }\r
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
63 //\r
64 // {91DB4238-B0C8-472e-BBCF-F3A6541010F4}\r
65 //\r
66 { 0x91db4238, 0xb0c8, 0x472e, { 0xbb, 0xcf, 0xf3, 0xa6, 0x54, 0x10, 0x10, 0xf4 } }\r
67 },\r
68 {\r
69 END_DEVICE_PATH_TYPE,\r
70 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
71 { \r
72 (UINT8) (END_DEVICE_PATH_LENGTH),\r
73 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
74 }\r
75 }\r
76};\r
77\r
78EFI_GUID mBootMaintGuid = BOOT_MAINT_FORMSET_GUID;\r
79EFI_GUID mFileExplorerGuid = FILE_EXPLORE_FORMSET_GUID;\r
80\r
81CHAR16 mBootMaintStorageName[] = L"BmmData";\r
82CHAR16 mFileExplorerStorageName[] = L"FeData";\r
83BMM_CALLBACK_DATA *mBmmCallbackInfo = NULL;\r
84BOOLEAN mAllMenuInit = FALSE;\r
85BOOLEAN mEnterFileExplorer = FALSE;\r
86\r
87/**\r
88 Init all memu.\r
89\r
90 @param CallbackData The BMM context data.\r
91\r
92**/\r
93VOID\r
94InitAllMenu (\r
95 IN BMM_CALLBACK_DATA *CallbackData\r
96 );\r
97\r
98/**\r
99 Free up all Menu Option list.\r
100\r
101**/\r
102VOID\r
103FreeAllMenu (\r
104 VOID\r
105 );\r
106\r
107/**\r
108 Create string tokens for a menu from its help strings and display strings\r
109\r
110 @param CallbackData The BMM context data.\r
111 @param HiiHandle Hii Handle of the package to be updated.\r
112 @param MenuOption The Menu whose string tokens need to be created\r
113\r
114 @retval EFI_SUCCESS String tokens created successfully\r
115 @retval others contain some errors\r
116**/\r
117EFI_STATUS\r
118CreateMenuStringToken (\r
119 IN BMM_CALLBACK_DATA *CallbackData,\r
120 IN EFI_HII_HANDLE HiiHandle,\r
121 IN BM_MENU_OPTION *MenuOption\r
122 )\r
123{\r
124 BM_MENU_ENTRY *NewMenuEntry;\r
125 UINTN Index;\r
126\r
127 for (Index = 0; Index < MenuOption->MenuNumber; Index++) {\r
128 NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);\r
129\r
130 NewMenuEntry->DisplayStringToken = HiiSetString (\r
131 HiiHandle,\r
132 0,\r
133 NewMenuEntry->DisplayString,\r
134 NULL\r
135 );\r
136\r
137 if (NULL == NewMenuEntry->HelpString) {\r
138 NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;\r
139 } else {\r
140 NewMenuEntry->HelpStringToken = HiiSetString (\r
141 HiiHandle,\r
142 0,\r
143 NewMenuEntry->HelpString,\r
144 NULL\r
145 );\r
146 }\r
147 }\r
148\r
149 return EFI_SUCCESS;\r
150}\r
151\r
152/**\r
153 This function allows a caller to extract the current configuration for one\r
154 or more named elements from the target driver.\r
155\r
156\r
157 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
158 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
159 @param Progress On return, points to a character in the Request string.\r
160 Points to the string's null terminator if request was successful.\r
161 Points to the most recent '&' before the first failing name/value\r
162 pair (or the beginning of the string if the failure is in the\r
163 first name/value pair) if the request was not successful.\r
164 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
165 has all values filled in for the names in the Request string.\r
166 String to be allocated by the called function.\r
167\r
168 @retval EFI_SUCCESS The Results is filled with the requested values.\r
169 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
170 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
171 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
172\r
173**/\r
174EFI_STATUS\r
175EFIAPI\r
176BootMaintExtractConfig (\r
177 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
178 IN CONST EFI_STRING Request,\r
179 OUT EFI_STRING *Progress,\r
180 OUT EFI_STRING *Results\r
181 )\r
182{\r
183 EFI_STATUS Status;\r
184 UINTN BufferSize;\r
185 BMM_CALLBACK_DATA *Private;\r
186 EFI_STRING ConfigRequestHdr;\r
187 EFI_STRING ConfigRequest;\r
188 BOOLEAN AllocatedRequest;\r
189 UINTN Size;\r
190\r
191 if (Progress == NULL || Results == NULL) {\r
192 return EFI_INVALID_PARAMETER;\r
193 }\r
194\r
195 *Progress = Request;\r
196 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mBootMaintGuid, mBootMaintStorageName)) {\r
197 return EFI_NOT_FOUND;\r
198 }\r
199\r
200 ConfigRequestHdr = NULL;\r
201 ConfigRequest = NULL;\r
202 AllocatedRequest = FALSE;\r
203 Size = 0;\r
204\r
205 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
206 //\r
207 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
208 //\r
209 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
210 ConfigRequest = Request;\r
211 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
212 //\r
213 // Request has no request element, construct full request string.\r
214 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
215 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
216 //\r
217 ConfigRequestHdr = HiiConstructConfigHdr (&mBootMaintGuid, mBootMaintStorageName, Private->BmmDriverHandle);\r
218 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
219 ConfigRequest = AllocateZeroPool (Size);\r
220 ASSERT (ConfigRequest != NULL);\r
221 AllocatedRequest = TRUE;\r
222 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
223 FreePool (ConfigRequestHdr);\r
224 }\r
225\r
226 Status = gHiiConfigRouting->BlockToConfig (\r
227 gHiiConfigRouting,\r
228 ConfigRequest,\r
229 (UINT8 *) &Private->BmmFakeNvData,\r
230 BufferSize,\r
231 Results,\r
232 Progress\r
233 );\r
234 //\r
235 // Free the allocated config request string.\r
236 //\r
237 if (AllocatedRequest) {\r
238 FreePool (ConfigRequest);\r
239 ConfigRequest = NULL;\r
240 }\r
241 //\r
242 // Set Progress string to the original request string.\r
243 //\r
244 if (Request == NULL) {\r
245 *Progress = NULL;\r
246 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
247 *Progress = Request + StrLen (Request);\r
248 }\r
249\r
250 return Status;\r
251}\r
252\r
253/**\r
254 This function applies changes in a driver's configuration.\r
255 Input is a Configuration, which has the routing data for this\r
256 driver followed by name / value configuration pairs. The driver\r
257 must apply those pairs to its configurable storage. If the\r
258 driver's configuration is stored in a linear block of data\r
259 and the driver's name / value pairs are in <BlockConfig>\r
260 format, it may use the ConfigToBlock helper function (above) to\r
261 simplify the job. Currently not implemented.\r
262\r
263 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
264 @param[in] Configuration A null-terminated Unicode string in\r
265 <ConfigString> format. \r
266 @param[out] Progress A pointer to a string filled in with the\r
267 offset of the most recent '&' before the\r
268 first failing name / value pair (or the\r
269 beginn ing of the string if the failure\r
270 is in the first name / value pair) or\r
271 the terminating NULL if all was\r
272 successful.\r
273\r
274 @retval EFI_SUCCESS The results have been distributed or are\r
275 awaiting distribution. \r
276 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
277 parts of the results that must be\r
278 stored awaiting possible future\r
279 protocols.\r
280 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
281 Results parameter would result\r
282 in this type of error.\r
283 @retval EFI_NOT_FOUND Target for the specified routing data\r
284 was not found.\r
285**/\r
286EFI_STATUS\r
287EFIAPI\r
288BootMaintRouteConfig (\r
289 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
290 IN CONST EFI_STRING Configuration,\r
291 OUT EFI_STRING *Progress\r
292 )\r
293{\r
294 EFI_STATUS Status;\r
295 UINTN BufferSize;\r
296 EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;\r
297 BMM_FAKE_NV_DATA *NewBmmData;\r
298 BMM_FAKE_NV_DATA *OldBmmData;\r
299 BM_MENU_ENTRY *NewMenuEntry;\r
300 BM_LOAD_CONTEXT *NewLoadContext;\r
301 UINT16 Index; \r
302 BMM_CALLBACK_DATA *Private; \r
303\r
304 if (Progress == NULL) {\r
305 return EFI_INVALID_PARAMETER;\r
306 }\r
307 *Progress = Configuration;\r
308\r
309 if (Configuration == NULL) {\r
310 return EFI_INVALID_PARAMETER;\r
311 }\r
312\r
313 //\r
314 // Check routing data in <ConfigHdr>.\r
315 // Note: there is no name for Name/Value storage, only GUID will be checked\r
316 //\r
317 if (!HiiIsConfigHdrMatch (Configuration, &mBootMaintGuid, mBootMaintStorageName)) {\r
318 return EFI_NOT_FOUND;\r
319 }\r
320\r
321 Status = gBS->LocateProtocol (\r
322 &gEfiHiiConfigRoutingProtocolGuid, \r
323 NULL, \r
324 (VOID **)&ConfigRouting\r
325 );\r
326 if (EFI_ERROR (Status)) {\r
327 return Status;\r
328 }\r
329 \r
330 Private = BMM_CALLBACK_DATA_FROM_THIS (This); \r
331 //\r
332 // Get Buffer Storage data from EFI variable\r
333 //\r
334 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
335 OldBmmData = &Private->BmmOldFakeNVData;\r
336 NewBmmData = &Private->BmmFakeNvData;\r
337 //\r
338 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
339 //\r
340 Status = ConfigRouting->ConfigToBlock (\r
341 ConfigRouting,\r
342 Configuration,\r
343 (UINT8 *) NewBmmData,\r
344 &BufferSize,\r
345 Progress\r
346 );\r
347 ASSERT_EFI_ERROR (Status); \r
348 //\r
349 // Compare new and old BMM configuration data and only do action for modified item to \r
350 // avoid setting unnecessary non-volatile variable\r
351 //\r
352 \r
353 //\r
354 // Check data which located in BMM main page and save the settings if need\r
355 // \r
356 if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {\r
357 Status = Var_UpdateBootNext (Private);\r
358 }\r
359 \r
360 //\r
361 // Check data which located in Boot Options Menu and save the settings if need\r
362 // \r
363 if (CompareMem (NewBmmData->BootOptionDel, OldBmmData->BootOptionDel, sizeof (NewBmmData->BootOptionDel)) != 0) { \r
364 for (Index = 0; \r
365 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->BootOptionDel) / sizeof (NewBmmData->BootOptionDel[0])))); \r
366 Index ++) {\r
367 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
368 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
369 NewLoadContext->Deleted = NewBmmData->BootOptionDel[Index];\r
370 NewBmmData->BootOptionDel[Index] = FALSE;\r
371 }\r
372 \r
373 Var_DelBootOption ();\r
374 }\r
375 \r
376 if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) { \r
377 Status = Var_UpdateBootOrder (Private);\r
378 } \r
379\r
380 //\r
381 // Check data which located in Driver Options Menu and save the settings if need\r
382 // \r
383 if (CompareMem (NewBmmData->DriverOptionDel, OldBmmData->DriverOptionDel, sizeof (NewBmmData->DriverOptionDel)) != 0) { \r
384 for (Index = 0; \r
385 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->DriverOptionDel) / sizeof (NewBmmData->DriverOptionDel[0])))); \r
386 Index++) {\r
387 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
388 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
389 NewLoadContext->Deleted = NewBmmData->DriverOptionDel[Index];\r
390 NewBmmData->DriverOptionDel[Index] = FALSE;\r
391 }\r
392 Var_DelDriverOption (); \r
393 }\r
394 \r
395 if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) { \r
396 Status = Var_UpdateDriverOrder (Private);\r
397 } \r
398\r
399 //\r
400 // After user do the save action, need to update OldBmmData.\r
401 //\r
402 CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));\r
403\r
404 return EFI_SUCCESS;\r
405}\r
406\r
407/**\r
408 This function processes the results of changes in configuration.\r
409\r
410\r
411 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
412 @param Action Specifies the type of action taken by the browser.\r
413 @param QuestionId A unique value which is sent to the original exporting driver\r
414 so that it can identify the type of data to expect.\r
415 @param Type The type of value for the question.\r
416 @param Value A pointer to the data being sent to the original exporting driver.\r
417 @param ActionRequest On return, points to the action requested by the callback function.\r
418\r
419 @retval EFI_SUCCESS The callback successfully handled the action.\r
420 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
421 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
422 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
423 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.\r
424**/\r
425EFI_STATUS\r
426EFIAPI\r
427BootMaintCallback (\r
428 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
429 IN EFI_BROWSER_ACTION Action,\r
430 IN EFI_QUESTION_ID QuestionId,\r
431 IN UINT8 Type,\r
432 IN EFI_IFR_TYPE_VALUE *Value,\r
433 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
434 )\r
435{\r
436 BMM_CALLBACK_DATA *Private;\r
437 BM_MENU_ENTRY *NewMenuEntry;\r
438 BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
439 EFI_STATUS Status;\r
440 UINTN OldValue;\r
441 UINTN NewValue;\r
442 UINTN Number;\r
443 UINTN Index;\r
444\r
445 //\r
446 //Chech whether exit from FileExplorer and reenter BM,if yes,reclaim string depositories\r
447 //\r
448 if (Action == EFI_BROWSER_ACTION_FORM_OPEN){\r
449 if(mEnterFileExplorer ){\r
450 ReclaimStringDepository();\r
451 mEnterFileExplorer = FALSE;\r
452 }\r
453 }\r
454\r
455 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {\r
456 //\r
457 // Do nothing for other UEFI Action. Only do call back when data is changed.\r
458 //\r
459 return EFI_UNSUPPORTED;\r
460 }\r
461\r
462 OldValue = 0;\r
463 NewValue = 0;\r
464 Number = 0;\r
465\r
466 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
467\r
468 //\r
469 // Retrive uncommitted data from Form Browser\r
470 //\r
471 CurrentFakeNVMap = &Private->BmmFakeNvData;\r
472 HiiGetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);\r
473\r
474 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
475 if (Value == NULL) {\r
476 return EFI_INVALID_PARAMETER;\r
477 }\r
478 \r
479 UpdatePageId (Private, QuestionId);\r
480\r
481 if (QuestionId < FILE_OPTION_OFFSET) {\r
482 if (QuestionId < CONFIG_OPTION_OFFSET) {\r
483 switch (QuestionId) {\r
484 case FORM_BOOT_ADD_ID:\r
485 // Leave Bm and enter FileExplorer.\r
486 Private->FeCurrentState = FileExplorerStateAddBootOption;\r
487 Private->FeDisplayContext = FileExplorerDisplayUnknown;\r
488 ReclaimStringDepository (); \r
489 UpdateFileExplorer(Private, 0);\r
490 mEnterFileExplorer = TRUE;\r
491 break;\r
492\r
493 case FORM_DRV_ADD_FILE_ID:\r
494 // Leave Bm and enter FileExplorer.\r
495 Private->FeCurrentState = FileExplorerStateAddDriverOptionState;\r
496 Private->FeDisplayContext = FileExplorerDisplayUnknown;\r
497 ReclaimStringDepository ();\r
498 UpdateFileExplorer(Private, 0);\r
499 mEnterFileExplorer = TRUE;\r
500 break;\r
501\r
502 case FORM_DRV_ADD_HANDLE_ID:\r
503 CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);\r
504 UpdateDrvAddHandlePage (Private);\r
505 break;\r
506\r
507 case FORM_BOOT_DEL_ID:\r
508 CleanUpPage (FORM_BOOT_DEL_ID, Private);\r
509 UpdateBootDelPage (Private);\r
510 break;\r
511\r
512 case FORM_BOOT_CHG_ID:\r
513 case FORM_DRV_CHG_ID:\r
514 UpdatePageBody (QuestionId, Private);\r
515 break;\r
516\r
517 case FORM_DRV_DEL_ID:\r
518 CleanUpPage (FORM_DRV_DEL_ID, Private);\r
519 UpdateDrvDelPage (Private);\r
520 break;\r
521\r
522 case FORM_BOOT_NEXT_ID:\r
523 CleanUpPage (FORM_BOOT_NEXT_ID, Private);\r
524 UpdateBootNextPage (Private);\r
525 break;\r
526\r
527 case FORM_TIME_OUT_ID:\r
528 CleanUpPage (FORM_TIME_OUT_ID, Private);\r
529 UpdateTimeOutPage (Private);\r
530 break;\r
531\r
532 case FORM_CON_IN_ID:\r
533 case FORM_CON_OUT_ID:\r
534 case FORM_CON_ERR_ID:\r
535 UpdatePageBody (QuestionId, Private);\r
536 break;\r
537\r
538 case FORM_CON_MODE_ID:\r
539 CleanUpPage (FORM_CON_MODE_ID, Private);\r
540 UpdateConModePage (Private);\r
541 break;\r
542\r
543 case FORM_CON_COM_ID:\r
544 CleanUpPage (FORM_CON_COM_ID, Private);\r
545 UpdateConCOMPage (Private);\r
546 break;\r
547\r
548 default:\r
549 break;\r
550 }\r
551 } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {\r
552 Index = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);\r
553 Private->CurrentTerminal = Index;\r
554\r
555 CleanUpPage (FORM_CON_COM_SETUP_ID, Private);\r
556 UpdateTerminalPage (Private);\r
557\r
558 } else if (QuestionId >= HANDLE_OPTION_OFFSET) {\r
559 Index = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);\r
560\r
561 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);\r
562 ASSERT (NewMenuEntry != NULL);\r
563 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;\r
564\r
565 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);\r
566\r
567 Private->MenuEntry = NewMenuEntry;\r
568 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;\r
569\r
570 UpdateDriverAddHandleDescPage (Private);\r
571 }\r
572 }\r
573 if (QuestionId == KEY_VALUE_BOOT_FROM_FILE){\r
574 // Leave Bm and enter FileExplorer.\r
575 Private->FeCurrentState = FileExplorerStateBootFromFile;\r
576 Private->FeDisplayContext = FileExplorerDisplayUnknown;\r
577 ReclaimStringDepository ();\r
578 UpdateFileExplorer(Private, 0);\r
579 mEnterFileExplorer = TRUE;\r
580 }\r
581 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
582 if ((Value == NULL) || (ActionRequest == NULL)) {\r
583 return EFI_INVALID_PARAMETER;\r
584 }\r
585\r
586 switch (QuestionId) {\r
587 case KEY_VALUE_SAVE_AND_EXIT:\r
588 case KEY_VALUE_NO_SAVE_AND_EXIT:\r
589 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {\r
590 Status = ApplyChangeHandler (Private, CurrentFakeNVMap, Private->BmmPreviousPageId);\r
591 if (EFI_ERROR (Status)) {\r
592 return Status;\r
593 }\r
594 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {\r
595 DiscardChangeHandler (Private, CurrentFakeNVMap);\r
596 }\r
597\r
598 //\r
599 // Tell browser not to ask for confirmation of changes,\r
600 // since we have already applied or discarded.\r
601 //\r
602 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
603\r
604 break;\r
605\r
606 default:\r
607 break;\r
608 }\r
609 }\r
610\r
611 //\r
612 // Pass changed uncommitted data back to Form Browser\r
613 //\r
614 HiiSetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);\r
615\r
616 return EFI_SUCCESS;\r
617}\r
618\r
619/**\r
620 Function handling request to apply changes for BMM pages.\r
621\r
622 @param Private Pointer to callback data buffer.\r
623 @param CurrentFakeNVMap Pointer to buffer holding data of various values used by BMM\r
624 @param FormId ID of the form which has sent the request to apply change.\r
625\r
626 @retval EFI_SUCCESS Change successfully applied.\r
627 @retval Other Error occurs while trying to apply changes.\r
628\r
629**/\r
630EFI_STATUS\r
631ApplyChangeHandler (\r
632 IN BMM_CALLBACK_DATA *Private,\r
633 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap,\r
634 IN EFI_FORM_ID FormId\r
635 )\r
636{\r
637 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
638 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
639 BM_LOAD_CONTEXT *NewLoadContext;\r
640 BM_MENU_ENTRY *NewMenuEntry;\r
641 EFI_STATUS Status;\r
642 UINT16 Index;\r
643\r
644 Status = EFI_SUCCESS;\r
645\r
646 switch (FormId) {\r
647 case FORM_BOOT_DEL_ID:\r
648 for (Index = 0; \r
649 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])))); \r
650 Index ++) {\r
651 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
652 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
653 NewLoadContext->Deleted = CurrentFakeNVMap->BootOptionDel[Index];\r
654 CurrentFakeNVMap->BootOptionDel[Index] = FALSE;\r
655 }\r
656\r
657 Var_DelBootOption ();\r
658 break;\r
659\r
660 case FORM_DRV_DEL_ID:\r
661 for (Index = 0; \r
662 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])))); \r
663 Index++) {\r
664 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
665 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
666 NewLoadContext->Deleted = CurrentFakeNVMap->DriverOptionDel[Index];\r
667 CurrentFakeNVMap->DriverOptionDel[Index] = FALSE;\r
668 }\r
669\r
670 Var_DelDriverOption ();\r
671 break;\r
672\r
673 case FORM_BOOT_CHG_ID:\r
674 Status = Var_UpdateBootOrder (Private);\r
675 break;\r
676\r
677 case FORM_DRV_CHG_ID:\r
678 Status = Var_UpdateDriverOrder (Private);\r
679 break;\r
680\r
681 case FORM_TIME_OUT_ID:\r
682 Status = gRT->SetVariable (\r
683 L"Timeout",\r
684 &gEfiGlobalVariableGuid,\r
685 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
686 sizeof (UINT16),\r
687 &(CurrentFakeNVMap->BootTimeOut)\r
688 );\r
689 ASSERT_EFI_ERROR(Status);\r
690\r
691 Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;\r
692 break;\r
693\r
694 case FORM_BOOT_NEXT_ID:\r
695 Status = Var_UpdateBootNext (Private);\r
696 break;\r
697\r
698 case FORM_CON_MODE_ID:\r
699 Status = Var_UpdateConMode (Private);\r
700 break;\r
701\r
702 case FORM_CON_COM_SETUP_ID:\r
703 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal);\r
704\r
705 ASSERT (NewMenuEntry != NULL);\r
706\r
707 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
708\r
709 NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate;\r
710 ASSERT (CurrentFakeNVMap->COMBaudRate < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));\r
711 NewTerminalContext->BaudRate = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value;\r
712 NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate;\r
713 ASSERT (CurrentFakeNVMap->COMDataRate < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));\r
714 NewTerminalContext->DataBits = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value;\r
715 NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits;\r
716 ASSERT (CurrentFakeNVMap->COMStopBits < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));\r
717 NewTerminalContext->StopBits = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value;\r
718 NewTerminalContext->ParityIndex = CurrentFakeNVMap->COMParity;\r
719 ASSERT (CurrentFakeNVMap->COMParity < (sizeof (ParityList) / sizeof (ParityList[0])));\r
720 NewTerminalContext->Parity = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value;\r
721 NewTerminalContext->TerminalType = CurrentFakeNVMap->COMTerminalType;\r
722\r
723 ChangeTerminalDevicePath (\r
724 NewTerminalContext->DevicePath,\r
725 FALSE\r
726 );\r
727\r
728 Var_UpdateConsoleInpOption ();\r
729 Var_UpdateConsoleOutOption ();\r
730 Var_UpdateErrorOutOption ();\r
731 break;\r
732\r
733 case FORM_CON_IN_ID:\r
734 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {\r
735 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);\r
736 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
737 ASSERT (Index < MAX_MENU_NUMBER);\r
738 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
739 }\r
740\r
741 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
742 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
743 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
744 ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);\r
745 NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber];\r
746 }\r
747\r
748 Var_UpdateConsoleInpOption ();\r
749 break;\r
750\r
751 case FORM_CON_OUT_ID:\r
752 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {\r
753 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);\r
754 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
755 ASSERT (Index < MAX_MENU_NUMBER);\r
756 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
757 }\r
758\r
759 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
760 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
761 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
762 ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);\r
763 NewTerminalContext->IsConOut = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber];\r
764 }\r
765\r
766 Var_UpdateConsoleOutOption ();\r
767 break;\r
768\r
769 case FORM_CON_ERR_ID:\r
770 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {\r
771 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);\r
772 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
773 ASSERT (Index < MAX_MENU_NUMBER);\r
774 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
775 }\r
776\r
777 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
778 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
779 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
780 ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);\r
781 NewTerminalContext->IsStdErr = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber];\r
782 }\r
783\r
784 Var_UpdateErrorOutOption ();\r
785 break;\r
786\r
787 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
788 Status = Var_UpdateDriverOption (\r
789 Private,\r
790 Private->BmmHiiHandle,\r
791 CurrentFakeNVMap->DriverAddHandleDesc,\r
792 CurrentFakeNVMap->DriverAddHandleOptionalData,\r
793 CurrentFakeNVMap->DriverAddForceReconnect\r
794 );\r
795 if (EFI_ERROR (Status)) {\r
796 goto Error;\r
797 }\r
798\r
799 BOpt_GetDriverOptions (Private);\r
800 CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);\r
801 break;\r
802\r
803 default:\r
804 break;\r
805 }\r
806\r
807Error:\r
808 return Status;\r
809}\r
810\r
811/**\r
812 Discard all changes done to the BMM pages such as Boot Order change,\r
813 Driver order change.\r
814\r
815 @param Private The BMM context data.\r
816 @param CurrentFakeNVMap The current Fack NV Map.\r
817\r
818**/\r
819VOID\r
820DiscardChangeHandler (\r
821 IN BMM_CALLBACK_DATA *Private,\r
822 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap\r
823 )\r
824{\r
825 UINT16 Index;\r
826\r
827 switch (Private->BmmPreviousPageId) {\r
828 case FORM_BOOT_CHG_ID:\r
829 CopyMem (CurrentFakeNVMap->BootOptionOrder, Private->BmmOldFakeNVData.BootOptionOrder, sizeof (CurrentFakeNVMap->BootOptionOrder));\r
830 break;\r
831 \r
832 case FORM_DRV_CHG_ID:\r
833 CopyMem (CurrentFakeNVMap->DriverOptionOrder, Private->BmmOldFakeNVData.DriverOptionOrder, sizeof (CurrentFakeNVMap->DriverOptionOrder));\r
834 break;\r
835\r
836 case FORM_BOOT_DEL_ID:\r
837 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));\r
838 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
839 CurrentFakeNVMap->BootOptionDel[Index] = FALSE;\r
840 }\r
841 break;\r
842\r
843 case FORM_DRV_DEL_ID:\r
844 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));\r
845 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
846 CurrentFakeNVMap->DriverOptionDel[Index] = FALSE;\r
847 }\r
848 break;\r
849\r
850 case FORM_BOOT_NEXT_ID:\r
851 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;\r
852 break;\r
853\r
854 case FORM_TIME_OUT_ID:\r
855 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;\r
856 break;\r
857\r
858 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
859 case FORM_DRV_ADD_FILE_ID:\r
860 case FORM_DRV_ADD_HANDLE_ID:\r
861 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;\r
862 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;\r
863 break;\r
864\r
865 default:\r
866 break;\r
867 }\r
868}\r
869\r
870\r
871/**\r
872 Create dynamic code for BMM.\r
873\r
874 @param BmmCallbackInfo The BMM context data.\r
875\r
876**/\r
877VOID\r
878InitializeDrivers(\r
879 IN BMM_CALLBACK_DATA *BmmCallbackInfo\r
880 )\r
881{\r
882 EFI_HII_HANDLE HiiHandle;\r
883 VOID *StartOpCodeHandle;\r
884 VOID *EndOpCodeHandle;\r
885 EFI_IFR_GUID_LABEL *StartLabel;\r
886 EFI_IFR_GUID_LABEL *EndLabel;\r
887 UINTN Index; \r
888 EFI_STRING_ID FormSetTitle;\r
889 EFI_STRING_ID FormSetHelp; \r
890 EFI_STRING String;\r
891 EFI_STRING_ID Token;\r
892 EFI_STRING_ID TokenHelp; \r
893 EFI_HII_HANDLE *HiiHandles;\r
894 UINTN SkipCount;\r
895 EFI_GUID FormSetGuid;\r
896 CHAR16 *DevicePathStr;\r
897 EFI_STRING_ID DevicePathId;\r
898\r
899 HiiHandle = BmmCallbackInfo->BmmHiiHandle;\r
900 //\r
901 // Allocate space for creation of UpdateData Buffer\r
902 //\r
903 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
904 ASSERT (StartOpCodeHandle != NULL);\r
905\r
906 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
907 ASSERT (EndOpCodeHandle != NULL);\r
908\r
909 //\r
910 // Create Hii Extend Label OpCode as the start opcode\r
911 //\r
912 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
913 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
914 StartLabel->Number = LABEL_BMM_PLATFORM_INFORMATION;\r
915\r
916 //\r
917 // Create Hii Extend Label OpCode as the end opcode\r
918 //\r
919 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
920 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
921 EndLabel->Number = LABEL_END;\r
922\r
923 //\r
924 // Get all the Hii handles\r
925 //\r
926 HiiHandles = HiiGetHiiHandles (NULL);\r
927 ASSERT (HiiHandles != NULL);\r
928\r
929 //\r
930 // Search for formset of each class type\r
931 //\r
932 SkipCount = 0;\r
933 for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
934 if (!ExtractDisplayedHiiFormFromHiiHandle (HiiHandles[Index], &gEfiIfrBootMaintenanceGuid, SkipCount, &FormSetTitle, &FormSetHelp, &FormSetGuid)) {\r
935 SkipCount = 0;\r
936 continue;\r
937 }\r
938 String = HiiGetString (HiiHandles[Index], FormSetTitle, NULL);\r
939 if (String == NULL) {\r
940 String = HiiGetString (HiiHandle, STR_MISSING_STRING, NULL);\r
941 ASSERT (String != NULL);\r
942 }\r
943 Token = HiiSetString (HiiHandle, 0, String, NULL);\r
944 FreePool (String);\r
945\r
946 String = HiiGetString (HiiHandles[Index], FormSetHelp, NULL);\r
947 if (String == NULL) {\r
948 String = HiiGetString (HiiHandle, STR_MISSING_STRING, NULL);\r
949 ASSERT (String != NULL);\r
950 }\r
951 TokenHelp = HiiSetString (HiiHandle, 0, String, NULL);\r
952 FreePool (String);\r
953\r
954 DevicePathStr = ExtractDevicePathFromHiiHandle(HiiHandles[Index]);\r
955 DevicePathId = 0;\r
956 if (DevicePathStr != NULL){\r
957 DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL);\r
958 FreePool (DevicePathStr);\r
959 }\r
960\r
961 HiiCreateGotoExOpCode (\r
962 StartOpCodeHandle,\r
963 0,\r
964 Token,\r
965 TokenHelp,\r
966 0,\r
967 (EFI_QUESTION_ID) (Index + FRONT_PAGE_KEY_OFFSET),\r
968 0,\r
969 &FormSetGuid,\r
970 DevicePathId\r
971 );\r
972 //\r
973 //One packagelist may has more than one form package,\r
974 //Index-- means keep current HiiHandle and still extract from the packagelist, \r
975 //SkipCount++ means skip the formset which was found before in the same form package. \r
976 //\r
977 SkipCount++;\r
978 Index--;\r
979 }\r
980\r
981 HiiUpdateForm (\r
982 HiiHandle,\r
983 &mBootMaintGuid,\r
984 FORM_MAIN_ID,\r
985 StartOpCodeHandle,\r
986 EndOpCodeHandle\r
987 );\r
988\r
989 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
990 HiiFreeOpCodeHandle (EndOpCodeHandle); \r
991 FreePool (HiiHandles);\r
992}\r
993\r
994\r
995/**\r
996 Create dynamic code for BMM.\r
997\r
998 @param BmmCallbackInfo The BMM context data.\r
999\r
1000**/\r
1001VOID\r
1002InitializeBmmConfig(\r
1003 IN BMM_CALLBACK_DATA *BmmCallbackInfo\r
1004 )\r
1005{\r
1006 UpdateBootDelPage (BmmCallbackInfo);\r
1007 UpdateDrvDelPage (BmmCallbackInfo);\r
1008\r
1009 if (TerminalMenu.MenuNumber > 0) {\r
1010 BmmCallbackInfo->CurrentTerminal = 0;\r
1011 UpdateTerminalPage (BmmCallbackInfo);\r
1012 }\r
1013\r
1014 InitializeDrivers (BmmCallbackInfo);\r
1015}\r
1016\r
1017/**\r
1018 Initialize the Boot Maintenance Utitliy.\r
1019\r
1020**/\r
1021VOID\r
1022InitializeBM (\r
1023 VOID\r
1024 )\r
1025{\r
1026 BMM_CALLBACK_DATA *BmmCallbackInfo;\r
1027\r
1028 BmmCallbackInfo = mBmmCallbackInfo;\r
1029 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;\r
1030 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;\r
1031 BmmCallbackInfo->FeCurrentState = FileExplorerStateInActive;\r
1032 BmmCallbackInfo->FeDisplayContext = FileExplorerDisplayUnknown;\r
1033\r
1034 InitAllMenu (BmmCallbackInfo);\r
1035\r
1036 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);\r
1037 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);\r
1038 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);\r
1039 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);\r
1040 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);\r
1041 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);\r
1042 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);\r
1043\r
1044 InitializeBmmConfig(BmmCallbackInfo);\r
1045}\r
1046\r
1047/**\r
1048 Initialized all Menu Option List.\r
1049\r
1050 @param CallbackData The BMM context data.\r
1051\r
1052**/\r
1053VOID\r
1054InitAllMenu (\r
1055 IN BMM_CALLBACK_DATA *CallbackData\r
1056 )\r
1057{\r
1058 InitializeListHead (&BootOptionMenu.Head);\r
1059 InitializeListHead (&DriverOptionMenu.Head);\r
1060 BOpt_GetBootOptions (CallbackData);\r
1061 BOpt_GetDriverOptions (CallbackData);\r
1062 InitializeListHead (&FsOptionMenu.Head);\r
1063 BOpt_FindDrivers ();\r
1064 InitializeListHead (&DirectoryMenu.Head);\r
1065 InitializeListHead (&ConsoleInpMenu.Head);\r
1066 InitializeListHead (&ConsoleOutMenu.Head);\r
1067 InitializeListHead (&ConsoleErrMenu.Head);\r
1068 InitializeListHead (&TerminalMenu.Head);\r
1069 LocateSerialIo ();\r
1070 GetAllConsoles ();\r
1071 mAllMenuInit = TRUE;\r
1072}\r
1073\r
1074/**\r
1075 Free up all Menu Option list.\r
1076\r
1077**/\r
1078VOID\r
1079FreeAllMenu (\r
1080 VOID\r
1081 )\r
1082{\r
1083 if (!mAllMenuInit){\r
1084 return;\r
1085 }\r
1086 BOpt_FreeMenu (&DirectoryMenu);\r
1087 BOpt_FreeMenu (&FsOptionMenu);\r
1088 BOpt_FreeMenu (&BootOptionMenu);\r
1089 BOpt_FreeMenu (&DriverOptionMenu);\r
1090 BOpt_FreeMenu (&DriverMenu);\r
1091 FreeAllConsoles ();\r
1092 mAllMenuInit = FALSE;\r
1093}\r
1094\r
1095/**\r
1096 Initialize all the string depositories.\r
1097\r
1098**/\r
1099VOID\r
1100InitializeStringDepository (\r
1101 VOID\r
1102 )\r
1103{\r
1104 STRING_DEPOSITORY *StringDepository;\r
1105 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);\r
1106 FileOptionStrDepository = StringDepository++;\r
1107 ConsoleOptionStrDepository = StringDepository++;\r
1108 BootOptionStrDepository = StringDepository++;\r
1109 BootOptionHelpStrDepository = StringDepository++;\r
1110 DriverOptionStrDepository = StringDepository++;\r
1111 DriverOptionHelpStrDepository = StringDepository++;\r
1112 TerminalStrDepository = StringDepository;\r
1113}\r
1114\r
1115/**\r
1116 Fetch a usable string node from the string depository and return the string token.\r
1117\r
1118 @param CallbackData The BMM context data.\r
1119 @param StringDepository The string repository.\r
1120\r
1121 @retval EFI_STRING_ID String token.\r
1122\r
1123**/\r
1124EFI_STRING_ID\r
1125GetStringTokenFromDepository (\r
1126 IN BMM_CALLBACK_DATA *CallbackData,\r
1127 IN STRING_DEPOSITORY *StringDepository\r
1128 )\r
1129{\r
1130 STRING_LIST_NODE *CurrentListNode;\r
1131 STRING_LIST_NODE *NextListNode;\r
1132\r
1133 CurrentListNode = StringDepository->CurrentNode;\r
1134\r
1135 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {\r
1136 //\r
1137 // Fetch one reclaimed node from the list.\r
1138 //\r
1139 NextListNode = StringDepository->CurrentNode->Next;\r
1140 } else {\r
1141 //\r
1142 // If there is no usable node in the list, update the list.\r
1143 //\r
1144 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));\r
1145 ASSERT (NextListNode != NULL);\r
1146 NextListNode->StringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, L" ", NULL);\r
1147 ASSERT (NextListNode->StringToken != 0);\r
1148\r
1149 StringDepository->TotalNodeNumber++;\r
1150\r
1151 if (NULL == CurrentListNode) {\r
1152 StringDepository->ListHead = NextListNode;\r
1153 } else {\r
1154 CurrentListNode->Next = NextListNode;\r
1155 }\r
1156 }\r
1157\r
1158 StringDepository->CurrentNode = NextListNode;\r
1159\r
1160 return StringDepository->CurrentNode->StringToken;\r
1161}\r
1162\r
1163/**\r
1164 Reclaim string depositories by moving the current node pointer to list head..\r
1165\r
1166**/\r
1167VOID\r
1168ReclaimStringDepository (\r
1169 VOID\r
1170 )\r
1171{\r
1172 UINTN DepositoryIndex;\r
1173 STRING_DEPOSITORY *StringDepository;\r
1174\r
1175 StringDepository = FileOptionStrDepository;\r
1176 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1177 StringDepository->CurrentNode = StringDepository->ListHead;\r
1178 StringDepository++;\r
1179 }\r
1180}\r
1181\r
1182/**\r
1183 Release resource for all the string depositories.\r
1184\r
1185**/\r
1186VOID\r
1187CleanUpStringDepository (\r
1188 VOID\r
1189 )\r
1190{\r
1191 UINTN NodeIndex;\r
1192 UINTN DepositoryIndex;\r
1193 STRING_LIST_NODE *CurrentListNode;\r
1194 STRING_LIST_NODE *NextListNode;\r
1195 STRING_DEPOSITORY *StringDepository;\r
1196\r
1197 //\r
1198 // Release string list nodes.\r
1199 //\r
1200 StringDepository = FileOptionStrDepository;\r
1201 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1202 CurrentListNode = StringDepository->ListHead;\r
1203 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {\r
1204 NextListNode = CurrentListNode->Next;\r
1205 FreePool (CurrentListNode);\r
1206 CurrentListNode = NextListNode;\r
1207 }\r
1208\r
1209 StringDepository++;\r
1210 }\r
1211 //\r
1212 // Release string depository.\r
1213 //\r
1214 FreePool (FileOptionStrDepository);\r
1215}\r
1216\r
1217/**\r
1218 Install BootMaint and FileExplorer HiiPackages.\r
1219\r
1220**/\r
1221VOID\r
1222InitBootMaintenance(\r
1223 VOID\r
1224 )\r
1225{\r
1226 BMM_CALLBACK_DATA *BmmCallbackInfo;\r
1227 EFI_STATUS Status;\r
1228 UINT8 *Ptr;\r
1229\r
1230 Status = EFI_SUCCESS;\r
1231\r
1232 if (!gConnectAllHappened){\r
1233 EfiBootManagerConnectAll();\r
1234 gConnectAllHappened = TRUE;\r
1235 }\r
1236\r
1237 EfiBootManagerRefreshAllBootOption ();\r
1238\r
1239 //\r
1240 // Create CallbackData structures for Driver Callback\r
1241 //\r
1242 BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));\r
1243 ASSERT (BmmCallbackInfo != NULL);\r
1244\r
1245 //\r
1246 // Create LoadOption in BmmCallbackInfo for Driver Callback\r
1247 //\r
1248 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));\r
1249 ASSERT (Ptr != NULL);\r
1250\r
1251 //\r
1252 // Initialize Bmm callback data.\r
1253 //\r
1254 BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;\r
1255 Ptr += sizeof (BM_LOAD_CONTEXT);\r
1256\r
1257 BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;\r
1258 Ptr += sizeof (BM_FILE_CONTEXT);\r
1259\r
1260 BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;\r
1261 Ptr += sizeof (BM_HANDLE_CONTEXT);\r
1262\r
1263 BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;\r
1264\r
1265 BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;\r
1266 BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;\r
1267 BmmCallbackInfo->BmmConfigAccess.RouteConfig = BootMaintRouteConfig;\r
1268 BmmCallbackInfo->BmmConfigAccess.Callback = BootMaintCallback;\r
1269 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;\r
1270 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;\r
1271 BmmCallbackInfo->FeConfigAccess.ExtractConfig = FakeExtractConfig;\r
1272 BmmCallbackInfo->FeConfigAccess.RouteConfig = FakeRouteConfig;\r
1273 BmmCallbackInfo->FeConfigAccess.Callback = FileExplorerCallback;\r
1274 BmmCallbackInfo->FeCurrentState = FileExplorerStateInActive;\r
1275 BmmCallbackInfo->FeDisplayContext = FileExplorerDisplayUnknown;\r
1276\r
1277 //\r
1278 // Install Device Path Protocol and Config Access protocol to driver handle\r
1279 //\r
1280 Status = gBS->InstallMultipleProtocolInterfaces (\r
1281 &BmmCallbackInfo->BmmDriverHandle,\r
1282 &gEfiDevicePathProtocolGuid,\r
1283 &mBmmHiiVendorDevicePath,\r
1284 &gEfiHiiConfigAccessProtocolGuid,\r
1285 &BmmCallbackInfo->BmmConfigAccess,\r
1286 NULL\r
1287 );\r
1288 ASSERT_EFI_ERROR (Status);\r
1289\r
1290 //\r
1291 // Install Device Path Protocol and Config Access protocol to driver handle\r
1292 //\r
1293 Status = gBS->InstallMultipleProtocolInterfaces (\r
1294 &BmmCallbackInfo->FeDriverHandle,\r
1295 &gEfiDevicePathProtocolGuid,\r
1296 &mFeHiiVendorDevicePath,\r
1297 &gEfiHiiConfigAccessProtocolGuid,\r
1298 &BmmCallbackInfo->FeConfigAccess,\r
1299 NULL\r
1300 );\r
1301 ASSERT_EFI_ERROR (Status);\r
1302\r
1303 //\r
1304 // Post our Boot Maint VFR binary to the HII database.\r
1305 //\r
1306 BmmCallbackInfo->BmmHiiHandle = HiiAddPackages (\r
1307 &mBootMaintGuid,\r
1308 BmmCallbackInfo->BmmDriverHandle,\r
1309 BmBin,\r
1310 UiAppStrings,\r
1311 NULL\r
1312 );\r
1313 ASSERT (BmmCallbackInfo->BmmHiiHandle != NULL);\r
1314\r
1315 //\r
1316 // Post our File Explorer VFR binary to the HII database.\r
1317 //\r
1318 BmmCallbackInfo->FeHiiHandle = HiiAddPackages (\r
1319 &mFileExplorerGuid,\r
1320 BmmCallbackInfo->FeDriverHandle,\r
1321 FEBin,\r
1322 UiAppStrings,\r
1323 NULL\r
1324 );\r
1325 ASSERT (BmmCallbackInfo->FeHiiHandle != NULL);\r
1326\r
1327 //\r
1328 // Init OpCode Handle and Allocate space for creation of Buffer\r
1329 //\r
1330 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1331 ASSERT (mStartOpCodeHandle != NULL);\r
1332\r
1333 mEndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1334 ASSERT (mEndOpCodeHandle != NULL);\r
1335\r
1336 //\r
1337 // Create Hii Extend Label OpCode as the start opcode\r
1338 //\r
1339 mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1340 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1341\r
1342 //\r
1343 // Create Hii Extend Label OpCode as the end opcode\r
1344 //\r
1345 mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mEndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1346 mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1347 mEndLabel->Number = LABEL_END;\r
1348\r
1349 mBmmCallbackInfo = BmmCallbackInfo;\r
1350\r
1351 InitializeStringDepository ();\r
1352\r
1353}\r
1354\r
1355/**\r
1356 Remove the installed BootMaint and FileExplorer HiiPackages.\r
1357\r
1358**/\r
1359\r
1360VOID\r
1361FreeBMPackage(\r
1362 VOID\r
1363 )\r
1364{\r
1365 BMM_CALLBACK_DATA *BmmCallbackInfo;\r
1366\r
1367 if (mStartOpCodeHandle != NULL) {\r
1368 HiiFreeOpCodeHandle (mStartOpCodeHandle);\r
1369 }\r
1370\r
1371 if (mEndOpCodeHandle != NULL) {\r
1372 HiiFreeOpCodeHandle (mEndOpCodeHandle);\r
1373 }\r
1374\r
1375 FreeAllMenu ();\r
1376 CleanUpStringDepository ();\r
1377\r
1378 BmmCallbackInfo = mBmmCallbackInfo;\r
1379\r
1380 //\r
1381 // Remove our IFR data from HII database\r
1382 //\r
1383 HiiRemovePackages (BmmCallbackInfo->BmmHiiHandle);\r
1384 HiiRemovePackages (BmmCallbackInfo->FeHiiHandle);\r
1385\r
1386 gBS->UninstallMultipleProtocolInterfaces (\r
1387 BmmCallbackInfo->FeDriverHandle,\r
1388 &gEfiDevicePathProtocolGuid,\r
1389 &mFeHiiVendorDevicePath,\r
1390 &gEfiHiiConfigAccessProtocolGuid,\r
1391 &BmmCallbackInfo->FeConfigAccess,\r
1392 NULL\r
1393 );\r
1394\r
1395 gBS->UninstallMultipleProtocolInterfaces (\r
1396 BmmCallbackInfo->BmmDriverHandle,\r
1397 &gEfiDevicePathProtocolGuid,\r
1398 &mBmmHiiVendorDevicePath,\r
1399 &gEfiHiiConfigAccessProtocolGuid,\r
1400 &BmmCallbackInfo->BmmConfigAccess,\r
1401 NULL\r
1402 );\r
1403\r
1404 FreePool (BmmCallbackInfo->LoadContext);\r
1405 FreePool (BmmCallbackInfo);\r
1406}\r
1407\r