2 FrontPage routines to handle the callbacks and browser calls
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "FrontPage.h"
17 #define MAX_STRING_LEN 200
19 EFI_GUID mFrontPageGuid
= FRONT_PAGE_FORMSET_GUID
;
21 BOOLEAN gConnectAllHappened
= FALSE
;
22 BOOLEAN mFeaturerSwitch
= TRUE
;
23 BOOLEAN mResetRequired
= FALSE
;
24 BOOLEAN mEnterBmm
= FALSE
;
26 EFI_FORM_BROWSER2_PROTOCOL
*gFormBrowser2
;
27 CHAR8
*mLanguageString
;
28 BOOLEAN mModeInitialized
= FALSE
;
30 // Boot video resolution and text mode.
32 UINT32 mBootHorizontalResolution
= 0;
33 UINT32 mBootVerticalResolution
= 0;
34 UINT32 mBootTextModeColumn
= 0;
35 UINT32 mBootTextModeRow
= 0;
37 // BIOS setup video resolution and text mode.
39 UINT32 mSetupTextModeColumn
= 0;
40 UINT32 mSetupTextModeRow
= 0;
41 UINT32 mSetupHorizontalResolution
= 0;
42 UINT32 mSetupVerticalResolution
= 0;
44 FRONT_PAGE_CALLBACK_DATA gFrontPagePrivate
= {
45 FRONT_PAGE_CALLBACK_DATA_SIGNATURE
,
56 HII_VENDOR_DEVICE_PATH mFrontPageHiiVendorDevicePath
= {
62 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
63 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
67 // {8E6D99EE-7531-48f8-8745-7F6144468FF2}
69 { 0x8e6d99ee, 0x7531, 0x48f8, { 0x87, 0x45, 0x7f, 0x61, 0x44, 0x46, 0x8f, 0xf2 } }
73 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
75 (UINT8
) (END_DEVICE_PATH_LENGTH
),
76 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
82 Update the banner information for the Front Page based on Smbios information.
86 UpdateFrontPageStrings (
91 This function allows a caller to extract the current configuration for one
92 or more named elements from the target driver.
95 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
96 @param Request A null-terminated Unicode string in <ConfigRequest> format.
97 @param Progress On return, points to a character in the Request string.
98 Points to the string's null terminator if request was successful.
99 Points to the most recent '&' before the first failing name/value
100 pair (or the beginning of the string if the failure is in the
101 first name/value pair) if the request was not successful.
102 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
103 has all values filled in for the names in the Request string.
104 String to be allocated by the called function.
106 @retval EFI_SUCCESS The Results is filled with the requested values.
107 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
108 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
109 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
115 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
116 IN CONST EFI_STRING Request
,
117 OUT EFI_STRING
*Progress
,
118 OUT EFI_STRING
*Results
121 if (Progress
== NULL
|| Results
== NULL
) {
122 return EFI_INVALID_PARAMETER
;
125 return EFI_NOT_FOUND
;
129 This function processes the results of changes in configuration.
132 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
133 @param Configuration A null-terminated Unicode string in <ConfigResp> format.
134 @param Progress A pointer to a string filled in with the offset of the most
135 recent '&' before the first failing name/value pair (or the
136 beginning of the string if the failure is in the first
137 name/value pair) or the terminating NULL if all was successful.
139 @retval EFI_SUCCESS The Results is processed successfully.
140 @retval EFI_INVALID_PARAMETER Configuration is NULL.
141 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
147 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
148 IN CONST EFI_STRING Configuration
,
149 OUT EFI_STRING
*Progress
152 if (Configuration
== NULL
|| Progress
== NULL
) {
153 return EFI_INVALID_PARAMETER
;
156 *Progress
= Configuration
;
157 if (!HiiIsConfigHdrMatch (Configuration
, &mBootMaintGuid
, mBootMaintStorageName
)
158 && !HiiIsConfigHdrMatch (Configuration
, &mFileExplorerGuid
, mFileExplorerStorageName
)) {
159 return EFI_NOT_FOUND
;
162 *Progress
= Configuration
+ StrLen (Configuration
);
167 Create oneof options for language.
180 CHAR16
*StringBuffer
;
181 EFI_HII_HANDLE HiiHandle
;
182 VOID
*OptionsOpCodeHandle
;
183 VOID
*StartOpCodeHandle
;
184 VOID
*EndOpCodeHandle
;
185 EFI_IFR_GUID_LABEL
*StartLabel
;
186 EFI_IFR_GUID_LABEL
*EndLabel
;
187 EFI_HII_STRING_PROTOCOL
*HiiString
;
194 // Init OpCode Handle and Allocate space for creation of UpdateData Buffer
196 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
197 ASSERT (StartOpCodeHandle
!= NULL
);
199 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
200 ASSERT (EndOpCodeHandle
!= NULL
);
202 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
203 ASSERT (OptionsOpCodeHandle
!= NULL
);
205 // Create Hii Extend Label OpCode as the start opcode
207 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
208 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
209 StartLabel
->Number
= LABEL_SELECT_LANGUAGE
;
212 // Create Hii Extend Label OpCode as the end opcode
214 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
215 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
216 EndLabel
->Number
= LABEL_END
;
218 // Collect the languages from what our current Language support is based on our VFR
220 HiiHandle
= gFrontPagePrivate
.HiiHandle
;
222 CurrentLang
= GetEfiGlobalVariable (L
"PlatformLang");
224 if (mLanguageString
== NULL
) {
226 // Get Support language list from variable.
228 mLanguageString
= GetEfiGlobalVariable (L
"PlatformLangCodes");
229 if (mLanguageString
== NULL
) {
230 mLanguageString
= AllocateCopyPool (
231 AsciiStrSize ((CHAR8
*) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes
)),
232 (CHAR8
*) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes
)
234 ASSERT (mLanguageString
!= NULL
);
238 if (gFrontPagePrivate
.LanguageToken
== NULL
) {
240 // Count the language list number.
242 LangCode
= mLanguageString
;
243 Lang
= AllocatePool (AsciiStrSize (mLanguageString
));
244 ASSERT (Lang
!= NULL
);
246 while (*LangCode
!= 0) {
247 GetNextLanguage (&LangCode
, Lang
);
252 // Allocate extra 1 as the end tag.
254 gFrontPagePrivate
.LanguageToken
= AllocateZeroPool ((OptionCount
+ 1) * sizeof (EFI_STRING_ID
));
255 ASSERT (gFrontPagePrivate
.LanguageToken
!= NULL
);
257 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &HiiString
);
258 ASSERT_EFI_ERROR (Status
);
260 LangCode
= mLanguageString
;
262 while (*LangCode
!= 0) {
263 GetNextLanguage (&LangCode
, Lang
);
266 Status
= HiiString
->GetString (HiiString
, Lang
, HiiHandle
, PRINTABLE_LANGUAGE_NAME_STRING_ID
, StringBuffer
, &StringSize
, NULL
);
267 if (Status
== EFI_BUFFER_TOO_SMALL
) {
268 StringBuffer
= AllocateZeroPool (StringSize
);
269 ASSERT (StringBuffer
!= NULL
);
270 Status
= HiiString
->GetString (HiiString
, Lang
, HiiHandle
, PRINTABLE_LANGUAGE_NAME_STRING_ID
, StringBuffer
, &StringSize
, NULL
);
271 ASSERT_EFI_ERROR (Status
);
274 if (EFI_ERROR (Status
)) {
275 StringBuffer
= AllocatePool (AsciiStrSize (Lang
) * sizeof (CHAR16
));
276 ASSERT (StringBuffer
!= NULL
);
277 AsciiStrToUnicodeStr (Lang
, StringBuffer
);
280 ASSERT (StringBuffer
!= NULL
);
281 gFrontPagePrivate
.LanguageToken
[OptionCount
] = HiiSetString (HiiHandle
, 0, StringBuffer
, NULL
);
282 FreePool (StringBuffer
);
288 ASSERT (gFrontPagePrivate
.LanguageToken
!= NULL
);
289 LangCode
= mLanguageString
;
292 Lang
= AllocatePool (AsciiStrSize (mLanguageString
));
293 ASSERT (Lang
!= NULL
);
295 while (*LangCode
!= 0) {
296 GetNextLanguage (&LangCode
, Lang
);
298 if (CurrentLang
!= NULL
&& AsciiStrCmp (Lang
, CurrentLang
) == 0) {
299 HiiCreateOneOfOptionOpCode (
301 gFrontPagePrivate
.LanguageToken
[OptionCount
],
302 EFI_IFR_OPTION_DEFAULT
,
303 EFI_IFR_NUMERIC_SIZE_1
,
307 HiiCreateOneOfOptionOpCode (
309 gFrontPagePrivate
.LanguageToken
[OptionCount
],
311 EFI_IFR_NUMERIC_SIZE_1
,
319 if (CurrentLang
!= NULL
) {
320 FreePool (CurrentLang
);
324 HiiCreateOneOfOpCode (
326 FRONT_PAGE_KEY_LANGUAGE
,
329 STRING_TOKEN (STR_LANGUAGE_SELECT
),
330 STRING_TOKEN (STR_LANGUAGE_SELECT_HELP
),
331 EFI_IFR_FLAG_CALLBACK
,
332 EFI_IFR_NUMERIC_SIZE_1
,
337 Status
= HiiUpdateForm (
341 StartOpCodeHandle
, // LABEL_SELECT_LANGUAGE
342 EndOpCodeHandle
// LABEL_END
345 HiiFreeOpCodeHandle (StartOpCodeHandle
);
346 HiiFreeOpCodeHandle (EndOpCodeHandle
);
347 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
351 This function processes the results of changes in configuration.
354 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
355 @param Action Specifies the type of action taken by the browser.
356 @param QuestionId A unique value which is sent to the original exporting driver
357 so that it can identify the type of data to expect.
358 @param Type The type of value for the question.
359 @param Value A pointer to the data being sent to the original exporting driver.
360 @param ActionRequest On return, points to the action requested by the callback function.
362 @retval EFI_SUCCESS The callback successfully handled the action.
363 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
364 @retval EFI_DEVICE_ERROR The variable could not be saved.
365 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
371 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
372 IN EFI_BROWSER_ACTION Action
,
373 IN EFI_QUESTION_ID QuestionId
,
375 IN EFI_IFR_TYPE_VALUE
*Value
,
376 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
385 //Chech whether exit from BMM and reenter frontpage,if yes,reclaim string depositories
387 if (Action
== EFI_BROWSER_ACTION_FORM_OPEN
){
389 ReclaimStringDepository();
394 if (Action
!= EFI_BROWSER_ACTION_CHANGING
&& Action
!= EFI_BROWSER_ACTION_CHANGED
) {
396 // Do nothing for other UEFI Action. Only do call back when data is changed.
398 return EFI_UNSUPPORTED
;
401 if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
402 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
403 return EFI_INVALID_PARAMETER
;
406 switch (QuestionId
) {
407 case FRONT_PAGE_KEY_CONTINUE
:
409 // This is the continue - clear the screen and return an error to get out of FrontPage loop
411 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
414 case FRONT_PAGE_KEY_LANGUAGE
:
416 // Allocate working buffer for RFC 4646 language in supported LanguageString.
418 Lang
= AllocatePool (AsciiStrSize (mLanguageString
));
419 ASSERT (Lang
!= NULL
);
422 LangCode
= mLanguageString
;
423 while (*LangCode
!= 0) {
424 GetNextLanguage (&LangCode
, Lang
);
426 if (Index
== Value
->u8
) {
433 if (Index
== Value
->u8
) {
434 Status
= gRT
->SetVariable (
436 &gEfiGlobalVariableGuid
,
437 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
441 ASSERT_EFI_ERROR(Status
);
447 //Current language of platform is changed,recreate oneof options for language.
449 InitializeLanguage();
453 case FRONT_PAGE_KEY_RESET
:
457 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
458 return EFI_UNSUPPORTED
;
463 } else if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
465 return EFI_INVALID_PARAMETER
;
469 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
470 // describe to their customers in documentation how to find their setup information (namely
471 // under the device manager and specific buckets)
473 switch (QuestionId
) {
474 case FRONT_PAGE_KEY_BOOT_MANAGER
:
478 EnumerateBootOptions ();
481 case FRONT_PAGE_KEY_DEVICE_MANAGER
:
485 CreateDeviceManagerForm(DEVICE_MANAGER_FORM_ID
);
488 case FRONT_PAGE_KEY_BOOT_MAINTAIN
:
490 // Boot Maintenance Manager
505 Initialize HII information for the FrontPage
508 @retval EFI_SUCCESS The operation is successful.
509 @retval EFI_DEVICE_ERROR If the dynamic opcode creation failed.
513 InitializeFrontPage (
520 // Locate Hii relative protocols
522 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &gFormBrowser2
);
523 if (EFI_ERROR (Status
)) {
528 // Install Device Path Protocol and Config Access protocol to driver handle
530 gFrontPagePrivate
.DriverHandle
= NULL
;
531 Status
= gBS
->InstallMultipleProtocolInterfaces (
532 &gFrontPagePrivate
.DriverHandle
,
533 &gEfiDevicePathProtocolGuid
,
534 &mFrontPageHiiVendorDevicePath
,
535 &gEfiHiiConfigAccessProtocolGuid
,
536 &gFrontPagePrivate
.ConfigAccess
,
539 ASSERT_EFI_ERROR (Status
);
542 // Publish our HII data
544 gFrontPagePrivate
.HiiHandle
= HiiAddPackages (
546 gFrontPagePrivate
.DriverHandle
,
551 ASSERT (gFrontPagePrivate
.HiiHandle
!= NULL
);
554 //Updata Front Page strings
556 UpdateFrontPageStrings ();
559 // Initialize laguage options
561 InitializeLanguage ();
567 Call the browser and display the front page
569 @return Status code that will be returned by
570 EFI_FORM_BROWSER2_PROTOCOL.SendForm ().
579 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
582 // Begin waiting for USER INPUT
586 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_INPUT_WAIT
)
589 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
590 Status
= gFormBrowser2
->SendForm (
592 &gFrontPagePrivate
.HiiHandle
,
600 // Check whether user change any option setting which needs a reset to be effective
602 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
603 EnableResetRequired ();
615 Status
= gBS
->UninstallMultipleProtocolInterfaces (
616 gFrontPagePrivate
.DriverHandle
,
617 &gEfiDevicePathProtocolGuid
,
618 &mFrontPageHiiVendorDevicePath
,
619 &gEfiHiiConfigAccessProtocolGuid
,
620 &gFrontPagePrivate
.ConfigAccess
,
623 ASSERT_EFI_ERROR (Status
);
626 // Publish our HII data
628 HiiRemovePackages (gFrontPagePrivate
.HiiHandle
);
629 if (gFrontPagePrivate
.LanguageToken
!= NULL
) {
630 FreePool (gFrontPagePrivate
.LanguageToken
);
631 gFrontPagePrivate
.LanguageToken
= NULL
;
636 Convert Processor Frequency Data to a string.
638 @param ProcessorFrequency The frequency data to process
639 @param Base10Exponent The exponent based on 10
640 @param String The string that is created
644 ConvertProcessorToString (
645 IN UINT16 ProcessorFrequency
,
646 IN UINT16 Base10Exponent
,
650 CHAR16
*StringBuffer
;
654 if (Base10Exponent
>= 6) {
655 FreqMhz
= ProcessorFrequency
;
656 for (Index
= 0; Index
< (UINTN
) (Base10Exponent
- 6); Index
++) {
663 StringBuffer
= AllocateZeroPool (0x20);
664 ASSERT (StringBuffer
!= NULL
);
665 Index
= UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, FreqMhz
/ 1000, 3);
666 StrCat (StringBuffer
, L
".");
667 UnicodeValueToString (StringBuffer
+ Index
+ 1, PREFIX_ZERO
, (FreqMhz
% 1000) / 10, 2);
668 StrCat (StringBuffer
, L
" GHz");
669 *String
= (CHAR16
*) StringBuffer
;
675 Convert Memory Size to a string.
677 @param MemorySize The size of the memory to process
678 @param String The string that is created
682 ConvertMemorySizeToString (
683 IN UINT32 MemorySize
,
687 CHAR16
*StringBuffer
;
689 StringBuffer
= AllocateZeroPool (0x24);
690 ASSERT (StringBuffer
!= NULL
);
691 UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, MemorySize
, 10);
692 StrCat (StringBuffer
, L
" MB RAM");
694 *String
= (CHAR16
*) StringBuffer
;
701 Acquire the string associated with the Index from smbios structure and return it.
702 The caller is responsible for free the string buffer.
704 @param OptionalStrStart The start position to search the string
705 @param Index The index of the string to extract
706 @param String The string that is extracted
708 @retval EFI_SUCCESS The function returns EFI_SUCCESS always.
712 GetOptionalStringByIndex (
713 IN CHAR8
*OptionalStrStart
,
721 *String
= AllocateZeroPool (sizeof (CHAR16
));
728 OptionalStrStart
+= StrSize
;
729 StrSize
= AsciiStrSize (OptionalStrStart
);
730 } while (OptionalStrStart
[StrSize
] != 0 && Index
!= 0);
732 if ((Index
!= 0) || (StrSize
== 1)) {
734 // Meet the end of strings set but Index is non-zero, or
735 // Find an empty string
737 *String
= GetStringById (STRING_TOKEN (STR_MISSING_STRING
));
739 *String
= AllocatePool (StrSize
* sizeof (CHAR16
));
740 AsciiStrToUnicodeStr (OptionalStrStart
, *String
);
748 Update the banner information for the Front Page based on Smbios information.
751 UpdateFrontPageStrings (
757 CHAR16
*FirmwareVersionString
;
760 EFI_STRING_ID TokenToUpdate
;
761 EFI_SMBIOS_HANDLE SmbiosHandle
;
762 EFI_SMBIOS_PROTOCOL
*Smbios
;
763 SMBIOS_TABLE_TYPE0
*Type0Record
;
764 SMBIOS_TABLE_TYPE1
*Type1Record
;
765 SMBIOS_TABLE_TYPE4
*Type4Record
;
766 SMBIOS_TABLE_TYPE19
*Type19Record
;
767 EFI_SMBIOS_TABLE_HEADER
*Record
;
769 ZeroMem (Find
, sizeof (Find
));
772 // Update Front Page strings
774 Status
= gBS
->LocateProtocol (
775 &gEfiSmbiosProtocolGuid
,
779 if (EFI_ERROR (Status
)) {
783 SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
785 Status
= Smbios
->GetNext (Smbios
, &SmbiosHandle
, NULL
, &Record
, NULL
);
786 if (EFI_ERROR(Status
)) {
790 if (Record
->Type
== EFI_SMBIOS_TYPE_BIOS_INFORMATION
) {
791 Type0Record
= (SMBIOS_TABLE_TYPE0
*) Record
;
792 StrIndex
= Type0Record
->BiosVersion
;
793 GetOptionalStringByIndex ((CHAR8
*)((UINT8
*)Type0Record
+ Type0Record
->Hdr
.Length
), StrIndex
, &NewString
);
794 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION
);
795 FirmwareVersionString
= (CHAR16
*) PcdGetPtr (PcdFirmwareVersionString
);
796 if (*FirmwareVersionString
!= 0x0000 ) {
797 FreePool (NewString
);
798 NewString
= (CHAR16
*) PcdGetPtr (PcdFirmwareVersionString
);
799 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
801 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
802 FreePool (NewString
);
807 if (Record
->Type
== EFI_SMBIOS_TYPE_SYSTEM_INFORMATION
) {
808 Type1Record
= (SMBIOS_TABLE_TYPE1
*) Record
;
809 StrIndex
= Type1Record
->ProductName
;
810 GetOptionalStringByIndex ((CHAR8
*)((UINT8
*)Type1Record
+ Type1Record
->Hdr
.Length
), StrIndex
, &NewString
);
811 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL
);
812 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
813 FreePool (NewString
);
817 if ((Record
->Type
== EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION
) && !Find
[2]) {
818 Type4Record
= (SMBIOS_TABLE_TYPE4
*) Record
;
820 // The information in the record should be only valid when the CPU Socket is populated.
822 if ((Type4Record
->Status
& SMBIOS_TYPE4_CPU_SOCKET_POPULATED
) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED
) {
823 StrIndex
= Type4Record
->ProcessorVersion
;
824 GetOptionalStringByIndex ((CHAR8
*)((UINT8
*)Type4Record
+ Type4Record
->Hdr
.Length
), StrIndex
, &NewString
);
825 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL
);
826 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
827 FreePool (NewString
);
832 if ((Record
->Type
== EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION
) && !Find
[3]) {
833 Type4Record
= (SMBIOS_TABLE_TYPE4
*) Record
;
835 // The information in the record should be only valid when the CPU Socket is populated.
837 if ((Type4Record
->Status
& SMBIOS_TYPE4_CPU_SOCKET_POPULATED
) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED
) {
838 ConvertProcessorToString(Type4Record
->CurrentSpeed
, 6, &NewString
);
839 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED
);
840 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
841 FreePool (NewString
);
846 if ( Record
->Type
== EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS
) {
847 Type19Record
= (SMBIOS_TABLE_TYPE19
*) Record
;
848 ConvertMemorySizeToString (
849 (UINT32
)(RShiftU64((Type19Record
->EndingAddress
- Type19Record
->StartingAddress
+ 1), 10)),
852 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE
);
853 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
854 FreePool (NewString
);
857 } while ( !(Find
[0] && Find
[1] && Find
[2] && Find
[3] && Find
[4]));
862 This function will change video resolution and text mode
863 according to defined setup mode or defined boot mode
865 @param IsSetupMode Indicate mode is changed to setup mode or boot mode.
867 @retval EFI_SUCCESS Mode is changed successfully.
868 @retval Others Mode failed to be changed.
877 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
878 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
880 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
884 UINT32 NewHorizontalResolution
;
885 UINT32 NewVerticalResolution
;
889 EFI_HANDLE
*HandleBuffer
;
899 // Get current video resolution and text mode
901 Status
= gBS
->HandleProtocol (
902 gST
->ConsoleOutHandle
,
903 &gEfiGraphicsOutputProtocolGuid
,
904 (VOID
**)&GraphicsOutput
906 if (EFI_ERROR (Status
)) {
907 GraphicsOutput
= NULL
;
910 Status
= gBS
->HandleProtocol (
911 gST
->ConsoleOutHandle
,
912 &gEfiSimpleTextOutProtocolGuid
,
913 (VOID
**)&SimpleTextOut
915 if (EFI_ERROR (Status
)) {
916 SimpleTextOut
= NULL
;
919 if ((GraphicsOutput
== NULL
) || (SimpleTextOut
== NULL
)) {
920 return EFI_UNSUPPORTED
;
925 // The requried resolution and text mode is setup mode.
927 NewHorizontalResolution
= mSetupHorizontalResolution
;
928 NewVerticalResolution
= mSetupVerticalResolution
;
929 NewColumns
= mSetupTextModeColumn
;
930 NewRows
= mSetupTextModeRow
;
933 // The required resolution and text mode is boot mode.
935 NewHorizontalResolution
= mBootHorizontalResolution
;
936 NewVerticalResolution
= mBootVerticalResolution
;
937 NewColumns
= mBootTextModeColumn
;
938 NewRows
= mBootTextModeRow
;
941 if (GraphicsOutput
!= NULL
) {
942 MaxGopMode
= GraphicsOutput
->Mode
->MaxMode
;
945 if (SimpleTextOut
!= NULL
) {
946 MaxTextMode
= SimpleTextOut
->Mode
->MaxMode
;
950 // 1. If current video resolution is same with required video resolution,
951 // video resolution need not be changed.
952 // 1.1. If current text mode is same with required text mode, text mode need not be changed.
953 // 1.2. If current text mode is different from required text mode, text mode need be changed.
954 // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.
956 for (ModeNumber
= 0; ModeNumber
< MaxGopMode
; ModeNumber
++) {
957 Status
= GraphicsOutput
->QueryMode (
963 if (!EFI_ERROR (Status
)) {
964 if ((Info
->HorizontalResolution
== NewHorizontalResolution
) &&
965 (Info
->VerticalResolution
== NewVerticalResolution
)) {
966 if ((GraphicsOutput
->Mode
->Info
->HorizontalResolution
== NewHorizontalResolution
) &&
967 (GraphicsOutput
->Mode
->Info
->VerticalResolution
== NewVerticalResolution
)) {
969 // Current resolution is same with required resolution, check if text mode need be set
971 Status
= SimpleTextOut
->QueryMode (SimpleTextOut
, SimpleTextOut
->Mode
->Mode
, &CurrentColumn
, &CurrentRow
);
972 ASSERT_EFI_ERROR (Status
);
973 if (CurrentColumn
== NewColumns
&& CurrentRow
== NewRows
) {
975 // If current text mode is same with required text mode. Do nothing
981 // If current text mode is different from requried text mode. Set new video mode
983 for (Index
= 0; Index
< MaxTextMode
; Index
++) {
984 Status
= SimpleTextOut
->QueryMode (SimpleTextOut
, Index
, &CurrentColumn
, &CurrentRow
);
985 if (!EFI_ERROR(Status
)) {
986 if ((CurrentColumn
== NewColumns
) && (CurrentRow
== NewRows
)) {
988 // Required text mode is supported, set it.
990 Status
= SimpleTextOut
->SetMode (SimpleTextOut
, Index
);
991 ASSERT_EFI_ERROR (Status
);
993 // Update text mode PCD.
995 PcdSet32 (PcdConOutColumn
, mSetupTextModeColumn
);
996 PcdSet32 (PcdConOutRow
, mSetupTextModeRow
);
1002 if (Index
== MaxTextMode
) {
1004 // If requried text mode is not supported, return error.
1007 return EFI_UNSUPPORTED
;
1012 // If current video resolution is not same with the new one, set new video resolution.
1013 // In this case, the driver which produces simple text out need be restarted.
1015 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeNumber
);
1016 if (!EFI_ERROR (Status
)) {
1026 if (ModeNumber
== MaxGopMode
) {
1028 // If the resolution is not supported, return error.
1030 return EFI_UNSUPPORTED
;
1034 // Set PCD to Inform GraphicsConsole to change video resolution.
1035 // Set PCD to Inform Consplitter to change text mode.
1037 PcdSet32 (PcdVideoHorizontalResolution
, NewHorizontalResolution
);
1038 PcdSet32 (PcdVideoVerticalResolution
, NewVerticalResolution
);
1039 PcdSet32 (PcdConOutColumn
, NewColumns
);
1040 PcdSet32 (PcdConOutRow
, NewRows
);
1044 // Video mode is changed, so restart graphics console driver and higher level driver.
1045 // Reconnect graphics console driver and higher level driver.
1046 // Locate all the handles with GOP protocol and reconnect it.
1048 Status
= gBS
->LocateHandleBuffer (
1050 &gEfiSimpleTextOutProtocolGuid
,
1055 if (!EFI_ERROR (Status
)) {
1056 for (Index
= 0; Index
< HandleCount
; Index
++) {
1057 gBS
->DisconnectController (HandleBuffer
[Index
], NULL
, NULL
);
1059 for (Index
= 0; Index
< HandleCount
; Index
++) {
1060 gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
1062 if (HandleBuffer
!= NULL
) {
1063 FreePool (HandleBuffer
);
1071 The user Entry Point for Application. The user code starts with this function
1072 as the real entry point for the image goes into a library that calls this
1075 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1076 @param[in] SystemTable A pointer to the EFI System Table.
1078 @retval EFI_SUCCESS The entry point is executed successfully.
1079 @retval other Some error occurs when executing this entry point.
1084 InitializeUserInterface (
1085 IN EFI_HANDLE ImageHandle
,
1086 IN EFI_SYSTEM_TABLE
*SystemTable
1089 EFI_HII_HANDLE HiiHandle
;
1091 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1092 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
1093 UINTN BootTextColumn
;
1096 if (!mModeInitialized
) {
1098 // After the console is ready, get current video resolution
1099 // and text mode before launching setup at first time.
1101 Status
= gBS
->HandleProtocol (
1102 gST
->ConsoleOutHandle
,
1103 &gEfiGraphicsOutputProtocolGuid
,
1104 (VOID
**)&GraphicsOutput
1106 if (EFI_ERROR (Status
)) {
1107 GraphicsOutput
= NULL
;
1110 Status
= gBS
->HandleProtocol (
1111 gST
->ConsoleOutHandle
,
1112 &gEfiSimpleTextOutProtocolGuid
,
1113 (VOID
**)&SimpleTextOut
1115 if (EFI_ERROR (Status
)) {
1116 SimpleTextOut
= NULL
;
1119 if (GraphicsOutput
!= NULL
) {
1121 // Get current video resolution and text mode.
1123 mBootHorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
1124 mBootVerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
1127 if (SimpleTextOut
!= NULL
) {
1128 Status
= SimpleTextOut
->QueryMode (
1130 SimpleTextOut
->Mode
->Mode
,
1134 mBootTextModeColumn
= (UINT32
)BootTextColumn
;
1135 mBootTextModeRow
= (UINT32
)BootTextRow
;
1139 // Get user defined text mode for setup.
1141 mSetupHorizontalResolution
= PcdGet32 (PcdSetupVideoHorizontalResolution
);
1142 mSetupVerticalResolution
= PcdGet32 (PcdSetupVideoVerticalResolution
);
1143 mSetupTextModeColumn
= PcdGet32 (PcdSetupConOutColumn
);
1144 mSetupTextModeRow
= PcdGet32 (PcdSetupConOutRow
);
1146 mModeInitialized
= TRUE
;
1149 gBS
->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL
);
1150 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1153 // Install customized fonts needed by Front Page
1156 HiiHandle
= ExportFonts ();
1157 ASSERT (HiiHandle
!= NULL
);
1159 InitializeStringSupport ();
1161 BdsSetConsoleMode (TRUE
);
1163 BdsSetConsoleMode (FALSE
);
1165 UninitializeStringSupport ();
1166 HiiRemovePackages (HiiHandle
);
1172 This function is the main entry of the UI entry.
1173 The function will present the main menu of the system UI.
1175 @param ConnectAllHappened Caller passes the value to UI to avoid unnecessary connect-all.
1181 IN BOOLEAN ConnectAllHappened
1185 EFI_BOOT_LOGO_PROTOCOL
*BootLogo
;
1188 // Indicate if the connect all has been performed before.
1190 if (ConnectAllHappened
) {
1191 gConnectAllHappened
= TRUE
;
1195 // The boot option enumeration time is acceptable in Ui driver
1197 EfiBootManagerRefreshAllBootOption ();
1200 // Boot Logo is corrupted, report it using Boot Logo protocol.
1202 Status
= gBS
->LocateProtocol (&gEfiBootLogoProtocolGuid
, NULL
, (VOID
**) &BootLogo
);
1203 if (!EFI_ERROR (Status
) && (BootLogo
!= NULL
)) {
1204 BootLogo
->SetBootLogo (BootLogo
, NULL
, 0, 0, 0, 0);
1207 InitializeFrontPage ();
1208 InitializeDeviceManager ();
1209 InitializeBootManager ();
1210 InitBootMaintenance();
1216 FreeDeviceManager ();
1219 if (mLanguageString
!= NULL
) {
1220 FreePool (mLanguageString
);
1221 mLanguageString
= NULL
;
1225 //Will leave browser, check any reset required change is applied? if yes, reset system
1227 SetupResetReminder ();
1231 Extract device path for given HII handle and class guid.
1233 @param Handle The HII handle.
1235 @retval NULL Fail to get the device path string.
1236 @return PathString Get the device path string.
1240 ExtractDevicePathFromHiiHandle (
1241 IN EFI_HII_HANDLE Handle
1245 EFI_HANDLE DriverHandle
;
1246 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1247 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL
*PathToText
;
1250 ASSERT (Handle
!= NULL
);
1252 if (Handle
== NULL
) {
1256 Status
= gHiiDatabase
->GetPackageListHandle (gHiiDatabase
, Handle
, &DriverHandle
);
1257 if (EFI_ERROR (Status
)) {
1262 // Get the device path by the got Driver handle .
1264 Status
= gBS
->HandleProtocol (DriverHandle
, &gEfiDevicePathProtocolGuid
, (VOID
**) &DevicePath
);
1265 if (EFI_ERROR (Status
)) {
1269 Status
= gBS
->LocateProtocol (
1270 &gEfiDevicePathToTextProtocolGuid
,
1272 (VOID
**) &PathToText
1274 if (EFI_ERROR (Status
)) {
1279 // Get device path string.
1281 NewString
= PathToText
->ConvertDevicePathToText(DevicePath
, FALSE
, FALSE
);
1287 Extract the displayed formset for given HII handle and class guid.
1289 @param Handle The HII handle.
1290 @param SetupClassGuid The class guid specifies which form set will be displayed.
1291 @param SkipCount Skip some formsets which has processed before.
1292 @param FormSetTitle Formset title string.
1293 @param FormSetHelp Formset help string.
1294 @param FormSetGuid Formset Guid.
1296 @retval TRUE The formset for given HII handle will be displayed.
1297 @return FALSE The formset for given HII handle will not be displayed.
1301 ExtractDisplayedHiiFormFromHiiHandle (
1302 IN EFI_HII_HANDLE Handle
,
1303 IN EFI_GUID
*SetupClassGuid
,
1305 OUT EFI_STRING_ID
*FormSetTitle
,
1306 OUT EFI_STRING_ID
*FormSetHelp
,
1307 OUT EFI_GUID
*FormSetGuid
1312 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
1317 UINT32 PackageListLength
;
1318 EFI_HII_PACKAGE_HEADER PackageHeader
;
1319 EFI_GUID
*ClassGuid
;
1321 BOOLEAN FoundAndSkip
;
1323 ASSERT (Handle
!= NULL
);
1324 ASSERT (SetupClassGuid
!= NULL
&& FormSetTitle
!= NULL
&& FormSetHelp
!= NULL
&& FormSetGuid
!= NULL
);
1330 FoundAndSkip
= FALSE
;
1333 // Get HII PackageList
1336 HiiPackageList
= NULL
;
1337 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
1339 // Handle is a invalid handle. Check if Handle is corrupted.
1341 ASSERT (Status
!= EFI_NOT_FOUND
);
1343 // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.
1345 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
1347 HiiPackageList
= AllocatePool (BufferSize
);
1348 ASSERT (HiiPackageList
!= NULL
);
1350 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
1351 if (EFI_ERROR (Status
)) {
1356 // Get Form package from this HII package List
1358 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
1359 PackageListLength
= ReadUnaligned32 (&HiiPackageList
->PackageLength
);
1361 while (Offset
< PackageListLength
) {
1362 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
1363 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
1364 Offset
+= PackageHeader
.Length
;
1366 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
1368 // Search FormSet Opcode in this Form Package
1370 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
1371 while (Offset2
< PackageHeader
.Length
) {
1372 OpCodeData
= Package
+ Offset2
;
1373 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1375 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
1376 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
1378 // Find FormSet OpCode
1380 ClassGuidNum
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
1381 ClassGuid
= (EFI_GUID
*) (VOID
*)(OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
1382 while (ClassGuidNum
-- > 0) {
1383 if (CompareGuid (SetupClassGuid
, ClassGuid
)) {
1385 // Check whether need to skip the formset.
1387 if (SkipCount
!= 0) {
1389 FoundAndSkip
= TRUE
;
1392 CopyMem (FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1393 CopyMem (FormSetHelp
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1394 CopyGuid (FormSetGuid
, (CONST EFI_GUID
*)(&((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
));
1395 FreePool (HiiPackageList
);
1403 } else if (CompareGuid (SetupClassGuid
, &gEfiHiiPlatformSetupFormsetGuid
)) {
1405 // Check whether need to skip the formset.
1407 if (SkipCount
!= 0) {
1411 CopyMem (FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
1412 CopyMem (FormSetHelp
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
1413 CopyGuid (FormSetGuid
, (CONST EFI_GUID
*)(&((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
));
1414 FreePool (HiiPackageList
);
1422 FreePool (HiiPackageList
);
1428 // Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.
1429 // Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if
1430 // user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection.
1435 Enable the setup browser reset reminder feature.
1436 This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it.
1441 EnableResetReminderFeature (
1445 mFeaturerSwitch
= TRUE
;
1450 Disable the setup browser reset reminder feature.
1451 This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it.
1456 DisableResetReminderFeature (
1460 mFeaturerSwitch
= FALSE
;
1465 Record the info that a reset is required.
1466 A module boolean variable is used to record whether a reset is required.
1471 EnableResetRequired (
1475 mResetRequired
= TRUE
;
1480 Record the info that no reset is required.
1481 A module boolean variable is used to record whether a reset is required.
1486 DisableResetRequired (
1490 mResetRequired
= FALSE
;
1495 Check whether platform policy enable the reset reminder feature. The default is enabled.
1500 IsResetReminderFeatureEnable (
1504 return mFeaturerSwitch
;
1509 Check if user changed any option setting which needs a system reset to be effective.
1518 return mResetRequired
;
1523 Check whether a reset is needed, and finish the reset reminder feature.
1524 If a reset is needed, Popup a menu to notice user, and finish the feature
1525 according to the user selection.
1530 SetupResetReminder (
1535 CHAR16
*StringBuffer1
;
1536 CHAR16
*StringBuffer2
;
1540 //check any reset required change is applied? if yes, reset system
1542 if (IsResetReminderFeatureEnable ()) {
1543 if (IsResetRequired ()) {
1545 StringBuffer1
= AllocateZeroPool (MAX_STRING_LEN
* sizeof (CHAR16
));
1546 ASSERT (StringBuffer1
!= NULL
);
1547 StringBuffer2
= AllocateZeroPool (MAX_STRING_LEN
* sizeof (CHAR16
));
1548 ASSERT (StringBuffer2
!= NULL
);
1549 StrCpy (StringBuffer1
, L
"Configuration changed. Reset to apply it Now.");
1550 StrCpy (StringBuffer2
, L
"Press ENTER to reset");
1552 // Popup a menu to notice user
1555 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, StringBuffer1
, StringBuffer2
, NULL
);
1556 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1558 FreePool (StringBuffer1
);
1559 FreePool (StringBuffer2
);
1561 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
1568 This function converts an input device structure to a Unicode string.
1570 @param DevPath A pointer to the device path structure.
1572 @return A new allocated Unicode string that represents the device path.
1577 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
1582 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL
*DevPathToText
;
1584 if (DevPath
== NULL
) {
1588 Status
= gBS
->LocateProtocol (
1589 &gEfiDevicePathToTextProtocolGuid
,
1591 (VOID
**) &DevPathToText
1593 ASSERT_EFI_ERROR (Status
);
1594 ToText
= DevPathToText
->ConvertDevicePathToText (
1599 ASSERT (ToText
!= NULL
);