public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Gao, Zhichao" <zhichao.gao@intel.com>
To: devel@edk2.groups.io
Cc: Jian J Wang <jian.j.wang@intel.com>,
	Hao A Wu <hao.a.wu@intel.com>, Ray Ni <ray.ni@intel.com>,
	Star Zeng <star.zeng@intel.com>,
	Liming gao <liming.gao@intel.com>,
	Sean Brogan <sean.brogan@microsoft.com>,
	Michael Turner <Michael.Turner@microsoft.com>,
	Bret Barkelew <Bret.Barkelew@microsoft.com>
Subject: [PATCH 3/3] MdeModulePkg/CapsuleRuntimeDxe: Control runtime services supported
Date: Wed, 17 Jul 2019 15:37:25 +0800	[thread overview]
Message-ID: <20190717073725.30304-4-zhichao.gao@intel.com> (raw)
In-Reply-To: <20190717073725.30304-1-zhichao.gao@intel.com>

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 <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Liming gao <liming.gao@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Michael Turner <Michael.Turner@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Signed-off-by: Zhichao Gao <zhichao.gao@intel.com>
---
 .../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


  parent reply	other threads:[~2019-07-17  7:37 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-17  7:37 [PATCH 0/3] MdePkg/MdeModulePkg: Introduce a pcd to control runtime services Gao, Zhichao
2019-07-17  7:37 ` [PATCH 1/3] MdePkg/UefiSpec.h: Add define of runtime services support Gao, Zhichao
2019-07-17  7:37 ` [PATCH 2/3] MdePkg: Add new pcd PcdRuntimeServicesSupport Gao, Zhichao
2019-07-17  7:37 ` Gao, Zhichao [this message]
2019-07-17 15:40   ` [edk2-devel] [PATCH 3/3] MdeModulePkg/CapsuleRuntimeDxe: Control runtime services supported Michael D Kinney
2019-07-18  1:56     ` Gao, Zhichao
2019-07-17 13:15 ` [edk2-devel] [PATCH 0/3] MdePkg/MdeModulePkg: Introduce a pcd to control runtime services Laszlo Ersek
2019-07-18  1:37   ` Gao, Zhichao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190717073725.30304-4-zhichao.gao@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox