From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.93; helo=mga11.intel.com; envelope-from=michael.d.kinney@intel.com; receiver=edk2-devel@lists.01.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (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 40B64222630A8 for ; Thu, 22 Feb 2018 09:40:23 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Feb 2018 09:46:24 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.47,378,1515484800"; d="scan'208";a="206187239" Received: from orsmsx110.amr.corp.intel.com ([10.22.240.8]) by fmsmga005.fm.intel.com with ESMTP; 22 Feb 2018 09:46:23 -0800 Received: from orsmsx113.amr.corp.intel.com ([169.254.9.232]) by ORSMSX110.amr.corp.intel.com ([169.254.10.12]) with mapi id 14.03.0319.002; Thu, 22 Feb 2018 09:46:23 -0800 From: "Kinney, Michael D" To: Ard Biesheuvel , "edk2-devel@lists.01.org" , "Kinney, Michael D" CC: "leif.lindholm@linaro.org" , "lersek@redhat.com" , "Gao, Liming" , "afish@apple.com" , "Zeng, Star" , "Ni, Ruiyu" Thread-Topic: [PATCH edk2-platforms v2 1/2] MdePkg: introduce DxeRuntimeDebugLibSerialPort Thread-Index: AQHTq/o017QkTQMl6kqSfq5ksDBRsKOwsRbw Date: Thu, 22 Feb 2018 17:46:22 +0000 Message-ID: References: <20180222162822.22703-1-ard.biesheuvel@linaro.org> <20180222162822.22703-2-ard.biesheuvel@linaro.org> In-Reply-To: <20180222162822.22703-2-ard.biesheuvel@linaro.org> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.0.0.116 dlp-reaction: no-action x-originating-ip: [10.22.254.138] MIME-Version: 1.0 Subject: Re: [PATCH edk2-platforms v2 1/2] MdePkg: introduce DxeRuntimeDebugLibSerialPort X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Feb 2018 17:40:24 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Ard, The check for the runtime flag seems inconsistent. Since the issue being addressed is use of SerialPortLib, can't the mEfiAtRuntime flag be use around SerialPortLib calls only. Mike > -----Original Message----- > From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org] > Sent: Thursday, February 22, 2018 8:28 AM > To: edk2-devel@lists.01.org > Cc: leif.lindholm@linaro.org; lersek@redhat.com; Gao, > Liming ; Kinney, Michael D > ; afish@apple.com; Zeng, > Star ; Ni, Ruiyu > ; Ard Biesheuvel > > Subject: [PATCH edk2-platforms v2 1/2] MdePkg: introduce > DxeRuntimeDebugLibSerialPort >=20 > Introduce a variant of BaseDebugLibSerialPort that > behaves correctly with > regards to the use of the serial port after > ExitBootServices(). Also, it > caches PCD values in the constructor so that no calls > into PcdLib are > made at runtime. >=20 > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ard Biesheuvel > > --- > MdePkg/Library/DxeRuntimeDebugLibSerialPort/DebugLib.c > | 373 ++++++++++++++++++++ >=20 > MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDe > bugLibSerialPort.inf | 56 +++ >=20 > MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDe > bugLibSerialPort.uni | 21 ++ > 3 files changed, 450 insertions(+) >=20 > diff --git > a/MdePkg/Library/DxeRuntimeDebugLibSerialPort/DebugLib.c > b/MdePkg/Library/DxeRuntimeDebugLibSerialPort/DebugLib.c > new file mode 100644 > index 000000000000..8579469029a1 > --- /dev/null > +++ > b/MdePkg/Library/DxeRuntimeDebugLibSerialPort/DebugLib.c > @@ -0,0 +1,373 @@ > +/** @file > + DXE runtime Debug library instance based on Serial > Port library. > + It takes care not to call into SerialPortLib or > PcdLib after > + ExitBootServices() has been called, to prevent > touching hardware that is > + no longer owned by the firmware, or invoking > protocols that are not safe > + for runtime (such as gEfiPcdProtocolGuid) > + > + Copyright (c) 2006 - 2011, Intel Corporation. All > rights reserved.
> + Copyright (c) 2018, Linaro, 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. > + > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +STATIC EFI_EVENT mEfiExitBootServicesEvent; > +STATIC BOOLEAN mEfiAtRuntime; > + > +STATIC UINT8 mDebugClearMemoryValue; > +STATIC UINT8 mDebugPropertyMask; > +STATIC UINT32 mFixedDebugPrintErrorLevel; > + > +// > +// Define the maximum debug and assert message length > that this library supports > +// > +#define MAX_DEBUG_MESSAGE_LENGTH 0x100 > + > +/** > + Set AtRuntime flag as TRUE after ExitBootServices. > + > + @param[in] Event The Event that is being > processed. > + @param[in] Context The Event Context. > + > +**/ > +STATIC > +VOID > +EFIAPI > +ExitBootServicesEvent ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + mEfiAtRuntime =3D TRUE; > +} > + > +/** > + The constructor function to initialize the Serial > Port library and > + register a callback for the ExitBootServices event. > + > + @param[in] ImageHandle The firmware allocated > handle for the EFI image. > + @param[in] SystemTable A pointer to the EFI System > Table. > + > + @retval EFI_SUCCESS The operation completed > successfully. > + @retval other Either the serial port failed > to initialize or the > + ExitBootServices event callback > registration failed. > +**/ > +EFI_STATUS > +EFIAPI > +DxeRuntimeDebugLibSerialPortConstructor ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + > + mDebugClearMemoryValue =3D PcdGet8 > (PcdDebugClearMemoryValue); > + mDebugPropertyMask =3D PcdGet8 > (PcdDebugPropertyMask); > + mFixedDebugPrintErrorLevel =3D PcdGet32 > (PcdFixedDebugPrintErrorLevel); > + > + Status =3D SerialPortInitialize (); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + return SystemTable->BootServices->CreateEventEx > (EVT_NOTIFY_SIGNAL, > + TPL_NOTIFY, > ExitBootServicesEvent, NULL, > + > &gEfiEventExitBootServicesGuid, > + > &mEfiExitBootServicesEvent); > +} > + > +/** > + If a runtime driver exits with an error, it must call > this routine > + to free the allocated resource before the exiting. > + > + @param[in] ImageHandle The firmware allocated > handle for the EFI image. > + @param[in] SystemTable A pointer to the EFI System > Table. > + > + @retval EFI_SUCCESS The Runtime Driver Lib > shutdown successfully. > + @retval EFI_UNSUPPORTED Runtime Driver lib was > not initialized. > +**/ > +EFI_STATUS > +EFIAPI > +DxeRuntimeDebugLibSerialPortDestructor ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + return SystemTable->BootServices->CloseEvent > (mEfiExitBootServicesEvent); > +} > + > +/** > + Prints a debug message to the debug output device if > the specified error level > + is enabled. > + > + If any bit in ErrorLevel is also set in > DebugPrintErrorLevelLib function > + GetDebugPrintErrorLevel (), then print the message > specified by Format and the > + associated variable argument list to the debug output > device. > + > + If Format is NULL, then ASSERT(). > + > + @param ErrorLevel The error level of the debug > message. > + @param Format Format string for the debug > message to print. > + @param ... Variable argument list whose > contents are accessed > + based on the format string > specified by Format. > + > +**/ > +VOID > +EFIAPI > +DebugPrint ( > + IN UINTN ErrorLevel, > + IN CONST CHAR8 *Format, > + ... > + ) > +{ > + CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; > + VA_LIST Marker; > + > + if (mEfiAtRuntime) { > + return; > + } > + > + ASSERT (Format !=3D NULL); > + > + // > + // Check driver debug mask value and global mask > + // > + if ((ErrorLevel & GetDebugPrintErrorLevel ()) =3D=3D 0) { > + return; > + } > + > + // > + // Convert the DEBUG() message to an ASCII String > + // > + VA_START (Marker, Format); > + AsciiVSPrint (Buffer, sizeof (Buffer), Format, > Marker); > + VA_END (Marker); > + > + // > + // Send the print string to a Serial Port > + // > + SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen > (Buffer)); > +} > + > + > +/** > + Prints an assert message containing a filename, line > number, and description. > + This may be followed by a breakpoint or a dead loop. > + > + Print a message of the form "ASSERT > (): \n" > + to the debug output device. If > DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit > + of PcdDebugProperyMask is set then CpuBreakpoint() is > called. Otherwise, if > + DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of > PcdDebugProperyMask is set then > + CpuDeadLoop() is called. If neither of these bits > are set, then this function > + returns immediately after the message is printed to > the debug output device. > + DebugAssert() must actively prevent recursion. If > DebugAssert() is called > + while processing another DebugAssert(), then > DebugAssert() must return > + immediately. > + > + If FileName is NULL, then a string of > "(NULL) Filename" is printed. > + If Description is NULL, then a string > of "(NULL) Description" is > + printed. > + > + @param FileName The pointer to the name of the > source file that generated > + the assert condition. > + @param LineNumber The line number in the source > file that generated the > + assert condition > + @param Description The pointer to the description > of the assert condition. > + > +**/ > +VOID > +EFIAPI > +DebugAssert ( > + IN CONST CHAR8 *FileName, > + IN UINTN LineNumber, > + IN CONST CHAR8 *Description > + ) > +{ > + CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; > + > + if (!mEfiAtRuntime) { > + // > + // Generate the ASSERT() message in Ascii format > + // > + AsciiSPrint (Buffer, sizeof (Buffer), "ASSERT [%a] > %a(%d): %a\n", > + gEfiCallerBaseName, FileName, LineNumber, > Description); > + > + // > + // Send the print string to the Console Output > device > + // > + SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen > (Buffer)); > + } > + > + // > + // Generate a Breakpoint, DeadLoop, or NOP based on > PCD settings > + // > + if ((mDebugPropertyMask & > DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) !=3D 0) { > + CpuBreakpoint (); > + } else if ((mDebugPropertyMask & > + DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) > !=3D 0) { > + CpuDeadLoop (); > + } > +} > + > + > +/** > + Fills a target buffer with PcdDebugClearMemoryValue, > and returns the target > + buffer. > + > + This function fills Length bytes of Buffer with the > value specified by > + PcdDebugClearMemoryValue, and returns Buffer. > + > + If Buffer is NULL, then ASSERT(). > + If Length is greater than (MAX_ADDRESS - Buffer + 1), > then ASSERT(). > + > + @param Buffer The pointer to the target buffer to > be filled with > + PcdDebugClearMemoryValue. > + @param Length The number of bytes in Buffer to > fill with > + PcdDebugClearMemoryValue. > + > + @return Buffer The pointer to the target buffer > filled with > + PcdDebugClearMemoryValue. > + > +**/ > +VOID * > +EFIAPI > +DebugClearMemory ( > + OUT VOID *Buffer, > + IN UINTN Length > + ) > +{ > + if (!mEfiAtRuntime) { > + ASSERT (Buffer !=3D NULL); > + ASSERT (Length <=3D (MAX_ADDRESS - (UINTN)Buffer + > 1)); > + } > + > + return SetMem (Buffer, Length, > mDebugClearMemoryValue); > +} > + > + > +/** > + Returns TRUE if ASSERT() macros are enabled. > + > + This function returns TRUE if the > DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of > + PcdDebugProperyMask is set. Otherwise FALSE is > returned. > + > + @retval TRUE The > DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of > + PcdDebugProperyMask is set. > + @retval FALSE The > DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of > + PcdDebugProperyMask is clear. > + > +**/ > +BOOLEAN > +EFIAPI > +DebugAssertEnabled ( > + VOID > + ) > +{ > + return (BOOLEAN)((mDebugPropertyMask & > + > DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) !=3D 0); > +} > + > + > +/** > + Returns TRUE if DEBUG() macros are enabled. > + > + This function returns TRUE if the > DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of > + PcdDebugProperyMask is set. Otherwise FALSE is > returned. > + > + @retval TRUE The > DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of > + PcdDebugProperyMask is set. > + @retval FALSE The > DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of > + PcdDebugProperyMask is clear. > + > +**/ > +BOOLEAN > +EFIAPI > +DebugPrintEnabled ( > + VOID > + ) > +{ > + return (BOOLEAN)((mDebugPropertyMask & > + DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) > !=3D 0); > +} > + > + > +/** > + Returns TRUE if DEBUG_CODE() macros are enabled. > + > + This function returns TRUE if the > DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of > + PcdDebugProperyMask is set. Otherwise FALSE is > returned. > + > + @retval TRUE The > DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of > + PcdDebugProperyMask is set. > + @retval FALSE The > DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of > + PcdDebugProperyMask is clear. > + > +**/ > +BOOLEAN > +EFIAPI > +DebugCodeEnabled ( > + VOID > + ) > +{ > + return (BOOLEAN)((mDebugPropertyMask & > + DEBUG_PROPERTY_DEBUG_CODE_ENABLED) > !=3D 0); > +} > + > + > +/** > + Returns TRUE if DEBUG_CLEAR_MEMORY() macro is > enabled. > + > + This function returns TRUE if the > DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of > + PcdDebugProperyMask is set. Otherwise FALSE is > returned. > + > + @retval TRUE The > DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of > + PcdDebugProperyMask is set. > + @retval FALSE The > DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of > + PcdDebugProperyMask is clear. > + > +**/ > +BOOLEAN > +EFIAPI > +DebugClearMemoryEnabled ( > + VOID > + ) > +{ > + return (BOOLEAN)((mDebugPropertyMask & > + > DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) !=3D 0); > +} > + > +/** > + Returns TRUE if any one of the bit is set both in > ErrorLevel and > + PcdFixedDebugPrintErrorLevel. > + > + This function compares the bit mask of ErrorLevel and > + PcdFixedDebugPrintErrorLevel. > + > + @retval TRUE Current ErrorLevel is supported. > + @retval FALSE Current ErrorLevel is not supported. > + > +**/ > +BOOLEAN > +EFIAPI > +DebugPrintLevelEnabled ( > + IN CONST UINTN ErrorLevel > + ) > +{ > + return (BOOLEAN)((ErrorLevel & > mFixedDebugPrintErrorLevel) !=3D 0); > +} > diff --git > a/MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntime > DebugLibSerialPort.inf > b/MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntime > DebugLibSerialPort.inf > new file mode 100644 > index 000000000000..d5e9d3f8dee7 > --- /dev/null > +++ > b/MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntime > DebugLibSerialPort.inf > @@ -0,0 +1,56 @@ > +## @file > +# DXE runtime Debug library instance based on Serial > Port library. > +# It takes care not to call into SerialPortLib or > PcdLib after > +# ExitBootServices() has been called, to prevent > touching hardware that is > +# no longer owned by the firmware, or invoking > protocols that are not safe > +# for runtime (such as gEfiPcdProtocolGuid) > +# > +# Copyright (c) 2006 - 2015, Intel Corporation. All > rights reserved.
> +# Copyright (c) 2018, Linaro, 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 =3D 0x0001001A > + BASE_NAME =3D > DxeRuntimeDebugLibSerialPort > + MODULE_UNI_FILE =3D > DxeRuntimeDebugLibSerialPort.uni > + FILE_GUID =3D 9D914E2F-7CCB-41DB- > 8E74-9AFF8F3BBFBF > + MODULE_TYPE =3D DXE_RUNTIME_DRIVER > + VERSION_STRING =3D 1.0 > + LIBRARY_CLASS =3D > DebugLib|DXE_RUNTIME_DRIVER > + CONSTRUCTOR =3D > DxeRuntimeDebugLibSerialPortConstructor > + DESTRUCTOR =3D > DxeRuntimeDebugLibSerialPortDestructor > + > +# > +# VALID_ARCHITECTURES =3D AARCH64 ARM IA32 X64 > IPF EBC > +# > + > +[Sources] > + DebugLib.c > + > +[Packages] > + MdePkg/MdePkg.dec > + > +[LibraryClasses] > + BaseLib > + BaseMemoryLib > + DebugPrintErrorLevelLib > + PcdLib > + PrintLib > + SerialPortLib > + > +[Guids] > + gEfiEventExitBootServicesGuid > ## CONSUMES ## Event > + > +[Pcd] > + gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue > ## CONSUMES > + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask > ## CONSUMES > + gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel > ## CONSUMES > diff --git > a/MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntime > DebugLibSerialPort.uni > b/MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntime > DebugLibSerialPort.uni > new file mode 100644 > index 000000000000..cd65515c4177 > --- /dev/null > +++ > b/MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntime > DebugLibSerialPort.uni > @@ -0,0 +1,21 @@ > +// /** @file > +// Instance of Debug Library based on Serial Port > Library. > +// > +// It uses Print Library to produce formatted output > strings to seiral port device. > +// > +// Copyright (c) 2006 - 2014, Intel Corporation. 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. > +// > +// **/ > + > + > +#string STR_MODULE_ABSTRACT #language en-US > "Instance of Debug Library based on Serial Port Library" > + > +#string STR_MODULE_DESCRIPTION #language en-US > "It uses Print Library to produce formatted output > strings to a serial port device." > + > -- > 2.11.0