]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Application/UiApp/FrontPage.c
MdeModulePkg: Update UiApp to handle terminal type TtyTerm
[mirror_edk2.git] / MdeModulePkg / Application / UiApp / FrontPage.c
CommitLineData
143f0b1d
ED
1/** @file\r
2 FrontPage routines to handle the callbacks and browser calls\r
3\r
afc244a5 4Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>\r
143f0b1d
ED
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 "FrontPage.h"\r
16#include "Language.h"\r
17#define MAX_STRING_LEN 200\r
18\r
19EFI_GUID mFrontPageGuid = FRONT_PAGE_FORMSET_GUID;\r
20\r
21BOOLEAN gConnectAllHappened = FALSE;\r
22BOOLEAN mFeaturerSwitch = TRUE;\r
23BOOLEAN mResetRequired = FALSE;\r
24BOOLEAN mEnterBmm = FALSE;\r
25\r
26EFI_FORM_BROWSER2_PROTOCOL *gFormBrowser2;\r
27CHAR8 *mLanguageString;\r
28BOOLEAN mModeInitialized = FALSE;\r
29//\r
30// Boot video resolution and text mode.\r
31//\r
32UINT32 mBootHorizontalResolution = 0;\r
33UINT32 mBootVerticalResolution = 0;\r
34UINT32 mBootTextModeColumn = 0;\r
35UINT32 mBootTextModeRow = 0;\r
36//\r
37// BIOS setup video resolution and text mode.\r
38//\r
39UINT32 mSetupTextModeColumn = 0;\r
40UINT32 mSetupTextModeRow = 0;\r
41UINT32 mSetupHorizontalResolution = 0;\r
42UINT32 mSetupVerticalResolution = 0;\r
43\r
44FRONT_PAGE_CALLBACK_DATA gFrontPagePrivate = {\r
45 FRONT_PAGE_CALLBACK_DATA_SIGNATURE,\r
46 NULL,\r
47 NULL,\r
48 NULL,\r
49 {\r
50 FakeExtractConfig,\r
51 FakeRouteConfig,\r
52 FrontPageCallback\r
53 }\r
54};\r
55\r
56HII_VENDOR_DEVICE_PATH mFrontPageHiiVendorDevicePath = {\r
57 {\r
58 {\r
59 HARDWARE_DEVICE_PATH,\r
60 HW_VENDOR_DP,\r
61 {\r
62 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
63 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
64 }\r
65 },\r
66 //\r
67 // {8E6D99EE-7531-48f8-8745-7F6144468FF2}\r
68 //\r
69 { 0x8e6d99ee, 0x7531, 0x48f8, { 0x87, 0x45, 0x7f, 0x61, 0x44, 0x46, 0x8f, 0xf2 } }\r
70 },\r
71 {\r
72 END_DEVICE_PATH_TYPE,\r
73 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
74 {\r
75 (UINT8) (END_DEVICE_PATH_LENGTH),\r
76 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
77 }\r
78 }\r
79};\r
80\r
81/**\r
82 Update the banner information for the Front Page based on Smbios information.\r
83\r
84**/\r
85VOID\r
86UpdateFrontPageStrings (\r
87 VOID\r
88 );\r
89\r
90/**\r
91 This function allows a caller to extract the current configuration for one\r
92 or more named elements from the target driver.\r
93\r
94\r
95 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
96 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
97 @param Progress On return, points to a character in the Request string.\r
98 Points to the string's null terminator if request was successful.\r
99 Points to the most recent '&' before the first failing name/value\r
100 pair (or the beginning of the string if the failure is in the\r
101 first name/value pair) if the request was not successful.\r
102 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
103 has all values filled in for the names in the Request string.\r
104 String to be allocated by the called function.\r
105\r
106 @retval EFI_SUCCESS The Results is filled with the requested values.\r
107 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
108 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
109 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
110\r
111**/\r
112EFI_STATUS\r
113EFIAPI\r
114FakeExtractConfig (\r
115 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
116 IN CONST EFI_STRING Request,\r
117 OUT EFI_STRING *Progress,\r
118 OUT EFI_STRING *Results\r
119 )\r
120{\r
121 if (Progress == NULL || Results == NULL) {\r
122 return EFI_INVALID_PARAMETER;\r
123 }\r
124 *Progress = Request;\r
125 return EFI_NOT_FOUND;\r
126}\r
127\r
128/**\r
129 This function processes the results of changes in configuration.\r
130\r
131\r
132 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
133 @param Configuration A null-terminated Unicode string in <ConfigResp> format.\r
134 @param Progress A pointer to a string filled in with the offset of the most\r
135 recent '&' before the first failing name/value pair (or the\r
136 beginning of the string if the failure is in the first\r
137 name/value pair) or the terminating NULL if all was successful.\r
138\r
139 @retval EFI_SUCCESS The Results is processed successfully.\r
140 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
141 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
142\r
143**/\r
144EFI_STATUS\r
145EFIAPI\r
146FakeRouteConfig (\r
147 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
148 IN CONST EFI_STRING Configuration,\r
149 OUT EFI_STRING *Progress\r
150 )\r
151{\r
152 if (Configuration == NULL || Progress == NULL) {\r
153 return EFI_INVALID_PARAMETER;\r
154 }\r
155\r
156 *Progress = Configuration;\r
157 if (!HiiIsConfigHdrMatch (Configuration, &mBootMaintGuid, mBootMaintStorageName)\r
158 && !HiiIsConfigHdrMatch (Configuration, &mFileExplorerGuid, mFileExplorerStorageName)) {\r
159 return EFI_NOT_FOUND;\r
160 }\r
161\r
162 *Progress = Configuration + StrLen (Configuration);\r
163 return EFI_SUCCESS;\r
164}\r
165\r
166/**\r
167 Create oneof options for language.\r
168\r
169**/\r
170VOID\r
171InitializeLanguage (\r
172 VOID\r
173 )\r
174{\r
175 EFI_STATUS Status;\r
176 CHAR8 *LangCode;\r
177 CHAR8 *Lang;\r
178 CHAR8 *CurrentLang;\r
179 UINTN OptionCount;\r
180 CHAR16 *StringBuffer;\r
181 EFI_HII_HANDLE HiiHandle;\r
182 VOID *OptionsOpCodeHandle;\r
183 VOID *StartOpCodeHandle;\r
184 VOID *EndOpCodeHandle;\r
185 EFI_IFR_GUID_LABEL *StartLabel;\r
186 EFI_IFR_GUID_LABEL *EndLabel; \r
187 EFI_HII_STRING_PROTOCOL *HiiString;\r
188 UINTN StringSize;\r
189\r
190 Lang = NULL;\r
191 StringBuffer = NULL;\r
192\r
193 //\r
194 // Init OpCode Handle and Allocate space for creation of UpdateData Buffer\r
195 //\r
196 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
197 ASSERT (StartOpCodeHandle != NULL);\r
198\r
199 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
200 ASSERT (EndOpCodeHandle != NULL);\r
201\r
202 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
203 ASSERT (OptionsOpCodeHandle != NULL);\r
204 //\r
205 // Create Hii Extend Label OpCode as the start opcode\r
206 //\r
207 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
208 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
209 StartLabel->Number = LABEL_SELECT_LANGUAGE;\r
210\r
211 //\r
212 // Create Hii Extend Label OpCode as the end opcode\r
213 //\r
214 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
215 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
216 EndLabel->Number = LABEL_END;\r
217 //\r
218 // Collect the languages from what our current Language support is based on our VFR\r
219 //\r
220 HiiHandle = gFrontPagePrivate.HiiHandle;\r
221\r
222 CurrentLang = GetEfiGlobalVariable (L"PlatformLang");\r
223\r
224 if (mLanguageString == NULL) {\r
225 //\r
226 // Get Support language list from variable.\r
227 //\r
228 mLanguageString = GetEfiGlobalVariable (L"PlatformLangCodes");\r
229 if (mLanguageString == NULL) {\r
230 mLanguageString = AllocateCopyPool (\r
231 AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)),\r
232 (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)\r
233 );\r
234 ASSERT (mLanguageString != NULL);\r
235 }\r
236 }\r
237\r
238 if (gFrontPagePrivate.LanguageToken == NULL) {\r
239 //\r
240 // Count the language list number.\r
241 // \r
242 LangCode = mLanguageString;\r
243 Lang = AllocatePool (AsciiStrSize (mLanguageString));\r
244 ASSERT (Lang != NULL);\r
245 OptionCount = 0;\r
246 while (*LangCode != 0) {\r
247 GetNextLanguage (&LangCode, Lang);\r
248 OptionCount ++;\r
249 }\r
250\r
251 //\r
252 // Allocate extra 1 as the end tag.\r
253 //\r
254 gFrontPagePrivate.LanguageToken = AllocateZeroPool ((OptionCount + 1) * sizeof (EFI_STRING_ID));\r
255 ASSERT (gFrontPagePrivate.LanguageToken != NULL);\r
256\r
257 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
258 ASSERT_EFI_ERROR (Status);\r
259\r
260 LangCode = mLanguageString;\r
261 OptionCount = 0;\r
262 while (*LangCode != 0) {\r
263 GetNextLanguage (&LangCode, Lang);\r
264\r
265 StringSize = 0;\r
266 Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);\r
267 if (Status == EFI_BUFFER_TOO_SMALL) {\r
268 StringBuffer = AllocateZeroPool (StringSize);\r
269 ASSERT (StringBuffer != NULL);\r
270 Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);\r
271 ASSERT_EFI_ERROR (Status);\r
272 }\r
273\r
274 if (EFI_ERROR (Status)) {\r
275 StringBuffer = AllocatePool (AsciiStrSize (Lang) * sizeof (CHAR16));\r
276 ASSERT (StringBuffer != NULL);\r
277 AsciiStrToUnicodeStr (Lang, StringBuffer);\r
278 }\r
279\r
280 ASSERT (StringBuffer != NULL);\r
281 gFrontPagePrivate.LanguageToken[OptionCount] = HiiSetString (HiiHandle, 0, StringBuffer, NULL);\r
282 FreePool (StringBuffer);\r
283\r
284 OptionCount++;\r
285 }\r
286 }\r
287\r
288 ASSERT (gFrontPagePrivate.LanguageToken != NULL);\r
289 LangCode = mLanguageString;\r
290 OptionCount = 0;\r
291 if (Lang == NULL) {\r
292 Lang = AllocatePool (AsciiStrSize (mLanguageString));\r
293 ASSERT (Lang != NULL);\r
294 }\r
295 while (*LangCode != 0) {\r
296 GetNextLanguage (&LangCode, Lang);\r
297\r
298 if (CurrentLang != NULL && AsciiStrCmp (Lang, CurrentLang) == 0) {\r
299 HiiCreateOneOfOptionOpCode (\r
300 OptionsOpCodeHandle,\r
301 gFrontPagePrivate.LanguageToken[OptionCount],\r
302 EFI_IFR_OPTION_DEFAULT,\r
303 EFI_IFR_NUMERIC_SIZE_1,\r
304 (UINT8) OptionCount\r
305 );\r
306 } else {\r
307 HiiCreateOneOfOptionOpCode (\r
308 OptionsOpCodeHandle,\r
309 gFrontPagePrivate.LanguageToken[OptionCount],\r
310 0,\r
311 EFI_IFR_NUMERIC_SIZE_1,\r
312 (UINT8) OptionCount\r
313 );\r
314 }\r
315\r
316 OptionCount++;\r
317 }\r
318\r
319 if (CurrentLang != NULL) {\r
320 FreePool (CurrentLang);\r
321 }\r
322 FreePool (Lang);\r
323\r
324 HiiCreateOneOfOpCode (\r
325 StartOpCodeHandle,\r
326 FRONT_PAGE_KEY_LANGUAGE,\r
327 0,\r
328 0,\r
329 STRING_TOKEN (STR_LANGUAGE_SELECT),\r
330 STRING_TOKEN (STR_LANGUAGE_SELECT_HELP),\r
331 EFI_IFR_FLAG_CALLBACK,\r
332 EFI_IFR_NUMERIC_SIZE_1,\r
333 OptionsOpCodeHandle,\r
334 NULL\r
335 );\r
336\r
337 Status = HiiUpdateForm (\r
338 HiiHandle,\r
339 &mFrontPageGuid,\r
340 FRONT_PAGE_FORM_ID,\r
341 StartOpCodeHandle, // LABEL_SELECT_LANGUAGE\r
342 EndOpCodeHandle // LABEL_END\r
343 );\r
344\r
345 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
346 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
347 HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
348}\r
349\r
350/**\r
351 This function processes the results of changes in configuration.\r
352\r
353\r
354 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
355 @param Action Specifies the type of action taken by the browser.\r
356 @param QuestionId A unique value which is sent to the original exporting driver\r
357 so that it can identify the type of data to expect.\r
358 @param Type The type of value for the question.\r
359 @param Value A pointer to the data being sent to the original exporting driver.\r
360 @param ActionRequest On return, points to the action requested by the callback function.\r
361\r
362 @retval EFI_SUCCESS The callback successfully handled the action.\r
363 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
364 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
365 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
366\r
367**/\r
368EFI_STATUS\r
369EFIAPI\r
370FrontPageCallback (\r
371 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
372 IN EFI_BROWSER_ACTION Action,\r
373 IN EFI_QUESTION_ID QuestionId,\r
374 IN UINT8 Type,\r
375 IN EFI_IFR_TYPE_VALUE *Value,\r
376 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
377 )\r
378{\r
379 CHAR8 *LangCode;\r
380 CHAR8 *Lang;\r
381 UINTN Index;\r
382 EFI_STATUS Status;\r
383\r
384 //\r
385 //Chech whether exit from BMM and reenter frontpage,if yes,reclaim string depositories\r
386 //\r
387 if (Action == EFI_BROWSER_ACTION_FORM_OPEN){\r
388 if (mEnterBmm){\r
389 ReclaimStringDepository();\r
390 mEnterBmm = FALSE;\r
391 }\r
392 }\r
393\r
394 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {\r
395 //\r
396 // Do nothing for other UEFI Action. Only do call back when data is changed.\r
397 //\r
398 return EFI_UNSUPPORTED;\r
399 }\r
400\r
401 if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
402 if ((Value == NULL) || (ActionRequest == NULL)) {\r
403 return EFI_INVALID_PARAMETER;\r
404 }\r
405\r
406 switch (QuestionId) {\r
407 case FRONT_PAGE_KEY_CONTINUE:\r
408 //\r
409 // This is the continue - clear the screen and return an error to get out of FrontPage loop\r
410 //\r
411 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
412 break;\r
413\r
414 case FRONT_PAGE_KEY_LANGUAGE:\r
415 //\r
416 // Allocate working buffer for RFC 4646 language in supported LanguageString.\r
417 //\r
418 Lang = AllocatePool (AsciiStrSize (mLanguageString));\r
419 ASSERT (Lang != NULL); \r
420\r
421 Index = 0;\r
422 LangCode = mLanguageString;\r
423 while (*LangCode != 0) {\r
424 GetNextLanguage (&LangCode, Lang);\r
425\r
426 if (Index == Value->u8) {\r
427 break;\r
428 }\r
429\r
430 Index++;\r
431 }\r
432\r
433 if (Index == Value->u8) {\r
434 Status = gRT->SetVariable (\r
435 L"PlatformLang",\r
436 &gEfiGlobalVariableGuid,\r
437 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
438 AsciiStrSize (Lang),\r
439 Lang\r
440 );\r
441 ASSERT_EFI_ERROR(Status);\r
442 } else {\r
443 ASSERT (FALSE);\r
444 }\r
445 FreePool (Lang);\r
446 //\r
447 //Current language of platform is changed,recreate oneof options for language.\r
448 //\r
449 InitializeLanguage();\r
450 break;\r
451\r
143f0b1d
ED
452 default:\r
453 break;\r
454 }\r
455 } else if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
456 if (Value == NULL) {\r
457 return EFI_INVALID_PARAMETER;\r
458 }\r
459\r
460 //\r
461 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can\r
462 // describe to their customers in documentation how to find their setup information (namely\r
463 // under the device manager and specific buckets)\r
464 //\r
465 switch (QuestionId) {\r
466 case FRONT_PAGE_KEY_BOOT_MANAGER:\r
467 //\r
468 // Boot Manager\r
469 //\r
470 EnumerateBootOptions ();\r
471 break;\r
472\r
473 case FRONT_PAGE_KEY_DEVICE_MANAGER:\r
474 //\r
475 // Device Manager\r
476 //\r
477 CreateDeviceManagerForm(DEVICE_MANAGER_FORM_ID);\r
478 break;\r
479\r
480 case FRONT_PAGE_KEY_BOOT_MAINTAIN:\r
481 //\r
482 // Boot Maintenance Manager\r
483 //\r
484 InitializeBM ();\r
485 mEnterBmm = TRUE;\r
486 break;\r
487\r
488 default:\r
489 break;\r
490 }\r
491 }\r
492\r
493 return EFI_SUCCESS;\r
494}\r
495\r
496/**\r
497 Initialize HII information for the FrontPage\r
498\r
499\r
500 @retval EFI_SUCCESS The operation is successful.\r
501 @retval EFI_DEVICE_ERROR If the dynamic opcode creation failed.\r
502\r
503**/\r
504EFI_STATUS\r
505InitializeFrontPage (\r
506 VOID\r
507 )\r
508{\r
509 EFI_STATUS Status;\r
510\r
511 //\r
512 // Locate Hii relative protocols\r
513 //\r
514 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFormBrowser2);\r
515 if (EFI_ERROR (Status)) {\r
516 return Status;\r
517 }\r
518\r
519 //\r
520 // Install Device Path Protocol and Config Access protocol to driver handle\r
521 //\r
522 gFrontPagePrivate.DriverHandle = NULL;\r
523 Status = gBS->InstallMultipleProtocolInterfaces (\r
524 &gFrontPagePrivate.DriverHandle,\r
525 &gEfiDevicePathProtocolGuid,\r
526 &mFrontPageHiiVendorDevicePath,\r
527 &gEfiHiiConfigAccessProtocolGuid,\r
528 &gFrontPagePrivate.ConfigAccess,\r
529 NULL\r
530 );\r
531 ASSERT_EFI_ERROR (Status);\r
532\r
533 //\r
534 // Publish our HII data\r
535 //\r
536 gFrontPagePrivate.HiiHandle = HiiAddPackages (\r
537 &mFrontPageGuid,\r
538 gFrontPagePrivate.DriverHandle,\r
539 FrontPageVfrBin,\r
540 UiAppStrings,\r
541 NULL\r
542 );\r
543 ASSERT (gFrontPagePrivate.HiiHandle != NULL);\r
544\r
545 //\r
546 //Updata Front Page strings\r
547 //\r
548 UpdateFrontPageStrings ();\r
549\r
550 //\r
551 // Initialize laguage options\r
552 //\r
553 InitializeLanguage ();\r
554\r
555 return Status;\r
556}\r
557\r
558/**\r
559 Call the browser and display the front page\r
560\r
561 @return Status code that will be returned by\r
562 EFI_FORM_BROWSER2_PROTOCOL.SendForm ().\r
563\r
564**/\r
565EFI_STATUS\r
566CallFrontPage (\r
567 VOID\r
568 )\r
569{\r
570 EFI_STATUS Status;\r
571 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
572\r
573 //\r
574 // Begin waiting for USER INPUT\r
575 //\r
576 REPORT_STATUS_CODE (\r
577 EFI_PROGRESS_CODE,\r
578 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)\r
579 );\r
580\r
581 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
582 Status = gFormBrowser2->SendForm (\r
583 gFormBrowser2,\r
584 &gFrontPagePrivate.HiiHandle,\r
585 1,\r
586 &mFrontPageGuid,\r
587 0,\r
588 NULL,\r
589 &ActionRequest\r
590 );\r
591 //\r
592 // Check whether user change any option setting which needs a reset to be effective\r
593 //\r
594 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
595 EnableResetRequired ();\r
596 }\r
597\r
598 return Status;\r
599}\r
600\r
3194d76f
DB
601/**\r
602 Remove the installed packages from the HiiDatabase.\r
603\r
604**/\r
143f0b1d
ED
605VOID\r
606FreeFrontPage(\r
607 VOID\r
608 )\r
609{\r
610 EFI_STATUS Status;\r
611 Status = gBS->UninstallMultipleProtocolInterfaces (\r
612 gFrontPagePrivate.DriverHandle,\r
613 &gEfiDevicePathProtocolGuid,\r
614 &mFrontPageHiiVendorDevicePath,\r
615 &gEfiHiiConfigAccessProtocolGuid,\r
616 &gFrontPagePrivate.ConfigAccess,\r
617 NULL\r
618 );\r
619 ASSERT_EFI_ERROR (Status);\r
620\r
621 //\r
622 // Publish our HII data\r
623 //\r
624 HiiRemovePackages (gFrontPagePrivate.HiiHandle);\r
625 if (gFrontPagePrivate.LanguageToken != NULL) {\r
626 FreePool (gFrontPagePrivate.LanguageToken);\r
627 gFrontPagePrivate.LanguageToken = NULL;\r
628 }\r
629}\r
630\r
631/**\r
632 Convert Processor Frequency Data to a string.\r
633\r
634 @param ProcessorFrequency The frequency data to process\r
635 @param Base10Exponent The exponent based on 10\r
636 @param String The string that is created\r
637\r
638**/\r
639VOID\r
640ConvertProcessorToString (\r
641 IN UINT16 ProcessorFrequency,\r
642 IN UINT16 Base10Exponent,\r
643 OUT CHAR16 **String\r
644 )\r
645{\r
646 CHAR16 *StringBuffer;\r
647 UINTN Index;\r
d91cb870 648 UINTN DestMax;\r
143f0b1d
ED
649 UINT32 FreqMhz;\r
650\r
651 if (Base10Exponent >= 6) {\r
652 FreqMhz = ProcessorFrequency;\r
653 for (Index = 0; Index < (UINTN) (Base10Exponent - 6); Index++) {\r
654 FreqMhz *= 10;\r
655 }\r
656 } else {\r
657 FreqMhz = 0;\r
658 }\r
d91cb870 659 DestMax = 0x20 / sizeof (CHAR16);\r
143f0b1d
ED
660 StringBuffer = AllocateZeroPool (0x20);\r
661 ASSERT (StringBuffer != NULL);\r
662 Index = UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, FreqMhz / 1000, 3);\r
d91cb870 663 StrCatS (StringBuffer, DestMax, L".");\r
143f0b1d 664 UnicodeValueToString (StringBuffer + Index + 1, PREFIX_ZERO, (FreqMhz % 1000) / 10, 2);\r
d91cb870 665 StrCatS (StringBuffer, DestMax, L" GHz");\r
143f0b1d
ED
666 *String = (CHAR16 *) StringBuffer;\r
667 return ;\r
668}\r
669\r
670\r
671/**\r
672 Convert Memory Size to a string.\r
673\r
674 @param MemorySize The size of the memory to process\r
675 @param String The string that is created\r
676\r
677**/\r
678VOID\r
679ConvertMemorySizeToString (\r
680 IN UINT32 MemorySize,\r
681 OUT CHAR16 **String\r
682 )\r
683{\r
684 CHAR16 *StringBuffer;\r
685\r
686 StringBuffer = AllocateZeroPool (0x24);\r
687 ASSERT (StringBuffer != NULL);\r
688 UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, MemorySize, 10);\r
d91cb870 689 StrCatS (StringBuffer, 0x24 / sizeof (CHAR16), L" MB RAM");\r
143f0b1d
ED
690\r
691 *String = (CHAR16 *) StringBuffer;\r
692\r
693 return ;\r
694}\r
695\r
696/**\r
697\r
698 Acquire the string associated with the Index from smbios structure and return it.\r
699 The caller is responsible for free the string buffer.\r
700\r
701 @param OptionalStrStart The start position to search the string\r
702 @param Index The index of the string to extract\r
703 @param String The string that is extracted\r
704\r
705 @retval EFI_SUCCESS The function returns EFI_SUCCESS always.\r
706\r
707**/\r
708EFI_STATUS\r
709GetOptionalStringByIndex (\r
710 IN CHAR8 *OptionalStrStart,\r
711 IN UINT8 Index,\r
712 OUT CHAR16 **String\r
713 )\r
714{\r
715 UINTN StrSize;\r
716\r
717 if (Index == 0) {\r
718 *String = AllocateZeroPool (sizeof (CHAR16));\r
719 return EFI_SUCCESS;\r
720 }\r
721\r
722 StrSize = 0;\r
723 do {\r
724 Index--;\r
725 OptionalStrStart += StrSize;\r
726 StrSize = AsciiStrSize (OptionalStrStart);\r
727 } while (OptionalStrStart[StrSize] != 0 && Index != 0);\r
728\r
729 if ((Index != 0) || (StrSize == 1)) {\r
730 //\r
731 // Meet the end of strings set but Index is non-zero, or\r
732 // Find an empty string\r
733 //\r
734 *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));\r
735 } else {\r
736 *String = AllocatePool (StrSize * sizeof (CHAR16));\r
737 AsciiStrToUnicodeStr (OptionalStrStart, *String);\r
738 }\r
739\r
740 return EFI_SUCCESS;\r
741}\r
742\r
743\r
744/**\r
745 Update the banner information for the Front Page based on Smbios information.\r
746**/\r
747VOID\r
748UpdateFrontPageStrings (\r
749 VOID\r
750 )\r
751{\r
752 UINT8 StrIndex;\r
753 CHAR16 *NewString;\r
754 CHAR16 *FirmwareVersionString;\r
755 BOOLEAN Find[5];\r
756 EFI_STATUS Status;\r
757 EFI_STRING_ID TokenToUpdate;\r
758 EFI_SMBIOS_HANDLE SmbiosHandle;\r
759 EFI_SMBIOS_PROTOCOL *Smbios;\r
760 SMBIOS_TABLE_TYPE0 *Type0Record;\r
761 SMBIOS_TABLE_TYPE1 *Type1Record;\r
762 SMBIOS_TABLE_TYPE4 *Type4Record;\r
763 SMBIOS_TABLE_TYPE19 *Type19Record;\r
764 EFI_SMBIOS_TABLE_HEADER *Record;\r
765\r
766 ZeroMem (Find, sizeof (Find));\r
767\r
768 //\r
769 // Update Front Page strings\r
770 //\r
771 Status = gBS->LocateProtocol (\r
772 &gEfiSmbiosProtocolGuid,\r
773 NULL,\r
774 (VOID **) &Smbios\r
775 );\r
776 if (EFI_ERROR (Status)) {\r
777 return ;\r
778 }\r
779\r
780 SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
781 do {\r
782 Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);\r
783 if (EFI_ERROR(Status)) {\r
784 break;\r
785 }\r
786\r
787 if (Record->Type == EFI_SMBIOS_TYPE_BIOS_INFORMATION) {\r
788 Type0Record = (SMBIOS_TABLE_TYPE0 *) Record;\r
789 StrIndex = Type0Record->BiosVersion;\r
790 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString);\r
791 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION);\r
792 FirmwareVersionString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);\r
793 if (*FirmwareVersionString != 0x0000 ) {\r
794 FreePool (NewString);\r
795 NewString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);\r
796 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
797 } else {\r
798 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
799 FreePool (NewString);\r
800 }\r
801 Find[0] = TRUE;\r
802 } \r
803\r
804 if (Record->Type == EFI_SMBIOS_TYPE_SYSTEM_INFORMATION) {\r
805 Type1Record = (SMBIOS_TABLE_TYPE1 *) Record;\r
806 StrIndex = Type1Record->ProductName;\r
807 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &NewString);\r
808 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL);\r
809 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
810 FreePool (NewString);\r
811 Find[1] = TRUE;\r
812 }\r
813\r
814 if ((Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) && !Find[2]) {\r
815 Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;\r
816 //\r
817 // The information in the record should be only valid when the CPU Socket is populated. \r
818 //\r
819 if ((Type4Record->Status & SMBIOS_TYPE4_CPU_SOCKET_POPULATED) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED) {\r
820 StrIndex = Type4Record->ProcessorVersion;\r
821 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString);\r
822 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL);\r
823 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
824 FreePool (NewString);\r
825 Find[2] = TRUE;\r
826 }\r
827 } \r
828\r
829 if ((Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) && !Find[3]) {\r
830 Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;\r
831 //\r
832 // The information in the record should be only valid when the CPU Socket is populated. \r
833 //\r
834 if ((Type4Record->Status & SMBIOS_TYPE4_CPU_SOCKET_POPULATED) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED) {\r
835 ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString);\r
836 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED);\r
837 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
838 FreePool (NewString);\r
839 Find[3] = TRUE;\r
840 }\r
841 } \r
842\r
843 if ( Record->Type == EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS ) {\r
844 Type19Record = (SMBIOS_TABLE_TYPE19 *) Record;\r
845 ConvertMemorySizeToString (\r
846 (UINT32)(RShiftU64((Type19Record->EndingAddress - Type19Record->StartingAddress + 1), 10)),\r
847 &NewString\r
848 );\r
849 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE);\r
850 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
851 FreePool (NewString);\r
852 Find[4] = TRUE; \r
853 }\r
854 } while ( !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4]));\r
855 return ;\r
856}\r
857\r
858/**\r
859 This function will change video resolution and text mode\r
860 according to defined setup mode or defined boot mode \r
861\r
862 @param IsSetupMode Indicate mode is changed to setup mode or boot mode. \r
863\r
864 @retval EFI_SUCCESS Mode is changed successfully.\r
865 @retval Others Mode failed to be changed.\r
866\r
867**/\r
868EFI_STATUS\r
869EFIAPI\r
870BdsSetConsoleMode (\r
871 BOOLEAN IsSetupMode\r
872 )\r
873{\r
874 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
875 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;\r
876 UINTN SizeOfInfo;\r
877 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
878 UINT32 MaxGopMode;\r
879 UINT32 MaxTextMode;\r
880 UINT32 ModeNumber;\r
881 UINT32 NewHorizontalResolution;\r
882 UINT32 NewVerticalResolution;\r
883 UINT32 NewColumns;\r
884 UINT32 NewRows;\r
885 UINTN HandleCount;\r
886 EFI_HANDLE *HandleBuffer;\r
887 EFI_STATUS Status;\r
888 UINTN Index;\r
889 UINTN CurrentColumn;\r
890 UINTN CurrentRow; \r
891\r
892 MaxGopMode = 0;\r
893 MaxTextMode = 0;\r
894\r
895 //\r
896 // Get current video resolution and text mode \r
897 //\r
898 Status = gBS->HandleProtocol (\r
899 gST->ConsoleOutHandle,\r
900 &gEfiGraphicsOutputProtocolGuid,\r
901 (VOID**)&GraphicsOutput\r
902 );\r
903 if (EFI_ERROR (Status)) {\r
904 GraphicsOutput = NULL;\r
905 }\r
906\r
907 Status = gBS->HandleProtocol (\r
908 gST->ConsoleOutHandle,\r
909 &gEfiSimpleTextOutProtocolGuid,\r
910 (VOID**)&SimpleTextOut\r
911 );\r
912 if (EFI_ERROR (Status)) {\r
913 SimpleTextOut = NULL;\r
914 } \r
915\r
916 if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {\r
917 return EFI_UNSUPPORTED;\r
918 }\r
919\r
920 if (IsSetupMode) {\r
921 //\r
922 // The requried resolution and text mode is setup mode.\r
923 //\r
924 NewHorizontalResolution = mSetupHorizontalResolution;\r
925 NewVerticalResolution = mSetupVerticalResolution;\r
926 NewColumns = mSetupTextModeColumn;\r
927 NewRows = mSetupTextModeRow;\r
928 } else {\r
929 //\r
930 // The required resolution and text mode is boot mode.\r
931 //\r
932 NewHorizontalResolution = mBootHorizontalResolution;\r
933 NewVerticalResolution = mBootVerticalResolution;\r
934 NewColumns = mBootTextModeColumn;\r
935 NewRows = mBootTextModeRow; \r
936 }\r
937 \r
938 if (GraphicsOutput != NULL) {\r
939 MaxGopMode = GraphicsOutput->Mode->MaxMode;\r
940 } \r
941\r
942 if (SimpleTextOut != NULL) {\r
943 MaxTextMode = SimpleTextOut->Mode->MaxMode;\r
944 }\r
945\r
946 //\r
947 // 1. If current video resolution is same with required video resolution,\r
948 // video resolution need not be changed.\r
949 // 1.1. If current text mode is same with required text mode, text mode need not be changed.\r
950 // 1.2. If current text mode is different from required text mode, text mode need be changed.\r
951 // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.\r
952 //\r
953 for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {\r
954 Status = GraphicsOutput->QueryMode (\r
955 GraphicsOutput,\r
956 ModeNumber,\r
957 &SizeOfInfo,\r
958 &Info\r
959 );\r
960 if (!EFI_ERROR (Status)) {\r
961 if ((Info->HorizontalResolution == NewHorizontalResolution) &&\r
962 (Info->VerticalResolution == NewVerticalResolution)) {\r
963 if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) &&\r
964 (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) {\r
965 //\r
966 // Current resolution is same with required resolution, check if text mode need be set\r
967 //\r
968 Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);\r
969 ASSERT_EFI_ERROR (Status);\r
970 if (CurrentColumn == NewColumns && CurrentRow == NewRows) {\r
971 //\r
972 // If current text mode is same with required text mode. Do nothing\r
973 //\r
974 FreePool (Info);\r
975 return EFI_SUCCESS;\r
976 } else {\r
977 //\r
978 // If current text mode is different from requried text mode. Set new video mode\r
979 //\r
980 for (Index = 0; Index < MaxTextMode; Index++) {\r
981 Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);\r
982 if (!EFI_ERROR(Status)) {\r
983 if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {\r
984 //\r
985 // Required text mode is supported, set it.\r
986 //\r
987 Status = SimpleTextOut->SetMode (SimpleTextOut, Index);\r
988 ASSERT_EFI_ERROR (Status);\r
989 //\r
990 // Update text mode PCD.\r
991 //\r
992 PcdSet32 (PcdConOutColumn, mSetupTextModeColumn);\r
993 PcdSet32 (PcdConOutRow, mSetupTextModeRow);\r
994 FreePool (Info);\r
995 return EFI_SUCCESS;\r
996 }\r
997 }\r
998 }\r
999 if (Index == MaxTextMode) {\r
1000 //\r
1001 // If requried text mode is not supported, return error.\r
1002 //\r
1003 FreePool (Info);\r
1004 return EFI_UNSUPPORTED;\r
1005 }\r
1006 }\r
1007 } else {\r
1008 //\r
1009 // If current video resolution is not same with the new one, set new video resolution.\r
1010 // In this case, the driver which produces simple text out need be restarted.\r
1011 //\r
1012 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);\r
1013 if (!EFI_ERROR (Status)) {\r
1014 FreePool (Info);\r
1015 break;\r
1016 }\r
1017 }\r
1018 }\r
1019 FreePool (Info);\r
1020 }\r
1021 }\r
1022\r
1023 if (ModeNumber == MaxGopMode) {\r
1024 //\r
1025 // If the resolution is not supported, return error.\r
1026 //\r
1027 return EFI_UNSUPPORTED;\r
1028 }\r
1029\r
1030 //\r
1031 // Set PCD to Inform GraphicsConsole to change video resolution.\r
1032 // Set PCD to Inform Consplitter to change text mode.\r
1033 //\r
1034 PcdSet32 (PcdVideoHorizontalResolution, NewHorizontalResolution);\r
1035 PcdSet32 (PcdVideoVerticalResolution, NewVerticalResolution);\r
1036 PcdSet32 (PcdConOutColumn, NewColumns);\r
1037 PcdSet32 (PcdConOutRow, NewRows);\r
1038 \r
1039 \r
1040 //\r
1041 // Video mode is changed, so restart graphics console driver and higher level driver.\r
1042 // Reconnect graphics console driver and higher level driver.\r
1043 // Locate all the handles with GOP protocol and reconnect it.\r
1044 //\r
1045 Status = gBS->LocateHandleBuffer (\r
1046 ByProtocol,\r
1047 &gEfiSimpleTextOutProtocolGuid,\r
1048 NULL,\r
1049 &HandleCount,\r
1050 &HandleBuffer\r
1051 );\r
1052 if (!EFI_ERROR (Status)) {\r
1053 for (Index = 0; Index < HandleCount; Index++) {\r
1054 gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);\r
1055 }\r
1056 for (Index = 0; Index < HandleCount; Index++) {\r
1057 gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);\r
1058 }\r
1059 if (HandleBuffer != NULL) {\r
1060 FreePool (HandleBuffer);\r
1061 }\r
1062 }\r
1063\r
1064 return EFI_SUCCESS;\r
1065}\r
1066\r
1067/**\r
1068 The user Entry Point for Application. The user code starts with this function\r
1069 as the real entry point for the image goes into a library that calls this \r
1070 function.\r
1071\r
1072 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
1073 @param[in] SystemTable A pointer to the EFI System Table.\r
1074 \r
1075 @retval EFI_SUCCESS The entry point is executed successfully.\r
1076 @retval other Some error occurs when executing this entry point.\r
1077\r
1078**/\r
1079EFI_STATUS\r
1080EFIAPI\r
1081InitializeUserInterface (\r
1082 IN EFI_HANDLE ImageHandle,\r
1083 IN EFI_SYSTEM_TABLE *SystemTable\r
1084 )\r
1085{\r
1086 EFI_HII_HANDLE HiiHandle;\r
1087 EFI_STATUS Status;\r
1088 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
1089 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;\r
1090 UINTN BootTextColumn;\r
1091 UINTN BootTextRow;\r
1092\r
1093 if (!mModeInitialized) {\r
1094 //\r
1095 // After the console is ready, get current video resolution \r
1096 // and text mode before launching setup at first time.\r
1097 //\r
1098 Status = gBS->HandleProtocol (\r
1099 gST->ConsoleOutHandle,\r
1100 &gEfiGraphicsOutputProtocolGuid,\r
1101 (VOID**)&GraphicsOutput\r
1102 );\r
1103 if (EFI_ERROR (Status)) {\r
1104 GraphicsOutput = NULL;\r
1105 }\r
1106 \r
1107 Status = gBS->HandleProtocol (\r
1108 gST->ConsoleOutHandle,\r
1109 &gEfiSimpleTextOutProtocolGuid,\r
1110 (VOID**)&SimpleTextOut\r
1111 );\r
1112 if (EFI_ERROR (Status)) {\r
1113 SimpleTextOut = NULL;\r
1114 } \r
1115\r
1116 if (GraphicsOutput != NULL) {\r
1117 //\r
1118 // Get current video resolution and text mode.\r
1119 //\r
1120 mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
1121 mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
1122 }\r
1123\r
1124 if (SimpleTextOut != NULL) {\r
1125 Status = SimpleTextOut->QueryMode (\r
1126 SimpleTextOut,\r
1127 SimpleTextOut->Mode->Mode,\r
1128 &BootTextColumn,\r
1129 &BootTextRow\r
1130 );\r
1131 mBootTextModeColumn = (UINT32)BootTextColumn;\r
1132 mBootTextModeRow = (UINT32)BootTextRow;\r
1133 }\r
1134\r
1135 //\r
1136 // Get user defined text mode for setup.\r
1137 // \r
1138 mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);\r
1139 mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution); \r
1140 mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);\r
1141 mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);\r
1142\r
1143 mModeInitialized = TRUE;\r
1144 }\r
1145\r
1146 gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);\r
1147 gST->ConOut->ClearScreen (gST->ConOut);\r
1148 \r
1149 //\r
1150 // Install customized fonts needed by Front Page\r
1151 //\r
1152 \r
1153 HiiHandle = ExportFonts ();\r
1154 ASSERT (HiiHandle != NULL);\r
1155\r
1156 InitializeStringSupport ();\r
1157\r
1158 BdsSetConsoleMode (TRUE);\r
1159 UiEntry (FALSE);\r
1160 BdsSetConsoleMode (FALSE);\r
1161\r
1162 UninitializeStringSupport ();\r
1163 HiiRemovePackages (HiiHandle);\r
1164\r
1165 return EFI_SUCCESS;\r
1166}\r
1167\r
1168/**\r
1169 This function is the main entry of the UI entry.\r
1170 The function will present the main menu of the system UI.\r
1171\r
1172 @param ConnectAllHappened Caller passes the value to UI to avoid unnecessary connect-all.\r
1173\r
1174**/\r
1175VOID\r
1176EFIAPI\r
1177UiEntry (\r
1178 IN BOOLEAN ConnectAllHappened\r
1179 )\r
1180{\r
1181 EFI_STATUS Status;\r
1182 EFI_BOOT_LOGO_PROTOCOL *BootLogo;\r
1183\r
1184 //\r
1185 // Indicate if the connect all has been performed before.\r
1186 //\r
1187 if (ConnectAllHappened) {\r
1188 gConnectAllHappened = TRUE;\r
1189 }\r
1190\r
1191 //\r
1192 // The boot option enumeration time is acceptable in Ui driver\r
1193 //\r
1194 EfiBootManagerRefreshAllBootOption ();\r
1195\r
1196 //\r
1197 // Boot Logo is corrupted, report it using Boot Logo protocol.\r
1198 //\r
1199 Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);\r
1200 if (!EFI_ERROR (Status) && (BootLogo != NULL)) {\r
1201 BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);\r
1202 }\r
1203\r
1204 InitializeFrontPage ();\r
1205 InitializeDeviceManager ();\r
1206 InitializeBootManager ();\r
1207 InitBootMaintenance();\r
1208\r
1209 CallFrontPage ();\r
1210\r
1211 FreeBMPackage ();\r
1212 FreeBootManager ();\r
1213 FreeDeviceManager ();\r
1214 FreeFrontPage ();\r
1215\r
1216 if (mLanguageString != NULL) {\r
1217 FreePool (mLanguageString);\r
1218 mLanguageString = NULL;\r
1219 }\r
1220\r
1221 //\r
1222 //Will leave browser, check any reset required change is applied? if yes, reset system\r
1223 //\r
1224 SetupResetReminder ();\r
1225}\r
1226\r
1227/**\r
1228 Extract device path for given HII handle and class guid.\r
1229\r
1230 @param Handle The HII handle.\r
1231\r
1232 @retval NULL Fail to get the device path string.\r
1233 @return PathString Get the device path string.\r
1234\r
1235**/\r
1236CHAR16 *\r
1237ExtractDevicePathFromHiiHandle (\r
1238 IN EFI_HII_HANDLE Handle\r
1239 )\r
1240{\r
1241 EFI_STATUS Status;\r
1242 EFI_HANDLE DriverHandle;\r
1243 EFI_DEVICE_PATH_PROTOCOL *DevicePath; \r
1244 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *PathToText;\r
1245 CHAR16 *NewString;\r
1246\r
1247 ASSERT (Handle != NULL);\r
1248\r
1249 if (Handle == NULL) {\r
1250 return NULL;\r
1251 }\r
1252\r
1253 Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);\r
1254 if (EFI_ERROR (Status)) {\r
1255 return NULL;\r
1256 }\r
1257\r
1258 //\r
1259 // Get the device path by the got Driver handle .\r
1260 //\r
1261 Status = gBS->HandleProtocol (DriverHandle, &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath);\r
1262 if (EFI_ERROR (Status)) {\r
1263 return NULL;\r
1264 }\r
1265\r
1266 Status = gBS->LocateProtocol (\r
1267 &gEfiDevicePathToTextProtocolGuid,\r
1268 NULL,\r
1269 (VOID **) &PathToText\r
1270 );\r
1271 if (EFI_ERROR (Status)) {\r
1272 return NULL;\r
1273 }\r
1274\r
1275 //\r
1276 // Get device path string.\r
1277 //\r
1278 NewString = PathToText->ConvertDevicePathToText(DevicePath, FALSE, FALSE);\r
1279\r
1280 return NewString;\r
1281}\r
1282\r
1283/**\r
1284 Extract the displayed formset for given HII handle and class guid.\r
1285\r
1286 @param Handle The HII handle.\r
1287 @param SetupClassGuid The class guid specifies which form set will be displayed.\r
1288 @param SkipCount Skip some formsets which has processed before.\r
1289 @param FormSetTitle Formset title string.\r
1290 @param FormSetHelp Formset help string.\r
1291 @param FormSetGuid Formset Guid.\r
1292\r
1293 @retval TRUE The formset for given HII handle will be displayed.\r
1294 @return FALSE The formset for given HII handle will not be displayed.\r
1295\r
1296**/\r
1297BOOLEAN\r
1298ExtractDisplayedHiiFormFromHiiHandle (\r
1299 IN EFI_HII_HANDLE Handle,\r
1300 IN EFI_GUID *SetupClassGuid,\r
1301 IN UINTN SkipCount,\r
1302 OUT EFI_STRING_ID *FormSetTitle,\r
1303 OUT EFI_STRING_ID *FormSetHelp,\r
1304 OUT EFI_GUID *FormSetGuid\r
1305 )\r
1306{\r
1307 EFI_STATUS Status;\r
1308 UINTN BufferSize;\r
1309 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
1310 UINT8 *Package;\r
1311 UINT8 *OpCodeData;\r
1312 UINT32 Offset;\r
1313 UINT32 Offset2;\r
1314 UINT32 PackageListLength;\r
1315 EFI_HII_PACKAGE_HEADER PackageHeader;\r
1316 EFI_GUID *ClassGuid;\r
1317 UINT8 ClassGuidNum;\r
1318 BOOLEAN FoundAndSkip;\r
1319\r
1320 ASSERT (Handle != NULL);\r
1321 ASSERT (SetupClassGuid != NULL && FormSetTitle != NULL && FormSetHelp != NULL && FormSetGuid != NULL);\r
1322\r
1323 *FormSetTitle = 0;\r
1324 *FormSetHelp = 0;\r
1325 ClassGuidNum = 0;\r
1326 ClassGuid = NULL;\r
1327 FoundAndSkip = FALSE;\r
1328\r
1329 //\r
1330 // Get HII PackageList\r
1331 //\r
1332 BufferSize = 0;\r
1333 HiiPackageList = NULL;\r
1334 Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
1335 //\r
1336 // Handle is a invalid handle. Check if Handle is corrupted.\r
1337 //\r
1338 ASSERT (Status != EFI_NOT_FOUND);\r
1339 //\r
1340 // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.\r
1341 //\r
1342 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
1343 \r
1344 HiiPackageList = AllocatePool (BufferSize);\r
1345 ASSERT (HiiPackageList != NULL);\r
1346\r
1347 Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
1348 if (EFI_ERROR (Status)) {\r
1349 return FALSE;\r
1350 }\r
1351\r
1352 //\r
1353 // Get Form package from this HII package List\r
1354 //\r
1355 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
1356 PackageListLength = ReadUnaligned32 (&HiiPackageList->PackageLength);\r
1357\r
1358 while (Offset < PackageListLength) {\r
1359 Package = ((UINT8 *) HiiPackageList) + Offset;\r
1360 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
1361 Offset += PackageHeader.Length;\r
1362\r
1363 if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
1364 //\r
1365 // Search FormSet Opcode in this Form Package\r
1366 //\r
1367 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
1368 while (Offset2 < PackageHeader.Length) {\r
1369 OpCodeData = Package + Offset2;\r
1370 Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
1371\r
1372 if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
1373 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {\r
1374 //\r
1375 // Find FormSet OpCode\r
1376 //\r
1377 ClassGuidNum = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
1378 ClassGuid = (EFI_GUID *) (VOID *)(OpCodeData + sizeof (EFI_IFR_FORM_SET));\r
1379 while (ClassGuidNum-- > 0) {\r
1380 if (CompareGuid (SetupClassGuid, ClassGuid)) {\r
1381 //\r
1382 // Check whether need to skip the formset.\r
1383 //\r
1384 if (SkipCount != 0) {\r
1385 SkipCount--;\r
1386 FoundAndSkip = TRUE;\r
1387 break;\r
1388 }\r
1389 CopyMem (FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
1390 CopyMem (FormSetHelp, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
1391 CopyGuid (FormSetGuid, (CONST EFI_GUID *)(&((EFI_IFR_FORM_SET *) OpCodeData)->Guid));\r
1392 FreePool (HiiPackageList);\r
1393 return TRUE;\r
1394 }\r
1395 ClassGuid ++;\r
1396 }\r
1397 if (FoundAndSkip) {\r
1398 break;\r
1399 }\r
1400 } else if (CompareGuid (SetupClassGuid, &gEfiHiiPlatformSetupFormsetGuid)) {\r
1401 //\r
1402 // Check whether need to skip the formset.\r
1403 //\r
1404 if (SkipCount != 0) {\r
1405 SkipCount--;\r
1406 break;\r
1407 }\r
1408 CopyMem (FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
1409 CopyMem (FormSetHelp, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
1410 CopyGuid (FormSetGuid, (CONST EFI_GUID *)(&((EFI_IFR_FORM_SET *) OpCodeData)->Guid));\r
1411 FreePool (HiiPackageList);\r
1412 return TRUE;\r
1413 }\r
1414 }\r
1415 }\r
1416 }\r
1417 }\r
1418\r
1419 FreePool (HiiPackageList);\r
1420\r
1421 return FALSE;\r
1422}\r
1423\r
1424//\r
1425// Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.\r
1426// Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if\r
1427// user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection.\r
1428//\r
1429\r
1430\r
1431/**\r
1432 Enable the setup browser reset reminder feature.\r
1433 This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it.\r
1434\r
1435**/\r
1436VOID\r
1437EFIAPI\r
1438EnableResetReminderFeature (\r
1439 VOID\r
1440 )\r
1441{\r
1442 mFeaturerSwitch = TRUE;\r
1443}\r
1444\r
1445\r
1446/**\r
1447 Disable the setup browser reset reminder feature.\r
1448 This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it.\r
1449\r
1450**/\r
1451VOID\r
1452EFIAPI\r
1453DisableResetReminderFeature (\r
1454 VOID\r
1455 )\r
1456{\r
1457 mFeaturerSwitch = FALSE;\r
1458}\r
1459\r
1460\r
1461/**\r
1462 Record the info that a reset is required.\r
1463 A module boolean variable is used to record whether a reset is required.\r
1464\r
1465**/\r
1466VOID\r
1467EFIAPI\r
1468EnableResetRequired (\r
1469 VOID\r
1470 )\r
1471{\r
1472 mResetRequired = TRUE;\r
1473}\r
1474\r
1475\r
1476/**\r
1477 Record the info that no reset is required.\r
1478 A module boolean variable is used to record whether a reset is required.\r
1479\r
1480**/\r
1481VOID\r
1482EFIAPI\r
1483DisableResetRequired (\r
1484 VOID\r
1485 )\r
1486{\r
1487 mResetRequired = FALSE;\r
1488}\r
1489\r
1490\r
1491/**\r
1492 Check whether platform policy enable the reset reminder feature. The default is enabled.\r
1493\r
1494**/\r
1495BOOLEAN\r
1496EFIAPI\r
1497IsResetReminderFeatureEnable (\r
1498 VOID\r
1499 )\r
1500{\r
1501 return mFeaturerSwitch;\r
1502}\r
1503\r
1504\r
1505/**\r
1506 Check if user changed any option setting which needs a system reset to be effective.\r
1507\r
1508**/\r
1509BOOLEAN\r
1510EFIAPI\r
1511IsResetRequired (\r
1512 VOID\r
1513 )\r
1514{\r
1515 return mResetRequired;\r
1516}\r
1517\r
1518\r
1519/**\r
1520 Check whether a reset is needed, and finish the reset reminder feature.\r
1521 If a reset is needed, Popup a menu to notice user, and finish the feature\r
1522 according to the user selection.\r
1523\r
1524**/\r
1525VOID\r
1526EFIAPI\r
1527SetupResetReminder (\r
1528 VOID\r
1529 )\r
1530{\r
1531 EFI_INPUT_KEY Key;\r
1532 CHAR16 *StringBuffer1;\r
1533 CHAR16 *StringBuffer2;\r
1534\r
1535\r
1536 //\r
1537 //check any reset required change is applied? if yes, reset system\r
1538 //\r
1539 if (IsResetReminderFeatureEnable ()) {\r
1540 if (IsResetRequired ()) {\r
1541\r
1542 StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));\r
1543 ASSERT (StringBuffer1 != NULL);\r
1544 StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));\r
1545 ASSERT (StringBuffer2 != NULL);\r
d91cb870
DB
1546 StrCpyS (StringBuffer1, MAX_STRING_LEN, L"Configuration changed. Reset to apply it Now.");\r
1547 StrCpyS (StringBuffer2, MAX_STRING_LEN, L"Press ENTER to reset");\r
143f0b1d
ED
1548 //\r
1549 // Popup a menu to notice user\r
1550 //\r
1551 do {\r
1552 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);\r
1553 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1554\r
1555 FreePool (StringBuffer1);\r
1556 FreePool (StringBuffer2);\r
1557\r
1558 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
1559 }\r
1560 }\r
1561}\r
1562\r
1563\r
1564/**\r
1565 This function converts an input device structure to a Unicode string.\r
1566\r
1567 @param DevPath A pointer to the device path structure.\r
1568\r
1569 @return A new allocated Unicode string that represents the device path.\r
1570\r
1571**/\r
1572CHAR16 *\r
1573UiDevicePathToStr (\r
1574 IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
1575 )\r
1576{\r
1577 EFI_STATUS Status;\r
1578 CHAR16 *ToText;\r
1579 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;\r
1580\r
1581 if (DevPath == NULL) {\r
1582 return NULL;\r
1583 }\r
1584\r
1585 Status = gBS->LocateProtocol (\r
1586 &gEfiDevicePathToTextProtocolGuid,\r
1587 NULL,\r
1588 (VOID **) &DevPathToText\r
1589 );\r
1590 ASSERT_EFI_ERROR (Status);\r
1591 ToText = DevPathToText->ConvertDevicePathToText (\r
1592 DevPath,\r
1593 FALSE,\r
1594 TRUE\r
1595 );\r
1596 ASSERT (ToText != NULL);\r
1597 return ToText;\r
1598}\r