public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: edk2-devel@lists.01.org
Cc: lersek@redhat.com, leif.lindholm@linaro.org, heyi.guo@linaro.org,
	star.zeng@intel.com, eric.dong@intel.com,
	michael.d.kinney@intel.com, liming.gao@intel.com,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>
Subject: [PATCH 3/4] MdeModulePkg/DxeRuntimeDebugLibSerialPort: invoke RuntimeDebugOutputProtocol
Date: Thu,  1 Mar 2018 18:11:41 +0000	[thread overview]
Message-ID: <20180301181142.16817-4-ard.biesheuvel@linaro.org> (raw)
In-Reply-To: <20180301181142.16817-1-ard.biesheuvel@linaro.org>

Extend the functionality of DxeRuntimeDebugLibSerialPort by invoking
any available RuntimeDebugOutputProtocol to emit debug output at
runtime rather than staying silent.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DebugLib.c                       | 155 +++++++++++++++++---
 MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf |   5 +
 2 files changed, 143 insertions(+), 17 deletions(-)

diff --git a/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DebugLib.c b/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DebugLib.c
index e1266f77fa41..b5460f10ebb6 100644
--- a/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DebugLib.c
+++ b/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DebugLib.c
@@ -25,10 +25,16 @@
 #include <Library/PcdLib.h>
 #include <Library/BaseMemoryLib.h>
 #include <Library/SerialPortLib.h>
+#include <Protocol/RuntimeDebugOutput.h>
 
 STATIC EFI_EVENT      mEfiExitBootServicesEvent;
+STATIC EFI_EVENT      mEfiVirtualAddressChangeEvent;
+STATIC EFI_EVENT      mRegisterRuntimeDebugOutputProtocolEvent;
+STATIC VOID           *mRegisterProtocolRegistration;
 STATIC BOOLEAN        mEfiAtRuntime = FALSE;
 
+STATIC EDK2_RUNTIME_DEBUG_OUTPUT_PROTOCOL   *mRuntimeOutput = NULL;
+
 //
 // Define the maximum debug and assert message length that this library supports
 //
