public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Heyi Guo <guoheyi@huawei.com>
To: Laszlo Ersek <lersek@redhat.com>, <edk2-devel@lists.01.org>
Cc: <wanghaibin.wang@huawei.com>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	 Julien Grall <julien.grall@arm.com>,
	Heyi Guo <heyi.guo@linaro.org>
Subject: Re: [PATCH 1/2] ArmVirtPkg: add runtime instance of FdtPL011SerialPortLib
Date: Tue, 2 Apr 2019 09:45:14 +0800	[thread overview]
Message-ID: <0b2b52c9-00ea-b7c6-9972-840ffb0f93c8@huawei.com> (raw)
In-Reply-To: <41295e12-8f53-7c81-0fd4-bf1f99aea3c8@redhat.com>

Hi Laszlo,

Thanks for your time of reviewing and sorry for code style issues. I accept most of comments, with some questions for below ones:

(7) coding style -- please use empty // lines before and after the
comment line that you have right now.

I remember Ard said this rule conflicted some other rule; not sure if it is decided to use empty // lines around comments.

> +
> +  gInternalRT = SystemTable->RuntimeServices;
> +
> +  Status = InternalGetSystemConfigurationTable (
> +      SystemTable,
> +      &gEfiDxeServicesTableGuid,
> +      (VOID **) &InternalDS
> +      );

(13) coding style -- indentation is broken

It is true that I'm not clear about the indentation rule for multiple-line function call; shall I use 2 spaces indentation following the function name, just like below?

+  Status = InternalGetSystemConfigurationTable (
+             SystemTable,
+             &gEfiDxeServicesTableGuid,
+             (VOID **) &InternalDS
+             );

Shall we follow the coding style in this document:
https://github.com/tianocore-docs/Docs/raw/master/Specifications/CCS_2_1_Draft.pdf?

Thanks,

Heyi

