public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH] Features/Intel: Add Usb3StatusCodeHandlerLib in Usb3DebugFeaturePkg
@ 2020-06-11 14:54 Tan, Ming
  0 siblings, 0 replies; only message in thread
From: Tan, Ming @ 2020-06-11 14:54 UTC (permalink / raw)
  To: devel; +Cc: Eric Dong, Liming Gao

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2794

In Features/Intel/Debugging/Usb3DebugFeaturePkg/Library, add
Usb3StatusCodeHandlerLib, used for output status code through USB3.

Also remove the prefix directory path of Debugging/ in .dsc file.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Ming Tan <ming.tan@intel.com>
---
 .../Include/Usb3DebugFeature.dsc              |  68 +++-
 .../Usb3DebugPortParamLibCmos.c               | 100 ++++++
 .../Usb3DebugPortParamLibCmos.inf             |  65 ++++
 .../PeiUsb3StatusCodeHandlerLib.c             | 216 +++++++++++++
 .../PeiUsb3StatusCodeHandlerLib.inf           |  52 +++
 .../RuntimeDxeUsb3StatusCodeHandlerLib.c      | 297 ++++++++++++++++++
 .../RuntimeDxeUsb3StatusCodeHandlerLib.inf    |  54 ++++
 .../SmmUsb3StatusCodeHandlerLib.c             | 250 +++++++++++++++
 .../SmmUsb3StatusCodeHandlerLib.inf           |  53 ++++
 .../Debugging/Usb3DebugFeaturePkg/Readme.md   | 174 ++++++----
 .../Usb3DebugFeaturePkg.dec                   |   2 +
 11 files changed, 1262 insertions(+), 69 deletions(-)
 create mode 100644 Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortParamLibCmos/Usb3DebugPortParamLibCmos.c
 create mode 100644 Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortParamLibCmos/Usb3DebugPortParamLibCmos.inf
 create mode 100644 Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/PeiUsb3StatusCodeHandlerLib.c
 create mode 100644 Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/PeiUsb3StatusCodeHandlerLib.inf
 create mode 100644 Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/RuntimeDxeUsb3StatusCodeHandlerLib.c
 create mode 100644 Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/RuntimeDxeUsb3StatusCodeHandlerLib.inf
 create mode 100644 Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/SmmUsb3StatusCodeHandlerLib.c
 create mode 100644 Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/SmmUsb3StatusCodeHandlerLib.inf

diff --git a/Features/Intel/Debugging/Usb3DebugFeaturePkg/Include/Usb3DebugFeature.dsc b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Include/Usb3DebugFeature.dsc
index 494dd7a342..548edc6182 100644
--- a/Features/Intel/Debugging/Usb3DebugFeaturePkg/Include/Usb3DebugFeature.dsc
+++ b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Include/Usb3DebugFeature.dsc
@@ -25,6 +25,16 @@
   !error "DXE_ARCH must be specified to build this feature!"
 !endif
 
+################################################################################
+#
+# PCD Section - list of PCD Entries modified by the feature.
+#
+################################################################################
+
+# Unmark the following and StatusCodeHandler.efi to build the .dsc file directly
+#[PcdsDynamicDefault]
+#  gUsb3DebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseUsb3|TRUE
+
 ################################################################################
 #
 # Library Class section - list of all Library Classes needed by this feature.
@@ -48,6 +58,9 @@
   UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
   UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
   UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
 
 [LibraryClasses.common.PEIM]
   #######################################
@@ -57,6 +70,9 @@
   MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
   PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
 
+[LibraryClasses.IA32.PEIM,LibraryClasses.IA32.PEI_CORE,LibraryClasses.IA32.SEC]
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+
 [LibraryClasses.common.DXE_DRIVER]
   #######################################
   # Edk2 Packages
@@ -71,6 +87,7 @@
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
   UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
 
 [LibraryClasses.common.UEFI_DRIVER]
   #######################################
@@ -79,6 +96,17 @@
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
 
+[LibraryClasses.X64.DXE_SMM_DRIVER]
+  #######################################
+  # Edk2 Packages
+  #######################################
+  SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
+  MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
+  SmmIoLib|MdePkg/Library/SmmIoLib/SmmIoLib.inf
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf
+
+
 ################################################################################
 #
 # Component section - list of all components that need built for this feature.
@@ -106,10 +134,18 @@
 
   # Add library instances here that are not included in package components and should be tested
   # in the package build.
-  Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibNull.inf
-  Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortParamLibPcd/Usb3DebugPortParamLibPcd.inf
-  Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibPei.inf
-  Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibPeiIoMmu.inf
+  Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibNull.inf
+  Usb3DebugFeaturePkg/Library/Usb3DebugPortParamLibPcd/Usb3DebugPortParamLibPcd.inf
+  Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibPei.inf
+  Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibPeiIoMmu.inf
+  Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/PeiUsb3StatusCodeHandlerLib.inf
+
+  # The following is an example for used with StatusCodeHandler:
+# MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf {
+#   <LibraryClasses>
+#     Usb3DebugPortLib|Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibNull.inf
+#     NULL|Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/PeiUsb3StatusCodeHandlerLib.inf
+# }
 
   # Add components here that should be included in the package build.
 
@@ -126,10 +162,26 @@
 
   # Add library instances here that are not included in package components and should be tested
   # in the package build.
-  Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibNull.inf
-  Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortParamLibPcd/Usb3DebugPortParamLibPcd.inf
-  Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibDxe.inf
-  Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibDxeIoMmu.inf
+  Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibNull.inf
+  Usb3DebugFeaturePkg/Library/Usb3DebugPortParamLibPcd/Usb3DebugPortParamLibPcd.inf
+  Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibDxe.inf
+  Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibDxeIoMmu.inf
+
+  Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/RuntimeDxeUsb3StatusCodeHandlerLib.inf
+  Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/SmmUsb3StatusCodeHandlerLib.inf
+
+  # The following is an example for used with StatusCodeHandler:
+# MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf {
+#   <LibraryClasses>
+#     Usb3DebugPortLib|Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibNull.inf
+#     NULL|Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/RuntimeDxeUsb3StatusCodeHandlerLib.inf
+# }
+
+# MdeModulePkg/Universal/StatusCodeHandler/Smm/StatusCodeHandlerSmm.inf {
+#   <LibraryClasses>
+#     Usb3DebugPortLib|Usb3DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibNull.inf
+#     NULL|Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/SmmUsb3StatusCodeHandlerLib.inf
+# }
 
   # Add components here that should be included in the package build.
 
