From a235abd2c9e7410bec55fe585168bcb6a8fac6f2 Mon Sep 17 00:00:00 2001 From: qwang12 Date: Wed, 17 Dec 2008 06:41:02 +0000 Subject: [PATCH] Following UEFI spec to do auto booting after a time-out. This feature is implemented in Framework Setup Browser and moved to MdeModulePkg/Universal/BdsDxe. The auto booting is moved here in HII Thunk module. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7062 6f19259b-4bc3-4df7-8a09-765794883524 --- .../FrameworkHiiToUefiHiiThunk.inf | 9 +- .../FrameworkHiiToUefiHiiThunk/HiiDatabase.c | 2 + .../FrameworkHiiToUefiHiiThunk/HiiDatabase.h | 14 + .../FrameworkHiiToUefiHiiThunk/SetupBrowser.c | 430 ++++++++++++++++++ .../FrameworkHiiToUefiHiiThunk/SetupBrowser.h | 25 + .../FrameworkHiiToUefiHiiThunk/Strings.uni | Bin 0 -> 1630 bytes 6 files changed, 478 insertions(+), 2 deletions(-) create mode 100644 EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.h create mode 100644 EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Strings.uni diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/FrameworkHiiToUefiHiiThunk.inf b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/FrameworkHiiToUefiHiiThunk.inf index b79a98459e..d1343adf5b 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/FrameworkHiiToUefiHiiThunk.inf +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/FrameworkHiiToUefiHiiThunk.inf @@ -37,6 +37,7 @@ # [Sources.common] + SetupBrowser.c HiiHandle.c HiiHandle.h ConfigAccess.c @@ -57,8 +58,7 @@ HiiDatabase.c Utility.c Utility.h - - SetupBrowser.c + Strings.uni [Packages] @@ -79,6 +79,8 @@ IfrSupportLib ExtendedIfrSupportLib PrintLib + UefiLib + PcdLib [Protocols] gEfiHiiImageProtocolGuid @@ -92,6 +94,9 @@ gEfiHiiCompatibilityProtocolGuid gEfiFormBrowserCompatibilityProtocolGuid +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdPlatformBootTimeOutDefault + [Depex] gEfiHiiDatabaseProtocolGuid AND gEfiHiiStringProtocolGuid AND diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c index 4dd33cfa0b..1bf17c174c 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c @@ -218,6 +218,8 @@ InitializeHiiDatabase ( ); ASSERT_EFI_ERROR (Status); + InitSetBrowserStrings (); + mBrowserThunkPrivateDataTemplate.ThunkPrivate = Private; Status = gBS->InstallProtocolInterface ( &mBrowserThunkPrivateDataTemplate.Handle, diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.h index 9ed45daea2..9eff9a264f 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.h +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.h @@ -34,6 +34,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include @@ -45,9 +46,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include #include +#include #include @@ -444,6 +447,17 @@ FwUpdateDataToUefiUpdateData ( ) ; +/** + + Initialize string packages in HII database. + +**/ +VOID +InitSetBrowserStrings ( + VOID + ) +; + #include "Utility.h" #include "ConfigAccess.h" diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.c b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.c index ca7bbe810a..7f42842755 100644 --- a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.c +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.c @@ -14,6 +14,400 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include "HiiDatabase.h" +#include "SetupBrowser.h" + +EFI_GUID gFrameworkBdsFrontPageFormsetGuid = FRAMEWORK_BDS_FRONTPAGE_FORMSET_GUID; +EFI_HII_HANDLE gStringPackHandle = NULL; +BOOLEAN mFrontPageDisplayed = FALSE; +// +// 106F3545-B788-4cb5-9D2A-CE0CDB208DF5 +// +EFI_GUID gEfiHiiThunkProducerGuid = { 0x106f3545, 0xb788, 0x4cb5, { 0x9d, 0x2a, 0xce, 0xc, 0xdb, 0x20, 0x8d, 0xf5 } }; + + +/** + Get string by string id from HII Interface + + + @param Id String ID. + + @retval CHAR16 * String from ID. + @retval NULL If error occurs. + +**/ +CHAR16 * +GetStringById ( + IN EFI_STRING_ID Id + ) +{ + CHAR16 *String; + + String = NULL; + HiiLibGetStringFromHandle (gStringPackHandle, Id, &String); + + return String; +} +/** + + Show progress bar with title above it. It only works in Graphics mode. + + + @param TitleForeground Foreground color for Title. + @param TitleBackground Background color for Title. + @param Title Title above progress bar. + @param ProgressColor Progress bar color. + @param Progress Progress (0-100) + @param PreviousValue The previous value of the progress. + + @retval EFI_STATUS Success update the progress bar + +**/ +EFI_STATUS +PlatformBdsShowProgress ( + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground, + IN CHAR16 *Title, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor, + IN UINTN Progress, + IN UINTN PreviousValue + ) +{ + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + EFI_UGA_DRAW_PROTOCOL *UgaDraw; + UINT32 SizeOfX; + UINT32 SizeOfY; + UINT32 ColorDepth; + UINT32 RefreshRate; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; + UINTN BlockHeight; + UINTN BlockWidth; + UINTN BlockNum; + UINTN PosX; + UINTN PosY; + UINTN Index; + + if (Progress > 100) { + return EFI_INVALID_PARAMETER; + } + + UgaDraw = NULL; + Status = gBS->HandleProtocol ( + gST->ConsoleOutHandle, + &gEfiGraphicsOutputProtocolGuid, + (VOID **) &GraphicsOutput + ); + if (EFI_ERROR (Status)) { + GraphicsOutput = NULL; + + Status = gBS->HandleProtocol ( + gST->ConsoleOutHandle, + &gEfiUgaDrawProtocolGuid, + (VOID **) &UgaDraw + ); + } + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + SizeOfX = 0; + SizeOfY = 0; + if (GraphicsOutput != NULL) { + SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution; + SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution; + } else { + Status = UgaDraw->GetMode ( + UgaDraw, + &SizeOfX, + &SizeOfY, + &ColorDepth, + &RefreshRate + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + } + + BlockWidth = SizeOfX / 100; + BlockHeight = SizeOfY / 50; + + BlockNum = Progress; + + PosX = 0; + PosY = SizeOfY * 48 / 50; + + if (BlockNum == 0) { + // + // Clear progress area + // + SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0); + + if (GraphicsOutput != NULL) { + Status = GraphicsOutput->Blt ( + GraphicsOutput, + &Color, + EfiBltVideoFill, + 0, + 0, + 0, + PosY - EFI_GLYPH_HEIGHT - 1, + SizeOfX, + SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1), + SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + } else { + Status = UgaDraw->Blt ( + UgaDraw, + (EFI_UGA_PIXEL *) &Color, + EfiUgaVideoFill, + 0, + 0, + 0, + PosY - EFI_GLYPH_HEIGHT - 1, + SizeOfX, + SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1), + SizeOfX * sizeof (EFI_UGA_PIXEL) + ); + } + } + // + // Show progress by drawing blocks + // + for (Index = PreviousValue; Index < BlockNum; Index++) { + PosX = Index * BlockWidth; + if (GraphicsOutput != NULL) { + Status = GraphicsOutput->Blt ( + GraphicsOutput, + &ProgressColor, + EfiBltVideoFill, + 0, + 0, + PosX, + PosY, + BlockWidth - 1, + BlockHeight, + (BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + } else { + Status = UgaDraw->Blt ( + UgaDraw, + (EFI_UGA_PIXEL *) &ProgressColor, + EfiUgaVideoFill, + 0, + 0, + PosX, + PosY, + BlockWidth - 1, + BlockHeight, + (BlockWidth) * sizeof (EFI_UGA_PIXEL) + ); + } + } + + PrintXY ( + (SizeOfX - StrLen (Title) * EFI_GLYPH_WIDTH) / 2, + PosY - EFI_GLYPH_HEIGHT - 1, + &TitleForeground, + &TitleBackground, + Title + ); + + return EFI_SUCCESS; +} + +/** + Function waits for a given event to fire, or for an optional timeout to expire. + + + @param Event The event to wait for + + @param Timeout An optional timeout value in 100 ns units. + + @retval EFI_SUCCESS Event fired before Timeout expired. + @retval EFI_TIME_OUT Timout expired before Event fired.. + +**/ +EFI_STATUS +WaitForSingleEvent ( + IN EFI_EVENT Event, + IN UINT64 Timeout OPTIONAL + ) +{ + EFI_STATUS Status; + UINTN Index; + EFI_EVENT TimerEvent; + EFI_EVENT WaitList[2]; + + if (Timeout != 0) { + // + // Create a timer event + // + Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent); + if (!EFI_ERROR (Status)) { + // + // Set the timer event + // + gBS->SetTimer ( + TimerEvent, + TimerRelative, + Timeout + ); + + // + // Wait for the original event or the timer + // + WaitList[0] = Event; + WaitList[1] = TimerEvent; + Status = gBS->WaitForEvent (2, WaitList, &Index); + gBS->CloseEvent (TimerEvent); + + // + // If the timer expired, change the return to timed out + // + if (!EFI_ERROR (Status) && Index == 1) { + Status = EFI_TIMEOUT; + } + } + } else { + // + // No timeout... just wait on the event + // + Status = gBS->WaitForEvent (1, &Event, &Index); + ASSERT (!EFI_ERROR (Status)); + ASSERT (Index == 0); + } + + return Status; +} + +/** + Function show progress bar to wait for user input. + + + @param TimeoutDefault - The fault time out value before the system + continue to boot. + + @retval EFI_SUCCESS User pressed some key except "Enter" + @retval EFI_TIME_OUT Timout expired or user press "Enter" + +**/ +EFI_STATUS +ShowProgress ( + IN UINT16 TimeoutDefault + ) +{ + EFI_STATUS Status; + CHAR16 *TmpStr; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; + EFI_INPUT_KEY Key; + UINT16 TimeoutRemain; + + if (TimeoutDefault == 0) { + return EFI_TIMEOUT; + } + + DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n")); + + SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); + SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0); + SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); + + // + // Clear the progress status bar first + // + TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION)); + if (TmpStr != NULL) { + PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0); + } + + TimeoutRemain = TimeoutDefault; + while (TimeoutRemain != 0) { + DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain)); + + Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND); + if (Status != EFI_TIMEOUT) { + break; + } + TimeoutRemain--; + + // + // Show progress + // + if (TmpStr != NULL) { + PlatformBdsShowProgress ( + Foreground, + Background, + TmpStr, + Color, + ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault), + 0 + ); + } + } + gBS->FreePool (TmpStr); + + // + // Timeout expired + // + if (TimeoutRemain == 0) { + return EFI_TIMEOUT; + } + + // + // User pressed some key + // + Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { + // + // User pressed enter, equivalent to select "continue" + // + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} + +/** + Return the default value for system Timeout variable. + + @return Timeout value. + +**/ +UINT16 +EFIAPI +GetTimeout ( + VOID + ) +{ + UINT16 Timeout; + UINTN Size; + EFI_STATUS Status; + + // + // Return Timeout variable or 0xffff if no valid + // Timeout variable exists. + // + Size = sizeof (UINT16); + Status = gRT->GetVariable (L"Timeout", &gEfiGlobalVariableGuid, NULL, &Size, &Timeout); + if (EFI_ERROR (Status)) { + // + // According to UEFI 2.0 spec, it should treat the Timeout value as 0xffff + // (default value PcdPlatformBootTimeOutDefault) when L"Timeout" variable is not present. + // To make the current EFI Automatic-Test activity possible, platform can choose other value + // for automatic boot when the variable is not present. + // + Timeout = PcdGet16 (PcdPlatformBootTimeOutDefault); + } + + return Timeout; +} + /** This is the Framework Setup Browser interface which displays a FormSet. @@ -74,6 +468,23 @@ ThunkSendForm ( return EFI_INVALID_PARAMETER; } + // + // Following UEFI spec to do auto booting after a time-out. This feature is implemented + // in Framework Setup Browser and moved to MdeModulePkg/Universal/BdsDxe. The auto booting is + // moved here in HII Thunk module. + // + if (CompareGuid (&gFrameworkBdsFrontPageFormsetGuid, &ThunkContext->FormSet->Guid) && !mFrontPageDisplayed) { + // + // Send form is called before entering the + // + mFrontPageDisplayed = TRUE; + Status = ShowProgress (GetTimeout ()); + + if (EFI_ERROR (Status)) { + return Status; + } + } + if (NvMapOverride != NULL) { ThunkContext->NvMapOverride = NvMapOverride; } @@ -143,3 +554,22 @@ ThunkCreatePopUp ( return Status; } +/** + + Initialize string packages in HII database. + +**/ +VOID +InitSetBrowserStrings ( + VOID + ) +{ + EFI_STATUS Status; + + // + // Initialize strings to HII database + // + Status = HiiLibAddPackages (1, &gEfiHiiThunkProducerGuid, NULL, &gStringPackHandle, STRING_ARRAY_NAME); + ASSERT_EFI_ERROR (Status); + +} diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.h new file mode 100644 index 0000000000..9fd033878e --- /dev/null +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.h @@ -0,0 +1,25 @@ +/**@file + This file contains macros to be included by SetupBrowser.c. + +Copyright (c) 2008, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _HIITHUNK_SETUPBROWSER_H_ +#define _HIITHUNK_SETUPBROWSER_H_ + +// +// In order to follow UEFI spec to do auto booting after a time-out, the GUID of Formset of Frontpage must match this value. +// +#define FRAMEWORK_BDS_FRONTPAGE_FORMSET_GUID { 0x9e0c30bc, 0x3f06, 0x4ba6, {0x82, 0x88, 0x9, 0x17, 0x9b, 0x85, 0x5d, 0xbe }} + +#define ONE_SECOND 10000000 + +#endif diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Strings.uni b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Strings.uni new file mode 100644 index 0000000000000000000000000000000000000000..9de7663df9f01891d63886ffd34f85915a713fa8 GIT binary patch literal 1630 zcmbu9TW`}q5QXO%iT_}w4_wqFh$n;q(GV9Rpstcsg{LZ)<|5L#a@<0HG2%}E-@KQUv<9Y$fVAN+?3#88x4?Vp8C^1;vs>sF ztc-{~r7z)k?&ApzbJi|>?FQ_i(S`F7?hvu90%Z20aX1gS&;)z4h zOR+YLmGu~&RdqQ&!IJ&GE39kN%^ztVqXMa*>z(`}THMQUGeaUyyT zEsm)y#q8d5>-GAyVJfQu)yU71Lx{q01BQaaqBiKY9;mr>$b;EQE!~4{=U)!4= GmHZ32&GYpD literal 0 HcmV?d00001