]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Following UEFI spec to do auto booting after a time-out. This feature is implemented
authorqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 17 Dec 2008 06:41:02 +0000 (06:41 +0000)
committerqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 17 Dec 2008 06:41:02 +0000 (06:41 +0000)
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

EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/FrameworkHiiToUefiHiiThunk.inf
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.c
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/HiiDatabase.h
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.c
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.h [new file with mode: 0644]
EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Strings.uni [new file with mode: 0644]

index b79a98459e3e80abd5a9a1d0ea5932e0169b2262..d1343adf5b7608ea88f02e6f17f5d4e52c5aef27 100644 (file)
@@ -37,6 +37,7 @@
 #\r
 \r
 [Sources.common]\r
+  SetupBrowser.c\r
   HiiHandle.c\r
   HiiHandle.h\r
   ConfigAccess.c\r
@@ -57,8 +58,7 @@
   HiiDatabase.c\r
   Utility.c\r
   Utility.h\r
-\r
-  SetupBrowser.c\r
+  Strings.uni\r
  \r
 \r
 [Packages]\r
@@ -79,6 +79,8 @@
   IfrSupportLib\r
   ExtendedIfrSupportLib\r
   PrintLib\r
+  UefiLib\r
+  PcdLib\r
 \r
 [Protocols]\r
   gEfiHiiImageProtocolGuid\r
@@ -92,6 +94,9 @@
   gEfiHiiCompatibilityProtocolGuid\r
   gEfiFormBrowserCompatibilityProtocolGuid\r
 \r
+[Pcd]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPlatformBootTimeOutDefault\r
+\r
 [Depex]\r
   gEfiHiiDatabaseProtocolGuid AND\r
   gEfiHiiStringProtocolGuid AND\r
index 4dd33cfa0b3422a811c4f0210477b28589f9c6e2..1bf17c174ca033e331fecd97e2058fd891ab4c62 100644 (file)
@@ -218,6 +218,8 @@ InitializeHiiDatabase (
                            );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  InitSetBrowserStrings ();\r
