diff options
6 files changed, 478 insertions, 2 deletions
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/FrameworkHiiToUefiHiiThunk.inf b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/FrameworkHiiToUefiHiiThunk.inf index b79a984..d1343ad 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 4dd33cf..1bf17c1 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 9ed45da..9eff9a2 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 <Protocol/HiiDatabase.h>
#include <Protocol/HiiConfigRouting.h>
#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/UgaDraw.h>
#include <Library/BaseLib.h>
@@ -45,9 +46,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/HiiLib.h>
#include <Library/ExtendedHiiLib.h>
+#include <Library/UefiLib.h>
#include <Library/IfrSupportLib.h>
#include <Library/ExtendedIfrSupportLib.h>
+#include <Library/PcdLib.h>
#include <MdeModuleHii.h>
@@ -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 ca7bbe8..7f42842 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 0000000..9fd0338 --- /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 Binary files differnew file mode 100644 index 0000000..9de7663 --- /dev/null +++ b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Strings.uni |