From 9e0e49fc76ce84779b34cf11a4bced3911df0391 Mon Sep 17 00:00:00 2001 From: dtang2 Date: Wed, 8 Nov 2006 03:12:19 +0000 Subject: [PATCH] Bug fix for "Tiano BIOS needs to implement an automatic reboot when BIOS settings are changed" git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1913 6f19259b-4bc3-4df7-8a09-765794883524 --- .../PlatformBds/Generic/BootMaint/BootMaint.c | 15 +- .../Generic/BootMngr/BootManager.c | 24 +- .../Generic/DeviceMngr/DeviceManager.c | 14 +- .../Dxe/PlatformBds/Generic/FrontPage.c | 15 +- EdkNt32Pkg/Include/library/EdkGenericBdsLib.h | 50 ++++ EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c | 218 ++++++++++++++++++ 6 files changed, 330 insertions(+), 6 deletions(-) diff --git a/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BootMaint.c b/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BootMaint.c index c4b3211dfd..6eefa0bd30 100644 --- a/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BootMaint.c +++ b/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/BootMaint.c @@ -1230,6 +1230,7 @@ Returns: UINTN Index; BM_MENU_ENTRY *NewMenuEntry; BM_FILE_CONTEXT *NewFileContext; + BOOLEAN BootMaintMenuResetRequired; Location = NULL; Index = 0; @@ -1247,6 +1248,7 @@ Returns: while (1) { UpdatePageId (CallbackData, FORM_MAIN_ID); + BootMaintMenuResetRequired = FALSE; Status = FormConfig->SendForm ( FormConfig, TRUE, @@ -1256,9 +1258,13 @@ Returns: NULL, (UINT8 *) CallbackData->BmmFakeNvData, NULL, - NULL + &BootMaintMenuResetRequired ); + if (BootMaintMenuResetRequired) { + EnableResetRequired (); + } + ReclaimStringDepository (); // @@ -1267,6 +1273,7 @@ Returns: if (INACTIVE_STATE != CallbackData->FeCurrentState) { UpdateFileExplorer (CallbackData, 0); + BootMaintMenuResetRequired = FALSE; Status = FormConfig->SendForm ( FormConfig, TRUE, @@ -1276,9 +1283,13 @@ Returns: NULL, NULL, NULL, - NULL + &BootMaintMenuResetRequired ); + if (BootMaintMenuResetRequired) { + EnableResetRequired (); + } + CallbackData->FeCurrentState = INACTIVE_STATE; CallbackData->FeDisplayContext = UNKNOWN_CONTEXT; ReclaimStringDepository (); diff --git a/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.c b/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.c index d90cfaa0a8..23b8789617 100644 --- a/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.c +++ b/EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMngr/BootManager.c @@ -139,6 +139,7 @@ Returns: UINT8 *Location; EFI_GUID BmGuid; LIST_ENTRY BdsBootOptionList; + BOOLEAN BootMngrMenuResetRequired; gOption = NULL; InitializeListHead (&BdsBootOptionList); @@ -299,13 +300,34 @@ Returns: ASSERT (gBrowser); - gBrowser->SendForm (gBrowser, TRUE, &gBootManagerHandle, 1, NULL, NULL, NULL, NULL, NULL); + BootMngrMenuResetRequired = FALSE; + gBrowser->SendForm ( + gBrowser, + TRUE, + &gBootManagerHandle, + 1, + NULL, + NULL, + NULL, + NULL, + &BootMngrMenuResetRequired + ); + + if (BootMngrMenuResetRequired) { + EnableResetRequired (); + } Hii->ResetStrings (Hii, gBootManagerHandle); if (gOption == NULL) { return ; } + + // + //Will leave browser, check any reset required change is applied? if yes, reset system + // + SetupResetReminder (); + // // BugBug: This code looks repeated from the BDS. Need to save code space. // diff --git a/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManager.c b/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManager.c index 0e73a4e3fe..3f648b7de6 100644 --- a/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManager.c +++ b/EdkNt32Pkg/Dxe/PlatformBds/Generic/DeviceMngr/DeviceManager.c @@ -197,6 +197,7 @@ Returns: UINTN VideoOptionSize; EFI_HII_HANDLE *HiiHandles; UINT16 HandleBufferLength; + BOOLEAN BootDeviceMngrMenuResetRequired; IfrOptionList = NULL; VideoOption = NULL; @@ -435,6 +436,7 @@ Returns: gBS->FreePool (IfrOptionList); } + BootDeviceMngrMenuResetRequired = FALSE; Status = gBrowser->SendForm ( gBrowser, TRUE, // Use the database @@ -444,9 +446,13 @@ Returns: FPCallbackInfo.CallbackHandle, (UINT8 *) &FPCallbackInfo.Data, NULL, - NULL + &BootDeviceMngrMenuResetRequired ); + if (BootDeviceMngrMenuResetRequired) { + EnableResetRequired (); + } + Hii->ResetStrings (Hii, FPCallbackInfo.DevMgrHiiHandle); // @@ -454,6 +460,7 @@ Returns: // a target to display // if (gCallbackKey != 0 && gCallbackKey < 0x2000) { + BootDeviceMngrMenuResetRequired = FALSE; Status = gBrowser->SendForm ( gBrowser, TRUE, // Use the database @@ -463,9 +470,12 @@ Returns: NULL, // This is the handle that the interface to the callback was installed on NULL, NULL, - NULL + &BootDeviceMngrMenuResetRequired ); + if (BootDeviceMngrMenuResetRequired) { + EnableResetRequired (); + } // // Force return to Device Manager // diff --git a/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPage.c b/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPage.c index 69b2fb5078..45992db02d 100644 --- a/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPage.c +++ b/EdkNt32Pkg/Dxe/PlatformBds/Generic/FrontPage.c @@ -417,6 +417,7 @@ Returns: { EFI_STATUS Status; UINT8 FakeNvRamMap[1]; + BOOLEAN FrontPageMenuResetRequired; // // Begin waiting for USER INPUT @@ -427,6 +428,7 @@ Returns: ); FakeNvRamMap[0] = (UINT8) mLastSelection; + FrontPageMenuResetRequired = FALSE; Status = gBrowser->SendForm ( gBrowser, TRUE, // Use the database @@ -436,8 +438,14 @@ Returns: FrontPageCallbackHandle, // This is the handle that the interface to the callback was installed on FakeNvRamMap, NULL, - NULL + &FrontPageMenuResetRequired ); + // + // Check whether user change any option setting which needs a reset to be effective + // + if (FrontPageMenuResetRequired) { + EnableResetRequired (); + } Hii->ResetStrings (Hii, gFrontPageHandle); @@ -877,6 +885,11 @@ Returns: } while ((Status == EFI_SUCCESS) && (gCallbackKey != 1)); + // + //Will leave browser, check any reset required change is applied? if yes, reset system + // + SetupResetReminder (); + // // Automatically load current entry // Note: The following lines of code only execute when Auto boot diff --git a/EdkNt32Pkg/Include/library/EdkGenericBdsLib.h b/EdkNt32Pkg/Include/library/EdkGenericBdsLib.h index 3f01119041..9abda55891 100644 --- a/EdkNt32Pkg/Include/library/EdkGenericBdsLib.h +++ b/EdkNt32Pkg/Include/library/EdkGenericBdsLib.h @@ -59,6 +59,11 @@ extern EFI_HANDLE mBdsImageHandle; #define MIN_ALIGNMENT_SIZE 4 #define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0) +// +// Define maximum characters for boot option variable "BootXXXX" +// +#define BOOT_OPTION_MAX_CHAR 10 + // // This data structure is the part of BDS_CONNECT_ENTRY that we can hard code. // @@ -329,4 +334,49 @@ BdsRefreshBbsTableForBoot ( IN BDS_COMMON_OPTION *Entry ); +EFI_STATUS +BdsDeleteBootOption ( + IN UINTN OptionNumber, + IN OUT UINT16 *BootOrder, + IN OUT UINTN *BootOrderSize + ); + +// +//The interface functions relate with Setup Browser Reset Reminder feature +// +VOID +EnableResetReminderFeature ( + VOID + ); + +VOID +DisableResetReminderFeature ( + VOID + ); + +VOID +EnableResetRequired ( + VOID + ); + +VOID +DisableResetRequired ( + VOID + ); + +BOOLEAN +IsResetReminderFeatureEnable ( + VOID + ); + +BOOLEAN +IsResetRequired ( + VOID + ); + +VOID +SetupResetReminder ( + VOID + ); + #endif // _BDS_LIB_H_ diff --git a/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c b/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c index 576ae7237f..def31023c0 100644 --- a/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c +++ b/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c @@ -19,6 +19,9 @@ Abstract: --*/ +#define MAX_STRING_LEN 200 +static BOOLEAN mFeaturerSwitch = TRUE; +static BOOLEAN mResetRequired = FALSE; extern UINT16 gPlatformBootTimeOutDefault; UINT16 @@ -762,3 +765,218 @@ Returns: return Status; } + +// +// Following are BDS Lib functions which contain all the code about setup browser reset reminder feature. +// Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if +// user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection. +// + +VOID +EnableResetReminderFeature ( + VOID + ) +/*++ + +Routine Description: + + Enable the setup browser reset reminder feature. + This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it. + +Arguments: + + VOID + +Returns: + + VOID + +--*/ +{ + mFeaturerSwitch = TRUE; +} + +VOID +DisableResetReminderFeature ( + VOID + ) +/*++ + +Routine Description: + + Disable the setup browser reset reminder feature. + This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it. + +Arguments: + + VOID + +Returns: + + VOID + +--*/ +{ + mFeaturerSwitch = FALSE; +} + +VOID +EnableResetRequired ( + VOID + ) +/*++ + +Routine Description: + + Record the info that a reset is required. + A module boolean variable is used to record whether a reset is required. + +Arguments: + + VOID + +Returns: + + VOID + +--*/ +{ + mResetRequired = TRUE; +} + +VOID +DisableResetRequired ( + VOID + ) +/*++ + +Routine Description: + + Record the info that no reset is required. + A module boolean variable is used to record whether a reset is required. + +Arguments: + + VOID + +Returns: + + VOID + +--*/ +{ + mResetRequired = FALSE; +} + +BOOLEAN +IsResetReminderFeatureEnable ( + VOID + ) +/*++ + +Routine Description: + + Check whether platform policy enable the reset reminder feature. The default is enabled. + +Arguments: + + VOID + +Returns: + + VOID + +--*/ +{ + return mFeaturerSwitch; +} + +BOOLEAN +IsResetRequired ( + VOID + ) +/*++ + +Routine Description: + + Check if user changed any option setting which needs a system reset to be effective. + +Arguments: + + VOID + +Returns: + + VOID + +--*/ +{ + return mResetRequired; +} + +VOID +SetupResetReminder ( + VOID + ) +/*++ + +Routine Description: + + Check whether a reset is needed, and finish the reset reminder feature. + If a reset is needed, Popup a menu to notice user, and finish the feature + according to the user selection. + +Arguments: + + VOID + +Returns: + + VOID + +--*/ +{ + EFI_STATUS Status; + EFI_FORM_BROWSER_PROTOCOL *Browser; + EFI_INPUT_KEY Key; + CHAR16 *StringBuffer1; + CHAR16 *StringBuffer2; + + + // + //check any reset required change is applied? if yes, reset system + // + if (IsResetReminderFeatureEnable ()) { + if (IsResetRequired ()) { + + Status = gBS->LocateProtocol ( + &gEfiFormBrowserProtocolGuid, + NULL, + &Browser + ); + + StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); + ASSERT (StringBuffer1 != NULL); + StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); + ASSERT (StringBuffer2 != NULL); + StrCpy (StringBuffer1, L"Configuration changed. Reset to apply it Now ? "); + StrCpy (StringBuffer2, L"Enter (YES) / Esc (NO)"); + // + // Popup a menu to notice user + // + do { + Browser->CreatePopUp (2, TRUE, 0, NULL, &Key, StringBuffer1, StringBuffer2); + } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); + + gBS->FreePool (StringBuffer1); + gBS->FreePool (StringBuffer2); + // + // If the user hits the YES Response key, reset + // + if ((Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) { + gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); + } + gST->ConOut->ClearScreen (gST->ConOut); + } + } +} -- 2.39.2