]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
Clean up BootMaint module in BdsDxe.
[mirror_edk2.git] / MdeModulePkg / Universal / BdsDxe / BootMaint / BootMaint.c
CommitLineData
fd6a62f3 1/** @file\r
2 Boot Maintainence Main File\r
93e3992d 3\r
fd6a62f3 4Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
93e3992d 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
fd6a62f3 13**/\r
93e3992d 14\r
15#include "BootMaint.h"\r
16#include "FormGuid.h"\r
17#include "Bds.h"\r
18#include "FrontPage.h"\r
19\r
dce655e8 20EFI_DEVICE_PATH_PROTOCOL EndDevicePath[] = {\r
21 END_DEVICE_PATH_TYPE,\r
22 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
23 END_DEVICE_PATH_LENGTH,\r
24 0\r
25};\r
26\r
27\r
93e3992d 28EFI_GUID EfiLegacyDevOrderGuid = EFI_LEGACY_DEV_ORDER_VARIABLE_GUID;\r
29EFI_GUID mBootMaintGuid = BOOT_MAINT_FORMSET_GUID;\r
30EFI_GUID mFileExplorerGuid = FILE_EXPLORE_FORMSET_GUID;\r
31\r
32CHAR16 mBootMaintStorageName[] = L"BmData";\r
33CHAR16 mFileExplorerStorageName[] = L"FeData";\r
34\r
b30312ba 35/**\r
36 Init all memu.\r
37\r
38 @param CallbackData The \r
39\r
40 @return EDES_TODO: Add description for return value\r
41\r
42**/\r
93e3992d 43VOID\r
44InitAllMenu (\r
45 IN BMM_CALLBACK_DATA *CallbackData\r
46 );\r
47\r
b30312ba 48/**\r
a78b08d1 49 EDES_TODO: Add function description.\r
b30312ba 50\r
51 @param VOID EDES_TODO: Add parameter description\r
52\r
53 @return EDES_TODO: Add description for return value\r
54\r
55**/\r
93e3992d 56VOID\r
57FreeAllMenu (\r
58 VOID\r
59 );\r
60\r
b30312ba 61/**\r
62 Create string tokens for a menu from its help strings and display strings\r
63\r
64\r
dce655e8 65 @param CallbackData The BMM context data.\r
66 @param HiiHandle Hii Handle of the package to be updated.\r
67 @param MenuOption The Menu whose string tokens need to be created\r
b30312ba 68\r
69 @retval EFI_SUCCESS string tokens created successfully\r
70 @retval others contain some errors\r
71\r
72**/\r
93e3992d 73EFI_STATUS\r
74CreateMenuStringToken (\r
75 IN BMM_CALLBACK_DATA *CallbackData,\r
76 IN EFI_HII_HANDLE HiiHandle,\r
77 IN BM_MENU_OPTION *MenuOption\r
78 )\r
93e3992d 79{\r
80 BM_MENU_ENTRY *NewMenuEntry;\r
81 UINTN Index;\r
82\r
83 for (Index = 0; Index < MenuOption->MenuNumber; Index++) {\r
84 NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);\r
85\r
9226efe5 86 HiiLibNewString (\r
93e3992d 87 HiiHandle,\r
88 &NewMenuEntry->DisplayStringToken,\r
89 NewMenuEntry->DisplayString\r
90 );\r
91\r
92 if (NULL == NewMenuEntry->HelpString) {\r
93 NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;\r
94 } else {\r
9226efe5 95 HiiLibNewString (\r
93e3992d 96 HiiHandle,\r
97 &NewMenuEntry->HelpStringToken,\r
98 NewMenuEntry->HelpString\r
99 );\r
100 }\r
101 }\r
102\r
103 return EFI_SUCCESS;\r
104}\r
105\r
b30312ba 106/**\r
107 This function allows a caller to extract the current configuration for one\r
108 or more named elements from the target driver.\r
109\r
110\r
111 @param This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
112 @param Request - A null-terminated Unicode string in <ConfigRequest> format.\r
113 @param Progress - On return, points to a character in the Request string.\r
114 Points to the string's null terminator if request was successful.\r
115 Points to the most recent '&' before the first failing name/value\r
116 pair (or the beginning of the string if the failure is in the\r
117 first name/value pair) if the request was not successful.\r
118 @param Results - A null-terminated Unicode string in <ConfigAltResp> format which\r
119 has all values filled in for the names in the Request string.\r
120 String to be allocated by the called function.\r
121\r
122 @retval EFI_SUCCESS The Results is filled with the requested values.\r
123 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
124 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
125 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
126\r
127**/\r
93e3992d 128EFI_STATUS\r
129EFIAPI\r
130BootMaintExtractConfig (\r
131 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
132 IN CONST EFI_STRING Request,\r
133 OUT EFI_STRING *Progress,\r
134 OUT EFI_STRING *Results\r
135 )\r
93e3992d 136{\r
137 EFI_STATUS Status;\r
138 UINTN BufferSize;\r
139 BMM_CALLBACK_DATA *Private;\r
140\r
141 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
142\r
143 //\r
144 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
145 //\r
146 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
147 Status = gHiiConfigRouting->BlockToConfig (\r
148 gHiiConfigRouting,\r
149 Request,\r
150 (UINT8 *) &Private->BmmFakeNvData,\r
151 BufferSize,\r
152 Results,\r
153 Progress\r
154 );\r
155 return Status;\r
156}\r
157\r
b30312ba 158/**\r
159 This function processes the results of changes in configuration.\r
160\r
161\r
162 @param This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
163 @param Action - Specifies the type of action taken by the browser.\r
164 @param QuestionId - A unique value which is sent to the original exporting driver\r
165 so that it can identify the type of data to expect.\r
166 @param Type - The type of value for the question.\r
167 @param Value - A pointer to the data being sent to the original exporting driver.\r
168 @param ActionRequest - On return, points to the action requested by the callback function.\r
169\r
170 @retval EFI_SUCCESS The callback successfully handled the action.\r
171 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
172 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
173 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
174\r
175**/\r
93e3992d 176EFI_STATUS\r
177EFIAPI\r
178BootMaintCallback (\r
179 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
180 IN EFI_BROWSER_ACTION Action,\r
181 IN EFI_QUESTION_ID QuestionId,\r
182 IN UINT8 Type,\r
183 IN EFI_IFR_TYPE_VALUE *Value,\r
184 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
185 )\r
93e3992d 186{\r
187 BMM_CALLBACK_DATA *Private;\r
188 BM_MENU_ENTRY *NewMenuEntry;\r
189 BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
190 EFI_STATUS Status;\r
191 UINTN OldValue;\r
192 UINTN NewValue;\r
193 UINTN Number;\r
194 UINTN Pos;\r
195 UINTN Bit;\r
196 UINT16 NewValuePos;\r
197 UINT16 Index2;\r
198 UINT16 Index;\r
199 UINT8 *OldLegacyDev;\r
200 UINT8 *NewLegacyDev;\r
201 UINT8 *DisMap;\r
202 EFI_FORM_ID FormId;\r
203 UINTN BufferSize;\r
204\r
205 if ((Value == NULL) || (ActionRequest == NULL)) {\r
206 return EFI_INVALID_PARAMETER;\r
207 }\r
208\r
209 OldValue = 0;\r
210 NewValue = 0;\r
211 Number = 0;\r
212 OldLegacyDev = NULL;\r
213 NewLegacyDev = NULL;\r
214 NewValuePos = 0;\r
215 DisMap = NULL;\r
216 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
217\r
218 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
219 UpdatePageId (Private, QuestionId);\r
220\r
221 //\r
222 // Retrive uncommitted data from Form Browser\r
223 //\r
224 CurrentFakeNVMap = &Private->BmmFakeNvData;\r
225 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
226 Status = GetBrowserData (NULL, NULL, &BufferSize, (UINT8 *) CurrentFakeNVMap);\r
227 if (EFI_ERROR (Status)) {\r
228 return Status;\r
229 }\r
230\r
231 //\r
232 // need to be subtituded.\r
233 //\r
234 // Update Select FD/HD/CD/NET/BEV Order Form\r
235 //\r
236 if (FORM_SET_FD_ORDER_ID == Private->BmmPreviousPageId ||\r
237 FORM_SET_HD_ORDER_ID == Private->BmmPreviousPageId ||\r
238 FORM_SET_CD_ORDER_ID == Private->BmmPreviousPageId ||\r
239 FORM_SET_NET_ORDER_ID == Private->BmmPreviousPageId ||\r
240 FORM_SET_BEV_ORDER_ID == Private->BmmPreviousPageId ||\r
241 ((FORM_BOOT_SETUP_ID == Private->BmmPreviousPageId) &&\r
242 (QuestionId >= LEGACY_FD_QUESTION_ID) &&\r
243 (QuestionId < (LEGACY_BEV_QUESTION_ID + 100)) )\r
244 ) {\r
245\r
246 DisMap = Private->BmmOldFakeNVData.DisableMap;\r
247\r
248 FormId = Private->BmmPreviousPageId;\r
249 if (FormId == FORM_BOOT_SETUP_ID) {\r
250 FormId = Private->BmmCurrentPageId;\r
251 }\r
252\r
253 switch (FormId) {\r
254 case FORM_SET_FD_ORDER_ID:\r
255 Number = (UINT16) LegacyFDMenu.MenuNumber;\r
256 OldLegacyDev = Private->BmmOldFakeNVData.LegacyFD;\r
257 NewLegacyDev = CurrentFakeNVMap->LegacyFD;\r
258 break;\r
259\r
260 case FORM_SET_HD_ORDER_ID:\r
261 Number = (UINT16) LegacyHDMenu.MenuNumber;\r
262 OldLegacyDev = Private->BmmOldFakeNVData.LegacyHD;\r
263 NewLegacyDev = CurrentFakeNVMap->LegacyHD;\r
264 break;\r
265\r
266 case FORM_SET_CD_ORDER_ID:\r
267 Number = (UINT16) LegacyCDMenu.MenuNumber;\r
268 OldLegacyDev = Private->BmmOldFakeNVData.LegacyCD;\r
269 NewLegacyDev = CurrentFakeNVMap->LegacyCD;\r
270 break;\r
271\r
272 case FORM_SET_NET_ORDER_ID:\r
273 Number = (UINT16) LegacyNETMenu.MenuNumber;\r
274 OldLegacyDev = Private->BmmOldFakeNVData.LegacyNET;\r
275 NewLegacyDev = CurrentFakeNVMap->LegacyNET;\r
276 break;\r
277\r
278 case FORM_SET_BEV_ORDER_ID:\r
279 Number = (UINT16) LegacyBEVMenu.MenuNumber;\r
280 OldLegacyDev = Private->BmmOldFakeNVData.LegacyBEV;\r
281 NewLegacyDev = CurrentFakeNVMap->LegacyBEV;\r
282 break;\r
283\r
284 default:\r
285 break;\r
286 }\r
287 //\r
288 // First, find the different position\r
289 // if there is change, it should be only one\r
290 //\r
291 for (Index = 0; Index < Number; Index++) {\r
292 if (OldLegacyDev[Index] != NewLegacyDev[Index]) {\r
293 OldValue = OldLegacyDev[Index];\r
294 NewValue = NewLegacyDev[Index];\r
295 break;\r
296 }\r
297 }\r
298\r
299 if (Index != Number) {\r
300 //\r
301 // there is change, now process\r
302 //\r
303 if (0xFF == NewValue) {\r
304 //\r
305 // This item will be disable\r
306 // Just move the items behind this forward to overlap it\r
307 //\r
308 Pos = OldValue / 8;\r
309 Bit = 7 - (OldValue % 8);\r
310 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));\r
311 for (Index2 = Index; Index2 < Number - 1; Index2++) {\r
312 NewLegacyDev[Index2] = NewLegacyDev[Index2 + 1];\r
313 }\r
314\r
315 NewLegacyDev[Index2] = 0xFF;\r
316 } else {\r
317 for (Index2 = 0; Index2 < Number; Index2++) {\r
318 if (Index2 == Index) {\r
319 continue;\r
320 }\r
321\r
322 if (OldLegacyDev[Index2] == NewValue) {\r
323 //\r
324 // If NewValue is in OldLegacyDev array\r
325 // remember its old position\r
326 //\r
327 NewValuePos = Index2;\r
328 break;\r
329 }\r
330 }\r
331\r
332 if (Index2 != Number) {\r
333 //\r
334 // We will change current item to an existing item\r
335 // (It's hard to describe here, please read code, it's like a cycle-moving)\r
336 //\r
337 for (Index2 = NewValuePos; Index2 != Index;) {\r
338 if (NewValuePos < Index) {\r
339 NewLegacyDev[Index2] = OldLegacyDev[Index2 + 1];\r
340 Index2++;\r
341 } else {\r
342 NewLegacyDev[Index2] = OldLegacyDev[Index2 - 1];\r
343 Index2--;\r
344 }\r
345 }\r
346 } else {\r
347 //\r
348 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item\r
349 // so we should modify DisMap to reflect the change\r
350 //\r
351 Pos = NewValue / 8;\r
352 Bit = 7 - (NewValue % 8);\r
353 DisMap[Pos] = (UINT8) (DisMap[Pos] & (~ (UINT8) (1 << Bit)));\r
354 if (0xFF != OldValue) {\r
355 //\r
356 // Because NewValue is a item that was disabled before\r
357 // so after changing the OldValue should be disabled\r
358 // actually we are doing a swap of enable-disable states of two items\r
359 //\r
360 Pos = OldValue / 8;\r
361 Bit = 7 - (OldValue % 8);\r
362 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));\r
363 }\r
364 }\r
365 }\r
366 //\r
367 // To prevent DISABLE appears in the middle of the list\r
368 // we should perform a re-ordering\r
369 //\r
370 Index = 0;\r
371 while (Index < Number) {\r
372 if (0xFF != NewLegacyDev[Index]) {\r
373 Index++;\r
374 continue;\r
375 }\r
376\r
377 Index2 = Index;\r
378 Index2++;\r
379 while (Index2 < Number) {\r
380 if (0xFF != NewLegacyDev[Index2]) {\r
381 break;\r
382 }\r
383\r
384 Index2++;\r
385 }\r
386\r
387 if (Index2 < Number) {\r
388 NewLegacyDev[Index] = NewLegacyDev[Index2];\r
389 NewLegacyDev[Index2] = 0xFF;\r
390 }\r
391\r
392 Index++;\r
393 }\r
394\r
395 CopyMem (\r
396 OldLegacyDev,\r
397 NewLegacyDev,\r
398 Number\r
399 );\r
400 }\r
401 }\r
402\r
403 if (QuestionId < FILE_OPTION_OFFSET) {\r
404 if (QuestionId < CONFIG_OPTION_OFFSET) {\r
405 switch (QuestionId) {\r
406 case KEY_VALUE_BOOT_FROM_FILE:\r
407 Private->FeCurrentState = BOOT_FROM_FILE_STATE;\r
408\r
409 //\r
410 // Exit Bmm main formset to send File Explorer formset.\r
411 //\r
412 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
413 break;\r
414\r
415 case FORM_BOOT_ADD_ID:\r
416 Private->FeCurrentState = ADD_BOOT_OPTION_STATE;\r
417\r
418 //\r
419 // Exit Bmm main formset to send File Explorer formset.\r
420 //\r
421 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
422 break;\r
423\r
424 case FORM_DRV_ADD_FILE_ID:\r
425 Private->FeCurrentState = ADD_DRIVER_OPTION_STATE;\r
426\r
427 //\r
428 // Exit Bmm main formset to send File Explorer formset.\r
429 //\r
430 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
431 break;\r
432\r
433 case FORM_DRV_ADD_HANDLE_ID:\r
434 CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);\r
435 UpdateDrvAddHandlePage (Private);\r
436 break;\r
437\r
438 case FORM_BOOT_DEL_ID:\r
439 CleanUpPage (FORM_BOOT_DEL_ID, Private);\r
440 UpdateBootDelPage (Private);\r
441 break;\r
442\r
443 case FORM_BOOT_CHG_ID:\r
444 case FORM_DRV_CHG_ID:\r
445 UpdatePageBody (QuestionId, Private);\r
446 break;\r
447\r
448 case FORM_DRV_DEL_ID:\r
449 CleanUpPage (FORM_DRV_DEL_ID, Private);\r
450 UpdateDrvDelPage (Private);\r
451 break;\r
452\r
453 case FORM_BOOT_NEXT_ID:\r
454 CleanUpPage (FORM_BOOT_NEXT_ID, Private);\r
455 UpdateBootNextPage (Private);\r
456 break;\r
457\r
458 case FORM_TIME_OUT_ID:\r
459 CleanUpPage (FORM_TIME_OUT_ID, Private);\r
460 UpdateTimeOutPage (Private);\r
461 break;\r
462\r
463 case FORM_RESET:\r
464 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
465 return EFI_UNSUPPORTED;\r
466\r
467 case FORM_CON_IN_ID:\r
468 case FORM_CON_OUT_ID:\r
469 case FORM_CON_ERR_ID:\r
470 UpdatePageBody (QuestionId, Private);\r
471 break;\r
472\r
473 case FORM_CON_MODE_ID:\r
474 CleanUpPage (FORM_CON_MODE_ID, Private);\r
475 UpdateConModePage (Private);\r
476 break;\r
477\r
478 case FORM_CON_COM_ID:\r
479 CleanUpPage (FORM_CON_COM_ID, Private);\r
480 UpdateConCOMPage (Private);\r
481 break;\r
482\r
483 case FORM_SET_FD_ORDER_ID:\r
484 case FORM_SET_HD_ORDER_ID:\r
485 case FORM_SET_CD_ORDER_ID:\r
486 case FORM_SET_NET_ORDER_ID:\r
487 case FORM_SET_BEV_ORDER_ID:\r
488 CleanUpPage (QuestionId, Private);\r
489 UpdateSetLegacyDeviceOrderPage (QuestionId, Private);\r
490 break;\r
491\r
492 case KEY_VALUE_SAVE_AND_EXIT:\r
493 case KEY_VALUE_NO_SAVE_AND_EXIT:\r
494\r
495 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {\r
496 Status = ApplyChangeHandler (Private, CurrentFakeNVMap, Private->BmmPreviousPageId);\r
497 if (EFI_ERROR (Status)) {\r
498 return Status;\r
499 }\r
500 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {\r
501 DiscardChangeHandler (Private, CurrentFakeNVMap);\r
502 }\r
503\r
504 //\r
505 // Tell browser not to ask for confirmation of changes,\r
506 // since we have already applied or discarded.\r
507 //\r
508 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
509 break;\r
510\r
511 default:\r
512 break;\r
513 }\r
514 } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {\r
515 Index2 = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);\r
516 Private->CurrentTerminal = Index2;\r
517\r
518 CleanUpPage (FORM_CON_COM_SETUP_ID, Private);\r
519 UpdateTerminalPage (Private);\r
520\r
521 } else if (QuestionId >= HANDLE_OPTION_OFFSET) {\r
522 Index2 = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);\r
523\r
524 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index2);\r
525 ASSERT (NewMenuEntry != NULL);\r
526 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;\r
527\r
528 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);\r
529\r
530 Private->MenuEntry = NewMenuEntry;\r
531 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;\r
532\r
533 UpdateDriverAddHandleDescPage (Private);\r
534 }\r
535 }\r
536\r
537 //\r
538 // Pass changed uncommitted data back to Form Browser\r
539 //\r
540 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
541 Status = SetBrowserData (NULL, NULL, BufferSize, (UINT8 *) CurrentFakeNVMap, NULL);\r
542\r
543 return Status;\r
544}\r
545\r
b30312ba 546/**\r
547 Function handling request to apply changes for BMM pages.\r
548\r
549\r
550 @param Private - Pointer to callback data buffer.\r
551 @param CurrentFakeNVMap - Pointer to buffer holding data of various values used by BMM\r
552 @param FormId - ID of the form which has sent the request to apply change.\r
553\r
554 @retval EFI_SUCCESS Change successfully applied.\r
555 @retval Other Error occurs while trying to apply changes.\r
556\r
557**/\r
93e3992d 558EFI_STATUS\r
559ApplyChangeHandler (\r
560 IN BMM_CALLBACK_DATA *Private,\r
561 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap,\r
562 IN EFI_FORM_ID FormId\r
563 )\r
93e3992d 564{\r
565 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
566 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
567 BM_LOAD_CONTEXT *NewLoadContext;\r
568 BM_MENU_ENTRY *NewMenuEntry;\r
569 EFI_STATUS Status;\r
570 UINT16 Index;\r
571\r
572 Status = EFI_SUCCESS;\r
573\r
574 switch (FormId) {\r
575 case FORM_SET_FD_ORDER_ID:\r
576 case FORM_SET_HD_ORDER_ID:\r
577 case FORM_SET_CD_ORDER_ID:\r
578 case FORM_SET_NET_ORDER_ID:\r
579 case FORM_SET_BEV_ORDER_ID:\r
580 Var_UpdateBBSOption (Private);\r
581 break;\r
582\r
583 case FORM_BOOT_DEL_ID:\r
584 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
585 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
586 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
587 NewLoadContext->Deleted = CurrentFakeNVMap->BootOptionDel[Index];\r
588 }\r
589\r
590 Var_DelBootOption ();\r
591 break;\r
592\r
593 case FORM_DRV_DEL_ID:\r
594 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
595 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
596 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
597 NewLoadContext->Deleted = CurrentFakeNVMap->DriverOptionDel[Index];\r
598 }\r
599\r
600 Var_DelDriverOption ();\r
601 break;\r
602\r
603 case FORM_BOOT_CHG_ID:\r
604 Status = Var_UpdateBootOrder (Private);\r
605 break;\r
606\r
607 case FORM_DRV_CHG_ID:\r
608 Status = Var_UpdateDriverOrder (Private);\r
609 break;\r
610\r
611 case FORM_TIME_OUT_ID:\r
612 Status = gRT->SetVariable (\r
613 L"Timeout",\r
614 &gEfiGlobalVariableGuid,\r
615 VAR_FLAG,\r
616 sizeof (UINT16),\r
617 &(CurrentFakeNVMap->BootTimeOut)\r
618 );\r
619 if (EFI_ERROR (Status)) {\r
620 goto Error;\r
621 }\r
622\r
623 Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;\r
624 break;\r
625\r
626 case FORM_BOOT_NEXT_ID:\r
627 Status = Var_UpdateBootNext (Private);\r
628 break;\r
629\r
630 case FORM_CON_MODE_ID:\r
631 Status = Var_UpdateConMode (Private);\r
632 break;\r
633\r
634 case FORM_CON_COM_SETUP_ID:\r
635 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal);\r
636\r
637 ASSERT (NewMenuEntry != NULL);\r
638\r
639 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
640\r
641 NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate;\r
642 NewTerminalContext->BaudRate = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value;\r
643 NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate;\r
644 NewTerminalContext->DataBits = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value;\r
645 NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits;\r
646 NewTerminalContext->StopBits = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value;\r
647 NewTerminalContext->ParityIndex = CurrentFakeNVMap->COMParity;\r
648 NewTerminalContext->Parity = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value;\r
649 NewTerminalContext->TerminalType = CurrentFakeNVMap->COMTerminalType;\r
650\r
651 ChangeTerminalDevicePath (\r
652 NewTerminalContext->DevicePath,\r
653 FALSE\r
654 );\r
655\r
656 Var_UpdateConsoleInpOption ();\r
657 Var_UpdateConsoleOutOption ();\r
658 Var_UpdateErrorOutOption ();\r
659 break;\r
660\r
661 case FORM_CON_IN_ID:\r
662 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {\r
663 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);\r
664 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
665 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
666 }\r
667\r
668 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
669 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
670 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
671 NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber];\r
672 }\r
673\r
674 Var_UpdateConsoleInpOption ();\r
675 break;\r
676\r
677 case FORM_CON_OUT_ID:\r
678 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {\r
679 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);\r
680 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
681 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
682 }\r
683\r
684 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
685 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
686 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
687 NewTerminalContext->IsConOut = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber];\r
688 }\r
689\r
690 Var_UpdateConsoleOutOption ();\r
691 break;\r
692\r
693 case FORM_CON_ERR_ID:\r
694 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {\r
695 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);\r
696 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
697 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
698 }\r
699\r
700 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
701 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
702 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
703 NewTerminalContext->IsStdErr = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber];\r
704 }\r
705\r
706 Var_UpdateErrorOutOption ();\r
707 break;\r
708\r
709 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
710 Status = Var_UpdateDriverOption (\r
711 Private,\r
712 Private->BmmHiiHandle,\r
713 CurrentFakeNVMap->DriverAddHandleDesc,\r
714 CurrentFakeNVMap->DriverAddHandleOptionalData,\r
715 CurrentFakeNVMap->DriverAddForceReconnect\r
716 );\r
717 if (EFI_ERROR (Status)) {\r
718 goto Error;\r
719 }\r
720\r
721 BOpt_GetDriverOptions (Private);\r
722 CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);\r
723 break;\r
724\r
725 default:\r
726 break;\r
727 }\r
728\r
729Error:\r
730 return Status;\r
731}\r
732\r
b30312ba 733/**\r
dce655e8 734 Discard all changes done to the BMM pages such as Boot Order change,\r
735 Driver order change.\r
b30312ba 736\r
dce655e8 737 @param Private The BMM context data.\r
738 @param CurrentFakeNVMap The current Fack NV Map.\r
b30312ba 739\r
dce655e8 740 @return VOID\r
b30312ba 741\r
742**/\r
93e3992d 743VOID\r
744DiscardChangeHandler (\r
745 IN BMM_CALLBACK_DATA *Private,\r
746 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap\r
747 )\r
748{\r
749 UINT16 Index;\r
750\r
751 switch (Private->BmmPreviousPageId) {\r
752 case FORM_BOOT_CHG_ID:\r
753 case FORM_DRV_CHG_ID:\r
754 CopyMem (CurrentFakeNVMap->OptionOrder, Private->BmmOldFakeNVData.OptionOrder, 100);\r
755 break;\r
756\r
757 case FORM_BOOT_DEL_ID:\r
758 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
759 CurrentFakeNVMap->BootOptionDel[Index] = 0x00;\r
760 }\r
761 break;\r
762\r
763 case FORM_DRV_DEL_ID:\r
764 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
765 CurrentFakeNVMap->DriverOptionDel[Index] = 0x00;\r
766 }\r
767 break;\r
768\r
769 case FORM_BOOT_NEXT_ID:\r
770 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;\r
771 break;\r
772\r
773 case FORM_TIME_OUT_ID:\r
774 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;\r
775 break;\r
776\r
777 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
778 case FORM_DRV_ADD_FILE_ID:\r
779 case FORM_DRV_ADD_HANDLE_ID:\r
780 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;\r
781 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;\r
782 break;\r
783\r
784 default:\r
785 break;\r
786 }\r
787}\r
788\r
b30312ba 789/**\r
93e3992d 790 Initialize the Boot Maintenance Utitliy\r
791\r
93e3992d 792\r
b30312ba 793 @param VOID EDES_TODO: Add parameter description\r
93e3992d 794\r
b30312ba 795 @retval EFI_SUCCESS utility ended successfully\r
796 @retval others contain some errors\r
797\r
798**/\r
799EFI_STATUS\r
800InitializeBM (\r
801 VOID\r
802 )\r
93e3992d 803{\r
804 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
805 EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
806 BMM_CALLBACK_DATA *BmmCallbackInfo;\r
807 EFI_STATUS Status;\r
808 UINT8 *Ptr;\r
809\r
810 Status = EFI_SUCCESS;\r
811\r
812 //\r
813 // Create CallbackData structures for Driver Callback\r
814 //\r
dce655e8 815 BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));\r
93e3992d 816 if (BmmCallbackInfo == NULL) {\r
817 return EFI_OUT_OF_RESOURCES;\r
818 }\r
819\r
820 //\r
821 // Create LoadOption in BmmCallbackInfo for Driver Callback\r
822 //\r
dce655e8 823 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));\r
a78b08d1 824 if (Ptr == NULL) {\r
93e3992d 825 SafeFreePool (BmmCallbackInfo);\r
826 return EFI_OUT_OF_RESOURCES;\r
827 }\r
828\r
829 //\r
830 // Initialize Bmm callback data.\r
831 //\r
832 BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;\r
833 Ptr += sizeof (BM_LOAD_CONTEXT);\r
834\r
835 BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;\r
836 Ptr += sizeof (BM_FILE_CONTEXT);\r
837\r
838 BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;\r
839 Ptr += sizeof (BM_HANDLE_CONTEXT);\r
840\r
841 BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;\r
842\r
843 BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;\r
844 BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;\r
845 BmmCallbackInfo->BmmConfigAccess.RouteConfig = FakeRouteConfig;\r
846 BmmCallbackInfo->BmmConfigAccess.Callback = BootMaintCallback;\r
847 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;\r
848 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;\r
849 BmmCallbackInfo->FeConfigAccess.ExtractConfig = FakeExtractConfig;\r
850 BmmCallbackInfo->FeConfigAccess.RouteConfig = FakeRouteConfig;\r
851 BmmCallbackInfo->FeConfigAccess.Callback = FileExplorerCallback;\r
852 BmmCallbackInfo->FeCurrentState = INACTIVE_STATE;\r
853 BmmCallbackInfo->FeDisplayContext = UNKNOWN_CONTEXT;\r
854\r
855 //\r
856 // Create driver handle used by HII database\r
857 //\r
858 Status = HiiLibCreateHiiDriverHandle (&BmmCallbackInfo->BmmDriverHandle);\r
859 if (EFI_ERROR (Status)) {\r
860 return Status;\r
861 }\r
862\r
863 //\r
864 // Install Config Access protocol to driver handle\r
865 //\r
866 Status = gBS->InstallProtocolInterface (\r
867 &BmmCallbackInfo->BmmDriverHandle,\r
868 &gEfiHiiConfigAccessProtocolGuid,\r
869 EFI_NATIVE_INTERFACE,\r
870 &BmmCallbackInfo->BmmConfigAccess\r
871 );\r
872 if (EFI_ERROR (Status)) {\r
873 return Status;\r
874 }\r
875\r
876 //\r
877 // Create driver handle used by HII database\r
878 //\r
879 Status = HiiLibCreateHiiDriverHandle (&BmmCallbackInfo->FeDriverHandle);\r
880 if (EFI_ERROR (Status)) {\r
881 return Status;\r
882 }\r
883\r
884 //\r
885 // Install Config Access protocol to driver handle\r
886 //\r
887 Status = gBS->InstallProtocolInterface (\r
888 &BmmCallbackInfo->FeDriverHandle,\r
889 &gEfiHiiConfigAccessProtocolGuid,\r
890 EFI_NATIVE_INTERFACE,\r
891 &BmmCallbackInfo->FeConfigAccess\r
892 );\r
893 if (EFI_ERROR (Status)) {\r
894 return Status;\r
895 }\r
896\r
897 //\r
898 // Post our Boot Maint VFR binnary to the HII database.\r
899 //\r
062539cf 900 PackageList = HiiLibPreparePackageList (2, &mBootMaintGuid, BmBin, BdsDxeStrings);\r
93e3992d 901 ASSERT (PackageList != NULL);\r
902\r
903 Status = gHiiDatabase->NewPackageList (\r
904 gHiiDatabase,\r
905 PackageList,\r
906 BmmCallbackInfo->BmmDriverHandle,\r
907 &BmmCallbackInfo->BmmHiiHandle\r
908 );\r
909 FreePool (PackageList);\r
910\r
911 //\r
912 // Post our File Explorer VFR binary to the HII database.\r
913 //\r
062539cf 914 PackageList = HiiLibPreparePackageList (2, &mFileExplorerGuid, FEBin, BdsDxeStrings);\r
93e3992d 915 ASSERT (PackageList != NULL);\r
916\r
917 Status = gHiiDatabase->NewPackageList (\r
918 gHiiDatabase,\r
919 PackageList,\r
920 BmmCallbackInfo->FeDriverHandle,\r
921 &BmmCallbackInfo->FeHiiHandle\r
922 );\r
923 FreePool (PackageList);\r
924\r
925 //\r
926 // Allocate space for creation of Buffer\r
927 //\r
928 gUpdateData.BufferSize = UPDATE_DATA_SIZE;\r
dce655e8 929 gUpdateData.Data = AllocateZeroPool (UPDATE_DATA_SIZE);\r
93e3992d 930 if (gUpdateData.Data == NULL) {\r
931 SafeFreePool (BmmCallbackInfo->LoadContext);\r
932 SafeFreePool (BmmCallbackInfo);\r
933 return EFI_OUT_OF_RESOURCES;\r
934 }\r
935\r
936 InitializeStringDepository ();\r
937\r
938 InitAllMenu (BmmCallbackInfo);\r
939\r
940 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);\r
941 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);\r
942 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);\r
943 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);\r
944 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);\r
945 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);\r
946 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);\r
947\r
948 UpdateBootDelPage (BmmCallbackInfo);\r
949 UpdateDrvDelPage (BmmCallbackInfo);\r
950\r
951 if (TerminalMenu.MenuNumber > 0) {\r
952 BmmCallbackInfo->CurrentTerminal = 0;\r
953 UpdateTerminalPage (BmmCallbackInfo);\r
954 }\r
955\r
956 Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);\r
957 if (!EFI_ERROR (Status)) {\r
958 RefreshUpdateData ();\r
959\r
960 //\r
961 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option\r
962 // in BootOption form: legacy FD/HD/CD/NET/BEV\r
963 //\r
964 CreateGotoOpCode (\r
965 FORM_SET_FD_ORDER_ID,\r
966 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
967 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
968 EFI_IFR_FLAG_CALLBACK,\r
969 FORM_SET_FD_ORDER_ID,\r
970 &gUpdateData\r
971 );\r
972\r
973 CreateGotoOpCode (\r
974 FORM_SET_HD_ORDER_ID,\r
975 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
976 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
977 EFI_IFR_FLAG_CALLBACK,\r
978 FORM_SET_HD_ORDER_ID,\r
979 &gUpdateData\r
980 );\r
981\r
982 CreateGotoOpCode (\r
983 FORM_SET_CD_ORDER_ID,\r
984 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
985 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
986 EFI_IFR_FLAG_CALLBACK,\r
987 FORM_SET_CD_ORDER_ID,\r
988 &gUpdateData\r
989 );\r
990\r
991 CreateGotoOpCode (\r
992 FORM_SET_NET_ORDER_ID,\r
993 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
994 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
995 EFI_IFR_FLAG_CALLBACK,\r
996 FORM_SET_NET_ORDER_ID,\r
997 &gUpdateData\r
998 );\r
999\r
1000 CreateGotoOpCode (\r
1001 FORM_SET_BEV_ORDER_ID,\r
1002 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
1003 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
1004 EFI_IFR_FLAG_CALLBACK,\r
1005 FORM_SET_BEV_ORDER_ID,\r
1006 &gUpdateData\r
1007 );\r
1008\r
1009 IfrLibUpdateForm (\r
1010 BmmCallbackInfo->BmmHiiHandle,\r
1011 &mBootMaintGuid,\r
1012 FORM_MAIN_ID,\r
1013 FORM_BOOT_LEGACY_DEVICE_ID,\r
1014 FALSE,\r
1015 &gUpdateData\r
1016 );\r
1017 }\r
1018\r
1019 //\r
1020 // Dispatch BMM main formset and File Explorer formset.\r
1021 //\r
1022 FormSetDispatcher (BmmCallbackInfo);\r
1023\r
1024 //\r
1025 // Remove our IFR data from HII database\r
1026 //\r
1027 gHiiDatabase->RemovePackageList (gHiiDatabase, BmmCallbackInfo->BmmHiiHandle);\r
1028 gHiiDatabase->RemovePackageList (gHiiDatabase, BmmCallbackInfo->FeHiiHandle);\r
1029\r
1030 CleanUpStringDepository ();\r
1031\r
1032 FreeAllMenu ();\r
1033\r
1034 SafeFreePool (BmmCallbackInfo->LoadContext);\r
1035 SafeFreePool (BmmCallbackInfo);\r
1036 SafeFreePool (gUpdateData.Data);\r
1037 gUpdateData.Data = NULL;\r
1038\r
1039 return Status;\r
1040}\r
1041\r
b30312ba 1042/**\r
dce655e8 1043 Initialized all Menu Option List.\r
b30312ba 1044\r
dce655e8 1045 @param CallbackData The BMM context data.\r
b30312ba 1046\r
dce655e8 1047 @return VOID\r
b30312ba 1048\r
1049**/\r
93e3992d 1050VOID\r
1051InitAllMenu (\r
1052 IN BMM_CALLBACK_DATA *CallbackData\r
1053 )\r
1054{\r
1055 InitializeListHead (&BootOptionMenu.Head);\r
1056 InitializeListHead (&DriverOptionMenu.Head);\r
1057 BOpt_GetBootOptions (CallbackData);\r
1058 BOpt_GetDriverOptions (CallbackData);\r
1059 BOpt_GetLegacyOptions ();\r
1060 InitializeListHead (&FsOptionMenu.Head);\r
1061 BOpt_FindDrivers ();\r
1062 InitializeListHead (&DirectoryMenu.Head);\r
1063 InitializeListHead (&ConsoleInpMenu.Head);\r
1064 InitializeListHead (&ConsoleOutMenu.Head);\r
1065 InitializeListHead (&ConsoleErrMenu.Head);\r
1066 InitializeListHead (&TerminalMenu.Head);\r
1067 LocateSerialIo ();\r
1068 GetAllConsoles ();\r
1069}\r
1070\r
b30312ba 1071/**\r
dce655e8 1072 Free up all Menu Option list.\r
b30312ba 1073\r
dce655e8 1074 @param VOID\r
b30312ba 1075\r
dce655e8 1076 @return VOID\r
b30312ba 1077\r
1078**/\r
93e3992d 1079VOID\r
1080FreeAllMenu (\r
1081 VOID\r
1082 )\r
1083{\r
1084 BOpt_FreeMenu (&DirectoryMenu);\r
1085 BOpt_FreeMenu (&FsOptionMenu);\r
1086 BOpt_FreeMenu (&BootOptionMenu);\r
1087 BOpt_FreeMenu (&DriverOptionMenu);\r
1088 BOpt_FreeMenu (&DriverMenu);\r
1089 BOpt_FreeLegacyOptions ();\r
1090 FreeAllConsoles ();\r
1091}\r
1092\r
b30312ba 1093/**\r
93e3992d 1094 Intialize all the string depositories.\r
1095\r
93e3992d 1096\r
dce655e8 1097 @param VOID\r
b30312ba 1098\r
dce655e8 1099 @return VOID\r
93e3992d 1100\r
b30312ba 1101**/\r
1102VOID\r
1103InitializeStringDepository (\r
1104 VOID\r
1105 )\r
93e3992d 1106{\r
1107 STRING_DEPOSITORY *StringDepository;\r
dce655e8 1108 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);\r
93e3992d 1109 FileOptionStrDepository = StringDepository++;\r
1110 ConsoleOptionStrDepository = StringDepository++;\r
1111 BootOptionStrDepository = StringDepository++;\r
1112 BootOptionHelpStrDepository = StringDepository++;\r
1113 DriverOptionStrDepository = StringDepository++;\r
1114 DriverOptionHelpStrDepository = StringDepository++;\r
1115 TerminalStrDepository = StringDepository;\r
1116}\r
1117\r
b30312ba 1118/**\r
1119 Fetch a usable string node from the string depository and return the string token.\r
1120\r
1121\r
1122 @param CallbackData EDES_TODO: Add parameter description\r
1123 @param StringDepository - Pointer of the string depository.\r
1124\r
1125 @retval EFI_STRING_ID String token.\r
1126\r
1127**/\r
93e3992d 1128EFI_STRING_ID\r
1129GetStringTokenFromDepository (\r
1130 IN BMM_CALLBACK_DATA *CallbackData,\r
1131 IN STRING_DEPOSITORY *StringDepository\r
1132 )\r
93e3992d 1133{\r
1134 STRING_LIST_NODE *CurrentListNode;\r
1135 STRING_LIST_NODE *NextListNode;\r
1136\r
1137 CurrentListNode = StringDepository->CurrentNode;\r
1138\r
1139 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {\r
1140 //\r
1141 // Fetch one reclaimed node from the list.\r
1142 //\r
1143 NextListNode = StringDepository->CurrentNode->Next;\r
1144 } else {\r
1145 //\r
1146 // If there is no usable node in the list, update the list.\r
1147 //\r
dce655e8 1148 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));\r
93e3992d 1149\r
9226efe5 1150 HiiLibNewString (CallbackData->BmmHiiHandle, &(NextListNode->StringToken), L" ");\r
93e3992d 1151 ASSERT (NextListNode->StringToken != 0);\r
1152\r
1153 StringDepository->TotalNodeNumber++;\r
1154\r
1155 if (NULL == CurrentListNode) {\r
1156 StringDepository->ListHead = NextListNode;\r
1157 } else {\r
1158 CurrentListNode->Next = NextListNode;\r
1159 }\r
1160 }\r
1161\r
1162 StringDepository->CurrentNode = NextListNode;\r
1163\r
1164 return StringDepository->CurrentNode->StringToken;\r
1165}\r
1166\r
b30312ba 1167/**\r
93e3992d 1168 Reclaim string depositories by moving the current node pointer to list head..\r
1169\r
93e3992d 1170\r
dce655e8 1171 @param VOID \r
b30312ba 1172\r
dce655e8 1173 @return VOID\r
93e3992d 1174\r
b30312ba 1175**/\r
1176VOID\r
1177ReclaimStringDepository (\r
1178 VOID\r
1179 )\r
93e3992d 1180{\r
1181 UINTN DepositoryIndex;\r
1182 STRING_DEPOSITORY *StringDepository;\r
1183\r
1184 StringDepository = FileOptionStrDepository;\r
1185 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1186 StringDepository->CurrentNode = StringDepository->ListHead;\r
1187 StringDepository++;\r
1188 }\r
1189}\r
1190\r
b30312ba 1191/**\r
93e3992d 1192 Release resource for all the string depositories.\r
1193\r
93e3992d 1194\r
dce655e8 1195 @param VOID\r
93e3992d 1196\r
dce655e8 1197 @return VOID\r
b30312ba 1198\r
1199**/\r
1200VOID\r
1201CleanUpStringDepository (\r
1202 VOID\r
1203 )\r
93e3992d 1204{\r
1205 UINTN NodeIndex;\r
1206 UINTN DepositoryIndex;\r
1207 STRING_LIST_NODE *CurrentListNode;\r
1208 STRING_LIST_NODE *NextListNode;\r
1209 STRING_DEPOSITORY *StringDepository;\r
1210\r
1211 //\r
1212 // Release string list nodes.\r
1213 //\r
1214 StringDepository = FileOptionStrDepository;\r
1215 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1216 CurrentListNode = StringDepository->ListHead;\r
1217 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {\r
1218 NextListNode = CurrentListNode->Next;\r
1219 SafeFreePool (CurrentListNode);\r
1220 CurrentListNode = NextListNode;\r
1221 }\r
1222\r
1223 StringDepository++;\r
1224 }\r
1225 //\r
1226 // Release string depository.\r
1227 //\r
1228 SafeFreePool (FileOptionStrDepository);\r
1229}\r
1230\r
b30312ba 1231/**\r
93e3992d 1232 Start boot maintenance manager\r
1233\r
93e3992d 1234\r
dce655e8 1235 @param VOID\r
b30312ba 1236\r
dce655e8 1237 @retval EFI_SUCCESS If BMM is invoked successfully.\r
1238 @return Other value if BMM return unsuccessfully.\r
93e3992d 1239\r
b30312ba 1240**/\r
1241EFI_STATUS\r
1242BdsStartBootMaint (\r
1243 VOID\r
1244 )\r
93e3992d 1245{\r
1246 EFI_STATUS Status;\r
1247 LIST_ENTRY BdsBootOptionList;\r
1248\r
1249 InitializeListHead (&BdsBootOptionList);\r
1250\r
1251 //\r
1252 // Connect all prior to entering the platform setup menu.\r
1253 //\r
1254 if (!gConnectAllHappened) {\r
1255 BdsLibConnectAllDriversToAllControllers ();\r
1256 gConnectAllHappened = TRUE;\r
1257 }\r
1258 //\r
1259 // Have chance to enumerate boot device\r
1260 //\r
1261 BdsLibEnumerateAllBootOption (&BdsBootOptionList);\r
1262\r
1263 //\r
1264 // Drop the TPL level from TPL_APPLICATION to TPL_APPLICATION\r
1265 //\r
1266 gBS->RestoreTPL (TPL_APPLICATION);\r
1267\r
1268 //\r
1269 // Init the BMM\r
1270 //\r
1271 Status = InitializeBM ();\r
1272\r
1273 //\r
1274 // Raise the TPL level back to TPL_APPLICATION\r
1275 //\r
1276 gBS->RaiseTPL (TPL_APPLICATION);\r
1277\r
1278 return Status;\r
1279}\r
1280\r
b30312ba 1281/**\r
93e3992d 1282 Dispatch BMM formset and FileExplorer formset.\r
1283\r
93e3992d 1284\r
dce655e8 1285 @param CallbackData The BMM context data.\r
93e3992d 1286\r
dce655e8 1287 @retval EFI_SUCCESS If function complete successfully.\r
1288 @retturn Other value if the Setup Browser process BMM's pages and\r
1289 return unsuccessfully.\r
b30312ba 1290\r
1291**/\r
1292EFI_STATUS\r
1293FormSetDispatcher (\r
1294 IN BMM_CALLBACK_DATA *CallbackData\r
1295 )\r
93e3992d 1296{\r
1297 EFI_STATUS Status;\r
1298 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
1299\r
1300 while (TRUE) {\r
1301 UpdatePageId (CallbackData, FORM_MAIN_ID);\r
1302\r
1303 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
1304 Status = gFormBrowser2->SendForm (\r
1305 gFormBrowser2,\r
1306 &CallbackData->BmmHiiHandle,\r
1307 1,\r
1308 NULL,\r
1309 0,\r
1310 NULL,\r
1311 &ActionRequest\r
1312 );\r
1313 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
1314 EnableResetRequired ();\r
1315 }\r
1316\r
1317 ReclaimStringDepository ();\r
1318\r
1319 //\r
1320 // When this Formset returns, check if we are going to explore files.\r
1321 //\r
1322 if (INACTIVE_STATE != CallbackData->FeCurrentState) {\r
1323 UpdateFileExplorer (CallbackData, 0);\r
1324\r
1325 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
1326 Status = gFormBrowser2->SendForm (\r
1327 gFormBrowser2,\r
1328 &CallbackData->FeHiiHandle,\r
1329 1,\r
1330 NULL,\r
1331 0,\r
1332 NULL,\r
1333 &ActionRequest\r
1334 );\r
1335 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
1336 EnableResetRequired ();\r
1337 }\r
1338\r
1339 CallbackData->FeCurrentState = INACTIVE_STATE;\r
1340 CallbackData->FeDisplayContext = UNKNOWN_CONTEXT;\r
1341 ReclaimStringDepository ();\r
1342 } else {\r
1343 break;\r
1344 }\r
1345 }\r
1346\r
1347 return Status;\r
1348}\r
1349\r
dce655e8 1350\r
1351/**\r
1352 Deletete the Boot Option from EFI Variable. The Boot Order Arrray\r
1353 is also updated.\r
1354\r
1355 @param OptionNumber EDES_TODO: Add parameter description\r
1356 @param BootOrder The Boot Order array.\r
1357 @param BootOrderSize The size of the Boot Order Array.\r
1358\r
1359 @return Other value if the Boot Option specified by OptionNumber is not deleteed succesfully.\r
1360 @retval EFI_SUCCESS If function return successfully.\r
1361\r
1362**/\r
1363EFI_STATUS\r
1364BdsDeleteBootOption (\r
1365 IN UINTN OptionNumber,\r
1366 IN OUT UINT16 *BootOrder,\r
1367 IN OUT UINTN *BootOrderSize\r
1368 )\r
1369{\r
1370 UINT16 BootOption[100];\r
1371 UINTN Index;\r
1372 EFI_STATUS Status;\r
1373 UINTN Index2Del;\r
1374\r
1375 Status = EFI_SUCCESS;\r
1376 Index2Del = 0;\r
1377\r
1378 UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber);\r
1379 Status = EfiLibDeleteVariable (BootOption, &gEfiGlobalVariableGuid);\r
1380 //\r
1381 // adjust boot order array\r
1382 //\r
1383 for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {\r
1384 if (BootOrder[Index] == OptionNumber) {\r
1385 Index2Del = Index;\r
1386 break;\r
1387 }\r
1388 }\r
1389\r
1390 if (Index != *BootOrderSize / sizeof (UINT16)) {\r
1391 for (Index = 0; Index < *BootOrderSize / sizeof (UINT16) - 1; Index++) {\r
1392 if (Index >= Index2Del) {\r
1393 BootOrder[Index] = BootOrder[Index + 1];\r
1394 }\r
1395 }\r
1396\r
1397 *BootOrderSize -= sizeof (UINT16);\r
1398 }\r
1399\r
1400 return Status;\r
1401\r
1402}\r
1403\r
1404\r