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