2 FrontPage routines to handle the callbacks and browser calls
4 Copyright (c) 2004 - 2016, 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
;
25 EFI_FORM_BROWSER2_PROTOCOL
*gFormBrowser2
;
26 CHAR8
*mLanguageString
;
27 BOOLEAN mModeInitialized
= FALSE
;
29 // Boot video resolution and text mode.
31 UINT32 mBootHorizontalResolution
= 0;
32 UINT32 mBootVerticalResolution
= 0;
33 UINT32 mBootTextModeColumn
= 0;
34 UINT32 mBootTextModeRow
= 0;
36 // BIOS setup video resolution and text mode.
38 UINT32 mSetupTextModeColumn
= 0;
39 UINT32 mSetupTextModeRow
= 0;
40 UINT32 mSetupHorizontalResolution
= 0;
41 UINT32 mSetupVerticalResolution
= 0;
43 FRONT_PAGE_CALLBACK_DATA gFrontPagePrivate
= {
44 FRONT_PAGE_CALLBACK_DATA_SIGNATURE
,
55 HII_VENDOR_DEVICE_PATH mFrontPageHiiVendorDevicePath
= {
61 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
62 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
66 // {8E6D99EE-7531-48f8-8745-7F6144468FF2}
68 { 0x8e6d99ee, 0x7531, 0x48f8, { 0x87, 0x45, 0x7f, 0x61, 0x44, 0x46, 0x8f, 0xf2 } }
72 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
74 (UINT8
) (END_DEVICE_PATH_LENGTH
),
75 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
81 Update the banner information for the Front Page based on Smbios information.
85 UpdateFrontPageStrings (
90 This function allows a caller to extract the current configuration for one
91 or more named elements from the target driver.
94 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
95 @param Request A null-terminated Unicode string in <ConfigRequest> format.
96 @param Progress On return, points to a character in the Request string.
97 Points to the string's null terminator if request was successful.
98 Points to the most recent '&' before the first failing name/value
99 pair (or the beginning of the string if the failure is in the
100 first name/value pair) if the request was not successful.
101 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
102 has all values filled in for the names in the Request string.
103 String to be allocated by the called function.
105 @retval EFI_SUCCESS The Results is filled with the requested values.
106 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
107 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
108 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
114 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
115 IN CONST EFI_STRING Request
,
116 OUT EFI_STRING
*Progress
,
117 OUT EFI_STRING
*Results
120 if (Progress
== NULL
|| Results
== NULL
) {
121 return EFI_INVALID_PARAMETER
;
124 return EFI_NOT_FOUND
;
128 This function processes the results of changes in configuration.
131 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
132 @param Configuration A null-terminated Unicode string in <ConfigResp> format.
133 @param Progress A pointer to a string filled in with the offset of the most
134 recent '&' before the first failing name/value pair (or the
135 beginning of the string if the failure is in the first
136 name/value pair) or the terminating NULL if all was successful.
138 @retval EFI_SUCCESS The Results is processed successfully.
139 @retval EFI_INVALID_PARAMETER Configuration is NULL.
140 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
146 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
147 IN CONST EFI_STRING Configuration
,
148 OUT EFI_STRING
*Progress
151 if (Configuration
== NULL
|| Progress
== NULL
) {
152 return EFI_INVALID_PARAMETER
;
155 return EFI_NOT_FOUND
;
159 Create oneof options for language.
172 CHAR16
*StringBuffer
;
173 EFI_HII_HANDLE HiiHandle
;
174 VOID
*OptionsOpCodeHandle
;
175 VOID
*StartOpCodeHandle
;
176 VOID
*EndOpCodeHandle
;
177 EFI_IFR_GUID_LABEL
*StartLabel
;
178 EFI_IFR_GUID_LABEL
*EndLabel
;
179 EFI_HII_STRING_PROTOCOL
*HiiString
;
186 // Init OpCode Handle and Allocate space for creation of UpdateData Buffer
188 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
189 ASSERT (StartOpCodeHandle
!= NULL
);
191 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
192 ASSERT (EndOpCodeHandle
!= NULL
);
194 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
195 ASSERT (OptionsOpCodeHandle
!= NULL
);
197 // Create Hii Extend Label OpCode as the start opcode
199 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
200 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
201 StartLabel
->Number
= LABEL_SELECT_LANGUAGE
;
204 // Create Hii Extend Label OpCode as the end opcode
206 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
207 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
208 EndLabel
->Number
= LABEL_END
;
210 // Collect the languages from what our current Language support is based on our VFR
212 HiiHandle
= gFrontPagePrivate
.HiiHandle
;
214 GetEfiGlobalVariable2 (L
"PlatformLang", (VOID
**)&CurrentLang
, NULL
);
216 if (mLanguageString
== NULL
) {
218 // Get Support language list from variable.
220 GetEfiGlobalVariable2 (L
"PlatformLangCodes", (VOID
**)&mLanguageString
, NULL
);
221 if (mLanguageString
== NULL
) {
222 mLanguageString
= AllocateCopyPool (
223 AsciiStrSize ((CHAR8
*) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes
)),
224 (CHAR8
*) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes
)
226 ASSERT (mLanguageString
!= NULL
);
230 if (gFrontPagePrivate
.LanguageToken
== NULL
) {
232 // Count the language list number.
234 LangCode
= mLanguageString
;
235 Lang
= AllocatePool (AsciiStrSize (mLanguageString
));
236 ASSERT (Lang
!= NULL
);
238 while (*LangCode
!= 0) {
239 GetNextLanguage (&LangCode
, Lang
);
244 // Allocate extra 1 as the end tag.
246 gFrontPagePrivate
.LanguageToken
= AllocateZeroPool ((OptionCount
+ 1) * sizeof (EFI_STRING_ID
));
247 ASSERT (gFrontPagePrivate
.LanguageToken
!= NULL
);
249 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &HiiString
);
250 ASSERT_EFI_ERROR (Status
);
252 LangCode
= mLanguageString
;
254 while (*LangCode
!= 0) {
255 GetNextLanguage (&LangCode
, Lang
);
258 Status
= HiiString
->GetString (HiiString
, Lang
, HiiHandle
, PRINTABLE_LANGUAGE_NAME_STRING_ID
, StringBuffer
, &StringSize
, NULL
);
259 if (Status
== EFI_BUFFER_TOO_SMALL
) {
260 StringBuffer
= AllocateZeroPool (StringSize
);
261 ASSERT (StringBuffer
!= NULL
);
262 Status
= HiiString
->GetString (HiiString
, Lang
, HiiHandle
, PRINTABLE_LANGUAGE_NAME_STRING_ID
, StringBuffer
, &StringSize
, NULL
);
263 ASSERT_EFI_ERROR (Status
);
266 if (EFI_ERROR (Status
)) {
267 StringBuffer
= AllocatePool (AsciiStrSize (Lang
) * sizeof (CHAR16
));
268 ASSERT (StringBuffer
!= NULL
);
269 AsciiStrToUnicodeStr (Lang
, StringBuffer
);
272 ASSERT (StringBuffer
!= NULL
);
273 gFrontPagePrivate
.LanguageToken
[OptionCount
] = HiiSetString (HiiHandle
, 0, StringBuffer
, NULL
);
274 FreePool (StringBuffer
);
280 ASSERT (gFrontPagePrivate
.LanguageToken
!= NULL
);
281 LangCode
= mLanguageString
;
284 Lang
= AllocatePool (AsciiStrSize (mLanguageString
));
285 ASSERT (Lang
!= NULL
);
287 while (*LangCode
!= 0) {
288 GetNextLanguage (&LangCode
, Lang
);
290 if (CurrentLang
!= NULL
&& AsciiStrCmp (Lang
, CurrentLang
) == 0) {
291 HiiCreateOneOfOptionOpCode (
293 gFrontPagePrivate
.LanguageToken
[OptionCount
],
294 EFI_IFR_OPTION_DEFAULT
,
295 EFI_IFR_NUMERIC_SIZE_1
,
299 HiiCreateOneOfOptionOpCode (
301 gFrontPagePrivate
.LanguageToken
[OptionCount
],
303 EFI_IFR_NUMERIC_SIZE_1
,
311 if (CurrentLang
!= NULL
) {
312 FreePool (CurrentLang
);
316 HiiCreateOneOfOpCode (
318 FRONT_PAGE_KEY_LANGUAGE
,
321 STRING_TOKEN (STR_LANGUAGE_SELECT
),
322 STRING_TOKEN (STR_LANGUAGE_SELECT_HELP
),
323 EFI_IFR_FLAG_CALLBACK
,
324 EFI_IFR_NUMERIC_SIZE_1
,
329 Status
= HiiUpdateForm (
333 StartOpCodeHandle
, // LABEL_SELECT_LANGUAGE
334 EndOpCodeHandle
// LABEL_END
337 HiiFreeOpCodeHandle (StartOpCodeHandle
);
338 HiiFreeOpCodeHandle (EndOpCodeHandle
);
339 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
343 This function processes the results of changes in configuration.
346 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
347 @param Action Specifies the type of action taken by the browser.
348 @param QuestionId A unique value which is sent to the original exporting driver
349 so that it can identify the type of data to expect.
350 @param Type The type of value for the question.
351 @param Value A pointer to the data being sent to the original exporting driver.
352 @param ActionRequest On return, points to the action requested by the callback function.
354 @retval EFI_SUCCESS The callback successfully handled the action.
355 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
356 @retval EFI_DEVICE_ERROR The variable could not be saved.
357 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
363 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
364 IN EFI_BROWSER_ACTION Action
,
365 IN EFI_QUESTION_ID QuestionId
,
367 IN EFI_IFR_TYPE_VALUE
*Value
,
368 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
376 if (Action
!= EFI_BROWSER_ACTION_CHANGED
) {
378 // Do nothing for other UEFI Action. Only do call back when data is changed.
380 return EFI_UNSUPPORTED
;
383 if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
384 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
385 return EFI_INVALID_PARAMETER
;
388 switch (QuestionId
) {
389 case FRONT_PAGE_KEY_CONTINUE
:
391 // This is the continue - clear the screen and return an error to get out of FrontPage loop
393 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
396 case FRONT_PAGE_KEY_LANGUAGE
:
398 // Allocate working buffer for RFC 4646 language in supported LanguageString.
400 Lang
= AllocatePool (AsciiStrSize (mLanguageString
));
401 ASSERT (Lang
!= NULL
);
404 LangCode
= mLanguageString
;
405 while (*LangCode
!= 0) {
406 GetNextLanguage (&LangCode
, Lang
);
408 if (Index
== Value
->u8
) {
415 if (Index
== Value
->u8
) {
416 Status
= gRT
->SetVariable (
418 &gEfiGlobalVariableGuid
,
419 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
423 if (EFI_ERROR (Status
)) {
425 return EFI_DEVICE_ERROR
;
432 //Current language of platform is changed,recreate oneof options for language.
434 InitializeLanguage();
446 Update front page form base on the ClassGuid in the formset in other modules.
450 UpdateFrontPageForm (
455 EFI_HII_HANDLE HiiHandle
;
456 VOID
*StartOpCodeHandle
;
457 VOID
*EndOpCodeHandle
;
458 EFI_IFR_GUID_LABEL
*StartLabel
;
459 EFI_IFR_GUID_LABEL
*EndLabel
;
463 EFI_STRING_ID TokenHelp
;
464 EFI_HII_HANDLE
*HiiHandles
;
465 EFI_GUID FormSetGuid
;
466 CHAR16
*DevicePathStr
;
467 EFI_STRING_ID DevicePathId
;
468 EFI_IFR_FORM_SET
*Buffer
;
479 HiiHandle
= gFrontPagePrivate
.HiiHandle
;
482 // Allocate space for creation of UpdateData Buffer
484 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
485 ASSERT (StartOpCodeHandle
!= NULL
);
487 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
488 ASSERT (EndOpCodeHandle
!= NULL
);
490 // Create Hii Extend Label OpCode as the start opcode
492 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
493 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
494 StartLabel
->Number
= LABEL_PLATFORM_INFORMATION
;
496 // Create Hii Extend Label OpCode as the end opcode
498 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
499 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
500 EndLabel
->Number
= LABEL_END
;
503 // Get all the Hii handles
505 HiiHandles
= HiiGetHiiHandles (NULL
);
506 ASSERT (HiiHandles
!= NULL
);
508 // Search for formset of each class type
510 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
511 Status
= HiiGetFormSetFromHiiHandle(HiiHandles
[Index
], &Buffer
,&BufferSize
);
512 if (EFI_ERROR (Status
)) {
516 Ptr
= (UINT8
*)Buffer
;
517 while(TempSize
< BufferSize
) {
518 TempSize
+= ((EFI_IFR_OP_HEADER
*) Ptr
)->Length
;
520 if (((EFI_IFR_OP_HEADER
*) Ptr
)->Length
<= OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)){
521 Ptr
+= ((EFI_IFR_OP_HEADER
*) Ptr
)->Length
;
528 ClassGuidNum
= (UINT8
) (((EFI_IFR_FORM_SET
*)Ptr
)->Flags
& 0x3);
529 ClassGuid
= (EFI_GUID
*) (VOID
*)(Ptr
+ sizeof (EFI_IFR_FORM_SET
));
530 while (ClassGuidNum
-- > 0) {
531 if (CompareGuid (&gEfiIfrFrontPageGuid
, ClassGuid
) == 0){
536 String
= HiiGetString (HiiHandles
[Index
], ((EFI_IFR_FORM_SET
*)Ptr
)->FormSetTitle
, NULL
);
537 if (String
== NULL
) {
538 String
= HiiGetString (HiiHandle
, STRING_TOKEN (STR_MISSING_STRING
), NULL
);
539 ASSERT (String
!= NULL
);
541 Token
= HiiSetString (HiiHandle
, 0, String
, NULL
);
544 String
= HiiGetString (HiiHandles
[Index
], ((EFI_IFR_FORM_SET
*)Ptr
)->Help
, NULL
);
546 if (String
== NULL
) {
547 String
= HiiGetString (HiiHandle
, STRING_TOKEN (STR_MISSING_STRING
), NULL
);
548 ASSERT (String
!= NULL
);
550 TokenHelp
= HiiSetString (HiiHandle
, 0, String
, NULL
);
553 FormSetGuid
= ((EFI_IFR_FORM_SET
*)Ptr
)->Guid
;
555 DevicePathStr
= ExtractDevicePathFromHiiHandle(HiiHandles
[Index
]);
557 if (DevicePathStr
!= NULL
){
558 DevicePathId
= HiiSetString (HiiHandle
, 0, DevicePathStr
, NULL
);
559 FreePool (DevicePathStr
);
561 HiiCreateGotoExOpCode (
567 (EFI_QUESTION_ID
) (Index
+ FRONT_PAGE_KEY_OFFSET
),
574 Ptr
+= ((EFI_IFR_OP_HEADER
*) Ptr
)->Length
;
591 HiiFreeOpCodeHandle (StartOpCodeHandle
);
592 HiiFreeOpCodeHandle (EndOpCodeHandle
);
593 FreePool (HiiHandles
);
597 Initialize HII information for the FrontPage
600 @retval EFI_SUCCESS The operation is successful.
601 @retval EFI_DEVICE_ERROR If the dynamic opcode creation failed.
605 InitializeFrontPage (
611 // Locate Hii relative protocols
613 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &gFormBrowser2
);
614 if (EFI_ERROR (Status
)) {
619 // Install Device Path Protocol and Config Access protocol to driver handle
621 gFrontPagePrivate
.DriverHandle
= NULL
;
622 Status
= gBS
->InstallMultipleProtocolInterfaces (
623 &gFrontPagePrivate
.DriverHandle
,
624 &gEfiDevicePathProtocolGuid
,
625 &mFrontPageHiiVendorDevicePath
,
626 &gEfiHiiConfigAccessProtocolGuid
,
627 &gFrontPagePrivate
.ConfigAccess
,
630 ASSERT_EFI_ERROR (Status
);
633 // Publish our HII data
635 gFrontPagePrivate
.HiiHandle
= HiiAddPackages (
637 gFrontPagePrivate
.DriverHandle
,
642 ASSERT (gFrontPagePrivate
.HiiHandle
!= NULL
);
645 //Updata Front Page strings
647 UpdateFrontPageStrings ();
650 // Initialize laguage options
652 InitializeLanguage ();
655 //Updata Front Page form
657 UpdateFrontPageForm();
663 Call the browser and display the front page
665 @return Status code that will be returned by
666 EFI_FORM_BROWSER2_PROTOCOL.SendForm ().
675 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
678 // Begin waiting for USER INPUT
682 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_INPUT_WAIT
)
685 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
686 Status
= gFormBrowser2
->SendForm (
688 &gFrontPagePrivate
.HiiHandle
,
696 // Check whether user change any option setting which needs a reset to be effective
698 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
699 EnableResetRequired ();
706 Remove the installed packages from the HiiDatabase.
715 Status
= gBS
->UninstallMultipleProtocolInterfaces (
716 gFrontPagePrivate
.DriverHandle
,
717 &gEfiDevicePathProtocolGuid
,
718 &mFrontPageHiiVendorDevicePath
,
719 &gEfiHiiConfigAccessProtocolGuid
,
720 &gFrontPagePrivate
.ConfigAccess
,
723 ASSERT_EFI_ERROR (Status
);
726 // Publish our HII data
728 HiiRemovePackages (gFrontPagePrivate
.HiiHandle
);
729 if (gFrontPagePrivate
.LanguageToken
!= NULL
) {
730 FreePool (gFrontPagePrivate
.LanguageToken
);
731 gFrontPagePrivate
.LanguageToken
= NULL
;
736 Convert Processor Frequency Data to a string.
738 @param ProcessorFrequency The frequency data to process
739 @param Base10Exponent The exponent based on 10
740 @param String The string that is created
744 ConvertProcessorToString (
745 IN UINT16 ProcessorFrequency
,
746 IN UINT16 Base10Exponent
,
750 CHAR16
*StringBuffer
;
755 if (Base10Exponent
>= 6) {
756 FreqMhz
= ProcessorFrequency
;
757 for (Index
= 0; Index
< (UINTN
) (Base10Exponent
- 6); Index
++) {
763 DestMax
= 0x20 / sizeof (CHAR16
);
764 StringBuffer
= AllocateZeroPool (0x20);
765 ASSERT (StringBuffer
!= NULL
);
766 Index
= UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, FreqMhz
/ 1000, 3);
767 StrCatS (StringBuffer
, DestMax
, L
".");
768 UnicodeValueToString (StringBuffer
+ Index
+ 1, PREFIX_ZERO
, (FreqMhz
% 1000) / 10, 2);
769 StrCatS (StringBuffer
, DestMax
, L
" GHz");
770 *String
= (CHAR16
*) StringBuffer
;
776 Convert Memory Size to a string.
778 @param MemorySize The size of the memory to process
779 @param String The string that is created
783 ConvertMemorySizeToString (
784 IN UINT32 MemorySize
,
788 CHAR16
*StringBuffer
;
790 StringBuffer
= AllocateZeroPool (0x24);
791 ASSERT (StringBuffer
!= NULL
);
792 UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, MemorySize
, 10);
793 StrCatS (StringBuffer
, 0x24 / sizeof (CHAR16
), L
" MB RAM");
795 *String
= (CHAR16
*) StringBuffer
;
802 Acquire the string associated with the Index from smbios structure and return it.
803 The caller is responsible for free the string buffer.
805 @param OptionalStrStart The start position to search the string
806 @param Index The index of the string to extract
807 @param String The string that is extracted
809 @retval EFI_SUCCESS The function returns EFI_SUCCESS always.
813 GetOptionalStringByIndex (
814 IN CHAR8
*OptionalStrStart
,
822 *String
= AllocateZeroPool (sizeof (CHAR16
));
829 OptionalStrStart
+= StrSize
;
830 StrSize
= AsciiStrSize (OptionalStrStart
);
831 } while (OptionalStrStart
[StrSize
] != 0 && Index
!= 0);
833 if ((Index
!= 0) || (StrSize
== 1)) {
835 // Meet the end of strings set but Index is non-zero, or
836 // Find an empty string
838 *String
= GetStringById (STRING_TOKEN (STR_MISSING_STRING
));
840 *String
= AllocatePool (StrSize
* sizeof (CHAR16
));
841 AsciiStrToUnicodeStr (OptionalStrStart
, *String
);
849 Update the banner information for the Front Page based on Smbios information.
852 UpdateFrontPageStrings (
858 CHAR16
*FirmwareVersionString
;
861 EFI_STRING_ID TokenToUpdate
;
862 EFI_SMBIOS_HANDLE SmbiosHandle
;
863 EFI_SMBIOS_PROTOCOL
*Smbios
;
864 SMBIOS_TABLE_TYPE0
*Type0Record
;
865 SMBIOS_TABLE_TYPE1
*Type1Record
;
866 SMBIOS_TABLE_TYPE4
*Type4Record
;
867 SMBIOS_TABLE_TYPE19
*Type19Record
;
868 EFI_SMBIOS_TABLE_HEADER
*Record
;
870 ZeroMem (Find
, sizeof (Find
));
873 // Update Front Page strings
875 Status
= gBS
->LocateProtocol (
876 &gEfiSmbiosProtocolGuid
,
880 if (EFI_ERROR (Status
)) {
884 SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
886 Status
= Smbios
->GetNext (Smbios
, &SmbiosHandle
, NULL
, &Record
, NULL
);
887 if (EFI_ERROR(Status
)) {
891 if (Record
->Type
== EFI_SMBIOS_TYPE_BIOS_INFORMATION
) {
892 Type0Record
= (SMBIOS_TABLE_TYPE0
*) Record
;
893 StrIndex
= Type0Record
->BiosVersion
;
894 GetOptionalStringByIndex ((CHAR8
*)((UINT8
*)Type0Record
+ Type0Record
->Hdr
.Length
), StrIndex
, &NewString
);
895 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION
);
896 FirmwareVersionString
= (CHAR16
*) PcdGetPtr (PcdFirmwareVersionString
);
897 if (*FirmwareVersionString
!= 0x0000 ) {
898 FreePool (NewString
);
899 NewString
= (CHAR16
*) PcdGetPtr (PcdFirmwareVersionString
);
900 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
902 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
903 FreePool (NewString
);
908 if (Record
->Type
== EFI_SMBIOS_TYPE_SYSTEM_INFORMATION
) {
909 Type1Record
= (SMBIOS_TABLE_TYPE1
*) Record
;
910 StrIndex
= Type1Record
->ProductName
;
911 GetOptionalStringByIndex ((CHAR8
*)((UINT8
*)Type1Record
+ Type1Record
->Hdr
.Length
), StrIndex
, &NewString
);
912 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL
);
913 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
914 FreePool (NewString
);
918 if ((Record
->Type
== EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION
) && !Find
[2]) {
919 Type4Record
= (SMBIOS_TABLE_TYPE4
*) Record
;
921 // The information in the record should be only valid when the CPU Socket is populated.
923 if ((Type4Record
->Status
& SMBIOS_TYPE4_CPU_SOCKET_POPULATED
) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED
) {
924 StrIndex
= Type4Record
->ProcessorVersion
;
925 GetOptionalStringByIndex ((CHAR8
*)((UINT8
*)Type4Record
+ Type4Record
->Hdr
.Length
), StrIndex
, &NewString
);
926 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL
);
927 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
928 FreePool (NewString
);
933 if ((Record
->Type
== EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION
) && !Find
[3]) {
934 Type4Record
= (SMBIOS_TABLE_TYPE4
*) Record
;
936 // The information in the record should be only valid when the CPU Socket is populated.
938 if ((Type4Record
->Status
& SMBIOS_TYPE4_CPU_SOCKET_POPULATED
) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED
) {
939 ConvertProcessorToString(Type4Record
->CurrentSpeed
, 6, &NewString
);
940 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED
);
941 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
942 FreePool (NewString
);
947 if ( Record
->Type
== EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS
) {
948 Type19Record
= (SMBIOS_TABLE_TYPE19
*) Record
;
949 ConvertMemorySizeToString (
950 (UINT32
)(RShiftU64((Type19Record
->EndingAddress
- Type19Record
->StartingAddress
+ 1), 10)),
953 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE
);
954 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
955 FreePool (NewString
);
958 } while ( !(Find
[0] && Find
[1] && Find
[2] && Find
[3] && Find
[4]));
963 This function will change video resolution and text mode
964 according to defined setup mode or defined boot mode
966 @param IsSetupMode Indicate mode is changed to setup mode or boot mode.
968 @retval EFI_SUCCESS Mode is changed successfully.
969 @retval Others Mode failed to be changed.
978 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
979 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
981 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
985 UINT32 NewHorizontalResolution
;
986 UINT32 NewVerticalResolution
;
990 EFI_HANDLE
*HandleBuffer
;
1000 // Get current video resolution and text mode
1002 Status
= gBS
->HandleProtocol (
1003 gST
->ConsoleOutHandle
,
1004 &gEfiGraphicsOutputProtocolGuid
,
1005 (VOID
**)&GraphicsOutput
1007 if (EFI_ERROR (Status
)) {
1008 GraphicsOutput
= NULL
;
1011 Status
= gBS
->HandleProtocol (
1012 gST
->ConsoleOutHandle
,
1013 &gEfiSimpleTextOutProtocolGuid
,
1014 (VOID
**)&SimpleTextOut
1016 if (EFI_ERROR (Status
)) {
1017 SimpleTextOut
= NULL
;
1020 if ((GraphicsOutput
== NULL
) || (SimpleTextOut
== NULL
)) {
1021 return EFI_UNSUPPORTED
;
1026 // The requried resolution and text mode is setup mode.
1028 NewHorizontalResolution
= mSetupHorizontalResolution
;
1029 NewVerticalResolution
= mSetupVerticalResolution
;
1030 NewColumns
= mSetupTextModeColumn
;
1031 NewRows
= mSetupTextModeRow
;
1034 // The required resolution and text mode is boot mode.
1036 NewHorizontalResolution
= mBootHorizontalResolution
;
1037 NewVerticalResolution
= mBootVerticalResolution
;
1038 NewColumns
= mBootTextModeColumn
;
1039 NewRows
= mBootTextModeRow
;
1042 if (GraphicsOutput
!= NULL
) {
1043 MaxGopMode
= GraphicsOutput
->Mode
->MaxMode
;
1046 if (SimpleTextOut
!= NULL
) {
1047 MaxTextMode
= SimpleTextOut
->Mode
->MaxMode
;
1051 // 1. If current video resolution is same with required video resolution,
1052 // video resolution need not be changed.
1053 // 1.1. If current text mode is same with required text mode, text mode need not be changed.
1054 // 1.2. If current text mode is different from required text mode, text mode need be changed.
1055 // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.
1057 for (ModeNumber
= 0; ModeNumber
< MaxGopMode
; ModeNumber
++) {
1058 Status
= GraphicsOutput
->QueryMode (
1064 if (!EFI_ERROR (Status
)) {
1065 if ((Info
->HorizontalResolution
== NewHorizontalResolution
) &&
1066 (Info
->VerticalResolution
== NewVerticalResolution
)) {
1067 if ((GraphicsOutput
->Mode
->Info
->HorizontalResolution
== NewHorizontalResolution
) &&
1068 (GraphicsOutput
->Mode
->Info
->VerticalResolution
== NewVerticalResolution
)) {
1070 // Current resolution is same with required resolution, check if text mode need be set
1072 Status
= SimpleTextOut
->QueryMode (SimpleTextOut
, SimpleTextOut
->Mode
->Mode
, &CurrentColumn
, &CurrentRow
);
1073 ASSERT_EFI_ERROR (Status
);
1074 if (CurrentColumn
== NewColumns
&& CurrentRow
== NewRows
) {
1076 // If current text mode is same with required text mode. Do nothing
1082 // If current text mode is different from requried text mode. Set new video mode
1084 for (Index
= 0; Index
< MaxTextMode
; Index
++) {
1085 Status
= SimpleTextOut
->QueryMode (SimpleTextOut
, Index
, &CurrentColumn
, &CurrentRow
);
1086 if (!EFI_ERROR(Status
)) {
1087 if ((CurrentColumn
== NewColumns
) && (CurrentRow
== NewRows
)) {
1089 // Required text mode is supported, set it.
1091 Status
= SimpleTextOut
->SetMode (SimpleTextOut
, Index
);
1092 ASSERT_EFI_ERROR (Status
);
1094 // Update text mode PCD.
1096 Status
= PcdSet32S (PcdConOutColumn
, mSetupTextModeColumn
);
1097 ASSERT_EFI_ERROR (Status
);
1098 Status
= PcdSet32S (PcdConOutRow
, mSetupTextModeRow
);
1099 ASSERT_EFI_ERROR (Status
);
1105 if (Index
== MaxTextMode
) {
1107 // If requried text mode is not supported, return error.
1110 return EFI_UNSUPPORTED
;
1115 // If current video resolution is not same with the new one, set new video resolution.
1116 // In this case, the driver which produces simple text out need be restarted.
1118 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeNumber
);
1119 if (!EFI_ERROR (Status
)) {
1129 if (ModeNumber
== MaxGopMode
) {
1131 // If the resolution is not supported, return error.
1133 return EFI_UNSUPPORTED
;
1137 // Set PCD to Inform GraphicsConsole to change video resolution.
1138 // Set PCD to Inform Consplitter to change text mode.
1140 Status
= PcdSet32S (PcdVideoHorizontalResolution
, NewHorizontalResolution
);
1141 ASSERT_EFI_ERROR (Status
);
1142 Status
= PcdSet32S (PcdVideoVerticalResolution
, NewVerticalResolution
);
1143 ASSERT_EFI_ERROR (Status
);
1144 Status
= PcdSet32S (PcdConOutColumn
, NewColumns
);
1145 ASSERT_EFI_ERROR (Status
);
1146 Status
= PcdSet32S (PcdConOutRow
, NewRows
);
1147 ASSERT_EFI_ERROR (Status
);
1151 // Video mode is changed, so restart graphics console driver and higher level driver.
1152 // Reconnect graphics console driver and higher level driver.
1153 // Locate all the handles with GOP protocol and reconnect it.
1155 Status
= gBS
->LocateHandleBuffer (
1157 &gEfiSimpleTextOutProtocolGuid
,
1162 if (!EFI_ERROR (Status
)) {
1163 for (Index
= 0; Index
< HandleCount
; Index
++) {
1164 gBS
->DisconnectController (HandleBuffer
[Index
], NULL
, NULL
);
1166 for (Index
= 0; Index
< HandleCount
; Index
++) {
1167 gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
1169 if (HandleBuffer
!= NULL
) {
1170 FreePool (HandleBuffer
);
1178 The user Entry Point for Application. The user code starts with this function
1179 as the real entry point for the image goes into a library that calls this
1182 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1183 @param[in] SystemTable A pointer to the EFI System Table.
1185 @retval EFI_SUCCESS The entry point is executed successfully.
1186 @retval other Some error occurs when executing this entry point.
1191 InitializeUserInterface (
1192 IN EFI_HANDLE ImageHandle
,
1193 IN EFI_SYSTEM_TABLE
*SystemTable
1196 EFI_HII_HANDLE HiiHandle
;
1198 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1199 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
1200 UINTN BootTextColumn
;
1203 if (!mModeInitialized
) {
1205 // After the console is ready, get current video resolution
1206 // and text mode before launching setup at first time.
1208 Status
= gBS
->HandleProtocol (
1209 gST
->ConsoleOutHandle
,
1210 &gEfiGraphicsOutputProtocolGuid
,
1211 (VOID
**)&GraphicsOutput
1213 if (EFI_ERROR (Status
)) {
1214 GraphicsOutput
= NULL
;
1217 Status
= gBS
->HandleProtocol (
1218 gST
->ConsoleOutHandle
,
1219 &gEfiSimpleTextOutProtocolGuid
,
1220 (VOID
**)&SimpleTextOut
1222 if (EFI_ERROR (Status
)) {
1223 SimpleTextOut
= NULL
;
1226 if (GraphicsOutput
!= NULL
) {
1228 // Get current video resolution and text mode.
1230 mBootHorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
1231 mBootVerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
1234 if (SimpleTextOut
!= NULL
) {
1235 Status
= SimpleTextOut
->QueryMode (
1237 SimpleTextOut
->Mode
->Mode
,
1241 mBootTextModeColumn
= (UINT32
)BootTextColumn
;
1242 mBootTextModeRow
= (UINT32
)BootTextRow
;
1246 // Get user defined text mode for setup.
1248 mSetupHorizontalResolution
= PcdGet32 (PcdSetupVideoHorizontalResolution
);
1249 mSetupVerticalResolution
= PcdGet32 (PcdSetupVideoVerticalResolution
);
1250 mSetupTextModeColumn
= PcdGet32 (PcdSetupConOutColumn
);
1251 mSetupTextModeRow
= PcdGet32 (PcdSetupConOutRow
);
1253 mModeInitialized
= TRUE
;
1256 gBS
->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL
);
1257 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1260 // Install customized fonts needed by Front Page
1263 HiiHandle
= ExportFonts ();
1264 ASSERT (HiiHandle
!= NULL
);
1266 InitializeStringSupport ();
1268 BdsSetConsoleMode (TRUE
);
1270 BdsSetConsoleMode (FALSE
);
1272 UninitializeStringSupport ();
1273 HiiRemovePackages (HiiHandle
);
1279 This function is the main entry of the UI entry.
1280 The function will present the main menu of the system UI.
1282 @param ConnectAllHappened Caller passes the value to UI to avoid unnecessary connect-all.
1288 IN BOOLEAN ConnectAllHappened
1292 EFI_BOOT_LOGO_PROTOCOL
*BootLogo
;
1295 // Indicate if the connect all has been performed before.
1297 if (ConnectAllHappened
) {
1298 gConnectAllHappened
= TRUE
;
1302 // The boot option enumeration time is acceptable in Ui driver
1304 EfiBootManagerRefreshAllBootOption ();
1307 // Boot Logo is corrupted, report it using Boot Logo protocol.
1309 Status
= gBS
->LocateProtocol (&gEfiBootLogoProtocolGuid
, NULL
, (VOID
**) &BootLogo
);
1310 if (!EFI_ERROR (Status
) && (BootLogo
!= NULL
)) {
1311 BootLogo
->SetBootLogo (BootLogo
, NULL
, 0, 0, 0, 0);
1314 InitializeFrontPage ();
1320 if (mLanguageString
!= NULL
) {
1321 FreePool (mLanguageString
);
1322 mLanguageString
= NULL
;
1326 //Will leave browser, check any reset required change is applied? if yes, reset system
1328 SetupResetReminder ();
1332 Extract device path for given HII handle and class guid.
1334 @param Handle The HII handle.
1336 @retval NULL Fail to get the device path string.
1337 @return PathString Get the device path string.
1341 ExtractDevicePathFromHiiHandle (
1342 IN EFI_HII_HANDLE Handle
1346 EFI_HANDLE DriverHandle
;
1348 ASSERT (Handle
!= NULL
);
1350 if (Handle
== NULL
) {
1354 Status
= gHiiDatabase
->GetPackageListHandle (gHiiDatabase
, Handle
, &DriverHandle
);
1355 if (EFI_ERROR (Status
)) {
1359 return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle
), FALSE
, FALSE
);
1364 // Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.
1365 // Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if
1366 // user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection.
1371 Enable the setup browser reset reminder feature.
1372 This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it.
1377 EnableResetReminderFeature (
1381 mFeaturerSwitch
= TRUE
;
1386 Disable the setup browser reset reminder feature.
1387 This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it.
1392 DisableResetReminderFeature (
1396 mFeaturerSwitch
= FALSE
;
1401 Record the info that a reset is required.
1402 A module boolean variable is used to record whether a reset is required.
1407 EnableResetRequired (
1411 mResetRequired
= TRUE
;
1416 Record the info that no reset is required.
1417 A module boolean variable is used to record whether a reset is required.
1422 DisableResetRequired (
1426 mResetRequired
= FALSE
;
1431 Check whether platform policy enable the reset reminder feature. The default is enabled.
1436 IsResetReminderFeatureEnable (
1440 return mFeaturerSwitch
;
1445 Check if user changed any option setting which needs a system reset to be effective.
1454 return mResetRequired
;
1459 Check whether a reset is needed, and finish the reset reminder feature.
1460 If a reset is needed, Popup a menu to notice user, and finish the feature
1461 according to the user selection.
1466 SetupResetReminder (
1471 CHAR16
*StringBuffer1
;
1472 CHAR16
*StringBuffer2
;
1476 //check any reset required change is applied? if yes, reset system
1478 if (IsResetReminderFeatureEnable ()) {
1479 if (IsResetRequired ()) {
1481 StringBuffer1
= AllocateZeroPool (MAX_STRING_LEN
* sizeof (CHAR16
));
1482 ASSERT (StringBuffer1
!= NULL
);
1483 StringBuffer2
= AllocateZeroPool (MAX_STRING_LEN
* sizeof (CHAR16
));
1484 ASSERT (StringBuffer2
!= NULL
);
1485 StrCpyS (StringBuffer1
, MAX_STRING_LEN
, L
"Configuration changed. Reset to apply it Now.");
1486 StrCpyS (StringBuffer2
, MAX_STRING_LEN
, L
"Press ENTER to reset");
1488 // Popup a menu to notice user
1491 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, StringBuffer1
, StringBuffer2
, NULL
);
1492 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1494 FreePool (StringBuffer1
);
1495 FreePool (StringBuffer2
);
1497 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);