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
next prev parent 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