+++ /dev/null
-/** @file\r
- FrontPage routines to handle the callbacks and browser calls\r
-\r
-Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "Bds.h"\r
-#include "FrontPage.h"\r
-#include "Language.h"\r
-#include "Hotkey.h"\r
-\r
-BOOLEAN mModeInitialized = FALSE;\r
-\r
-BOOLEAN gConnectAllHappened = FALSE;\r
-UINTN gCallbackKey;\r
-CHAR8 *mLanguageString;\r
-\r
-//\r
-// Boot video resolution and text mode.\r
-//\r
-UINT32 mBootHorizontalResolution = 0;\r
-UINT32 mBootVerticalResolution = 0;\r
-UINT32 mBootTextModeColumn = 0;\r
-UINT32 mBootTextModeRow = 0;\r
-//\r
-// BIOS setup video resolution and text mode.\r
-//\r
-UINT32 mSetupTextModeColumn = 0;\r
-UINT32 mSetupTextModeRow = 0;\r
-UINT32 mSetupHorizontalResolution = 0;\r
-UINT32 mSetupVerticalResolution = 0;\r
-\r
-EFI_FORM_BROWSER2_PROTOCOL *gFormBrowser2;\r
-\r
-FRONT_PAGE_CALLBACK_DATA gFrontPagePrivate = {\r
- FRONT_PAGE_CALLBACK_DATA_SIGNATURE,\r
- NULL,\r
- NULL,\r
- NULL,\r
- {\r
- FakeExtractConfig,\r
- FakeRouteConfig,\r
- FrontPageCallback\r
- }\r
-};\r
-\r
-HII_VENDOR_DEVICE_PATH mFrontPageHiiVendorDevicePath = {\r
- {\r
- {\r
- HARDWARE_DEVICE_PATH,\r
- HW_VENDOR_DP,\r
- {\r
- (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
- (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
- }\r
- },\r
- FRONT_PAGE_FORMSET_GUID\r
- },\r
- {\r
- END_DEVICE_PATH_TYPE,\r
- END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
- {\r
- (UINT8) (END_DEVICE_PATH_LENGTH),\r
- (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
- }\r
- }\r
-};\r
-\r
-/**\r
- This function allows a caller to extract the current configuration for one\r
- or more named elements from the target driver.\r
-\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
- @param Progress On return, points to a character in the Request string.\r
- Points to the string's null terminator if request was successful.\r
- Points to the most recent '&' before the first failing name/value\r
- pair (or the beginning of the string if the failure is in the\r
- first name/value pair) if the request was not successful.\r
- @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
- has all values filled in for the names in the Request string.\r
- String to be allocated by the called function.\r
-\r
- @retval EFI_SUCCESS The Results is filled with the requested values.\r
- @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
- @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FakeExtractConfig (\r
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- IN CONST EFI_STRING Request,\r
- OUT EFI_STRING *Progress,\r
- OUT EFI_STRING *Results\r
- )\r
-{\r
- if (Progress == NULL || Results == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- *Progress = Request;\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
- This function processes the results of changes in configuration.\r
-\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Configuration A null-terminated Unicode string in <ConfigResp> format.\r
- @param Progress A pointer to a string filled in with the offset of the most\r
- recent '&' before the first failing name/value pair (or the\r
- beginning of the string if the failure is in the first\r
- name/value pair) or the terminating NULL if all was successful.\r
-\r
- @retval EFI_SUCCESS The Results is processed successfully.\r
- @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FakeRouteConfig (\r
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- IN CONST EFI_STRING Configuration,\r
- OUT EFI_STRING *Progress\r
- )\r
-{\r
- if (Configuration == NULL || Progress == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *Progress = Configuration;\r
- if (!HiiIsConfigHdrMatch (Configuration, &gBootMaintFormSetGuid, mBootMaintStorageName)\r
- && !HiiIsConfigHdrMatch (Configuration, &gFileExploreFormSetGuid, mFileExplorerStorageName)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- *Progress = Configuration + StrLen (Configuration);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function processes the results of changes in configuration.\r
-\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Action Specifies the type of action taken by the browser.\r
- @param QuestionId A unique value which is sent to the original exporting driver\r
- so that it can identify the type of data to expect.\r
- @param Type The type of value for the question.\r
- @param Value A pointer to the data being sent to the original exporting driver.\r
- @param ActionRequest On return, points to the action requested by the callback function.\r
-\r
- @retval EFI_SUCCESS The callback successfully handled the action.\r
- @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
- @retval EFI_DEVICE_ERROR The variable could not be saved.\r
- @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FrontPageCallback (\r
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- IN EFI_BROWSER_ACTION Action,\r
- IN EFI_QUESTION_ID QuestionId,\r
- IN UINT8 Type,\r
- IN EFI_IFR_TYPE_VALUE *Value,\r
- OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
- )\r
-{\r
- CHAR8 *LangCode;\r
- CHAR8 *Lang;\r
- UINTN Index;\r
-\r
- if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {\r
- //\r
- // All other action return unsupported.\r
- //\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- gCallbackKey = QuestionId;\r
-\r
- if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
- if ((Value == NULL) || (ActionRequest == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- switch (QuestionId) {\r
- case FRONT_PAGE_KEY_CONTINUE:\r
- //\r
- // This is the continue - clear the screen and return an error to get out of FrontPage loop\r
- //\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
- break;\r
-\r
- case FRONT_PAGE_KEY_LANGUAGE:\r
- //\r
- // Allocate working buffer for RFC 4646 language in supported LanguageString.\r
- //\r
- Lang = AllocatePool (AsciiStrSize (mLanguageString));\r
- ASSERT (Lang != NULL);\r
-\r
- Index = 0;\r
- LangCode = mLanguageString;\r
- while (*LangCode != 0) {\r
- GetNextLanguage (&LangCode, Lang);\r
-\r
- if (Index == Value->u8) {\r
- break;\r
- }\r
-\r
- Index++;\r
- }\r
-\r
- if (Index == Value->u8) {\r
- BdsDxeSetVariableAndReportStatusCodeOnError (\r
- L"PlatformLang",\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- AsciiStrSize (Lang),\r
- Lang\r
- );\r
- } else {\r
- ASSERT (FALSE);\r
- }\r
-\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
-\r
- FreePool (Lang);\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- } else if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
- if (Value == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can\r
- // describe to their customers in documentation how to find their setup information (namely\r
- // under the device manager and specific buckets)\r
- //\r
- switch (QuestionId) {\r
- case FRONT_PAGE_KEY_BOOT_MANAGER:\r
- //\r
- // Boot Manager\r
- //\r
- break;\r
-\r
- case FRONT_PAGE_KEY_DEVICE_MANAGER:\r
- //\r
- // Device Manager\r
- //\r
- break;\r
-\r
- case FRONT_PAGE_KEY_BOOT_MAINTAIN:\r
- //\r
- // Boot Maintenance Manager\r
- //\r
- break;\r
-\r
- default:\r
- gCallbackKey = 0;\r
- break;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Initialize HII information for the FrontPage\r
-\r
-\r
- @param InitializeHiiData TRUE if HII elements need to be initialized.\r
-\r
- @retval EFI_SUCCESS The operation is successful.\r
- @retval EFI_DEVICE_ERROR If the dynamic opcode creation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-InitializeFrontPage (\r
- IN BOOLEAN InitializeHiiData\r
- )\r
-{\r
- EFI_STATUS Status;\r
- CHAR8 *LangCode;\r
- CHAR8 *Lang;\r
- UINTN LangSize;\r
- CHAR8 *CurrentLang;\r
- UINTN OptionCount;\r
- CHAR16 *StringBuffer;\r
- EFI_HII_HANDLE HiiHandle;\r
- VOID *OptionsOpCodeHandle;\r
- VOID *StartOpCodeHandle;\r
- VOID *EndOpCodeHandle;\r
- EFI_IFR_GUID_LABEL *StartLabel;\r
- EFI_IFR_GUID_LABEL *EndLabel;\r
- EFI_HII_STRING_PROTOCOL *HiiString;\r
- UINTN StringSize;\r
-\r
- Lang = NULL;\r
- StringBuffer = NULL;\r
-\r
- if (InitializeHiiData) {\r
- //\r
- // Initialize the Device Manager\r
- //\r
- InitializeDeviceManager ();\r
-\r
- //\r
- // Initialize the Device Manager\r
- //\r
- InitializeBootManager ();\r
-\r
- gCallbackKey = 0;\r
-\r
- //\r
- // Locate Hii relative protocols\r
- //\r
- Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFormBrowser2);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Install Device Path Protocol and Config Access protocol to driver handle\r
- //\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &gFrontPagePrivate.DriverHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- &mFrontPageHiiVendorDevicePath,\r
- &gEfiHiiConfigAccessProtocolGuid,\r
- &gFrontPagePrivate.ConfigAccess,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Publish our HII data\r
- //\r
- gFrontPagePrivate.HiiHandle = HiiAddPackages (\r
- &gFrontPageFormSetGuid,\r
- gFrontPagePrivate.DriverHandle,\r
- FrontPageVfrBin,\r
- BdsDxeStrings,\r
- NULL\r
- );\r
- if (gFrontPagePrivate.HiiHandle == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
-\r
-\r
- //\r
- // Init OpCode Handle and Allocate space for creation of UpdateData Buffer\r
- //\r
- StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (StartOpCodeHandle != NULL);\r
-\r
- EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (EndOpCodeHandle != NULL);\r
-\r
- OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (OptionsOpCodeHandle != NULL);\r
- //\r
- // Create Hii Extend Label OpCode as the start opcode\r
- //\r
- StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
- StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
- StartLabel->Number = LABEL_SELECT_LANGUAGE;\r
-\r
- //\r
- // Create Hii Extend Label OpCode as the end opcode\r
- //\r
- EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
- EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
- EndLabel->Number = LABEL_END;\r
-\r
- //\r
- // Collect the languages from what our current Language support is based on our VFR\r
- //\r
- HiiHandle = gFrontPagePrivate.HiiHandle;\r
-\r
- GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLang, NULL);\r
-\r
- //\r
- // Get Support language list from variable.\r
- //\r
- if (mLanguageString == NULL){\r
- GetEfiGlobalVariable2 (L"PlatformLangCodes", (VOID**)&mLanguageString, NULL);\r
- if (mLanguageString == NULL) {\r
- mLanguageString = AllocateCopyPool (\r
- AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)),\r
- (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)\r
- );\r
- ASSERT (mLanguageString != NULL);\r
- }\r
- }\r
-\r
- if (gFrontPagePrivate.LanguageToken == NULL) {\r
- //\r
- // Count the language list number.\r
- //\r
- LangCode = mLanguageString;\r
- Lang = AllocatePool (AsciiStrSize (mLanguageString));\r
- ASSERT (Lang != NULL);\r
- OptionCount = 0;\r
- while (*LangCode != 0) {\r
- GetNextLanguage (&LangCode, Lang);\r
- OptionCount ++;\r
- }\r
-\r
- //\r
- // Allocate extra 1 as the end tag.\r
- //\r
- gFrontPagePrivate.LanguageToken = AllocateZeroPool ((OptionCount + 1) * sizeof (EFI_STRING_ID));\r
- ASSERT (gFrontPagePrivate.LanguageToken != NULL);\r
-\r
- Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- LangCode = mLanguageString;\r
- OptionCount = 0;\r
- while (*LangCode != 0) {\r
- GetNextLanguage (&LangCode, Lang);\r
-\r
- StringSize = 0;\r
- Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- StringBuffer = AllocateZeroPool (StringSize);\r
- ASSERT (StringBuffer != NULL);\r
- Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- LangSize = AsciiStrSize (Lang);\r
- StringBuffer = AllocatePool (LangSize * sizeof (CHAR16));\r
- ASSERT (StringBuffer != NULL);\r
- AsciiStrToUnicodeStrS (Lang, StringBuffer, LangSize);\r
- }\r
-\r
- ASSERT (StringBuffer != NULL);\r
- gFrontPagePrivate.LanguageToken[OptionCount] = HiiSetString (HiiHandle, 0, StringBuffer, NULL);\r
- FreePool (StringBuffer);\r
-\r
- OptionCount++;\r
- }\r
- }\r
-\r
- ASSERT (gFrontPagePrivate.LanguageToken != NULL);\r
- LangCode = mLanguageString;\r
- OptionCount = 0;\r
- if (Lang == NULL) {\r
- Lang = AllocatePool (AsciiStrSize (mLanguageString));\r
- ASSERT (Lang != NULL);\r
- }\r
- while (*LangCode != 0) {\r
- GetNextLanguage (&LangCode, Lang);\r
-\r
- if (CurrentLang != NULL && AsciiStrCmp (Lang, CurrentLang) == 0) {\r
- HiiCreateOneOfOptionOpCode (\r
- OptionsOpCodeHandle,\r
- gFrontPagePrivate.LanguageToken[OptionCount],\r
- EFI_IFR_OPTION_DEFAULT,\r
- EFI_IFR_NUMERIC_SIZE_1,\r
- (UINT8) OptionCount\r
- );\r
- } else {\r
- HiiCreateOneOfOptionOpCode (\r
- OptionsOpCodeHandle,\r
- gFrontPagePrivate.LanguageToken[OptionCount],\r
- 0,\r
- EFI_IFR_NUMERIC_SIZE_1,\r
- (UINT8) OptionCount\r
- );\r
- }\r
-\r
- OptionCount++;\r
- }\r
-\r
- if (CurrentLang != NULL) {\r
- FreePool (CurrentLang);\r
- }\r
- FreePool (Lang);\r
-\r
- HiiCreateOneOfOpCode (\r
- StartOpCodeHandle,\r
- FRONT_PAGE_KEY_LANGUAGE,\r
- 0,\r
- 0,\r
- STRING_TOKEN (STR_LANGUAGE_SELECT),\r
- STRING_TOKEN (STR_LANGUAGE_SELECT_HELP),\r
- EFI_IFR_FLAG_CALLBACK,\r
- EFI_IFR_NUMERIC_SIZE_1,\r
- OptionsOpCodeHandle,\r
- NULL\r
- );\r
-\r
- Status = HiiUpdateForm (\r
- HiiHandle,\r
- &gFrontPageFormSetGuid,\r
- FRONT_PAGE_FORM_ID,\r
- StartOpCodeHandle, // LABEL_SELECT_LANGUAGE\r
- EndOpCodeHandle // LABEL_END\r
- );\r
-\r
- HiiFreeOpCodeHandle (StartOpCodeHandle);\r
- HiiFreeOpCodeHandle (EndOpCodeHandle);\r
- HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
- return Status;\r
-}\r
-\r
-/**\r
- Call the browser and display the front page\r
-\r
- @return Status code that will be returned by\r
- EFI_FORM_BROWSER2_PROTOCOL.SendForm ().\r
-\r
-**/\r
-EFI_STATUS\r
-CallFrontPage (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
-\r
- //\r
- // Begin waiting for USER INPUT\r
- //\r
- REPORT_STATUS_CODE (\r
- EFI_PROGRESS_CODE,\r
- (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)\r
- );\r
-\r
- ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
- Status = gFormBrowser2->SendForm (\r
- gFormBrowser2,\r
- &gFrontPagePrivate.HiiHandle,\r
- 1,\r
- &gFrontPageFormSetGuid,\r
- 0,\r
- NULL,\r
- &ActionRequest\r
- );\r
- //\r
- // Check whether user change any option setting which needs a reset to be effective\r
- //\r
- if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
- EnableResetRequired ();\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Convert Processor Frequency Data to a string.\r
-\r
- @param ProcessorFrequency The frequency data to process\r
- @param Base10Exponent The exponent based on 10\r
- @param String The string that is created\r
-\r
-**/\r
-VOID\r
-ConvertProcessorToString (\r
- IN UINT16 ProcessorFrequency,\r
- IN UINT16 Base10Exponent,\r
- OUT CHAR16 **String\r
- )\r
-{\r
- CHAR16 *StringBuffer;\r
- UINTN Index;\r
- UINT32 FreqMhz;\r
-\r
- if (Base10Exponent >= 6) {\r
- FreqMhz = ProcessorFrequency;\r
- for (Index = 0; Index < ((UINT32)Base10Exponent - 6); Index++) {\r
- FreqMhz *= 10;\r
- }\r
- } else {\r
- FreqMhz = 0;\r
- }\r
-\r
- StringBuffer = AllocateZeroPool (0x20);\r
- ASSERT (StringBuffer != NULL);\r
- UnicodeValueToStringS (StringBuffer, 0x20, LEFT_JUSTIFY, FreqMhz / 1000, 3);\r
- Index = StrnLenS (StringBuffer, 0x20 / sizeof (CHAR16));\r
- StrCatS (StringBuffer, 0x20 / sizeof (CHAR16), L".");\r
- UnicodeValueToStringS (\r
- StringBuffer + Index + 1,\r
- 0x20 - sizeof (CHAR16) * (Index + 1),\r
- PREFIX_ZERO,\r
- (FreqMhz % 1000) / 10,\r
- 2\r
- );\r
- StrCatS (StringBuffer, 0x20 / sizeof (CHAR16), L" GHz");\r
- *String = (CHAR16 *) StringBuffer;\r
- return ;\r
-}\r
-\r
-\r
-/**\r
- Convert Memory Size to a string.\r
-\r
- @param MemorySize The size of the memory to process\r
- @param String The string that is created\r
-\r
-**/\r
-VOID\r
-ConvertMemorySizeToString (\r
- IN UINT32 MemorySize,\r
- OUT CHAR16 **String\r
- )\r
-{\r
- CHAR16 *StringBuffer;\r
-\r
- StringBuffer = AllocateZeroPool (0x20);\r
- ASSERT (StringBuffer != NULL);\r
- UnicodeValueToStringS (StringBuffer, 0x20, LEFT_JUSTIFY, MemorySize, 6);\r
- StrCatS (StringBuffer, 0x20 / sizeof (CHAR16), L" MB RAM");\r
-\r
- *String = (CHAR16 *) StringBuffer;\r
-\r
- return ;\r
-}\r
-\r
-/**\r
-\r
- Acquire the string associated with the Index from smbios structure and return it.\r
- The caller is responsible for free the string buffer.\r
-\r
- @param OptionalStrStart The start position to search the string\r
- @param Index The index of the string to extract\r
- @param String The string that is extracted\r
-\r
- @retval EFI_SUCCESS The function returns EFI_SUCCESS always.\r
-\r
-**/\r
-EFI_STATUS\r
-GetOptionalStringByIndex (\r
- IN CHAR8 *OptionalStrStart,\r
- IN UINT8 Index,\r
- OUT CHAR16 **String\r
- )\r
-{\r
- UINTN StrSize;\r
-\r
- if (Index == 0) {\r
- *String = AllocateZeroPool (sizeof (CHAR16));\r
- return EFI_SUCCESS;\r
- }\r
-\r
- StrSize = 0;\r
- do {\r
- Index--;\r
- OptionalStrStart += StrSize;\r
- StrSize = AsciiStrSize (OptionalStrStart);\r
- } while (OptionalStrStart[StrSize] != 0 && Index != 0);\r
-\r
- if ((Index != 0) || (StrSize == 1)) {\r
- //\r
- // Meet the end of strings set but Index is non-zero, or\r
- // Find an empty string\r
- //\r
- *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));\r
- } else {\r
- *String = AllocatePool (StrSize * sizeof (CHAR16));\r
- AsciiStrToUnicodeStrS (OptionalStrStart, *String, StrSize);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Update the banner information for the Front Page based on DataHub information.\r
-\r
-**/\r
-VOID\r
-UpdateFrontPageStrings (\r
- VOID\r
- )\r
-{\r
- UINT8 StrIndex;\r
- CHAR16 *NewString;\r
- EFI_STATUS Status;\r
- EFI_STRING_ID TokenToUpdate;\r
- EFI_SMBIOS_HANDLE SmbiosHandle;\r
- EFI_SMBIOS_PROTOCOL *Smbios;\r
- SMBIOS_TABLE_TYPE0 *Type0Record;\r
- SMBIOS_TABLE_TYPE1 *Type1Record;\r
- SMBIOS_TABLE_TYPE4 *Type4Record;\r
- SMBIOS_TABLE_TYPE19 *Type19Record;\r
- EFI_SMBIOS_TABLE_HEADER *Record;\r
- UINT64 InstalledMemory;\r
-\r
- InstalledMemory = 0;\r
-\r
- //\r
- // Update Front Page strings\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiSmbiosProtocolGuid,\r
- NULL,\r
- (VOID **) &Smbios\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
- Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);\r
- while (!EFI_ERROR(Status)) {\r
- if (Record->Type == SMBIOS_TYPE_BIOS_INFORMATION) {\r
- Type0Record = (SMBIOS_TABLE_TYPE0 *) Record;\r
- StrIndex = Type0Record->BiosVersion;\r
- GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString);\r
- TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION);\r
- HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
- FreePool (NewString);\r
- }\r
-\r
- if (Record->Type == SMBIOS_TYPE_SYSTEM_INFORMATION) {\r
- Type1Record = (SMBIOS_TABLE_TYPE1 *) Record;\r
- StrIndex = Type1Record->ProductName;\r
- GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &NewString);\r
- TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL);\r
- HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
- FreePool (NewString);\r
- }\r
-\r
- if (Record->Type == SMBIOS_TYPE_PROCESSOR_INFORMATION) {\r
- Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;\r
- StrIndex = Type4Record->ProcessorVersion;\r
- GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString);\r
- TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL);\r
- HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
- FreePool (NewString);\r
- }\r
-\r
- if (Record->Type == SMBIOS_TYPE_PROCESSOR_INFORMATION) {\r
- Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;\r
- ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString);\r
- TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED);\r
- HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
- FreePool (NewString);\r
- }\r
-\r
- if ( Record->Type == SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS ) {\r
- Type19Record = (SMBIOS_TABLE_TYPE19 *) Record;\r
- if (Type19Record->StartingAddress != 0xFFFFFFFF ) {\r
- InstalledMemory += RShiftU64(Type19Record->EndingAddress -\r
- Type19Record->StartingAddress + 1, 10);\r
- } else {\r
- InstalledMemory += RShiftU64(Type19Record->ExtendedEndingAddress -\r
- Type19Record->ExtendedStartingAddress + 1, 20);\r
- }\r
- }\r
-\r
- Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);\r
- }\r
-\r
- // now update the total installed RAM size\r
- ConvertMemorySizeToString ((UINT32)InstalledMemory, &NewString );\r
- TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE);\r
- HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
- FreePool (NewString);\r
- }\r
-\r
- return ;\r
-}\r
-\r
-\r
-/**\r
- Function waits for a given event to fire, or for an optional timeout to expire.\r
-\r
- @param Event The event to wait for\r
- @param Timeout An optional timeout value in 100 ns units.\r
-\r
- @retval EFI_SUCCESS Event fired before Timeout expired.\r
- @retval EFI_TIME_OUT Timout expired before Event fired..\r
-\r
-**/\r
-EFI_STATUS\r
-WaitForSingleEvent (\r
- IN EFI_EVENT Event,\r
- IN UINT64 Timeout OPTIONAL\r
- )\r
-{\r
- UINTN Index;\r
- EFI_STATUS Status;\r
- EFI_EVENT TimerEvent;\r
- EFI_EVENT WaitList[2];\r
-\r
- if (Timeout != 0) {\r
- //\r
- // Create a timer event\r
- //\r
- Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Set the timer event\r
- //\r
- gBS->SetTimer (\r
- TimerEvent,\r
- TimerRelative,\r
- Timeout\r
- );\r
-\r
- //\r
- // Wait for the original event or the timer\r
- //\r
- WaitList[0] = Event;\r
- WaitList[1] = TimerEvent;\r
- Status = gBS->WaitForEvent (2, WaitList, &Index);\r
- gBS->CloseEvent (TimerEvent);\r
-\r
- //\r
- // If the timer expired, change the return to timed out\r
- //\r
- if (!EFI_ERROR (Status) && Index == 1) {\r
- Status = EFI_TIMEOUT;\r
- }\r
- }\r
- } else {\r
- //\r
- // No timeout... just wait on the event\r
- //\r
- Status = gBS->WaitForEvent (1, &Event, &Index);\r
- ASSERT (!EFI_ERROR (Status));\r
- ASSERT (Index == 0);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Function show progress bar to wait for user input.\r
-\r
-\r
- @param TimeoutDefault The fault time out value before the system continue to boot.\r
-\r
- @retval EFI_SUCCESS User pressed some key except "Enter"\r
- @retval EFI_TIME_OUT Timeout expired or user press "Enter"\r
-\r
-**/\r
-EFI_STATUS\r
-ShowProgress (\r
- IN UINT16 TimeoutDefault\r
- )\r
-{\r
- CHAR16 *TmpStr;\r
- UINT16 TimeoutRemain;\r
- EFI_STATUS Status;\r
- EFI_INPUT_KEY Key;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
-\r
- if (TimeoutDefault != 0) {\r
- DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));\r
-\r
- SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
- SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
- SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
-\r
- TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));\r
-\r
- if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {\r
- //\r
- // Clear the progress status bar first\r
- //\r
- if (TmpStr != NULL) {\r
- PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);\r
- }\r
- }\r
-\r
-\r
- TimeoutRemain = TimeoutDefault;\r
- while (TimeoutRemain != 0) {\r
- DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));\r
-\r
- Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);\r
- if (Status != EFI_TIMEOUT) {\r
- break;\r
- }\r
- TimeoutRemain--;\r
-\r
- if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {\r
- //\r
- // Show progress\r
- //\r
- if (TmpStr != NULL) {\r
- PlatformBdsShowProgress (\r
- Foreground,\r
- Background,\r
- TmpStr,\r
- Color,\r
- ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),\r
- 0\r
- );\r
- }\r
- }\r
- }\r
-\r
- if (TmpStr != NULL) {\r
- gBS->FreePool (TmpStr);\r
- }\r
-\r
- //\r
- // Timeout expired\r
- //\r
- if (TimeoutRemain == 0) {\r
- return EFI_TIMEOUT;\r
- }\r
- }\r
-\r
- //\r
- // User pressed some key\r
- //\r
- if (!PcdGetBool (PcdConInConnectOnDemand)) {\r
- Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
- //\r
- // User pressed enter, equivalent to select "continue"\r
- //\r
- return EFI_TIMEOUT;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is the main entry of the platform setup entry.\r
- The function will present the main menu of the system setup,\r
- this is the platform reference part and can be customize.\r
-\r
-\r
- @param TimeoutDefault The fault time out value before the system\r
- continue to boot.\r
- @param ConnectAllHappened The indicater to check if the connect all have\r
- already happened.\r
-\r
-**/\r
-VOID\r
-PlatformBdsEnterFrontPage (\r
- IN UINT16 TimeoutDefault,\r
- IN BOOLEAN ConnectAllHappened\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS StatusHotkey;\r
- EFI_BOOT_LOGO_PROTOCOL *BootLogo;\r
- EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;\r
- UINTN BootTextColumn;\r
- UINTN BootTextRow;\r
- UINT64 OsIndication;\r
- UINTN DataSize;\r
- EFI_INPUT_KEY Key;\r
-\r
- GraphicsOutput = NULL;\r
- SimpleTextOut = NULL;\r
-\r
- PERF_START (NULL, "BdsTimeOut", "BDS", 0);\r
- //\r
- // Indicate if we need connect all in the platform setup\r
- //\r
- if (ConnectAllHappened) {\r
- gConnectAllHappened = TRUE;\r
- }\r
-\r
- if (!mModeInitialized) {\r
- //\r
- // After the console is ready, get current video resolution\r
- // and text mode before launching setup at first time.\r
- //\r
- Status = gBS->HandleProtocol (\r
- gST->ConsoleOutHandle,\r
- &gEfiGraphicsOutputProtocolGuid,\r
- (VOID**)&GraphicsOutput\r
- );\r
- if (EFI_ERROR (Status)) {\r
- GraphicsOutput = NULL;\r
- }\r
-\r
- Status = gBS->HandleProtocol (\r
- gST->ConsoleOutHandle,\r
- &gEfiSimpleTextOutProtocolGuid,\r
- (VOID**)&SimpleTextOut\r
- );\r
- if (EFI_ERROR (Status)) {\r
- SimpleTextOut = NULL;\r
- }\r
-\r
- if (GraphicsOutput != NULL) {\r
- //\r
- // Get current video resolution and text mode.\r
- //\r
- mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
- mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
- }\r
-\r
- if (SimpleTextOut != NULL) {\r
- Status = SimpleTextOut->QueryMode (\r
- SimpleTextOut,\r
- SimpleTextOut->Mode->Mode,\r
- &BootTextColumn,\r
- &BootTextRow\r
- );\r
- mBootTextModeColumn = (UINT32)BootTextColumn;\r
- mBootTextModeRow = (UINT32)BootTextRow;\r
- }\r
-\r
- //\r
- // Get user defined text mode for setup.\r
- //\r
- mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);\r
- mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);\r
- mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);\r
- mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);\r
-\r
- mModeInitialized = TRUE;\r
- }\r
-\r
-\r
- //\r
- // goto FrontPage directly when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set\r
- //\r
- OsIndication = 0;\r
- DataSize = sizeof(UINT64);\r
- Status = gRT->GetVariable (\r
- L"OsIndications",\r
- &gEfiGlobalVariableGuid,\r
- NULL,\r
- &DataSize,\r
- &OsIndication\r
- );\r
-\r
- //\r
- // goto FrontPage directly when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot\r
- //\r
- if (!EFI_ERROR(Status) && ((OsIndication & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0)) {\r
- //\r
- // Clear EFI_OS_INDICATIONS_BOOT_TO_FW_UI to acknowledge OS\r
- //\r
- OsIndication &= ~((UINT64)EFI_OS_INDICATIONS_BOOT_TO_FW_UI);\r
- Status = gRT->SetVariable (\r
- L"OsIndications",\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- sizeof(UINT64),\r
- &OsIndication\r
- );\r
- //\r
- // Changing the content without increasing its size with current variable implementation shouldn't fail.\r
- //\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Follow generic rule, Call ReadKeyStroke to connect ConIn before enter UI\r
- //\r
- if (PcdGetBool (PcdConInConnectOnDemand)) {\r
- gST->ConIn->ReadKeyStroke(gST->ConIn, &Key);\r
- }\r
-\r
- //\r
- // Ensure screen is clear when switch Console from Graphics mode to Text mode\r
- //\r
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
- gST->ConOut->ClearScreen (gST->ConOut);\r
-\r
- } else {\r
-\r
- HotkeyBoot ();\r
- if (TimeoutDefault != 0xffff) {\r
- Status = ShowProgress (TimeoutDefault);\r
- StatusHotkey = HotkeyBoot ();\r
-\r
- if (!FeaturePcdGet(PcdBootlogoOnlyEnable) || !EFI_ERROR(Status) || !EFI_ERROR(StatusHotkey)){\r
- //\r
- // Ensure screen is clear when switch Console from Graphics mode to Text mode\r
- // Skip it in normal boot\r
- //\r
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
- gST->ConOut->ClearScreen (gST->ConOut);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Timeout or user press enter to continue\r
- //\r
- goto Exit;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Boot Logo is corrupted, report it using Boot Logo protocol.\r
- //\r
- Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);\r
- if (!EFI_ERROR (Status) && (BootLogo != NULL)) {\r
- BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);\r
- }\r
-\r
- //\r
- // Install BM HiiPackages.\r
- // Keep BootMaint HiiPackage, so that it can be covered by global setting.\r
- //\r
- InitBMPackage ();\r
-\r
- Status = EFI_SUCCESS;\r
- do {\r
- //\r
- // Set proper video resolution and text mode for setup\r
- //\r
- BdsSetConsoleMode (TRUE);\r
-\r
- InitializeFrontPage (FALSE);\r
-\r
- //\r
- // Update Front Page strings\r
- //\r
- UpdateFrontPageStrings ();\r
-\r
- gCallbackKey = 0;\r
- CallFrontPage ();\r
-\r
- //\r
- // If gCallbackKey is greater than 1 and less or equal to 5,\r
- // it will launch configuration utilities.\r
- // 2 = set language\r
- // 3 = boot manager\r
- // 4 = device manager\r
- // 5 = boot maintenance manager\r
- //\r
- if (gCallbackKey != 0) {\r
- REPORT_STATUS_CODE (\r
- EFI_PROGRESS_CODE,\r
- (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)\r
- );\r
- }\r
- //\r
- // Based on the key that was set, we can determine what to do\r
- //\r
- switch (gCallbackKey) {\r
- //\r
- // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can\r
- // describe to their customers in documentation how to find their setup information (namely\r
- // under the device manager and specific buckets)\r
- //\r
- // These entries consist of the Continue, Select language, Boot Manager, and Device Manager\r
- //\r
- case FRONT_PAGE_KEY_CONTINUE:\r
- //\r
- // User hit continue\r
- //\r
- break;\r
-\r
- case FRONT_PAGE_KEY_LANGUAGE:\r
- //\r
- // User made a language setting change - display front page again\r
- //\r
- break;\r
-\r
- case FRONT_PAGE_KEY_BOOT_MANAGER:\r
- //\r
- // Remove the installed BootMaint HiiPackages when exit.\r
- //\r
- FreeBMPackage ();\r
-\r
- //\r
- // User chose to run the Boot Manager\r
- //\r
- CallBootManager ();\r
-\r
- //\r
- // Reinstall BootMaint HiiPackages after exiting from Boot Manager.\r
- //\r
- InitBMPackage ();\r
- break;\r
-\r
- case FRONT_PAGE_KEY_DEVICE_MANAGER:\r
- //\r
- // Display the Device Manager\r
- //\r
- do {\r
- CallDeviceManager ();\r
- } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);\r
- break;\r
-\r
- case FRONT_PAGE_KEY_BOOT_MAINTAIN:\r
- //\r
- // Display the Boot Maintenance Manager\r
- //\r
- BdsStartBootMaint ();\r
- break;\r
- }\r
-\r
- } while ((Status == EFI_SUCCESS) && (gCallbackKey != FRONT_PAGE_KEY_CONTINUE));\r
-\r
- if (mLanguageString != NULL) {\r
- FreePool (mLanguageString);\r
- mLanguageString = NULL;\r
- }\r
- //\r
- //Will leave browser, check any reset required change is applied? if yes, reset system\r
- //\r
- SetupResetReminder ();\r
-\r
- //\r
- // Remove the installed BootMaint HiiPackages when exit.\r
- //\r
- FreeBMPackage ();\r
-\r
-Exit:\r
- //\r
- // Automatically load current entry\r
- // Note: The following lines of code only execute when Auto boot\r
- // takes affect\r
- //\r
- PERF_END (NULL, "BdsTimeOut", "BDS", 0);\r
-}\r
-\r
-/**\r
- This function will change video resolution and text mode\r
- according to defined setup mode or defined boot mode\r
-\r
- @param IsSetupMode Indicate mode is changed to setup mode or boot mode.\r
-\r
- @retval EFI_SUCCESS Mode is changed successfully.\r
- @retval Others Mode failed to be changed.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BdsSetConsoleMode (\r
- BOOLEAN IsSetupMode\r
- )\r
-{\r
- EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;\r
- UINTN SizeOfInfo;\r
- EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
- UINT32 MaxGopMode;\r
- UINT32 MaxTextMode;\r
- UINT32 ModeNumber;\r
- UINT32 NewHorizontalResolution;\r
- UINT32 NewVerticalResolution;\r
- UINT32 NewColumns;\r
- UINT32 NewRows;\r
- UINTN HandleCount;\r
- EFI_HANDLE *HandleBuffer;\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- UINTN CurrentColumn;\r
- UINTN CurrentRow;\r
-\r
- MaxGopMode = 0;\r
- MaxTextMode = 0;\r
-\r
- //\r
- // Get current video resolution and text mode\r
- //\r
- Status = gBS->HandleProtocol (\r
- gST->ConsoleOutHandle,\r
- &gEfiGraphicsOutputProtocolGuid,\r
- (VOID**)&GraphicsOutput\r
- );\r
- if (EFI_ERROR (Status)) {\r
- GraphicsOutput = NULL;\r
- }\r
-\r
- Status = gBS->HandleProtocol (\r
- gST->ConsoleOutHandle,\r
- &gEfiSimpleTextOutProtocolGuid,\r
- (VOID**)&SimpleTextOut\r
- );\r
- if (EFI_ERROR (Status)) {\r
- SimpleTextOut = NULL;\r
- }\r
-\r
- if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (IsSetupMode) {\r
- //\r
- // The required resolution and text mode is setup mode.\r
- //\r
- NewHorizontalResolution = mSetupHorizontalResolution;\r
- NewVerticalResolution = mSetupVerticalResolution;\r
- NewColumns = mSetupTextModeColumn;\r
- NewRows = mSetupTextModeRow;\r
- } else {\r
- //\r
- // The required resolution and text mode is boot mode.\r
- //\r
- NewHorizontalResolution = mBootHorizontalResolution;\r
- NewVerticalResolution = mBootVerticalResolution;\r
- NewColumns = mBootTextModeColumn;\r
- NewRows = mBootTextModeRow;\r
- }\r
-\r
- if (GraphicsOutput != NULL) {\r
- MaxGopMode = GraphicsOutput->Mode->MaxMode;\r
- }\r
-\r
- if (SimpleTextOut != NULL) {\r
- MaxTextMode = SimpleTextOut->Mode->MaxMode;\r
- }\r
-\r
- //\r
- // 1. If current video resolution is same with required video resolution,\r
- // video resolution need not be changed.\r
- // 1.1. If current text mode is same with required text mode, text mode need not be changed.\r
- // 1.2. If current text mode is different from required text mode, text mode need be changed.\r
- // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.\r
- //\r
- for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {\r
- Status = GraphicsOutput->QueryMode (\r
- GraphicsOutput,\r
- ModeNumber,\r
- &SizeOfInfo,\r
- &Info\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- if ((Info->HorizontalResolution == NewHorizontalResolution) &&\r
- (Info->VerticalResolution == NewVerticalResolution)) {\r
- if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) &&\r
- (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) {\r
- //\r
- // Current resolution is same with required resolution, check if text mode need be set\r
- //\r
- Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);\r
- ASSERT_EFI_ERROR (Status);\r
- if (CurrentColumn == NewColumns && CurrentRow == NewRows) {\r
- //\r
- // If current text mode is same with required text mode. Do nothing\r
- //\r
- FreePool (Info);\r
- return EFI_SUCCESS;\r
- } else {\r
- //\r
- // If current text mode is different from required text mode. Set new video mode\r
- //\r
- for (Index = 0; Index < MaxTextMode; Index++) {\r
- Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);\r
- if (!EFI_ERROR(Status)) {\r
- if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {\r
- //\r
- // Required text mode is supported, set it.\r
- //\r
- Status = SimpleTextOut->SetMode (SimpleTextOut, Index);\r
- ASSERT_EFI_ERROR (Status);\r
- //\r
- // Update text mode PCD.\r
- //\r
- Status = PcdSet32S (PcdConOutColumn, mSetupTextModeColumn);\r
- ASSERT_EFI_ERROR (Status);\r
- Status = PcdSet32S (PcdConOutRow, mSetupTextModeRow);\r
- ASSERT_EFI_ERROR (Status);\r
- FreePool (Info);\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- }\r
- if (Index == MaxTextMode) {\r
- //\r
- // If required text mode is not supported, return error.\r
- //\r
- FreePool (Info);\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
- } else {\r
- //\r
- // If current video resolution is not same with the new one, set new video resolution.\r
- // In this case, the driver which produces simple text out need be restarted.\r
- //\r
- Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);\r
- if (!EFI_ERROR (Status)) {\r
- FreePool (Info);\r
- break;\r
- }\r
- }\r
- }\r
- FreePool (Info);\r
- }\r
- }\r
-\r
- if (ModeNumber == MaxGopMode) {\r
- //\r
- // If the resolution is not supported, return error.\r
- //\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Set PCD to Inform GraphicsConsole to change video resolution.\r
- // Set PCD to Inform Consplitter to change text mode.\r
- //\r
- Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution);\r
- ASSERT_EFI_ERROR (Status);\r
- Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution);\r
- ASSERT_EFI_ERROR (Status);\r
- Status = PcdSet32S (PcdConOutColumn, NewColumns);\r
- ASSERT_EFI_ERROR (Status);\r
- Status = PcdSet32S (PcdConOutRow, NewRows);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
-\r
- //\r
- // Video mode is changed, so restart graphics console driver and higher level driver.\r
- // Reconnect graphics console driver and higher level driver.\r
- // Locate all the handles with GOP protocol and reconnect it.\r
- //\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiSimpleTextOutProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuffer\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);\r
- }\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);\r
- }\r
- if (HandleBuffer != NULL) {\r
- FreePool (HandleBuffer);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r