public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Heyi Guo <guoheyi@huawei.com>
To: <edk2-devel@lists.01.org>
Cc: <wanghaibin.wang@huawei.com>, Heyi Guo <guoheyi@huawei.com>,
	Laszlo Ersek <lersek@redhat.com>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Julien Grall <julien.grall@arm.com>,
	Heyi Guo <heyi.guo@linaro.org>
Subject: [PATCH 1/2] ArmVirtPkg: add runtime instance of FdtPL011SerialPortLib
Date: Mon, 1 Apr 2019 17:06:29 +0800	[thread overview]
Message-ID: <1554109590-16131-2-git-send-email-guoheyi@huawei.com> (raw)
In-Reply-To: <1554109590-16131-1-git-send-email-guoheyi@huawei.com>

Add a runtime instance of FdtPL011SerialPortLib to support runtime
serial port debug for UEFI runtime services.

The framework is based on below discussion:
https://lists.01.org/pipermail/edk2-devel/2019-March/037986.html

We have decided to use an individual firmware UART for UEFI runtime
debug, however this depends on QEMU to provide this virtual device, so
we still use the OS visible system UART at the moment, with the
potential *risk* of conflicting OS serial port read/write.

Once QEMU implements individual firmware UART, we need rewrite
PlatformGetRtSerialBase() to get the real runtime serial port base
address.

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Julien Grall <julien.grall@arm.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
---
 ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c          |   6 +-
 ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.h          |  32 ++++
 ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLibRuntime.c   | 187 ++++++++++++++++++++
 ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLibRuntime.inf |  59 ++++++
 4 files changed, 282 insertions(+), 2 deletions(-)

diff --git a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c
index 2f10fb7..017ca30 100644
--- a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c
+++ b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c
@@ -3,9 +3,10 @@
 
   Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
   Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.<BR>
-  Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+  Copyright (c) 2014 - 2019, Linaro Ltd. All rights reserved.<BR>
   Copyright (c) 2014, Red Hat, Inc.<BR>
   Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2019, Huawei Technologies Co., Ltd. All rights reserved.<BR>
 
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
@@ -28,8 +29,9 @@
 #include <Pi/PiHob.h>
 #include <Library/HobLib.h>
 #include <Guid/EarlyPL011BaseAddress.h>
+#include "FdtPL011SerialPortLib.h"
 
-STATIC UINTN mSerialBaseAddress;
+UINTN mSerialBaseAddress;
 
 RETURN_STATUS
 EFIAPI
