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