]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c
MdeModulePkg/Library: Fix typos in comments and variables
[mirror_edk2.git] / MdeModulePkg / Library / BootMaintenanceManagerUiLib / BootMaintenance.c
CommitLineData
4af04335
DB
1/** @file\r
2The functions for Boot Maintainence Main menu.\r
3\r
c7d310dd 4Copyright (c) 2004 - 2016, 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
551 ASSERT (BmmData->COMBaudRate[Index] < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));\r
552 NewTerminalContext->BaudRate = BaudRateList[BmmData->COMBaudRate[Index]].Value;\r
553 NewTerminalContext->DataBitsIndex = BmmData->COMDataRate[Index];\r
554 ASSERT (BmmData->COMDataRate[Index] < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));\r
555 NewTerminalContext->DataBits = (UINT8) DataBitsList[BmmData->COMDataRate[Index]].Value;\r
556 NewTerminalContext->StopBitsIndex = BmmData->COMStopBits[Index];\r
557 ASSERT (BmmData->COMStopBits[Index] < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));\r
558 NewTerminalContext->StopBits = (UINT8) StopBitsList[BmmData->COMStopBits[Index]].Value;\r
559 NewTerminalContext->ParityIndex = BmmData->COMParity[Index];\r
560 ASSERT (BmmData->COMParity[Index] < (sizeof (ParityList) / sizeof (ParityList[0])));\r
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
574 @param BmmData The BMM fake NV data.\r
575\r
576**/\r
577VOID\r
578UpdateConsoleContent(\r
579 IN CHAR16 *ConsoleName,\r
580 IN BMM_FAKE_NV_DATA *BmmData\r
581 )\r
582{\r
583 UINT16 Index;\r
584 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
585 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
586 BM_MENU_ENTRY *NewMenuEntry;\r
587\r
588 if (StrCmp (ConsoleName, L"ConIn") == 0) {\r
589 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++){\r
590 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleInpMenu, Index);\r
591 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;\r
592 ASSERT (Index < MAX_MENU_NUMBER);\r
593 NewConsoleContext->IsActive = BmmData->ConsoleInCheck[Index];\r
594 }\r
595 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
596 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
597 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
598 ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);\r
599 NewTerminalContext->IsConIn = BmmData->ConsoleInCheck[Index + ConsoleInpMenu.MenuNumber];\r
600 }\r
601 }\r
602\r
603 if (StrCmp (ConsoleName, L"ConOut") == 0) {\r
604 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++){\r
605 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleOutMenu, Index);\r
606 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;\r
607 ASSERT (Index < MAX_MENU_NUMBER);\r
608 NewConsoleContext->IsActive = BmmData->ConsoleOutCheck[Index];\r
609 }\r
610 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
611 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
612 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
613 ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);\r
614 NewTerminalContext->IsConOut = BmmData->ConsoleOutCheck[Index + ConsoleOutMenu.MenuNumber];\r
615 }\r
616 }\r
617 if (StrCmp (ConsoleName, L"ErrOut") == 0) {\r
618 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++){\r
619 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleErrMenu, Index);\r
620 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;\r
621 ASSERT (Index < MAX_MENU_NUMBER);\r
622 NewConsoleContext->IsActive = BmmData->ConsoleErrCheck[Index];\r
623 }\r
624 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
625 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
626 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
627 ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);\r
628 NewTerminalContext->IsStdErr = BmmData->ConsoleErrCheck[Index + ConsoleErrMenu.MenuNumber];\r
629 }\r
630 }\r
631}\r
632\r
4af04335
DB
633/**\r
634 This function allows a caller to extract the current configuration for one\r
635 or more named elements from the target driver.\r
636\r
637 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
638 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
639 @param Progress On return, points to a character in the Request string.\r
640 Points to the string's null terminator if request was successful.\r
641 Points to the most recent '&' before the first failing name/value\r
642 pair (or the beginning of the string if the failure is in the\r
643 first name/value pair) if the request was not successful.\r
644 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
645 has all values filled in for the names in the Request string.\r
646 String to be allocated by the called function.\r
647\r
648 @retval EFI_SUCCESS The Results is filled with the requested values.\r
649 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
650 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
651 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
652\r
653**/\r
654EFI_STATUS\r
655EFIAPI\r
656BootMaintExtractConfig (\r
657 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
658 IN CONST EFI_STRING Request,\r
659 OUT EFI_STRING *Progress,\r
660 OUT EFI_STRING *Results\r
661 )\r
662{\r
663 EFI_STATUS Status;\r
664 UINTN BufferSize;\r
665 BMM_CALLBACK_DATA *Private;\r
666 EFI_STRING ConfigRequestHdr;\r
667 EFI_STRING ConfigRequest;\r
668 BOOLEAN AllocatedRequest;\r
669 UINTN Size;\r
670\r
671 if (Progress == NULL || Results == NULL) {\r
672 return EFI_INVALID_PARAMETER;\r
673 }\r
674\r
675 *Progress = Request;\r
676 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mBootMaintGuid, mBootMaintStorageName)) {\r
677 return EFI_NOT_FOUND;\r
678 }\r
679\r
680 ConfigRequestHdr = NULL;\r
681 ConfigRequest = NULL;\r
682 AllocatedRequest = FALSE;\r
683 Size = 0;\r
684\r
685 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
686 //\r
687 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
688 //\r
689 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
690 ConfigRequest = Request;\r
691 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
692 //\r
693 // Request has no request element, construct full request string.\r
694 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
695 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
696 //\r
697 ConfigRequestHdr = HiiConstructConfigHdr (&mBootMaintGuid, mBootMaintStorageName, Private->BmmDriverHandle);\r
698 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
699 ConfigRequest = AllocateZeroPool (Size);\r
700 ASSERT (ConfigRequest != NULL);\r
701 AllocatedRequest = TRUE;\r
702 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
703 FreePool (ConfigRequestHdr);\r
704 }\r
705\r
706 Status = gHiiConfigRouting->BlockToConfig (\r
707 gHiiConfigRouting,\r
708 ConfigRequest,\r
709 (UINT8 *) &Private->BmmFakeNvData,\r
710 BufferSize,\r
711 Results,\r
712 Progress\r
713 );\r
714 //\r
715 // Free the allocated config request string.\r
716 //\r
717 if (AllocatedRequest) {\r
718 FreePool (ConfigRequest);\r
719 ConfigRequest = NULL;\r
720 }\r
721 //\r
722 // Set Progress string to the original request string.\r
723 //\r
724 if (Request == NULL) {\r
725 *Progress = NULL;\r
726 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
727 *Progress = Request + StrLen (Request);\r
728 }\r
729\r
730 return Status;\r
731}\r
732\r
733/**\r
734 This function applies changes in a driver's configuration.\r
735 Input is a Configuration, which has the routing data for this\r
736 driver followed by name / value configuration pairs. The driver\r
737 must apply those pairs to its configurable storage. If the\r
738 driver's configuration is stored in a linear block of data\r
739 and the driver's name / value pairs are in <BlockConfig>\r
740 format, it may use the ConfigToBlock helper function (above) to\r
741 simplify the job. Currently not implemented.\r
742\r
743 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
744 @param[in] Configuration A null-terminated Unicode string in\r
745 <ConfigString> format. \r
746 @param[out] Progress A pointer to a string filled in with the\r
747 offset of the most recent '&' before the\r
748 first failing name / value pair (or the\r
749 beginn ing of the string if the failure\r
750 is in the first name / value pair) or\r
751 the terminating NULL if all was\r
752 successful.\r
753\r
754 @retval EFI_SUCCESS The results have been distributed or are\r
755 awaiting distribution. \r
756 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
757 parts of the results that must be\r
758 stored awaiting possible future\r
759 protocols.\r
760 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
761 Results parameter would result\r
762 in this type of error.\r
763 @retval EFI_NOT_FOUND Target for the specified routing data\r
764 was not found.\r
765**/\r
766EFI_STATUS\r
767EFIAPI\r
768BootMaintRouteConfig (\r
769 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
770 IN CONST EFI_STRING Configuration,\r
771 OUT EFI_STRING *Progress\r
772 )\r
773{\r
774 EFI_STATUS Status;\r
775 UINTN BufferSize;\r
776 EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;\r
777 BMM_FAKE_NV_DATA *NewBmmData;\r
778 BMM_FAKE_NV_DATA *OldBmmData;\r
4af04335
DB
779 BM_MENU_ENTRY *NewMenuEntry;\r
780 BM_LOAD_CONTEXT *NewLoadContext;\r
781 UINT16 Index;\r
782 BOOLEAN TerminalAttChange;\r
201fbce6
DB
783 BMM_CALLBACK_DATA *Private;\r
784 UINTN Offset;\r
4af04335
DB
785\r
786 if (Progress == NULL) {\r
787 return EFI_INVALID_PARAMETER;\r
788 }\r
789 *Progress = Configuration;\r
790\r
791 if (Configuration == NULL) {\r
792 return EFI_INVALID_PARAMETER;\r
793 }\r
794\r
795 //\r
796 // Check routing data in <ConfigHdr>.\r
797 // Note: there is no name for Name/Value storage, only GUID will be checked\r
798 //\r
799 if (!HiiIsConfigHdrMatch (Configuration, &mBootMaintGuid, mBootMaintStorageName)) {\r
800 return EFI_NOT_FOUND;\r
801 }\r
802\r
803 Status = gBS->LocateProtocol (\r
804 &gEfiHiiConfigRoutingProtocolGuid, \r
805 NULL, \r
806 (VOID **)&ConfigRouting\r
807 );\r
808 if (EFI_ERROR (Status)) {\r
809 return Status;\r
810 }\r
811\r
812 Private = BMM_CALLBACK_DATA_FROM_THIS (This); \r
813 //\r
814 // Get Buffer Storage data from EFI variable\r
815 //\r
816 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
817 OldBmmData = &Private->BmmOldFakeNVData;\r
818 NewBmmData = &Private->BmmFakeNvData;\r
201fbce6 819 Offset = 0;\r
4af04335
DB
820 //\r
821 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
822 //\r
823 Status = ConfigRouting->ConfigToBlock (\r
824 ConfigRouting,\r
825 Configuration,\r
826 (UINT8 *) NewBmmData,\r
827 &BufferSize,\r
828 Progress\r
829 );\r
830 ASSERT_EFI_ERROR (Status); \r
831 //\r
832 // Compare new and old BMM configuration data and only do action for modified item to \r
833 // avoid setting unnecessary non-volatile variable\r
834 //\r
835\r
836 //\r
837 // Check data which located in BMM main page and save the settings if need\r
838 // \r
839 if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {\r
840 Status = Var_UpdateBootNext (Private);\r
201fbce6
DB
841 if (EFI_ERROR (Status)) {\r
842 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootNext);\r
843 goto Exit;\r
844 }\r
4af04335
DB
845 }\r
846\r
847 //\r
848 // Check data which located in Boot Options Menu and save the settings if need\r
849 // \r
850 if (CompareMem (NewBmmData->BootOptionDel, OldBmmData->BootOptionDel, sizeof (NewBmmData->BootOptionDel)) != 0) { \r
851 for (Index = 0; \r
852 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->BootOptionDel) / sizeof (NewBmmData->BootOptionDel[0])))); \r
853 Index ++) {\r
854 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
855 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
856 NewLoadContext->Deleted = NewBmmData->BootOptionDel[Index];\r
857 NewBmmData->BootOptionDel[Index] = FALSE;\r
858 NewBmmData->BootOptionDelMark[Index] = FALSE;\r
859 }\r
860\r
201fbce6
DB
861 Status = Var_DelBootOption ();\r
862 if (EFI_ERROR (Status)) {\r
863 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionDel);\r
864 goto Exit;\r
865 }\r
4af04335
DB
866 }\r
867\r
868 if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) {\r
869 Status = Var_UpdateBootOrder (Private);\r
201fbce6
DB
870 if (EFI_ERROR (Status)) {\r
871 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionOrder);\r
872 goto Exit;\r
873 }\r
4af04335
DB
874 }\r
875\r
876 if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0){\r
877 Status = gRT->SetVariable(\r
878 L"Timeout",\r
879 &gEfiGlobalVariableGuid,\r
880 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
881 sizeof(UINT16),\r
882 &(NewBmmData->BootTimeOut)\r
883 );\r
c7d310dd 884 if (EFI_ERROR (Status)) {\r
201fbce6
DB
885 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootTimeOut);\r
886 goto Exit;\r
c7d310dd 887 }\r
4af04335
DB
888 Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut;\r
889 }\r
890\r
891 //\r
892 // Check data which located in Driver Options Menu and save the settings if need\r
893 // \r
894 if (CompareMem (NewBmmData->DriverOptionDel, OldBmmData->DriverOptionDel, sizeof (NewBmmData->DriverOptionDel)) != 0) { \r
895 for (Index = 0; \r
896 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->DriverOptionDel) / sizeof (NewBmmData->DriverOptionDel[0])))); \r
897 Index++) {\r
898 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
899 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
900 NewLoadContext->Deleted = NewBmmData->DriverOptionDel[Index];\r
901 NewBmmData->DriverOptionDel[Index] = FALSE;\r
902 NewBmmData->DriverOptionDelMark[Index] = FALSE;\r
903 }\r
201fbce6
DB
904 Status = Var_DelDriverOption ();\r
905 if (EFI_ERROR (Status)) {\r
906 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionDel);\r
907 goto Exit;\r
908 }\r
4af04335
DB
909 }\r
910\r
911 if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) { \r
912 Status = Var_UpdateDriverOrder (Private);\r
201fbce6
DB
913 if (EFI_ERROR (Status)) {\r
914 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionOrder);\r
915 goto Exit;\r
916 }\r
4af04335
DB
917 }\r
918\r
919 if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0){\r
201fbce6
DB
920 Status = Var_UpdateConMode(Private);\r
921 if (EFI_ERROR (Status)) {\r
922 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutMode);\r
923 goto Exit;\r
924 }\r
4af04335
DB
925 }\r
926\r
927 TerminalAttChange = FALSE;\r
928 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
929\r
930 //\r
931 // only need update modified items\r
932 //\r
933 if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) == 0 &&\r
934 CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) == 0 &&\r
935 CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) == 0 &&\r
936 CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) == 0 &&\r
937 CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) == 0 &&\r
938 CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) == 0) {\r
939 continue;\r
940 }\r
941\r
4af04335
DB
942 TerminalAttChange = TRUE;\r
943 }\r
944 if (TerminalAttChange) {\r
201fbce6
DB
945 if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) != 0) {\r
946 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMBaudRate);\r
947 } else if (CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) != 0) {\r
948 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMDataRate);\r
949 } else if (CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) != 0) {\r
950 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMStopBits);\r
951 } else if (CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) != 0) {\r
952 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMParity);\r
953 } else if (CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) != 0) {\r
954 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMTerminalType);\r
955 } else if (CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) != 0) {\r
956 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMFlowControl);\r
957 }\r
958 Status = Var_UpdateConsoleInpOption ();\r
959 if (EFI_ERROR (Status)) {\r
960 goto Exit;\r
961 }\r
962 Status = Var_UpdateConsoleOutOption ();\r
963 if (EFI_ERROR (Status)) {\r
964 goto Exit;\r
965 }\r
966 Status = Var_UpdateErrorOutOption ();\r
967 if (EFI_ERROR (Status)) {\r
968 goto Exit;\r
969 }\r
4af04335
DB
970 }\r
971 //\r
972 // Check data which located in Console Options Menu and save the settings if need\r
973 //\r
974 if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, sizeof (NewBmmData->ConsoleInCheck)) != 0){\r
201fbce6
DB
975 Status = Var_UpdateConsoleInpOption();\r
976 if (EFI_ERROR (Status)) {\r
977 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleInCheck);\r
978 goto Exit;\r
979 }\r
4af04335
DB
980 }\r
981\r
982 if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, sizeof (NewBmmData->ConsoleOutCheck)) != 0){\r
201fbce6
DB
983 Status = Var_UpdateConsoleOutOption();\r
984 if (EFI_ERROR (Status)) {\r
985 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutCheck);\r
986 goto Exit;\r
987 }\r
4af04335
DB
988 }\r
989\r
990 if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, sizeof (NewBmmData->ConsoleErrCheck)) != 0){\r
201fbce6
DB
991 Status = Var_UpdateErrorOutOption();\r
992 if (EFI_ERROR (Status)) {\r
993 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleErrCheck);\r
994 goto Exit;\r
995 }\r
4af04335
DB
996 }\r
997\r
998 if (CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0 ||\r
999 CompareMem (NewBmmData->BootOptionalData, OldBmmData->BootOptionalData, sizeof (NewBmmData->BootOptionalData)) != 0) {\r
1000 Status = Var_UpdateBootOption (Private);\r
1001 NewBmmData->BootOptionChanged = FALSE;\r
1002 if (EFI_ERROR (Status)) {\r
201fbce6
DB
1003 if (CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0) {\r
1004 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootDescriptionData);\r
1005 } else {\r
1006 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionalData);\r
1007 }\r
1008 goto Exit;\r
4af04335
DB
1009 }\r
1010 BOpt_GetBootOptions (Private);\r
1011 }\r
1012\r
1013 if (CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0 ||\r
1014 CompareMem (NewBmmData->DriverOptionalData, OldBmmData->DriverOptionalData, sizeof (NewBmmData->DriverOptionalData)) != 0) {\r
1015 Status = Var_UpdateDriverOption (\r
1016 Private,\r
1017 Private->BmmHiiHandle,\r
1018 NewBmmData->DriverDescriptionData,\r
1019 NewBmmData->DriverOptionalData,\r
1020 NewBmmData->ForceReconnect\r
1021 );\r
1022 NewBmmData->DriverOptionChanged = FALSE;\r
1023 NewBmmData->ForceReconnect = TRUE;\r
1024 if (EFI_ERROR (Status)) {\r
201fbce6
DB
1025 if (CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0) {\r
1026 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverDescriptionData);\r
1027 } else {\r
1028 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionalData);\r
1029 }\r
1030 goto Exit;\r
4af04335
DB
1031 }\r
1032\r
1033 BOpt_GetDriverOptions (Private);\r
1034 }\r
1035\r
1036 //\r
1037 // After user do the save action, need to update OldBmmData.\r
1038 //\r
1039 CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));\r
1040\r
1041 return EFI_SUCCESS;\r
201fbce6
DB
1042\r
1043Exit:\r
1044 //\r
1045 // Fail to save the data, update the progress string.\r
1046 //\r
1047 *Progress = UpdateProgress (Offset, Configuration);\r
1048 if (Status == EFI_OUT_OF_RESOURCES) {\r
1049 return Status;\r
1050 } else {\r
1051 return EFI_NOT_FOUND;\r
1052 }\r
4af04335
DB
1053}\r
1054\r
1055/**\r
1056 This function processes the results of changes in configuration.\r
1057\r
1058\r
1059 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1060 @param Action Specifies the type of action taken by the browser.\r
1061 @param QuestionId A unique value which is sent to the original exporting driver\r
1062 so that it can identify the type of data to expect.\r
1063 @param Type The type of value for the question.\r
1064 @param Value A pointer to the data being sent to the original exporting driver.\r
1065 @param ActionRequest On return, points to the action requested by the callback function.\r
1066\r
1067 @retval EFI_SUCCESS The callback successfully handled the action.\r
1068 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
1069 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
1070 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
1071 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.\r
1072**/\r
1073EFI_STATUS\r
1074EFIAPI\r
1075BootMaintCallback (\r
1076 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1077 IN EFI_BROWSER_ACTION Action,\r
1078 IN EFI_QUESTION_ID QuestionId,\r
1079 IN UINT8 Type,\r
1080 IN EFI_IFR_TYPE_VALUE *Value,\r
1081 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
1082 )\r
1083{\r
1084 BMM_CALLBACK_DATA *Private;\r
1085 BM_MENU_ENTRY *NewMenuEntry;\r
1086 BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
7880f73a 1087 BMM_FAKE_NV_DATA *OldFakeNVMap;\r
4af04335
DB
1088 UINTN Index;\r
1089 EFI_DEVICE_PATH_PROTOCOL * File;\r
1090\r
984cb646 1091 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED && Action != EFI_BROWSER_ACTION_FORM_OPEN) {\r
4af04335 1092 //\r
984cb646 1093 // Do nothing for other UEFI Action. Only do call back when data is changed or the form is open.\r
4af04335
DB
1094 //\r
1095 return EFI_UNSUPPORTED;\r
1096 }\r
4af04335
DB
1097\r
1098 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
984cb646
DB
1099\r
1100 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
1101 if (QuestionId == KEY_VALUE_TRIGGER_FORM_OPEN_ACTION) {\r
1102 if (!mFirstEnterBMMForm) {\r
1103 //\r
1104 // BMMUiLib depends on LegacyUi library to show legacy menus.\r
1105 // If we want to show Legacy menus correctly in BMM page,\r
1106 // we must do it after the LegacyUi library has already been initialized.\r
1107 // Opening the BMM form is the appropriate time that the LegacyUi library has already been initialized.\r
1108 // So we do the tasks which are related to legacy menus here.\r
1109 // 1. Update the menus (including legacy munu) show in BootMiantenanceManager page.\r
1110 // 2. Re-scan the BootOption menus (including the legacy boot option).\r
1111 //\r
1112 CustomizeMenus ();\r
1113 BOpt_GetBootOptions (Private);\r
1114 mFirstEnterBMMForm = TRUE;\r
1115 }\r
1116 }\r
1117 }\r
4af04335 1118 //\r
3b28e744 1119 // Retrieve uncommitted data from Form Browser\r
4af04335
DB
1120 //\r
1121 CurrentFakeNVMap = &Private->BmmFakeNvData;\r
7880f73a 1122 OldFakeNVMap = &Private->BmmOldFakeNVData;\r
4af04335
DB
1123 HiiGetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);\r
1124\r
1125 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
1126 if (Value == NULL) {\r
1127 return EFI_INVALID_PARAMETER;\r
1128 }\r
1129 \r
1130 UpdatePageId (Private, QuestionId);\r
1131\r
1132 if (QuestionId < FILE_OPTION_OFFSET) {\r
1133 if (QuestionId < CONFIG_OPTION_OFFSET) {\r
1134 switch (QuestionId) {\r
1135 case FORM_BOOT_ADD_ID:\r
1136 // Leave BMM and enter FileExplorer. \r
c7d1e742 1137 ChooseFile (NULL, L".efi", CreateBootOptionFromFile, &File);\r
4af04335
DB
1138 break;\r
1139\r
1140 case FORM_DRV_ADD_FILE_ID:\r
1141 // Leave BMM and enter FileExplorer.\r
c7d1e742 1142 ChooseFile (NULL, L".efi", CreateDriverOptionFromFile, &File);\r
4af04335
DB
1143 break;\r
1144\r
1145 case FORM_DRV_ADD_HANDLE_ID:\r
1146 CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);\r
1147 UpdateDrvAddHandlePage (Private);\r
1148 break;\r
1149\r
1150 case FORM_BOOT_DEL_ID:\r
1151 CleanUpPage (FORM_BOOT_DEL_ID, Private);\r
1152 UpdateBootDelPage (Private);\r
1153 break;\r
1154\r
1155 case FORM_BOOT_CHG_ID:\r
1156 case FORM_DRV_CHG_ID:\r
1157 UpdatePageBody (QuestionId, Private);\r
1158 break;\r
1159\r
1160 case FORM_DRV_DEL_ID:\r
1161 CleanUpPage (FORM_DRV_DEL_ID, Private);\r
1162 UpdateDrvDelPage (Private);\r
1163 break;\r
1164\r
4af04335
DB
1165 case FORM_CON_IN_ID:\r
1166 case FORM_CON_OUT_ID:\r
1167 case FORM_CON_ERR_ID:\r
1168 UpdatePageBody (QuestionId, Private);\r
1169 break;\r
1170\r
1171 case FORM_CON_MODE_ID:\r
1172 CleanUpPage (FORM_CON_MODE_ID, Private);\r
1173 UpdateConModePage (Private);\r
1174 break;\r
1175\r
1176 case FORM_CON_COM_ID:\r
1177 CleanUpPage (FORM_CON_COM_ID, Private);\r
1178 UpdateConCOMPage (Private);\r
1179 break;\r
1180\r
1181 default:\r
1182 break;\r
1183 }\r
1184 } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {\r
1185 Index = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);\r
1186 Private->CurrentTerminal = Index;\r
1187\r
1188 CleanUpPage (FORM_CON_COM_SETUP_ID, Private);\r
1189 UpdateTerminalPage (Private);\r
1190\r
1191 } else if (QuestionId >= HANDLE_OPTION_OFFSET) {\r
1192 Index = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);\r
1193\r
1194 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);\r
1195 ASSERT (NewMenuEntry != NULL);\r
1196 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;\r
1197\r
1198 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);\r
1199\r
1200 Private->MenuEntry = NewMenuEntry;\r
1201 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;\r
1202\r
1203 UpdateDriverAddHandleDescPage (Private);\r
1204 }\r
1205 }\r
1206 if (QuestionId == KEY_VALUE_BOOT_FROM_FILE){\r
1207 // Leave BMM and enter FileExplorer.\r
c7d1e742 1208 ChooseFile (NULL, L".efi", BootFromFile, &File);\r
4af04335
DB
1209 }\r
1210 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
1211 if ((Value == NULL) || (ActionRequest == NULL)) {\r
1212 return EFI_INVALID_PARAMETER;\r
1213 }\r
1214 \r
1215 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT) {\r
1216 CurrentFakeNVMap->BootOptionChanged = FALSE;\r
1217 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
1218 } else if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {\r
1219 CurrentFakeNVMap->DriverOptionChanged = FALSE;\r
1220 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
1221 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {\r
1222 //\r
1223 // Discard changes and exit formset\r
1224 //\r
7880f73a
DB
1225 ZeroMem (CurrentFakeNVMap->DriverOptionalData, sizeof (CurrentFakeNVMap->DriverOptionalData));\r
1226 ZeroMem (CurrentFakeNVMap->BootDescriptionData, sizeof (CurrentFakeNVMap->BootDescriptionData));\r
1227 ZeroMem (OldFakeNVMap->DriverOptionalData, sizeof (OldFakeNVMap->DriverOptionalData));\r
1228 ZeroMem (OldFakeNVMap->DriverDescriptionData, sizeof (OldFakeNVMap->DriverDescriptionData));\r
4af04335
DB
1229 CurrentFakeNVMap->DriverOptionChanged = FALSE;\r
1230 CurrentFakeNVMap->ForceReconnect = TRUE;\r
1231 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
1232 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT) {\r
1233 //\r
1234 // Discard changes and exit formset\r
1235 //\r
7880f73a
DB
1236 ZeroMem (CurrentFakeNVMap->BootOptionalData, sizeof (CurrentFakeNVMap->BootOptionalData));\r
1237 ZeroMem (CurrentFakeNVMap->BootDescriptionData, sizeof (CurrentFakeNVMap->BootDescriptionData));\r
1238 ZeroMem (OldFakeNVMap->BootOptionalData, sizeof (OldFakeNVMap->BootOptionalData));\r
1239 ZeroMem (OldFakeNVMap->BootDescriptionData, sizeof (OldFakeNVMap->BootDescriptionData));\r
4af04335
DB
1240 CurrentFakeNVMap->BootOptionChanged = FALSE;\r
1241 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
1242 } else if (QuestionId == KEY_VALUE_BOOT_DESCRIPTION || QuestionId == KEY_VALUE_BOOT_OPTION) {\r
1243 CurrentFakeNVMap->BootOptionChanged = TRUE;\r
1244 } else if (QuestionId == KEY_VALUE_DRIVER_DESCRIPTION || QuestionId == KEY_VALUE_DRIVER_OPTION) {\r
1245 CurrentFakeNVMap->DriverOptionChanged = TRUE;\r
1246 } \r
1247\r
1248 if ((QuestionId >= BOOT_OPTION_DEL_QUESTION_ID) && (QuestionId < BOOT_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {\r
1249 if (Value->b){\r
1250 //\r
1251 // Means user try to delete this boot option but not press F10 or "Commit Changes and Exit" menu.\r
1252 //\r
1253 CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = TRUE;\r
1254 } else {\r
1255 //\r
1256 // Means user remove the old check status.\r
1257 //\r
1258 CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = FALSE;\r
1259 }\r
1260 } else if ((QuestionId >= DRIVER_OPTION_DEL_QUESTION_ID) && (QuestionId < DRIVER_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {\r
1261 if (Value->b){\r
1262 CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = TRUE;\r
1263 } else {\r
1264 CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = FALSE;\r
1265 }\r
1266 } else {\r
1267 switch (QuestionId) {\r
1268 case KEY_VALUE_SAVE_AND_EXIT:\r
1269 case KEY_VALUE_NO_SAVE_AND_EXIT:\r
1270 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {\r
1271 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
1272 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {\r
1273 DiscardChangeHandler (Private, CurrentFakeNVMap);\r
1274 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
1275 }\r
1276\r
1277 break;\r
1278\r
1279 case FORM_RESET:\r
1280 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
1281 return EFI_UNSUPPORTED;\r
1282\r
1283 default:\r
1284 break;\r
1285 }\r
1286 }\r
a3475fe0
DB
1287 //\r
1288 // Update the content in Terminal menu and Console menu here.\r
1289 //\r
1290 if (QuestionId == COM_BAUD_RATE_QUESTION_ID + Private->CurrentTerminal || QuestionId == COM_DATA_RATE_QUESTION_ID + Private->CurrentTerminal ||\r
1291 QuestionId == COM_PARITY_QUESTION_ID + Private->CurrentTerminal || QuestionId == COM_STOP_BITS_QUESTION_ID + Private->CurrentTerminal ||\r
1292 QuestionId == COM_TERMINAL_QUESTION_ID + Private->CurrentTerminal || QuestionId == COM_FLOWCONTROL_QUESTION_ID + Private->CurrentTerminal\r
1293 ) {\r
1294 UpdateTerminalContent(CurrentFakeNVMap);\r
1295 }\r
1296 if ((QuestionId >= CON_IN_DEVICE_QUESTION_ID) && (QuestionId < CON_IN_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {\r
1297 UpdateConsoleContent (L"ConIn",CurrentFakeNVMap);\r
1298 } else if ((QuestionId >= CON_OUT_DEVICE_QUESTION_ID) && (QuestionId < CON_OUT_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {\r
1299 UpdateConsoleContent (L"ConOut", CurrentFakeNVMap);\r
1300 } else if ((QuestionId >= CON_ERR_DEVICE_QUESTION_ID) && (QuestionId < CON_ERR_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {\r
1301 UpdateConsoleContent (L"ConErr", CurrentFakeNVMap);\r
1302 }\r
4af04335
DB
1303 }\r
1304\r
1305 //\r
1306 // Pass changed uncommitted data back to Form Browser\r
1307 //\r
1308 HiiSetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);\r
1309\r
1310 return EFI_SUCCESS;\r
1311}\r
1312\r
1313/**\r
1314 Discard all changes done to the BMM pages such as Boot Order change,\r
1315 Driver order change.\r
1316\r
1317 @param Private The BMM context data.\r
1318 @param CurrentFakeNVMap The current Fack NV Map.\r
1319\r
1320**/\r
1321VOID\r
1322DiscardChangeHandler (\r
1323 IN BMM_CALLBACK_DATA *Private,\r
1324 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap\r
1325 )\r
1326{\r
1327 UINT16 Index;\r
1328\r
1329 switch (Private->BmmPreviousPageId) {\r
1330 case FORM_BOOT_CHG_ID:\r
1331 CopyMem (CurrentFakeNVMap->BootOptionOrder, Private->BmmOldFakeNVData.BootOptionOrder, sizeof (CurrentFakeNVMap->BootOptionOrder));\r
1332 break;\r
1333\r
1334 case FORM_DRV_CHG_ID:\r
1335 CopyMem (CurrentFakeNVMap->DriverOptionOrder, Private->BmmOldFakeNVData.DriverOptionOrder, sizeof (CurrentFakeNVMap->DriverOptionOrder));\r
1336 break;\r
1337\r
1338 case FORM_BOOT_DEL_ID:\r
1339 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));\r
1340 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
1341 CurrentFakeNVMap->BootOptionDel[Index] = FALSE;\r
1342 }\r
1343 break;\r
1344\r
1345 case FORM_DRV_DEL_ID:\r
1346 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));\r
1347 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
1348 CurrentFakeNVMap->DriverOptionDel[Index] = FALSE;\r
1349 }\r
1350 break;\r
1351\r
1352 case FORM_BOOT_NEXT_ID:\r
1353 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;\r
1354 break;\r
1355\r
1356 case FORM_TIME_OUT_ID:\r
1357 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;\r
1358 break;\r
1359\r
1360 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
1361 case FORM_DRV_ADD_FILE_ID:\r
1362 case FORM_DRV_ADD_HANDLE_ID:\r
1363 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;\r
1364 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;\r
1365 break;\r
1366\r
1367 default:\r
1368 break;\r
1369 }\r
1370}\r
1371\r
1372/**\r
4af04335 1373\r
a85be3ae 1374 Update the menus in the BMM page.\r
4af04335
DB
1375\r
1376**/\r
1377VOID\r
a85be3ae
ED
1378CustomizeMenus (\r
1379 VOID\r
4af04335
DB
1380 )\r
1381{\r
4af04335
DB
1382 VOID *StartOpCodeHandle;\r
1383 VOID *EndOpCodeHandle;\r
a85be3ae
ED
1384 EFI_IFR_GUID_LABEL *StartGuidLabel;\r
1385 EFI_IFR_GUID_LABEL *EndGuidLabel;\r
1386\r
4af04335
DB
1387 //\r
1388 // Allocate space for creation of UpdateData Buffer\r
1389 //\r
1390 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1391 ASSERT (StartOpCodeHandle != NULL);\r
1392\r
1393 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1394 ASSERT (EndOpCodeHandle != NULL);\r
4af04335
DB
1395 //\r
1396 // Create Hii Extend Label OpCode as the start opcode\r
1397 //\r
a85be3ae
ED
1398 StartGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1399 StartGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1400 StartGuidLabel->Number = LABEL_FORM_MAIN_START;\r
4af04335
DB
1401 //\r
1402 // Create Hii Extend Label OpCode as the end opcode\r
1403 //\r
a85be3ae
ED
1404 EndGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1405 EndGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1406 EndGuidLabel->Number = LABEL_FORM_MAIN_END;\r
4af04335
DB
1407\r
1408 //\r
a85be3ae 1409 //Updata Front Page form\r
4af04335 1410 //\r
a85be3ae
ED
1411 UiCustomizeBMMPage (\r
1412 mBmmCallbackInfo->BmmHiiHandle,\r
1413 StartOpCodeHandle\r
1414 );\r
4af04335 1415\r
4af04335 1416 HiiUpdateForm (\r
a85be3ae 1417 mBmmCallbackInfo->BmmHiiHandle,\r
4af04335
DB
1418 &mBootMaintGuid,\r
1419 FORM_MAIN_ID,\r
1420 StartOpCodeHandle,\r
1421 EndOpCodeHandle\r
1422 );\r
1423\r
1424 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
a85be3ae 1425 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
4af04335
DB
1426}\r
1427\r
1428/**\r
1429 Create dynamic code for BMM and initialize all of BMM configuration data in BmmFakeNvData and\r
1430 BmmOldFakeNVData member in BMM context data.\r
1431\r
1432 @param CallbackData The BMM context data.\r
1433\r
1434**/\r
1435VOID\r
1436InitializeBmmConfig (\r
1437 IN BMM_CALLBACK_DATA *CallbackData\r
1438 )\r
1439{\r
1440 BM_MENU_ENTRY *NewMenuEntry;\r
1441 BM_LOAD_CONTEXT *NewLoadContext;\r
1442 UINT16 Index;\r
1443\r
1444 ASSERT (CallbackData != NULL);\r
1445\r
4af04335
DB
1446 //\r
1447 // Initialize data which located in BMM main page\r
1448 //\r
f7986526 1449 CallbackData->BmmFakeNvData.BootNext = NONE_BOOTNEXT_VALUE;\r
4af04335
DB
1450 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
1451 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
1452 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
1453\r
1454 if (NewLoadContext->IsBootNext) {\r
1455 CallbackData->BmmFakeNvData.BootNext = Index;\r
1456 break;\r
1457 }\r
1458 }\r
1459\r
1460 CallbackData->BmmFakeNvData.BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut);\r
1461\r
1462 //\r
1463 // Initialize data which located in Boot Options Menu\r
1464 //\r
1465 GetBootOrder (CallbackData);\r
1466\r
1467 //\r
1468 // Initialize data which located in Driver Options Menu\r
1469 //\r
1470 GetDriverOrder (CallbackData);\r
1471\r
1472 //\r
1473 // Initialize data which located in Console Options Menu\r
1474 //\r
1475 GetConsoleOutMode (CallbackData);\r
1476 GetConsoleInCheck (CallbackData);\r
1477 GetConsoleOutCheck (CallbackData);\r
1478 GetConsoleErrCheck (CallbackData);\r
1479 GetTerminalAttribute (CallbackData);\r
1480\r
1481 CallbackData->BmmFakeNvData.ForceReconnect = TRUE;\r
1482\r
1483 //\r
1484 // Backup Initialize BMM configuartion data to BmmOldFakeNVData\r
1485 //\r
1486 CopyMem (&CallbackData->BmmOldFakeNVData, &CallbackData->BmmFakeNvData, sizeof (BMM_FAKE_NV_DATA));\r
1487}\r
1488\r
1489/**\r
1490 Initialized all Menu Option List.\r
1491\r
1492 @param CallbackData The BMM context data.\r
1493\r
1494**/\r
1495VOID\r
1496InitAllMenu (\r
1497 IN BMM_CALLBACK_DATA *CallbackData\r
1498 )\r
1499{\r
1500 InitializeListHead (&BootOptionMenu.Head);\r
1501 InitializeListHead (&DriverOptionMenu.Head);\r
1502 BOpt_GetBootOptions (CallbackData);\r
1503 BOpt_GetDriverOptions (CallbackData);\r
1504 BOpt_FindDrivers ();\r
1505 InitializeListHead (&ConsoleInpMenu.Head);\r
1506 InitializeListHead (&ConsoleOutMenu.Head);\r
1507 InitializeListHead (&ConsoleErrMenu.Head);\r
1508 InitializeListHead (&TerminalMenu.Head);\r
1509 LocateSerialIo ();\r
1510 GetAllConsoles ();\r
1511 mAllMenuInit = TRUE;\r
1512}\r
1513\r
1514/**\r
1515 Free up all Menu Option list.\r
1516\r
1517**/\r
1518VOID\r
1519FreeAllMenu (\r
1520 VOID\r
1521 )\r
1522{\r
1523 if (!mAllMenuInit){\r
1524 return;\r
1525 }\r
1526 BOpt_FreeMenu (&BootOptionMenu);\r
1527 BOpt_FreeMenu (&DriverOptionMenu);\r
1528 BOpt_FreeMenu (&DriverMenu);\r
1529 FreeAllConsoles ();\r
1530 mAllMenuInit = FALSE;\r
1531}\r
1532\r
8c53b5e6
ED
1533/**\r
1534 Initial the boot mode related parameters.\r
1535\r
1536**/\r
1537VOID\r
1538BmmInitialBootModeInfo (\r
1539 VOID\r
1540 )\r
1541{\r
1542 EFI_STATUS Status;\r
1543 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1544 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;\r
1545 UINTN BootTextColumn;\r
1546 UINTN BootTextRow;\r
1547\r
1548 if (mBmmModeInitialized) {\r
1549 return;\r
1550 }\r
1551\r
1552 //\r
1553 // After the console is ready, get current video resolution\r
1554 // and text mode before launching setup at first time.\r
1555 //\r
1556 Status = gBS->HandleProtocol (\r
1557 gST->ConsoleOutHandle,\r
1558 &gEfiGraphicsOutputProtocolGuid,\r
1559 (VOID**)&GraphicsOutput\r
1560 );\r
1561 if (EFI_ERROR (Status)) {\r
1562 GraphicsOutput = NULL;\r
1563 }\r
1564\r
1565 Status = gBS->HandleProtocol (\r
1566 gST->ConsoleOutHandle,\r
1567 &gEfiSimpleTextOutProtocolGuid,\r
1568 (VOID**)&SimpleTextOut\r
1569 );\r
1570 if (EFI_ERROR (Status)) {\r
1571 SimpleTextOut = NULL;\r
1572 }\r
1573\r
1574 if (GraphicsOutput != NULL) {\r
1575 //\r
1576 // Get current video resolution and text mode.\r
1577 //\r
1578 mBmmBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
1579 mBmmBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
1580 }\r
1581\r
1582 if (SimpleTextOut != NULL) {\r
1583 Status = SimpleTextOut->QueryMode (\r
1584 SimpleTextOut,\r
1585 SimpleTextOut->Mode->Mode,\r
1586 &BootTextColumn,\r
1587 &BootTextRow\r
1588 );\r
1589 mBmmBootTextModeColumn = (UINT32)BootTextColumn;\r
1590 mBmmBootTextModeRow = (UINT32)BootTextRow;\r
1591 }\r
1592\r
1593 //\r
1594 // Get user defined text mode for setup.\r
1595 //\r
1596 mBmmSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);\r
1597 mBmmSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);\r
1598 mBmmSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);\r
1599 mBmmSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);\r
1600\r
1601 mBmmModeInitialized = TRUE;\r
1602}\r
1603\r
4af04335
DB
1604/**\r
1605\r
1606 Install Boot Maintenance Manager Menu driver.\r
1607\r
1608 @param ImageHandle The image handle.\r
1609 @param SystemTable The system table.\r
1610\r
1611 @retval EFI_SUCEESS Install Boot manager menu success.\r
1612 @retval Other Return error status.\r
1613\r
1614**/\r
1615EFI_STATUS\r
1616EFIAPI\r
13c4e864 1617BootMaintenanceManagerUiLibConstructor (\r
4af04335
DB
1618 IN EFI_HANDLE ImageHandle,\r
1619 IN EFI_SYSTEM_TABLE *SystemTable\r
1620 )\r
1621\r
1622{\r
1623 EFI_STATUS Status;\r
1624 UINT8 *Ptr;\r
1625\r
1626 Status = EFI_SUCCESS;\r
1627\r
1628 //\r
1629 // Install Device Path Protocol and Config Access protocol to driver handle\r
1630 //\r
1631 Status = gBS->InstallMultipleProtocolInterfaces (\r
1632 &mBmmCallbackInfo->BmmDriverHandle,\r
1633 &gEfiDevicePathProtocolGuid,\r
1634 &mBmmHiiVendorDevicePath,\r
1635 &gEfiHiiConfigAccessProtocolGuid,\r
1636 &mBmmCallbackInfo->BmmConfigAccess,\r
1637 NULL\r
1638 );\r
1639 ASSERT_EFI_ERROR (Status);\r
1640\r
1641 //\r
1642 // Post our Boot Maint VFR binary to the HII database.\r
1643 //\r
1644 mBmmCallbackInfo->BmmHiiHandle = HiiAddPackages (\r
1645 &mBootMaintGuid,\r
1646 mBmmCallbackInfo->BmmDriverHandle,\r
1647 BootMaintenanceManagerBin,\r
13c4e864 1648 BootMaintenanceManagerUiLibStrings,\r
4af04335
DB
1649 NULL\r
1650 );\r
1651 ASSERT (mBmmCallbackInfo->BmmHiiHandle != NULL);\r
1652\r
1653 //\r
1654 // Locate Formbrowser2 protocol\r
1655 //\r
1656 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &mBmmCallbackInfo->FormBrowser2);\r
1657 ASSERT_EFI_ERROR (Status);\r
1658\r
1659 EfiBootManagerRefreshAllBootOption ();\r
1660\r
1661 //\r
1662 // Create LoadOption in BmmCallbackInfo for Driver Callback\r
1663 //\r
1664 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));\r
1665 ASSERT (Ptr != NULL);\r
1666\r
1667 //\r
1668 // Initialize Bmm callback data.\r
1669 //\r
1670 mBmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;\r
1671 Ptr += sizeof (BM_LOAD_CONTEXT);\r
1672\r
1673 mBmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;\r
1674 Ptr += sizeof (BM_FILE_CONTEXT);\r
1675\r
1676 mBmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;\r
1677 Ptr += sizeof (BM_HANDLE_CONTEXT);\r
1678\r
1679 mBmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;\r
1680\r
1681 mBmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;\r
1682 mBmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;\r
1683\r
1684 InitAllMenu (mBmmCallbackInfo);\r
1685\r
1686 CreateUpdateData();\r
1687 //\r
1688 // Update boot maintenance manager page \r
1689 //\r
1690 InitializeBmmConfig(mBmmCallbackInfo);\r
1691\r
8c53b5e6
ED
1692 BmmInitialBootModeInfo();\r
1693\r
4af04335
DB
1694 return EFI_SUCCESS;\r
1695}\r
1696\r
1697/**\r
1698 Unloads the application and its installed protocol.\r
1699\r
1700 @param ImageHandle Handle that identifies the image to be unloaded.\r
1701 @param SystemTable The system table.\r
1702\r
1703 @retval EFI_SUCCESS The image has been unloaded.\r
1704\r
1705**/\r
1706EFI_STATUS\r
1707EFIAPI\r
13c4e864 1708BootMaintenanceManagerUiLibDestructor (\r
4af04335
DB
1709 IN EFI_HANDLE ImageHandle,\r
1710 IN EFI_SYSTEM_TABLE *SystemTable\r
1711 )\r
1712\r
1713{\r
1714 if (mStartOpCodeHandle != NULL) {\r
1715 HiiFreeOpCodeHandle (mStartOpCodeHandle);\r
1716 }\r
1717\r
1718 if (mEndOpCodeHandle != NULL) {\r
1719 HiiFreeOpCodeHandle (mEndOpCodeHandle);\r
1720 }\r
1721\r
1722 FreeAllMenu ();\r
1723\r
1724 //\r
1725 // Remove our IFR data from HII database\r
1726 //\r
1727 HiiRemovePackages (mBmmCallbackInfo->BmmHiiHandle);\r
1728\r
1729 gBS->UninstallMultipleProtocolInterfaces (\r
1730 mBmmCallbackInfo->BmmDriverHandle,\r
1731 &gEfiDevicePathProtocolGuid,\r
1732 &mBmmHiiVendorDevicePath,\r
1733 &gEfiHiiConfigAccessProtocolGuid,\r
1734 &mBmmCallbackInfo->BmmConfigAccess,\r
1735 NULL\r
1736 );\r
1737\r
1738 FreePool (mBmmCallbackInfo->LoadContext);\r
1739\r
1740 return EFI_SUCCESS;\r
1741}\r
1742\r