From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: zhichao.gao@intel.com) Received: from mga14.intel.com (mga14.intel.com []) by groups.io with SMTP; Wed, 17 Jul 2019 00:37:34 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Jul 2019 00:37:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,273,1559545200"; d="scan'208";a="187506311" Received: from fieedk001.ccr.corp.intel.com ([10.239.33.119]) by fmsmga001.fm.intel.com with ESMTP; 17 Jul 2019 00:37:32 -0700 From: "Gao, Zhichao" To: devel@edk2.groups.io Cc: Jian J Wang , Hao A Wu , Ray Ni , Star Zeng , Liming gao , Sean Brogan , Michael Turner , Bret Barkelew Subject: [PATCH 3/3] MdeModulePkg/CapsuleRuntimeDxe: Control runtime services supported Date: Wed, 17 Jul 2019 15:37:25 +0800 Message-Id: <20190717073725.30304-4-zhichao.gao@intel.com> X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: <20190717073725.30304-1-zhichao.gao@intel.com> References: <20190717073725.30304-1-zhichao.gao@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1907 Add PcdRuntimeServicesSupport to control whether the capsule services is supported during runtime phase. If the L"RuntimeServicesSupported" variable is not set yet, it would set the variable base on the pcd. If the pcd value is 0x3FFF that means all runtime services is supported at runtime phase, L"RuntimeServicesSupported" would not be set. Cc: Jian J Wang Cc: Hao A Wu Cc: Ray Ni Cc: Star Zeng Cc: Liming gao Cc: Sean Brogan Cc: Michael Turner Cc: Bret Barkelew Signed-off-by: Zhichao Gao --- .../CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf | 3 + .../CapsuleRuntimeDxe/CapsuleService.c | 129 ++++++++++++++++++ 2 files changed, 132 insertions(+) diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf index 9da450722b..95b760d94e 100644 --- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf +++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf @@ -72,6 +72,8 @@ ## SOMETIMES_PRODUCES ## Variable:L"CapsuleLongModeBuffer" # The long mode buffer used by IA32 Capsule PEIM to call X64 CapsuleCoalesce code to handle >4GB capsule blocks gEfiCapsuleVendorGuid gEfiFmpCapsuleGuid ## SOMETIMES_CONSUMES ## GUID # FMP capsule GUID + gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## Variable L"RuntimeServicesSupported" + gEfiEventExitBootServicesGuid ## CONSUMES [Protocols] gEfiCapsuleArchProtocolGuid ## PRODUCES @@ -91,6 +93,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizeNonPopulateCapsule ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizePopulateCapsule ## SOMETIMES_CONSUMES # Populate Image requires reset support. gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleInRamSupport ## CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdRuntimeServicesSupport ## SOME_TIMES_CONSUMES [Pcd.X64] gEfiMdeModulePkgTokenSpaceGuid.PcdCapsulePeiLongModeStackSize ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c index 77b8f00062..8ab77361d8 100644 --- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c +++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c @@ -24,6 +24,12 @@ UINTN mTimes = 0; UINT32 mMaxSizePopulateCapsule = 0; UINT32 mMaxSizeNonPopulateCapsule = 0; +// +// Runtime Services Supported Flag +// Initialize it to 0x3FFF to indicate it is all supported before runtime +// +static UINT16 mRuntimeServicesSupported = 0x3FFF; + /** Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended consumption, the firmware may process the capsule immediately. If the payload should persist @@ -71,6 +77,10 @@ UpdateCapsule ( CHAR16 CapsuleVarName[30]; CHAR16 *TempVarName; + if (!(mRuntimeServicesSupported | EFI_RT_SUPPORTED_UPDATE_CAPSULE)) { + return EFI_UNSUPPORTED; + } + // // Check if platform support Capsule In RAM or not. // Platform could choose to drop CapsulePei/CapsuleX64 and do not support Capsule In RAM. @@ -259,6 +269,10 @@ QueryCapsuleCapabilities ( EFI_CAPSULE_HEADER *CapsuleHeader; BOOLEAN NeedReset; + if (!(mRuntimeServicesSupported | EFI_RT_SUPPORTED_QUERY_CAPSULE_CAPABILITIES)) { + return EFI_UNSUPPORTED; + } + // // Capsule Count can't be less than one. // @@ -343,6 +357,106 @@ QueryCapsuleCapabilities ( return EFI_SUCCESS; } +/** + Set the L"RuntimeServicesSupported" variable depend on the pcd PcdRuntimeServicesSupport. + + Firstly try to get the variable, it may be set in other dxe driver. If it is set, then return + EFI_SUCCESS. If it isn't present, try to set it. + + @retval EFI_SUCCESS The variable is already set. + EFI_NOT_FOUND All runtime services are supported at runtime. No variable is set. + Others Error to get variable or set variable. Unexpected. +**/ +static +EFI_STATUS +SetRuntimeServicesSupported ( + VOID + ) +{ + EFI_STATUS Status; + UINT16 RuntimeServicesSupported; + UINT32 Attributes; + UINTN DataSize; + + // + // Firstly try to get L"RuntimeServicesSupported" variable + // + Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; + DataSize = sizeof (UINT16); + Status = gRT->GetVariable ( + L"RuntimeServicesSupported", + &gEfiGlobalVariableGuid, + &Attributes, + &DataSize, + &RuntimeServicesSupported + ); + + if (Status == EFI_NOT_FOUND) { + // + // L"RuntimeServicesSupported" isn't set yet. Then set it if + // some of the RuntimeServices is unsupported. + // + RuntimeServicesSupported = PcdGet16 (PcdRuntimeServicesSupport); + if (RuntimeServicesSupported != 0x3FFF) { + Status = gRT->SetVariable ( + L"RuntimeServicesSupported", + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (UINT16), + &RuntimeServicesSupported + ); + } else { + // + // Set Status to EFI_NOT_FOUND to indicate not such variable + // + Status = EFI_NOT_FOUND; + } + } + + return Status; +} + +/** + ExitBootServices Event to update the mRuntimeServicesSupported to + affect the runtime services. + + @param[in] Event Event whose notification function is being invoked + @param[in] Context Pointer to the notification function's context +**/ +static +VOID +UpdateRuntimeServicesSupported ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + UINT16 RuntimeServicesSupported; + UINT32 Attributes; + UINTN DataSize; + + Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; + DataSize = sizeof (UINT16); + Status = gRT->GetVariable ( + L"RuntimeServicesSupported", + &gEfiGlobalVariableGuid, + &Attributes, + &DataSize, + &RuntimeServicesSupported + ); + + if (!EFI_ERROR (Status)) { + mRuntimeServicesSupported = RuntimeServicesSupported; + } else if (Status == EFI_NOT_FOUND) { + mRuntimeServicesSupported = 0x3FFF; + } else { + // + // Should never arrive here. + // + ASSERT_EFI_ERROR (Status); + } +} + /** @@ -362,6 +476,7 @@ CapsuleServiceInitialize ( ) { EFI_STATUS Status; + EFI_EVENT Event; mMaxSizePopulateCapsule = PcdGet32(PcdMaxSizePopulateCapsule); mMaxSizeNonPopulateCapsule = PcdGet32(PcdMaxSizeNonPopulateCapsule); @@ -393,5 +508,19 @@ CapsuleServiceInitialize ( ); ASSERT_EFI_ERROR (Status); + Status = SetRuntimeServicesSupported (); + + ASSERT (Status == EFI_NOT_FOUND || Status == EFI_SUCCESS); + + Status = gBS->CreateEventEx( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + UpdateRuntimeServicesSupported, + NULL, + &gEfiEventExitBootServicesGuid, + &Event + ); + ASSERT_EFI_ERROR (Status); + return Status; } -- 2.21.0.windows.1