@@ -53,6 +59,58 @@ ExitBootServicesEvent (
 }
 
 /**
+  Attach to the RuntimeDebugOutputProtocol as soon as it gets registered
+
+  @param[in]  Event   The Event that is being processed.
+  @param[in]  Context The Event Context.
+
+**/
+STATIC
+VOID
+EFIAPI
+RegisterRuntimeDebugOutputProtocolEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  EFI_STATUS          Status;
+  EFI_BOOT_SERVICES   *BS;
+
+  BS = Context;
+
+  Status = BS->LocateProtocol (&gEdkiiRuntimeDebugOutputProtocolGuid,
+                 mRegisterProtocolRegistration,
+                 (VOID **)&mRuntimeOutput);
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  BS->CloseEvent (Event);
+}
+
+/**
+  Fix up virtual address of the runtime debug output protocol
+
+  @param[in]  Event   The Event that is being processed.
+  @param[in]  Context The Event Context.
+
+**/
+STATIC
+VOID
+EFIAPI
+VirtualAddressChangeEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  EFI_RUNTIME_SERVICES  *RT;
+
+  RT = Context;
+
+  RT->ConvertPointer (0x0, (VOID **)&mRuntimeOutput);
+}
+
+/**
   The constructor function to initialize the Serial Port library and
   register a callback for the ExitBootServices event.
 
@@ -70,17 +128,64 @@ DxeRuntimeDebugLibSerialPortConstructor (
   IN EFI_SYSTEM_TABLE  *SystemTable
   )
 {
-  EFI_STATUS    Status;
+  EFI_STATUS          Status;
+  EFI_BOOT_SERVICES   *BS;
 
   Status = SerialPortInitialize ();
   if (EFI_ERROR (Status)) {
     return Status;
   }
 
-  return SystemTable->BootServices->CreateEventEx (EVT_NOTIFY_SIGNAL,
-                                      TPL_NOTIFY, ExitBootServicesEvent, NULL,
-                                      &gEfiEventExitBootServicesGuid,
-                                      &mEfiExitBootServicesEvent);
+  BS = SystemTable->BootServices;
+
+  Status = BS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_NOTIFY,
+                 RegisterRuntimeDebugOutputProtocolEvent, BS,
+                 &mRegisterRuntimeDebugOutputProtocolEvent);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Register for protocol notifications on this event
+  //
+  Status = BS->RegisterProtocolNotify (&gEdkiiRuntimeDebugOutputProtocolGuid,
+                 mRegisterRuntimeDebugOutputProtocolEvent,
+                 &mRegisterProtocolRegistration);
+  if (EFI_ERROR (Status)) {
+    goto CloseProtocolEvent;
+  }
+
+  //
+  // Kick the event so we will perform an initial pass of
+  // current installed drivers
+  //
+  BS->SignalEvent (mRegisterRuntimeDebugOutputProtocolEvent);
+
+  Status = BS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_NOTIFY,
+                 ExitBootServicesEvent, NULL,
+                 &gEfiEventExitBootServicesGuid,
+                 &mEfiExitBootServicesEvent);
+  if (EFI_ERROR (Status)) {
+    goto CloseProtocolEvent;
+  }
+
+  Status = BS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_NOTIFY,
+                 VirtualAddressChangeEvent, SystemTable->RuntimeServices,
+                 &gEfiEventVirtualAddressChangeGuid,
+                 &mEfiVirtualAddressChangeEvent);
+  if (EFI_ERROR (Status)) {
+    goto CloseExitBootServicesEvent;
+  }
+
+  return EFI_SUCCESS;
+
+CloseExitBootServicesEvent:
+  BS->CloseEvent (mEfiExitBootServicesEvent);
+
+CloseProtocolEvent:
+  BS->CloseEvent (mRegisterRuntimeDebugOutputProtocolEvent);
+
+  return Status;
 }
 
 /**
@@ -100,7 +205,29 @@ DxeRuntimeDebugLibSerialPortDestructor (
   IN EFI_SYSTEM_TABLE  *SystemTable
   )
 {
-  return SystemTable->BootServices->CloseEvent (mEfiExitBootServicesEvent);
+  EFI_BOOT_SERVICES   *BS;
+
+  BS = SystemTable->BootServices;
+
+  BS->CloseEvent (mRegisterRuntimeDebugOutputProtocolEvent);
+  BS->CloseEvent (mEfiExitBootServicesEvent);
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+UINTN
+DebugWriteOutput (
+  IN  UINT8               *Buffer,
+  IN  UINTN               NumberOfBytes
+  )
+{
+  if (!mEfiAtRuntime) {
+    return SerialPortWrite (Buffer, NumberOfBytes);
+  } else if (mRuntimeOutput != NULL) {
+    return mRuntimeOutput->Write (mRuntimeOutput, Buffer, NumberOfBytes);
+  }
+  return 0;
 }
 
 /**
@@ -129,10 +256,6 @@ DebugPrint (
   CHAR8    Buffer[MAX_DEBUG_MESSAGE_LENGTH];
   VA_LIST  Marker;
 
-  if (mEfiAtRuntime) {
-    return;
-  }
-
   //
   // If Format is NULL, then ASSERT().
   //
@@ -155,7 +278,7 @@ DebugPrint (
   //
   // Send the print string to a Serial Port
   //
-  SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
+  DebugWriteOutput ((UINT8 *)Buffer, AsciiStrLen (Buffer));
 }
 
 
@@ -196,12 +319,10 @@ DebugAssert (
   AsciiSPrint (Buffer, sizeof (Buffer), "ASSERT [%a] %a(%d): %a\n",
     gEfiCallerBaseName, FileName, LineNumber, Description);
 
-  if (!mEfiAtRuntime) {
-    //
-    // Send the print string to the Console Output device
-    //
-    SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
-  }
+  //
+  // Send the print string to the Console Output device
+  //
+  DebugWriteOutput ((UINT8 *)Buffer, AsciiStrLen (Buffer));
 
   //
   // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings
diff --git a/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf b/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
index 813358096982..d2fbdde25f1d 100644
--- a/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
+++ b/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
@@ -36,6 +36,7 @@ [Sources]
   DebugLib.c
 
 [Packages]
+  MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
 
 [LibraryClasses]
@@ -48,6 +49,10 @@ [LibraryClasses]
 
 [Guids]
   gEfiEventExitBootServicesGuid                         ## CONSUMES ## Event
+  gEfiEventVirtualAddressChangeGuid                     ## CONSUMES ## Event
+
+[Protocols]
+  gEdkiiRuntimeDebugOutputProtocolGuid                  ## SOMETIMES_CONSUMES
 
 [Pcd]
   gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue     ## SOMETIMES_CONSUMES
-- 
2.11.0



  parent reply	other threads:[~2018-03-01 18:05 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-01 18:11 [PATCH 0/4] implement runtime debug output protocl Ard Biesheuvel
2018-03-01 18:11 ` [PATCH 1/4] MdePkg: move DxeRuntimeDebugLibSerialPort to MdeModulePkg Ard Biesheuvel
2018-03-01 18:11 ` [PATCH 2/4] MdeModulePkg: introduce runtime debug output protocol Ard Biesheuvel
2018-03-01 18:11 ` Ard Biesheuvel [this message]
2018-03-01 18:11 ` [PATCH 4/4] ArmPlatformPkg: add PL011 UART runtime debug driver Ard Biesheuvel
2018-03-15 12:49   ` Leif Lindholm
2018-04-20 14:14     ` Alexei Fedorov
2018-04-23 10:31       ` Ard Biesheuvel
2018-03-02  2:09 ` [PATCH 0/4] implement runtime debug output protocl Zeng, Star

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=20180301181142.16817-4-ard.biesheuvel@linaro.org \
    --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