On 2019/4/2 0:14, Laszlo Ersek wrote:
> On 04/01/19 11:06, Heyi Guo wrote:
>> 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.
> (1) I'll defer to Ard on whether this is a good idea after all, even
> just for debugging. I realize the feature is disabled by default, so
> personally I wouldn't mind, I think.
>
>> Once QEMU implements individual firmware UART, we need rewrite
>> PlatformGetRtSerialBase() to get the real runtime serial port base
>> address.
> (2) Assuming Ard is OK with this, please file a feature request in the
> upstream QEMU bug tracker <https://bugs.launchpad.net/qemu/+bugs>, about
> the new UART.
>
> In turn, this launchpad bug URL should be mentioned (a) in the FIXME
> comment in patch #1 (below), (b) more importantly, near the default
> RT_DEBUG setting (of FALSE) in the DSC file, in patch #2.
>
> People looking at the build flags should realize that RT_DEBUG=TRUE is
> basically broken, and find a pointer to the missing QEMU feature.
>
>> 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>
> (3) This pair of signoffs looks strange, but maybe it is justified. Was
> it your intent? (Applies to patch #2 as well.)
>
>> ---
>>   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.
>> +
>> +**/
> (4) From April 2nd through April 9th, the edk2 tree will be locked from
> file additions / removals, due to a patch review period for
> <https://bugzilla.tianocore.org/show_bug.cgi?id=1373>.
>
> I think you will have to repost after that period, and then the license
> blocks in all the new files should follow the new format.
>
>> +
>> +#ifndef _FDT_PL011_SERIAL_PORT_LIB_H_
>> +#define _FDT_PL011_SERIAL_PORT_LIB_H_
>> +
>> +extern UINTN mSerialBaseAddress;
>> +
>> +RETURN_STATUS
>> +EFIAPI
>> +FdtPL011SerialPortLibInitialize (
>> +  VOID
>> +  );
>> +
>> +#endif
> (5) We should list *.h files in INF files, as sources. I.e., please
> update "FdtPL011SerialPortLib.inf" too.
>
> Also, please split these changes to a separate patch. The API export
> patch is not big, bit splitting it off simplifies the diffstat for the
> feature addition.
>
>> 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;
> (6) I think it would be justified to use an "m" prefix here, rather than
> "g".
>
> (7) coding style -- please use empty // lines before and after the
> comment line that you have right now.
>
>> +
>> +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
> (8) indentation / alignment looks broken
>
>> +  )
>> +{
>> +  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,
> (9) These parameters are currently unused, and this is a function that
> we can declare whichever way we want. Can you drop the parameters?
>
>> +    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;
> (10) Coding style -- edk2 doesn't allow initialization of variables with
> auto storage duration.
>
>> +
>> +  Status = FdtPL011SerialPortLibInitialize();
> (11) Coding style -- please insert a space character after the function
> name.
>
>> +  if (RETURN_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  Status = PlatformGetRtSerialBase (ImageHandle, SystemTable, &mRtSerialBaseAddress);
>> +  if (RETURN_ERROR (Status)) {
>> +    return Status;
>> +  }
> (12) Please add a comment here about the next steps -- namely that we're
> going to set up the memory space map for the runtime serial port
> register block.
>
>> +
>> +  gInternalRT = SystemTable->RuntimeServices;
>> +
>> +  Status = InternalGetSystemConfigurationTable (
>> +      SystemTable,
>> +      &gEfiDxeServicesTableGuid,
>> +      (VOID **) &InternalDS
>> +      );
> (13) coding style -- indentation is broken
>
>> +  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.
>> +  //
> (14) Please replace the "Length" variable with a macro then, or even
> open-code SIZE_4KB below.
>
>> +  Status = InternalDS->GetMemorySpaceDescriptor(mRtSerialBaseAddress, &Desc);
> (15) coding style -- missing space
>
>> +  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;
>> +    }
>> +  }
> (16) The indentation is wrong, but more importantly,
>
> (17) I don't like how this logic tries to be halfway-generic. Normally,
> I would suggest making it stricter:
>
> - If GetMemorySpaceDescriptor() fails, just return an error (it should
> never happen).
>
> - If the descriptor reports "nonexistent", then add the range, and set
> the attributes as well.
>
> - If the descriptor reports "MMIO", check the attributes. If there is
> any mismatch in the attributes, return an error.
>
> - If the descriptor reports some type other than nonexistent and MMIO,
> return an error.
>
> - The idea is that we expect to "own" this range.
>
> However, given the current messy state, namely that the MMIO area is
> *not* owned by us (because we're just piggy-backing the normal UART), we
> get to fiddle with *just* the runtime attribute.
>
> This is super ugly. So I suggest extracting this logic too, to a
> separate function, and making a comment (with LP# reference again) that
> once the QEMU feature is implemented, the function will have to be
> rewritten. Separating this mess to a dedicated helper will keep the
> constructor function cleaner, structurally.
>
>> +
>> +  Status = SystemTable->BootServices->CreateEventEx (
>> +      EVT_NOTIFY_SIGNAL,
>> +      TPL_NOTIFY,
>> +      SerialVirtualAddressChangeCallBack,
>> +      NULL,
>> +      &gEfiEventVirtualAddressChangeGuid,
>> +      &mSerialVirtualAddressChangeEvent
>> +      );
> (18) The indentation is wrong.
>
>> +  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);
>> +}
> (19) This implementation has a subtle logic bug, which is -- of course
> -- hidden by the fact that we don't have two UARTs presently.
>
> The logic bug is that the system can be *between* ExitBootServices() and
> SetVirtualAddressMap(). In that state, the boot loader can perfectly
> well call runtime services, such as variable services, and you would
> want to see debug messages on the *runtime* UART (because, we have
> exited the UEFI boot services). However, the virtual address map has not
> been set yet, and so the code above will not flip the drivers to the
> runtime UART.
>
> Therefore, the code in SerialVirtualAddressChangeCallBack() should be
> split, to an EBS callback, and to a VAC callback. In the EBS callback,
> we should only do "mSerialBaseAddress = mRtSerialBaseAddress". And in
> the VAC callback, we should ignore "mRtSerialBaseAddress"; we should
> convert "mSerialBaseAddress" in-place, instead.
>
>> 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
> (20) This comment should be replaced with something non-generic. Please
> explain the core idea behind the library instance in one or two sentences.
>
>> +#
>> +#  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
> (21) We should use "1.28" here --
> <https://edk2-docs.gitbooks.io/edk-ii-inf-specification/content/#edk-ii-module-information-inf-file-specification>.
>
>> +  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
> (22) Please list the header file too.
>
>> +
>> +[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
>>
> This review ate half of my day, and now I'm seriously doubting the
> series gives us enough bang for the buck, with the underlying QEMU
> feature missing -- which will require a significant rework of this code
> anyway.
>
> I don't mind if you post a v2 before upstreaming the QEMU feature, but
> please try to make *really sure* that you get the edk2 coding style bits
> right. Wrong indentation and such is very distracting when I should
> think about ordering of events and so on.
>
> Thanks
> Laszlo
>
> .
>




  reply	other threads:[~2019-04-02  1:45 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 ` [PATCH 1/2] ArmVirtPkg: add runtime instance of FdtPL011SerialPortLib Heyi Guo
2019-04-01 16:14   ` Laszlo Ersek
2019-04-02  1:45     ` Heyi Guo [this message]
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=0b2b52c9-00ea-b7c6-9972-840ffb0f93c8@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