2 FrontPage routines to handle the callbacks and browser calls
4 Copyright (c) 2004 - 2013, 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.
16 #include "FrontPage.h"
20 BOOLEAN mModeInitialized
= FALSE
;
22 BOOLEAN gConnectAllHappened
= FALSE
;
24 CHAR8
*mLanguageString
;
27 // Boot video resolution and text mode.
29 UINT32 mBootHorizontalResolution
= 0;
30 UINT32 mBootVerticalResolution
= 0;
31 UINT32 mBootTextModeColumn
= 0;
32 UINT32 mBootTextModeRow
= 0;
34 // BIOS setup video resolution and text mode.
36 UINT32 mSetupTextModeColumn
= 0;
37 UINT32 mSetupTextModeRow
= 0;
38 UINT32 mSetupHorizontalResolution
= 0;
39 UINT32 mSetupVerticalResolution
= 0;
41 EFI_FORM_BROWSER2_PROTOCOL
*gFormBrowser2
;
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)
65 FRONT_PAGE_FORMSET_GUID
69 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
71 (UINT8
) (END_DEVICE_PATH_LENGTH
),
72 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
78 This function allows a caller to extract the current configuration for one
79 or more named elements from the target driver.
82 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
83 @param Request A null-terminated Unicode string in <ConfigRequest> format.
84 @param Progress On return, points to a character in the Request string.
85 Points to the string's null terminator if request was successful.
86 Points to the most recent '&' before the first failing name/value
87 pair (or the beginning of the string if the failure is in the
88 first name/value pair) if the request was not successful.
89 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
90 has all values filled in for the names in the Request string.
91 String to be allocated by the called function.
93 @retval EFI_SUCCESS The Results is filled with the requested values.
94 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
95 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
96 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
102 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
103 IN CONST EFI_STRING Request
,
104 OUT EFI_STRING
*Progress
,
105 OUT EFI_STRING
*Results
108 if (Progress
== NULL
|| Results
== NULL
) {
109 return EFI_INVALID_PARAMETER
;
112 return EFI_NOT_FOUND
;
116 This function processes the results of changes in configuration.
119 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
120 @param Configuration A null-terminated Unicode string in <ConfigResp> format.
121 @param Progress A pointer to a string filled in with the offset of the most
122 recent '&' before the first failing name/value pair (or the
123 beginning of the string if the failure is in the first
124 name/value pair) or the terminating NULL if all was successful.
126 @retval EFI_SUCCESS The Results is processed successfully.
127 @retval EFI_INVALID_PARAMETER Configuration is NULL.
128 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
134 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
135 IN CONST EFI_STRING Configuration
,
136 OUT EFI_STRING
*Progress
139 if (Configuration
== NULL
|| Progress
== NULL
) {
140 return EFI_INVALID_PARAMETER
;
143 *Progress
= Configuration
;
144 if (!HiiIsConfigHdrMatch (Configuration
, &gBootMaintFormSetGuid
, mBootMaintStorageName
)
145 && !HiiIsConfigHdrMatch (Configuration
, &gFileExploreFormSetGuid
, mFileExplorerStorageName
)) {
146 return EFI_NOT_FOUND
;
149 *Progress
= Configuration
+ StrLen (Configuration
);
154 This function processes the results of changes in configuration.
157 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
158 @param Action Specifies the type of action taken by the browser.
159 @param QuestionId A unique value which is sent to the original exporting driver
160 so that it can identify the type of data to expect.
161 @param Type The type of value for the question.
162 @param Value A pointer to the data being sent to the original exporting driver.
163 @param ActionRequest On return, points to the action requested by the callback function.
165 @retval EFI_SUCCESS The callback successfully handled the action.
166 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
167 @retval EFI_DEVICE_ERROR The variable could not be saved.
168 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
174 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
175 IN EFI_BROWSER_ACTION Action
,
176 IN EFI_QUESTION_ID QuestionId
,
178 IN EFI_IFR_TYPE_VALUE
*Value
,
179 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
187 if (Action
!= EFI_BROWSER_ACTION_CHANGING
&& Action
!= EFI_BROWSER_ACTION_CHANGED
) {
189 // All other action return unsupported.
191 return EFI_UNSUPPORTED
;
194 gCallbackKey
= QuestionId
;
196 if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
197 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
198 return EFI_INVALID_PARAMETER
;
201 switch (QuestionId
) {
202 case FRONT_PAGE_KEY_CONTINUE
:
204 // This is the continue - clear the screen and return an error to get out of FrontPage loop
206 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
209 case FRONT_PAGE_KEY_LANGUAGE
:
211 // Allocate working buffer for RFC 4646 language in supported LanguageString.
213 Lang
= AllocatePool (AsciiStrSize (mLanguageString
));
214 ASSERT (Lang
!= NULL
);
217 LangCode
= mLanguageString
;
218 while (*LangCode
!= 0) {
219 GetNextLanguage (&LangCode
, Lang
);
221 if (Index
== Value
->u8
) {
228 if (Index
== Value
->u8
) {
229 Status
= gRT
->SetVariable (
231 &gEfiGlobalVariableGuid
,
232 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
236 ASSERT_EFI_ERROR(Status
);
241 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
249 } else if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
251 return EFI_INVALID_PARAMETER
;
255 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
256 // describe to their customers in documentation how to find their setup information (namely
257 // under the device manager and specific buckets)
259 switch (QuestionId
) {
260 case FRONT_PAGE_KEY_BOOT_MANAGER
:
266 case FRONT_PAGE_KEY_DEVICE_MANAGER
:
272 case FRONT_PAGE_KEY_BOOT_MAINTAIN
:
274 // Boot Maintenance Manager
288 Initialize HII information for the FrontPage
291 @param InitializeHiiData TRUE if HII elements need to be initialized.
293 @retval EFI_SUCCESS The operation is successful.
294 @retval EFI_DEVICE_ERROR If the dynamic opcode creation failed.
298 InitializeFrontPage (
299 IN BOOLEAN InitializeHiiData
307 CHAR16
*StringBuffer
;
308 EFI_HII_HANDLE HiiHandle
;
309 VOID
*OptionsOpCodeHandle
;
310 VOID
*StartOpCodeHandle
;
311 VOID
*EndOpCodeHandle
;
312 EFI_IFR_GUID_LABEL
*StartLabel
;
313 EFI_IFR_GUID_LABEL
*EndLabel
;
314 EFI_HII_STRING_PROTOCOL
*HiiString
;
320 if (InitializeHiiData
) {
322 // Initialize the Device Manager
324 InitializeDeviceManager ();
327 // Initialize the Device Manager
329 InitializeBootManager ();
334 // Locate Hii relative protocols
336 Status
= gBS
->LocateProtocol (&gEfiFormBrowser2ProtocolGuid
, NULL
, (VOID
**) &gFormBrowser2
);
337 if (EFI_ERROR (Status
)) {
342 // Install Device Path Protocol and Config Access protocol to driver handle
344 Status
= gBS
->InstallMultipleProtocolInterfaces (
345 &gFrontPagePrivate
.DriverHandle
,
346 &gEfiDevicePathProtocolGuid
,
347 &mFrontPageHiiVendorDevicePath
,
348 &gEfiHiiConfigAccessProtocolGuid
,
349 &gFrontPagePrivate
.ConfigAccess
,
352 ASSERT_EFI_ERROR (Status
);
355 // Publish our HII data
357 gFrontPagePrivate
.HiiHandle
= HiiAddPackages (
358 &gFrontPageFormSetGuid
,
359 gFrontPagePrivate
.DriverHandle
,
364 if (gFrontPagePrivate
.HiiHandle
== NULL
) {
365 return EFI_OUT_OF_RESOURCES
;
371 // Init OpCode Handle and Allocate space for creation of UpdateData Buffer
373 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
374 ASSERT (StartOpCodeHandle
!= NULL
);
376 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
377 ASSERT (EndOpCodeHandle
!= NULL
);
379 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
380 ASSERT (OptionsOpCodeHandle
!= NULL
);
382 // Create Hii Extend Label OpCode as the start opcode
384 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
385 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
386 StartLabel
->Number
= LABEL_SELECT_LANGUAGE
;
389 // Create Hii Extend Label OpCode as the end opcode
391 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
392 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
393 EndLabel
->Number
= LABEL_END
;
396 // Collect the languages from what our current Language support is based on our VFR
398 HiiHandle
= gFrontPagePrivate
.HiiHandle
;
400 CurrentLang
= GetEfiGlobalVariable (L
"PlatformLang");
403 // Get Support language list from variable.
405 if (mLanguageString
== NULL
){
406 mLanguageString
= GetEfiGlobalVariable (L
"PlatformLangCodes");
407 if (mLanguageString
== NULL
) {
408 mLanguageString
= AllocateCopyPool (
409 AsciiStrSize ((CHAR8
*) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes
)),
410 (CHAR8
*) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes
)
412 ASSERT (mLanguageString
!= NULL
);
416 if (gFrontPagePrivate
.LanguageToken
== NULL
) {
418 // Count the language list number.
420 LangCode
= mLanguageString
;
421 Lang
= AllocatePool (AsciiStrSize (mLanguageString
));
422 ASSERT (Lang
!= NULL
);
424 while (*LangCode
!= 0) {
425 GetNextLanguage (&LangCode
, Lang
);
430 // Allocate extra 1 as the end tag.
432 gFrontPagePrivate
.LanguageToken
= AllocateZeroPool ((OptionCount
+ 1) * sizeof (EFI_STRING_ID
));
433 ASSERT (gFrontPagePrivate
.LanguageToken
!= NULL
);
435 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &HiiString
);
436 ASSERT_EFI_ERROR (Status
);
438 LangCode
= mLanguageString
;
440 while (*LangCode
!= 0) {
441 GetNextLanguage (&LangCode
, Lang
);
444 Status
= HiiString
->GetString (HiiString
, Lang
, HiiHandle
, PRINTABLE_LANGUAGE_NAME_STRING_ID
, StringBuffer
, &StringSize
, NULL
);
445 if (Status
== EFI_BUFFER_TOO_SMALL
) {
446 StringBuffer
= AllocateZeroPool (StringSize
);
447 ASSERT (StringBuffer
!= NULL
);
448 Status
= HiiString
->GetString (HiiString
, Lang
, HiiHandle
, PRINTABLE_LANGUAGE_NAME_STRING_ID
, StringBuffer
, &StringSize
, NULL
);
449 ASSERT_EFI_ERROR (Status
);
452 if (EFI_ERROR (Status
)) {
453 StringBuffer
= AllocatePool (AsciiStrSize (Lang
) * sizeof (CHAR16
));
454 ASSERT (StringBuffer
!= NULL
);
455 AsciiStrToUnicodeStr (Lang
, StringBuffer
);
458 ASSERT (StringBuffer
!= NULL
);
459 gFrontPagePrivate
.LanguageToken
[OptionCount
] = HiiSetString (HiiHandle
, 0, StringBuffer
, NULL
);
460 FreePool (StringBuffer
);
466 ASSERT (gFrontPagePrivate
.LanguageToken
!= NULL
);
467 LangCode
= mLanguageString
;
470 Lang
= AllocatePool (AsciiStrSize (mLanguageString
));
471 ASSERT (Lang
!= NULL
);
473 while (*LangCode
!= 0) {
474 GetNextLanguage (&LangCode
, Lang
);
476 if (CurrentLang
!= NULL
&& AsciiStrCmp (Lang
, CurrentLang
) == 0) {
477 HiiCreateOneOfOptionOpCode (
479 gFrontPagePrivate
.LanguageToken
[OptionCount
],
480 EFI_IFR_OPTION_DEFAULT
,
481 EFI_IFR_NUMERIC_SIZE_1
,
485 HiiCreateOneOfOptionOpCode (
487 gFrontPagePrivate
.LanguageToken
[OptionCount
],
489 EFI_IFR_NUMERIC_SIZE_1
,
497 if (CurrentLang
!= NULL
) {
498 FreePool (CurrentLang
);
502 HiiCreateOneOfOpCode (
504 FRONT_PAGE_KEY_LANGUAGE
,
507 STRING_TOKEN (STR_LANGUAGE_SELECT
),
508 STRING_TOKEN (STR_LANGUAGE_SELECT_HELP
),
509 EFI_IFR_FLAG_CALLBACK
,
510 EFI_IFR_NUMERIC_SIZE_1
,
515 Status
= HiiUpdateForm (
517 &gFrontPageFormSetGuid
,
519 StartOpCodeHandle
, // LABEL_SELECT_LANGUAGE
520 EndOpCodeHandle
// LABEL_END
523 HiiFreeOpCodeHandle (StartOpCodeHandle
);
524 HiiFreeOpCodeHandle (EndOpCodeHandle
);
525 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
530 Call the browser and display the front page
532 @return Status code that will be returned by
533 EFI_FORM_BROWSER2_PROTOCOL.SendForm ().
542 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
545 // Begin waiting for USER INPUT
549 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_INPUT_WAIT
)
552 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
553 Status
= gFormBrowser2
->SendForm (
555 &gFrontPagePrivate
.HiiHandle
,
557 &gFrontPageFormSetGuid
,
563 // Check whether user change any option setting which needs a reset to be effective
565 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
566 EnableResetRequired ();
573 Acquire the string associated with the ProducerGuid and return it.
576 @param ProducerGuid The Guid to search the HII database for
577 @param Token The token value of the string to extract
578 @param String The string that is extracted
580 @retval EFI_SUCCESS The function returns EFI_SUCCESS always.
585 IN EFI_GUID
*ProducerGuid
,
586 IN EFI_STRING_ID Token
,
590 EFI_STRING TmpString
;
592 TmpString
= HiiGetPackageString (ProducerGuid
, Token
, NULL
);
593 if (TmpString
== NULL
) {
594 *String
= GetStringById (STRING_TOKEN (STR_MISSING_STRING
));
603 Convert Processor Frequency Data to a string.
605 @param ProcessorFrequency The frequency data to process
606 @param Base10Exponent The exponent based on 10
607 @param String The string that is created
611 ConvertProcessorToString (
612 IN UINT16 ProcessorFrequency
,
613 IN UINT16 Base10Exponent
,
617 CHAR16
*StringBuffer
;
621 if (Base10Exponent
>= 6) {
622 FreqMhz
= ProcessorFrequency
;
623 for (Index
= 0; Index
< (UINTN
) (Base10Exponent
- 6); Index
++) {
630 StringBuffer
= AllocateZeroPool (0x20);
631 ASSERT (StringBuffer
!= NULL
);
632 Index
= UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, FreqMhz
/ 1000, 3);
633 StrCat (StringBuffer
, L
".");
634 UnicodeValueToString (StringBuffer
+ Index
+ 1, PREFIX_ZERO
, (FreqMhz
% 1000) / 10, 2);
635 StrCat (StringBuffer
, L
" GHz");
636 *String
= (CHAR16
*) StringBuffer
;
642 Convert Memory Size to a string.
644 @param MemorySize The size of the memory to process
645 @param String The string that is created
649 ConvertMemorySizeToString (
650 IN UINT32 MemorySize
,
654 CHAR16
*StringBuffer
;
656 StringBuffer
= AllocateZeroPool (0x20);
657 ASSERT (StringBuffer
!= NULL
);
658 UnicodeValueToString (StringBuffer
, LEFT_JUSTIFY
, MemorySize
, 6);
659 StrCat (StringBuffer
, L
" MB RAM");
661 *String
= (CHAR16
*) StringBuffer
;
668 Acquire the string associated with the Index from smbios structure and return it.
669 The caller is responsible for free the string buffer.
671 @param OptionalStrStart The start position to search the string
672 @param Index The index of the string to extract
673 @param String The string that is extracted
675 @retval EFI_SUCCESS The function returns EFI_SUCCESS always.
679 GetOptionalStringByIndex (
680 IN CHAR8
*OptionalStrStart
,
688 *String
= AllocateZeroPool (sizeof (CHAR16
));
695 OptionalStrStart
+= StrSize
;
696 StrSize
= AsciiStrSize (OptionalStrStart
);
697 } while (OptionalStrStart
[StrSize
] != 0 && Index
!= 0);
699 if ((Index
!= 0) || (StrSize
== 1)) {
701 // Meet the end of strings set but Index is non-zero, or
702 // Find an empty string
704 *String
= GetStringById (STRING_TOKEN (STR_MISSING_STRING
));
706 *String
= AllocatePool (StrSize
* sizeof (CHAR16
));
707 AsciiStrToUnicodeStr (OptionalStrStart
, *String
);
715 Update the banner information for the Front Page based on DataHub information.
719 UpdateFrontPageStrings (
727 EFI_STRING_ID TokenToUpdate
;
728 EFI_SMBIOS_HANDLE SmbiosHandle
;
729 EFI_SMBIOS_PROTOCOL
*Smbios
;
730 SMBIOS_TABLE_TYPE0
*Type0Record
;
731 SMBIOS_TABLE_TYPE1
*Type1Record
;
732 SMBIOS_TABLE_TYPE4
*Type4Record
;
733 SMBIOS_TABLE_TYPE19
*Type19Record
;
734 EFI_SMBIOS_TABLE_HEADER
*Record
;
736 ZeroMem (Find
, sizeof (Find
));
739 // Update Front Page strings
741 Status
= gBS
->LocateProtocol (
742 &gEfiSmbiosProtocolGuid
,
746 ASSERT_EFI_ERROR (Status
);
748 SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
750 Status
= Smbios
->GetNext (Smbios
, &SmbiosHandle
, NULL
, &Record
, NULL
);
751 if (EFI_ERROR(Status
)) {
755 if (Record
->Type
== EFI_SMBIOS_TYPE_BIOS_INFORMATION
) {
756 Type0Record
= (SMBIOS_TABLE_TYPE0
*) Record
;
757 StrIndex
= Type0Record
->BiosVersion
;
758 GetOptionalStringByIndex ((CHAR8
*)((UINT8
*)Type0Record
+ Type0Record
->Hdr
.Length
), StrIndex
, &NewString
);
759 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION
);
760 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
761 FreePool (NewString
);
765 if (Record
->Type
== EFI_SMBIOS_TYPE_SYSTEM_INFORMATION
) {
766 Type1Record
= (SMBIOS_TABLE_TYPE1
*) Record
;
767 StrIndex
= Type1Record
->ProductName
;
768 GetOptionalStringByIndex ((CHAR8
*)((UINT8
*)Type1Record
+ Type1Record
->Hdr
.Length
), StrIndex
, &NewString
);
769 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL
);
770 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
771 FreePool (NewString
);
775 if (Record
->Type
== EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION
) {
776 Type4Record
= (SMBIOS_TABLE_TYPE4
*) Record
;
777 StrIndex
= Type4Record
->ProcessorVersion
;
778 GetOptionalStringByIndex ((CHAR8
*)((UINT8
*)Type4Record
+ Type4Record
->Hdr
.Length
), StrIndex
, &NewString
);
779 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL
);
780 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
781 FreePool (NewString
);
785 if (Record
->Type
== EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION
) {
786 Type4Record
= (SMBIOS_TABLE_TYPE4
*) Record
;
787 ConvertProcessorToString(Type4Record
->CurrentSpeed
, 6, &NewString
);
788 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED
);
789 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
790 FreePool (NewString
);
794 if ( Record
->Type
== EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS
) {
795 Type19Record
= (SMBIOS_TABLE_TYPE19
*) Record
;
796 ConvertMemorySizeToString (
797 (UINT32
)(RShiftU64((Type19Record
->EndingAddress
- Type19Record
->StartingAddress
+ 1), 10)),
800 TokenToUpdate
= STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE
);
801 HiiSetString (gFrontPagePrivate
.HiiHandle
, TokenToUpdate
, NewString
, NULL
);
802 FreePool (NewString
);
805 } while ( !(Find
[0] && Find
[1] && Find
[2] && Find
[3] && Find
[4]));
811 Function waits for a given event to fire, or for an optional timeout to expire.
813 @param Event The event to wait for
814 @param Timeout An optional timeout value in 100 ns units.
816 @retval EFI_SUCCESS Event fired before Timeout expired.
817 @retval EFI_TIME_OUT Timout expired before Event fired..
823 IN UINT64 Timeout OPTIONAL
828 EFI_EVENT TimerEvent
;
829 EFI_EVENT WaitList
[2];
833 // Create a timer event
835 Status
= gBS
->CreateEvent (EVT_TIMER
, 0, NULL
, NULL
, &TimerEvent
);
836 if (!EFI_ERROR (Status
)) {
838 // Set the timer event
847 // Wait for the original event or the timer
850 WaitList
[1] = TimerEvent
;
851 Status
= gBS
->WaitForEvent (2, WaitList
, &Index
);
852 gBS
->CloseEvent (TimerEvent
);
855 // If the timer expired, change the return to timed out
857 if (!EFI_ERROR (Status
) && Index
== 1) {
858 Status
= EFI_TIMEOUT
;
863 // No timeout... just wait on the event
865 Status
= gBS
->WaitForEvent (1, &Event
, &Index
);
866 ASSERT (!EFI_ERROR (Status
));
874 Function show progress bar to wait for user input.
877 @param TimeoutDefault The fault time out value before the system continue to boot.
879 @retval EFI_SUCCESS User pressed some key except "Enter"
880 @retval EFI_TIME_OUT Timeout expired or user press "Enter"
885 IN UINT16 TimeoutDefault
889 UINT16 TimeoutRemain
;
892 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
893 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
894 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
896 if (TimeoutDefault
== 0) {
900 DEBUG ((EFI_D_INFO
, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));
902 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
903 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
904 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
906 TmpStr
= GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION
));
908 if (!FeaturePcdGet(PcdBootlogoOnlyEnable
)) {
910 // Clear the progress status bar first
912 if (TmpStr
!= NULL
) {
913 PlatformBdsShowProgress (Foreground
, Background
, TmpStr
, Color
, 0, 0);
918 TimeoutRemain
= TimeoutDefault
;
919 while (TimeoutRemain
!= 0) {
920 DEBUG ((EFI_D_INFO
, "Showing progress bar...Remaining %d second!\n", TimeoutRemain
));
922 Status
= WaitForSingleEvent (gST
->ConIn
->WaitForKey
, ONE_SECOND
);
923 if (Status
!= EFI_TIMEOUT
) {
928 if (!FeaturePcdGet(PcdBootlogoOnlyEnable
)) {
932 if (TmpStr
!= NULL
) {
933 PlatformBdsShowProgress (
938 ((TimeoutDefault
- TimeoutRemain
) * 100 / TimeoutDefault
),
945 if (TmpStr
!= NULL
) {
946 gBS
->FreePool (TmpStr
);
952 if (TimeoutRemain
== 0) {
957 // User pressed some key
959 if (!PcdGetBool (PcdConInConnectOnDemand
)) {
960 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
961 if (EFI_ERROR (Status
)) {
965 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
967 // User pressed enter, equivalent to select "continue"
977 This function is the main entry of the platform setup entry.
978 The function will present the main menu of the system setup,
979 this is the platform reference part and can be customize.
982 @param TimeoutDefault The fault time out value before the system
984 @param ConnectAllHappened The indicater to check if the connect all have
989 PlatformBdsEnterFrontPage (
990 IN UINT16 TimeoutDefault
,
991 IN BOOLEAN ConnectAllHappened
995 EFI_STATUS StatusHotkey
;
996 EFI_BOOT_LOGO_PROTOCOL
*BootLogo
;
997 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
998 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
999 UINTN BootTextColumn
;
1001 UINT64 OsIndication
;
1005 GraphicsOutput
= NULL
;
1006 SimpleTextOut
= NULL
;
1008 PERF_START (NULL
, "BdsTimeOut", "BDS", 0);
1010 // Indicate if we need connect all in the platform setup
1012 if (ConnectAllHappened
) {
1013 gConnectAllHappened
= TRUE
;
1016 if (!mModeInitialized
) {
1018 // After the console is ready, get current video resolution
1019 // and text mode before launching setup at first time.
1021 Status
= gBS
->HandleProtocol (
1022 gST
->ConsoleOutHandle
,
1023 &gEfiGraphicsOutputProtocolGuid
,
1024 (VOID
**)&GraphicsOutput
1026 if (EFI_ERROR (Status
)) {
1027 GraphicsOutput
= NULL
;
1030 Status
= gBS
->HandleProtocol (
1031 gST
->ConsoleOutHandle
,
1032 &gEfiSimpleTextOutProtocolGuid
,
1033 (VOID
**)&SimpleTextOut
1035 if (EFI_ERROR (Status
)) {
1036 SimpleTextOut
= NULL
;
1039 if (GraphicsOutput
!= NULL
) {
1041 // Get current video resolution and text mode.
1043 mBootHorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
1044 mBootVerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
1047 if (SimpleTextOut
!= NULL
) {
1048 Status
= SimpleTextOut
->QueryMode (
1050 SimpleTextOut
->Mode
->Mode
,
1054 mBootTextModeColumn
= (UINT32
)BootTextColumn
;
1055 mBootTextModeRow
= (UINT32
)BootTextRow
;
1059 // Get user defined text mode for setup.
1061 mSetupHorizontalResolution
= PcdGet32 (PcdSetupVideoHorizontalResolution
);
1062 mSetupVerticalResolution
= PcdGet32 (PcdSetupVideoVerticalResolution
);
1063 mSetupTextModeColumn
= PcdGet32 (PcdSetupConOutColumn
);
1064 mSetupTextModeRow
= PcdGet32 (PcdSetupConOutRow
);
1066 mModeInitialized
= TRUE
;
1071 // goto FrontPage directly when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set
1074 DataSize
= sizeof(UINT64
);
1075 Status
= gRT
->GetVariable (
1077 &gEfiGlobalVariableGuid
,
1084 // goto FrontPage directly when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot
1086 if (!EFI_ERROR(Status
) && ((OsIndication
& EFI_OS_INDICATIONS_BOOT_TO_FW_UI
) != 0)) {
1088 // Clear EFI_OS_INDICATIONS_BOOT_TO_FW_UI to acknowledge OS
1090 OsIndication
&= ~EFI_OS_INDICATIONS_BOOT_TO_FW_UI
;
1091 Status
= gRT
->SetVariable (
1093 &gEfiGlobalVariableGuid
,
1094 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1098 ASSERT_EFI_ERROR (Status
);
1101 // Follow generic rule, Call ReadKeyStroke to connect ConIn before enter UI
1103 if (PcdGetBool (PcdConInConnectOnDemand
)) {
1104 gST
->ConIn
->ReadKeyStroke(gST
->ConIn
, &Key
);
1108 // Ensure screen is clear when switch Console from Graphics mode to Text mode
1110 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
1111 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1116 if (TimeoutDefault
!= 0xffff) {
1117 Status
= ShowProgress (TimeoutDefault
);
1118 StatusHotkey
= HotkeyBoot ();
1120 if (!FeaturePcdGet(PcdBootlogoOnlyEnable
) || !EFI_ERROR(Status
) || !EFI_ERROR(StatusHotkey
)){
1122 // Ensure screen is clear when switch Console from Graphics mode to Text mode
1123 // Skip it in normal boot
1125 gST
->ConOut
->EnableCursor (gST
->ConOut
, TRUE
);
1126 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1129 if (EFI_ERROR (Status
)) {
1131 // Timeout or user press enter to continue
1139 // Boot Logo is corrupted, report it using Boot Logo protocol.
1141 Status
= gBS
->LocateProtocol (&gEfiBootLogoProtocolGuid
, NULL
, (VOID
**) &BootLogo
);
1142 if (!EFI_ERROR (Status
) && (BootLogo
!= NULL
)) {
1143 BootLogo
->SetBootLogo (BootLogo
, NULL
, 0, 0, 0, 0);
1146 Status
= EFI_SUCCESS
;
1149 // Set proper video resolution and text mode for setup
1151 BdsSetConsoleMode (TRUE
);
1153 InitializeFrontPage (FALSE
);
1156 // Update Front Page strings
1158 UpdateFrontPageStrings ();
1164 // If gCallbackKey is greater than 1 and less or equal to 5,
1165 // it will launch configuration utilities.
1168 // 4 = device manager
1169 // 5 = boot maintenance manager
1171 if (gCallbackKey
!= 0) {
1172 REPORT_STATUS_CODE (
1174 (EFI_SOFTWARE_DXE_BS_DRIVER
| EFI_SW_PC_USER_SETUP
)
1178 // Based on the key that was set, we can determine what to do
1180 switch (gCallbackKey
) {
1182 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
1183 // describe to their customers in documentation how to find their setup information (namely
1184 // under the device manager and specific buckets)
1186 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
1188 case FRONT_PAGE_KEY_CONTINUE
:
1190 // User hit continue
1194 case FRONT_PAGE_KEY_LANGUAGE
:
1196 // User made a language setting change - display front page again
1200 case FRONT_PAGE_KEY_BOOT_MANAGER
:
1202 // User chose to run the Boot Manager
1207 case FRONT_PAGE_KEY_DEVICE_MANAGER
:
1209 // Display the Device Manager
1212 CallDeviceManager ();
1213 } while (gCallbackKey
== FRONT_PAGE_KEY_DEVICE_MANAGER
);
1216 case FRONT_PAGE_KEY_BOOT_MAINTAIN
:
1218 // Display the Boot Maintenance Manager
1220 BdsStartBootMaint ();
1224 } while ((Status
== EFI_SUCCESS
) && (gCallbackKey
!= FRONT_PAGE_KEY_CONTINUE
));
1226 if (mLanguageString
!= NULL
) {
1227 FreePool (mLanguageString
);
1228 mLanguageString
= NULL
;
1231 //Will leave browser, check any reset required change is applied? if yes, reset system
1233 SetupResetReminder ();
1237 // Automatically load current entry
1238 // Note: The following lines of code only execute when Auto boot
1241 PERF_END (NULL
, "BdsTimeOut", "BDS", 0);
1245 This function will change video resolution and text mode
1246 according to defined setup mode or defined boot mode
1248 @param IsSetupMode Indicate mode is changed to setup mode or boot mode.
1250 @retval EFI_SUCCESS Mode is changed successfully.
1251 @retval Others Mode failed to be changed.
1260 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1261 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOut
;
1263 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
1267 UINT32 NewHorizontalResolution
;
1268 UINT32 NewVerticalResolution
;
1272 EFI_HANDLE
*HandleBuffer
;
1275 UINTN CurrentColumn
;
1282 // Get current video resolution and text mode
1284 Status
= gBS
->HandleProtocol (
1285 gST
->ConsoleOutHandle
,
1286 &gEfiGraphicsOutputProtocolGuid
,
1287 (VOID
**)&GraphicsOutput
1289 if (EFI_ERROR (Status
)) {
1290 GraphicsOutput
= NULL
;
1293 Status
= gBS
->HandleProtocol (
1294 gST
->ConsoleOutHandle
,
1295 &gEfiSimpleTextOutProtocolGuid
,
1296 (VOID
**)&SimpleTextOut
1298 if (EFI_ERROR (Status
)) {
1299 SimpleTextOut
= NULL
;
1302 if ((GraphicsOutput
== NULL
) || (SimpleTextOut
== NULL
)) {
1303 return EFI_UNSUPPORTED
;
1308 // The requried resolution and text mode is setup mode.
1310 NewHorizontalResolution
= mSetupHorizontalResolution
;
1311 NewVerticalResolution
= mSetupVerticalResolution
;
1312 NewColumns
= mSetupTextModeColumn
;
1313 NewRows
= mSetupTextModeRow
;
1316 // The required resolution and text mode is boot mode.
1318 NewHorizontalResolution
= mBootHorizontalResolution
;
1319 NewVerticalResolution
= mBootVerticalResolution
;
1320 NewColumns
= mBootTextModeColumn
;
1321 NewRows
= mBootTextModeRow
;
1324 if (GraphicsOutput
!= NULL
) {
1325 MaxGopMode
= GraphicsOutput
->Mode
->MaxMode
;
1328 if (SimpleTextOut
!= NULL
) {
1329 MaxTextMode
= SimpleTextOut
->Mode
->MaxMode
;
1333 // 1. If current video resolution is same with required video resolution,
1334 // video resolution need not be changed.
1335 // 1.1. If current text mode is same with required text mode, text mode need not be changed.
1336 // 1.2. If current text mode is different from required text mode, text mode need be changed.
1337 // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.
1339 for (ModeNumber
= 0; ModeNumber
< MaxGopMode
; ModeNumber
++) {
1340 Status
= GraphicsOutput
->QueryMode (
1346 if (!EFI_ERROR (Status
)) {
1347 if ((Info
->HorizontalResolution
== NewHorizontalResolution
) &&
1348 (Info
->VerticalResolution
== NewVerticalResolution
)) {
1349 if ((GraphicsOutput
->Mode
->Info
->HorizontalResolution
== NewHorizontalResolution
) &&
1350 (GraphicsOutput
->Mode
->Info
->VerticalResolution
== NewVerticalResolution
)) {
1352 // Current resolution is same with required resolution, check if text mode need be set
1354 Status
= SimpleTextOut
->QueryMode (SimpleTextOut
, SimpleTextOut
->Mode
->Mode
, &CurrentColumn
, &CurrentRow
);
1355 ASSERT_EFI_ERROR (Status
);
1356 if (CurrentColumn
== NewColumns
&& CurrentRow
== NewRows
) {
1358 // If current text mode is same with required text mode. Do nothing
1364 // If current text mode is different from requried text mode. Set new video mode
1366 for (Index
= 0; Index
< MaxTextMode
; Index
++) {
1367 Status
= SimpleTextOut
->QueryMode (SimpleTextOut
, Index
, &CurrentColumn
, &CurrentRow
);
1368 if (!EFI_ERROR(Status
)) {
1369 if ((CurrentColumn
== NewColumns
) && (CurrentRow
== NewRows
)) {
1371 // Required text mode is supported, set it.
1373 Status
= SimpleTextOut
->SetMode (SimpleTextOut
, Index
);
1374 ASSERT_EFI_ERROR (Status
);
1376 // Update text mode PCD.
1378 PcdSet32 (PcdConOutColumn
, mSetupTextModeColumn
);
1379 PcdSet32 (PcdConOutRow
, mSetupTextModeRow
);
1385 if (Index
== MaxTextMode
) {
1387 // If requried text mode is not supported, return error.
1390 return EFI_UNSUPPORTED
;
1395 // If current video resolution is not same with the new one, set new video resolution.
1396 // In this case, the driver which produces simple text out need be restarted.
1398 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, ModeNumber
);
1399 if (!EFI_ERROR (Status
)) {
1409 if (ModeNumber
== MaxGopMode
) {
1411 // If the resolution is not supported, return error.
1413 return EFI_UNSUPPORTED
;
1417 // Set PCD to Inform GraphicsConsole to change video resolution.
1418 // Set PCD to Inform Consplitter to change text mode.
1420 PcdSet32 (PcdVideoHorizontalResolution
, NewHorizontalResolution
);
1421 PcdSet32 (PcdVideoVerticalResolution
, NewVerticalResolution
);
1422 PcdSet32 (PcdConOutColumn
, NewColumns
);
1423 PcdSet32 (PcdConOutRow
, NewRows
);
1427 // Video mode is changed, so restart graphics console driver and higher level driver.
1428 // Reconnect graphics console driver and higher level driver.
1429 // Locate all the handles with GOP protocol and reconnect it.
1431 Status
= gBS
->LocateHandleBuffer (
1433 &gEfiSimpleTextOutProtocolGuid
,
1438 if (!EFI_ERROR (Status
)) {
1439 for (Index
= 0; Index
< HandleCount
; Index
++) {
1440 gBS
->DisconnectController (HandleBuffer
[Index
], NULL
, NULL
);
1442 for (Index
= 0; Index
< HandleCount
; Index
++) {
1443 gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
1445 if (HandleBuffer
!= NULL
) {
1446 FreePool (HandleBuffer
);