diff --git a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.h b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.h
new file mode 100644
index 0000000..32c0b9b
--- /dev/null
+++ b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.h
@@ -0,0 +1,32 @@
+/** @file
+  Serial I/O Port library internal header
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2014 - 2019, Linaro Ltd. All rights reserved.<BR>
+  Copyright (c) 2014, Red Hat, Inc.<BR>
+  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2019, Huawei Technologies Co., Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _FDT_PL011_SERIAL_PORT_LIB_H_
+#define _FDT_PL011_SERIAL_PORT_LIB_H_
+
+extern UINTN mSerialBaseAddress;
+
+RETURN_STATUS
+EFIAPI
+FdtPL011SerialPortLibInitialize (
+  VOID
+  );
+
+#endif
diff --git a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLibRuntime.c b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLibRuntime.c
new file mode 100644
index 0000000..4a7b0b5
--- /dev/null
+++ b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLibRuntime.c
@@ -0,0 +1,187 @@
+/** @file
+  Initialization for runtime serial I/O port library
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2014 - 2019, Linaro Ltd. All rights reserved.<BR>
+  Copyright (c) 2014, Red Hat, Inc.<BR>
+  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2019, Huawei Technologies Co., Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// UEFI runtime serial port debug framework:
+// - Use BaseDebugLibSerialPort for DebugLib
+// - Boot time debug message of runtime modules will be directed to the same
+//   serial port of other modules
+// - Runtime debug message should be directed to an individual firmware serial
+//   port to avoid conflict with OS serial port access
+//
+
+#include <Uefi.h>
+#include <Guid/EventGroup.h>
+#include <Library/BaseMemoryLib.h>
+#include "FdtPL011SerialPortLib.h"
+
+STATIC UINTN mRtSerialBaseAddress;
+STATIC EFI_EVENT mSerialVirtualAddressChangeEvent = NULL;
+// We can't use gRT directly due to library dependency.
+STATIC EFI_RUNTIME_SERVICES *gInternalRT = NULL;
+
+VOID
+EFIAPI
+SerialVirtualAddressChangeCallBack (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  gInternalRT->ConvertPointer (0, (VOID **) &mRtSerialBaseAddress);
+  mSerialBaseAddress = mRtSerialBaseAddress;
+}
+
+//
+// To avoid library constructor looped dependence, we copy
+// EfiGetSystemConfigurationTable() here instead of using UefiLib.
+//
+STATIC
+RETURN_STATUS
+InternalGetSystemConfigurationTable (
+  IN  EFI_SYSTEM_TABLE  *SystemTable,
+  IN  EFI_GUID  *TableGuid,
+  OUT VOID      **Table
+  )
+{
+  UINTN             Index;
+
+  *Table = NULL;
+  for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {
+    if (CompareGuid (TableGuid, &(SystemTable->ConfigurationTable[Index].VendorGuid))) {
+      *Table = SystemTable->ConfigurationTable[Index].VendorTable;
+      return RETURN_SUCCESS;
+    }
+  }
+
+  return RETURN_NOT_FOUND;
+}
+
+STATIC
+RETURN_STATUS
+PlatformGetRtSerialBase (
+    IN EFI_HANDLE        ImageHandle,
+    IN EFI_SYSTEM_TABLE  *SystemTable,
+    IN OUT UINTN         *SerialBase
+    )
+{
+  //
+  // FIXME: Using system serial port will probably cause conflict with OS serial
+  // port access, so this code can ONLY be used for debug purpose and may cause
+  // unexpected system behaviour!
+  // We need change to the individual firmware serial port as soon as QEMU
+  // implements that.
+  //
+  *SerialBase = mSerialBaseAddress;
+  return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+EFIAPI
+SerialPortLibConstructorRuntime (
+    IN EFI_HANDLE        ImageHandle,
+    IN EFI_SYSTEM_TABLE  *SystemTable
+    )
+{
+  RETURN_STATUS                   Status;
+  UINT64                          Length = SIZE_4KB;
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR Desc = {0};
+  EFI_DXE_SERVICES                *InternalDS = NULL;
+
+  Status = FdtPL011SerialPortLibInitialize();
+  if (RETURN_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = PlatformGetRtSerialBase (ImageHandle, SystemTable, &mRtSerialBaseAddress);
+  if (RETURN_ERROR (Status)) {
+    return Status;
+  }
+
+  gInternalRT = SystemTable->RuntimeServices;
+
+  Status = InternalGetSystemConfigurationTable (
+      SystemTable,
+      &gEfiDxeServicesTableGuid,
+      (VOID **) &InternalDS
+      );
+  if (RETURN_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // For the serial port register space length is only 4KB, we don't need to
+  // check if the descriptor is large enough to cover the space.
+  //
+  Status = InternalDS->GetMemorySpaceDescriptor(mRtSerialBaseAddress, &Desc);
+  if (RETURN_ERROR (Status) ||
+      Desc.GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
+    Status = InternalDS->AddMemorySpace (
+        EfiGcdMemoryTypeMemoryMappedIo,
+        mRtSerialBaseAddress,
+        Length,
+        EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+        );
+    if (RETURN_ERROR (Status)) {
+      return Status;
+    }
+    Desc.Attributes = EFI_MEMORY_UC;
+  }
+
+  if ((Desc.Attributes & EFI_MEMORY_RUNTIME) == 0) {
+    Desc.Attributes |= EFI_MEMORY_RUNTIME;
+    Status = InternalDS->SetMemorySpaceAttributes (
+        mRtSerialBaseAddress,
+        Length,
+        Desc.Attributes
+        );
+    if(RETURN_ERROR (Status)){
+      return Status;
+    }
+  }
+
+  Status = SystemTable->BootServices->CreateEventEx (
+      EVT_NOTIFY_SIGNAL,
+      TPL_NOTIFY,
+      SerialVirtualAddressChangeCallBack,
+      NULL,
+      &gEfiEventVirtualAddressChangeGuid,
+      &mSerialVirtualAddressChangeEvent
+      );
+  if (RETURN_ERROR (Status)) {
+    mSerialVirtualAddressChangeEvent = NULL;
+  }
+
+  return Status;
+}
+
+RETURN_STATUS
+EFIAPI
+SerialPortLibDestructor (
+    IN EFI_HANDLE        ImageHandle,
+    IN EFI_SYSTEM_TABLE  *SystemTable
+    )
+{
+
+  if (!mSerialVirtualAddressChangeEvent) {
+    return RETURN_SUCCESS;
+  }
+
+  return SystemTable->BootServices->CloseEvent (mSerialVirtualAddressChangeEvent);
+}
diff --git a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLibRuntime.inf b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLibRuntime.inf
new file mode 100644
index 0000000..9403030
--- /dev/null
+++ b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLibRuntime.inf
@@ -0,0 +1,59 @@
+#/** @file
+#
+#  Component description file for FdtPL011SerialPortLibRuntime module
+#
+#  Copyright (c) 2011-2015, ARM Ltd. All rights reserved.<BR>
+#  Copyright (c) 2019, Linaro Ltd. All rights reserved.<BR>
+#  Copyright (c) 2019, Huawei Technologies Co., Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FdtPL011SerialPortLibRuntime
+  FILE_GUID                      = 83afbb90-38c6-11e9-aeab-203db202c950
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SerialPortLib|DXE_RUNTIME_DRIVER
+  CONSTRUCTOR                    = SerialPortLibConstructorRuntime
+  DESTRUCTOR                     = SerialPortLibDestructor
+
+[Sources.common]
+  FdtPL011SerialPortLib.c
+  FdtPL011SerialPortLibRuntime.c
+
+[LibraryClasses]
+  BaseMemoryLib
+  HobLib
+  PL011UartLib
+
+[Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  ArmVirtPkg/ArmVirtPkg.dec
+  ArmPkg/ArmPkg.dec
+
+[FixedPcd]
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
+  gArmPlatformTokenSpaceGuid.PL011UartClkInHz
+
+[Guids]
+  gEarlyPL011BaseAddressGuid
+  gEfiDxeServicesTableGuid
+  gEfiEventVirtualAddressChangeGuid
+
+[Depex]
+  gEfiCpuArchProtocolGuid
-- 
1.8.3.1



  reply	other threads:[~2019-04-01  9:07 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-01  9:06 [PATCH 0/2] Enable runtime serial port debug for ArmVirtQemu Heyi Guo
2019-04-01  9:06 ` Heyi Guo [this message]
2019-04-01 16:14   ` [PATCH 1/2] ArmVirtPkg: add runtime instance of FdtPL011SerialPortLib Laszlo Ersek
2019-04-02  1:45     ` Heyi Guo
2019-04-02  7:38       ` Laszlo Ersek
2019-04-01  9:06 ` [PATCH 2/2] ArmVirtQemu: enable runtime debug by build flag Heyi Guo
2019-04-01 16:14   ` Laszlo Ersek

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=1554109590-16131-2-git-send-email-guoheyi@huawei.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