+\r
   mBrowserThunkPrivateDataTemplate.ThunkPrivate = Private;\r
   Status = gBS->InstallProtocolInterface (\r
                   &mBrowserThunkPrivateDataTemplate.Handle,\r
index 9ed45daea21bc7430edc96ce77fb6c85ef13ecb7..9eff9a264f997a127b1d9c27fc99105105656c4a 100644 (file)
@@ -34,6 +34,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/HiiDatabase.h>\r
 #include <Protocol/HiiConfigRouting.h>\r
 #include <Protocol/HiiConfigAccess.h>\r
+#include <Protocol/UgaDraw.h>\r
 \r
 \r
 #include <Library/BaseLib.h>\r
@@ -45,9 +46,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/UefiRuntimeServicesTableLib.h>\r
 #include <Library/HiiLib.h>\r
 #include <Library/ExtendedHiiLib.h>\r
+#include <Library/UefiLib.h>\r
 \r
 #include <Library/IfrSupportLib.h>\r
 #include <Library/ExtendedIfrSupportLib.h>\r
+#include <Library/PcdLib.h>\r
 \r
 #include <MdeModuleHii.h>\r
 \r
@@ -444,6 +447,17 @@ FwUpdateDataToUefiUpdateData (
   )\r
 ;\r
 \r
+/** \r
+\r
+  Initialize string packages in HII database.\r
+\r
+**/\r
+VOID\r
+InitSetBrowserStrings (\r
+  VOID\r
+  )\r
+;\r
+\r
 #include "Utility.h"\r
 #include "ConfigAccess.h"\r
 \r
index ca7bbe810ad21f4c9f8de00e652ece0f86eb865e..7f42842755abb6a8b31f2acb1a4439489356365c 100644 (file)
@@ -14,6 +14,400 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 \r
 #include "HiiDatabase.h"\r
+#include "SetupBrowser.h"\r
+\r
+EFI_GUID gFrameworkBdsFrontPageFormsetGuid = FRAMEWORK_BDS_FRONTPAGE_FORMSET_GUID;\r
+EFI_HII_HANDLE gStringPackHandle = NULL;\r
+BOOLEAN mFrontPageDisplayed = FALSE;\r
+//\r
+// 106F3545-B788-4cb5-9D2A-CE0CDB208DF5\r
+//\r
+EFI_GUID gEfiHiiThunkProducerGuid = { 0x106f3545, 0xb788, 0x4cb5, { 0x9d, 0x2a, 0xce, 0xc, 0xdb, 0x20, 0x8d, 0xf5 } }; \r
+\r
+\r
+/**\r
+  Get string by string id from HII Interface\r
+\r
+\r
+  @param Id              String ID.\r
+\r
+  @retval  CHAR16 *  String from ID.\r
+  @retval  NULL      If error occurs.\r
+\r
+**/\r
+CHAR16 *\r
+GetStringById (\r
+  IN  EFI_STRING_ID   Id\r
+  )\r
+{\r
+  CHAR16 *String;\r
+\r
+  String = NULL;\r
+  HiiLibGetStringFromHandle (gStringPackHandle, Id, &String);\r
+\r
+  return String;\r
+}\r
+/**\r
+\r
+  Show progress bar with title above it. It only works in Graphics mode.\r
+\r
+\r
+  @param TitleForeground Foreground color for Title.\r
+  @param TitleBackground Background color for Title.\r
+  @param Title           Title above progress bar.\r
+  @param ProgressColor   Progress bar color.\r
+  @param Progress        Progress (0-100)\r
+  @param PreviousValue   The previous value of the progress.\r
+\r
+  @retval  EFI_STATUS       Success update the progress bar\r
+\r
+**/\r
+EFI_STATUS\r
+PlatformBdsShowProgress (\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,\r
+  IN CHAR16                        *Title,\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,\r
+  IN UINTN                         Progress,\r
+  IN UINTN                         PreviousValue\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL   *GraphicsOutput;\r
+  EFI_UGA_DRAW_PROTOCOL          *UgaDraw;\r
+  UINT32                         SizeOfX;\r
+  UINT32                         SizeOfY;\r
+  UINT32                         ColorDepth;\r
+  UINT32                         RefreshRate;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Color;\r
+  UINTN                          BlockHeight;\r
+  UINTN                          BlockWidth;\r
+  UINTN                          BlockNum;\r
+  UINTN                          PosX;\r
+  UINTN                          PosY;\r
+  UINTN                          Index;\r
+\r
+  if (Progress > 100) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  UgaDraw = NULL;\r
+  Status = gBS->HandleProtocol (\r
+                  gST->ConsoleOutHandle,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  (VOID **) &GraphicsOutput\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    GraphicsOutput = NULL;\r
+\r
+    Status = gBS->HandleProtocol (\r
+                    gST->ConsoleOutHandle,\r
+                    &gEfiUgaDrawProtocolGuid,\r
+                    (VOID **) &UgaDraw\r
+                    );\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  SizeOfX = 0;\r
+  SizeOfY = 0;\r
+  if (GraphicsOutput != NULL) {\r
+    SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
+    SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
+  } else {\r
+    Status = UgaDraw->GetMode (\r
+                        UgaDraw,\r
+                        &SizeOfX,\r
+                        &SizeOfY,\r
+                        &ColorDepth,\r
+                        &RefreshRate\r
+                        );\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  }\r
+\r
+  BlockWidth  = SizeOfX / 100;\r
+  BlockHeight = SizeOfY / 50;\r
+\r
+  BlockNum    = Progress;\r
+\r
+  PosX        = 0;\r
+  PosY        = SizeOfY * 48 / 50;\r
+\r
+  if (BlockNum == 0) {\r
+    //\r
+    // Clear progress area\r
+    //\r
+    SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
+\r
+    if (GraphicsOutput != NULL) {\r
+      Status = GraphicsOutput->Blt (\r
+                          GraphicsOutput,\r
+                          &Color,\r
+                          EfiBltVideoFill,\r
+                          0,\r
+                          0,\r
+                          0,\r
+                          PosY - EFI_GLYPH_HEIGHT - 1,\r
+                          SizeOfX,\r
+                          SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),\r
+                          SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+                          );\r
+    } else {\r
+      Status = UgaDraw->Blt (\r
+                          UgaDraw,\r
+                          (EFI_UGA_PIXEL *) &Color,\r
+                          EfiUgaVideoFill,\r
+                          0,\r
+                          0,\r
+                          0,\r
+                          PosY - EFI_GLYPH_HEIGHT - 1,\r
+                          SizeOfX,\r
+                          SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),\r
+                          SizeOfX * sizeof (EFI_UGA_PIXEL)\r
+                          );\r
+    }\r
+  }\r
+  //\r
+  // Show progress by drawing blocks\r
+  //\r
+  for (Index = PreviousValue; Index < BlockNum; Index++) {\r
+    PosX = Index * BlockWidth;\r
+    if (GraphicsOutput != NULL) {\r
+      Status = GraphicsOutput->Blt (\r
+                          GraphicsOutput,\r
+                          &ProgressColor,\r
+                          EfiBltVideoFill,\r
+                          0,\r
+                          0,\r
+                          PosX,\r
+                          PosY,\r
+                          BlockWidth - 1,\r
+                          BlockHeight,\r
+                          (BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+                          );\r
+    } else {\r
+      Status = UgaDraw->Blt (\r
+                          UgaDraw,\r
+                          (EFI_UGA_PIXEL *) &ProgressColor,\r
+                          EfiUgaVideoFill,\r
+                          0,\r
+                          0,\r
+                          PosX,\r
+                          PosY,\r
+                          BlockWidth - 1,\r
+                          BlockHeight,\r
+                          (BlockWidth) * sizeof (EFI_UGA_PIXEL)\r
+                          );\r
+    }\r
+  }\r
+\r
+  PrintXY (\r
+    (SizeOfX - StrLen (Title) * EFI_GLYPH_WIDTH) / 2,\r
+    PosY - EFI_GLYPH_HEIGHT - 1,\r
+    &TitleForeground,\r
+    &TitleBackground,\r
+    Title\r
+    );\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Function waits for a given event to fire, or for an optional timeout to expire.\r
+\r
+\r
+  @param Event           The event to wait for\r
+                        \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
+  EFI_STATUS  Status;\r
+  UINTN       Index;\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\r
+                         continue to boot.\r
+\r
+  @retval  EFI_SUCCESS       User pressed some key except "Enter"\r
+  @retval  EFI_TIME_OUT      Timout expired or user press "Enter"\r
+\r
+**/\r
+EFI_STATUS\r
+ShowProgress (\r
+  IN UINT16                       TimeoutDefault\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  CHAR16                        *TmpStr;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
+  EFI_INPUT_KEY                 Key;\r
+  UINT16                        TimeoutRemain;\r
+\r
+  if (TimeoutDefault == 0) {\r
+    return EFI_TIMEOUT;\r
+  }\r
+\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
+  //\r
+  // Clear the progress status bar first\r
+  //\r
+  TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));\r
+  if (TmpStr != NULL) {\r
+    PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);\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
+    //\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
+  gBS->FreePool (TmpStr);\r
+\r
+  //\r
+  // Timeout expired\r
+  //\r
+  if (TimeoutRemain == 0) {\r
+    return EFI_TIMEOUT;\r
+  }\r
+\r
+  //\r
+  // User pressed some key\r
+  //\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
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Return the default value for system Timeout variable.\r
+\r
+  @return Timeout value.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+GetTimeout (\r
+  VOID\r
+  )\r
+{\r
+  UINT16      Timeout;\r
+  UINTN       Size;\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Return Timeout variable or 0xffff if no valid\r
+  // Timeout variable exists.\r
+  //\r
+  Size    = sizeof (UINT16);\r
+  Status  = gRT->GetVariable (L"Timeout", &gEfiGlobalVariableGuid, NULL, &Size, &Timeout);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // According to UEFI 2.0 spec, it should treat the Timeout value as 0xffff\r
+    // (default value PcdPlatformBootTimeOutDefault) when L"Timeout" variable is not present.\r
+    // To make the current EFI Automatic-Test activity possible, platform can choose other value\r
+    // for automatic boot when the variable is not present.\r
+    //\r
+    Timeout = PcdGet16 (PcdPlatformBootTimeOutDefault);\r
+  }\r
+\r
+  return Timeout;\r
+}\r
+\r
 \r
 /**\r
   This is the Framework Setup Browser interface which displays a FormSet.\r
@@ -74,6 +468,23 @@ ThunkSendForm (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  //\r
+  // Following UEFI spec to do auto booting after a time-out. This feature is implemented \r
+  // in Framework Setup Browser and moved to MdeModulePkg/Universal/BdsDxe. The auto booting is\r
+  // moved here in HII Thunk module. \r
+  //\r
+  if (CompareGuid (&gFrameworkBdsFrontPageFormsetGuid, &ThunkContext->FormSet->Guid) && !mFrontPageDisplayed) {\r
+    //\r
+    // Send form is called before entering the \r
+    //\r
+    mFrontPageDisplayed = TRUE;\r
+    Status = ShowProgress (GetTimeout ());\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+  \r
   if (NvMapOverride != NULL) {\r
     ThunkContext->NvMapOverride = NvMapOverride;\r
   }\r
@@ -143,3 +554,22 @@ ThunkCreatePopUp (
   return Status;\r
 }\r
 \r
+/** \r
+\r
+  Initialize string packages in HII database.\r
+\r
+**/\r
+VOID\r
+InitSetBrowserStrings (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  \r
+  //\r
+  // Initialize strings to HII database\r
+  //\r
+  Status = HiiLibAddPackages (1, &gEfiHiiThunkProducerGuid, NULL, &gStringPackHandle, STRING_ARRAY_NAME);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+}\r
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.h b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/SetupBrowser.h
new file mode 100644 (file)
index 0000000..9fd0338
--- /dev/null
@@ -0,0 +1,25 @@
+/**@file\r
+  This file contains macros to be included by SetupBrowser.c.\r
+  \r
+Copyright (c) 2008, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _HIITHUNK_SETUPBROWSER_H_\r
+#define _HIITHUNK_SETUPBROWSER_H_\r
+\r
+//\r
+// In order to follow UEFI spec to do auto booting after a time-out, the GUID of Formset of Frontpage must match this value.\r
+//\r
+#define FRAMEWORK_BDS_FRONTPAGE_FORMSET_GUID  { 0x9e0c30bc, 0x3f06, 0x4ba6, {0x82, 0x88, 0x9, 0x17, 0x9b, 0x85, 0x5d, 0xbe }}\r
+\r
+#define ONE_SECOND  10000000\r
+\r
+#endif\r
diff --git a/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Strings.uni b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Strings.uni
new file mode 100644 (file)
index 0000000..9de7663
Binary files /dev/null and b/EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Strings.uni differ