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