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