]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c
MdeModulePkg UiApp: Remove invalid keyword "bds" in UiApp.
[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
87\r
88/**\r
89 Init all memu.\r
90\r
91 @param CallbackData The BMM context data.\r
92\r
93**/\r
94VOID\r
95InitAllMenu (\r
96 IN BMM_CALLBACK_DATA *CallbackData\r
97 );\r
98\r
99/**\r
100 Free up all Menu Option list.\r
101\r
102**/\r
103VOID\r
104FreeAllMenu (\r
105 VOID\r
106 );\r
107\r
108/**\r
109 This function will change video resolution and text mode\r
110 according to defined setup mode or defined boot mode \r
111\r
112 @param IsSetupMode Indicate mode is changed to setup mode or boot mode. \r
113\r
114 @retval EFI_SUCCESS Mode is changed successfully.\r
115 @retval Others Mode failed to be changed.\r
116\r
117**/\r
118EFI_STATUS\r
119EFIAPI\r
120BmmBdsSetConsoleMode (\r
121 BOOLEAN IsSetupMode\r
122 )\r
123{\r
124 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
125 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;\r
126 UINTN SizeOfInfo;\r
127 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
128 UINT32 MaxGopMode;\r
129 UINT32 MaxTextMode;\r
130 UINT32 ModeNumber;\r
131 UINT32 NewHorizontalResolution;\r
132 UINT32 NewVerticalResolution;\r
133 UINT32 NewColumns;\r
134 UINT32 NewRows;\r
135 UINTN HandleCount;\r
136 EFI_HANDLE *HandleBuffer;\r
137 EFI_STATUS Status;\r
138 UINTN Index;\r
139 UINTN CurrentColumn;\r
140 UINTN CurrentRow; \r
141\r
142 MaxGopMode = 0;\r
143 MaxTextMode = 0;\r
144\r
145 //\r
146 // Get current video resolution and text mode \r
147 //\r
148 Status = gBS->HandleProtocol (\r
149 gST->ConsoleOutHandle,\r
150 &gEfiGraphicsOutputProtocolGuid,\r
151 (VOID**)&GraphicsOutput\r
152 );\r
153 if (EFI_ERROR (Status)) {\r
154 GraphicsOutput = NULL;\r
155 }\r
156\r
157 Status = gBS->HandleProtocol (\r
158 gST->ConsoleOutHandle,\r
159 &gEfiSimpleTextOutProtocolGuid,\r
160 (VOID**)&SimpleTextOut\r
161 );\r
162 if (EFI_ERROR (Status)) {\r
163 SimpleTextOut = NULL;\r
164 } \r
165\r
166 if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {\r
167 return EFI_UNSUPPORTED;\r
168 }\r
169\r
170 if (IsSetupMode) {\r
171 //\r
172 // The requried resolution and text mode is setup mode.\r
173 //\r
174 NewHorizontalResolution = mBmmSetupHorizontalResolution;\r
175 NewVerticalResolution = mBmmSetupVerticalResolution;\r
176 NewColumns = mBmmSetupTextModeColumn;\r
177 NewRows = mBmmSetupTextModeRow;\r
178 } else {\r
179 //\r
180 // The required resolution and text mode is boot mode.\r
181 //\r
182 NewHorizontalResolution = mBmmBootHorizontalResolution;\r
183 NewVerticalResolution = mBmmBootVerticalResolution;\r
184 NewColumns = mBmmBootTextModeColumn;\r
185 NewRows = mBmmBootTextModeRow; \r
186 }\r
187\r
188 if (GraphicsOutput != NULL) {\r
189 MaxGopMode = GraphicsOutput->Mode->MaxMode;\r
190 } \r
191\r
192 if (SimpleTextOut != NULL) {\r
193 MaxTextMode = SimpleTextOut->Mode->MaxMode;\r
194 }\r
195\r
196 //\r
197 // 1. If current video resolution is same with required video resolution,\r
198 // video resolution need not be changed.\r
199 // 1.1. If current text mode is same with required text mode, text mode need not be changed.\r
200 // 1.2. If current text mode is different from required text mode, text mode need be changed.\r
201 // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.\r
202 //\r
203 for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {\r
204 Status = GraphicsOutput->QueryMode (\r
205 GraphicsOutput,\r
206 ModeNumber,\r
207 &SizeOfInfo,\r
208 &Info\r
209 );\r
210 if (!EFI_ERROR (Status)) {\r
211 if ((Info->HorizontalResolution == NewHorizontalResolution) &&\r
212 (Info->VerticalResolution == NewVerticalResolution)) {\r
213 if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) &&\r
214 (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) {\r
215 //\r
216 // Current resolution is same with required resolution, check if text mode need be set\r
217 //\r
218 Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);\r
219 ASSERT_EFI_ERROR (Status);\r
220 if (CurrentColumn == NewColumns && CurrentRow == NewRows) {\r
221 //\r
222 // If current text mode is same with required text mode. Do nothing\r
223 //\r
224 FreePool (Info);\r
225 return EFI_SUCCESS;\r
226 } else {\r
227 //\r
228 // If current text mode is different from requried text mode. Set new video mode\r
229 //\r
230 for (Index = 0; Index < MaxTextMode; Index++) {\r
231 Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);\r
232 if (!EFI_ERROR(Status)) {\r
233 if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {\r
234 //\r
235 // Required text mode is supported, set it.\r
236 //\r
237 Status = SimpleTextOut->SetMode (SimpleTextOut, Index);\r
238 ASSERT_EFI_ERROR (Status);\r
239 //\r
240 // Update text mode PCD.\r
241 //\r
e750958b
DB
242 Status = PcdSet32S (PcdConOutColumn, mBmmSetupTextModeColumn);\r
243 ASSERT_EFI_ERROR (Status);\r
244 Status = PcdSet32S (PcdConOutRow, mBmmSetupTextModeRow);\r
245 ASSERT_EFI_ERROR (Status);\r
4af04335
DB
246 FreePool (Info);\r
247 return EFI_SUCCESS;\r
248 }\r
249 }\r
250 }\r
251 if (Index == MaxTextMode) {\r
252 //\r
253 // If requried text mode is not supported, return error.\r
254 //\r
255 FreePool (Info);\r
256 return EFI_UNSUPPORTED;\r
257 }\r
258 }\r
259 } else {\r
260 //\r
261 // If current video resolution is not same with the new one, set new video resolution.\r
262 // In this case, the driver which produces simple text out need be restarted.\r
263 //\r
264 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);\r
265 if (!EFI_ERROR (Status)) {\r
266 FreePool (Info);\r
267 break;\r
268 }\r
269 }\r
270 }\r
271 FreePool (Info);\r
272 }\r
273 }\r
274\r
275 if (ModeNumber == MaxGopMode) {\r
276 //\r
277 // If the resolution is not supported, return error.\r
278 //\r
279 return EFI_UNSUPPORTED;\r
280 }\r
281\r
282 //\r
283 // Set PCD to Inform GraphicsConsole to change video resolution.\r
284 // Set PCD to Inform Consplitter to change text mode.\r
285 //\r
e750958b
DB
286 Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution);\r
287 ASSERT_EFI_ERROR (Status);\r
288 Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution);\r
289 ASSERT_EFI_ERROR (Status);\r
290 Status = PcdSet32S (PcdConOutColumn, NewColumns);\r
291 ASSERT_EFI_ERROR (Status);\r
292 Status = PcdSet32S (PcdConOutRow, NewRows);\r
293 ASSERT_EFI_ERROR (Status);\r
4af04335
DB
294\r
295 //\r
296 // Video mode is changed, so restart graphics console driver and higher level driver.\r
297 // Reconnect graphics console driver and higher level driver.\r
298 // Locate all the handles with GOP protocol and reconnect it.\r
299 //\r
300 Status = gBS->LocateHandleBuffer (\r
301 ByProtocol,\r
302 &gEfiSimpleTextOutProtocolGuid,\r
303 NULL,\r
304 &HandleCount,\r
305 &HandleBuffer\r
306 );\r
307 if (!EFI_ERROR (Status)) {\r
308 for (Index = 0; Index < HandleCount; Index++) {\r
309 gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);\r
310 }\r
311 for (Index = 0; Index < HandleCount; Index++) {\r
312 gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);\r
313 }\r
314 if (HandleBuffer != NULL) {\r
315 FreePool (HandleBuffer);\r
316 }\r
317 }\r
318\r
319 return EFI_SUCCESS;\r
320}\r
321\r
322/**\r
323 This function converts an input device structure to a Unicode string.\r
324\r
325 @param DevPath A pointer to the device path structure.\r
326\r
327 @return A new allocated Unicode string that represents the device path.\r
328\r
329**/\r
330CHAR16 *\r
331UiDevicePathToStr (\r
332 IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
333 )\r
334{\r
335 EFI_STATUS Status;\r
336 CHAR16 *ToText;\r
337 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;\r
338\r
339 if (DevPath == NULL) {\r
340 return NULL;\r
341 }\r
342\r
343 Status = gBS->LocateProtocol (\r
344 &gEfiDevicePathToTextProtocolGuid,\r
345 NULL,\r
346 (VOID **) &DevPathToText\r
347 );\r
348 ASSERT_EFI_ERROR (Status);\r
349 ToText = DevPathToText->ConvertDevicePathToText (\r
350 DevPath,\r
351 FALSE,\r
352 TRUE\r
353 );\r
354 ASSERT (ToText != NULL);\r
355 return ToText;\r
356}\r
357\r
358/**\r
359 Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.\r
360 The caller is responsible for freeing the allocated buffer using FreePool().\r
361\r
362 @param DevicePath Device path.\r
363\r
364 @return A new allocated string that represents the file name.\r
365\r
366**/\r
367CHAR16 *\r
368ExtractFileNameFromDevicePath (\r
369 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
370 )\r
371{\r
372 CHAR16 *String;\r
373 CHAR16 *MatchString;\r
374 CHAR16 *LastMatch;\r
375 CHAR16 *FileName;\r
376 UINTN Length;\r
377\r
378 ASSERT(DevicePath != NULL);\r
379\r
380 String = UiDevicePathToStr(DevicePath);\r
381 MatchString = String;\r
382 LastMatch = String;\r
383\r
384 while(MatchString != NULL){\r
385 LastMatch = MatchString + 1;\r
386 MatchString = StrStr(LastMatch,L"\\");\r
387 }\r
388\r
389 Length = StrLen(LastMatch);\r
390 FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch);\r
391 *(FileName + Length) = 0;\r
392\r
393 FreePool(String);\r
394\r
395 return FileName;\r
396}\r
397\r
398/**\r
399 Extract device path for given HII handle and class guid.\r
400\r
401 @param Handle The HII handle.\r
402\r
403 @retval NULL Fail to get the device path string.\r
404 @return PathString Get the device path string.\r
405\r
406**/\r
407CHAR16 *\r
408BmmExtractDevicePathFromHiiHandle (\r
409 IN EFI_HII_HANDLE Handle\r
410 )\r
411{\r
412 EFI_STATUS Status;\r
413 EFI_HANDLE DriverHandle;\r
414\r
415 ASSERT (Handle != NULL);\r
416\r
417 if (Handle == NULL) {\r
418 return NULL;\r
419 }\r
420\r
421 Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);\r
422 if (EFI_ERROR (Status)) {\r
423 return NULL;\r
424 }\r
425\r
426 //\r
427 // Get device path string.\r
428 //\r
429 return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE);\r
430\r
431}\r
432\r
433/**\r
434 This function allows a caller to extract the current configuration for one\r
435 or more named elements from the target driver.\r
436\r
437 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
438 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
439 @param Progress On return, points to a character in the Request string.\r
440 Points to the string's null terminator if request was successful.\r
441 Points to the most recent '&' before the first failing name/value\r
442 pair (or the beginning of the string if the failure is in the\r
443 first name/value pair) if the request was not successful.\r
444 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
445 has all values filled in for the names in the Request string.\r
446 String to be allocated by the called function.\r
447\r
448 @retval EFI_SUCCESS The Results is filled with the requested values.\r
449 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
450 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
451 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
452\r
453**/\r
454EFI_STATUS\r
455EFIAPI\r
456BootMaintExtractConfig (\r
457 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
458 IN CONST EFI_STRING Request,\r
459 OUT EFI_STRING *Progress,\r
460 OUT EFI_STRING *Results\r
461 )\r
462{\r
463 EFI_STATUS Status;\r
464 UINTN BufferSize;\r
465 BMM_CALLBACK_DATA *Private;\r
466 EFI_STRING ConfigRequestHdr;\r
467 EFI_STRING ConfigRequest;\r
468 BOOLEAN AllocatedRequest;\r
469 UINTN Size;\r
470\r
471 if (Progress == NULL || Results == NULL) {\r
472 return EFI_INVALID_PARAMETER;\r
473 }\r
474\r
475 *Progress = Request;\r
476 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mBootMaintGuid, mBootMaintStorageName)) {\r
477 return EFI_NOT_FOUND;\r
478 }\r
479\r
480 ConfigRequestHdr = NULL;\r
481 ConfigRequest = NULL;\r
482 AllocatedRequest = FALSE;\r
483 Size = 0;\r
484\r
485 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
486 //\r
487 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
488 //\r
489 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
490 ConfigRequest = Request;\r
491 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
492 //\r
493 // Request has no request element, construct full request string.\r
494 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
495 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
496 //\r
497 ConfigRequestHdr = HiiConstructConfigHdr (&mBootMaintGuid, mBootMaintStorageName, Private->BmmDriverHandle);\r
498 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
499 ConfigRequest = AllocateZeroPool (Size);\r
500 ASSERT (ConfigRequest != NULL);\r
501 AllocatedRequest = TRUE;\r
502 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
503 FreePool (ConfigRequestHdr);\r
504 }\r
505\r
506 Status = gHiiConfigRouting->BlockToConfig (\r
507 gHiiConfigRouting,\r
508 ConfigRequest,\r
509 (UINT8 *) &Private->BmmFakeNvData,\r
510 BufferSize,\r
511 Results,\r
512 Progress\r
513 );\r
514 //\r
515 // Free the allocated config request string.\r
516 //\r
517 if (AllocatedRequest) {\r
518 FreePool (ConfigRequest);\r
519 ConfigRequest = NULL;\r
520 }\r
521 //\r
522 // Set Progress string to the original request string.\r
523 //\r
524 if (Request == NULL) {\r
525 *Progress = NULL;\r
526 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
527 *Progress = Request + StrLen (Request);\r
528 }\r
529\r
530 return Status;\r
531}\r
532\r
533/**\r
534 This function applies changes in a driver's configuration.\r
535 Input is a Configuration, which has the routing data for this\r
536 driver followed by name / value configuration pairs. The driver\r
537 must apply those pairs to its configurable storage. If the\r
538 driver's configuration is stored in a linear block of data\r
539 and the driver's name / value pairs are in <BlockConfig>\r
540 format, it may use the ConfigToBlock helper function (above) to\r
541 simplify the job. Currently not implemented.\r
542\r
543 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
544 @param[in] Configuration A null-terminated Unicode string in\r
545 <ConfigString> format. \r
546 @param[out] Progress A pointer to a string filled in with the\r
547 offset of the most recent '&' before the\r
548 first failing name / value pair (or the\r
549 beginn ing of the string if the failure\r
550 is in the first name / value pair) or\r
551 the terminating NULL if all was\r
552 successful.\r
553\r
554 @retval EFI_SUCCESS The results have been distributed or are\r
555 awaiting distribution. \r
556 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
557 parts of the results that must be\r
558 stored awaiting possible future\r
559 protocols.\r
560 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
561 Results parameter would result\r
562 in this type of error.\r
563 @retval EFI_NOT_FOUND Target for the specified routing data\r
564 was not found.\r
565**/\r
566EFI_STATUS\r
567EFIAPI\r
568BootMaintRouteConfig (\r
569 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
570 IN CONST EFI_STRING Configuration,\r
571 OUT EFI_STRING *Progress\r
572 )\r
573{\r
574 EFI_STATUS Status;\r
575 UINTN BufferSize;\r
576 EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;\r
577 BMM_FAKE_NV_DATA *NewBmmData;\r
578 BMM_FAKE_NV_DATA *OldBmmData;\r
579 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
580 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
581 BM_MENU_ENTRY *NewMenuEntry;\r
582 BM_LOAD_CONTEXT *NewLoadContext;\r
583 UINT16 Index;\r
584 BOOLEAN TerminalAttChange;\r
585 BMM_CALLBACK_DATA *Private; \r
586\r
587 if (Progress == NULL) {\r
588 return EFI_INVALID_PARAMETER;\r
589 }\r
590 *Progress = Configuration;\r
591\r
592 if (Configuration == NULL) {\r
593 return EFI_INVALID_PARAMETER;\r
594 }\r
595\r
596 //\r
597 // Check routing data in <ConfigHdr>.\r
598 // Note: there is no name for Name/Value storage, only GUID will be checked\r
599 //\r
600 if (!HiiIsConfigHdrMatch (Configuration, &mBootMaintGuid, mBootMaintStorageName)) {\r
601 return EFI_NOT_FOUND;\r
602 }\r
603\r
604 Status = gBS->LocateProtocol (\r
605 &gEfiHiiConfigRoutingProtocolGuid, \r
606 NULL, \r
607 (VOID **)&ConfigRouting\r
608 );\r
609 if (EFI_ERROR (Status)) {\r
610 return Status;\r
611 }\r
612\r
613 Private = BMM_CALLBACK_DATA_FROM_THIS (This); \r
614 //\r
615 // Get Buffer Storage data from EFI variable\r
616 //\r
617 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
618 OldBmmData = &Private->BmmOldFakeNVData;\r
619 NewBmmData = &Private->BmmFakeNvData;\r
620 //\r
621 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
622 //\r
623 Status = ConfigRouting->ConfigToBlock (\r
624 ConfigRouting,\r
625 Configuration,\r
626 (UINT8 *) NewBmmData,\r
627 &BufferSize,\r
628 Progress\r
629 );\r
630 ASSERT_EFI_ERROR (Status); \r
631 //\r
632 // Compare new and old BMM configuration data and only do action for modified item to \r
633 // avoid setting unnecessary non-volatile variable\r
634 //\r
635\r
636 //\r
637 // Check data which located in BMM main page and save the settings if need\r
638 // \r
639 if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {\r
640 Status = Var_UpdateBootNext (Private);\r
641 }\r
642\r
643 //\r
644 // Check data which located in Boot Options Menu and save the settings if need\r
645 // \r
646 if (CompareMem (NewBmmData->BootOptionDel, OldBmmData->BootOptionDel, sizeof (NewBmmData->BootOptionDel)) != 0) { \r
647 for (Index = 0; \r
648 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->BootOptionDel) / sizeof (NewBmmData->BootOptionDel[0])))); \r
649 Index ++) {\r
650 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
651 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
652 NewLoadContext->Deleted = NewBmmData->BootOptionDel[Index];\r
653 NewBmmData->BootOptionDel[Index] = FALSE;\r
654 NewBmmData->BootOptionDelMark[Index] = FALSE;\r
655 }\r
656\r
657 Var_DelBootOption ();\r
658 }\r
659\r
660 if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) {\r
661 Status = Var_UpdateBootOrder (Private);\r
662 }\r
663\r
664 if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0){\r
665 Status = gRT->SetVariable(\r
666 L"Timeout",\r
667 &gEfiGlobalVariableGuid,\r
668 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
669 sizeof(UINT16),\r
670 &(NewBmmData->BootTimeOut)\r
671 );\r
c7d310dd
DB
672 if (EFI_ERROR (Status)) {\r
673 //\r
674 // If set variable fail, and don't have the appropriate error status for RouteConfig fuction to return,\r
675 // just return the EFI_NOT_FOUND.\r
676 //\r
677 if (Status == EFI_OUT_OF_RESOURCES) {\r
678 return Status;\r
679 } else {\r
680 return EFI_NOT_FOUND;\r
681 }\r
682 }\r
4af04335
DB
683 Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut;\r
684 }\r
685\r
686 //\r
687 // Check data which located in Driver Options Menu and save the settings if need\r
688 // \r
689 if (CompareMem (NewBmmData->DriverOptionDel, OldBmmData->DriverOptionDel, sizeof (NewBmmData->DriverOptionDel)) != 0) { \r
690 for (Index = 0; \r
691 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->DriverOptionDel) / sizeof (NewBmmData->DriverOptionDel[0])))); \r
692 Index++) {\r
693 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
694 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
695 NewLoadContext->Deleted = NewBmmData->DriverOptionDel[Index];\r
696 NewBmmData->DriverOptionDel[Index] = FALSE;\r
697 NewBmmData->DriverOptionDelMark[Index] = FALSE;\r
698 }\r
699 Var_DelDriverOption (); \r
700 }\r
701\r
702 if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) { \r
703 Status = Var_UpdateDriverOrder (Private);\r
704 }\r
705\r
706 if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0){\r
707 Var_UpdateConMode(Private);\r
708 }\r
709\r
710 TerminalAttChange = FALSE;\r
711 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
712\r
713 //\r
714 // only need update modified items\r
715 //\r
716 if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) == 0 &&\r
717 CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) == 0 &&\r
718 CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) == 0 &&\r
719 CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) == 0 &&\r
720 CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) == 0 &&\r
721 CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) == 0) {\r
722 continue;\r
723 }\r
724\r
725 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
726 ASSERT (NewMenuEntry != NULL);\r
727 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
728 NewTerminalContext->BaudRateIndex = NewBmmData->COMBaudRate[Index];\r
729 ASSERT (NewBmmData->COMBaudRate[Index] < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));\r
730 NewTerminalContext->BaudRate = BaudRateList[NewBmmData->COMBaudRate[Index]].Value;\r
731 NewTerminalContext->DataBitsIndex = NewBmmData->COMDataRate[Index];\r
732 ASSERT (NewBmmData->COMDataRate[Index] < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));\r
733 NewTerminalContext->DataBits = (UINT8) DataBitsList[NewBmmData->COMDataRate[Index]].Value;\r
734 NewTerminalContext->StopBitsIndex = NewBmmData->COMStopBits[Index];\r
735 ASSERT (NewBmmData->COMStopBits[Index] < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));\r
736 NewTerminalContext->StopBits = (UINT8) StopBitsList[NewBmmData->COMStopBits[Index]].Value;\r
737 NewTerminalContext->ParityIndex = NewBmmData->COMParity[Index];\r
738 ASSERT (NewBmmData->COMParity[Index] < (sizeof (ParityList) / sizeof (ParityList[0])));\r
739 NewTerminalContext->Parity = (UINT8) ParityList[NewBmmData->COMParity[Index]].Value;\r
740 NewTerminalContext->TerminalType = NewBmmData->COMTerminalType[Index];\r
741 NewTerminalContext->FlowControl = NewBmmData->COMFlowControl[Index];\r
742 ChangeTerminalDevicePath (\r
743 NewTerminalContext->DevicePath,\r
744 FALSE\r
745 );\r
746 TerminalAttChange = TRUE;\r
747 }\r
748 if (TerminalAttChange) {\r
749 Var_UpdateConsoleInpOption ();\r
750 Var_UpdateConsoleOutOption ();\r
751 Var_UpdateErrorOutOption ();\r
752 }\r
753 //\r
754 // Check data which located in Console Options Menu and save the settings if need\r
755 //\r
756 if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, sizeof (NewBmmData->ConsoleInCheck)) != 0){\r
757 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++){\r
758 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleInpMenu, Index);\r
759 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;\r
760 ASSERT (Index < MAX_MENU_NUMBER);\r
761 NewConsoleContext->IsActive = NewBmmData->ConsoleInCheck[Index];\r
762 }\r
763 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
764 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
765 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
766 ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);\r
767 NewTerminalContext->IsConIn = NewBmmData->ConsoleInCheck[Index + ConsoleInpMenu.MenuNumber];\r
768 }\r
769 Var_UpdateConsoleInpOption();\r
770 }\r
771\r
772 if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, sizeof (NewBmmData->ConsoleOutCheck)) != 0){\r
773 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++){\r
774 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleOutMenu, Index);\r
775 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;\r
776 ASSERT (Index < MAX_MENU_NUMBER);\r
777 NewConsoleContext->IsActive = NewBmmData->ConsoleOutCheck[Index];\r
778 }\r
779 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
780 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
781 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
782 ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);\r
783 NewTerminalContext->IsConOut = NewBmmData->ConsoleOutCheck[Index + ConsoleOutMenu.MenuNumber];\r
784 }\r
785 Var_UpdateConsoleOutOption();\r
786 }\r
787\r
788 if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, sizeof (NewBmmData->ConsoleErrCheck)) != 0){\r
789 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++){\r
790 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleErrMenu, Index);\r
791 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;\r
792 ASSERT (Index < MAX_MENU_NUMBER);\r
793 NewConsoleContext->IsActive = NewBmmData->ConsoleErrCheck[Index];\r
794 }\r
795 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
796 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
797 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
798 ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);\r
799 NewTerminalContext->IsStdErr = NewBmmData->ConsoleErrCheck[Index + ConsoleErrMenu.MenuNumber];\r
800 }\r
801 Var_UpdateErrorOutOption();\r
802 }\r
803\r
804 if (CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0 ||\r
805 CompareMem (NewBmmData->BootOptionalData, OldBmmData->BootOptionalData, sizeof (NewBmmData->BootOptionalData)) != 0) {\r
806 Status = Var_UpdateBootOption (Private);\r
807 NewBmmData->BootOptionChanged = FALSE;\r
808 if (EFI_ERROR (Status)) {\r
809 return Status;\r
810 }\r
811 BOpt_GetBootOptions (Private);\r
812 }\r
813\r
814 if (CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0 ||\r
815 CompareMem (NewBmmData->DriverOptionalData, OldBmmData->DriverOptionalData, sizeof (NewBmmData->DriverOptionalData)) != 0) {\r
816 Status = Var_UpdateDriverOption (\r
817 Private,\r
818 Private->BmmHiiHandle,\r
819 NewBmmData->DriverDescriptionData,\r
820 NewBmmData->DriverOptionalData,\r
821 NewBmmData->ForceReconnect\r
822 );\r
823 NewBmmData->DriverOptionChanged = FALSE;\r
824 NewBmmData->ForceReconnect = TRUE;\r
825 if (EFI_ERROR (Status)) {\r
826 return Status;\r
827 }\r
828\r
829 BOpt_GetDriverOptions (Private);\r
830 }\r
831\r
832 //\r
833 // After user do the save action, need to update OldBmmData.\r
834 //\r
835 CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));\r
836\r
837 return EFI_SUCCESS;\r
838}\r
839\r
840/**\r
841 This function processes the results of changes in configuration.\r
842\r
843\r
844 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
845 @param Action Specifies the type of action taken by the browser.\r
846 @param QuestionId A unique value which is sent to the original exporting driver\r
847 so that it can identify the type of data to expect.\r
848 @param Type The type of value for the question.\r
849 @param Value A pointer to the data being sent to the original exporting driver.\r
850 @param ActionRequest On return, points to the action requested by the callback function.\r
851\r
852 @retval EFI_SUCCESS The callback successfully handled the action.\r
853 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
854 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
855 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
856 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.\r
857**/\r
858EFI_STATUS\r
859EFIAPI\r
860BootMaintCallback (\r
861 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
862 IN EFI_BROWSER_ACTION Action,\r
863 IN EFI_QUESTION_ID QuestionId,\r
864 IN UINT8 Type,\r
865 IN EFI_IFR_TYPE_VALUE *Value,\r
866 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
867 )\r
868{\r
869 BMM_CALLBACK_DATA *Private;\r
870 BM_MENU_ENTRY *NewMenuEntry;\r
871 BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
4af04335
DB
872 UINTN Index;\r
873 EFI_DEVICE_PATH_PROTOCOL * File;\r
874\r
875 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {\r
876 //\r
877 // Do nothing for other UEFI Action. Only do call back when data is changed.\r
878 //\r
879 return EFI_UNSUPPORTED;\r
880 }\r
4af04335
DB
881\r
882 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
883 //\r
884 // Retrive uncommitted data from Form Browser\r
885 //\r
886 CurrentFakeNVMap = &Private->BmmFakeNvData;\r
887 HiiGetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);\r
888\r
889 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
890 if (Value == NULL) {\r
891 return EFI_INVALID_PARAMETER;\r
892 }\r
893 \r
894 UpdatePageId (Private, QuestionId);\r
895\r
896 if (QuestionId < FILE_OPTION_OFFSET) {\r
897 if (QuestionId < CONFIG_OPTION_OFFSET) {\r
898 switch (QuestionId) {\r
899 case FORM_BOOT_ADD_ID:\r
900 // Leave BMM and enter FileExplorer. \r
c7d1e742 901 ChooseFile (NULL, L".efi", CreateBootOptionFromFile, &File);\r
4af04335
DB
902 break;\r
903\r
904 case FORM_DRV_ADD_FILE_ID:\r
905 // Leave BMM and enter FileExplorer.\r
c7d1e742 906 ChooseFile (NULL, L".efi", CreateDriverOptionFromFile, &File);\r
4af04335
DB
907 break;\r
908\r
909 case FORM_DRV_ADD_HANDLE_ID:\r
910 CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);\r
911 UpdateDrvAddHandlePage (Private);\r
912 break;\r
913\r
914 case FORM_BOOT_DEL_ID:\r
915 CleanUpPage (FORM_BOOT_DEL_ID, Private);\r
916 UpdateBootDelPage (Private);\r
917 break;\r
918\r
919 case FORM_BOOT_CHG_ID:\r
920 case FORM_DRV_CHG_ID:\r
921 UpdatePageBody (QuestionId, Private);\r
922 break;\r
923\r
924 case FORM_DRV_DEL_ID:\r
925 CleanUpPage (FORM_DRV_DEL_ID, Private);\r
926 UpdateDrvDelPage (Private);\r
927 break;\r
928\r
4af04335
DB
929 case FORM_CON_IN_ID:\r
930 case FORM_CON_OUT_ID:\r
931 case FORM_CON_ERR_ID:\r
932 UpdatePageBody (QuestionId, Private);\r
933 break;\r
934\r
935 case FORM_CON_MODE_ID:\r
936 CleanUpPage (FORM_CON_MODE_ID, Private);\r
937 UpdateConModePage (Private);\r
938 break;\r
939\r
940 case FORM_CON_COM_ID:\r
941 CleanUpPage (FORM_CON_COM_ID, Private);\r
942 UpdateConCOMPage (Private);\r
943 break;\r
944\r
945 default:\r
946 break;\r
947 }\r
948 } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {\r
949 Index = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);\r
950 Private->CurrentTerminal = Index;\r
951\r
952 CleanUpPage (FORM_CON_COM_SETUP_ID, Private);\r
953 UpdateTerminalPage (Private);\r
954\r
955 } else if (QuestionId >= HANDLE_OPTION_OFFSET) {\r
956 Index = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);\r
957\r
958 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);\r
959 ASSERT (NewMenuEntry != NULL);\r
960 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;\r
961\r
962 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);\r
963\r
964 Private->MenuEntry = NewMenuEntry;\r
965 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;\r
966\r
967 UpdateDriverAddHandleDescPage (Private);\r
968 }\r
969 }\r
970 if (QuestionId == KEY_VALUE_BOOT_FROM_FILE){\r
971 // Leave BMM and enter FileExplorer.\r
c7d1e742 972 ChooseFile (NULL, L".efi", BootFromFile, &File);\r
4af04335
DB
973 }\r
974 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
975 if ((Value == NULL) || (ActionRequest == NULL)) {\r
976 return EFI_INVALID_PARAMETER;\r
977 }\r
978 \r
979 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT) {\r
980 CurrentFakeNVMap->BootOptionChanged = FALSE;\r
981 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
982 } else if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {\r
983 CurrentFakeNVMap->DriverOptionChanged = FALSE;\r
984 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
985 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {\r
986 //\r
987 // Discard changes and exit formset\r
988 //\r
989 CurrentFakeNVMap->DriverOptionalData[0] = 0x0000;\r
990 CurrentFakeNVMap->DriverDescriptionData[0] = 0x0000;\r
991 CurrentFakeNVMap->DriverOptionChanged = FALSE;\r
992 CurrentFakeNVMap->ForceReconnect = TRUE;\r
993 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
994 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT) {\r
995 //\r
996 // Discard changes and exit formset\r
997 //\r
998 CurrentFakeNVMap->BootOptionalData[0] = 0x0000;\r
999 CurrentFakeNVMap->BootDescriptionData[0] = 0x0000;\r
1000 CurrentFakeNVMap->BootOptionChanged = FALSE;\r
1001 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
1002 } else if (QuestionId == KEY_VALUE_BOOT_DESCRIPTION || QuestionId == KEY_VALUE_BOOT_OPTION) {\r
1003 CurrentFakeNVMap->BootOptionChanged = TRUE;\r
1004 } else if (QuestionId == KEY_VALUE_DRIVER_DESCRIPTION || QuestionId == KEY_VALUE_DRIVER_OPTION) {\r
1005 CurrentFakeNVMap->DriverOptionChanged = TRUE;\r
1006 } \r
1007\r
1008 if ((QuestionId >= BOOT_OPTION_DEL_QUESTION_ID) && (QuestionId < BOOT_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {\r
1009 if (Value->b){\r
1010 //\r
1011 // Means user try to delete this boot option but not press F10 or "Commit Changes and Exit" menu.\r
1012 //\r
1013 CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = TRUE;\r
1014 } else {\r
1015 //\r
1016 // Means user remove the old check status.\r
1017 //\r
1018 CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = FALSE;\r
1019 }\r
1020 } else if ((QuestionId >= DRIVER_OPTION_DEL_QUESTION_ID) && (QuestionId < DRIVER_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {\r
1021 if (Value->b){\r
1022 CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = TRUE;\r
1023 } else {\r
1024 CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = FALSE;\r
1025 }\r
1026 } else {\r
1027 switch (QuestionId) {\r
1028 case KEY_VALUE_SAVE_AND_EXIT:\r
1029 case KEY_VALUE_NO_SAVE_AND_EXIT:\r
1030 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {\r
1031 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
1032 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {\r
1033 DiscardChangeHandler (Private, CurrentFakeNVMap);\r
1034 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
1035 }\r
1036\r
1037 break;\r
1038\r
1039 case FORM_RESET:\r
1040 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
1041 return EFI_UNSUPPORTED;\r
1042\r
1043 default:\r
1044 break;\r
1045 }\r
1046 }\r
1047 }\r
1048\r
1049 //\r
1050 // Pass changed uncommitted data back to Form Browser\r
1051 //\r
1052 HiiSetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);\r
1053\r
1054 return EFI_SUCCESS;\r
1055}\r
1056\r
1057/**\r
1058 Discard all changes done to the BMM pages such as Boot Order change,\r
1059 Driver order change.\r
1060\r
1061 @param Private The BMM context data.\r
1062 @param CurrentFakeNVMap The current Fack NV Map.\r
1063\r
1064**/\r
1065VOID\r
1066DiscardChangeHandler (\r
1067 IN BMM_CALLBACK_DATA *Private,\r
1068 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap\r
1069 )\r
1070{\r
1071 UINT16 Index;\r
1072\r
1073 switch (Private->BmmPreviousPageId) {\r
1074 case FORM_BOOT_CHG_ID:\r
1075 CopyMem (CurrentFakeNVMap->BootOptionOrder, Private->BmmOldFakeNVData.BootOptionOrder, sizeof (CurrentFakeNVMap->BootOptionOrder));\r
1076 break;\r
1077\r
1078 case FORM_DRV_CHG_ID:\r
1079 CopyMem (CurrentFakeNVMap->DriverOptionOrder, Private->BmmOldFakeNVData.DriverOptionOrder, sizeof (CurrentFakeNVMap->DriverOptionOrder));\r
1080 break;\r
1081\r
1082 case FORM_BOOT_DEL_ID:\r
1083 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));\r
1084 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
1085 CurrentFakeNVMap->BootOptionDel[Index] = FALSE;\r
1086 }\r
1087 break;\r
1088\r
1089 case FORM_DRV_DEL_ID:\r
1090 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));\r
1091 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
1092 CurrentFakeNVMap->DriverOptionDel[Index] = FALSE;\r
1093 }\r
1094 break;\r
1095\r
1096 case FORM_BOOT_NEXT_ID:\r
1097 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;\r
1098 break;\r
1099\r
1100 case FORM_TIME_OUT_ID:\r
1101 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;\r
1102 break;\r
1103\r
1104 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
1105 case FORM_DRV_ADD_FILE_ID:\r
1106 case FORM_DRV_ADD_HANDLE_ID:\r
1107 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;\r
1108 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;\r
1109 break;\r
1110\r
1111 default:\r
1112 break;\r
1113 }\r
1114}\r
1115\r
1116/**\r
4af04335 1117\r
a85be3ae 1118 Update the menus in the BMM page.\r
4af04335
DB
1119\r
1120**/\r
1121VOID\r
a85be3ae
ED
1122CustomizeMenus (\r
1123 VOID\r
4af04335
DB
1124 )\r
1125{\r
4af04335
DB
1126 VOID *StartOpCodeHandle;\r
1127 VOID *EndOpCodeHandle;\r
a85be3ae
ED
1128 EFI_IFR_GUID_LABEL *StartGuidLabel;\r
1129 EFI_IFR_GUID_LABEL *EndGuidLabel;\r
1130\r
4af04335
DB
1131 //\r
1132 // Allocate space for creation of UpdateData Buffer\r
1133 //\r
1134 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1135 ASSERT (StartOpCodeHandle != NULL);\r
1136\r
1137 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1138 ASSERT (EndOpCodeHandle != NULL);\r
4af04335
DB
1139 //\r
1140 // Create Hii Extend Label OpCode as the start opcode\r
1141 //\r
a85be3ae
ED
1142 StartGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1143 StartGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1144 StartGuidLabel->Number = LABEL_FORM_MAIN_START;\r
4af04335
DB
1145 //\r
1146 // Create Hii Extend Label OpCode as the end opcode\r
1147 //\r
a85be3ae
ED
1148 EndGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1149 EndGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1150 EndGuidLabel->Number = LABEL_FORM_MAIN_END;\r
4af04335
DB
1151\r
1152 //\r
a85be3ae 1153 //Updata Front Page form\r
4af04335 1154 //\r
a85be3ae
ED
1155 UiCustomizeBMMPage (\r
1156 mBmmCallbackInfo->BmmHiiHandle,\r
1157 StartOpCodeHandle\r
1158 );\r
4af04335 1159\r
4af04335 1160 HiiUpdateForm (\r
a85be3ae 1161 mBmmCallbackInfo->BmmHiiHandle,\r
4af04335
DB
1162 &mBootMaintGuid,\r
1163 FORM_MAIN_ID,\r
1164 StartOpCodeHandle,\r
1165 EndOpCodeHandle\r
1166 );\r
1167\r
1168 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
a85be3ae 1169 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
4af04335
DB
1170}\r
1171\r
1172/**\r
1173 Create dynamic code for BMM and initialize all of BMM configuration data in BmmFakeNvData and\r
1174 BmmOldFakeNVData member in BMM context data.\r
1175\r
1176 @param CallbackData The BMM context data.\r
1177\r
1178**/\r
1179VOID\r
1180InitializeBmmConfig (\r
1181 IN BMM_CALLBACK_DATA *CallbackData\r
1182 )\r
1183{\r
1184 BM_MENU_ENTRY *NewMenuEntry;\r
1185 BM_LOAD_CONTEXT *NewLoadContext;\r
1186 UINT16 Index;\r
1187\r
1188 ASSERT (CallbackData != NULL);\r
1189\r
4af04335
DB
1190 //\r
1191 // Initialize data which located in BMM main page\r
1192 //\r
f7986526 1193 CallbackData->BmmFakeNvData.BootNext = NONE_BOOTNEXT_VALUE;\r
4af04335
DB
1194 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
1195 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
1196 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
1197\r
1198 if (NewLoadContext->IsBootNext) {\r
1199 CallbackData->BmmFakeNvData.BootNext = Index;\r
1200 break;\r
1201 }\r
1202 }\r
1203\r
1204 CallbackData->BmmFakeNvData.BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut);\r
1205\r
1206 //\r
1207 // Initialize data which located in Boot Options Menu\r
1208 //\r
1209 GetBootOrder (CallbackData);\r
1210\r
1211 //\r
1212 // Initialize data which located in Driver Options Menu\r
1213 //\r
1214 GetDriverOrder (CallbackData);\r
1215\r
1216 //\r
1217 // Initialize data which located in Console Options Menu\r
1218 //\r
1219 GetConsoleOutMode (CallbackData);\r
1220 GetConsoleInCheck (CallbackData);\r
1221 GetConsoleOutCheck (CallbackData);\r
1222 GetConsoleErrCheck (CallbackData);\r
1223 GetTerminalAttribute (CallbackData);\r
1224\r
1225 CallbackData->BmmFakeNvData.ForceReconnect = TRUE;\r
1226\r
a85be3ae
ED
1227 //\r
1228 // Update the menus.\r
1229 //\r
1230 CustomizeMenus ();\r
1231\r
4af04335
DB
1232 //\r
1233 // Backup Initialize BMM configuartion data to BmmOldFakeNVData\r
1234 //\r
1235 CopyMem (&CallbackData->BmmOldFakeNVData, &CallbackData->BmmFakeNvData, sizeof (BMM_FAKE_NV_DATA));\r
1236}\r
1237\r
1238/**\r
1239 Initialized all Menu Option List.\r
1240\r
1241 @param CallbackData The BMM context data.\r
1242\r
1243**/\r
1244VOID\r
1245InitAllMenu (\r
1246 IN BMM_CALLBACK_DATA *CallbackData\r
1247 )\r
1248{\r
1249 InitializeListHead (&BootOptionMenu.Head);\r
1250 InitializeListHead (&DriverOptionMenu.Head);\r
1251 BOpt_GetBootOptions (CallbackData);\r
1252 BOpt_GetDriverOptions (CallbackData);\r
1253 BOpt_FindDrivers ();\r
1254 InitializeListHead (&ConsoleInpMenu.Head);\r
1255 InitializeListHead (&ConsoleOutMenu.Head);\r
1256 InitializeListHead (&ConsoleErrMenu.Head);\r
1257 InitializeListHead (&TerminalMenu.Head);\r
1258 LocateSerialIo ();\r
1259 GetAllConsoles ();\r
1260 mAllMenuInit = TRUE;\r
1261}\r
1262\r
1263/**\r
1264 Free up all Menu Option list.\r
1265\r
1266**/\r
1267VOID\r
1268FreeAllMenu (\r
1269 VOID\r
1270 )\r
1271{\r
1272 if (!mAllMenuInit){\r
1273 return;\r
1274 }\r
1275 BOpt_FreeMenu (&BootOptionMenu);\r
1276 BOpt_FreeMenu (&DriverOptionMenu);\r
1277 BOpt_FreeMenu (&DriverMenu);\r
1278 FreeAllConsoles ();\r
1279 mAllMenuInit = FALSE;\r
1280}\r
1281\r
8c53b5e6
ED
1282/**\r
1283 Initial the boot mode related parameters.\r
1284\r
1285**/\r
1286VOID\r
1287BmmInitialBootModeInfo (\r
1288 VOID\r
1289 )\r
1290{\r
1291 EFI_STATUS Status;\r
1292 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1293 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;\r
1294 UINTN BootTextColumn;\r
1295 UINTN BootTextRow;\r
1296\r
1297 if (mBmmModeInitialized) {\r
1298 return;\r
1299 }\r
1300\r
1301 //\r
1302 // After the console is ready, get current video resolution\r
1303 // and text mode before launching setup at first time.\r
1304 //\r
1305 Status = gBS->HandleProtocol (\r
1306 gST->ConsoleOutHandle,\r
1307 &gEfiGraphicsOutputProtocolGuid,\r
1308 (VOID**)&GraphicsOutput\r
1309 );\r
1310 if (EFI_ERROR (Status)) {\r
1311 GraphicsOutput = NULL;\r
1312 }\r
1313\r
1314 Status = gBS->HandleProtocol (\r
1315 gST->ConsoleOutHandle,\r
1316 &gEfiSimpleTextOutProtocolGuid,\r
1317 (VOID**)&SimpleTextOut\r
1318 );\r
1319 if (EFI_ERROR (Status)) {\r
1320 SimpleTextOut = NULL;\r
1321 }\r
1322\r
1323 if (GraphicsOutput != NULL) {\r
1324 //\r
1325 // Get current video resolution and text mode.\r
1326 //\r
1327 mBmmBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
1328 mBmmBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
1329 }\r
1330\r
1331 if (SimpleTextOut != NULL) {\r
1332 Status = SimpleTextOut->QueryMode (\r
1333 SimpleTextOut,\r
1334 SimpleTextOut->Mode->Mode,\r
1335 &BootTextColumn,\r
1336 &BootTextRow\r
1337 );\r
1338 mBmmBootTextModeColumn = (UINT32)BootTextColumn;\r
1339 mBmmBootTextModeRow = (UINT32)BootTextRow;\r
1340 }\r
1341\r
1342 //\r
1343 // Get user defined text mode for setup.\r
1344 //\r
1345 mBmmSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);\r
1346 mBmmSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);\r
1347 mBmmSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);\r
1348 mBmmSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);\r
1349\r
1350 mBmmModeInitialized = TRUE;\r
1351}\r
1352\r
4af04335
DB
1353/**\r
1354\r
1355 Install Boot Maintenance Manager Menu driver.\r
1356\r
1357 @param ImageHandle The image handle.\r
1358 @param SystemTable The system table.\r
1359\r
1360 @retval EFI_SUCEESS Install Boot manager menu success.\r
1361 @retval Other Return error status.\r
1362\r
1363**/\r
1364EFI_STATUS\r
1365EFIAPI\r
13c4e864 1366BootMaintenanceManagerUiLibConstructor (\r
4af04335
DB
1367 IN EFI_HANDLE ImageHandle,\r
1368 IN EFI_SYSTEM_TABLE *SystemTable\r
1369 )\r
1370\r
1371{\r
1372 EFI_STATUS Status;\r
1373 UINT8 *Ptr;\r
1374\r
1375 Status = EFI_SUCCESS;\r
1376\r
1377 //\r
1378 // Install Device Path Protocol and Config Access protocol to driver handle\r
1379 //\r
1380 Status = gBS->InstallMultipleProtocolInterfaces (\r
1381 &mBmmCallbackInfo->BmmDriverHandle,\r
1382 &gEfiDevicePathProtocolGuid,\r
1383 &mBmmHiiVendorDevicePath,\r
1384 &gEfiHiiConfigAccessProtocolGuid,\r
1385 &mBmmCallbackInfo->BmmConfigAccess,\r
1386 NULL\r
1387 );\r
1388 ASSERT_EFI_ERROR (Status);\r
1389\r
1390 //\r
1391 // Post our Boot Maint VFR binary to the HII database.\r
1392 //\r
1393 mBmmCallbackInfo->BmmHiiHandle = HiiAddPackages (\r
1394 &mBootMaintGuid,\r
1395 mBmmCallbackInfo->BmmDriverHandle,\r
1396 BootMaintenanceManagerBin,\r
13c4e864 1397 BootMaintenanceManagerUiLibStrings,\r
4af04335
DB
1398 NULL\r
1399 );\r
1400 ASSERT (mBmmCallbackInfo->BmmHiiHandle != NULL);\r
1401\r
1402 //\r
1403 // Locate Formbrowser2 protocol\r
1404 //\r
1405 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &mBmmCallbackInfo->FormBrowser2);\r
1406 ASSERT_EFI_ERROR (Status);\r
1407\r
1408 EfiBootManagerRefreshAllBootOption ();\r
1409\r
1410 //\r
1411 // Create LoadOption in BmmCallbackInfo for Driver Callback\r
1412 //\r
1413 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));\r
1414 ASSERT (Ptr != NULL);\r
1415\r
1416 //\r
1417 // Initialize Bmm callback data.\r
1418 //\r
1419 mBmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;\r
1420 Ptr += sizeof (BM_LOAD_CONTEXT);\r
1421\r
1422 mBmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;\r
1423 Ptr += sizeof (BM_FILE_CONTEXT);\r
1424\r
1425 mBmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;\r
1426 Ptr += sizeof (BM_HANDLE_CONTEXT);\r
1427\r
1428 mBmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;\r
1429\r
1430 mBmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;\r
1431 mBmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;\r
1432\r
1433 InitAllMenu (mBmmCallbackInfo);\r
1434\r
1435 CreateUpdateData();\r
1436 //\r
1437 // Update boot maintenance manager page \r
1438 //\r
1439 InitializeBmmConfig(mBmmCallbackInfo);\r
1440\r
8c53b5e6
ED
1441 BmmInitialBootModeInfo();\r
1442\r
4af04335
DB
1443 return EFI_SUCCESS;\r
1444}\r
1445\r
1446/**\r
1447 Unloads the application and its installed protocol.\r
1448\r
1449 @param ImageHandle Handle that identifies the image to be unloaded.\r
1450 @param SystemTable The system table.\r
1451\r
1452 @retval EFI_SUCCESS The image has been unloaded.\r
1453\r
1454**/\r
1455EFI_STATUS\r
1456EFIAPI\r
13c4e864 1457BootMaintenanceManagerUiLibDestructor (\r
4af04335
DB
1458 IN EFI_HANDLE ImageHandle,\r
1459 IN EFI_SYSTEM_TABLE *SystemTable\r
1460 )\r
1461\r
1462{\r
1463 if (mStartOpCodeHandle != NULL) {\r
1464 HiiFreeOpCodeHandle (mStartOpCodeHandle);\r
1465 }\r
1466\r
1467 if (mEndOpCodeHandle != NULL) {\r
1468 HiiFreeOpCodeHandle (mEndOpCodeHandle);\r
1469 }\r
1470\r
1471 FreeAllMenu ();\r
1472\r
1473 //\r
1474 // Remove our IFR data from HII database\r
1475 //\r
1476 HiiRemovePackages (mBmmCallbackInfo->BmmHiiHandle);\r
1477\r
1478 gBS->UninstallMultipleProtocolInterfaces (\r
1479 mBmmCallbackInfo->BmmDriverHandle,\r
1480 &gEfiDevicePathProtocolGuid,\r
1481 &mBmmHiiVendorDevicePath,\r
1482 &gEfiHiiConfigAccessProtocolGuid,\r
1483 &mBmmCallbackInfo->BmmConfigAccess,\r
1484 NULL\r
1485 );\r
1486\r
1487 FreePool (mBmmCallbackInfo->LoadContext);\r
1488\r
1489 return EFI_SUCCESS;\r
1490}\r
1491\r