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