diff --git a/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortParamLibCmos/Usb3DebugPortParamLibCmos.c b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortParamLibCmos/Usb3DebugPortParamLibCmos.c
new file mode 100644
index 0000000000..41172eb89c
--- /dev/null
+++ b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortParamLibCmos/Usb3DebugPortParamLibCmos.c
@@ -0,0 +1,100 @@
+/** @file
+  USB debug Port Parameter library instance based on PCD.
+
+ @copyright
+  INTEL CONFIDENTIAL
+  Copyright 2011 - 2016 Intel Corporation.
+
+  The source code contained or described herein and all documents related to the
+  source code ("Material") are owned by Intel Corporation or its suppliers or
+  licensors. Title to the Material remains with Intel Corporation or its suppliers
+  and licensors. The Material may contain trade secrets and proprietary and
+  confidential information of Intel Corporation and its suppliers and licensors,
+  and is protected by worldwide copyright and trade secret laws and treaty
+  provisions. No part of the Material may be used, copied, reproduced, modified,
+  published, uploaded, posted, transmitted, distributed, or disclosed in any way
+  without Intel's prior express written permission.
+
+  No license under any patent, copyright, trade secret or other intellectual
+  property right is granted to or conferred upon you by disclosure or delivery
+  of the Materials, either expressly, by implication, inducement, estoppel or
+  otherwise. Any license under such intellectual property rights must be
+  express and approved by Intel in writing.
+
+  Unless otherwise agreed by Intel in writing, you may not remove or alter
+  this notice or any other notice embedded in Materials by Intel or
+  Intel's suppliers or licensors in any way.
+
+  This file contains 'Framework Code' and is licensed as such under the terms
+  of your license agreement with Intel or your vendor. This file may not be 
+  modified, except as allowed by additional terms of your license agreement.
+
+@par Specification Reference:
+**/
+
+#include <Base.h>
+#include <Library/DebugLib.h>
+#include <Library/CmosAccessLib.h>
+#include <Library/PcdLib.h>
+#include <Library/Usb3DebugPortParamLib.h>
+
+/**
+  Returns the USB3 debug port controller.
+  bit:  0~ 7: Function
+  bit:  8~15: Device
+  bit: 16~24: Bus
+  
+  @return  Controller information of USB debug port.
+
+**/
+UINT32
+EFIAPI
+GetUsb3DebugPortController (
+  VOID
+  )
+{
+  USB3_DEBUG_PORT_CONTROLLER       UsbDebugPort;
+
+  UsbDebugPort.Controller = 0;
+  UsbDebugPort.PciAddress.Bus = CmosRead8 (PcdGet8 (PcdUsb3DebugPortBusIndex));
+  UsbDebugPort.PciAddress.Device = CmosRead8 (PcdGet8 (PcdUsb3DebugPortDeviceIndex));
+  UsbDebugPort.PciAddress.Function = CmosRead8 (PcdGet8 (PcdUsb3DebugPortFunctionIndex));
+  if (UsbDebugPort.Controller == 0) {
+    // Just in case CMOS cleared
+    UsbDebugPort.PciAddress.Bus = PcdGet8(PcdUsbSerialXhciBus);
+    UsbDebugPort.PciAddress.Device = PcdGet8(PcdUsbSerialXhciDev);
+    UsbDebugPort.PciAddress.Function = PcdGet8(PcdUsbSerialXhciFunc);
+    CmosWrite8 (PcdGet8 (PcdUsb3DebugPortBusIndex), UsbDebugPort.PciAddress.Bus);
+    CmosWrite8 (PcdGet8 (PcdUsb3DebugPortDeviceIndex), UsbDebugPort.PciAddress.Device);
+    CmosWrite8 (PcdGet8 (PcdUsb3DebugPortFunctionIndex), UsbDebugPort.PciAddress.Function);
+  }
+
+  return UsbDebugPort.Controller;
+}
+
+/**
+  Sets the USB3 debug port controller.
+  bit:  0~ 7: Function
+  bit:  8~15: Device
+  bit: 16~24: Bus
+  
+  @param[in]    Controller information of USB debug port value to be set.
+
+  @retval  TRUE           The controller of USB debug port was sucessfully set.
+  @retval  FALSE          The controller of USB debug port could not be set.
+
+**/
+BOOLEAN
+EFIAPI
+SetUsb3DebugPortController (
+  UINT32        Controller
+  )
+{
+  USB3_DEBUG_PORT_CONTROLLER       UsbDebugPort;
+
+  UsbDebugPort.Controller = Controller;
+  CmosWrite8 (PcdGet8 (PcdUsb3DebugPortBusIndex), UsbDebugPort.PciAddress.Bus);
+  CmosWrite8 (PcdGet8 (PcdUsb3DebugPortDeviceIndex), UsbDebugPort.PciAddress.Device);
+  CmosWrite8 (PcdGet8 (PcdUsb3DebugPortFunctionIndex), UsbDebugPort.PciAddress.Function);
+  return TRUE;
+}
diff --git a/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortParamLibCmos/Usb3DebugPortParamLibCmos.inf b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortParamLibCmos/Usb3DebugPortParamLibCmos.inf
new file mode 100644
index 0000000000..0dd614e645
--- /dev/null
+++ b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3DebugPortParamLibCmos/Usb3DebugPortParamLibCmos.inf
@@ -0,0 +1,65 @@
+### @file
+# Get and/or set USB 3 debug port controller based on PCD.
+#
+# @copyright
+#  INTEL CONFIDENTIAL
+#  Copyright 2013 - 2020 Intel Corporation.
+#
+#  The source code contained or described herein and all documents related to the
+#  source code ("Material") are owned by Intel Corporation or its suppliers or
+#  licensors. Title to the Material remains with Intel Corporation or its suppliers
+#  and licensors. The Material may contain trade secrets and proprietary and
+#  confidential information of Intel Corporation and its suppliers and licensors,
+#  and is protected by worldwide copyright and trade secret laws and treaty
+#  provisions. No part of the Material may be used, copied, reproduced, modified,
+#  published, uploaded, posted, transmitted, distributed, or disclosed in any way
+#  without Intel's prior express written permission.
+#
+#  No license under any patent, copyright, trade secret or other intellectual
+#  property right is granted to or conferred upon you by disclosure or delivery
+#  of the Materials, either expressly, by implication, inducement, estoppel or
+#  otherwise. Any license under such intellectual property rights must be
+#  express and approved by Intel in writing.
+#
+#  Unless otherwise agreed by Intel in writing, you may not remove or alter
+#  this notice or any other notice embedded in Materials by Intel or
+#  Intel's suppliers or licensors in any way.
+#
+#  This file contains 'Framework Code' and is licensed as such under the terms
+#  of your license agreement with Intel or your vendor. This file may not be
+#  modified, except as allowed by additional terms of your license agreement.
+#
+# @par Specification Reference:
+#
+# @par Glossary:
+###
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = Usb3DebugPortParamLibCmos
+  FILE_GUID                      = 45837D7D-C4AB-4f77-8D51-F9355EB93139
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = Usb3DebugPortParamLib
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  CmosAccessLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  BoardModulePkg/BoardModulePkg.dec
+  Debugging/Usb3DebugFeaturePkg/Usb3DebugFeaturePkg.dec
+
+[Pcd]
+  gAcpiDebugFeaturePkgTokenSpaceGuid.PcdUsbSerialXhciBus
+  gAcpiDebugFeaturePkgTokenSpaceGuid.PcdUsbSerialXhciDev
+  gAcpiDebugFeaturePkgTokenSpaceGuid.PcdUsbSerialXhciFunc
+  gAcpiDebugFeaturePkgTokenSpaceGuid.PcdUsb3DebugPortBusIndex
+  gAcpiDebugFeaturePkgTokenSpaceGuid.PcdUsb3DebugPortDeviceIndex
+  gAcpiDebugFeaturePkgTokenSpaceGuid.PcdUsb3DebugPortFunctionIndex
+
+[Sources]
+  Usb3DebugPortParamLibCmos.c
+
diff --git a/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/PeiUsb3StatusCodeHandlerLib.c b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/PeiUsb3StatusCodeHandlerLib.c
new file mode 100644
index 0000000000..d144312301
--- /dev/null
+++ b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/PeiUsb3StatusCodeHandlerLib.c
@@ -0,0 +1,216 @@
+/** @file
+  Usb3 status code implementation.
+
+  Copyright (c) 2011 - 2020, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/PeiServicesLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Ppi/ReportStatusCodeHandler.h>
+
+#include <Library/Usb3DebugPortLib.h>
+
+#include <Guid/StatusCodeDataTypeId.h>
+#include <Guid/StatusCodeDataTypeDebug.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/PrintLib.h>
+
+/**
+  Convert status code value and extended data to readable ASCII string, send string to Usb3 device.
+
+  @param  PeiServices      An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or
+                           software entity. This includes information about the class and
+                           subclass that is used to classify the entity as well as an operation.
+                           For progress codes, the operation is the current activity.
+                           For error codes, it is the exception.For debug codes,it is not defined at this time.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. A system may contain multiple entities that match a class/subclass
+                           pairing. The instance differentiates between them. An instance of 0 indicates
+                           that instance information is unavailable, not meaningful, or not relevant.
+                           Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      Status code reported to Usb3 successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+Usb3StatusCodeReportWorker (
+  IN CONST  EFI_PEI_SERVICES        **PeiServices,
+  IN EFI_STATUS_CODE_TYPE           CodeType,
+  IN EFI_STATUS_CODE_VALUE          Value,
+  IN UINT32                         Instance,
+  IN CONST EFI_GUID                 *CallerId,
+  IN CONST EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  )
+{
+  CHAR8           *Filename;
+  CHAR8           *Description;
+  CHAR8           *Format;
+  CHAR8           Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
+  UINT32          ErrorLevel;
+  UINT32          LineNumber;
+  UINTN           CharCount;
+  BASE_LIST       Marker;
+
+  Buffer[0] = '\0';
+
+  if (Data != NULL &&
+      CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeStringGuid) &&
+      ((EFI_STATUS_CODE_STRING_DATA *) Data)->StringType == EfiStringAscii) {
+    //
+    // Print String Data.
+    //
+    Usb3DebugPortWrite (
+      (UINT8 *) (((EFI_STATUS_CODE_STRING_DATA *) Data)->String.Ascii),
+      ((EFI_STATUS_CODE_STRING_DATA *) Data)->DataHeader.Size
+      );
+    return EFI_SUCCESS;
+  } else if (Data != NULL &&
+             ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
+    //
+    // Print ASSERT() information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "\n\rPEI_ASSERT!: %a (%d): %a\n\r",
+                  Filename,
+                  LineNumber,
+                  Description
+                  );
+  } else if (Data != NULL &&
+             ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
+    //
+    // Print DEBUG() information into output buffer.
+    //
+    CharCount = AsciiBSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  Format,
+                  Marker
+                  );
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
+    //
+    // Print ERROR information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "ERROR: C%08x:V%08x I%x",
+                  CodeType,
+                  Value,
+                  Instance
+                  );
+
+    ASSERT(CharCount > 0);
+
+    if (CallerId != NULL) {
+      CharCount += AsciiSPrint (
+                     &Buffer[CharCount],
+                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                     " %g",
+                     CallerId
+                     );
+    }
+
+    if (Data != NULL) {
+      CharCount += AsciiSPrint (
+                     &Buffer[CharCount],
+                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                     " %x",
+                     Data
+                     );
+    }
+
+    CharCount += AsciiSPrint (
+                   &Buffer[CharCount],
+                   (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                   "\n\r"
+                   );
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
+    //
+    // Print PROGRESS information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "PROGRESS CODE: V%08x I%x\n\r",
+                  Value,
+                  Instance
+                  );
+  } else {
+    //
+    // Code type is not defined.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "Undefined: C%08x:V%08x I%x\n\r",
+                  CodeType,
+                  Value,
+                  Instance
+                  );
+  }
+
+  //
+  // Call Usb3DebugPortLib function to do print.
+  //
+  Usb3DebugPortWrite ((UINT8 *) Buffer, CharCount);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Constructor function of PeiUsb3StatusCodeHandlerLib.
+
+  This function is the constructor function of this USB3 Status Code Handler Library for PEI Phase.
+  It check whether need beep, and register it to gEfiPeiRscHandlerPpiGuid.
+
+  @param  FileHandle  Handle of the file being invoked.
+  @param  PeiServices Describes the list of possible PEI Services.
+
+  @retval EFI_SUCESS  The entry point of DXE IPL PEIM executes successfully.
+
+**/
+RETURN_STATUS
+EFIAPI
+PeiUsb3StatusCodeHandlerLibConstructor (
+  IN       EFI_PEI_FILE_HANDLE       FileHandle,
+  IN CONST EFI_PEI_SERVICES          **PeiServices
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PEI_RSC_HANDLER_PPI     *RscHandlerPpi;
+
+  if (!PcdGetBool (PcdStatusCodeUseUsb3)) {
+    return RETURN_SUCCESS;
+  }
+
+  Status = PeiServicesLocatePpi (
+             &gEfiPeiRscHandlerPpiGuid,
+             0,
+             NULL,
+             (VOID **) &RscHandlerPpi
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = Usb3DebugPortInitialize ();
+  ASSERT_EFI_ERROR (Status);
+
+  Status = RscHandlerPpi->Register (Usb3StatusCodeReportWorker);
+  ASSERT_EFI_ERROR (Status);
+
+  return RETURN_SUCCESS;
+}
diff --git a/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/PeiUsb3StatusCodeHandlerLib.inf b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/PeiUsb3StatusCodeHandlerLib.inf
new file mode 100644
index 0000000000..7315ea5bf4
--- /dev/null
+++ b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/PeiUsb3StatusCodeHandlerLib.inf
@@ -0,0 +1,52 @@
+## @file
+#  USB3 status code implementation.
+#
+# Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# vendor.  This file may not be modified, except as allowed by
+# additional terms of your license agreement.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiUsb3StatusCodeHandlerLib
+  FILE_GUID                      = 4FC1BF4D-0FC4-4B0A-B02E-302705076C6A
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  CONSTRUCTOR                    = PeiUsb3StatusCodeHandlerLibConstructor
+  LIBRARY_CLASS                  = StatusCodeHandlerLib|SEC PEIM PEI_COR
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is only for build)
+#
+
+[Sources]
+  PeiUsb3StatusCodeHandlerLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Usb3DebugFeaturePkg/Usb3DebugFeaturePkg.dec
+
+[LibraryClasses]
+  PeiServicesLib
+  PcdLib
+  DebugLib
+  ReportStatusCodeLib
+  Usb3DebugPortLib
+
+[Guids]
+  gEfiStatusCodeDataTypeStringGuid              ## SOMETIMES_CONSUMES ## GUID
+
+[Pcd]
+  gUsb3DebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseUsb3               ## CONSUMES
+
+[Ppis]
+  gEfiPeiRscHandlerPpiGuid                      ## CONSUMES
+
+[Depex]
+  TRUE
diff --git a/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/RuntimeDxeUsb3StatusCodeHandlerLib.c b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/RuntimeDxeUsb3StatusCodeHandlerLib.c
new file mode 100644
index 0000000000..25c991d195
--- /dev/null
+++ b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/RuntimeDxeUsb3StatusCodeHandlerLib.c
@@ -0,0 +1,297 @@
+/** @file
+  Usb3 status code implementation.
+
+  Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Guid/EventGroup.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Protocol/ReportStatusCodeHandler.h>
+
+#include <Library/Usb3DebugPortLib.h>
+
+#include <Guid/StatusCodeDataTypeId.h>
+#include <Guid/StatusCodeDataTypeDebug.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/PrintLib.h>
+
+
+EFI_RSC_HANDLER_PROTOCOL  *mRscHandlerProtocol       = NULL;
+EFI_EVENT                 mExitBootServicesEvent     = NULL;
+BOOLEAN                   mRegistered                = FALSE;
+
+/**
+  Convert status code value and extended data to readable ASCII string, send string to Usb3 device.
+
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or software entity.
+                           This included information about the class and subclass that is used to
+                           classify the entity as well as an operation.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      Status code reported to Usb3 successfully.
+  @retval EFI_DEVICE_ERROR Usb3 device cannot work after ExitBootService() is called.
+  @retval EFI_DEVICE_ERROR Usb3 device cannot work with TPL higher than TPL_CALLBACK.
+
+**/
+EFI_STATUS
+EFIAPI
+Usb3StatusCodeReportWorker (
+  IN EFI_STATUS_CODE_TYPE     CodeType,
+  IN EFI_STATUS_CODE_VALUE    Value,
+  IN UINT32                   Instance,
+  IN EFI_GUID                 *CallerId,
+  IN EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  )
+{
+  CHAR8           *Filename;
+  CHAR8           *Description;
+  CHAR8           *Format;
+  CHAR8           Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
+  UINT32          ErrorLevel;
+  UINT32          LineNumber;
+  UINTN           CharCount;
+  BASE_LIST       Marker;
+
+  Buffer[0] = '\0';
+
+  if (Data != NULL &&
+      CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeStringGuid) &&
+      ((EFI_STATUS_CODE_STRING_DATA *) Data)->StringType == EfiStringAscii) {
+    //
+    // Print String Data.
+    //
+    Usb3DebugPortWrite (
+      (UINT8 *) (((EFI_STATUS_CODE_STRING_DATA *) Data)->String.Ascii),
+      ((EFI_STATUS_CODE_STRING_DATA *) Data)->DataHeader.Size
+      );
+    return EFI_SUCCESS;
+  } else if (Data != NULL &&
+      ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
+    //
+    // Print ASSERT() information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "\n\rDXE_ASSERT!: %a (%d): %a\n\r",
+                  Filename,
+                  LineNumber,
+                  Description
+                  );
+  } else if (Data != NULL &&
+             ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
+    //
+    // Print DEBUG() information into output buffer.
+    //
+    CharCount = AsciiBSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  Format,
+                  Marker
+                  );
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
+    //
+    // Print ERROR information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "ERROR: C%08x:V%08x I%x",
+                  CodeType,
+                  Value,
+                  Instance
+                  );
+    ASSERT (CharCount > 0);
+
+    if (CallerId != NULL) {
+      CharCount += AsciiSPrint (
+                     &Buffer[CharCount],
+                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                     " %g",
+                     CallerId
+                     );
+    }
+
+    if (Data != NULL) {
+      CharCount += AsciiSPrint (
+                     &Buffer[CharCount],
+                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                     " %x",
+                     Data
+                     );
+    }
+
+    CharCount += AsciiSPrint (
+                   &Buffer[CharCount],
+                   (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                   "\n\r"
+                   );
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
+    //
+    // Print PROGRESS information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "PROGRESS CODE: V%08x I%x\n\r",
+                  Value,
+                  Instance
+                  );
+  } else {
+    //
+    // Code type is not defined.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "Undefined: C%08x:V%08x I%x\n\r",
+                  CodeType,
+                  Value,
+                  Instance
+                  );
+  }
+
+  //
+  // Call Usb3DebugPortLib function to do print.
+  //
+  Usb3DebugPortWrite ((UINT8 *) Buffer, CharCount);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Unregister status code callback functions only available at boot time from
+  report status code router when exiting boot services.
+
+  @param  Event         Event whose notification function is being invoked.
+  @param  Context       Pointer to the notification function's context, which is
+                        always zero in current implementation.
+
+**/
+VOID
+EFIAPI
+UnregisterUsb3BootTimeHandlers (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  if (mRegistered) {
+    mRscHandlerProtocol->Unregister (Usb3StatusCodeReportWorker);
+  }
+}
+
+/**
+  Register status code callback function only when Report Status Code protocol
+  is installed.
+
+  @param  Event         Event whose notification function is being invoked.
+  @param  Context       Pointer to the notification function's context, which is
+                        always zero in current implementation.
+
+**/
+VOID
+EFIAPI
+RegisterUsb3BootTimeHandlers (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  EFI_STATUS                Status;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiRscHandlerProtocolGuid,
+                  NULL,
+                  (VOID **) &mRscHandlerProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = Usb3DebugPortInitialize ();
+  ASSERT_EFI_ERROR (Status);
+
+  mRscHandlerProtocol->Register (Usb3StatusCodeReportWorker, TPL_HIGH_LEVEL);
+  ASSERT_EFI_ERROR (Status);
+  mRegistered = TRUE;
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  UnregisterUsb3BootTimeHandlers,
+                  NULL,
+                  &gEfiEventExitBootServicesGuid,
+                  &mExitBootServicesEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  Constructor function of RuntimeDxeUsb3StatusCodeHandlerLib.
+
+  This function allocates memory for extended status code data, caches
+  the report status code service, and registers events.
+
+  @param  ImageHandle   The firmware allocated handle for the EFI image.
+  @param  SystemTable   A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+RuntimeDxeUsb3StatusCodeHandlerLibConstructor (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  EFI_STATUS                Status;
+  EFI_EVENT                 RegisterStatusCodeHandlerEvent;
+  VOID                      *Registration;
+
+  if (!PcdGetBool (PcdStatusCodeUseUsb3)) {
+    return EFI_SUCCESS;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEfiRscHandlerProtocolGuid,
+                  NULL,
+                  (VOID **) &mRscHandlerProtocol
+                  );
+
+  if (!EFI_ERROR (Status)) {
+    RegisterUsb3BootTimeHandlers (NULL, NULL);
+  } else {
+    Status = gBS->CreateEvent (
+                    EVT_NOTIFY_SIGNAL,
+                    TPL_NOTIFY,
+                    RegisterUsb3BootTimeHandlers,
+                    NULL,
+                    &RegisterStatusCodeHandlerEvent
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Register for protocol notifications on this event
+    //
+    Status = gBS->RegisterProtocolNotify (
+                    &gEfiRscHandlerProtocolGuid,
+                    RegisterStatusCodeHandlerEvent,
+                    &Registration
+                    );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/RuntimeDxeUsb3StatusCodeHandlerLib.inf b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/RuntimeDxeUsb3StatusCodeHandlerLib.inf
new file mode 100644
index 0000000000..0819f97a1f
--- /dev/null
+++ b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/RuntimeDxeUsb3StatusCodeHandlerLib.inf
@@ -0,0 +1,54 @@
+## @file
+#  USB3 status code implementation.
+#
+# Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# vendor.  This file may not be modified, except as allowed by
+# additional terms of your license agreement.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = RuntimeDxeUsb3StatusCodeHandlerLib
+  FILE_GUID                      = 146052EF-0462-4F06-BFDB-EAB90B4519A7
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+  CONSTRUCTOR                    = RuntimeDxeUsb3StatusCodeHandlerLibConstructor
+  LIBRARY_CLASS                  = StatusCodeHandlerLib|DXE_RUNTIME_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is only for build)
+#
+
+[Sources]
+  RuntimeDxeUsb3StatusCodeHandlerLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Usb3DebugFeaturePkg/Usb3DebugFeaturePkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  UefiRuntimeLib
+  PcdLib
+  DebugLib
+  BaseMemoryLib
+  ReportStatusCodeLib
+  Usb3DebugPortLib
+
+[Guids]
+  gEfiStatusCodeDataTypeStringGuid              ## SOMETIMES_CONSUMES ## GUID
+
+[Pcd]
+  gUsb3DebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseUsb3               ## CONSUMES
+
+[Protocols]
+  gEfiRscHandlerProtocolGuid                    ## CONSUMES
+
+[Depex]
+  TRUE
diff --git a/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/SmmUsb3StatusCodeHandlerLib.c b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/SmmUsb3StatusCodeHandlerLib.c
new file mode 100644
index 0000000000..c6b3b9aac5
--- /dev/null
+++ b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/SmmUsb3StatusCodeHandlerLib.c
@@ -0,0 +1,250 @@
+/** @file
+  Usb3 status code implementation.
+
+  Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Protocol/SmmReportStatusCodeHandler.h>
+
+#include <Library/Usb3DebugPortLib.h>
+
+#include <Guid/StatusCodeDataTypeId.h>
+#include <Guid/StatusCodeDataTypeDebug.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/PrintLib.h>
+
+
+/**
+  Convert status code value and extended data to readable ASCII string, send string to Usb3 device.
+
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or software entity.
+                           This included information about the class and subclass that is used to
+                           classify the entity as well as an operation.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      Status code reported to Usb3 successfully.
+  @retval EFI_DEVICE_ERROR Usb3 device cannot work after ExitBootService() is called.
+  @retval EFI_DEVICE_ERROR Usb3 device cannot work with TPL higher than TPL_CALLBACK.
+
+**/
+EFI_STATUS
+EFIAPI
+Usb3StatusCodeReportWorker (
+  IN EFI_STATUS_CODE_TYPE     CodeType,
+  IN EFI_STATUS_CODE_VALUE    Value,
+  IN UINT32                   Instance,
+  IN EFI_GUID                 *CallerId,
+  IN EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  )
+{
+  CHAR8           *Filename;
+  CHAR8           *Description;
+  CHAR8           *Format;
+  CHAR8           Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
+  UINT32          ErrorLevel;
+  UINT32          LineNumber;
+  UINTN           CharCount;
+  BASE_LIST       Marker;
+
+  Buffer[0] = '\0';
+
+  if (Data != NULL &&
+      ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
+    //
+    // Print ASSERT() information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "\n\rSMM_ASSERT!: %a (%d): %a\n\r",
+                  Filename,
+                  LineNumber,
+                  Description
+                  );
+  } else if (Data != NULL &&
+             ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
+    //
+    // Print DEBUG() information into output buffer.
+    //
+    CharCount = AsciiBSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  Format,
+                  Marker
+                  );
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
+    //
+    // Print ERROR information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "ERROR: C%08x:V%08x I%x",
+                  CodeType,
+                  Value,
+                  Instance
+                  );
+    ASSERT (CharCount > 0);
+
+    if (CallerId != NULL) {
+      CharCount += AsciiSPrint (
+                     &Buffer[CharCount],
+                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                     " %g",
+                     CallerId
+                     );
+    }
+
+    if (Data != NULL) {
+      CharCount += AsciiSPrint (
+                     &Buffer[CharCount],
+                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                     " %x",
+                     Data
+                     );
+    }
+
+    CharCount += AsciiSPrint (
+                   &Buffer[CharCount],
+                   (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                   "\n\r"
+                   );
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
+    //
+    // Print PROGRESS information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "PROGRESS CODE: V%08x I%x\n\r",
+                  Value,
+                  Instance
+                  );
+  } else if (Data != NULL &&
+             CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeStringGuid) &&
+             ((EFI_STATUS_CODE_STRING_DATA *) Data)->StringType == EfiStringAscii) {
+    //
+    // EFI_STATUS_CODE_STRING_DATA
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "%a",
+                  ((EFI_STATUS_CODE_STRING_DATA *) Data)->String.Ascii
+                  );
+  } else {
+    //
+    // Code type is not defined.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "Undefined: C%08x:V%08x I%x\n\r",
+                  CodeType,
+                  Value,
+                  Instance
+                  );
+  }
+
+  //
+  // Call Usb3DebugPortLib function to do print.
+  //
+  Usb3DebugPortWrite ((UINT8 *) Buffer, CharCount);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Register status code callback function only when Report Status Code protocol
+  is installed.
+
+  @param  Event         Event whose notification function is being invoked.
+  @param  Context       Pointer to the notification function's context, which is
+                        always zero in current implementation.
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterUsb3BootTimeHandlers (
+  IN CONST EFI_GUID        *Protocol,
+  IN VOID                  *Interface,
+  IN EFI_HANDLE            Handle
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_SMM_RSC_HANDLER_PROTOCOL *RscHandlerProtocol;
+
+  Status = gSmst->SmmLocateProtocol (
+                    &gEfiSmmRscHandlerProtocolGuid,
+                    NULL,
+                    (VOID **) &RscHandlerProtocol
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = Usb3DebugPortInitialize ();
+  ASSERT_EFI_ERROR (Status);
+
+  RscHandlerProtocol->Register (Usb3StatusCodeReportWorker);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Constructor function of SmmUsb3StatusCodeHandlerLib.
+
+  This function allocates memory for extended status code data, caches
+  the report status code service, and registers events.
+
+  @param  ImageHandle   The firmware allocated handle for the EFI image.
+  @param  SystemTable   A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+SmmUsb3StatusCodeHandlerLibConstructor (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  EFI_STATUS                   Status;
+  VOID                         *Registration;
+  EFI_SMM_RSC_HANDLER_PROTOCOL *RscHandlerProtocol;
+
+  if (!PcdGetBool (PcdStatusCodeUseUsb3)) {
+    return EFI_SUCCESS;
+  }
+
+  Status = gSmst->SmmLocateProtocol (
+                    &gEfiSmmRscHandlerProtocolGuid,
+                    NULL,
+                    (VOID **) &RscHandlerProtocol
+                    );
+  if (!EFI_ERROR (Status)) {
+    RegisterUsb3BootTimeHandlers (NULL, NULL, NULL);
+  } else {
+    gSmst->SmmRegisterProtocolNotify (
+             &gEfiSmmRscHandlerProtocolGuid,
+             RegisterUsb3BootTimeHandlers,
+             &Registration
+             );
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/SmmUsb3StatusCodeHandlerLib.inf b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/SmmUsb3StatusCodeHandlerLib.inf
new file mode 100644
index 0000000000..1ea7c4d913
--- /dev/null
+++ b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/SmmUsb3StatusCodeHandlerLib.inf
@@ -0,0 +1,53 @@
+## @file
+#  USB3 status code implementation.
+#
+# Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# vendor.  This file may not be modified, except as allowed by
+# additional terms of your license agreement.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmmUsb3StatusCodeHandlerLib
+  FILE_GUID                      = 23C08AC3-130A-4E68-A1D5-A9FA8950677A
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  VERSION_STRING                 = 1.0
+  CONSTRUCTOR                    = SmmUsb3StatusCodeHandlerLibConstructor
+  LIBRARY_CLASS                  = StatusCodeHandlerLib|DXE_SMM_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is only for build)
+#
+
+[Sources]
+  SmmUsb3StatusCodeHandlerLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Usb3DebugFeaturePkg/Usb3DebugFeaturePkg.dec
+
+[LibraryClasses]
+  SmmServicesTableLib
+  PcdLib
+  DebugLib
+  BaseMemoryLib
+  ReportStatusCodeLib
+  Usb3DebugPortLib
+
+[Guids]
+  gEfiStatusCodeDataTypeStringGuid              ## SOMETIMES_CONSUMES ## GUID
+
+[Pcd]
+  gUsb3DebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseUsb3               ## CONSUMES
+
+[Protocols]
+  gEfiSmmRscHandlerProtocolGuid                 ## CONSUMES
+
+[Depex]
+  TRUE
diff --git a/Features/Intel/Debugging/Usb3DebugFeaturePkg/Readme.md b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Readme.md
index dc92f108ff..83d5b3606b 100644
--- a/Features/Intel/Debugging/Usb3DebugFeaturePkg/Readme.md
+++ b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Readme.md
@@ -1,7 +1,7 @@
 # Overview
 * **Feature Name:** USB3 Debug
-* **PI Phase(s) Supported:** PEI, DXE
-* **SMM Required?** No
+* **PI Phase(s) Supported:** PEI, DXE, SMM
+* **SMM Required?** Yes
 
 More Information:
 * [USB 3.1 Device-Class Specification for Debug Devices](https://www.usb.org/sites/default/files/documents/usb_debug_class_rev_1_0_final_0.pdf)
@@ -21,88 +21,140 @@ The Intel&reg; UDK Debugger Tool can be used in a Linux or Windows host environm
 and provide runtime debug control via GNU Project Debugger (GDB) or the Microsoft Windows Debug Tool (WinDbg)
 respectively.
 
+This feature also include a library used with StatusCodeHandler, it can get output status code through USB.
+
 # High-Level Theory of Operation
-*_TODO_*
-A description of how the device works at a high-level.
+It provide a library Usb3StatusCodeHandlerLib used by edk2 StatusCodeHandler.efi, used to output status code through USB3.
+
+In the library contstructor function, Usb3StatusCodeHandlerLib register the call back function for ReportStatusCode.
+When called, it call convert data from status code, and call Usb3DebugPortWrite() in Usb3DebugPortLib to output through USB3.
 
-The description should not be constrained to implementation details but provide a simple mental model of how the
-feature is supposed to work.
+Usb3StatusCodeHandlerLib include 3 libraries for PEI, RuntimeDxe, SMM:
+* PeiUsb3StatusCodeHandlerLib
+* RuntimeDxeUsb3StatusCodeHandlerLib
+* SmmUsb3StatusCodeHandlerLib
 
 ## Firmware Volumes
-*_TODO_*
-A bulleted list of the firmware volumes that feature module(s) are placed in.
+Linked with StatusCodeHandler.efi, and make sure put the StatusCodeHandler.efi after the ReportStatusCodeRouter.efi.
 
 ## Modules
-*_TODO_*
-A bulleted list of the modules that make up the feature.
+* Usb3StatusCodeHandlerLib
+* Usb3DebugPortLib
+* Usb3DebugPortParamLibPcd
 
-## <Module Name>
-*_TODO_*
-Each module in the feature should have a section that describes the module in a level of detail that is useful
-to better understand the module source code.
+## Usb3StatusCodeHandlerLib
+This library register the call back function for ReportStatusCode, and output status code through USB3.
 
-## <Library Name>
-*_TODO_*
-Each library in the feature should have a section that describes the library in a level of detail that is useful
-to better understand the library source code.
+## Usb3DebugPortLib
+The library provide the Usb3DebugPortWrite function to do the real write.
 
-## Key Functions
-*_TODO_*
-A bulleted list of key functions for interacting with the feature.
+## Usb3DebugPortParamLibPcd
+The library provide some functions to get the parameters of USB3 debug port from PCDs.
 
-Not all features need to be listed. Only functions exposed through external interfaces that are important for feature
-users to be aware of.
+## Key Functions
+* In PeiUsb3StatusCodeHandlerLib:
+  EFI_STATUS
+  EFIAPI
+  Usb3StatusCodeReportWorker (
+    IN CONST  EFI_PEI_SERVICES        **PeiServices,
+    IN EFI_STATUS_CODE_TYPE           CodeType,
+    IN EFI_STATUS_CODE_VALUE          Value,
+    IN UINT32                         Instance,
+    IN CONST EFI_GUID                 *CallerId,
+    IN CONST EFI_STATUS_CODE_DATA     *Data OPTIONAL
+    )
+
+* In RuntimeDxeUsb3StatusCodeHandlerLib:
+  EFI_STATUS
+  EFIAPI
+  Usb3StatusCodeReportWorker (
+    IN EFI_STATUS_CODE_TYPE           CodeType,
+    IN EFI_STATUS_CODE_VALUE          Value,
+    IN UINT32                         Instance,
+    IN EFI_GUID                       *CallerId,
+    IN EFI_STATUS_CODE_DATA           *Data OPTIONAL
+    )
+
+* In SmmUsb3StatusCodeHandlerLib:
+  EFI_STATUS
+  EFIAPI
+  Usb3StatusCodeReportWorker (
+    IN EFI_STATUS_CODE_TYPE           CodeType,
+    IN EFI_STATUS_CODE_VALUE          Value,
+    IN UINT32                         Instance,
+    IN EFI_GUID                       *CallerId,
+    IN EFI_STATUS_CODE_DATA           *Data OPTIONAL
+    )
+
+* In Usb3DebugPortLib:
+  RETURN_STATUS
+  EFIAPI
+  Usb3DebugPortInitialize (
+    VOID
+    )
+
+  UINTN
+  EFIAPI
+  Usb3DebugPortWrite (
+    IN UINT8     *Buffer,
+    IN UINTN     NumberOfBytes
+    )
+
+  BOOLEAN
+  EFIAPI
+  Usb3DebugPortPoll (
+    VOID
+    )
+
+
+* In Usb3DebugPortParamLibPcd:
+  UINT32
+  EFIAPI
+  GetUsb3DebugPortController (
+    VOID
+    )
+
+  BOOLEAN
+  EFIAPI
+  SetUsb3DebugPortController (
+    UINT32        Controller
+    )
 
 ## Configuration
-*_TODO_*
-Information that is useful for configuring the feature.
-
-Not all configuration options need to be listed. This section is used to provide more background on configuration
-options than possible elsewhere.
+** Link the library to StatusCodeHandler.efi.
+  Example:
+    MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf {
+    <LibraryClasses>
+      NULL|Usb3DebugFeaturePkg/Library/Usb3StatusCodeHandlerLib/RuntimeDxeUsb3StatusCodeHandlerLib.inf
+    }
+  Refer to Usb3DebugFeature.dsc for other example.
+* Config PCD gUsb3DebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseUsb3.
+  In platform .dsc file, need to config the type of gUsb3DebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseUsb3.
+  Use PcdsFixedAtBuild to save binary size, and use PcdsDynamic if want to enable/disable in runtime.
+* Select library used Usb3DebugPortLib and Usb3DebugPortParamLib, or provide the platform's special library.
+* If select use Usb3DebugPortParamLibPcd, then config the PCDs.
+* Make sure put the StatusCodeHandler.efi after the ReportStatusCodeRouter.efi.
 
 ## Data Flows
-*_TODO_*
-Architecturally defined data structures and flows for the feature.
+Status Code (ReportStatusCode) -> USB3 data.
 
 ## Control Flows
-*_TODO_*
-Key control flows for the feature.
+ReportStatusCode() -> Usb3StatusCodeReportWorker() -> Usb3DebugPortWrite()
 
 ## Build Flows
-*_TODO_*
-Any special build flows should be described in this section.
-
-This is particularly useful for features that use custom build tools or require non-standard tool configuration. If the
-standard flow in the feature package template is used, this section may be empty.
+There is not special build flows.
 
 ## Test Point Results
-*_TODO_*
-The test(s) that can verify porting is complete for the feature.
-
-Each feature must describe at least one test point to verify the feature is successful. If the test point is not
-implemented, this should be stated.
+Verify the status code can output through USB3.
 
 ## Functional Exit Criteria
-*_TODO_*
-The testable functionality for the feature.
-
-This section should provide an ordered list of criteria that a board integrator can reference to ensure the feature is
-functional on their board.
+N/A
 
 ## Feature Enabling Checklist
-*_TODO_*
-An ordered list of required activities to achieve desired functionality for the feature.
-
-## Performance Impact
-A general expectation for the impact on overall boot performance due to using this feature.
-
-This section is expected to provide guidance on:
-* How to estimate performance impact due to the feature
-* How to measure performance impact of the feature
-* How to manage performance impact of the feature
+* Set the PCD gUsb3DebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseUsb3 to TRUE.
+* Connect the device and host with a USB3 debug cable and use the USB port as configured.
+* Config the host OS or tools.
+* Check the status code can output through USB3.
 
 ## Common Optimizations
-*_TODO_*
-Common size or performance tuning options for this feature.
-
-This section is recommended but not required. If not used, the contents should be left empty.
+Provide platform special Usb3DebugPortLib or Usb3DebugPortParamLib if needed.
diff --git a/Features/Intel/Debugging/Usb3DebugFeaturePkg/Usb3DebugFeaturePkg.dec b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Usb3DebugFeaturePkg.dec
index 2b19e48491..fc4092ffe1 100644
--- a/Features/Intel/Debugging/Usb3DebugFeaturePkg/Usb3DebugFeaturePkg.dec
+++ b/Features/Intel/Debugging/Usb3DebugFeaturePkg/Usb3DebugFeaturePkg.dec
@@ -55,3 +55,5 @@
   ## This PCD sepcifies the start index in CMOS, it will occupy 1 bytes space.
   gUsb3DebugFeaturePkgTokenSpaceGuid.PcdUsb3DebugPortFunctionIndex|0x5B|UINT8|0xF0000008
 
+[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
+  gUsb3DebugFeaturePkgTokenSpaceGuid.PcdStatusCodeUseUsb3|FALSE|BOOLEAN|0xFF000001
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2020-06-11 14:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-06-11 14:54 [PATCH] Features/Intel: Add Usb3StatusCodeHandlerLib in Usb3DebugFeaturePkg Tan, Ming

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox