MdeModulePkg BootMaintenanceManagerUiLib: Move refresh boot option later
[mirror_edk2.git] / MdeModulePkg / Library / BootMaintenanceManagerUiLib / BootMaintenance.c
CommitLineData
4af04335
DB
1/** @file\r
2The functions for Boot Maintainence Main menu.\r
3\r
85520606 4Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>\r
4af04335
DB
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "BootMaintenanceManager.h"\r
16\r
17#define FRONT_PAGE_KEY_OFFSET 0x4000\r
18//\r
19// Boot video resolution and text mode.\r
20//\r
21UINT32 mBmmBootHorizontalResolution = 0;\r
22UINT32 mBmmBootVerticalResolution = 0;\r
23UINT32 mBmmBootTextModeColumn = 0;\r
24UINT32 mBmmBootTextModeRow = 0;\r
25//\r
26// BIOS setup video resolution and text mode.\r
27//\r
28UINT32 mBmmSetupTextModeColumn = 0;\r
29UINT32 mBmmSetupTextModeRow = 0;\r
30UINT32 mBmmSetupHorizontalResolution = 0;\r
31UINT32 mBmmSetupVerticalResolution = 0;\r
32\r
8c53b5e6
ED
33BOOLEAN mBmmModeInitialized = FALSE;\r
34\r
4af04335
DB
35EFI_DEVICE_PATH_PROTOCOL EndDevicePath[] = {\r
36 {\r
37 END_DEVICE_PATH_TYPE,\r
38 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
39 {\r
40 END_DEVICE_PATH_LENGTH,\r
41 0\r
42 }\r
43 }\r
44};\r
45\r
46HII_VENDOR_DEVICE_PATH mBmmHiiVendorDevicePath = {\r
47 {\r
48 {\r
49 HARDWARE_DEVICE_PATH,\r
50 HW_VENDOR_DP,\r
51 {\r
52 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
53 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
54 }\r
55 },\r
56 //\r
57 // {165A028F-0BB2-4b5f-8747-77592E3F6499}\r
58 //\r
59 { 0x165a028f, 0xbb2, 0x4b5f, { 0x87, 0x47, 0x77, 0x59, 0x2e, 0x3f, 0x64, 0x99 } }\r
60 },\r
61 {\r
62 END_DEVICE_PATH_TYPE,\r
63 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
64 { \r
65 (UINT8) (END_DEVICE_PATH_LENGTH),\r
66 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
67 }\r
68 }\r
69};\r
70\r
71EFI_GUID mBootMaintGuid = BOOT_MAINT_FORMSET_GUID;\r
72\r
73CHAR16 mBootMaintStorageName[] = L"BmmData";\r
74BMM_CALLBACK_DATA gBootMaintenancePrivate = {\r
75 BMM_CALLBACK_DATA_SIGNATURE,\r
76 NULL,\r
77 NULL,\r
78 {\r
79 BootMaintExtractConfig,\r
80 BootMaintRouteConfig,\r
81 BootMaintCallback\r
82 }\r
83};\r
84\r
85BMM_CALLBACK_DATA *mBmmCallbackInfo = &gBootMaintenancePrivate;\r
86BOOLEAN mAllMenuInit = FALSE;\r
984cb646 87BOOLEAN mFirstEnterBMMForm = FALSE;\r
4af04335
DB
88\r
89/**\r
90 Init all memu.\r
91\r
92 @param CallbackData The BMM context data.\r
93\r
94**/\r
95VOID\r
96InitAllMenu (\r
97 IN BMM_CALLBACK_DATA *CallbackData\r
98 );\r
99\r
100/**\r
101 Free up all Menu Option list.\r
102\r
103**/\r
104VOID\r
105FreeAllMenu (\r
106 VOID\r
107 );\r
108\r
984cb646
DB
109/**\r
110\r
111 Update the menus in the BMM page.\r
112\r
113**/\r
114VOID\r
115CustomizeMenus (\r
116 VOID\r
117 );\r
118\r
4af04335
DB
119/**\r
120 This function will change video resolution and text mode\r
121 according to defined setup mode or defined boot mode \r
122\r
123 @param IsSetupMode Indicate mode is changed to setup mode or boot mode. \r
124\r
125 @retval EFI_SUCCESS Mode is changed successfully.\r
126 @retval Others Mode failed to be changed.\r
127\r
128**/\r
129EFI_STATUS\r
80b14f9a 130BmmSetConsoleMode (\r
4af04335
DB
131 BOOLEAN IsSetupMode\r
132 )\r
133{\r
134 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
135 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;\r
136 UINTN SizeOfInfo;\r
137 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
138 UINT32 MaxGopMode;\r
139 UINT32 MaxTextMode;\r
140 UINT32 ModeNumber;\r
141 UINT32 NewHorizontalResolution;\r
142 UINT32 NewVerticalResolution;\r
143 UINT32 NewColumns;\r
144 UINT32 NewRows;\r
145 UINTN HandleCount;\r
146 EFI_HANDLE *HandleBuffer;\r
147 EFI_STATUS Status;\r
148 UINTN Index;\r
149 UINTN CurrentColumn;\r
150 UINTN CurrentRow; \r
151\r
152 MaxGopMode = 0;\r
153 MaxTextMode = 0;\r
154\r
155 //\r
156 // Get current video resolution and text mode \r
157 //\r
158 Status = gBS->HandleProtocol (\r
159 gST->ConsoleOutHandle,\r
160 &gEfiGraphicsOutputProtocolGuid,\r
161 (VOID**)&GraphicsOutput\r
162 );\r
163 if (EFI_ERROR (Status)) {\r
164 GraphicsOutput = NULL;\r
165 }\r
166\r
167 Status = gBS->HandleProtocol (\r
168 gST->ConsoleOutHandle,\r
169 &gEfiSimpleTextOutProtocolGuid,\r
170 (VOID**)&SimpleTextOut\r
171 );\r
172 if (EFI_ERROR (Status)) {\r
173 SimpleTextOut = NULL;\r
174 } \r
175\r
176 if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {\r
177 return EFI_UNSUPPORTED;\r
178 }\r
179\r
180 if (IsSetupMode) {\r
181 //\r
2048c585 182 // The required resolution and text mode is setup mode.\r
4af04335
DB
183 //\r
184 NewHorizontalResolution = mBmmSetupHorizontalResolution;\r
185 NewVerticalResolution = mBmmSetupVerticalResolution;\r
186 NewColumns = mBmmSetupTextModeColumn;\r
187 NewRows = mBmmSetupTextModeRow;\r
188 } else {\r
189 //\r
190 // The required resolution and text mode is boot mode.\r
191 //\r
192 NewHorizontalResolution = mBmmBootHorizontalResolution;\r
193 NewVerticalResolution = mBmmBootVerticalResolution;\r
194 NewColumns = mBmmBootTextModeColumn;\r
195 NewRows = mBmmBootTextModeRow; \r
196 }\r
197\r
198 if (GraphicsOutput != NULL) {\r
199 MaxGopMode = GraphicsOutput->Mode->MaxMode;\r
200 } \r
201\r
202 if (SimpleTextOut != NULL) {\r
203 MaxTextMode = SimpleTextOut->Mode->MaxMode;\r
204 }\r
205\r
206 //\r
207 // 1. If current video resolution is same with required video resolution,\r
208 // video resolution need not be changed.\r
209 // 1.1. If current text mode is same with required text mode, text mode need not be changed.\r
210 // 1.2. If current text mode is different from required text mode, text mode need be changed.\r
211 // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.\r
212 //\r
213 for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {\r
214 Status = GraphicsOutput->QueryMode (\r
215 GraphicsOutput,\r
216 ModeNumber,\r
217 &SizeOfInfo,\r
218 &Info\r
219 );\r
220 if (!EFI_ERROR (Status)) {\r
221 if ((Info->HorizontalResolution == NewHorizontalResolution) &&\r
222 (Info->VerticalResolution == NewVerticalResolution)) {\r
223 if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) &&\r
224 (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) {\r
225 //\r
226 // Current resolution is same with required resolution, check if text mode need be set\r
227 //\r
228 Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);\r
229 ASSERT_EFI_ERROR (Status);\r
230 if (CurrentColumn == NewColumns && CurrentRow == NewRows) {\r
231 //\r
232 // If current text mode is same with required text mode. Do nothing\r
233 //\r
234 FreePool (Info);\r
235 return EFI_SUCCESS;\r
236 } else {\r
237 //\r
2048c585 238 // If current text mode is different from required text mode. Set new video mode\r
4af04335
DB
239 //\r
240 for (Index = 0; Index < MaxTextMode; Index++) {\r
241 Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);\r
242 if (!EFI_ERROR(Status)) {\r
243 if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {\r
244 //\r
245 // Required text mode is supported, set it.\r
246 //\r
247 Status = SimpleTextOut->SetMode (SimpleTextOut, Index);\r
248 ASSERT_EFI_ERROR (Status);\r
249 //\r
250 // Update text mode PCD.\r
251 //\r
e750958b
DB
252 Status = PcdSet32S (PcdConOutColumn, mBmmSetupTextModeColumn);\r
253 ASSERT_EFI_ERROR (Status);\r
254 Status = PcdSet32S (PcdConOutRow, mBmmSetupTextModeRow);\r
255 ASSERT_EFI_ERROR (Status);\r
4af04335
DB
256 FreePool (Info);\r
257 return EFI_SUCCESS;\r
258 }\r
259 }\r
260 }\r
261 if (Index == MaxTextMode) {\r
262 //\r
2048c585 263 // If required text mode is not supported, return error.\r
4af04335
DB
264 //\r
265 FreePool (Info);\r
266 return EFI_UNSUPPORTED;\r
267 }\r
268 }\r
269 } else {\r
270 //\r
271 // If current video resolution is not same with the new one, set new video resolution.\r
272 // In this case, the driver which produces simple text out need be restarted.\r
273 //\r
274 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);\r
275 if (!EFI_ERROR (Status)) {\r
276 FreePool (Info);\r
277 break;\r
278 }\r
279 }\r
280 }\r
281 FreePool (Info);\r
282 }\r
283 }\r
284\r
285 if (ModeNumber == MaxGopMode) {\r
286 //\r
287 // If the resolution is not supported, return error.\r
288 //\r
289 return EFI_UNSUPPORTED;\r
290 }\r
291\r
292 //\r
293 // Set PCD to Inform GraphicsConsole to change video resolution.\r
294 // Set PCD to Inform Consplitter to change text mode.\r
295 //\r
e750958b
DB
296 Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution);\r
297 ASSERT_EFI_ERROR (Status);\r
298 Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution);\r
299 ASSERT_EFI_ERROR (Status);\r
300 Status = PcdSet32S (PcdConOutColumn, NewColumns);\r
301 ASSERT_EFI_ERROR (Status);\r
302 Status = PcdSet32S (PcdConOutRow, NewRows);\r
303 ASSERT_EFI_ERROR (Status);\r
4af04335
DB
304\r
305 //\r
306 // Video mode is changed, so restart graphics console driver and higher level driver.\r
307 // Reconnect graphics console driver and higher level driver.\r
308 // Locate all the handles with GOP protocol and reconnect it.\r
309 //\r
310 Status = gBS->LocateHandleBuffer (\r
311 ByProtocol,\r
312 &gEfiSimpleTextOutProtocolGuid,\r
313 NULL,\r
314 &HandleCount,\r
315 &HandleBuffer\r
316 );\r
317 if (!EFI_ERROR (Status)) {\r
318 for (Index = 0; Index < HandleCount; Index++) {\r
319 gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);\r
320 }\r
321 for (Index = 0; Index < HandleCount; Index++) {\r
322 gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);\r
323 }\r
324 if (HandleBuffer != NULL) {\r
325 FreePool (HandleBuffer);\r
326 }\r
327 }\r
328\r
329 return EFI_SUCCESS;\r
330}\r
331\r
332/**\r
333 This function converts an input device structure to a Unicode string.\r
334\r
335 @param DevPath A pointer to the device path structure.\r
336\r
337 @return A new allocated Unicode string that represents the device path.\r
338\r
339**/\r
340CHAR16 *\r
341UiDevicePathToStr (\r
342 IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
343 )\r
344{\r
345 EFI_STATUS Status;\r
346 CHAR16 *ToText;\r
347 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;\r
348\r
349 if (DevPath == NULL) {\r
350 return NULL;\r
351 }\r
352\r
353 Status = gBS->LocateProtocol (\r
354 &gEfiDevicePathToTextProtocolGuid,\r
355 NULL,\r
356 (VOID **) &DevPathToText\r
357 );\r
358 ASSERT_EFI_ERROR (Status);\r
359 ToText = DevPathToText->ConvertDevicePathToText (\r
360 DevPath,\r
361 FALSE,\r
362 TRUE\r
363 );\r
364 ASSERT (ToText != NULL);\r
365 return ToText;\r
366}\r
367\r
368/**\r
369 Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.\r
370 The caller is responsible for freeing the allocated buffer using FreePool().\r
371\r
372 @param DevicePath Device path.\r
373\r
374 @return A new allocated string that represents the file name.\r
375\r
376**/\r
377CHAR16 *\r
378ExtractFileNameFromDevicePath (\r
379 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
380 )\r
381{\r
382 CHAR16 *String;\r
383 CHAR16 *MatchString;\r
384 CHAR16 *LastMatch;\r
385 CHAR16 *FileName;\r
386 UINTN Length;\r
387\r
388 ASSERT(DevicePath != NULL);\r
389\r
390 String = UiDevicePathToStr(DevicePath);\r
391 MatchString = String;\r
392 LastMatch = String;\r
a91f1a0e 393 FileName = NULL;\r
4af04335
DB
394\r
395 while(MatchString != NULL){\r
396 LastMatch = MatchString + 1;\r
397 MatchString = StrStr(LastMatch,L"\\");\r
398 }\r
399\r
400 Length = StrLen(LastMatch);\r
401 FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch);\r
a91f1a0e
BD
402 if (FileName != NULL) {\r
403 *(FileName + Length) = 0;\r
404 }\r
4af04335
DB
405\r
406 FreePool(String);\r
407\r
408 return FileName;\r
409}\r
410\r
411/**\r
412 Extract device path for given HII handle and class guid.\r
413\r
414 @param Handle The HII handle.\r
415\r
416 @retval NULL Fail to get the device path string.\r
417 @return PathString Get the device path string.\r
418\r
419**/\r
420CHAR16 *\r
421BmmExtractDevicePathFromHiiHandle (\r
422 IN EFI_HII_HANDLE Handle\r
423 )\r
424{\r
425 EFI_STATUS Status;\r
426 EFI_HANDLE DriverHandle;\r
427\r
428 ASSERT (Handle != NULL);\r
429\r
430 if (Handle == NULL) {\r
431 return NULL;\r
432 }\r
433\r
434 Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);\r
435 if (EFI_ERROR (Status)) {\r
436 return NULL;\r
437 }\r
438\r
439 //\r
440 // Get device path string.\r
441 //\r
442 return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE);\r
443\r
444}\r
445\r
201fbce6
DB
446/**\r
447 Converts the unicode character of the string from uppercase to lowercase.\r
448 This is a internal function.\r
449\r
450 @param ConfigString String to be converted\r
451\r
452**/\r
453VOID\r
454HiiToLower (\r
455 IN EFI_STRING ConfigString\r
456 )\r
457{\r
458 EFI_STRING String;\r
459 BOOLEAN Lower;\r
460\r
461 ASSERT (ConfigString != NULL);\r
462\r
463 //\r
464 // Convert all hex digits in range [A-F] in the configuration header to [a-f]\r
465 //\r
466 for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {\r
467 if (*String == L'=') {\r
468 Lower = TRUE;\r
469 } else if (*String == L'&') {\r
470 Lower = FALSE;\r
471 } else if (Lower && *String >= L'A' && *String <= L'F') {\r
472 *String = (CHAR16) (*String - L'A' + L'a');\r
473 }\r
474 }\r
475}\r
476\r
477/**\r
478 Update the progress string through the offset value.\r
479\r
480 @param Offset The offset value\r
481 @param Configuration Point to the configuration string.\r
482\r
483**/\r
484EFI_STRING\r
485UpdateProgress(\r
486 IN UINTN Offset,\r
487 IN EFI_STRING Configuration\r
488)\r
489{\r
490 UINTN Length;\r
491 EFI_STRING StringPtr;\r
492 EFI_STRING ReturnString;\r
493\r
494 StringPtr = NULL;\r
495 ReturnString = NULL;\r
496\r
497 //\r
498 // &OFFSET=XXXX followed by a Null-terminator.\r
499 // Length = StrLen (L"&OFFSET=") + 4 + 1\r
500 //\r
501 Length = StrLen (L"&OFFSET=") + 4 + 1;\r
502\r
503 StringPtr = AllocateZeroPool (Length * sizeof (CHAR16));\r
504\r
505 if (StringPtr == NULL) {\r
506 return NULL;\r
507 }\r
508\r
509 UnicodeSPrint (\r
510 StringPtr,\r
511 (8 + 4 + 1) * sizeof (CHAR16),\r
512 L"&OFFSET=%04x",\r
513 Offset\r
514 );\r
515\r
516 ReturnString = StrStr (Configuration, StringPtr);\r
517\r
518 if (ReturnString == NULL) {\r
519 //\r
520 // If doesn't find the string in Configuration, convert the string to lower case then search again.\r
521 //\r
522 HiiToLower (StringPtr);\r
523 ReturnString = StrStr (Configuration, StringPtr);\r
524 }\r
525\r
526 FreePool (StringPtr);\r
527\r
528 return ReturnString;\r
529}\r
530\r
a3475fe0
DB
531/**\r
532 Update the terminal content in TerminalMenu.\r
533\r
534 @param BmmData The BMM fake NV data.\r
535\r
536**/\r
537VOID\r
538UpdateTerminalContent (\r
539 IN BMM_FAKE_NV_DATA *BmmData\r
540 )\r
541{\r
542 UINT16 Index;\r
543 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
544 BM_MENU_ENTRY *NewMenuEntry;\r
545\r
546 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
547 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
548 ASSERT (NewMenuEntry != NULL);\r
549 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
550 NewTerminalContext->BaudRateIndex = BmmData->COMBaudRate[Index];\r
6eeeb288 551 ASSERT (BmmData->COMBaudRate[Index] < (ARRAY_SIZE (BaudRateList)));\r
a3475fe0
DB
552 NewTerminalContext->BaudRate = BaudRateList[BmmData->COMBaudRate[Index]].Value;\r
553 NewTerminalContext->DataBitsIndex = BmmData->COMDataRate[Index];\r
6eeeb288 554 ASSERT (BmmData->COMDataRate[Index] < (ARRAY_SIZE (DataBitsList)));\r
a3475fe0
DB
555 NewTerminalContext->DataBits = (UINT8) DataBitsList[BmmData->COMDataRate[Index]].Value;\r
556 NewTerminalContext->StopBitsIndex = BmmData->COMStopBits[Index];\r
6eeeb288 557 ASSERT (BmmData->COMStopBits[Index] < (ARRAY_SIZE (StopBitsList)));\r
a3475fe0
DB
558 NewTerminalContext->StopBits = (UINT8) StopBitsList[BmmData->COMStopBits[Index]].Value;\r
559 NewTerminalContext->ParityIndex = BmmData->COMParity[Index];\r
6eeeb288 560 ASSERT (BmmData->COMParity[Index] < (ARRAY_SIZE (ParityList)));\r
a3475fe0
DB
561 NewTerminalContext->Parity = (UINT8) ParityList[BmmData->COMParity[Index]].Value;\r
562 NewTerminalContext->TerminalType = BmmData->COMTerminalType[Index];\r
563 NewTerminalContext->FlowControl = BmmData->COMFlowControl[Index];\r
564 ChangeTerminalDevicePath (\r
565 NewTerminalContext->DevicePath,\r
566 FALSE\r
567 );\r
568 }\r
569}\r
570\r
571/**\r
572 Update the console content in ConsoleMenu.\r
573\r
c37dcee6 574 @param ConsoleName The name for the console device type.\r
a3475fe0
DB
575 @param BmmData The BMM fake NV data.\r
576\r
577**/\r
578VOID\r
579UpdateConsoleContent(\r
580 IN CHAR16 *ConsoleName,\r
581 IN BMM_FAKE_NV_DATA *BmmData\r
582 )\r
583{\r
584 UINT16 Index;\r
585 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
586 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
587 BM_MENU_ENTRY *NewMenuEntry;\r
588\r
589 if (StrCmp (ConsoleName, L"ConIn") == 0) {\r
590 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++){\r
591 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleInpMenu, Index);\r
592 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;\r
593 ASSERT (Index < MAX_MENU_NUMBER);\r
594 NewConsoleContext->IsActive = BmmData->ConsoleInCheck[Index];\r
595 }\r
596 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
597 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
598 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
599 ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);\r
600 NewTerminalContext->IsConIn = BmmData->ConsoleInCheck[Index + ConsoleInpMenu.MenuNumber];\r
601 }\r
602 }\r
603\r
604 if (StrCmp (ConsoleName, L"ConOut") == 0) {\r
605 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++){\r
606 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleOutMenu, Index);\r
607 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;\r
608 ASSERT (Index < MAX_MENU_NUMBER);\r
609 NewConsoleContext->IsActive = BmmData->ConsoleOutCheck[Index];\r
610 }\r
611 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
612 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
613 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
614 ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);\r
615 NewTerminalContext->IsConOut = BmmData->ConsoleOutCheck[Index + ConsoleOutMenu.MenuNumber];\r
616 }\r
617 }\r
618 if (StrCmp (ConsoleName, L"ErrOut") == 0) {\r
619 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++){\r
620 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleErrMenu, Index);\r
621 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;\r
622 ASSERT (Index < MAX_MENU_NUMBER);\r
623 NewConsoleContext->IsActive = BmmData->ConsoleErrCheck[Index];\r
624 }\r
625 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
626 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
627 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
628 ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);\r
629 NewTerminalContext->IsStdErr = BmmData->ConsoleErrCheck[Index + ConsoleErrMenu.MenuNumber];\r
630 }\r
631 }\r
632}\r
633\r
4af04335
DB
634/**\r
635 This function allows a caller to extract the current configuration for one\r
636 or more named elements from the target driver.\r
637\r
638 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
639 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
640 @param Progress On return, points to a character in the Request string.\r
641 Points to the string's null terminator if request was successful.\r
642 Points to the most recent '&' before the first failing name/value\r
643 pair (or the beginning of the string if the failure is in the\r
644 first name/value pair) if the request was not successful.\r
645 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
646 has all values filled in for the names in the Request string.\r
647 String to be allocated by the called function.\r
648\r
649 @retval EFI_SUCCESS The Results is filled with the requested values.\r
650 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
651 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
652 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
653\r
654**/\r
655EFI_STATUS\r
656EFIAPI\r
657BootMaintExtractConfig (\r
658 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
659 IN CONST EFI_STRING Request,\r
660 OUT EFI_STRING *Progress,\r
661 OUT EFI_STRING *Results\r
662 )\r
663{\r
664 EFI_STATUS Status;\r
665 UINTN BufferSize;\r
666 BMM_CALLBACK_DATA *Private;\r
667 EFI_STRING ConfigRequestHdr;\r
668 EFI_STRING ConfigRequest;\r
669 BOOLEAN AllocatedRequest;\r
670 UINTN Size;\r
671\r
672 if (Progress == NULL || Results == NULL) {\r
673 return EFI_INVALID_PARAMETER;\r
674 }\r
675\r
676 *Progress = Request;\r
677 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mBootMaintGuid, mBootMaintStorageName)) {\r
678 return EFI_NOT_FOUND;\r
679 }\r
680\r
681 ConfigRequestHdr = NULL;\r
682 ConfigRequest = NULL;\r
683 AllocatedRequest = FALSE;\r
684 Size = 0;\r
685\r
686 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
687 //\r
688 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
689 //\r
690 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
691 ConfigRequest = Request;\r
692 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
693 //\r
694 // Request has no request element, construct full request string.\r
695 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
696 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
697 //\r
698 ConfigRequestHdr = HiiConstructConfigHdr (&mBootMaintGuid, mBootMaintStorageName, Private->BmmDriverHandle);\r
699 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
700 ConfigRequest = AllocateZeroPool (Size);\r
701 ASSERT (ConfigRequest != NULL);\r
702 AllocatedRequest = TRUE;\r
703 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
704 FreePool (ConfigRequestHdr);\r
705 }\r
706\r
707 Status = gHiiConfigRouting->BlockToConfig (\r
708 gHiiConfigRouting,\r
709 ConfigRequest,\r
710 (UINT8 *) &Private->BmmFakeNvData,\r
711 BufferSize,\r
712 Results,\r
713 Progress\r
714 );\r
715 //\r
716 // Free the allocated config request string.\r
717 //\r
718 if (AllocatedRequest) {\r
719 FreePool (ConfigRequest);\r
720 ConfigRequest = NULL;\r
721 }\r
722 //\r
723 // Set Progress string to the original request string.\r
724 //\r
725 if (Request == NULL) {\r
726 *Progress = NULL;\r
727 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
728 *Progress = Request + StrLen (Request);\r
729 }\r
730\r
731 return Status;\r
732}\r
733\r
734/**\r
735 This function applies changes in a driver's configuration.\r
736 Input is a Configuration, which has the routing data for this\r
737 driver followed by name / value configuration pairs. The driver\r
738 must apply those pairs to its configurable storage. If the\r
739 driver's configuration is stored in a linear block of data\r
740 and the driver's name / value pairs are in <BlockConfig>\r
741 format, it may use the ConfigToBlock helper function (above) to\r
742 simplify the job. Currently not implemented.\r
743\r
744 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
745 @param[in] Configuration A null-terminated Unicode string in\r
746 <ConfigString> format. \r
747 @param[out] Progress A pointer to a string filled in with the\r
748 offset of the most recent '&' before the\r
749 first failing name / value pair (or the\r
750 beginn ing of the string if the failure\r
751 is in the first name / value pair) or\r
752 the terminating NULL if all was\r
753 successful.\r
754\r
755 @retval EFI_SUCCESS The results have been distributed or are\r
756 awaiting distribution. \r
757 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
758 parts of the results that must be\r
759 stored awaiting possible future\r
760 protocols.\r
761 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
762 Results parameter would result\r
763 in this type of error.\r
764 @retval EFI_NOT_FOUND Target for the specified routing data\r
765 was not found.\r
766**/\r
767EFI_STATUS\r
768EFIAPI\r
769BootMaintRouteConfig (\r
770 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
771 IN CONST EFI_STRING Configuration,\r
772 OUT EFI_STRING *Progress\r
773 )\r
774{\r
775 EFI_STATUS Status;\r
776 UINTN BufferSize;\r
777 EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;\r
778 BMM_FAKE_NV_DATA *NewBmmData;\r
779 BMM_FAKE_NV_DATA *OldBmmData;\r
4af04335
DB
780 BM_MENU_ENTRY *NewMenuEntry;\r
781 BM_LOAD_CONTEXT *NewLoadContext;\r
782 UINT16 Index;\r
783 BOOLEAN TerminalAttChange;\r
201fbce6
DB
784 BMM_CALLBACK_DATA *Private;\r
785 UINTN Offset;\r
4af04335
DB
786\r
787 if (Progress == NULL) {\r
788 return EFI_INVALID_PARAMETER;\r
789 }\r
790 *Progress = Configuration;\r
791\r
792 if (Configuration == NULL) {\r
793 return EFI_INVALID_PARAMETER;\r
794 }\r
795\r
796 //\r
797 // Check routing data in <ConfigHdr>.\r
798 // Note: there is no name for Name/Value storage, only GUID will be checked\r
799 //\r
800 if (!HiiIsConfigHdrMatch (Configuration, &mBootMaintGuid, mBootMaintStorageName)) {\r
801 return EFI_NOT_FOUND;\r
802 }\r
803\r
804 Status = gBS->LocateProtocol (\r
805 &gEfiHiiConfigRoutingProtocolGuid, \r
806 NULL, \r
807 (VOID **)&ConfigRouting\r
808 );\r
809 if (EFI_ERROR (Status)) {\r
810 return Status;\r
811 }\r
812\r
813 Private = BMM_CALLBACK_DATA_FROM_THIS (This); \r
814 //\r
815 // Get Buffer Storage data from EFI variable\r
816 //\r
817 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
818 OldBmmData = &Private->BmmOldFakeNVData;\r
819 NewBmmData = &Private->BmmFakeNvData;\r
201fbce6 820 Offset = 0;\r
4af04335
DB
821 //\r
822 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
823 //\r
824 Status = ConfigRouting->ConfigToBlock (\r
825 ConfigRouting,\r
826 Configuration,\r
827 (UINT8 *) NewBmmData,\r
828 &BufferSize,\r
829 Progress\r
830 );\r
831 ASSERT_EFI_ERROR (Status); \r
832 //\r
833 // Compare new and old BMM configuration data and only do action for modified item to \r
834 // avoid setting unnecessary non-volatile variable\r
835 //\r
836\r
837 //\r
838 // Check data which located in BMM main page and save the settings if need\r
839 // \r
840 if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {\r
841 Status = Var_UpdateBootNext (Private);\r
201fbce6
DB
842 if (EFI_ERROR (Status)) {\r
843 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootNext);\r
844 goto Exit;\r
845 }\r
4af04335
DB
846 }\r
847\r
848 //\r
849 // Check data which located in Boot Options Menu and save the settings if need\r
850 // \r
851 if (CompareMem (NewBmmData->BootOptionDel, OldBmmData->BootOptionDel, sizeof (NewBmmData->BootOptionDel)) != 0) { \r
852 for (Index = 0; \r
853 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->BootOptionDel) / sizeof (NewBmmData->BootOptionDel[0])))); \r
854 Index ++) {\r
855 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
856 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
857 NewLoadContext->Deleted = NewBmmData->BootOptionDel[Index];\r
858 NewBmmData->BootOptionDel[Index] = FALSE;\r
859 NewBmmData->BootOptionDelMark[Index] = FALSE;\r
860 }\r
861\r
201fbce6
DB
862 Status = Var_DelBootOption ();\r
863 if (EFI_ERROR (Status)) {\r
864 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionDel);\r
865 goto Exit;\r
866 }\r
4af04335
DB
867 }\r
868\r
869 if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) {\r
870 Status = Var_UpdateBootOrder (Private);\r
201fbce6
DB
871 if (EFI_ERROR (Status)) {\r
872 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionOrder);\r
873 goto Exit;\r
874 }\r
4af04335
DB
875 }\r
876\r
877 if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0){\r
878 Status = gRT->SetVariable(\r
879 L"Timeout",\r
880 &gEfiGlobalVariableGuid,\r
881 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
882 sizeof(UINT16),\r
883 &(NewBmmData->BootTimeOut)\r
884 );\r
c7d310dd 885 if (EFI_ERROR (Status)) {\r
201fbce6
DB
886 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootTimeOut);\r
887 goto Exit;\r
c7d310dd 888 }\r
4af04335
DB
889 Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut;\r
890 }\r
891\r
892 //\r
893 // Check data which located in Driver Options Menu and save the settings if need\r
894 // \r
895 if (CompareMem (NewBmmData->DriverOptionDel, OldBmmData->DriverOptionDel, sizeof (NewBmmData->DriverOptionDel)) != 0) { \r
896 for (Index = 0; \r
897 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->DriverOptionDel) / sizeof (NewBmmData->DriverOptionDel[0])))); \r
898 Index++) {\r
899 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
900 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
901 NewLoadContext->Deleted = NewBmmData->DriverOptionDel[Index];\r
902 NewBmmData->DriverOptionDel[Index] = FALSE;\r
903 NewBmmData->DriverOptionDelMark[Index] = FALSE;\r
904 }\r
201fbce6
DB
905 Status = Var_DelDriverOption ();\r
906 if (EFI_ERROR (Status)) {\r
907 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionDel);\r
908 goto Exit;\r
909 }\r
4af04335
DB
910 }\r
911\r
912 if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) { \r
913 Status = Var_UpdateDriverOrder (Private);\r
201fbce6
DB
914 if (EFI_ERROR (Status)) {\r
915 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionOrder);\r
916 goto Exit;\r
917 }\r
4af04335
DB
918 }\r
919\r
920 if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0){\r
201fbce6
DB
921 Status = Var_UpdateConMode(Private);\r
922 if (EFI_ERROR (Status)) {\r
923 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutMode);\r
924 goto Exit;\r
925 }\r
4af04335
DB
926 }\r
927\r
928 TerminalAttChange = FALSE;\r
929 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
930\r
931 //\r
932 // only need update modified items\r
933 //\r
934 if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) == 0 &&\r
935 CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) == 0 &&\r
936 CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) == 0 &&\r
937 CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) == 0 &&\r
938 CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) == 0 &&\r
939 CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) == 0) {\r
940 continue;\r
941 }\r
942\r
4af04335
DB
943 TerminalAttChange = TRUE;\r
944 }\r
945 if (TerminalAttChange) {\r
201fbce6
DB
946 if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) != 0) {\r
947 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMBaudRate);\r
948 } else if (CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) != 0) {\r
949 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMDataRate);\r
950 } else if (CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) != 0) {\r
951 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMStopBits);\r
952 } else if (CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) != 0) {\r
953 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMParity);\r
954 } else if (CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) != 0) {\r
955 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMTerminalType);\r
956 } else if (CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) != 0) {\r
957 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMFlowControl);\r
958 }\r
959 Status = Var_UpdateConsoleInpOption ();\r
960 if (EFI_ERROR (Status)) {\r
961 goto Exit;\r
962 }\r
963 Status = Var_UpdateConsoleOutOption ();\r
964 if (EFI_ERROR (Status)) {\r
965 goto Exit;\r
966 }\r
967 Status = Var_UpdateErrorOutOption ();\r
968 if (EFI_ERROR (Status)) {\r
969 goto Exit;\r
970 }\r
4af04335
DB
971 }\r
972 //\r
973 // Check data which located in Console Options Menu and save the settings if need\r
974 //\r
975 if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, sizeof (NewBmmData->ConsoleInCheck)) != 0){\r
201fbce6
DB
976 Status = Var_UpdateConsoleInpOption();\r
977 if (EFI_ERROR (Status)) {\r
978 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleInCheck);\r
979 goto Exit;\r
980 }\r
4af04335
DB
981 }\r
982\r
983 if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, sizeof (NewBmmData->ConsoleOutCheck)) != 0){\r
201fbce6
DB
984 Status = Var_UpdateConsoleOutOption();\r
985 if (EFI_ERROR (Status)) {\r
986 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutCheck);\r
987 goto Exit;\r
988 }\r
4af04335
DB
989 }\r
990\r
991 if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, sizeof (NewBmmData->ConsoleErrCheck)) != 0){\r
201fbce6
DB
992 Status = Var_UpdateErrorOutOption();\r
993 if (EFI_ERROR (Status)) {\r
994 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleErrCheck);\r
995 goto Exit;\r
996 }\r
4af04335
DB
997 }\r
998\r
999 if (CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0 ||\r
1000 CompareMem (NewBmmData->BootOptionalData, OldBmmData->BootOptionalData, sizeof (NewBmmData->BootOptionalData)) != 0) {\r
1001 Status = Var_UpdateBootOption (Private);\r
1002 NewBmmData->BootOptionChanged = FALSE;\r
1003 if (EFI_ERROR (Status)) {\r
201fbce6
DB
1004 if (CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0) {\r
1005 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootDescriptionData);\r
1006 } else {\r
1007 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionalData);\r
1008 }\r
1009 goto Exit;\r
4af04335
DB
1010 }\r
1011 BOpt_GetBootOptions (Private);\r
1012 }\r
1013\r
1014 if (CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0 ||\r
1015 CompareMem (NewBmmData->DriverOptionalData, OldBmmData->DriverOptionalData, sizeof (NewBmmData->DriverOptionalData)) != 0) {\r
1016 Status = Var_UpdateDriverOption (\r
1017 Private,\r
1018 Private->BmmHiiHandle,\r
1019 NewBmmData->DriverDescriptionData,\r
1020 NewBmmData->DriverOptionalData,\r
1021 NewBmmData->ForceReconnect\r
1022 );\r
1023 NewBmmData->DriverOptionChanged = FALSE;\r
1024 NewBmmData->ForceReconnect = TRUE;\r
1025 if (EFI_ERROR (Status)) {\r
201fbce6
DB
1026 if (CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0) {\r
1027 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverDescriptionData);\r
1028 } else {\r
1029 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionalData);\r
1030 }\r
1031 goto Exit;\r
4af04335
DB
1032 }\r
1033\r
1034 BOpt_GetDriverOptions (Private);\r
1035 }\r
1036\r
1037 //\r
1038 // After user do the save action, need to update OldBmmData.\r
1039 //\r
1040 CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));\r
1041\r
1042 return EFI_SUCCESS;\r
201fbce6
DB
1043\r
1044Exit:\r
1045 //\r
1046 // Fail to save the data, update the progress string.\r
1047 //\r
1048 *Progress = UpdateProgress (Offset, Configuration);\r
1049 if (Status == EFI_OUT_OF_RESOURCES) {\r
1050 return Status;\r
1051 } else {\r
1052 return EFI_NOT_FOUND;\r
1053 }\r
4af04335
DB
1054}\r
1055\r
1056/**\r
1057 This function processes the results of changes in configuration.\r
1058\r
1059\r
1060 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1061 @param Action Specifies the type of action taken by the browser.\r
1062 @param QuestionId A unique value which is sent to the original exporting driver\r
1063 so that it can identify the type of data to expect.\r
1064 @param Type The type of value for the question.\r
1065 @param Value A pointer to the data being sent to the original exporting driver.\r
1066 @param ActionRequest On return, points to the action requested by the callback function.\r
1067\r
1068 @retval EFI_SUCCESS The callback successfully handled the action.\r
1069 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
1070 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
1071 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
1072 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.\r
1073**/\r
1074EFI_STATUS\r
1075EFIAPI\r
1076BootMaintCallback (\r
1077 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1078 IN EFI_BROWSER_ACTION Action,\r
1079 IN EFI_QUESTION_ID QuestionId,\r
1080 IN UINT8 Type,\r
1081 IN EFI_IFR_TYPE_VALUE *Value,\r
1082 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
1083 )\r
1084{\r
1085 BMM_CALLBACK_DATA *Private;\r
1086 BM_MENU_ENTRY *NewMenuEntry;\r
1087 BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
7880f73a 1088 BMM_FAKE_NV_DATA *OldFakeNVMap;\r
4af04335
DB
1089 UINTN Index;\r
1090 EFI_DEVICE_PATH_PROTOCOL * File;\r
1091\r
984cb646 1092 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED && Action != EFI_BROWSER_ACTION_FORM_OPEN) {\r
4af04335 1093 //\r
984cb646 1094 // Do nothing for other UEFI Action. Only do call back when data is changed or the form is open.\r
4af04335
DB
1095 //\r
1096 return EFI_UNSUPPORTED;\r
1097 }\r
4af04335
DB
1098\r
1099 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
984cb646
DB
1100\r
1101 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
1102 if (QuestionId == KEY_VALUE_TRIGGER_FORM_OPEN_ACTION) {\r
1103 if (!mFirstEnterBMMForm) {\r
1104 //\r
1105 // BMMUiLib depends on LegacyUi library to show legacy menus.\r
1106 // If we want to show Legacy menus correctly in BMM page,\r
1107 // we must do it after the LegacyUi library has already been initialized.\r
1108 // Opening the BMM form is the appropriate time that the LegacyUi library has already been initialized.\r
1109 // So we do the tasks which are related to legacy menus here.\r
1110 // 1. Update the menus (including legacy munu) show in BootMiantenanceManager page.\r
1111 // 2. Re-scan the BootOption menus (including the legacy boot option).\r
1112 //\r
1113 CustomizeMenus ();\r
14923c1a 1114 EfiBootManagerRefreshAllBootOption ();\r
984cb646
DB
1115 BOpt_GetBootOptions (Private);\r
1116 mFirstEnterBMMForm = TRUE;\r
1117 }\r
1118 }\r
1119 }\r
4af04335 1120 //\r
3b28e744 1121 // Retrieve uncommitted data from Form Browser\r
4af04335
DB
1122 //\r
1123 CurrentFakeNVMap = &Private->BmmFakeNvData;\r
7880f73a 1124 OldFakeNVMap = &Private->BmmOldFakeNVData;\r
4af04335
DB
1125 HiiGetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);\r
1126\r
1127 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
1128 if (Value == NULL) {\r
1129 return EFI_INVALID_PARAMETER;\r
1130 }\r
1131 \r
1132 UpdatePageId (Private, QuestionId);\r
1133\r
1134 if (QuestionId < FILE_OPTION_OFFSET) {\r
1135 if (QuestionId < CONFIG_OPTION_OFFSET) {\r
1136 switch (QuestionId) {\r
1137 case FORM_BOOT_ADD_ID:\r
1138 // Leave BMM and enter FileExplorer. \r
c7d1e742 1139 ChooseFile (NULL, L".efi", CreateBootOptionFromFile, &File);\r
4af04335
DB
1140 break;\r
1141\r
1142 case FORM_DRV_ADD_FILE_ID:\r
1143 // Leave BMM and enter FileExplorer.\r
c7d1e742 1144 ChooseFile (NULL, L".efi", CreateDriverOptionFromFile, &File);\r
4af04335
DB
1145 break;\r
1146\r
1147 case FORM_DRV_ADD_HANDLE_ID:\r
1148 CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);\r
1149 UpdateDrvAddHandlePage (Private);\r
1150 break;\r
1151\r
1152 case FORM_BOOT_DEL_ID:\r
1153 CleanUpPage (FORM_BOOT_DEL_ID, Private);\r
1154 UpdateBootDelPage (Private);\r
1155 break;\r
1156\r
1157 case FORM_BOOT_CHG_ID:\r
1158 case FORM_DRV_CHG_ID:\r
1159 UpdatePageBody (QuestionId, Private);\r
1160 break;\r
1161\r
1162 case FORM_DRV_DEL_ID:\r
1163 CleanUpPage (FORM_DRV_DEL_ID, Private);\r
1164 UpdateDrvDelPage (Private);\r
1165 break;\r
1166\r
4af04335
DB
1167 case FORM_CON_IN_ID:\r
1168 case FORM_CON_OUT_ID:\r
1169 case FORM_CON_ERR_ID:\r
1170 UpdatePageBody (QuestionId, Private);\r
1171 break;\r
1172\r
1173 case FORM_CON_MODE_ID:\r
1174 CleanUpPage (FORM_CON_MODE_ID, Private);\r
1175 UpdateConModePage (Private);\r
1176 break;\r
1177\r
1178 case FORM_CON_COM_ID:\r
1179 CleanUpPage (FORM_CON_COM_ID, Private);\r
1180 UpdateConCOMPage (Private);\r
1181 break;\r
1182\r
1183 default:\r
1184 break;\r
1185 }\r
1186 } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {\r
1187 Index = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);\r
1188 Private->CurrentTerminal = Index;\r
1189\r
1190 CleanUpPage (FORM_CON_COM_SETUP_ID, Private);\r
1191 UpdateTerminalPage (Private);\r
1192\r
1193 } else if (QuestionId >= HANDLE_OPTION_OFFSET) {\r
1194 Index = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);\r
1195\r
1196 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);\r
1197 ASSERT (NewMenuEntry != NULL);\r
1198 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;\r
1199\r
1200 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);\r
1201\r
1202 Private->MenuEntry = NewMenuEntry;\r
1203 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;\r
1204\r
1205 UpdateDriverAddHandleDescPage (Private);\r
1206 }\r
1207 }\r
1208 if (QuestionId == KEY_VALUE_BOOT_FROM_FILE){\r
1209 // Leave BMM and enter FileExplorer.\r
c7d1e742 1210 ChooseFile (NULL, L".efi", BootFromFile, &File);\r
4af04335
DB
1211 }\r
1212 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
1213 if ((Value == NULL) || (ActionRequest == NULL)) {\r
1214 return EFI_INVALID_PARAMETER;\r
1215 }\r
1216 \r
1217 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT) {\r
85520606 1218 CleanUselessBeforeSubmit (Private);\r
4af04335
DB
1219 CurrentFakeNVMap->BootOptionChanged = FALSE;\r
1220 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
1221 } else if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {\r
85520606 1222 CleanUselessBeforeSubmit (Private);\r
4af04335
DB
1223 CurrentFakeNVMap->DriverOptionChanged = FALSE;\r
1224 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
1225 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {\r
1226 //\r
1227 // Discard changes and exit formset\r
1228 //\r
7880f73a
DB
1229 ZeroMem (CurrentFakeNVMap->DriverOptionalData, sizeof (CurrentFakeNVMap->DriverOptionalData));\r
1230 ZeroMem (CurrentFakeNVMap->BootDescriptionData, sizeof (CurrentFakeNVMap->BootDescriptionData));\r
1231 ZeroMem (OldFakeNVMap->DriverOptionalData, sizeof (OldFakeNVMap->DriverOptionalData));\r
1232 ZeroMem (OldFakeNVMap->DriverDescriptionData, sizeof (OldFakeNVMap->DriverDescriptionData));\r
4af04335
DB
1233 CurrentFakeNVMap->DriverOptionChanged = FALSE;\r
1234 CurrentFakeNVMap->ForceReconnect = TRUE;\r
1235 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
1236 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT) {\r
1237 //\r
1238 // Discard changes and exit formset\r
1239 //\r
7880f73a
DB
1240 ZeroMem (CurrentFakeNVMap->BootOptionalData, sizeof (CurrentFakeNVMap->BootOptionalData));\r
1241 ZeroMem (CurrentFakeNVMap->BootDescriptionData, sizeof (CurrentFakeNVMap->BootDescriptionData));\r
1242 ZeroMem (OldFakeNVMap->BootOptionalData, sizeof (OldFakeNVMap->BootOptionalData));\r
1243 ZeroMem (OldFakeNVMap->BootDescriptionData, sizeof (OldFakeNVMap->BootDescriptionData));\r
4af04335
DB
1244 CurrentFakeNVMap->BootOptionChanged = FALSE;\r
1245 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
1246 } else if (QuestionId == KEY_VALUE_BOOT_DESCRIPTION || QuestionId == KEY_VALUE_BOOT_OPTION) {\r
1247 CurrentFakeNVMap->BootOptionChanged = TRUE;\r
1248 } else if (QuestionId == KEY_VALUE_DRIVER_DESCRIPTION || QuestionId == KEY_VALUE_DRIVER_OPTION) {\r
1249 CurrentFakeNVMap->DriverOptionChanged = TRUE;\r
1250 } \r
1251\r
1252 if ((QuestionId >= BOOT_OPTION_DEL_QUESTION_ID) && (QuestionId < BOOT_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {\r
1253 if (Value->b){\r
1254 //\r
1255 // Means user try to delete this boot option but not press F10 or "Commit Changes and Exit" menu.\r
1256 //\r
1257 CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = TRUE;\r
1258 } else {\r
1259 //\r
1260 // Means user remove the old check status.\r
1261 //\r
1262 CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = FALSE;\r
1263 }\r
1264 } else if ((QuestionId >= DRIVER_OPTION_DEL_QUESTION_ID) && (QuestionId < DRIVER_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {\r
1265 if (Value->b){\r
1266 CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = TRUE;\r
1267 } else {\r
1268 CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = FALSE;\r
1269 }\r
1270 } else {\r
1271 switch (QuestionId) {\r
1272 case KEY_VALUE_SAVE_AND_EXIT:\r
1273 case KEY_VALUE_NO_SAVE_AND_EXIT:\r
1274 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {\r
85520606 1275 CleanUselessBeforeSubmit (Private);\r
4af04335
DB
1276 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
1277 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {\r
1278 DiscardChangeHandler (Private, CurrentFakeNVMap);\r
1279 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
1280 }\r
1281\r
1282 break;\r
1283\r
1284 case FORM_RESET:\r
1285 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
1286 return EFI_UNSUPPORTED;\r
1287\r
1288 default:\r
1289 break;\r
1290 }\r
1291 }\r
a3475fe0
DB
1292 //\r
1293 // Update the content in Terminal menu and Console menu here.\r
1294 //\r
1295 if (QuestionId == COM_BAUD_RATE_QUESTION_ID + Private->CurrentTerminal || QuestionId == COM_DATA_RATE_QUESTION_ID + Private->CurrentTerminal ||\r
1296 QuestionId == COM_PARITY_QUESTION_ID + Private->CurrentTerminal || QuestionId == COM_STOP_BITS_QUESTION_ID + Private->CurrentTerminal ||\r
1297 QuestionId == COM_TERMINAL_QUESTION_ID + Private->CurrentTerminal || QuestionId == COM_FLOWCONTROL_QUESTION_ID + Private->CurrentTerminal\r
1298 ) {\r
1299 UpdateTerminalContent(CurrentFakeNVMap);\r
1300 }\r
1301 if ((QuestionId >= CON_IN_DEVICE_QUESTION_ID) && (QuestionId < CON_IN_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {\r
1302 UpdateConsoleContent (L"ConIn",CurrentFakeNVMap);\r
1303 } else if ((QuestionId >= CON_OUT_DEVICE_QUESTION_ID) && (QuestionId < CON_OUT_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {\r
1304 UpdateConsoleContent (L"ConOut", CurrentFakeNVMap);\r
1305 } else if ((QuestionId >= CON_ERR_DEVICE_QUESTION_ID) && (QuestionId < CON_ERR_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {\r
983f5993 1306 UpdateConsoleContent (L"ErrOut", CurrentFakeNVMap);\r
a3475fe0 1307 }\r
4af04335
DB
1308 }\r
1309\r
1310 //\r
1311 // Pass changed uncommitted data back to Form Browser\r
1312 //\r
1313 HiiSetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);\r
1314\r
1315 return EFI_SUCCESS;\r
1316}\r
1317\r
1318/**\r
1319 Discard all changes done to the BMM pages such as Boot Order change,\r
1320 Driver order change.\r
1321\r
1322 @param Private The BMM context data.\r
1323 @param CurrentFakeNVMap The current Fack NV Map.\r
1324\r
1325**/\r
1326VOID\r
1327DiscardChangeHandler (\r
1328 IN BMM_CALLBACK_DATA *Private,\r
1329 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap\r
1330 )\r
1331{\r
1332 UINT16 Index;\r
1333\r
1334 switch (Private->BmmPreviousPageId) {\r
1335 case FORM_BOOT_CHG_ID:\r
1336 CopyMem (CurrentFakeNVMap->BootOptionOrder, Private->BmmOldFakeNVData.BootOptionOrder, sizeof (CurrentFakeNVMap->BootOptionOrder));\r
1337 break;\r
1338\r
1339 case FORM_DRV_CHG_ID:\r
1340 CopyMem (CurrentFakeNVMap->DriverOptionOrder, Private->BmmOldFakeNVData.DriverOptionOrder, sizeof (CurrentFakeNVMap->DriverOptionOrder));\r
1341 break;\r
1342\r
1343 case FORM_BOOT_DEL_ID:\r
1344 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));\r
1345 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
1346 CurrentFakeNVMap->BootOptionDel[Index] = FALSE;\r
1347 }\r
1348 break;\r
1349\r
1350 case FORM_DRV_DEL_ID:\r
1351 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));\r
1352 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
1353 CurrentFakeNVMap->DriverOptionDel[Index] = FALSE;\r
1354 }\r
1355 break;\r
1356\r
1357 case FORM_BOOT_NEXT_ID:\r
1358 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;\r
1359 break;\r
1360\r
1361 case FORM_TIME_OUT_ID:\r
1362 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;\r
1363 break;\r
1364\r
1365 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
1366 case FORM_DRV_ADD_FILE_ID:\r
1367 case FORM_DRV_ADD_HANDLE_ID:\r
1368 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;\r
1369 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;\r
1370 break;\r
1371\r
1372 default:\r
1373 break;\r
1374 }\r
1375}\r
1376\r
85520606
DB
1377/**\r
1378 This function is to clean some useless data before submit changes.\r
1379\r
1380 @param Private The BMM context data.\r
1381\r
1382**/\r
1383VOID\r
1384CleanUselessBeforeSubmit (\r
1385 IN BMM_CALLBACK_DATA *Private\r
1386 )\r
1387{\r
1388 UINT16 Index;\r
1389 if (Private->BmmPreviousPageId != FORM_BOOT_DEL_ID) {\r
1390 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
1391 if (Private->BmmFakeNvData.BootOptionDel[Index] && !Private->BmmFakeNvData.BootOptionDelMark[Index]) {\r
1392 Private->BmmFakeNvData.BootOptionDel[Index] = FALSE;\r
1393 Private->BmmOldFakeNVData.BootOptionDel[Index] = FALSE;\r
1394 }\r
1395 }\r
1396 }\r
1397 if (Private->BmmPreviousPageId != FORM_DRV_DEL_ID) {\r
1398 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
1399 if (Private->BmmFakeNvData.DriverOptionDel[Index] && !Private->BmmFakeNvData.DriverOptionDelMark[Index]) {\r
1400 Private->BmmFakeNvData.DriverOptionDel[Index] = FALSE;\r
1401 Private->BmmOldFakeNVData.DriverOptionDel[Index] = FALSE;\r
1402 }\r
1403 }\r
1404 }\r
1405}\r
1406\r
4af04335 1407/**\r
4af04335 1408\r
a85be3ae 1409 Update the menus in the BMM page.\r
4af04335
DB
1410\r
1411**/\r
1412VOID\r
a85be3ae
ED
1413CustomizeMenus (\r
1414 VOID\r
4af04335
DB
1415 )\r
1416{\r
4af04335
DB
1417 VOID *StartOpCodeHandle;\r
1418 VOID *EndOpCodeHandle;\r
a85be3ae
ED
1419 EFI_IFR_GUID_LABEL *StartGuidLabel;\r
1420 EFI_IFR_GUID_LABEL *EndGuidLabel;\r
1421\r
4af04335
DB
1422 //\r
1423 // Allocate space for creation of UpdateData Buffer\r
1424 //\r
1425 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1426 ASSERT (StartOpCodeHandle != NULL);\r
1427\r
1428 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1429 ASSERT (EndOpCodeHandle != NULL);\r
4af04335
DB
1430 //\r
1431 // Create Hii Extend Label OpCode as the start opcode\r
1432 //\r
a85be3ae
ED
1433 StartGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1434 StartGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1435 StartGuidLabel->Number = LABEL_FORM_MAIN_START;\r
4af04335
DB
1436 //\r
1437 // Create Hii Extend Label OpCode as the end opcode\r
1438 //\r
a85be3ae
ED
1439 EndGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1440 EndGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1441 EndGuidLabel->Number = LABEL_FORM_MAIN_END;\r
4af04335
DB
1442\r
1443 //\r
a85be3ae 1444 //Updata Front Page form\r
4af04335 1445 //\r
a85be3ae
ED
1446 UiCustomizeBMMPage (\r
1447 mBmmCallbackInfo->BmmHiiHandle,\r
1448 StartOpCodeHandle\r
1449 );\r
4af04335 1450\r
4af04335 1451 HiiUpdateForm (\r
a85be3ae 1452 mBmmCallbackInfo->BmmHiiHandle,\r
4af04335
DB
1453 &mBootMaintGuid,\r
1454 FORM_MAIN_ID,\r
1455 StartOpCodeHandle,\r
1456 EndOpCodeHandle\r
1457 );\r
1458\r
1459 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
a85be3ae 1460 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
4af04335
DB
1461}\r
1462\r
1463/**\r
1464 Create dynamic code for BMM and initialize all of BMM configuration data in BmmFakeNvData and\r
1465 BmmOldFakeNVData member in BMM context data.\r
1466\r
1467 @param CallbackData The BMM context data.\r
1468\r
1469**/\r
1470VOID\r
1471InitializeBmmConfig (\r
1472 IN BMM_CALLBACK_DATA *CallbackData\r
1473 )\r
1474{\r
1475 BM_MENU_ENTRY *NewMenuEntry;\r
1476 BM_LOAD_CONTEXT *NewLoadContext;\r
1477 UINT16 Index;\r
1478\r
1479 ASSERT (CallbackData != NULL);\r
1480\r
4af04335
DB
1481 //\r
1482 // Initialize data which located in BMM main page\r
1483 //\r
f7986526 1484 CallbackData->BmmFakeNvData.BootNext = NONE_BOOTNEXT_VALUE;\r
4af04335
DB
1485 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
1486 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
1487 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
1488\r
1489 if (NewLoadContext->IsBootNext) {\r
1490 CallbackData->BmmFakeNvData.BootNext = Index;\r
1491 break;\r
1492 }\r
1493 }\r
1494\r
1495 CallbackData->BmmFakeNvData.BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut);\r
1496\r
1497 //\r
1498 // Initialize data which located in Boot Options Menu\r
1499 //\r
1500 GetBootOrder (CallbackData);\r
1501\r
1502 //\r
1503 // Initialize data which located in Driver Options Menu\r
1504 //\r
1505 GetDriverOrder (CallbackData);\r
1506\r
1507 //\r
1508 // Initialize data which located in Console Options Menu\r
1509 //\r
1510 GetConsoleOutMode (CallbackData);\r
1511 GetConsoleInCheck (CallbackData);\r
1512 GetConsoleOutCheck (CallbackData);\r
1513 GetConsoleErrCheck (CallbackData);\r
1514 GetTerminalAttribute (CallbackData);\r
1515\r
1516 CallbackData->BmmFakeNvData.ForceReconnect = TRUE;\r
1517\r
1518 //\r
1519 // Backup Initialize BMM configuartion data to BmmOldFakeNVData\r
1520 //\r
1521 CopyMem (&CallbackData->BmmOldFakeNVData, &CallbackData->BmmFakeNvData, sizeof (BMM_FAKE_NV_DATA));\r
1522}\r
1523\r
1524/**\r
1525 Initialized all Menu Option List.\r
1526\r
1527 @param CallbackData The BMM context data.\r
1528\r
1529**/\r
1530VOID\r
1531InitAllMenu (\r
1532 IN BMM_CALLBACK_DATA *CallbackData\r
1533 )\r
1534{\r
1535 InitializeListHead (&BootOptionMenu.Head);\r
1536 InitializeListHead (&DriverOptionMenu.Head);\r
1537 BOpt_GetBootOptions (CallbackData);\r
1538 BOpt_GetDriverOptions (CallbackData);\r
1539 BOpt_FindDrivers ();\r
1540 InitializeListHead (&ConsoleInpMenu.Head);\r
1541 InitializeListHead (&ConsoleOutMenu.Head);\r
1542 InitializeListHead (&ConsoleErrMenu.Head);\r
1543 InitializeListHead (&TerminalMenu.Head);\r
1544 LocateSerialIo ();\r
1545 GetAllConsoles ();\r
1546 mAllMenuInit = TRUE;\r
1547}\r
1548\r
1549/**\r
1550 Free up all Menu Option list.\r
1551\r
1552**/\r
1553VOID\r
1554FreeAllMenu (\r
1555 VOID\r
1556 )\r
1557{\r
1558 if (!mAllMenuInit){\r
1559 return;\r
1560 }\r
1561 BOpt_FreeMenu (&BootOptionMenu);\r
1562 BOpt_FreeMenu (&DriverOptionMenu);\r
1563 BOpt_FreeMenu (&DriverMenu);\r
1564 FreeAllConsoles ();\r
1565 mAllMenuInit = FALSE;\r
1566}\r
1567\r
8c53b5e6
ED
1568/**\r
1569 Initial the boot mode related parameters.\r
1570\r
1571**/\r
1572VOID\r
1573BmmInitialBootModeInfo (\r
1574 VOID\r
1575 )\r
1576{\r
1577 EFI_STATUS Status;\r
1578 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1579 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;\r
1580 UINTN BootTextColumn;\r
1581 UINTN BootTextRow;\r
1582\r
1583 if (mBmmModeInitialized) {\r
1584 return;\r
1585 }\r
1586\r
1587 //\r
1588 // After the console is ready, get current video resolution\r
1589 // and text mode before launching setup at first time.\r
1590 //\r
1591 Status = gBS->HandleProtocol (\r
1592 gST->ConsoleOutHandle,\r
1593 &gEfiGraphicsOutputProtocolGuid,\r
1594 (VOID**)&GraphicsOutput\r
1595 );\r
1596 if (EFI_ERROR (Status)) {\r
1597 GraphicsOutput = NULL;\r
1598 }\r
1599\r
1600 Status = gBS->HandleProtocol (\r
1601 gST->ConsoleOutHandle,\r
1602 &gEfiSimpleTextOutProtocolGuid,\r
1603 (VOID**)&SimpleTextOut\r
1604 );\r
1605 if (EFI_ERROR (Status)) {\r
1606 SimpleTextOut = NULL;\r
1607 }\r
1608\r
1609 if (GraphicsOutput != NULL) {\r
1610 //\r
1611 // Get current video resolution and text mode.\r
1612 //\r
1613 mBmmBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
1614 mBmmBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
1615 }\r
1616\r
1617 if (SimpleTextOut != NULL) {\r
1618 Status = SimpleTextOut->QueryMode (\r
1619 SimpleTextOut,\r
1620 SimpleTextOut->Mode->Mode,\r
1621 &BootTextColumn,\r
1622 &BootTextRow\r
1623 );\r
1624 mBmmBootTextModeColumn = (UINT32)BootTextColumn;\r
1625 mBmmBootTextModeRow = (UINT32)BootTextRow;\r
1626 }\r
1627\r
1628 //\r
1629 // Get user defined text mode for setup.\r
1630 //\r
1631 mBmmSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);\r
1632 mBmmSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);\r
1633 mBmmSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);\r
1634 mBmmSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);\r
1635\r
1636 mBmmModeInitialized = TRUE;\r
1637}\r
1638\r
4af04335
DB
1639/**\r
1640\r
1641 Install Boot Maintenance Manager Menu driver.\r
1642\r
1643 @param ImageHandle The image handle.\r
1644 @param SystemTable The system table.\r
1645\r
1646 @retval EFI_SUCEESS Install Boot manager menu success.\r
1647 @retval Other Return error status.\r
1648\r
1649**/\r
1650EFI_STATUS\r
1651EFIAPI\r
13c4e864 1652BootMaintenanceManagerUiLibConstructor (\r
4af04335
DB
1653 IN EFI_HANDLE ImageHandle,\r
1654 IN EFI_SYSTEM_TABLE *SystemTable\r
1655 )\r
1656\r
1657{\r
1658 EFI_STATUS Status;\r
1659 UINT8 *Ptr;\r
1660\r
1661 Status = EFI_SUCCESS;\r
1662\r
1663 //\r
1664 // Install Device Path Protocol and Config Access protocol to driver handle\r
1665 //\r
1666 Status = gBS->InstallMultipleProtocolInterfaces (\r
1667 &mBmmCallbackInfo->BmmDriverHandle,\r
1668 &gEfiDevicePathProtocolGuid,\r
1669 &mBmmHiiVendorDevicePath,\r
1670 &gEfiHiiConfigAccessProtocolGuid,\r
1671 &mBmmCallbackInfo->BmmConfigAccess,\r
1672 NULL\r
1673 );\r
1674 ASSERT_EFI_ERROR (Status);\r
1675\r
1676 //\r
1677 // Post our Boot Maint VFR binary to the HII database.\r
1678 //\r
1679 mBmmCallbackInfo->BmmHiiHandle = HiiAddPackages (\r
1680 &mBootMaintGuid,\r
1681 mBmmCallbackInfo->BmmDriverHandle,\r
1682 BootMaintenanceManagerBin,\r
13c4e864 1683 BootMaintenanceManagerUiLibStrings,\r
4af04335
DB
1684 NULL\r
1685 );\r
1686 ASSERT (mBmmCallbackInfo->BmmHiiHandle != NULL);\r
1687\r
1688 //\r
1689 // Locate Formbrowser2 protocol\r
1690 //\r
1691 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &mBmmCallbackInfo->FormBrowser2);\r
1692 ASSERT_EFI_ERROR (Status);\r
1693\r
4af04335
DB
1694 //\r
1695 // Create LoadOption in BmmCallbackInfo for Driver Callback\r
1696 //\r
1697 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));\r
1698 ASSERT (Ptr != NULL);\r
1699\r
1700 //\r
1701 // Initialize Bmm callback data.\r
1702 //\r
1703 mBmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;\r
1704 Ptr += sizeof (BM_LOAD_CONTEXT);\r
1705\r
1706 mBmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;\r
1707 Ptr += sizeof (BM_FILE_CONTEXT);\r
1708\r
1709 mBmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;\r
1710 Ptr += sizeof (BM_HANDLE_CONTEXT);\r
1711\r
1712 mBmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;\r
1713\r
1714 mBmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;\r
1715 mBmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;\r
1716\r
1717 InitAllMenu (mBmmCallbackInfo);\r
1718\r
1719 CreateUpdateData();\r
1720 //\r
1721 // Update boot maintenance manager page \r
1722 //\r
1723 InitializeBmmConfig(mBmmCallbackInfo);\r
1724\r
8c53b5e6
ED
1725 BmmInitialBootModeInfo();\r
1726\r
4af04335
DB
1727 return EFI_SUCCESS;\r
1728}\r
1729\r
1730/**\r
1731 Unloads the application and its installed protocol.\r
1732\r
1733 @param ImageHandle Handle that identifies the image to be unloaded.\r
1734 @param SystemTable The system table.\r
1735\r
1736 @retval EFI_SUCCESS The image has been unloaded.\r
1737\r
1738**/\r
1739EFI_STATUS\r
1740EFIAPI\r
13c4e864 1741BootMaintenanceManagerUiLibDestructor (\r
4af04335
DB
1742 IN EFI_HANDLE ImageHandle,\r
1743 IN EFI_SYSTEM_TABLE *SystemTable\r
1744 )\r
1745\r
1746{\r
1747 if (mStartOpCodeHandle != NULL) {\r
1748 HiiFreeOpCodeHandle (mStartOpCodeHandle);\r
1749 }\r
1750\r
1751 if (mEndOpCodeHandle != NULL) {\r
1752 HiiFreeOpCodeHandle (mEndOpCodeHandle);\r
1753 }\r
1754\r
1755 FreeAllMenu ();\r
1756\r
1757 //\r
1758 // Remove our IFR data from HII database\r
1759 //\r
1760 HiiRemovePackages (mBmmCallbackInfo->BmmHiiHandle);\r
1761\r
1762 gBS->UninstallMultipleProtocolInterfaces (\r
1763 mBmmCallbackInfo->BmmDriverHandle,\r
1764 &gEfiDevicePathProtocolGuid,\r
1765 &mBmmHiiVendorDevicePath,\r
1766 &gEfiHiiConfigAccessProtocolGuid,\r
1767 &mBmmCallbackInfo->BmmConfigAccess,\r
1768 NULL\r
1769 );\r
1770\r
1771 FreePool (mBmmCallbackInfo->LoadContext);\r
1772\r
1773 return EFI_SUCCESS;\r
1774}\r
1775\r