]> git.proxmox.com Git - mirror_edk2.git/blame - EdkUnixPkg/Dxe/PlatformBds/Generic/BootMaint/BootMaint.c
newline added at end
[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
ad2baeff 452 ASSERT (NewMenuEntry != NULL);\r
c9093a06 453 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;\r
454\r
455 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);\r
456\r
457 Private->MenuEntry = NewMenuEntry;\r
458 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;\r
459\r
460 UpdateDriverAddHandleDescPage (Private);\r
461 }\r
462 }\r
463\r
464 return EFI_SUCCESS;\r
465}\r
466\r
467EFI_STATUS\r
468ApplyChangeHandler (\r
469 IN BMM_CALLBACK_DATA *Private,\r
470 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap,\r
471 IN FORM_ID FormId\r
472 )\r
473/*++\r
474\r
475Routine Description:\r
476\r
477 Function handling request to apply changes for BMM pages.\r
478\r
479Arguments:\r
480\r
481 Private - Pointer to callback data buffer.\r
482 CurrentFakeNVMap - Pointer to buffer holding data of various values used by BMM\r
483 FormId - ID of the form which has sent the request to apply change.\r
484\r
485Returns:\r
486\r
487 EFI_SUCCESS - Change successfully applied.\r
488 Other - Error occurs while trying to apply changes.\r
489\r
490--*/\r
491{\r
492 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
493 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
494 BM_LOAD_CONTEXT *NewLoadContext;\r
495 BM_MENU_ENTRY *NewMenuEntry;\r
496 EFI_STATUS Status;\r
497 UINT16 Index;\r
498\r
499 Status = EFI_SUCCESS;\r
500\r
501 switch (FormId) {\r
502 case FORM_SET_FD_ORDER_ID:\r
503 case FORM_SET_HD_ORDER_ID:\r
504 case FORM_SET_CD_ORDER_ID:\r
505 case FORM_SET_NET_ORDER_ID:\r
506 case FORM_SET_BEV_ORDER_ID:\r
507 Var_UpdateBBSOption (Private);\r
508 break;\r
509\r
510 case FORM_BOOT_DEL_ID:\r
511 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
512 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
513 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
514 NewLoadContext->Deleted = CurrentFakeNVMap->BootOptionDel[Index];\r
515 }\r
516\r
517 Var_DelBootOption ();\r
518 break;\r
519\r
520 case FORM_DRV_DEL_ID:\r
521 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
522 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
523 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
524 NewLoadContext->Deleted = CurrentFakeNVMap->DriverOptionDel[Index];\r
525 }\r
526\r
527 Var_DelDriverOption ();\r
528 break;\r
529\r
530 case FORM_BOOT_CHG_ID:\r
531 Status = Var_UpdateBootOrder (Private);\r
532 break;\r
533\r
534 case FORM_DRV_CHG_ID:\r
535 Status = Var_UpdateDriverOrder (Private);\r
536 break;\r
537\r
538 case FORM_TIME_OUT_ID:\r
539 Status = gRT->SetVariable (\r
540 L"Timeout",\r
541 &gEfiGlobalVariableGuid,\r
542 VAR_FLAG,\r
543 sizeof (UINT16),\r
544 &(CurrentFakeNVMap->BootTimeOut)\r
545 );\r
546 if (EFI_ERROR (Status)) {\r
547 goto Error;\r
548 }\r
549\r
550 Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;\r
551 break;\r
552\r
553 case FORM_BOOT_NEXT_ID:\r
554 Status = Var_UpdateBootNext (Private);\r
555 break;\r
556\r
557 case FORM_CON_COM_ID:\r
558 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal);\r
559\r
ad2baeff 560 ASSERT (NewMenuEntry != NULL);\r
561\r
c9093a06 562 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
563\r
564 NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate;\r
565 NewTerminalContext->BaudRate = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value;\r
566 NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate;\r
567 NewTerminalContext->DataBits = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value;\r
568 NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits;\r
569 NewTerminalContext->StopBits = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value;\r
570 NewTerminalContext->ParityIndex = CurrentFakeNVMap->COMParity;\r
571 NewTerminalContext->Parity = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value;\r
572 NewTerminalContext->TerminalType = CurrentFakeNVMap->COMTerminalType;\r
573\r
574 ChangeTerminalDevicePath (\r
575 NewTerminalContext->DevicePath,\r
576 FALSE\r
577 );\r
578\r
579 Var_UpdateConsoleInpOption ();\r
580 Var_UpdateConsoleOutOption ();\r
581 Var_UpdateErrorOutOption ();\r
582 break;\r
583\r
584 case FORM_CON_IN_ID:\r
585 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {\r
586 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);\r
587 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
588 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
589 }\r
590\r
591 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
592 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
593 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
594 NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber];\r
595 }\r
596\r
597 Var_UpdateConsoleInpOption ();\r
598 break;\r
599\r
600 case FORM_CON_OUT_ID:\r
601 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {\r
602 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);\r
603 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
604 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
605 }\r
606\r
607 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
608 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
609 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
610 NewTerminalContext->IsConOut = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber];\r
611 }\r
612\r
613 Var_UpdateConsoleOutOption ();\r
614 break;\r
615\r
616 case FORM_CON_ERR_ID:\r
617 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {\r
618 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);\r
619 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
620 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
621 }\r
622\r
623 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
624 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
625 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
626 NewTerminalContext->IsStdErr = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber];\r
627 }\r
628\r
629 Var_UpdateErrorOutOption ();\r
630 break;\r
631\r
632 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
633 Status = Var_UpdateDriverOption (\r
634 Private,\r
635 Private->BmmHiiHandle,\r
636 CurrentFakeNVMap->DriverAddHandleDesc,\r
637 CurrentFakeNVMap->DriverAddHandleOptionalData,\r
638 CurrentFakeNVMap->DriverAddForceReconnect\r
639 );\r
640 if (EFI_ERROR (Status)) {\r
641 goto Error;\r
642 }\r
643\r
644 BOpt_GetDriverOptions (Private);\r
645 CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);\r
646 break;\r
647\r
648 default:\r
649 break;\r
650 }\r
651\r
652Error:\r
653 return Status;\r
654}\r
655\r
656VOID\r
657DiscardChangeHandler (\r
658 IN BMM_CALLBACK_DATA *Private,\r
659 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap\r
660 )\r
661{\r
662 UINT16 Index;\r
663\r
664 switch (Private->BmmPreviousPageId) {\r
665 case FORM_BOOT_CHG_ID:\r
666 case FORM_DRV_CHG_ID:\r
667 CopyMem (CurrentFakeNVMap->OptionOrder, Private->BmmOldFakeNVData.OptionOrder, 100);\r
668 break;\r
669\r
670 case FORM_BOOT_DEL_ID:\r
671 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
672 CurrentFakeNVMap->BootOptionDel[Index] = 0x00;\r
673 }\r
674 break;\r
675\r
676 case FORM_DRV_DEL_ID:\r
677 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
678 CurrentFakeNVMap->DriverOptionDel[Index] = 0x00;\r
679 }\r
680 break;\r
681\r
682 case FORM_BOOT_NEXT_ID:\r
683 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;\r
684 break;\r
685\r
686 case FORM_TIME_OUT_ID:\r
687 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;\r
688 break;\r
689\r
690 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
691 case FORM_DRV_ADD_FILE_ID:\r
692 case FORM_DRV_ADD_HANDLE_ID:\r
693 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;\r
694 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;\r
695 break;\r
696\r
697 default:\r
698 break;\r
699 }\r
700}\r
701\r
702EFI_STATUS\r
703EFIAPI\r
704NvWrite (\r
705 IN EFI_FORM_CALLBACK_PROTOCOL *This,\r
706 IN CHAR16 *VariableName,\r
707 IN EFI_GUID *VendorGuid,\r
708 OUT UINT32 Attributes OPTIONAL,\r
709 IN OUT UINTN DataSize,\r
710 OUT VOID *Buffer,\r
711 OUT BOOLEAN *ResetRequired\r
712 )\r
713{\r
714 //\r
715 // Do nothing here. Just to catch the F10, we use "Apply Changes" tag to save.\r
716 //\r
717 return EFI_SUCCESS;\r
718}\r
719\r
720EFI_STATUS\r
721InitializeBM (\r
722 VOID\r
723 )\r
724/*++\r
725Routine Description:\r
726\r
727 Initialize the Boot Maintenance Utitliy\r
728\r
729Arguments:\r
730\r
731 ImageHandle - caller provided handle\r
732 \r
733 SystemTable - caller provided system tables\r
734\r
735Returns:\r
736\r
737 EFI_SUCCESS - utility ended successfully\r
738 \r
739 others - contain some errors\r
740 \r
741--*/\r
742{\r
743 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
744 EFI_HII_PACKAGES *PackageList;\r
745 BMM_CALLBACK_DATA *BmmCallbackInfo;\r
746 EFI_HII_PROTOCOL *Hii;\r
747 EFI_HII_HANDLE HiiHandle;\r
748 EFI_STATUS Status;\r
749 EFI_HANDLE Handle;\r
750 UINT8 *Ptr;\r
751 UINT8 *Location;\r
752\r
753 Status = EFI_SUCCESS;\r
754 UpdateData = NULL;\r
755 //\r
756 // Initialize EfiUtilityLib and EfiDriverLib\r
757 // Since many functions in UtilityLib must be used and\r
758 // SetupBrowser use DriverLib\r
759 //\r
760 //\r
761 // There should be only one EFI_HII_PROTOCOL Image\r
762 //\r
8ef571df 763 Status = EfiLibLocateProtocol (&gEfiHiiProtocolGuid, (VOID**)&Hii);\r
c9093a06 764 if (EFI_ERROR (Status)) {\r
765 return Status;\r
766 }\r
767 //\r
768 // Create CallbackData structures for Driver Callback\r
769 //\r
770 BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));\r
771 if (!BmmCallbackInfo) {\r
772 return EFI_OUT_OF_RESOURCES;\r
773 }\r
774 //\r
775 // Create LoadOption in BmmCallbackInfo for Driver Callback\r
776 //\r
777 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));\r
778 if (!Ptr) {\r
779 SafeFreePool (BmmCallbackInfo);\r
780 return EFI_OUT_OF_RESOURCES;\r
781 }\r
782 //\r
783 // Initialize Bmm callback data.\r
784 //\r
785 BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;\r
786 Ptr += sizeof (BM_LOAD_CONTEXT);\r
787\r
788 BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;\r
789 Ptr += sizeof (BM_FILE_CONTEXT);\r
790\r
791 BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;\r
792 Ptr += sizeof (BM_HANDLE_CONTEXT);\r
793\r
794 BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;\r
795\r
796 BmmCallbackInfo->BmmFakeNvData = &BmmCallbackInfo->BmmOldFakeNVData;\r
797\r
798 ZeroMem (BmmCallbackInfo->BmmFakeNvData, sizeof (BMM_FAKE_NV_DATA));\r
799\r
800 BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;\r
801 BmmCallbackInfo->Hii = Hii;\r
802 BmmCallbackInfo->BmmDriverCallback.NvRead = NULL;\r
803 BmmCallbackInfo->BmmDriverCallback.NvWrite = NvWrite;\r
804 BmmCallbackInfo->BmmDriverCallback.Callback = DriverCallback;\r
805 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;\r
806 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;\r
807 BmmCallbackInfo->FeDriverCallback.NvRead = NULL;\r
808 BmmCallbackInfo->FeDriverCallback.NvWrite = NvWrite;\r
809 BmmCallbackInfo->FeDriverCallback.Callback = FileExplorerCallback;\r
810 BmmCallbackInfo->FeCurrentState = INACTIVE_STATE;\r
811 BmmCallbackInfo->FeDisplayContext = UNKNOWN_CONTEXT;\r
812\r
813 //\r
814 // Install bmm callback protocol interface\r
815 //\r
816 Handle = NULL;\r
817 Status = gBS->InstallProtocolInterface (\r
818 &Handle,\r
819 &gEfiFormCallbackProtocolGuid,\r
820 EFI_NATIVE_INTERFACE,\r
821 &BmmCallbackInfo->BmmDriverCallback\r
822 );\r
823\r
824 if (EFI_ERROR (Status)) {\r
825 return Status;\r
826 }\r
827\r
828 BmmCallbackInfo->BmmCallbackHandle = Handle;\r
829\r
830 //\r
831 // Install file explorer callback protocol interface\r
832 //\r
833 Handle = NULL;\r
834 Status = gBS->InstallProtocolInterface (\r
835 &Handle,\r
836 &gEfiFormCallbackProtocolGuid,\r
837 EFI_NATIVE_INTERFACE,\r
838 &BmmCallbackInfo->FeDriverCallback\r
839 );\r
840\r
841 if (EFI_ERROR (Status)) {\r
842 return Status;\r
843 }\r
844\r
845 BmmCallbackInfo->FeCallbackHandle = Handle;\r
846\r
847 //\r
848 // Post our VFR to the HII database.\r
849 //\r
850 PackageList = PreparePackages (1, &gBdsStringPackGuid, BmBin);\r
851 Status = Hii->NewPack (Hii, PackageList, &HiiHandle);\r
852 gBS->FreePool (PackageList);\r
853\r
854 BmmCallbackInfo->BmmHiiHandle = HiiHandle;\r
855\r
856 PackageList = PreparePackages (1, &gBdsStringPackGuid, FEBin);\r
857 Status = Hii->NewPack (Hii, PackageList, &HiiHandle);\r
858 gBS->FreePool (PackageList);\r
859\r
860 BmmCallbackInfo->FeHiiHandle = HiiHandle;\r
861\r
862 //\r
863 // Allocate space for creation of Buffer\r
864 //\r
865 UpdateData = AllocateZeroPool (UPDATE_DATA_SIZE);\r
866 if (!UpdateData) {\r
867 SafeFreePool (BmmCallbackInfo->LoadContext);\r
868 SafeFreePool (BmmCallbackInfo);\r
869 return EFI_OUT_OF_RESOURCES;\r
870 }\r
871 //\r
872 // Initialize UpdateData structure\r
873 //\r
874 RefreshUpdateData (TRUE, (EFI_PHYSICAL_ADDRESS) (UINTN) BmmCallbackInfo->BmmCallbackHandle, FALSE, 0, 0);\r
875\r
876 Location = (UINT8 *) &UpdateData->Data;\r
877\r
878 InitializeStringDepository ();\r
879\r
880 InitAllMenu (BmmCallbackInfo);\r
881\r
882 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);\r
883 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);\r
884 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);\r
885 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);\r
886 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);\r
887 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);\r
888 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);\r
889\r
890 UpdateBootDelPage (BmmCallbackInfo);\r
891 UpdateDrvDelPage (BmmCallbackInfo);\r
892\r
893 if (TerminalMenu.MenuNumber > 0) {\r
894 BmmCallbackInfo->CurrentTerminal = 0;\r
895 UpdateTerminalPage (BmmCallbackInfo);\r
896 }\r
897\r
898 Location = (UINT8 *) &UpdateData->Data;\r
8ef571df 899 Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID**) &LegacyBios);\r
c9093a06 900 if (!EFI_ERROR (Status)) {\r
901 //\r
902 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option\r
903 // in BootOption form: legacy FD/HD/CD/NET/BEV\r
904 //\r
905 UpdateData->DataCount = 5;\r
906 CreateGotoOpCode (\r
907 FORM_SET_FD_ORDER_ID,\r
908 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
909 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
910 EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
911 FORM_SET_FD_ORDER_ID,\r
912 Location\r
913 );\r
914\r
915 Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
916\r
917 CreateGotoOpCode (\r
918 FORM_SET_HD_ORDER_ID,\r
919 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
920 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
921 EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
922 FORM_SET_HD_ORDER_ID,\r
923 Location\r
924 );\r
925\r
926 Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
927\r
928 CreateGotoOpCode (\r
929 FORM_SET_CD_ORDER_ID,\r
930 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
931 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
932 EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
933 FORM_SET_CD_ORDER_ID,\r
934 Location\r
935 );\r
936\r
937 Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
938\r
939 CreateGotoOpCode (\r
940 FORM_SET_NET_ORDER_ID,\r
941 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
942 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
943 EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
944 FORM_SET_NET_ORDER_ID,\r
945 Location\r
946 );\r
947\r
948 Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
949\r
950 CreateGotoOpCode (\r
951 FORM_SET_BEV_ORDER_ID,\r
952 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
953 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
954 EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
955 FORM_SET_BEV_ORDER_ID,\r
956 Location\r
957 );\r
958\r
959 Hii->UpdateForm (\r
960 Hii,\r
961 BmmCallbackInfo->BmmHiiHandle,\r
962 (EFI_FORM_LABEL) FORM_BOOT_LEGACY_DEVICE_ID,\r
963 TRUE,\r
964 UpdateData\r
965 );\r
966 }\r
967 //\r
968 // Dispatch BMM main formset and File Explorer formset.\r
969 //\r
970 FormSetDispatcher (BmmCallbackInfo);\r
971\r
972 Hii->ResetStrings (Hii, HiiHandle);\r
973\r
974 CleanUpStringDepository ();\r
975\r
976 if (EFI_ERROR (Status)) {\r
977 return Status;\r
978 }\r
979\r
980 FreeAllMenu ();\r
981\r
982 SafeFreePool (BmmCallbackInfo->LoadContext);\r
983 BmmCallbackInfo->LoadContext = NULL;\r
984 SafeFreePool (BmmCallbackInfo);\r
985 BmmCallbackInfo = NULL;\r
986 SafeFreePool (UpdateData);\r
987 UpdateData = NULL;\r
988\r
989 return Status;\r
990}\r
991\r
992VOID\r
993InitAllMenu (\r
994 IN BMM_CALLBACK_DATA *CallbackData\r
995 )\r
996{\r
997 InitializeListHead (&BootOptionMenu.Head);\r
998 InitializeListHead (&DriverOptionMenu.Head);\r
999 BOpt_GetBootOptions (CallbackData);\r
1000 BOpt_GetDriverOptions (CallbackData);\r
1001 BOpt_GetLegacyOptions ();\r
1002 InitializeListHead (&FsOptionMenu.Head);\r
1003 BOpt_FindDrivers ();\r
1004 InitializeListHead (&DirectoryMenu.Head);\r
1005 InitializeListHead (&ConsoleInpMenu.Head);\r
1006 InitializeListHead (&ConsoleOutMenu.Head);\r
1007 InitializeListHead (&ConsoleErrMenu.Head);\r
1008 InitializeListHead (&TerminalMenu.Head);\r
1009 LocateSerialIo ();\r
1010 GetAllConsoles ();\r
1011}\r
1012\r
1013VOID\r
1014FreeAllMenu (\r
1015 VOID\r
1016 )\r
1017{\r
1018 BOpt_FreeMenu (&DirectoryMenu);\r
1019 BOpt_FreeMenu (&FsOptionMenu);\r
1020 BOpt_FreeMenu (&BootOptionMenu);\r
1021 BOpt_FreeMenu (&DriverOptionMenu);\r
1022 BOpt_FreeMenu (&DriverMenu);\r
1023 BOpt_FreeLegacyOptions ();\r
1024 FreeAllConsoles ();\r
1025}\r
1026\r
1027VOID\r
1028InitializeStringDepository (\r
1029 VOID\r
1030 )\r
1031/*++\r
1032Routine Description:\r
1033 Intialize all the string depositories.\r
1034\r
1035Arguments:\r
1036 None.\r
1037\r
1038Returns:\r
1039 None. \r
1040--*/\r
1041{\r
1042 STRING_DEPOSITORY *StringDepository;\r
1043 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);\r
1044 FileOptionStrDepository = StringDepository++;\r
1045 ConsoleOptionStrDepository = StringDepository++;\r
1046 BootOptionStrDepository = StringDepository++;\r
1047 BootOptionHelpStrDepository = StringDepository++;\r
1048 DriverOptionStrDepository = StringDepository++;\r
1049 DriverOptionHelpStrDepository = StringDepository++;\r
1050 TerminalStrDepository = StringDepository;\r
1051}\r
1052\r
1053STRING_REF\r
1054GetStringTokenFromDepository (\r
1055 IN BMM_CALLBACK_DATA *CallbackData,\r
1056 IN STRING_DEPOSITORY *StringDepository\r
1057 )\r
1058/*++\r
1059Routine Description:\r
1060 Fetch a usable string node from the string depository and return the string token.\r
1061\r
1062Arguments:\r
1063 StringDepository - Pointer of the string depository.\r
1064\r
1065Returns:\r
1066 STRING_REF - String token.\r
1067--*/\r
1068{\r
1069 STRING_LIST_NODE *CurrentListNode;\r
1070 STRING_LIST_NODE *NextListNode;\r
1071\r
1072 CurrentListNode = StringDepository->CurrentNode;\r
1073\r
1074 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {\r
1075 //\r
1076 // Fetch one reclaimed node from the list.\r
1077 //\r
1078 NextListNode = StringDepository->CurrentNode->Next;\r
1079 } else {\r
1080 //\r
1081 // If there is no usable node in the list, update the list.\r
1082 //\r
1083 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));\r
1084\r
1085 CallbackData->Hii->NewString (\r
1086 CallbackData->Hii,\r
1087 NULL,\r
1088 CallbackData->BmmHiiHandle,\r
1089 &(NextListNode->StringToken),\r
1090 L" "\r
1091 );\r
1092\r
1093 ASSERT (NextListNode->StringToken != 0);\r
1094\r
1095 StringDepository->TotalNodeNumber++;\r
1096\r
1097 if (NULL == CurrentListNode) {\r
1098 StringDepository->ListHead = NextListNode;\r
1099 } else {\r
1100 CurrentListNode->Next = NextListNode;\r
1101 }\r
1102 }\r
1103\r
1104 StringDepository->CurrentNode = NextListNode;\r
1105\r
1106 return StringDepository->CurrentNode->StringToken;\r
1107}\r
1108\r
1109VOID\r
1110ReclaimStringDepository (\r
1111 VOID\r
1112 )\r
1113/*++\r
1114Routine Description:\r
1115 Reclaim string depositories by moving the current node pointer to list head..\r
1116\r
1117Arguments:\r
1118 None.\r
1119\r
1120Returns:\r
1121 None.\r
1122--*/\r
1123{\r
1124 UINTN DepositoryIndex;\r
1125 STRING_DEPOSITORY *StringDepository;\r
1126\r
1127 StringDepository = FileOptionStrDepository;\r
1128 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1129 StringDepository->CurrentNode = StringDepository->ListHead;\r
1130 StringDepository++;\r
1131 }\r
1132}\r
1133\r
1134VOID\r
1135CleanUpStringDepository (\r
1136 VOID\r
1137 )\r
1138/*++\r
1139Routine Description:\r
1140 Release resource for all the string depositories.\r
1141\r
1142Arguments:\r
1143 None.\r
1144\r
1145Returns:\r
1146 None.\r
1147--*/\r
1148{\r
1149 UINTN NodeIndex;\r
1150 UINTN DepositoryIndex;\r
1151 STRING_LIST_NODE *CurrentListNode;\r
1152 STRING_LIST_NODE *NextListNode;\r
1153 STRING_DEPOSITORY *StringDepository;\r
1154\r
1155 //\r
1156 // Release string list nodes.\r
1157 //\r
1158 StringDepository = FileOptionStrDepository;\r
1159 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1160 CurrentListNode = StringDepository->ListHead;\r
1161 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {\r
1162 NextListNode = CurrentListNode->Next;\r
1163 SafeFreePool (CurrentListNode);\r
1164 CurrentListNode = NextListNode;\r
1165 }\r
1166\r
1167 StringDepository++;\r
1168 }\r
1169 //\r
1170 // Release string depository.\r
1171 //\r
1172 SafeFreePool (FileOptionStrDepository);\r
1173}\r
1174\r
1175EFI_STATUS\r
1176BdsStartBootMaint (\r
1177 VOID\r
1178 )\r
1179/*++\r
1180\r
1181Routine Description:\r
1182 Start boot maintenance manager\r
1183\r
1184Arguments:\r
1185\r
1186Returns:\r
1187\r
1188--*/\r
1189{\r
1190 EFI_STATUS Status;\r
1191 LIST_ENTRY BdsBootOptionList;\r
1192\r
1193 InitializeListHead (&BdsBootOptionList);\r
1194\r
1195 //\r
1196 // Connect all prior to entering the platform setup menu.\r
1197 //\r
1198 if (!gConnectAllHappened) {\r
1199 BdsLibConnectAllDriversToAllControllers ();\r
1200 gConnectAllHappened = TRUE;\r
1201 }\r
1202 //\r
1203 // Have chance to enumerate boot device\r
1204 //\r
1205 BdsLibEnumerateAllBootOption (&BdsBootOptionList);\r
1206\r
1207 //\r
1208 // Init the BMM\r
1209 //\r
1210 Status = InitializeBM ();\r
1211\r
1212 return Status;\r
1213}\r
1214\r
1215EFI_STATUS\r
1216FormSetDispatcher (\r
1217 IN BMM_CALLBACK_DATA *CallbackData\r
1218 )\r
1219/*++\r
1220\r
1221Routine Description:\r
1222 Dispatch BMM formset and FileExplorer formset.\r
1223\r
1224Arguments:\r
1225\r
1226Returns:\r
1227\r
1228--*/\r
1229{\r
1230 EFI_FORM_BROWSER_PROTOCOL *FormConfig;\r
1231 UINT8 *Location;\r
1232 EFI_STATUS Status;\r
1233 UINTN Index;\r
1234 BM_MENU_ENTRY *NewMenuEntry;\r
1235 BM_FILE_CONTEXT *NewFileContext;\r
1236 BOOLEAN BootMaintMenuResetRequired;\r
1237\r
1238 Location = NULL;\r
1239 Index = 0;\r
1240 NewMenuEntry = NULL;\r
1241 NewFileContext = NULL;\r
1242\r
1243 //\r
1244 // There should only be one Form Configuration protocol\r
1245 //\r
8ef571df 1246 Status = EfiLibLocateProtocol (&gEfiFormBrowserProtocolGuid, (VOID**) &FormConfig);\r
c9093a06 1247 if (EFI_ERROR (Status)) {\r
1248 return Status;\r
1249 }\r
1250\r
1251 while (1) {\r
1252 UpdatePageId (CallbackData, FORM_MAIN_ID);\r
1253\r
1254 BootMaintMenuResetRequired = FALSE;\r
1255 Status = FormConfig->SendForm (\r
1256 FormConfig,\r
1257 TRUE,\r
1258 &(CallbackData->BmmHiiHandle),\r
1259 1,\r
1260 NULL,\r
1261 NULL,\r
1262 (UINT8 *) CallbackData->BmmFakeNvData,\r
1263 NULL,\r
1264 &BootMaintMenuResetRequired\r
1265 );\r
1266\r
1267 if (BootMaintMenuResetRequired) {\r
1268 EnableResetRequired ();\r
1269 }\r
1270\r
1271 ReclaimStringDepository ();\r
1272\r
1273 //\r
1274 // When this Formset returns, check if we are going to explore files.\r
1275 //\r
1276 if (INACTIVE_STATE != CallbackData->FeCurrentState) {\r
1277 UpdateFileExplorer (CallbackData, 0);\r
1278\r
1279 BootMaintMenuResetRequired = FALSE;\r
1280 Status = FormConfig->SendForm (\r
1281 FormConfig,\r
1282 TRUE,\r
1283 &(CallbackData->FeHiiHandle),\r
1284 1,\r
1285 NULL,\r
1286 NULL,\r
1287 NULL,\r
1288 NULL,\r
1289 &BootMaintMenuResetRequired\r
1290 );\r
1291\r
1292 if (BootMaintMenuResetRequired) {\r
1293 EnableResetRequired ();\r
1294 }\r
1295\r
1296 CallbackData->FeCurrentState = INACTIVE_STATE;\r
1297 CallbackData->FeDisplayContext = UNKNOWN_CONTEXT;\r
1298 ReclaimStringDepository ();\r
1299 } else {\r
1300 break;\r
1301 }\r
1302 }\r
1303\r
1304 return Status;\r
1305}\r
1306\r
1307VOID\r
1308CreateCallbackPacket (\r
1309 OUT EFI_HII_CALLBACK_PACKET **Packet,\r
1310 IN UINT16 Flags\r
1311 )\r
1312{\r
1313 *Packet = (EFI_HII_CALLBACK_PACKET *) AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET) + 2);\r
1314 ASSERT (*Packet != NULL);\r
1315\r
1316 (*Packet)->DataArray.EntryCount = 1;\r
1317 (*Packet)->DataArray.NvRamMap = NULL;\r
1318 ((EFI_IFR_DATA_ENTRY *) (&((*Packet)->DataArray) + 1))->Flags = Flags;\r
1319}\r