From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=45.249.212.190; helo=huawei.com; envelope-from=guoheyi@huawei.com; receiver=edk2-devel@lists.01.org Received: from huawei.com (szxga04-in.huawei.com [45.249.212.190]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 969C12194EB76 for ; Mon, 1 Apr 2019 02:07:54 -0700 (PDT) Received: from DGGEMS410-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id DCCEE3416BCDA9DD6844; Mon, 1 Apr 2019 17:07:51 +0800 (CST) Received: from linux-Bxxcye.huawei.com (10.175.104.222) by DGGEMS410-HUB.china.huawei.com (10.3.19.210) with Microsoft SMTP Server id 14.3.408.0; Mon, 1 Apr 2019 17:07:41 +0800 From: Heyi Guo To: CC: , Heyi Guo , Laszlo Ersek , Ard Biesheuvel , Julien Grall , Heyi Guo Date: Mon, 1 Apr 2019 17:06:29 +0800 Message-ID: <1554109590-16131-2-git-send-email-guoheyi@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1554109590-16131-1-git-send-email-guoheyi@huawei.com> References: <1554109590-16131-1-git-send-email-guoheyi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.104.222] X-CFilter-Loop: Reflected Subject: [PATCH 1/2] ArmVirtPkg: add runtime instance of FdtPL011SerialPortLib X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 X-List-Received-Date: Mon, 01 Apr 2019 09:07:55 -0000 Content-Type: text/plain 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 Cc: Ard Biesheuvel Cc: Julien Grall Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Heyi Guo Signed-off-by: Heyi Guo --- 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.
Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.
- Copyright (c) 2014, Linaro Ltd. All rights reserved.
+ Copyright (c) 2014 - 2019, Linaro Ltd. All rights reserved.
Copyright (c) 2014, Red Hat, Inc.
Copyright (c) 2015, Intel Corporation. All rights reserved.
+ Copyright (c) 2019, Huawei Technologies Co., Ltd. All rights reserved.
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 #include #include +#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.
+ Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.
+ Copyright (c) 2014 - 2019, Linaro Ltd. All rights reserved.
+ Copyright (c) 2014, Red Hat, Inc.
+ Copyright (c) 2015, Intel Corporation. All rights reserved.
+ Copyright (c) 2019, Huawei Technologies Co., Ltd. All rights reserved.
+ + 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.
+ Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.
+ Copyright (c) 2014 - 2019, Linaro Ltd. All rights reserved.
+ Copyright (c) 2014, Red Hat, Inc.
+ Copyright (c) 2015, Intel Corporation. All rights reserved.
+ Copyright (c) 2019, Huawei Technologies Co., Ltd. All rights reserved.
+ + 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 +#include +#include +#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.
+# Copyright (c) 2019, Linaro Ltd. All rights reserved.
+# Copyright (c) 2019, Huawei Technologies Co., Ltd. All rights reserved.
+# +# 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