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