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