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