From nobody Sat May 4 09:59:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+41555+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+41555+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1559090878; cv=none; d=zoho.com; s=zohoarc; b=ORc3rSxVELv//YnBX2SR1ipTcIy4+pAxXi6qQ6MaGY7vRZosBHpCSt7CfPXhzg0pCc6ffYqU7LVML+NDdxe3JDZsL9ukzG9y0tAt0vjTGOhrOYFdnm2O4uP2oyBpGEsM7LwiQBlvRJh0BGy5eAEB/YE2tcVXNXzS24aJ9/3/rlg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559090878; h=Content-Transfer-Encoding:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=T21S1LBw2yxgEmL2cGuskB2ZRs32HBC6GP3sLFLRO2w=; b=HeQQIoiqGj+T+Gq9Y50tq1zpkqfu28w7bqh+VtkFVuwgGKMi+lKY0K8tIhtyjOCGwEMWiSPyWfXMqrf72kluu3dpZKEaB33GDUnNUd3WOQdsB7w6VMiK59QYZfzuj7G8ccLMAfTDWMOt9RYXgiwnPSepa5XT2OjLGF88WBrj4mw= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+41555+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1559090878125569.150552678456; Tue, 28 May 2019 17:47:58 -0700 (PDT) Return-Path: X-Received: from mga04.intel.com (mga04.intel.com []) by groups.io with SMTP; Tue, 28 May 2019 17:47:56 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 May 2019 17:47:56 -0700 X-ExtLoop1: 1 X-Received: from ydong10-win10.ccr.corp.intel.com ([10.239.158.133]) by fmsmga006.fm.intel.com with ESMTP; 28 May 2019 17:47:56 -0700 From: "Dong, Eric" To: devel@edk2.groups.io Subject: [edk2-devel] [Patch 1/3] [edk2-platforms] Platform/Intel/DebugFeaturePkg: Add DebugFeaturePkg Date: Wed, 29 May 2019 08:47:52 +0800 Message-Id: <20190529004754.22332-2-eric.dong@intel.com> In-Reply-To: <20190529004754.22332-1-eric.dong@intel.com> References: <20190529004754.22332-1-eric.dong@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,eric.dong@intel.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1559090877; bh=3yj9+OQ3sAm5iv3n9qkC2U1IVNcAlXDqU+LcmcNZaDg=; h=Date:From:Reply-To:Subject:To; b=rXU8iFrDAjwc+/8jTyBBsX6bQcsSFVle60ztB8yV5BYRIpg77aZIklBT9fbv+VdoKR+ yViELbOxNaDynmNA+NRhxQK9g3TQf/RbfCi3dUdV6mLI4J7DjKnU5AboJa6PhWgYernIo n1MPDKjucPlKEVdAh2oXrZKAd0mp+6vuBgQ= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" Add new package DebugFeaturePkg in Platform/Intel/ folder. It will keep debug related features in this package. Signed-off-by: Eric Dong --- Maintainers.txt | 4 ++++ .../Intel/DebugFeaturePkg/DebugFeaturePkg.dec | 19 +++++++++++++++ .../Intel/DebugFeaturePkg/DebugFeaturePkg.dsc | 24 +++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dec create mode 100644 Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dsc diff --git a/Maintainers.txt b/Maintainers.txt index 76feecceb7..66782b4b92 100644 --- a/Maintainers.txt +++ b/Maintainers.txt @@ -60,6 +60,10 @@ M: Michael Kubacki M: Sai Chaganty R: Liming Gao =20 +Platform/Intel/DebugFeaturePkg +M: Eric Dong +R: Liming Gao + Platform/Intel/ClevoOpenBoardPkg M: Michael Kubacki M: Ankit Sinha diff --git a/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dec b/Platform/= Intel/DebugFeaturePkg/DebugFeaturePkg.dec new file mode 100644 index 0000000000..839684183a --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dec @@ -0,0 +1,19 @@ +## @file +# This package provides the modules that build for debug feature. +# This DebugAdvancedFeaturePkg should only depend on EDKII Core packages a= nd MinPlatformPkg. +# +# The DEC files are used by the utilities that parse DSC and +# INF files to generate AutoGen.c and AutoGen.h files +# for the build infrastructure. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + DEC_SPECIFICATION =3D 0x00010005 + PACKAGE_NAME =3D DebugFeaturePkg + PACKAGE_GUID =3D 58B6F2BB-A94F-4EB9-89DA-2F06ED59CE39 + PACKAGE_VERSION =3D 0.1 \ No newline at end of file diff --git a/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dsc b/Platform/= Intel/DebugFeaturePkg/DebugFeaturePkg.dsc new file mode 100644 index 0000000000..351d6583d5 --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dsc @@ -0,0 +1,24 @@ +## @file +# This package provides the modules that build for debug feature. +# This DebugFeaturePkg should only depend on EDKII Core packages and MinPl= atformPkg. +# +# The DEC files are used by the utilities that parse DSC and +# INF files to generate AutoGen.c and AutoGen.h files +# for the build infrastructure. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + PLATFORM_NAME =3D DebugFeaturePkg + PLATFORM_GUID =3D 3A0DBEF4-3C16-4F6B-8B55-BABB260D30B9 + PLATFORM_VERSION =3D 0.1 + DSC_SPECIFICATION =3D 0x00010005 + OUTPUT_DIRECTORY =3D Build/DebugFeaturePkg + SUPPORTED_ARCHITECTURES =3D IA32|X64 + BUILD_TARGETS =3D DEBUG|RELEASE|NOOPT + SKUID_IDENTIFIER =3D DEFAULT + --=20 2.21.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#41555): https://edk2.groups.io/g/devel/message/41555 Mute This Topic: https://groups.io/mt/31828869/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat May 4 09:59:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+41556+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+41556+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1559090880; cv=none; d=zoho.com; s=zohoarc; b=DWMwak3ZTDaxJLWr9tzZ1w1qN7sixXSI6ZZoSfhKIsMtjzvyGoqn/iGwA1daM81FxFYjG7dWi1zPLqVZ+5SJsh+hAWeIbGaYXPhAuPoatO6bJKgDse6tdgE7D8VM4d4z+A/+CcR8EhwzUsmxlNK2zxRiA2tz9E1SwNod31dRshY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559090880; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=J2cowUEcXWVKq4POiY5KT+GWGEw7MkaN21Htgb5SfKQ=; b=lE0R83uesQuOapdaymWdSV8X2TRCdnay21eL0cyALrnyqi3EgpRjorXv7l/BobxakTE5A0Qfm4B1KWUtbpwpW5Py5Bkb4GXR00RcxeSzcgC23EfgB7VkVedxGsUanKw2GiKcKaPVBMuLFxxM/VwLPQ4RM9P6tzZop1pT+67Hzqc= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+41556+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1559090880635639.5166173206686; Tue, 28 May 2019 17:48:00 -0700 (PDT) Return-Path: X-Received: from mga04.intel.com (mga04.intel.com []) by groups.io with SMTP; Tue, 28 May 2019 17:47:59 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 May 2019 17:47:59 -0700 X-ExtLoop1: 1 X-Received: from ydong10-win10.ccr.corp.intel.com ([10.239.158.133]) by fmsmga006.fm.intel.com with ESMTP; 28 May 2019 17:47:56 -0700 From: "Dong, Eric" To: devel@edk2.groups.io Cc: Liming Gao Subject: [edk2-devel] [Patch 2/3] [edk2-platforms] Platform/Intel/DebugFeaturePkg: Add USB3DebugPort related modules. Date: Wed, 29 May 2019 08:47:53 +0800 Message-Id: <20190529004754.22332-3-eric.dong@intel.com> In-Reply-To: <20190529004754.22332-1-eric.dong@intel.com> References: <20190529004754.22332-1-eric.dong@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,eric.dong@intel.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1559090880; bh=fA+oIGnVop5BPxv/Dx25MjmLSutci9hxHx495zpRSF8=; h=Cc:Date:From:Reply-To:Subject:To; b=XHEDj2S+/T50QvG6H3x5gTv/6TWpZGymY1EYGuWTkw6QBoq0WboaA+asCu/T9MW7rg4 Bcx4SNARbDTqA1LP5fsDWi/WdFO3f9IYwph5w6E1zwTY4MVuxz84Q6X7xBGx09dHNtxB1 Cbd1OzQ7nu2DoE+0z8aFLUwWS+se+GJWm9I= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" https://bugzilla.tianocore.org/show_bug.cgi?id=3D1553 Add USB3DebugPort related modules, include Usb3DebugPortLib and Usb3DebugPortParameterLib. Usb3DebugPortParameterLib will be consumed by Usb3DebugPortLib. Interfaces export by Us3DebugPortLib includes: Usb3DebugPortParameterLib Usb3DebugPortWrite Usb3DebugPortPoll Interfaces export by Usb3DebugPortParameterLib includes: GetUsb3DebugPortController SetUsb3DebugPortController Signed-off-by: Eric Dong Cc: Liming Gao --- .../Intel/DebugFeaturePkg/DebugFeaturePkg.dec | 36 +- .../Intel/DebugFeaturePkg/DebugFeaturePkg.dsc | 62 ++ .../Include/Library/Usb3DebugPortLib.h | 76 ++ .../Library/Usb3DebugPortParameterLib.h | 56 ++ .../Library/Usb3DebugPortLib/MiscServices.c | 385 ++++++++ .../Usb3DebugPortDataTransfer.c | 892 ++++++++++++++++++ .../Usb3DebugPortInitialize.c | 726 ++++++++++++++ .../Usb3DebugPortLib/Usb3DebugPortLibDxe.c | 454 +++++++++ .../Usb3DebugPortLib/Usb3DebugPortLibDxe.inf | 55 ++ .../Usb3DebugPortLibDxeIoMmu.c | 828 ++++++++++++++++ .../Usb3DebugPortLibDxeIoMmu.inf | 63 ++ .../Usb3DebugPortLibInternal.h | 887 +++++++++++++++++ .../Usb3DebugPortLib/Usb3DebugPortLibNull.c | 103 ++ .../Usb3DebugPortLib/Usb3DebugPortLibNull.inf | 28 + .../Usb3DebugPortLib/Usb3DebugPortLibPei.c | 236 +++++ .../Usb3DebugPortLib/Usb3DebugPortLibPei.inf | 48 + .../Usb3DebugPortLibPeiIoMmu.c | 440 +++++++++ .../Usb3DebugPortLibPeiIoMmu.inf | 51 + .../Usb3DebugPortParameterLibPcd.c | 58 ++ .../Usb3DebugPortParameterLibPcd.inf | 31 + 20 files changed, 5514 insertions(+), 1 deletion(-) create mode 100644 Platform/Intel/DebugFeaturePkg/Include/Library/Usb3Debu= gPortLib.h create mode 100644 Platform/Intel/DebugFeaturePkg/Include/Library/Usb3Debu= gPortParameterLib.h create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /MiscServices.c create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortDataTransfer.c create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortInitialize.c create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortLibDxe.c create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortLibDxe.inf create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortLibDxeIoMmu.c create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortLibDxeIoMmu.inf create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortLibInternal.h create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortLibNull.c create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortLibNull.inf create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortLibPei.c create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortLibPei.inf create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortLibPeiIoMmu.c create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortLibPeiIoMmu.inf create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortPar= ameterLibPcd/Usb3DebugPortParameterLibPcd.c create mode 100644 Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortPar= ameterLibPcd/Usb3DebugPortParameterLibPcd.inf diff --git a/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dec b/Platform/= Intel/DebugFeaturePkg/DebugFeaturePkg.dec index 839684183a..63a6ed03b7 100644 --- a/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dec +++ b/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dec @@ -16,4 +16,38 @@ DEC_SPECIFICATION =3D 0x00010005 PACKAGE_NAME =3D DebugFeaturePkg PACKAGE_GUID =3D 58B6F2BB-A94F-4EB9-89DA-2F06ED59CE39 - PACKAGE_VERSION =3D 0.1 \ No newline at end of file + PACKAGE_VERSION =3D 0.1 + +[Includes] + Include + +[LibraryClasses] + ## @libraryclass Provide capability to get/set USB3 debug port param= eter. + Usb3DebugPortParameterLib|Include/Library/Usb3DebugPortParameterLib.h + +[Guids] + gEfiUsb3DebugPortTokenSpaceGuid =3D { 0x87e7378b, 0xc59d, 0x4a16, { 0xa4= , 0x21, 0x2c, 0xdb, 0x78, 0x26, 0xb1, 0xca } } + +[PcdsFeatureFlag] + ## This PCD specifies whether StatusCode is reported via USB3 Serial por= t. + gEfiUsb3DebugPortTokenSpaceGuid.PcdStatusCodeUseUsb3Serial|TRUE|BOOLEAN|= 0x10000003 + +[PcdsFixedAtBuild] + ## These PCD specify XHCI controller Bus/Device/Function, which are used= to enable + # XHCI debug device. + gEfiUsb3DebugPortTokenSpaceGuid.PcdUsbSerialXhciBus|0x00|UINT8|0x00000016 + gEfiUsb3DebugPortTokenSpaceGuid.PcdUsbSerialXhciDev|0x14|UINT8|0x00000017 + gEfiUsb3DebugPortTokenSpaceGuid.PcdUsbSerialXhciFunc|0x00|UINT8|0x000000= 18 + gEfiUsb3DebugPortTokenSpaceGuid.PcdXhciDefaultBaseAddress|0xFEA10000|UIN= T32|0x00000019 + + ## This PCD specifies the wait timeout value in microsecond if USB debug= cable is detected but host not connected. + # Default timeout value is 2000000 microseconds. + # If user does not want system stall for long time, it can be set to sm= all value. + gEfiUsb3DebugPortTokenSpaceGuid.PcdXhciHostWaitTimeout|2000000|UINT64|0x= 00000020 + + ## This PCD sepcifies the start index in CMOS, it will occupy 1 bytes sp= ace. + gEfiUsb3DebugPortTokenSpaceGuid.PcdUsb3DebugPortBusIndex|0x59|UINT8|0x10= 000024 + ## This PCD sepcifies the start index in CMOS, it will occupy 1 bytes sp= ace. + gEfiUsb3DebugPortTokenSpaceGuid.PcdUsb3DebugPortDeviceIndex|0x5A|UINT8|0= x10000025 + ## This PCD sepcifies the start index in CMOS, it will occupy 1 bytes sp= ace. + gEfiUsb3DebugPortTokenSpaceGuid.PcdUsb3DebugPortFunctionIndex|0x5B|UINT8= |0x10000026 \ No newline at end of file diff --git a/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dsc b/Platform/= Intel/DebugFeaturePkg/DebugFeaturePkg.dsc index 351d6583d5..aeca73a8c8 100644 --- a/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dsc +++ b/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dsc @@ -22,3 +22,65 @@ BUILD_TARGETS =3D DEBUG|RELEASE|NOOPT SKUID_IDENTIFIER =3D DEFAULT =20 +[LibraryClasses] + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBoo= tServicesTableLib.inf + TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplat= e.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + +[LibraryClasses.common.PEIM] + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAlloc= ationLib.inf + #Usb3DebugPortLib|DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPort= LibPeiIoMmu.inf + +[LibraryClasses.IA32.PEIM, LibraryClasses.X64.PEIM] + PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/= PeiServicesTablePointerLibIdt.inf + +[LibraryClasses.common.DXE_DRIVER] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAll= ocationLib.inf + +[LibraryClasses.common.UEFI_DRIVER] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAll= ocationLib.inf + +[LibraryClasses.common.DXE_RUNTIME_DRIVER] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAll= ocationLib.inf + UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf + +[LibraryClasses.common.DXE_SMM_DRIVER] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAlloc= ationLib.inf + +##########################################################################= ######################### +# +# Components Section - list of the modules and components that will be pro= cessed by compilation +# tools and the EDK II tools to generate PE32/PE32+/C= off image files. +# +# Note: The EDK II DSC file is not used to specify how compiled binary ima= ges get placed +# into firmware volume images. This section is just a list of module= s to compile from +# source into UEFI-compliant binaries. +# It is the FDF file that contains information on combining binary f= iles into firmware +# volume images, whose concept is beyond UEFI and is described in PI= specification. +# Binary modules do not need to be listed in this section, as they s= hould be +# specified in the FDF file. For example: Shell binary (Shell_Full.e= fi), FAT binary (Fat.efi), +# Logo (Logo.bmp), and etc. +# There may also be modules listed in this section that are not requ= ired in the FDF file, +# When a module listed here is excluded from FDF file, then UEFI-com= pliant binary will be +# generated for it, but the binary will not be put into any firmware= volume. +# +##########################################################################= ######################### + +[Components] + DebugFeaturePkg/Library/Usb3DebugPortParameterLibPcd/Usb3DebugPortParame= terLibPcd.inf + DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibNull.inf + DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibPeiIoMmu.inf + DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibDxeIoMmu.inf + DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibPei.inf + DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibDxe.inf diff --git a/Platform/Intel/DebugFeaturePkg/Include/Library/Usb3DebugPortLi= b.h b/Platform/Intel/DebugFeaturePkg/Include/Library/Usb3DebugPortLib.h new file mode 100644 index 0000000000..61adf654d2 --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Include/Library/Usb3DebugPortLib.h @@ -0,0 +1,76 @@ +/** @file + This library class provides common USB3 debug port functions. + + Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __USB3_DEBUG_PORT_LIB__ +#define __USB3_DEBUG_PORT_LIB__ + +/** + Initialize the USB3 debug port hardware. + + If no initialization is required, then return RETURN_SUCCESS. + If the serial device was successfully initialized, then return RETURN_SU= CCESS. + If the serial device could not be initialized, then return RETURN_DEVICE= _ERROR. + + @retval RETURN_SUCCESS The serial device was initialized. + @retval RETURN_DEVICE_ERROR The serial device could not be initialized. + +**/ +RETURN_STATUS +EFIAPI +Usb3DebugPortInitialize ( + VOID + ); + +/** + Write data from buffer to USB3 debug port. + + Writes NumberOfBytes data bytes from Buffer to the serial device. + The number of bytes actually written to the serial device is returned. + If the return value is less than NumberOfBytes, then the write operation= failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer Pointer to the data buffer to be written. + @param NumberOfBytes Number of bytes to written to the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes written to the serial devic= e. + If this value is less than NumberOfBytes, then = the read operation failed. + +**/ +UINTN +EFIAPI +Usb3DebugPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ); + + +/** + Read data from USB3 debug port and save the datas in buffer. + + Reads NumberOfBytes data bytes from a serial device into the buffer + specified by Buffer. The number of bytes actua +/** + Polls a USB3 debug port to see if there is any data waiting to be read. + + Polls a serial device to see if there is any data waiting to be read. + If there is data waiting to be read from the serial device, then TRUE is= returned. + If there is no data waiting to be read from the serial device, then FALS= E is returned. + + @retval TRUE Data is waiting to be read from the serial devi= ce. + @retval FALSE There is no data waiting to be read from the se= rial device. + +**/ +BOOLEAN +EFIAPI +Usb3DebugPortPoll ( + VOID + ); + +#endif diff --git a/Platform/Intel/DebugFeaturePkg/Include/Library/Usb3DebugPortPa= rameterLib.h b/Platform/Intel/DebugFeaturePkg/Include/Library/Usb3DebugPort= ParameterLib.h new file mode 100644 index 0000000000..167c607e9f --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Include/Library/Usb3DebugPortParameter= Lib.h @@ -0,0 +1,56 @@ +/** @file + This library class provides capability to get/set usb3 debug port parame= ter. + + Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __USB3_DEBUG_PORT_PARAMETER_LIB__ +#define __USB3_DEBUG_PORT_PARAMETER_LIB__ + +typedef struct { + UINT8 Function; + UINT8 Device; + UINT8 Bus; +} PCI_ADDRESS; + +typedef union { + UINT32 Controller; + PCI_ADDRESS PciAddress; +} USB3_DEBUG_PORT_CONTROLLER; + +/** + Returns the USB 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 + ); + +/** + Sets the USB 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 se= t. + +**/ +BOOLEAN +EFIAPI +SetUsb3DebugPortController ( + UINT32 Controller + ); + +#endif diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/MiscSe= rvices.c b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/MiscServ= ices.c new file mode 100644 index 0000000000..cb29a880e6 --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/MiscServices.c @@ -0,0 +1,385 @@ +/** @file + Miscellaneous services internal to USB debug port implementation. + + Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Usb3DebugPortLibInternal.h" + +/** + Verifies if the bit positions specified by a mask are set in a register. + + @param[in, out] Register UNITN register + @param[in] BitMask 32-bit mask + + @return BOOLEAN - TRUE if all bits specified by the mask are enabled. + - FALSE even if one of the bits specified by the mask + is not enabled. +**/ +BOOLEAN +XhcIsBitSet( + IN OUT UINTN Register, + IN UINT32 BitMask + ) +{ + if ((MmioRead32 (Register) & (BitMask)) !=3D 0) { + return TRUE; + } + return FALSE; +} + +/** + Sets bits as per the enabled bit positions in the mask. + + @param[in, out] Register UINTN register + @param[in] BitMask 32-bit mask +**/ +VOID +XhcSetR32Bit( + IN OUT UINTN Register, + IN UINT32 BitMask + ) +{ + UINT32 RegisterValue; + + RegisterValue =3D MmioRead32 (Register); + RegisterValue |=3D (UINT32)(BitMask); + MmioWrite32 (Register, RegisterValue); +} + +/** + Clears bits as per the enabled bit positions in the mask. + + @param[in, out] Register UINTN register + @param[in] BitMask 32-bit mask +**/ +VOID +XhcClrR32Bit( + IN OUT UINTN Register, + IN UINT32 BitMask + ) +{ + UINT32 RegisterValue; + + RegisterValue =3D MmioRead32 (Register); + RegisterValue &=3D (UINT32)(~(BitMask)); + MmioWrite32 (Register, RegisterValue); +} + +/** + Initialize the USB debug port hardware. + + If no initialization is required, then return RETURN_SUCCESS. + If the serial device was successfully initialized, then return RETURN_SU= CCESS. + If the serial device could not be initialized, then return RETURN_DEVICE= _ERROR. + + @retval RETURN_SUCCESS The serial device was initialized. + @retval RETURN_DEVICE_ERROR The serial device could not be initialized. +**/ +RETURN_STATUS +EFIAPI +Usb3DebugPortInitialize ( + VOID + ) +{ + USB3Initialize (); + return RETURN_SUCCESS; +} + +/** + Write data from buffer to USB debug port. + + Writes NumberOfBytes data bytes from Buffer to the serial device. + The number of bytes actually written to the serial device is returned. + If the return value is less than NumberOfBytes, then the write operation= failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer Pointer to the data buffer to be written. + @param NumberOfBytes Number of bytes to written to the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes written to the serial devic= e. + If this value is less than NumberOfBytes, then = the read operation failed. +**/ +UINTN +EFIAPI +Usb3DebugPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + Usb3DbgOut (Buffer, &NumberOfBytes); + return NumberOfBytes; +} + +/** + Read data from USB debug port and save the datas in buffer. + + Reads NumberOfBytes data bytes from a serial device into the buffer + specified by Buffer. The number of bytes actually read is returned. + If the return value is less than NumberOfBytes, then the rest operation = failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer Pointer to the data buffer to store the data re= ad from the serial device. + @param NumberOfBytes Number of bytes which will be read. + + @retval 0 Read data failed, no data is to be read. + @retval >0 Actual number of bytes read from serial device. +**/ +UINTN +EFIAPI +Usb3DebugPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + Usb3DbgIn (Buffer, &NumberOfBytes); + return NumberOfBytes; +} + +/** + Polls a USB debug port to see if there is any data waiting to be read. + + Polls a serial device to see if there is any data waiting to be read. + If there is data waiting to be read from the serial device, then TRUE is= returned. + If there is no data waiting to be read from the serial device, then FALS= E is returned. + + @retval TRUE Data is waiting to be read from the serial devi= ce. + @retval FALSE There is no data waiting to be read from the se= rial device. +**/ +BOOLEAN +EFIAPI +Usb3DebugPortPoll ( + VOID + ) +{ + return FALSE; +} + +/** + Write the data to the XHCI debug register. + + @param Xhc The XHCI Instance. + @param Offset The offset of the runtime register. + @param Data The data to write. + +**/ +VOID +XhcWriteDebugReg ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset, + IN UINT32 Data + ) +{ + EFI_PHYSICAL_ADDRESS DebugCapabilityBase; + + DebugCapabilityBase =3D Xhc->DebugCapabilityBase; + + MmioWrite32 ((UINTN)(DebugCapabilityBase + Offset), Data); + + return; +} + +/** + Read XHCI debug register. + + @param Xhc The XHCI Instance. + @param Offset The offset of the debug register. + + @return The register content read + +**/ +UINT32 +XhcReadDebugReg ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset + ) +{ + UINT32 Data; + EFI_PHYSICAL_ADDRESS DebugCapabilityBase; + + DebugCapabilityBase =3D Xhc->DebugCapabilityBase; + + Data =3D MmioRead32 ((UINTN)(DebugCapabilityBase + Offset)); + + return Data; +} + +/** + Set one bit of the debug register while keeping other bits. + + @param Xhc The XHCI Instance. + @param Offset The offset of the debug register. + @param Bit The bit mask of the register to set. + +**/ +VOID +XhcSetDebugRegBit ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset, + IN UINT32 Bit + ) +{ + UINT32 Data; + + Data =3D XhcReadDebugReg (Xhc, Offset); + Data |=3D Bit; + XhcWriteDebugReg (Xhc, Offset, Data); +} + +/** + Clear one bit of the debug register while keeping other bits. + + @param Xhc The XHCI Instance. + @param Offset The offset of the debug register. + @param Bit The bit mask of the register to set. + +**/ +VOID +XhcClearDebugRegBit ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset, + IN UINT32 Bit + ) +{ + UINT32 Data; + + Data =3D XhcReadDebugReg (Xhc, Offset); + Data &=3D ~Bit; + XhcWriteDebugReg (Xhc, Offset, Data); +} + +/** + Write the data to the XHCI MMIO register. + + @param Xhc The XHCI Instance. + @param Offset The offset of the runtime register. + @param Data The data to write. + +**/ +VOID +XhcWriteMmioReg ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset, + IN UINT32 Data + ) +{ + EFI_PHYSICAL_ADDRESS MmioBase; + + MmioBase =3D Xhc->XhcMmioBase; + MmioWrite32 ((UINTN)(MmioBase + Offset), Data); + + return; +} + +/** + Read XHCI MMIO register. + + @param Xhc The XHCI Instance. + @param Offset The offset of the runtime register. + + @return The register content read + +**/ +UINT32 +XhcReadMmioReg ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset + ) +{ + UINT32 Data; + EFI_PHYSICAL_ADDRESS MmioBase; + + MmioBase =3D Xhc->XhcMmioBase; + + Data =3D MmioRead32 ((UINTN)(MmioBase + Offset)); + + return Data; +} + +/** + Set one bit of the operational register while keeping other bits. + + @param Xhc The XHCI Instance. + @param Offset The offset of the runtime register. + @param Bit The bit mask of the register to set. + +**/ +VOID +XhcSetMmioRegBit ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset, + IN UINT32 Bit + ) +{ + UINT32 Data; + + Data =3D XhcReadMmioReg (Xhc, Offset); + Data |=3D Bit; + XhcWriteMmioReg (Xhc, Offset, Data); +} + +/** + Clear one bit of the operational register while keeping other bits. + + @param Xhc The XHCI Instance. + @param Offset The offset of the runtime register. + @param Bit The bit mask of the register to set. + +**/ +VOID +XhcClearMmioRegBit ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset, + IN UINT32 Bit + ) +{ + UINT32 Data; + + Data =3D XhcReadMmioReg (Xhc, Offset); + Data &=3D ~Bit; + XhcWriteMmioReg (Xhc, Offset, Data); +} + +/** + Wait the operation register's bit as specified by Bit + to be set (or clear). + + @param Xhc The XHCI Instance. + @param Offset The offset of the operational register. + @param Bit The bit of the register to wait for. + @param WaitToSet Wait the bit to set or clear. + @param Timeout The time to wait before abort (in millisecond, ms). + + @retval EFI_SUCCESS The bit successfully changed by host controller. + @retval EFI_TIMEOUT The time out occurred. + +**/ +EFI_STATUS +XhcWaitMmioRegBit ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset, + IN UINT32 Bit, + IN BOOLEAN WaitToSet, + IN UINT32 Timeout + ) +{ + UINT32 Index; + UINTN Loop; + + Loop =3D (Timeout * XHC_1_MILLISECOND / XHC_POLL_DELAY) + 1; + + for (Index =3D 0; Index < Loop; Index++) { + if (XHC_REG_BIT_IS_SET (Xhc, Offset, Bit) =3D=3D WaitToSet) { + return EFI_SUCCESS; + } + + MicroSecondDelay (XHC_POLL_DELAY); + } + + return EFI_TIMEOUT; +} diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3De= bugPortDataTransfer.c b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPor= tLib/Usb3DebugPortDataTransfer.c new file mode 100644 index 0000000000..53478a49b8 --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPort= DataTransfer.c @@ -0,0 +1,892 @@ +/** @file + Usb3 Debug Port library instance + + Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include "Usb3DebugPortLibInternal.h" + +EFI_SMRAM_DESCRIPTOR mSmramCheckRanges[MAX_SMRAM_RANGE]; +UINTN mSmramCheckRangeCount =3D 0; +BOOLEAN mUsb3InSmm =3D FALSE; +UINT64 mUsb3MmioSize =3D 0; + +/** + Synchronize the specified transfer ring to update the enqueue and dequeu= e pointer. + + @param Xhc The XHCI Instance. + @param TrsRing The transfer ring to sync. + + @retval EFI_SUCCESS The transfer ring is synchronized successfully. + +**/ +EFI_STATUS +EFIAPI +XhcSyncTrsRing ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN TRANSFER_RING *TrsRing + ) +{ + UINTN Index; + TRB_TEMPLATE *TrsTrb; + + ASSERT (TrsRing !=3D NULL); + + // + // Calculate the latest RingEnqueue and RingPCS + // + TrsTrb =3D (TRB_TEMPLATE *)(UINTN) TrsRing->RingEnqueue; + + ASSERT (TrsTrb !=3D NULL); + + for (Index =3D 0; Index < TrsRing->TrbNumber; Index++) { + if (TrsTrb->CycleBit !=3D (TrsRing->RingPCS & BIT0)) { + break; + } + TrsTrb++; + if ((UINT8) TrsTrb->Type =3D=3D TRB_TYPE_LINK) { + ASSERT (((LINK_TRB*)TrsTrb)->TC !=3D 0); + // + // set cycle bit in Link TRB as normal + // + ((LINK_TRB*)TrsTrb)->CycleBit =3D TrsRing->RingPCS & BIT0; + // + // Toggle PCS maintained by software + // + TrsRing->RingPCS =3D (TrsRing->RingPCS & BIT0) ? 0 : 1; + TrsTrb =3D (TRB_TEMPLATE *)(UINTN)((TrsTrb->Parameter1 | L= ShiftU64 ((UINT64)TrsTrb->Parameter2, 32)) & ~0x0F); + } + } + ASSERT (Index !=3D TrsRing->TrbNumber); + + if ((EFI_PHYSICAL_ADDRESS)(UINTN) TrsTrb !=3D TrsRing->RingEnqueue) { + TrsRing->RingEnqueue =3D (EFI_PHYSICAL_ADDRESS)(UINTN) TrsTrb; + } + + // + // Clear the Trb context for enqueue, but reserve the PCS bit + // + TrsTrb->Parameter1 =3D 0; + TrsTrb->Parameter2 =3D 0; + TrsTrb->Status =3D 0; + TrsTrb->RsvdZ1 =3D 0; + TrsTrb->Type =3D 0; + TrsTrb->Control =3D 0; + + return EFI_SUCCESS; +} + +/** + Synchronize the specified event ring to update the enqueue and dequeue p= ointer. + + @param Xhc The XHCI Instance. + @param EvtRing The event ring to sync. + + @retval EFI_SUCCESS The event ring is synchronized successfully. + +**/ +EFI_STATUS +EFIAPI +XhcSyncEventRing ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN EVENT_RING *EvtRing + ) +{ + UINTN Index; + TRB_TEMPLATE *EvtTrb1; + + ASSERT (EvtRing !=3D NULL); + + // + // Calculate the EventRingEnqueue and EventRingCCS. + // Note: only support single Segment + // + EvtTrb1 =3D (TRB_TEMPLATE *)(UINTN) EvtRing->EventRingDequeue; + + for (Index =3D 0; Index < EvtRing->TrbNumber; Index++) { + if (EvtTrb1->CycleBit !=3D EvtRing->EventRingCCS) { + break; + } + + EvtTrb1++; + + if ((UINTN)EvtTrb1 >=3D ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB_= TEMPLATE) * EvtRing->TrbNumber)) { + EvtTrb1 =3D (TRB_TEMPLATE *)(UINTN) EvtRing->EventRingSeg0; + EvtRing->EventRingCCS =3D (EvtRing->EventRingCCS) ? 0 : 1; + } + } + + if (Index < EvtRing->TrbNumber) { + EvtRing->EventRingEnqueue =3D (EFI_PHYSICAL_ADDRESS)(UINTN)EvtTrb1; + } else { + ASSERT (FALSE); + } + + return EFI_SUCCESS; +} + +/** + Check if there is a new generated event. + + @param Xhc The XHCI Instance. + @param EvtRing The event ring to check. + @param NewEvtTrb The new event TRB found. + + @retval EFI_SUCCESS Found a new event TRB at the event ring. + @retval EFI_NOT_READY The event ring has no new event. + +**/ +EFI_STATUS +EFIAPI +XhcCheckNewEvent ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN EVENT_RING *EvtRing, + OUT TRB_TEMPLATE **NewEvtTrb + ) +{ + EFI_STATUS Status; + + ASSERT (EvtRing !=3D NULL); + + *NewEvtTrb =3D (TRB_TEMPLATE *)(UINTN) EvtRing->EventRingDequeue; + + if (EvtRing->EventRingDequeue =3D=3D EvtRing->EventRingEnqueue) { + return EFI_NOT_READY; + } + + Status =3D EFI_SUCCESS; + + EvtRing->EventRingDequeue +=3D sizeof (TRB_TEMPLATE); + // + // If the dequeue pointer is beyond the ring, then roll-back it to the b= egining of the ring. + // + if ((UINTN)EvtRing->EventRingDequeue >=3D ((UINTN) EvtRing->EventRingSeg= 0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) { + EvtRing->EventRingDequeue =3D EvtRing->EventRingSeg0; + } + + return Status; +} + +/** + Check if the Trb is a transaction of the URB. + + @param Trb The TRB to be checked + @param Urb The transfer ring to be checked. + + @retval TRUE It is a transaction of the URB. + @retval FALSE It is not any transaction of the URB. + +**/ +BOOLEAN +IsTransferRingTrb ( + IN TRB_TEMPLATE *Trb, + IN URB *Urb + ) +{ + TRB_TEMPLATE *CheckedTrb; + TRANSFER_RING *Ring; + UINTN Index; + + Ring =3D (TRANSFER_RING *)(UINTN) Urb->Ring; + CheckedTrb =3D (TRB_TEMPLATE *)(UINTN) Ring->RingSeg0; + + ASSERT (Ring->TrbNumber =3D=3D CMD_RING_TRB_NUMBER || Ring->TrbNumber = =3D=3D TR_RING_TRB_NUMBER); + + for (Index =3D 0; Index < Ring->TrbNumber; Index++) { + if (Trb =3D=3D CheckedTrb) { + return TRUE; + } + CheckedTrb++; + } + + return FALSE; +} + +/** + Check the URB's execution result and update the URB's + result accordingly. + + @param Xhc The XHCI Instance. + @param Urb The URB to check result. + + @return Whether the result of URB transfer is finialized. + +**/ +EFI_STATUS +XhcCheckUrbResult ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN URB *Urb + ) +{ + EVT_TRB_TRANSFER *EvtTrb; + TRB_TEMPLATE *TRBPtr; + UINTN Index; + UINT8 TRBType; + EFI_STATUS Status; + URB *CheckedUrb; + UINT64 XhcDequeue; + UINT32 High; + UINT32 Low; + + ASSERT ((Xhc !=3D NULL) && (Urb !=3D NULL)); + + Status =3D EFI_SUCCESS; + + if (Urb->Finished) { + goto EXIT; + } + + EvtTrb =3D NULL; + + // + // Traverse the event ring to find out all new events from the previous = check. + // + XhcSyncEventRing (Xhc, &Xhc->EventRing); + + for (Index =3D 0; Index < Xhc->EventRing.TrbNumber; Index++) { + Status =3D XhcCheckNewEvent (Xhc, &Xhc->EventRing, ((TRB_TEMPLATE **)&= EvtTrb)); + if (Status =3D=3D EFI_NOT_READY) { + // + // All new events are handled, return directly. + // + goto EXIT; + } + // + // Only handle COMMAND_COMPLETETION_EVENT and TRANSFER_EVENT. + // + if ((EvtTrb->Type !=3D TRB_TYPE_COMMAND_COMPLT_EVENT) && (EvtTrb->Type= !=3D TRB_TYPE_TRANS_EVENT)) { + continue; + } + + TRBPtr =3D (TRB_TEMPLATE *)(UINTN)(EvtTrb->TRBPtrLo | LShiftU64 ((UINT= 64) EvtTrb->TRBPtrHi, 32)); + + // + // Update the status of Urb according to the finished event regardless= of whether + // the urb is current checked one or in the XHCI's async transfer list. + // This way is used to avoid that those completed async transfer event= s don't get + // handled in time and are flushed by newer coming events. + // + if (IsTransferRingTrb (TRBPtr, Urb)) { + CheckedUrb =3D Urb; + } else { + continue; + } + switch (EvtTrb->Completecode) { + case TRB_COMPLETION_STALL_ERROR: + CheckedUrb->Result |=3D EFI_USB_ERR_STALL; + CheckedUrb->Finished =3D TRUE; + break; + + case TRB_COMPLETION_BABBLE_ERROR: + CheckedUrb->Result |=3D EFI_USB_ERR_BABBLE; + CheckedUrb->Finished =3D TRUE; + break; + + case TRB_COMPLETION_DATA_BUFFER_ERROR: + CheckedUrb->Result |=3D EFI_USB_ERR_BUFFER; + CheckedUrb->Finished =3D TRUE; + break; + + case TRB_COMPLETION_USB_TRANSACTION_ERROR: + CheckedUrb->Result |=3D EFI_USB_ERR_TIMEOUT; + CheckedUrb->Finished =3D TRUE; + break; + + case TRB_COMPLETION_SHORT_PACKET: + case TRB_COMPLETION_SUCCESS: + if (EvtTrb->Completecode =3D=3D TRB_COMPLETION_SHORT_PACKET) { + } + + TRBType =3D (UINT8) (TRBPtr->Type); + if ((TRBType =3D=3D TRB_TYPE_DATA_STAGE) || + (TRBType =3D=3D TRB_TYPE_NORMAL) || + (TRBType =3D=3D TRB_TYPE_ISOCH)) { + CheckedUrb->Completed +=3D (CheckedUrb->DataLen - EvtTrb->Length= ); + } + + break; + + default: + CheckedUrb->Result |=3D EFI_USB_ERR_TIMEOUT; + CheckedUrb->Finished =3D TRUE; + break; + } + + // + // Only check first and end Trb event address + // + + if ((EFI_PHYSICAL_ADDRESS)(UINTN) TRBPtr =3D=3D CheckedUrb->TrbStart) { + CheckedUrb->StartDone =3D TRUE; + } + + if ((EFI_PHYSICAL_ADDRESS)(UINTN) TRBPtr =3D=3D CheckedUrb->TrbEnd) { + CheckedUrb->EndDone =3D TRUE; + } + + if (CheckedUrb->StartDone && CheckedUrb->EndDone) { + CheckedUrb->Finished =3D TRUE; + } + + } + +EXIT: + // + // Advance event ring to last available entry + // + // Some 3rd party XHCI external cards don't support single 64-bytes widt= h register access, + // So divide it to two 32-bytes width register access. + // + Low =3D XhcReadDebugReg (Xhc, XHC_DC_DCERDP); + High =3D XhcReadDebugReg (Xhc, XHC_DC_DCERDP + 4); + XhcDequeue =3D (UINT64)(LShiftU64((UINT64)High, 32) | Low); + + if ((XhcDequeue & (~0x0F)) !=3D ((UINT64)(UINTN)Xhc->EventRing.EventRing= Dequeue & (~0x0F))) { + // + // Some 3rd party XHCI external cards don't support single 64-bytes wi= dth register access, + // So divide it to two 32-bytes width register access. + // + XhcWriteDebugReg (Xhc, XHC_DC_DCERDP, XHC_LOW_32BIT (Xhc->EventRing.Ev= entRingDequeue)); + XhcWriteDebugReg (Xhc, XHC_DC_DCERDP + 4, XHC_HIGH_32BIT (Xhc->EventRi= ng.EventRingDequeue)); + } + + return Status; +} + +/** + Ring the door bell to notify XHCI there is a transaction to be executed. + + @param Xhc The XHCI Instance. + @param Urb The pointer to URB. + + @retval EFI_SUCCESS Successfully ring the door bell. + +**/ +EFI_STATUS +EFIAPI +XhcRingDoorBell ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN URB *Urb + ) +{ + UINT32 Dcdb; + + // + // 7.6.8.2 DCDB Register + // + if (Urb->Direction =3D=3D EfiUsbDataIn) { + Dcdb =3D 0x100; + } else { + Dcdb =3D 0x0; + } + + XhcWriteDebugReg ( + Xhc, + XHC_DC_DCDB, + Dcdb + ); + + return EFI_SUCCESS; +} + +/** + Execute the transfer by polling the URB. This is a synchronous operation. + + @param Xhc The XHCI Instance. + @param Urb The URB to execute. + @param Timeout The time to wait before abort, in millisecond. + + @return EFI_DEVICE_ERROR The transfer failed due to transfer error. + @return EFI_TIMEOUT The transfer failed due to time out. + @return EFI_SUCCESS The transfer finished OK. + +**/ +EFI_STATUS +XhcExecTransfer ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN URB *Urb, + IN UINTN Timeout + ) +{ + EFI_STATUS Status; + UINTN Index; + UINTN Loop; + TRB_TEMPLATE *Trb; + TRANSFER_RING *Ring; + TRB_TEMPLATE *TrbStart; + TRB_TEMPLATE *TrbEnd; + + Status =3D EFI_SUCCESS; + + Loop =3D (Timeout * XHC_1_MILLISECOND / XHC_POLL_DELAY) + 1; + if (Timeout =3D=3D 0) { + Loop =3D 0xFFFFFFFF; + } + XhcRingDoorBell (Xhc, Urb); + // + // DSCT BIT0: Event Ring Not Empty bit can only be set to 1 by XHC after= ringing door bell with some delay. + // + + for (Index =3D 0; Index < Loop; Index++) { + Status =3D XhcCheckUrbResult (Xhc, Urb); + if (Urb->Finished) { + break; + } + MicroSecondDelay (XHC_POLL_DELAY); + } + if (Index =3D=3D Loop) { + Urb->Result =3D EFI_USB_ERR_TIMEOUT; + } + + // + // If URB transfer is error, restore transfer ring to original value bef= ore URB transfer + // This will make the current transfer TRB is always at the latest unuse= d one in transfer ring. + // Without this code, when there is read TRB from target, but host does = not write anything, this TRB (A) + // will be still here, next read TRB (B) will be put next to TRB (A), wh= en host write then, the TRB (A) + // will be used to contain data, not TRB(B), this will cause Finished fl= ag will not be set and return error in this function. + // + Ring =3D (TRANSFER_RING *)(UINTN) Urb->Ring; + if (Urb->Result !=3D EFI_USB_NOERROR) { + Ring->RingEnqueue =3D Urb->TrbStart; + // + // Clear CCS flag for next use + // + TrbStart =3D (TRB_TEMPLATE *)(UINTN) Urb->TrbStart; + TrbEnd =3D (TRB_TEMPLATE *)(UINTN) Urb->TrbEnd; + for (Trb =3D TrbStart; Trb <=3D TrbEnd; Trb++) { + Trb->CycleBit =3D ((~Ring->RingPCS) & BIT0); + } + } + return Status; +} + +/** + Create a transfer TRB. + + @param Xhc The XHCI Instance + @param Urb The urb used to construct the transfer TRB. + + @return Created TRB or NULL + +**/ +EFI_STATUS +XhcCreateTransferTrb ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN URB *Urb + ) +{ + TRANSFER_RING *EPRing; + TRB *TrbStart; + UINT32 TotalLen; + UINT32 Len; + UINT32 TrbNum; + + Urb->Finished =3D FALSE; + Urb->StartDone =3D FALSE; + Urb->EndDone =3D FALSE; + Urb->Completed =3D 0; + Urb->Result =3D EFI_USB_NOERROR; + + if (Urb->Direction =3D=3D EfiUsbDataIn) { + EPRing =3D &Xhc->TransferRingIn; + } else { + EPRing =3D &Xhc->TransferRingOut; + } + + Urb->Ring =3D (EFI_PHYSICAL_ADDRESS)(UINTN) EPRing; + // + // Construct the TRB for ED_BULK_OUT and ED_BULK_IN + // + XhcSyncTrsRing (Xhc, EPRing); + + Urb->TrbStart =3D EPRing->RingEnqueue; + + TotalLen =3D 0; + Len =3D 0; + TrbNum =3D 0; + TrbStart =3D (TRB *)(UINTN)EPRing->RingEnqueue; + + while (TotalLen < Urb->DataLen) { + if ((TotalLen + 0x10000) >=3D Urb->DataLen) { + Len =3D Urb->DataLen - TotalLen; + } else { + Len =3D 0x10000; + } + TrbStart =3D (TRB *)(UINTN)EPRing->RingEnqueue; + TrbStart->TrbNormal.TRBPtrLo =3D XHC_LOW_32BIT(Urb->Data + TotalLen); + TrbStart->TrbNormal.TRBPtrHi =3D XHC_HIGH_32BIT(Urb->Data + TotalLen); + TrbStart->TrbNormal.Length =3D Len; + TrbStart->TrbNormal.TDSize =3D 0; + TrbStart->TrbNormal.IntTarget =3D 0; + TrbStart->TrbNormal.ISP =3D 1; + TrbStart->TrbNormal.IOC =3D 1; + TrbStart->TrbNormal.Type =3D TRB_TYPE_NORMAL; + + // + // Update the cycle bit + // + TrbStart->TrbNormal.CycleBit =3D EPRing->RingPCS & BIT0; + + XhcSyncTrsRing (Xhc, EPRing); + TrbNum++; + TotalLen +=3D Len; + } + + Urb->TrbNum =3D TrbNum; + + // + // Update to the last TRB + // + Urb->TrbEnd =3D (EFI_PHYSICAL_ADDRESS)(UINTN) TrbStart; + return EFI_SUCCESS; +} + +/** + Create a new URB for a new transaction. + + @param Xhc The XHCI Instance + @param Direction The direction of data flow. + @param Data The user data to transfer + @param DataLen The length of data buffer + + @return Created URB or NULL + +**/ +URB* +XhcCreateUrb ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN EFI_USB_DATA_DIRECTION Direction, + IN VOID *Data, + IN UINTN DataLen + ) +{ + EFI_STATUS Status; + URB *Urb; + EFI_PHYSICAL_ADDRESS DataAddress; + + Urb =3D &Xhc->Urb; + ASSERT (Urb->Data !=3D 0); + DataAddress =3D Urb->Data; + ZeroMem (Urb, sizeof (URB)); + + Urb->Signature =3D USB3_DEBUG_PORT_INSTANCE_SIGNATURE; + Urb->Direction =3D Direction; + Urb->Data =3D DataAddress; + + ZeroMem ((VOID*)(UINTN) Urb->Data, DataLen); + CopyMem ((VOID*)(UINTN) Urb->Data, Data, DataLen); + + Urb->DataLen =3D (UINT32) DataLen; + Status =3D XhcCreateTransferTrb (Xhc, Urb); + ASSERT_EFI_ERROR (Status); + + return Urb; +} + +/** + Submits bulk transfer to a bulk endpoint of a USB device. + + @param Xhc The instance of debug device. + @param Direction The direction of data transfer. + @param Data Array of pointers to the buffers of data t= o transmit + from or receive into. + @param DataLength The lenght of the data buffer. + @param Timeout Indicates the maximum time, in millisecond= , which + the transfer is allowed to complete. + @param TransferResult Transfer result. + + @retval EFI_SUCCESS The transfer was completed successfully. + @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resourc= e. + @retval EFI_INVALID_PARAMETER Some parameters are invalid. + @retval EFI_TIMEOUT The transfer failed due to timeout. + @retval EFI_DEVICE_ERROR The transfer failed due to host controller= error. + +**/ +EFI_STATUS +EFIAPI +XhcDataTransfer ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN EFI_USB_DATA_DIRECTION Direction, + IN OUT VOID *Data, + IN OUT UINTN *DataLength, + IN UINTN Timeout, + OUT UINT32 *TransferResult + ) +{ + URB *Urb; + EFI_STATUS Status; + + // + // Validate the parameters + // + if ((DataLength =3D=3D NULL) || (*DataLength =3D=3D 0) || + (Data =3D=3D NULL) || (TransferResult =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + *TransferResult =3D EFI_USB_ERR_SYSTEM; + Status =3D EFI_DEVICE_ERROR; + + // + // Create a new URB, insert it into the asynchronous + // schedule list, then poll the execution status. + // + Urb =3D XhcCreateUrb (Xhc, Direction, Data, *DataLength); + + if (Urb =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + Status =3D XhcExecTransfer (Xhc, Urb, Timeout); + + *TransferResult =3D Urb->Result; + *DataLength =3D Urb->Completed; + + if (*TransferResult =3D=3D EFI_USB_NOERROR) { + Status =3D EFI_SUCCESS; + } + +ON_EXIT: + + return Status; +} + +/** + Check whether the MMIO Bar is within any of the SMRAM ranges. + + @param[in] XhcMmioBase The address of the MMIO to be checked. + + @retval TURE The XHCI MMIO is in SMRAM ranges. + @retval FALSE The XHCI MMIO is out of SMRAM ranges. +**/ +BOOLEAN +EFIAPI +Usb3DebugIsAddressInSmram ( + IN EFI_PHYSICAL_ADDRESS XhcMmioBase + ) +{ + UINTN Index; + + if (mSmramCheckRangeCount =3D=3D 0) { + // + // When we invoke this function, we are already in SMM mode, + // but SmmAccess->GetCapabilities failed which kept mSmramCheckRanges = as 0. + // + return TRUE; + } + + for (Index =3D 0; Index < mSmramCheckRangeCount; Index ++) { + if (((XhcMmioBase >=3D mSmramCheckRanges[Index].CpuStart) && (XhcMmioB= ase < mSmramCheckRanges[Index].CpuStart + mSmramCheckRanges[Index].Physical= Size)) || + ((mSmramCheckRanges[Index].CpuStart >=3D XhcMmioBase) && (mSmramCh= eckRanges[Index].CpuStart < XhcMmioBase + mUsb3MmioSize))) { + return TRUE; + } + } + + return FALSE; +} + +/** + Transfer data via XHC controller. + + @param Data Data buffer. + @param Length Data length. + @param Direction Transfer direction. + +**/ +VOID +Usb3DebugPortDataTransfer ( + UINT8 *Data, + UINTN *Length, + EFI_USB_DATA_DIRECTION Direction + ) +{ + USB3_DEBUG_PORT_INSTANCE *Instance; + EFI_PHYSICAL_ADDRESS XhcMmioBase; + UINT16 Command; + UINT8 Bus; + UINT8 Device; + UINT8 Function; + UINT32 TransferResult; + UINT32 Dcctrl; + EFI_PHYSICAL_ADDRESS UsbBase; + UINTN BytesToSend; + USB3_DEBUG_PORT_CONTROLLER UsbDebugPort; + EFI_STATUS Status; + USB3_DEBUG_PORT_INSTANCE UsbDbgInstance; + + UsbDebugPort.Controller =3D GetUsb3DebugPortController(); + Bus =3D UsbDebugPort.PciAddress.Bus; + Device =3D UsbDebugPort.PciAddress.Device; + Function =3D UsbDebugPort.PciAddress.Function; + + // + // MMIO base address is possible to clear, set it if it is cleared. (Xhc= iMemorySpaceClose in PchUsbCommon.c) + // + XhcMmioBase =3D GetXhciBaseAddress (); + Command =3D GetXhciPciCommand (); + + if ((XhcMmioBase =3D=3D 0) || (XhcMmioBase =3D=3D XHCI_BASE_ADDRESS_64_B= IT_MASK)) { + // + // XHCI device MMIO base is cleared by someone, set it again + // + UsbBase =3D PcdGet32 (PcdXhciDefaultBaseAddress); + PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG= _OFFSET), (UINT32)UsbBase); + PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG= _OFFSET + 4), 0x0); + UsbBase =3D PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE= _ADDRESSREG_OFFSET)) & XHCI_BASE_ADDRESS_32_BIT_MASK; + if (UsbBase =3D=3D 0 || UsbBase =3D=3D XHCI_BASE_ADDRESS_32_BIT_MASK) { + return; + } + } + + // + // Check if XHC debug MMIO range is in SMRAM + // + if ((mUsb3InSmm) && (Usb3DebugIsAddressInSmram (XhcMmioBase))) { + return; + } + + // + // Save and set Command Register + // + if (((Command & EFI_PCI_COMMAND_MEMORY_SPACE) =3D=3D 0) || ((Command & E= FI_PCI_COMMAND_BUS_MASTER) =3D=3D 0)) { + PciWrite16(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAND_OFFSET),= Command | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER); + PciRead16(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAND_OFFSET)); + } + + Instance =3D GetUsb3DebugPortInstance (); + + if (Instance !=3D NULL) { + if (!Instance->DebugSupport) { + // + // Debug device is not supported by XHCI, return + // + goto Done; + } + } + + if ((Instance !=3D NULL) && (Instance->Ready)) { + // + // Debug device is broken suddently (e.g. Windows OS), return + // + Dcctrl =3D XhcReadDebugReg (Instance, XHC_DC_DCCTRL); + if ((Dcctrl & BIT0) =3D=3D 0) { + goto Done; + } + } + + if ((Instance !=3D NULL) && (!Instance->Ready)) { + // + // Debug host does not connect with target + // + goto Done; + } + + if (Instance =3D=3D NULL) { + ZeroMem (&UsbDbgInstance, sizeof (USB3_DEBUG_PORT_INSTANCE)); + DiscoverUsb3DebugPort (&UsbDbgInstance); + if (UsbDbgInstance.DebugSupport) { + if (!IsAllocatePagesReady ()) { + // + // AllocatePages can not work, return + // + goto Done; + } + } + Status =3D USB3InitializeReal (); + if (EFI_ERROR (Status)) { + // + // Debug device is failed to initialize + // + goto Done; + } + + // + // Update instance + // + Instance =3D GetUsb3DebugPortInstance (); + + if (Instance =3D=3D NULL) { + // + // Debug device instance is failed to create + // + goto Done; + } + + if ((!Instance->Ready) || (!Instance->DebugSupport)) { + // + // Debug host does not connect at first or is not supported + // + goto Done; + } + } + + BytesToSend =3D 0; + while (*Length > 0) { + BytesToSend =3D ((*Length) > XHC_DEBUG_PORT_DATA_LENGTH) ? XHC_DEBUG_P= ORT_DATA_LENGTH : *Length; + XhcDataTransfer ( + Instance, + Direction, + Data, + &BytesToSend, + DATA_TRANSFER_TIME_OUT, + &TransferResult + ); + if (TransferResult !=3D EFI_USB_NOERROR) { + break; + } + *Length -=3D BytesToSend; + Data +=3D BytesToSend; + } + +Done: + // + // Restore Command Register + // + PciWrite16(PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), = Command); + +} + +/** + Receive data over the USB3 debug cable. + + @param[out] Data Pointer to data + @param[in, out] Length Pointer to data length + +**/ +RETURN_STATUS +Usb3DbgIn ( + OUT UINT8 *Data, + IN OUT UINTN *Length + ) +{ + Usb3DebugPortDataTransfer (Data, Length, EfiUsbDataIn); + return EFI_SUCCESS; +} + +/** + Send data over the USB3 debug cable. + + @param[out] Data Pointer to data + @param[in, out] Length Pointer to data length + +**/ +VOID +Usb3DbgOut ( + OUT UINT8 *Data, + IN OUT UINTN *Length + ) +{ + Usb3DebugPortDataTransfer (Data, Length, EfiUsbDataOut); +} diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3De= bugPortInitialize.c b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortL= ib/Usb3DebugPortInitialize.c new file mode 100644 index 0000000000..dbdae59253 --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPort= Initialize.c @@ -0,0 +1,726 @@ +/** @file + Usb3 Debug Port initialization + + Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Usb3DebugPortLibInternal.h" + +UINT16 mString0Desc[] =3D { + // String Descriptor Type + Length + ( USB_DESC_TYPE_STRING << 8 ) + STRING0_DESC_LEN, + 0x0409 +}; + +UINT16 mManufacturerStrDesc[] =3D { + // String Descriptor Type + Length + ( USB_DESC_TYPE_STRING << 8 ) + MANU_DESC_LEN, + 'I', 'n', 't', 'e', 'l' +}; + +//USB 3.0 Debug Cable +UINT16 mProductStrDesc[] =3D { + // String Descriptor Type + Length + ( USB_DESC_TYPE_STRING << 8 ) + PRODUCT_DESC_LEN, + 'U', 'S', 'B', ' ', '3', '.', '0', ' ', 'D', 'e', 'b', 'u', 'g', ' ', 'C= ', 'a', 'b', 'l', 'e' +}; + +UINT16 mSerialNumberStrDesc[] =3D { + // String Descriptor Type + Length + ( USB_DESC_TYPE_STRING << 8 ) + SERIAL_DESC_LEN, + '1' +}; + +XHC_DC_CONTEXT DebugCapabilityContextTemplate =3D { + { + 0, + 0, + 0, + 0, + STRING0_DESC_LEN, + MANU_DESC_LEN, + PRODUCT_DESC_LEN, + SERIAL_DESC_LEN, + 0, + 0, + 0, + 0 + }, + { + 0, // EPState + 0, // RsvdZ1 + 0, // Mult + 0, // MaxPStreams + 0, // LSA + 0, // Interval + 0, // RsvdZ2 + 0, // RsvdZ3 + 3, // CERR + ED_BULK_OUT, // EPType + 0, // RsvdZ4 + 0, // HID + 0, // MaxBurstSize + 1024, // MaxPacketSize + 0, // PtrLo + 0, // PtrHi + 0x1000, // AverageTRBLength + 0, // MaxESITPayload + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, //CERR + ED_BULK_IN, + 0, + 0, + 0, + 1024, //MaxPacketSize + 0, + 0, + 0x1000, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + } +}; + +/** + Return command register value in XHCI controller. + +**/ +UINT16 +GetXhciPciCommand ( + VOID + ) +{ + UINT8 Bus; + UINT8 Device; + UINT8 Function; + UINT16 Command; + USB3_DEBUG_PORT_CONTROLLER UsbDebugPort; + + UsbDebugPort.Controller =3D GetUsb3DebugPortController(); + + Bus =3D UsbDebugPort.PciAddress.Bus; + Device =3D UsbDebugPort.PciAddress.Device; + Function =3D UsbDebugPort.PciAddress.Function; + Command =3D PciRead16(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAND= _OFFSET)); + return Command; +} + +/** + Discover the USB3 debug device. + + @param[in] Instance Pointer to USB3 debug port object instance. + + @retval RETURN_SUCCESS The USB3 debug device was found. + @retval RETURN_DEVICE_ERROR The USB3 debug device was not found. + +**/ +RETURN_STATUS +DiscoverUsb3DebugPort( + IN USB3_DEBUG_PORT_INSTANCE *Instance + ) +{ + UINT8 Bus; + UINT8 Device; + UINT8 Function; + UINT16 Command; + EFI_PHYSICAL_ADDRESS UsbBase; + USB3_DEBUG_PORT_CONTROLLER UsbDebugPort; + EFI_PHYSICAL_ADDRESS CapabilityPointer; + UINT32 Capability; + BOOLEAN Flag; + UINT8 CapLength; + + UsbDebugPort.Controller =3D GetUsb3DebugPortController(); + Bus =3D UsbDebugPort.PciAddress.Bus; + Device =3D UsbDebugPort.PciAddress.Device; + Function =3D UsbDebugPort.PciAddress.Function; + if ((PciRead8(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_CLASSCODE_OFFSE= T + 2)) !=3D PCI_CLASS_SERIAL) || + (PciRead8(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_CLASSCODE_OFFSE= T + 1)) !=3D PCI_CLASS_SERIAL_USB) || + (PciRead8(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_CLASSCODE_OFFSE= T)) !=3D 0x30)) { + // + // The device is not XHCI controller + // + return RETURN_NOT_FOUND; + } + + // + // USBBASE is at 10-13h, i.e. the first BAR, clear the low bits which is= not part of base address + // + UsbBase =3D GetXhciBaseAddress (); + + // + // Set XHCI MMIO base address if necessary + // + if ((UsbBase =3D=3D 0) || (UsbBase =3D=3D XHCI_BASE_ADDRESS_64_BIT_MASK)= ) { + UsbBase =3D PcdGet32 (PcdXhciDefaultBaseAddress); + PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG= _OFFSET), (UINT32)UsbBase); + PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG= _OFFSET + 4), 0x0); + UsbBase =3D PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE= _ADDRESSREG_OFFSET)) & XHCI_BASE_ADDRESS_32_BIT_MASK; + if (UsbBase =3D=3D 0 || UsbBase =3D=3D XHCI_BASE_ADDRESS_32_BIT_MASK) { + return RETURN_DEVICE_ERROR; + } + } + + // + // Set MSE and BME bit - enable the address space + // + Command =3D PciRead16 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAN= D_OFFSET)); + if ((Command & EFI_PCI_COMMAND_MEMORY_SPACE) =3D=3D 0) { + PciWrite16(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAND_OFFSET),= Command | EFI_PCI_COMMAND_MEMORY_SPACE); + PciRead16(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAND_OFFSET)); + } + + CapLength =3D MmioRead8 ((UINTN) UsbBase); + + // + // Get capability pointer from HCCPARAMS at offset 0x10 + // + CapabilityPointer =3D UsbBase + (MmioRead32 ((UINTN)(UsbBase + XHC_HCCPA= RAMS_OFFSET)) >> 16) * 4; + + // + // Search XHCI debug capability + // + Flag =3D FALSE; + Capability =3D MmioRead32 ((UINTN)CapabilityPointer); + while (TRUE) { + if ((Capability & XHC_CAPABILITY_ID_MASK) =3D=3D PCI_CAPABILITY_ID_DEB= UG_PORT) { + Flag =3D TRUE; + break; + } + if ((((Capability & XHC_NEXT_CAPABILITY_MASK) >> 8) & XHC_CAPABILITY_I= D_MASK) =3D=3D 0) { + // + // Reach the end of capability list, quit + // + break; + } + CapabilityPointer +=3D ((Capability & XHC_NEXT_CAPABILITY_MASK) >> 8) = * 4; + Capability =3D MmioRead32 ((UINTN)CapabilityPointer); + } + + Instance->Signature =3D USB3_DEBUG_PORT_INSTANCE_SIGNATURE; + + if (Flag) { + Instance->DebugSupport =3D TRUE; + Instance->DebugCapabilityBase =3D CapabilityPointer; + Instance->DebugCapabilityOffset =3D CapabilityPointer - UsbBase; + + Instance->XhciOpRegister =3D UsbBase + CapLength; + Instance->XhcMmioBase =3D UsbBase; + + Instance->PciBusNumber =3D Bus; + Instance->PciDeviceNumber =3D Device; + Instance->PciFunctionNumber =3D Function; + } + + // + // Restore Command Register + // + PciWrite16(PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), = Command); + + return RETURN_SUCCESS; +} + +/** + Create XHCI event ring. + + @param Xhc The XHCI Instance. + @param EventRing The created event ring. + +**/ +EFI_STATUS +CreateEventRing ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + OUT EVENT_RING *EventRing + ) +{ + VOID *Buf; + EVENT_RING_SEG_TABLE_ENTRY *ERSTBase; + + ASSERT (EventRing !=3D NULL); + + // + // Allocate Event Ring + // + Buf =3D AllocateAlignBuffer (sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMB= ER); + ASSERT (Buf !=3D NULL); + ASSERT (((UINTN) Buf & 0x3F) =3D=3D 0); + ZeroMem (Buf, sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER); + + EventRing->EventRingSeg0 =3D (EFI_PHYSICAL_ADDRESS)(UINTN) Buf; + EventRing->TrbNumber =3D EVENT_RING_TRB_NUMBER; + EventRing->EventRingDequeue =3D (EFI_PHYSICAL_ADDRESS)(UINTN) EventRing-= >EventRingSeg0; + EventRing->EventRingEnqueue =3D (EFI_PHYSICAL_ADDRESS)(UINTN) EventRing-= >EventRingSeg0; + + // + // Software maintains an Event Ring Consumer Cycle State (CCS) bit, init= ializing it to '1' + // and toggling it every time the Event Ring Dequeue Pointer wraps back = to the beginning of the Event Ring. + // + EventRing->EventRingCCS =3D 1; + + // + // Allocate Event Ring Segment Table Entry 0 in Event Ring Segment Table + // + Buf =3D AllocateAlignBuffer (sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_= NUMBER); + ASSERT (Buf !=3D NULL); + ASSERT (((UINTN) Buf & 0x3F) =3D=3D 0); + ZeroMem (Buf, sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER); + + ERSTBase =3D (EVENT_RING_SEG_TABLE_ENTRY *) Buf; + EventRing->ERSTBase =3D (EFI_PHYSICAL_ADDRESS)(UINTN) ERSTBase; + + // + // Fill Event Segment address + // + ERSTBase->PtrLo =3D XHC_LOW_32BIT (EventRing->EventRingSeg0); + ERSTBase->PtrHi =3D XHC_HIGH_32BIT (EventRing->EventRingSeg0); + ERSTBase->RingTrbSize =3D EVENT_RING_TRB_NUMBER; + + // + // Program the Interrupter Event Ring Dequeue Pointer (DCERDP) register = (7.6.4.1) + // + XhcWriteDebugReg ( + Xhc, + XHC_DC_DCERDP, + XHC_LOW_32BIT((UINT64)(UINTN)EventRing->EventRingDequeue) + ); + + XhcWriteDebugReg ( + Xhc, + XHC_DC_DCERDP + 4, + XHC_HIGH_32BIT((UINT64)(UINTN)EventRing->EventRingDequeue) + ); + + // + // Program the Debug Capability Event Ring Segment Table Base Address (D= CERSTBA) register(7.6.4.1) + // + XhcWriteDebugReg ( + Xhc, + XHC_DC_DCERSTBA, + XHC_LOW_32BIT((UINT64)(UINTN)ERSTBase) + ); + + XhcWriteDebugReg ( + Xhc, + XHC_DC_DCERSTBA + 4, + XHC_HIGH_32BIT((UINT64)(UINTN)ERSTBase) + ); + + // + // Program the Debug Capability Event Ring Segment Table Size (DCERSTSZ)= register(7.6.4.1) + // + XhcWriteDebugReg ( + Xhc, + XHC_DC_DCERSTSZ, + ERST_NUMBER + ); + return EFI_SUCCESS; +} + +/** + Create XHCI transfer ring. + + @param Xhc The XHCI Instance. + @param TrbNum The number of TRB in the ring. + @param TransferRing The created transfer ring. + +**/ +VOID +CreateTransferRing ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 TrbNum, + OUT TRANSFER_RING *TransferRing + ) +{ + VOID *Buf; + LINK_TRB *EndTrb; + + Buf =3D AllocateAlignBuffer (sizeof (TRB_TEMPLATE) * TrbNum); + ASSERT (Buf !=3D NULL); + ASSERT (((UINTN) Buf & 0xF) =3D=3D 0); + ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum); + + TransferRing->RingSeg0 =3D (EFI_PHYSICAL_ADDRESS)(UINTN) Buf; + TransferRing->TrbNumber =3D TrbNum; + TransferRing->RingEnqueue =3D TransferRing->RingSeg0; + TransferRing->RingDequeue =3D TransferRing->RingSeg0; + TransferRing->RingPCS =3D 1; + // + // 4.9.2 Transfer Ring Management + // To form a ring (or circular queue) a Link TRB may be inserted at the = end of a ring to + // point to the first TRB in the ring. + // + EndTrb =3D (LINK_TRB *) ((UINTN)Buf + sizeof (TRB_TEMPLATE) * (Tr= bNum - 1)); + EndTrb->Type =3D TRB_TYPE_LINK; + EndTrb->PtrLo =3D XHC_LOW_32BIT (Buf); + EndTrb->PtrHi =3D XHC_HIGH_32BIT (Buf); + // + // Toggle Cycle (TC). When set to '1', the xHC shall toggle its interpre= tation of the Cycle bit. + // + EndTrb->TC =3D 1; + // + // Set Cycle bit as other TRB PCS init value + // + EndTrb->CycleBit =3D 0; +} + +/** + Create debug capability context for XHC debug device. + + @param Xhc The XHCI Instance. + + @retval EFI_SUCCESS The bit successfully changed by host controller. + @retval EFI_TIMEOUT The time out occurred. + +**/ +EFI_STATUS +CreateDebugCapabilityContext ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc + ) +{ + VOID *Buf; + XHC_DC_CONTEXT *DebugCapabilityContext; + UINT8 *String0Desc; + UINT8 *ManufacturerStrDesc; + UINT8 *ProductStrDesc; + UINT8 *SerialNumberStrDesc; + + // + // Allocate debug device context + // + Buf =3D AllocateAlignBuffer (sizeof (XHC_DC_CONTEXT)); + ASSERT (Buf !=3D NULL); + ASSERT (((UINTN) Buf & 0xF) =3D=3D 0); + ZeroMem (Buf, sizeof (XHC_DC_CONTEXT)); + + DebugCapabilityContext =3D (XHC_DC_CONTEXT *)(UINTN) Buf; + Xhc->DebugCapabilityContext =3D (EFI_PHYSICAL_ADDRESS)(UINTN) DebugCapab= ilityContext; + + CopyMem (DebugCapabilityContext, &DebugCapabilityContextTemplate, sizeof= (XHC_DC_CONTEXT)); + + // + // Update string descriptor address + // + String0Desc =3D (UINT8 *) AllocateAlignBuffer (STRING0_DESC_LEN + MANU_D= ESC_LEN + PRODUCT_DESC_LEN + SERIAL_DESC_LEN); + ASSERT (String0Desc !=3D NULL); + ZeroMem (String0Desc, STRING0_DESC_LEN + MANU_DESC_LEN + PRODUCT_DESC_LE= N + SERIAL_DESC_LEN); + CopyMem (String0Desc, mString0Desc, STRING0_DESC_LEN); + DebugCapabilityContext->DbcInfoContext.String0DescAddress =3D (UINT64)(U= INTN)String0Desc; + + ManufacturerStrDesc =3D String0Desc + STRING0_DESC_LEN; + CopyMem (ManufacturerStrDesc, mManufacturerStrDesc, MANU_DESC_LEN); + DebugCapabilityContext->DbcInfoContext.ManufacturerStrDescAddress =3D (U= INT64)(UINTN)ManufacturerStrDesc; + + ProductStrDesc =3D ManufacturerStrDesc + MANU_DESC_LEN; + CopyMem (ProductStrDesc, mProductStrDesc, PRODUCT_DESC_LEN); + DebugCapabilityContext->DbcInfoContext.ProductStrDescAddress =3D (UINT64= )(UINTN)ProductStrDesc; + + SerialNumberStrDesc =3D ProductStrDesc + PRODUCT_DESC_LEN; + CopyMem (SerialNumberStrDesc, mSerialNumberStrDesc, SERIAL_DESC_LEN); + DebugCapabilityContext->DbcInfoContext.SerialNumberStrDescAddress =3D (U= INT64)(UINTN)SerialNumberStrDesc; + + // + // Allocate and initialize the Transfer Ring for the Input Endpoint Cont= ext. + // + ZeroMem (&Xhc->TransferRingIn, sizeof (TRANSFER_RING)); + CreateTransferRing (Xhc, TR_RING_TRB_NUMBER, &Xhc->TransferRingIn); + + // + // Can not set BIT0, otherwise there is no transfer ring detected. + // + DebugCapabilityContext->EpInContext.PtrLo =3D XHC_LOW_32BIT (Xhc->Transf= erRingIn.RingSeg0) | BIT0; + DebugCapabilityContext->EpInContext.PtrHi =3D XHC_HIGH_32BIT (Xhc->Trans= ferRingIn.RingSeg0); + + // + // Allocate and initialize the Transfer Ring for the Output Endpoint Con= text. + // + ZeroMem (&Xhc->TransferRingOut, sizeof (TRANSFER_RING)); + CreateTransferRing (Xhc, TR_RING_TRB_NUMBER, &Xhc->TransferRingOut); + + // + // Can not set BIT0, otherwise there is no transfer ring detected. + // + DebugCapabilityContext->EpOutContext.PtrLo =3D XHC_LOW_32BIT (Xhc->Trans= ferRingOut.RingSeg0) | BIT0; + DebugCapabilityContext->EpOutContext.PtrHi =3D XHC_HIGH_32BIT (Xhc->Tran= sferRingOut.RingSeg0); + + // + // Program the Debug Capability Context Pointer (DCCP) register(7.6.8.7) + // + XhcWriteDebugReg ( + Xhc, + XHC_DC_DCCP, + XHC_LOW_32BIT((UINT64)(UINTN)DebugCapabilityContext) + ); + XhcWriteDebugReg ( + Xhc, + XHC_DC_DCCP + 4, + XHC_HIGH_32BIT((UINT64)(UINTN)DebugCapabilityContext) + ); + return EFI_SUCCESS; +} + +/** + Initialize the USB3 debug Device hardware. + + @param[in] Instance Pointer to USB3 debug port object instance. + + @retval RETURN_SUCCESS The USB3 debug device was initialized successf= ully. + @retval !RETURN_SUCCESS Error. + +**/ +RETURN_STATUS +InitializeUsb3DebugPort ( + IN USB3_DEBUG_PORT_INSTANCE *Instance + ) +{ + RETURN_STATUS Status; + UINT64 XhciOpRegister; + volatile UINT32 Dcctrl; + UINT8 Bus; + UINT8 Device; + UINT8 Function; + UINT16 Command; + EFI_BOOT_MODE BootMode; + UINT64 TimeOut; + CHAR8 *TestString; + UINTN Length; + UINT32 TransferResult; + + Bus =3D Instance->PciBusNumber; + Device =3D Instance->PciDeviceNumber; + Function =3D Instance->PciFunctionNumber; + + Command =3D GetXhciPciCommand (); + + // + // Save and set Command Register + // + if (((Command & EFI_PCI_COMMAND_MEMORY_SPACE) =3D=3D 0) || ((Command & E= FI_PCI_COMMAND_BUS_MASTER) =3D=3D 0)) { + PciWrite16(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAND_OFFSET),= Command | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER); + PciRead16(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAND_OFFSET)); + } + + // + // Clear DCE bit and LSE bit in DCCTRL + // + if ((XhcReadDebugReg (Instance, XHC_DC_DCCTRL) & (BIT1|BIT31)) =3D=3D (B= IT1|BIT31)) { + XhcClearDebugRegBit (Instance, XHC_DC_DCCTRL, BIT1|BIT31); + } + + XhciOpRegister =3D Instance->XhciOpRegister; + + // + // Get current Boot Mode + // + BootMode =3D GetBootModeHob (); + + if (BootMode !=3D BOOT_ON_S3_RESUME) { + if (!XhcIsBitSet((UINTN)(XhciOpRegister + XHC_USBSTS_OFFSET), XHC_USBS= TS_HALT)) { + XhcClrR32Bit((UINTN) XhciOpRegister + XHC_USBCMD_OFFSET, XHC_USBCMD_= RUN); + while (!XhcIsBitSet((UINTN)(XhciOpRegister + XHC_USBSTS_OFFSET), XHC= _USBSTS_HALT)) { + MicroSecondDelay (10); + } + } + + // + // Reset host controller + // + XhcSetR32Bit((UINTN)XhciOpRegister + XHC_USBCMD_OFFSET, XHC_USBCMD_RES= ET); + + // + // Ensure that the host controller is reset (RESET bit must be cleared= after reset) + // + while (XhcIsBitSet((UINTN)XhciOpRegister + XHC_USBCMD_OFFSET, XHC_USBC= MD_RESET)) { + MicroSecondDelay (10); + } + } + + // + // Initialize event ring + // + ZeroMem (&Instance->EventRing, sizeof (EVENT_RING)); + Status =3D CreateEventRing (Instance, &Instance->EventRing); + ASSERT_EFI_ERROR (Status); + + // + // Init IN and OUT endpoint context + // + Status =3D CreateDebugCapabilityContext (Instance); + ASSERT_EFI_ERROR (Status); + + // + // Init data buffer used to transfer + // + Instance->Urb.Data =3D (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateAlignBuffe= r (XHC_DEBUG_PORT_DATA_LENGTH); + + // + // Init DCDDI1 and DCDDI2 + // + XhcWriteDebugReg ( + Instance, + XHC_DC_DCDDI1, + (UINT32)((XHCI_DEBUG_DEVICE_VENDOR_ID << 16) | XHCI_DEBUG_DEVICE_PROTOC= OL) + ); + + XhcWriteDebugReg ( + Instance, + XHC_DC_DCDDI2, + (UINT32)((XHCI_DEBUG_DEVICE_REVISION << 16) | XHCI_DEBUG_DEVICE_PRODUCT= _ID) + ); + + // + // Set DCE bit and LSE bit to "1" in DCCTRL + // + XhcSetDebugRegBit (Instance, XHC_DC_DCCTRL, BIT1|BIT31); + + TimeOut =3D DivU64x32 (PcdGet64 (PcdXhciHostWaitTimeout), XHC_POLL_DELAY= ) + 1; + while (TimeOut !=3D 0) { + // + // Check if debug device is in configured state + // + Dcctrl =3D XhcReadDebugReg (Instance, XHC_DC_DCCTRL); + if ((Dcctrl & BIT0) !=3D 0) { + // + // Set the flag to indicate debug device is ready + // + Instance->Ready =3D TRUE; + break; + } + MicroSecondDelay (XHC_POLL_DELAY); + TimeOut--; + } + + if (!Instance->Ready) { + XhcClearDebugRegBit (Instance, XHC_DC_DCCTRL, BIT1|BIT31); + } else { + TestString =3D "Usb 3.0 Debug Message Start\n"; + Length =3D AsciiStrLen (TestString); + XhcDataTransfer ( + Instance, + EfiUsbDataOut, + TestString, + &Length, + 0, + &TransferResult + ); + } + + // + // Restore Command Register + // + PciWrite16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET),= Command); + + return EFI_SUCCESS; +} + +/** + Update XHC hardware address when MMIO base is changed. + + @param Instance The XHCI Instance. + @param XhcMmioBase XHCI MMIO base address. + +**/ +VOID +FixUsb3InstanceResource ( + IN OUT USB3_DEBUG_PORT_INSTANCE *Instance, + IN EFI_PHYSICAL_ADDRESS XhcMmioBase + ) +{ + if ((Instance =3D=3D NULL) || (Instance->XhcMmioBase =3D=3D XhcMmioBase)= ) { + return; + } + + // + // Need fix Instance data according to PCI resource + // + Instance->XhcMmioBase =3D XhcMmioBase; + Instance->DebugCapabilityBase =3D XhcMmioBase + Instance->DebugCapabilit= yOffset; + Instance->XhciOpRegister =3D XhcMmioBase + MmioRead8 ((UINTN)XhcMmi= oBase); +} + +/** + Save USB3 instance address. + + @param[in] Instance The XHCI Instance. + +**/ +VOID +SaveUsb3InstanceAddress ( + IN USB3_DEBUG_PORT_INSTANCE *Instance + ) +{ + UINT16 Command; + USB3_DEBUG_PORT_CONTROLLER UsbDebugPort; + UINT8 Bus; + UINT8 Device; + UINT8 Function; + + Command =3D GetXhciPciCommand (); + UsbDebugPort.Controller =3D GetUsb3DebugPortController(); + Bus =3D UsbDebugPort.PciAddress.Bus; + Device =3D UsbDebugPort.PciAddress.Device; + Function =3D UsbDebugPort.PciAddress.Function; + + // + // Set Command Register + // + if ((Command & EFI_PCI_COMMAND_MEMORY_SPACE) =3D=3D 0) { + PciWrite16(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAND_OFFSET),= Command | EFI_PCI_COMMAND_MEMORY_SPACE); + PciRead16(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAND_OFFSET)); + } + + // + // After debug device is finished to enumerate, use DCDDI2 register to s= tore instance address + // + XhcWriteDebugReg ( + Instance, + XHC_DC_DCDDI2, + (UINT32)(UINTN)Instance + ); + + // + // Restore Command Register + // + PciWrite16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET),= Command); +} + diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3De= bugPortLibDxe.c b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/U= sb3DebugPortLibDxe.c new file mode 100644 index 0000000000..8c3dd999db --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPort= LibDxe.c @@ -0,0 +1,454 @@ +/** @file + Usb3 Debug Port library instance + + Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Usb3DebugPortLibInternal.h" + +extern EFI_SMRAM_DESCRIPTOR mSmramCheckRanges[MAX_SMRAM_RANGE]; +extern UINTN mSmramCheckRangeCount; +extern BOOLEAN mUsb3InSmm; +extern UINT64 mUsb3MmioSize; +extern BOOLEAN mUsb3GetCapSuccess; + +GUID gUsb3DbgGuid =3D USB3_DBG_GUID; + +USB3_DEBUG_PORT_CONTROLLER mUsb3DebugPort; +USB3_DEBUG_PORT_INSTANCE *mUsb3Instance =3D NULL; + +/** + Return XHCI MMIO base address. + +**/ +EFI_PHYSICAL_ADDRESS +GetXhciBaseAddress ( + VOID + ) +{ + UINT8 Bus; + UINT8 Device; + UINT8 Function; + EFI_PHYSICAL_ADDRESS Address; + UINT32 Low; + UINT32 High; + + if (mUsb3DebugPort.Controller =3D=3D 0) { + mUsb3DebugPort.Controller =3D GetUsb3DebugPortController(); + } + + Bus =3D mUsb3DebugPort.PciAddress.Bus; + Device =3D mUsb3DebugPort.PciAddress.Device; + Function =3D mUsb3DebugPort.PciAddress.Function; + + Low =3D PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRE= SSREG_OFFSET)); + High =3D PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDR= ESSREG_OFFSET + 4)); + Address =3D (EFI_PHYSICAL_ADDRESS) (LShiftU64 ((UINT64) High, 32) | Low); + // + // Mask other parts which are not part of base address + // + Address &=3D XHCI_BASE_ADDRESS_64_BIT_MASK; + return Address; +} + +/** + Return XHCI debug instance address. + +**/ +USB3_DEBUG_PORT_INSTANCE * +GetUsb3DebugPortInstance ( + VOID + ) +{ + USB3_DEBUG_PORT_INSTANCE *Instance; + EFI_PHYSICAL_ADDRESS XhcMmioBase; + UINT64 CapabilityPointer; + UINT32 Capability; + BOOLEAN Flag; + UINT8 Bus; + UINT8 Device; + UINT8 Function; + UINT16 Command; + USB3_DEBUG_PORT_CONTROLLER UsbDebugPort; + + Instance =3D NULL; + + XhcMmioBase =3D GetXhciBaseAddress (); + + if ((XhcMmioBase =3D=3D 0) || (XhcMmioBase =3D=3D XHCI_BASE_ADDRESS_64_B= IT_MASK)) { + return NULL; + } + + if (mUsb3Instance !=3D NULL) { + FixUsb3InstanceResource (mUsb3Instance, XhcMmioBase); + return mUsb3Instance; + } + + Command =3D GetXhciPciCommand (); + + UsbDebugPort.Controller =3D GetUsb3DebugPortController(); + Bus =3D UsbDebugPort.PciAddress.Bus; + Device =3D UsbDebugPort.PciAddress.Device; + Function =3D UsbDebugPort.PciAddress.Function; + + // + // Set Command Register + // + if ((Command & EFI_PCI_COMMAND_MEMORY_SPACE) =3D=3D 0) { + PciWrite16(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAND_OFFSET),= Command | EFI_PCI_COMMAND_MEMORY_SPACE); + PciRead16(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAND_OFFSET)); + } + + // + // Calculate capability offset from HCCPARAMS [16:31], in 32-bit words + // + CapabilityPointer =3D XhcMmioBase + (MmioRead32 ((UINTN)(XhcMmioBase + X= HC_HCCPARAMS_OFFSET)) >> 16) * 4; + + // + // Search XHCI debug capability + // + Flag =3D FALSE; + Capability =3D MmioRead32 ((UINTN)CapabilityPointer); + while (TRUE) { + if ((Capability & XHC_CAPABILITY_ID_MASK) =3D=3D PCI_CAPABILITY_ID_DEB= UG_PORT) { + Flag =3D TRUE; + break; + } + if ((((Capability & XHC_NEXT_CAPABILITY_MASK) >> 8) & XHC_CAPABILITY_I= D_MASK) =3D=3D 0) { + // + // Reach the end of list, quit + // + break; + } + CapabilityPointer +=3D ((Capability & XHC_NEXT_CAPABILITY_MASK) >> 8) = * 4; + Capability =3D MmioRead32 ((UINTN)CapabilityPointer); + } + + if (Flag) { + Instance =3D (USB3_DEBUG_PORT_INSTANCE *)(UINTN) MmioRead32 ((UINTN) (= CapabilityPointer + XHC_DC_DCDDI2)); + + if (Instance !=3D NULL) { + FixUsb3InstanceResource (Instance, XhcMmioBase); + } + } + + // + // Restore Command Register + // + PciWrite16(PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), = Command); + + return Instance; +} + + +/** + Initialize USB3 debug port. + + This method invokes various internal functions to facilitate + detection and initialization of USB3 debug port. + + @retval RETURN_SUCCESS The USB3 debug port was initialized. +**/ +RETURN_STATUS +EFIAPI +USB3Initialize ( + VOID + ) +{ + // + // Leave it empty, we assume PEI phase already do initialization + // + return RETURN_SUCCESS; +} + +/** + Initialize USB3 debug port. + + This method invokes various internal functions to facilitate + detection and initialization of USB3 debug port. + + @retval RETURN_SUCCESS The serial device was initialized. +**/ +RETURN_STATUS +EFIAPI +USB3InitializeReal ( + VOID + ) +{ + USB3_DEBUG_PORT_INSTANCE UsbDbg; + USB3_DEBUG_PORT_INSTANCE *Instance; + EFI_PHYSICAL_ADDRESS Address; + EFI_STATUS Status; + + if ((gST =3D=3D NULL) || (gBS =3D=3D NULL)) { + // + // gST and gBS have not been initialized yet + // + return EFI_DEVICE_ERROR; + } + + Status =3D EfiGetSystemConfigurationTable (&gUsb3DbgGuid, (VOID **) &mUs= b3Instance); + if (!EFI_ERROR (Status)) { + return RETURN_SUCCESS; + } + + // + // It is first time to run DXE instance, copy Instance from Hob to ACPIN= vs + // NOTE: Hob is not ready at this time, so copy it from XHCI register. + // + Instance =3D GetUsb3DebugPortInstance (); + if (Instance =3D=3D NULL) { + // + // Initialize USB debug + // + SetMem (&UsbDbg, sizeof(UsbDbg), 0); + DiscoverUsb3DebugPort (&UsbDbg); + if (UsbDbg.DebugSupport) { + InitializeUsb3DebugPort (&UsbDbg); + } + Instance =3D &UsbDbg; + } + Address =3D SIZE_4GB; + Status =3D gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + EFI_SIZE_TO_PAGES (sizeof (USB3_DEBUG_PORT_INSTANCE)), + &Address + ); + if (EFI_ERROR (Status)) { + return Status; + } + + CopyMem ( + (VOID *)(UINTN)Address, + Instance, + sizeof (USB3_DEBUG_PORT_INSTANCE) + ); + mUsb3Instance =3D (USB3_DEBUG_PORT_INSTANCE *)(UINTN)Address; + + Status =3D gBS->InstallConfigurationTable (&gUsb3DbgGuid, mUsb3Instance); + if (EFI_ERROR (Status)) { + return Status; + } + + if (mUsb3Instance->DebugSupport) { + SaveUsb3InstanceAddress (mUsb3Instance); + } + + return RETURN_SUCCESS; +} + +/** + Calculate the size of XHCI MMIO space. + + @retval TURE The XHCI MMIO is in SMRAM ranges. + @retval FALSE The XHCI MMIO is out of SMRAM ranges. +**/ +UINT64 +CalculateMmioSize ( + VOID + ) +{ + UINT8 Bus; + UINT8 Device; + UINT8 Function; + UINT32 Value; + UINT32 Mask; + UINT64 MmioSize; + UINT16 Command; + USB3_DEBUG_PORT_CONTROLLER UsbDebugPort; + EFI_PHYSICAL_ADDRESS XhcMmioBase; + + UsbDebugPort.Controller =3D GetUsb3DebugPortController(); + Bus =3D UsbDebugPort.PciAddress.Bus; + Device =3D UsbDebugPort.PciAddress.Device; + Function =3D UsbDebugPort.PciAddress.Function; + + Mask =3D 0xFFFFFFF0; + MmioSize =3D 0; + + XhcMmioBase =3D GetXhciBaseAddress (); + + // + // Disable MSE + // + Command =3D PciRead16 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAN= D_OFFSET)); + PciWrite16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET),= Command & ~(EFI_PCI_COMMAND_MEMORY_SPACE)); + + // + // Get Mmio Size + // + PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_O= FFSET), 0xFFFFFFFF); + Value =3D PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_= ADDRESSREG_OFFSET)); + + switch (Value & 0x07) { + case 0x0: + // + // Memory space: anywhere in 32 bit address space + // + MmioSize =3D (~(Value & Mask)) + 1; + break; + case 0x4: + // + // Memory space: anywhere in 64 bit address space + // + MmioSize =3D Value & Mask; + PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSR= EG_OFFSET + 4), 0xFFFFFFFF); + Value =3D PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_B= ASE_ADDRESSREG_OFFSET + 4)); + // + // Fix the length to support some spefic 64 bit BAR + // + Value |=3D ((UINT32)(-1) << HighBitSet32 (Value)); + // + // Calculate the size of 64bit bar + // + MmioSize |=3D LShiftU64 ((UINT64) Value, 32); + MmioSize =3D (~(MmioSize)) + 1; + break; + default: + // + // Unknown BAR type + // + MmioSize =3D (~(Value & Mask)) + 1; + break; + }; + + + // + // Restore MMIO address + // + PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_O= FFSET), (UINT32)XhcMmioBase); + PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_O= FFSET + 4), (UINT32) (XhcMmioBase >> 32)); + + PciWrite16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET),= Command | EFI_PCI_COMMAND_MEMORY_SPACE); + + return MmioSize; +} + +/** + The constructor function initialize USB3 debug port. + + @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 +Usb3DebugPortLibDxeConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_SMM_BASE2_PROTOCOL *SmmBase; + EFI_SMM_ACCESS2_PROTOCOL *SmmAccess; + UINTN Size; + EFI_STATUS Status; + + // + // Do real initialization here, because we need copy data from Hob to AC= PINvs. + // We must do it in constructor because it depends on UefiBootServicesTa= bleLib. + // + if (FeaturePcdGet (PcdStatusCodeUseUsb3Serial)) { + USB3InitializeReal (); + } + + mUsb3MmioSize =3D CalculateMmioSize (); + + if (gBS !=3D NULL) { + SmmBase =3D NULL; + Status =3D gBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, (VOID= **)&SmmBase); + if (!EFI_ERROR (Status)) { + SmmBase->InSmm(SmmBase, &mUsb3InSmm); + } + + if (mUsb3InSmm) { + // + // Get SMRAM information + // + SmmAccess =3D NULL; + Status =3D gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (= VOID **)&SmmAccess); + if (!EFI_ERROR (Status)) { + Size =3D sizeof (mSmramCheckRanges); + + Status =3D SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramChe= ckRanges); + if (!EFI_ERROR (Status)) { + mSmramCheckRangeCount =3D Size / sizeof (EFI_SMRAM_DESCRIPTOR); + } + } + } + } + + return EFI_SUCCESS; +} + +/** + Allocate aligned memory for XHC's usage. + + @param BufferSize The size, in bytes, of the Buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID* +AllocateAlignBuffer ( + IN UINTN BufferSize + ) +{ + VOID *Buf; + EFI_PHYSICAL_ADDRESS Address; + EFI_STATUS Status; + + Buf =3D NULL; + + if (gBS !=3D NULL) { + Address =3D 0xFFFFFFFF; + Status =3D gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + EFI_SIZE_TO_PAGES (BufferSize), + &Address + ); + if (!EFI_ERROR (Status)) { + Buf =3D (VOID *)(UINTN)Address; + } + } + + return Buf; +} + +/** + Check whether AllocatePages in permanent memory is ready. + + @retval TRUE AllocatePages in permanent memory is ready. + @retval FALSE AllocatePages in permanent memory is not ready. + +**/ +BOOLEAN +IsAllocatePagesReady ( + VOID + ) +{ + if (gBS !=3D NULL) { + return TRUE; + } + + return FALSE; +} + diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3De= bugPortLibDxe.inf b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortLibDxe.inf new file mode 100644 index 0000000000..1d4b05779c --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPort= LibDxe.inf @@ -0,0 +1,55 @@ +## @file +# Usb3 debug port library. +# +# Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D Usb3DebugPortLibDxe + FILE_GUID =3D 08A575C4-D962-4ca5-8855-D3B4AE93A141 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D Usb3DebugPortLib|DXE_CORE DXE_DRIVER = DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIV= ER SMM_CORE + CONSTRUCTOR =3D Usb3DebugPortLibDxeConstructor + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 IPF +# + +[Sources] + Usb3DebugPortLibDxe.c + Usb3DebugPortDataTransfer.c + Usb3DebugPortInitialize.c + MiscServices.c + Usb3DebugPortLibInternal.h + +[Packages] + MdePkg/MdePkg.dec + DebugFeaturePkg/DebugFeaturePkg.dec + +[LibraryClasses] + BaseLib + PcdLib + IoLib + PciLib + TimerLib + UefiBootServicesTableLib + UefiLib + HobLib + Usb3DebugPortParameterLib + +[Protocols] + gEfiSmmAccess2ProtocolGuid ## CONSUMES + gEfiSmmBase2ProtocolGuid ## CONSUMES + +[Pcd] + gEfiUsb3DebugPortTokenSpaceGuid.PcdXhciDefaultBaseAddress ## SOMETIM= ES_CONSUMES + gEfiUsb3DebugPortTokenSpaceGuid.PcdXhciHostWaitTimeout ## CONSUMES + +[FeaturePcd] + gEfiUsb3DebugPortTokenSpaceGuid.PcdStatusCodeUseUsb3Serial ## CONSUMES diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3De= bugPortLibDxeIoMmu.c b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPort= Lib/Usb3DebugPortLibDxeIoMmu.c new file mode 100644 index 0000000000..97c3f88113 --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPort= LibDxeIoMmu.c @@ -0,0 +1,828 @@ +/** @file + Usb3 Debug Port library instance + + Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Usb3DebugPortLibInternal.h" + +extern EFI_SMRAM_DESCRIPTOR mSmramCheckRanges[MAX_SMRAM_RANGE]; +extern UINTN mSmramCheckRangeCount; +extern BOOLEAN mUsb3InSmm; +extern UINT64 mUsb3MmioSize; +extern BOOLEAN mUsb3GetCapSuccess; + +GUID gUsb3DbgGuid =3D USB3_DBG_GUID; + +USB3_DEBUG_PORT_CONTROLLER mUsb3DebugPort; +USB3_DEBUG_PORT_INSTANCE *mUsb3Instance =3D NULL; +EFI_PCI_IO_PROTOCOL *mUsb3PciIo =3D NULL; + +/** + Creates a named event that can be signaled. + + This function creates an event using NotifyTpl, NoifyFunction. + If Name is NULL, then ASSERT(). + If NotifyTpl is not a legal TPL value, then ASSERT(). + If NotifyFunction is NULL, then ASSERT(). + + @param Name Supplies the GUID name of the event. + @param NotifyTpl Supplies the task priority level of the ev= ent notifications. + @param NotifyFunction Supplies the function to notify when the e= vent is signaled. + @param Event A pointer to the event created. + + @retval EFI_SUCCESS A named event was created. + @retval EFI_OUT_OF_RESOURCES There are not enough resource to create th= e named event. + +**/ +EFI_STATUS +EFIAPI +Usb3NamedEventListen ( + IN CONST EFI_GUID *Name, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, + IN EFI_EVENT *Event + ) +{ + EFI_STATUS Status; + VOID *RegistrationLocal; + + ASSERT (Name !=3D NULL); + ASSERT (NotifyFunction !=3D NULL); + ASSERT (NotifyTpl <=3D TPL_HIGH_LEVEL); + + // + // Create event + // + Status =3D gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + NotifyTpl, + NotifyFunction, + NULL, + Event + ); + ASSERT_EFI_ERROR (Status); + + // + // Register for an installation of protocol interface + // + Status =3D gBS->RegisterProtocolNotify ( + (EFI_GUID *) Name, + *Event, + &RegistrationLocal + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + USB3 map one DMA buffer. + + @param PciIo Pointer to PciIo for USB3 debug port. + @param Address DMA buffer address to be mapped. + @param NumberOfBytes Number of bytes to be mapped. + +**/ +VOID +Usb3MapOneDmaBuffer ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN EFI_PHYSICAL_ADDRESS Address, + IN UINTN NumberOfBytes + ) +{ + EFI_STATUS Status; + VOID *HostAddress; + EFI_PHYSICAL_ADDRESS DeviceAddress; + VOID *Mapping; + + HostAddress =3D (VOID *) (UINTN) Address; + Status =3D PciIo->Map ( + PciIo, + EfiPciIoOperationBusMasterCommonBuffer, + HostAddress, + &NumberOfBytes, + &DeviceAddress, + &Mapping + ); + ASSERT_EFI_ERROR (Status); + ASSERT (DeviceAddress =3D=3D ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress= )); +} + +/** + USB3 map DMA buffers. + + @param Instance Pointer to USB3 debug port instance. + @param PciIo Pointer to PciIo for USB3 debug port. + +**/ +VOID +Usb3MapDmaBuffers ( + IN USB3_DEBUG_PORT_INSTANCE *Instance, + IN EFI_PCI_IO_PROTOCOL *PciIo + ) +{ + Usb3MapOneDmaBuffer ( + PciIo, + Instance->Urb.Data, + XHC_DEBUG_PORT_DATA_LENGTH + ); + + Usb3MapOneDmaBuffer ( + PciIo, + Instance->TransferRingIn.RingSeg0, + sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER + ); + + Usb3MapOneDmaBuffer ( + PciIo, + Instance->TransferRingOut.RingSeg0, + sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER + ); + + Usb3MapOneDmaBuffer ( + PciIo, + Instance->EventRing.EventRingSeg0, + sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER + ); + + Usb3MapOneDmaBuffer ( + PciIo, + Instance->EventRing.ERSTBase, + sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER + ); + + Usb3MapOneDmaBuffer ( + PciIo, + Instance->DebugCapabilityContext, + sizeof (XHC_DC_CONTEXT) + ); + + Usb3MapOneDmaBuffer ( + PciIo, + ((XHC_DC_CONTEXT *) (UINTN) Instance->DebugCapabilityContext)->DbcInfo= Context.String0DescAddress, + STRING0_DESC_LEN + MANU_DESC_LEN + PRODUCT_DESC_LEN + SERIAL_DESC_LEN + ); +} + +/** + Invoke a notification event + + @param[in] Event Event whose notification function is b= eing invoked. + @param[in] Context The pointer to the notification functi= on's context, + which is implementation-dependent. + +**/ +VOID +EFIAPI +Usb3DxeSmmReadyToLockNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + ASSERT (mUsb3Instance !=3D NULL); + + // + // For the case that the USB3 debug port instance and DMA buffers are + // from PEI HOB with IOMMU enabled. + // Reinitialize USB3 debug port with granted DXE DMA buffer accessible + // by SMM environment. + // + InitializeUsb3DebugPort (mUsb3Instance); + + SaveUsb3InstanceAddress (mUsb3Instance); + + gBS->CloseEvent (Event); +} + +/** + USB3 get IOMMU protocol. + + @return Pointer to IOMMU protocol. + +**/ +EDKII_IOMMU_PROTOCOL * +Usb3GetIoMmu ( + VOID + ) +{ + EFI_STATUS Status; + EDKII_IOMMU_PROTOCOL *IoMmu; + + IoMmu =3D NULL; + Status =3D gBS->LocateProtocol ( + &gEdkiiIoMmuProtocolGuid, + NULL, + (VOID **) &IoMmu + ); + if (!EFI_ERROR (Status) && (IoMmu !=3D NULL)) { + return IoMmu; + } + + return NULL; +} + +/** + Invoke a notification event + + @param[in] Event Event whose notification function is b= eing invoked. + @param[in] Context The pointer to the notification functi= on's context, + which is implementation-dependent. + +**/ +VOID +EFIAPI +Usb3PciIoNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + UINTN PciIoHandleCount; + EFI_HANDLE *PciIoHandleBuffer; + UINTN Index; + EFI_PCI_IO_PROTOCOL *PciIo; + UINTN PciSegment; + UINTN PciBusNumber; + UINTN PciDeviceNumber; + UINTN PciFunctionNumber; + EFI_EVENT SmmReadyToLockEvent; + + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiPciIoProtocolGuid, + NULL, + &PciIoHandleCount, + &PciIoHandleBuffer + ); + if (!EFI_ERROR (Status) && + (PciIoHandleBuffer !=3D NULL) && + (PciIoHandleCount !=3D 0)) { + for (Index =3D 0; Index < PciIoHandleCount; Index++) { + Status =3D gBS->HandleProtocol ( + PciIoHandleBuffer[Index], + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo + ); + ASSERT_EFI_ERROR (Status); + Status =3D PciIo->GetLocation (PciIo, &PciSegment, &PciBusNumber, &P= ciDeviceNumber, &PciFunctionNumber); + ASSERT_EFI_ERROR (Status); + if ((PciBusNumber =3D=3D mUsb3DebugPort.PciAddress.Bus) && + (PciDeviceNumber =3D=3D mUsb3DebugPort.PciAddress.Device) && + (PciFunctionNumber =3D=3D mUsb3DebugPort.PciAddress.Function)) { + // + // Found the PciIo for USB3 debug port. + // + ASSERT (mUsb3Instance !=3D NULL); + if (Usb3GetIoMmu () !=3D NULL) { + Usb3MapDmaBuffers (mUsb3Instance, PciIo); + + if (mUsb3Instance->FromHob) { + mUsb3PciIo =3D PciIo; + Usb3NamedEventListen ( + &gEfiDxeSmmReadyToLockProtocolGuid, + TPL_NOTIFY, + Usb3DxeSmmReadyToLockNotify, + &SmmReadyToLockEvent + ); + } + } + gBS->CloseEvent (Event); + break; + } + } + + gBS->FreePool (PciIoHandleBuffer); + } +} + +/** + Return XHCI MMIO base address. + +**/ +EFI_PHYSICAL_ADDRESS +GetXhciBaseAddress ( + VOID + ) +{ + UINT8 Bus; + UINT8 Device; + UINT8 Function; + EFI_PHYSICAL_ADDRESS Address; + UINT32 Low; + UINT32 High; + + if (mUsb3DebugPort.Controller =3D=3D 0) { + mUsb3DebugPort.Controller =3D GetUsb3DebugPortController(); + } + + Bus =3D mUsb3DebugPort.PciAddress.Bus; + Device =3D mUsb3DebugPort.PciAddress.Device; + Function =3D mUsb3DebugPort.PciAddress.Function; + + Low =3D PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRE= SSREG_OFFSET)); + High =3D PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDR= ESSREG_OFFSET + 4)); + Address =3D (EFI_PHYSICAL_ADDRESS) (LShiftU64 ((UINT64) High, 32) | Low); + // + // Mask other parts which are not part of base address + // + Address &=3D XHCI_BASE_ADDRESS_64_BIT_MASK; + return Address; +} + +/** + Return XHCI debug instance address. + +**/ +USB3_DEBUG_PORT_INSTANCE * +GetUsb3DebugPortInstance ( + VOID + ) +{ + USB3_DEBUG_PORT_INSTANCE *Instance; + EFI_PHYSICAL_ADDRESS XhcMmioBase; + UINT64 CapabilityPointer; + UINT32 Capability; + BOOLEAN Flag; + UINT8 Bus; + UINT8 Device; + UINT8 Function; + UINT16 Command; + USB3_DEBUG_PORT_CONTROLLER UsbDebugPort; + + Instance =3D NULL; + + XhcMmioBase =3D GetXhciBaseAddress (); + + if ((XhcMmioBase =3D=3D 0) || (XhcMmioBase =3D=3D XHCI_BASE_ADDRESS_64_B= IT_MASK)) { + return NULL; + } + + if (mUsb3Instance !=3D NULL) { + FixUsb3InstanceResource (mUsb3Instance, XhcMmioBase); + return mUsb3Instance; + } + + Command =3D GetXhciPciCommand (); + + UsbDebugPort.Controller =3D GetUsb3DebugPortController(); + Bus =3D UsbDebugPort.PciAddress.Bus; + Device =3D UsbDebugPort.PciAddress.Device; + Function =3D UsbDebugPort.PciAddress.Function; + + // + // Set Command Register + // + if ((Command & EFI_PCI_COMMAND_MEMORY_SPACE) =3D=3D 0) { + PciWrite16(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAND_OFFSET),= Command | EFI_PCI_COMMAND_MEMORY_SPACE); + PciRead16(PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAND_OFFSET)); + } + + // + // Calculate capability offset from HCCPARAMS [16:31], in 32-bit words + // + CapabilityPointer =3D XhcMmioBase + (MmioRead32 ((UINTN)(XhcMmioBase + X= HC_HCCPARAMS_OFFSET)) >> 16) * 4; + + // + // Search XHCI debug capability + // + Flag =3D FALSE; + Capability =3D MmioRead32 ((UINTN)CapabilityPointer); + while (TRUE) { + if ((Capability & XHC_CAPABILITY_ID_MASK) =3D=3D PCI_CAPABILITY_ID_DEB= UG_PORT) { + Flag =3D TRUE; + break; + } + if ((((Capability & XHC_NEXT_CAPABILITY_MASK) >> 8) & XHC_CAPABILITY_I= D_MASK) =3D=3D 0) { + // + // Reach the end of list, quit + // + break; + } + CapabilityPointer +=3D ((Capability & XHC_NEXT_CAPABILITY_MASK) >> 8) = * 4; + Capability =3D MmioRead32 ((UINTN)CapabilityPointer); + } + + if (Flag) { + Instance =3D (USB3_DEBUG_PORT_INSTANCE *)(UINTN) MmioRead32 ((UINTN) (= CapabilityPointer + XHC_DC_DCDDI2)); + + if (Instance !=3D NULL) { + FixUsb3InstanceResource (Instance, XhcMmioBase); + } + } + + // + // Restore Command Register + // + PciWrite16(PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), = Command); + + return Instance; +} + + +/** + Initialize USB3 debug port. + + This method invokes various internal functions to facilitate + detection and initialization of USB3 debug port. + + @retval RETURN_SUCCESS The USB3 debug port was initialized. +**/ +RETURN_STATUS +EFIAPI +USB3Initialize ( + VOID + ) +{ + // + // Leave it empty, we assume PEI phase already do initialization + // + return RETURN_SUCCESS; +} + +/** + Initialize USB3 debug port. + + This method invokes various internal functions to facilitate + detection and initialization of USB3 debug port. + + @retval RETURN_SUCCESS The serial device was initialized. +**/ +RETURN_STATUS +EFIAPI +USB3InitializeReal ( + VOID + ) +{ + USB3_DEBUG_PORT_INSTANCE UsbDbg; + USB3_DEBUG_PORT_INSTANCE *Instance; + EFI_PHYSICAL_ADDRESS Address; + EFI_STATUS Status; + EFI_EVENT Event; + + if ((gST =3D=3D NULL) || (gBS =3D=3D NULL)) { + // + // gST and gBS have not been initialized yet + // + return EFI_DEVICE_ERROR; + } + + Status =3D EfiGetSystemConfigurationTable (&gUsb3DbgGuid, (VOID **) &mUs= b3Instance); + if (!EFI_ERROR (Status)) { + goto Done; + } + + // + // It is first time to run DXE instance, copy Instance from Hob to ACPIN= vs + // NOTE: Hob is not ready at this time, so copy it from XHCI register. + // + Instance =3D GetUsb3DebugPortInstance (); + if (Instance =3D=3D NULL) { + // + // Initialize USB debug + // + SetMem (&UsbDbg, sizeof(UsbDbg), 0); + DiscoverUsb3DebugPort (&UsbDbg); + if (UsbDbg.DebugSupport) { + InitializeUsb3DebugPort (&UsbDbg); + } + Instance =3D &UsbDbg; + } + Address =3D SIZE_4GB; + Status =3D gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + EFI_SIZE_TO_PAGES (sizeof (USB3_DEBUG_PORT_INSTANCE)), + &Address + ); + if (EFI_ERROR (Status)) { + return Status; + } + + CopyMem ( + (VOID *)(UINTN)Address, + Instance, + sizeof (USB3_DEBUG_PORT_INSTANCE) + ); + mUsb3Instance =3D (USB3_DEBUG_PORT_INSTANCE *)(UINTN)Address; + + Status =3D gBS->InstallConfigurationTable (&gUsb3DbgGuid, mUsb3Instance); + if (EFI_ERROR (Status)) { + return Status; + } + + if (mUsb3Instance->DebugSupport) { + SaveUsb3InstanceAddress (mUsb3Instance); + } + +Done: + if ((mUsb3Instance !=3D NULL) && mUsb3Instance->Ready && (mUsb3Instance-= >PciIoEvent =3D=3D 0)) { + Status =3D Usb3NamedEventListen ( + &gEfiPciIoProtocolGuid, + TPL_NOTIFY, + Usb3PciIoNotify, + &Event + ); + if (!EFI_ERROR (Status)) { + mUsb3Instance->PciIoEvent =3D (EFI_PHYSICAL_ADDRESS) (UINTN) Event; + } + } + + return RETURN_SUCCESS; +} + +/** + Calculate the size of XHCI MMIO space. + + @retval TURE The XHCI MMIO is in SMRAM ranges. + @retval FALSE The XHCI MMIO is out of SMRAM ranges. +**/ +UINT64 +CalculateMmioSize ( + VOID + ) +{ + UINT8 Bus; + UINT8 Device; + UINT8 Function; + UINT32 Value; + UINT32 Mask; + UINT64 MmioSize; + UINT16 Command; + USB3_DEBUG_PORT_CONTROLLER UsbDebugPort; + EFI_PHYSICAL_ADDRESS XhcMmioBase; + + UsbDebugPort.Controller =3D GetUsb3DebugPortController(); + Bus =3D UsbDebugPort.PciAddress.Bus; + Device =3D UsbDebugPort.PciAddress.Device; + Function =3D UsbDebugPort.PciAddress.Function; + + Mask =3D 0xFFFFFFF0; + MmioSize =3D 0; + + XhcMmioBase =3D GetXhciBaseAddress (); + + // + // Disable MSE + // + Command =3D PciRead16 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAN= D_OFFSET)); + PciWrite16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET),= Command & ~(EFI_PCI_COMMAND_MEMORY_SPACE)); + + // + // Get Mmio Size + // + PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_O= FFSET), 0xFFFFFFFF); + Value =3D PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_= ADDRESSREG_OFFSET)); + + switch (Value & 0x07) { + case 0x0: + // + // Memory space: anywhere in 32 bit address space + // + MmioSize =3D (~(Value & Mask)) + 1; + break; + case 0x4: + // + // Memory space: anywhere in 64 bit address space + // + MmioSize =3D Value & Mask; + PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSR= EG_OFFSET + 4), 0xFFFFFFFF); + Value =3D PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_B= ASE_ADDRESSREG_OFFSET + 4)); + // + // Fix the length to support some spefic 64 bit BAR + // + Value |=3D ((UINT32)(-1) << HighBitSet32 (Value)); + // + // Calculate the size of 64bit bar + // + MmioSize |=3D LShiftU64 ((UINT64) Value, 32); + MmioSize =3D (~(MmioSize)) + 1; + break; + default: + // + // Unknown BAR type + // + MmioSize =3D (~(Value & Mask)) + 1; + break; + }; + + + // + // Restore MMIO address + // + PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_O= FFSET), (UINT32)XhcMmioBase); + PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_O= FFSET + 4), (UINT32) (XhcMmioBase >> 32)); + + PciWrite16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET),= Command | EFI_PCI_COMMAND_MEMORY_SPACE); + + return MmioSize; +} + +/** + The constructor function initialize USB3 debug port. + + @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 +Usb3DebugPortLibDxeConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_SMM_BASE2_PROTOCOL *SmmBase; + EFI_SMM_ACCESS2_PROTOCOL *SmmAccess; + UINTN Size; + EFI_STATUS Status; + + // + // Do real initialization here, because we need copy data from Hob to AC= PINvs. + // We must do it in constructor because it depends on UefiBootServicesTa= bleLib. + // + if (FeaturePcdGet (PcdStatusCodeUseUsb3Serial)) { + USB3InitializeReal (); + } + + mUsb3MmioSize =3D CalculateMmioSize (); + + if (gBS !=3D NULL) { + SmmBase =3D NULL; + Status =3D gBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, (VOID= **)&SmmBase); + if (!EFI_ERROR (Status)) { + SmmBase->InSmm(SmmBase, &mUsb3InSmm); + } + + if (mUsb3InSmm) { + // + // Get SMRAM information + // + SmmAccess =3D NULL; + Status =3D gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (= VOID **)&SmmAccess); + if (!EFI_ERROR (Status)) { + Size =3D sizeof (mSmramCheckRanges); + + Status =3D SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramChe= ckRanges); + if (!EFI_ERROR (Status)) { + mSmramCheckRangeCount =3D Size / sizeof (EFI_SMRAM_DESCRIPTOR); + } + } + } + } + + return EFI_SUCCESS; +} + +/** + The destructor function. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The destructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +Usb3DebugPortLibDxeDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + if ((mUsb3Instance !=3D NULL) && (mUsb3Instance->PciIoEvent !=3D 0)) { + // + // Close the event created. + // + gBS->CloseEvent ((EFI_EVENT) (UINTN) mUsb3Instance->PciIoEvent); + mUsb3Instance->PciIoEvent =3D 0; + } + return EFI_SUCCESS; +} + +/** + Allocates pages that are suitable for an OperationBusMasterCommonBuffer = or + OperationBusMasterCommonBuffer64 mapping. + + @param PciIo Pointer to PciIo for USB3 debug port. + @param Pages The number of pages to allocate. + @param Address A pointer to store the base system memory = address of the + allocated range. + + @retval EFI_SUCCESS The requested memory pages were allocated. + @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal = attribute bits are + MEMORY_WRITE_COMBINE and MEMORY_CACHED. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + +**/ +EFI_STATUS +Usb3AllocateDmaBuffer ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINTN Pages, + OUT VOID **Address + ) +{ + EFI_STATUS Status; + + *Address =3D NULL; + Status =3D PciIo->AllocateBuffer ( + PciIo, + AllocateAnyPages, + EfiRuntimeServicesData, + Pages, + Address, + 0 + ); + if (!EFI_ERROR (Status)) { + Usb3MapOneDmaBuffer ( + PciIo, + (EFI_PHYSICAL_ADDRESS) (UINTN) *Address, + EFI_PAGES_TO_SIZE (Pages) + ); + } + return Status; +} + +/** + Allocate aligned memory for XHC's usage. + + @param BufferSize The size, in bytes, of the Buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID* +AllocateAlignBuffer ( + IN UINTN BufferSize + ) +{ + VOID *Buf; + EFI_PHYSICAL_ADDRESS Address; + EFI_STATUS Status; + + Buf =3D NULL; + + if (gBS !=3D NULL) { + if (mUsb3PciIo !=3D NULL) { + Usb3AllocateDmaBuffer ( + mUsb3PciIo, + EFI_SIZE_TO_PAGES (BufferSize), + &Buf + ); + } else { + Address =3D 0xFFFFFFFF; + Status =3D gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + EFI_SIZE_TO_PAGES (BufferSize), + &Address + ); + if (!EFI_ERROR (Status)) { + Buf =3D (VOID *)(UINTN)Address; + } + } + } + + return Buf; +} + +/** + Check whether AllocatePages in permanent memory is ready. + + @retval TRUE AllocatePages in permanent memory is ready. + @retval FALSE AllocatePages in permanent memory is not ready. + +**/ +BOOLEAN +IsAllocatePagesReady ( + VOID + ) +{ + if (gBS !=3D NULL) { + return TRUE; + } + + return FALSE; +} + diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3De= bugPortLibDxeIoMmu.inf b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPo= rtLib/Usb3DebugPortLibDxeIoMmu.inf new file mode 100644 index 0000000000..7e84d26864 --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPort= LibDxeIoMmu.inf @@ -0,0 +1,63 @@ +## @file +# Usb3 debug port library. +# +# Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D Usb3DebugPortLibDxeIoMmu + FILE_GUID =3D BC48A65D-5E5E-4512-8ACC-90E79E2D80C2 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D Usb3DebugPortLib|DXE_CORE DXE_DRIVER = DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIV= ER SMM_CORE + CONSTRUCTOR =3D Usb3DebugPortLibDxeConstructor + DESTRUCTOR =3D Usb3DebugPortLibDxeDestructor + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 IPF +# + +[Sources] + Usb3DebugPortLibDxeIoMmu.c + Usb3DebugPortDataTransfer.c + Usb3DebugPortInitialize.c + MiscServices.c + Usb3DebugPortLibInternal.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + DebugFeaturePkg/DebugFeaturePkg.dec + +[LibraryClasses] + BaseLib + PcdLib + IoLib + PciLib + TimerLib + UefiBootServicesTableLib + UefiLib + HobLib + Usb3DebugPortParameterLib + +[Protocols] + gEfiSmmAccess2ProtocolGuid ## CONSUMES + gEfiSmmBase2ProtocolGuid ## CONSUMES + ## NOTIFY + ## SOMETIMES_CONSUMES + gEfiPciIoProtocolGuid + gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES + ## NOTIFY + gEfiDxeSmmReadyToLockProtocolGuid + +[Pcd] + gEfiUsb3DebugPortTokenSpaceGuid.PcdXhciDefaultBaseAddress ## SOMETIM= ES_CONSUMES + gEfiUsb3DebugPortTokenSpaceGuid.PcdXhciHostWaitTimeout ## CONSUMES + +[FeaturePcd] + gEfiUsb3DebugPortTokenSpaceGuid.PcdStatusCodeUseUsb3Serial ## CONSUMES diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3De= bugPortLibInternal.h b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPort= Lib/Usb3DebugPortLibInternal.h new file mode 100644 index 0000000000..3641cc1d52 --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPort= LibInternal.h @@ -0,0 +1,887 @@ +/** @file + This library class provides common Usb debug port functions. + + Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __USB3_DEBUG_PORT_LIB_INTERNAL__ +#define __USB3_DEBUG_PORT_LIB_INTERNAL__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// USB Debug GUID value +// +#define USB3_DBG_GUID \ + { \ + 0xb2a56f4d, 0x9177, 0x4fc8, { 0xa6, 0x77, 0xdd, 0x96, 0x3e, 0xb4, 0x= cb, 0x1b } \ + } + +// +// Define the maximum of SMRAM ranges +// +#define MAX_SMRAM_RANGE 8 + +#define XHCI_DEBUG_DEVICE_VENDOR_ID 0x8086 +#define XHCI_DEBUG_DEVICE_PRODUCT_ID 0x1234 +#define XHCI_DEBUG_DEVICE_PROTOCOL 0xFF +#define XHCI_DEBUG_DEVICE_REVISION 0x00 + +#define XHCI_BASE_ADDRESS_64_BIT_MASK 0xFFFFFFFFFFFF0000ULL +#define XHCI_BASE_ADDRESS_32_BIT_MASK 0xFFFF0000 + +#define PCI_CAPABILITY_ID_DEBUG_PORT 0x0A +#define XHC_HCCPARAMS_OFFSET 0x10 +#define XHC_CAPABILITY_ID_MASK 0xFF +#define XHC_NEXT_CAPABILITY_MASK 0xFF00 + +#define XHC_USBCMD_OFFSET 0x0 // USB Command Register Offset +#define XHC_USBSTS_OFFSET 0x4 // USB Status Register Offset + +#define XHC_USBCMD_RUN BIT0 // Run/Stop +#define XHC_USBCMD_RESET BIT1 // Host Controller Reset + +#define XHC_USBSTS_HALT BIT0 + +// +// Transfer the data of 8 bytes each time +// +#define XHC_DEBUG_PORT_DATA_LENGTH 8 + +// +// Indicate the timeout when data is transferred. 0 means infinite timeout. +// +#define DATA_TRANSFER_TIME_OUT 0 + +// +// USB debug device string descritpor (header size + unicode string length) +// +#define STRING0_DESC_LEN 4 +#define MANU_DESC_LEN 12 +#define PRODUCT_DESC_LEN 40 +#define SERIAL_DESC_LEN 4 + +// +// Debug Capability Register Offset +// +#define XHC_DC_DCID 0x0 +#define XHC_DC_DCDB 0x4 +#define XHC_DC_DCERSTSZ 0x8 +#define XHC_DC_DCERSTBA 0x10 +#define XHC_DC_DCERDP 0x18 +#define XHC_DC_DCCTRL 0x20 +#define XHC_DC_DCST 0x24 +#define XHC_DC_DCPORTSC 0x28 +#define XHC_DC_DCCP 0x30 +#define XHC_DC_DCDDI1 0x38 +#define XHC_DC_DCDDI2 0x3C + +#define TRB_TYPE_LINK 6 + +#define ERST_NUMBER 0x01 +#define TR_RING_TRB_NUMBER 0x100 +#define EVENT_RING_TRB_NUMBER 0x200 +#define CMD_RING_TRB_NUMBER 0x100 + +#define ED_BULK_OUT 2 +#define ED_BULK_IN 6 + +#define XHC_LOW_32BIT(Addr64) ((UINT32)(((UINTN)(Addr64)) & 0xFFF= FFFFF)) +#define XHC_HIGH_32BIT(Addr64) ((UINT32)(RShiftU64((UINT64)(UINTN)= (Addr64), 32) & 0xFFFFFFFF)) +#define XHC_BIT_IS_SET(Data, Bit) ((BOOLEAN)(((Data) & (Bit)) =3D=3D = (Bit))) + +#define XHC_REG_BIT_IS_SET(Xhc, Offset, Bit) \ + (XHC_BIT_IS_SET(XhcReadMmioReg ((Xhc), (Offset)), (Bit))) + +// +// Endpoint Type (EP Type). +// +#define ED_NOT_VALID 0 +#define ED_ISOCH_OUT 1 +#define ED_BULK_OUT 2 +#define ED_INTERRUPT_OUT 3 +#define ED_CONTROL_BIDIR 4 +#define ED_ISOCH_IN 5 +#define ED_BULK_IN 6 +#define ED_INTERRUPT_IN 7 + +// +// 6.4.5 TRB Completion Codes +// +#define TRB_COMPLETION_INVALID 0 +#define TRB_COMPLETION_SUCCESS 1 +#define TRB_COMPLETION_DATA_BUFFER_ERROR 2 +#define TRB_COMPLETION_BABBLE_ERROR 3 +#define TRB_COMPLETION_USB_TRANSACTION_ERROR 4 +#define TRB_COMPLETION_TRB_ERROR 5 +#define TRB_COMPLETION_STALL_ERROR 6 +#define TRB_COMPLETION_SHORT_PACKET 13 + +// +// 6.4.6 TRB Types +// +#define TRB_TYPE_NORMAL 1 +#define TRB_TYPE_SETUP_STAGE 2 +#define TRB_TYPE_DATA_STAGE 3 +#define TRB_TYPE_STATUS_STAGE 4 +#define TRB_TYPE_ISOCH 5 +#define TRB_TYPE_LINK 6 +#define TRB_TYPE_EVENT_DATA 7 +#define TRB_TYPE_NO_OP 8 +#define TRB_TYPE_EN_SLOT 9 +#define TRB_TYPE_DIS_SLOT 10 +#define TRB_TYPE_ADDRESS_DEV 11 +#define TRB_TYPE_CON_ENDPOINT 12 +#define TRB_TYPE_EVALU_CONTXT 13 +#define TRB_TYPE_RESET_ENDPOINT 14 +#define TRB_TYPE_STOP_ENDPOINT 15 +#define TRB_TYPE_SET_TR_DEQUE 16 +#define TRB_TYPE_RESET_DEV 17 +#define TRB_TYPE_GET_PORT_BANW 21 +#define TRB_TYPE_FORCE_HEADER 22 +#define TRB_TYPE_NO_OP_COMMAND 23 +#define TRB_TYPE_TRANS_EVENT 32 +#define TRB_TYPE_COMMAND_COMPLT_EVENT 33 +#define TRB_TYPE_PORT_STATUS_CHANGE_EVENT 34 +#define TRB_TYPE_HOST_CONTROLLER_EVENT 37 +#define TRB_TYPE_DEVICE_NOTIFI_EVENT 38 +#define TRB_TYPE_MFINDEX_WRAP_EVENT 39 + +// +// Convert millisecond to microsecond. +// +#define XHC_1_MILLISECOND (1000) +#define XHC_POLL_DELAY (1000) +#define XHC_GENERIC_TIMEOUT (10 * 1000) + +#define EFI_USB_SPEED_FULL 0x0000 ///< 12 Mb/s, USB 1.= 1 OHCI and UHCI HC. +#define EFI_USB_SPEED_LOW 0x0001 ///< 1 Mb/s, USB 1.1= OHCI and UHCI HC. +#define EFI_USB_SPEED_HIGH 0x0002 ///< 480 Mb/s, USB 2= .0 EHCI HC. +#define EFI_USB_SPEED_SUPER 0x0003 ///< 4.8 Gb/s, USB 3= .0 XHCI HC. + +// +// Transfer types, used in URB to identify the transfer type +// +#define XHC_CTRL_TRANSFER 0x01 +#define XHC_BULK_TRANSFER 0x02 +#define XHC_INT_TRANSFER_SYNC 0x04 +#define XHC_INT_TRANSFER_ASYNC 0x08 +#define XHC_INT_ONLY_TRANSFER_ASYNC 0x10 + +// +// USB Transfer Results +// +#define EFI_USB_NOERROR 0x00 +#define EFI_USB_ERR_NOTEXECUTE 0x01 +#define EFI_USB_ERR_STALL 0x02 +#define EFI_USB_ERR_BUFFER 0x04 +#define EFI_USB_ERR_BABBLE 0x08 +#define EFI_USB_ERR_NAK 0x10 +#define EFI_USB_ERR_CRC 0x20 +#define EFI_USB_ERR_TIMEOUT 0x40 +#define EFI_USB_ERR_BITSTUFF 0x80 +#define EFI_USB_ERR_SYSTEM 0x100 + +#define USB3_DEBUG_PORT_INSTANCE_SIGNATURE SIGNATURE_32('D', 'B', 'G', '= P') + +#pragma pack(1) + +// +// 7.6.9 OUT/IN EP Context: 64 bytes +// 7.6.9.2 When used by the DbC it is always a 64 byte data structure +// +typedef struct _ENDPOINT_CONTEXT_64 { + UINT32 EPState:3; + UINT32 RsvdZ1:5; + UINT32 Mult:2; // set to 0 + UINT32 MaxPStreams:5; // set to 0 + UINT32 LSA:1; // set to 0 + UINT32 Interval:8; // set to 0 + UINT32 RsvdZ2:8; + + UINT32 RsvdZ3:1; + UINT32 CErr:2; + UINT32 EPType:3; + UINT32 RsvdZ4:1; + UINT32 HID:1; // set to 0 + UINT32 MaxBurstSize:8; + UINT32 MaxPacketSize:16; + + UINT32 PtrLo; + + UINT32 PtrHi; + + UINT32 AverageTRBLength:16; + UINT32 MaxESITPayload:16; // set to 0 + + UINT32 RsvdZ5; // Reserved + UINT32 RsvdZ6; + UINT32 RsvdZ7; + + UINT32 RsvdZ8; + UINT32 RsvdZ9; + UINT32 RsvdZ10; + UINT32 RsvdZ11; + + UINT32 RsvdZ12; + UINT32 RsvdZ13; + UINT32 RsvdZ14; + UINT32 RsvdZ15; +} ENDPOINT_CONTEXT_64; + +// +// 6.4.1.1 Normal TRB: 16 bytes +// A Normal TRB is used in several ways; exclusively on Bulk and Interrupt= Transfer Rings for normal and +// Scatter/Gather operations, to define additional data buffers for Scatte= r/Gather operations on Isoch Transfer +// Rings, and to define the Data stage information for Control Transfer Ri= ngs. +// +typedef struct _TRANSFER_TRB_NORMAL { + UINT32 TRBPtrLo; + + UINT32 TRBPtrHi; + + UINT32 Length:17; + UINT32 TDSize:5; + UINT32 IntTarget:10; + + UINT32 CycleBit:1; + UINT32 ENT:1; + UINT32 ISP:1; + UINT32 NS:1; + UINT32 CH:1; + UINT32 IOC:1; + UINT32 IDT:1; + UINT32 RsvdZ1:2; + UINT32 BEI:1; + UINT32 Type:6; + UINT32 RsvdZ2:16; +} TRANSFER_TRB_NORMAL; + +// +// 6.4.2.1 Transfer Event TRB: 16 bytes +// A Transfer Event provides the completion status associated with a Trans= fer TRB. Refer to section 4.11.3.1 +// for more information on the use and operation of Transfer Events. +// +typedef struct _EVT_TRB_TRANSFER { + UINT32 TRBPtrLo; + + UINT32 TRBPtrHi; + + UINT32 Length:24; + UINT32 Completecode:8; + + UINT32 CycleBit:1; + UINT32 RsvdZ1:1; + UINT32 ED:1; + UINT32 RsvdZ2:7; + UINT32 Type:6; + UINT32 EndpointId:5; + UINT32 RsvdZ3:3; + UINT32 SlotId:8; +} EVT_TRB_TRANSFER; + +// +// 6.4.4.1 Link TRB: 16 bytes +// A Link TRB provides support for non-contiguous TRB Rings. +// +typedef struct _LINK_TRB { + UINT32 PtrLo; + + UINT32 PtrHi; + + UINT32 RsvdZ1:22; + UINT32 InterTarget:10; + + UINT32 CycleBit:1; + UINT32 TC:1; + UINT32 RsvdZ2:2; + UINT32 CH:1; + UINT32 IOC:1; + UINT32 RsvdZ3:4; + UINT32 Type:6; + UINT32 RsvdZ4:16; +} LINK_TRB; + +// +// TRB Template: 16 bytes +// +typedef struct _TRB_TEMPLATE { + UINT32 Parameter1; + + UINT32 Parameter2; + + UINT32 Status; + + UINT32 CycleBit:1; + UINT32 RsvdZ1:9; + UINT32 Type:6; + UINT32 Control:16; +} TRB_TEMPLATE; + +// +// Refer to XHCI 6.5 Event Ring Segment Table: 16 bytes +// +typedef struct _EVENT_RING_SEG_TABLE_ENTRY { + UINT32 PtrLo; + UINT32 PtrHi; + UINT32 RingTrbSize:16; + UINT32 RsvdZ1:16; + UINT32 RsvdZ2; +} EVENT_RING_SEG_TABLE_ENTRY; + +// +// Size: 40 bytes +// +typedef struct _EVENT_RING { + EFI_PHYSICAL_ADDRESS ERSTBase; + EFI_PHYSICAL_ADDRESS EventRingSeg0; + UINT32 TrbNumber; + EFI_PHYSICAL_ADDRESS EventRingEnqueue; + EFI_PHYSICAL_ADDRESS EventRingDequeue; + UINT32 EventRingCCS; +} EVENT_RING; + +// Size: 32 bytes +typedef struct _TRANSFER_RING { + EFI_PHYSICAL_ADDRESS RingSeg0; + UINT32 TrbNumber; + EFI_PHYSICAL_ADDRESS RingEnqueue; + EFI_PHYSICAL_ADDRESS RingDequeue; + UINT32 RingPCS; +} TRANSFER_RING; + +// +// Size: 64 bytes +// +typedef struct _DBC_INFO_CONTEXT { + UINT64 String0DescAddress; + UINT64 ManufacturerStrDescAddress; + UINT64 ProductStrDescAddress; + UINT64 SerialNumberStrDescAddress; + UINT64 String0Length:8; + UINT64 ManufacturerStrLength:8; + UINT64 ProductStrLength:8; + UINT64 SerialNumberStrLength:8; + UINT64 RsvdZ1:32; + UINT64 RsvdZ2; + UINT64 RsvdZ3; + UINT64 RsvdZ4; +} DBC_INFO_CONTEXT; + +// +// Debug Capability Context Data Structure: 192 bytes +// +typedef struct _XHC_DC_CONTEXT { + DBC_INFO_CONTEXT DbcInfoContext; + ENDPOINT_CONTEXT_64 EpOutContext; + ENDPOINT_CONTEXT_64 EpInContext; +} XHC_DC_CONTEXT; + +// +// Size: 16 bytes +// +typedef union _TRB { + TRB_TEMPLATE TrbTemplate; + TRANSFER_TRB_NORMAL TrbNormal; +} TRB; + +/// +/// USB data transfer direction +/// +typedef enum { + EfiUsbDataIn, + EfiUsbDataOut, + EfiUsbNoData +} EFI_USB_DATA_DIRECTION; + +// +// URB (Usb Request Block) contains information for all kinds of +// usb requests. +// +typedef struct _URB { + UINT32 Signature; + // + // Transfer data + // + EFI_PHYSICAL_ADDRESS Data; + UINT32 DataLen; + // + // Execute result + // + UINT32 Result; + // + // Completed data length + // + UINT32 Completed; + // + // Tranfer Ring info + // + EFI_PHYSICAL_ADDRESS Ring; + EFI_PHYSICAL_ADDRESS TrbStart; + EFI_PHYSICAL_ADDRESS TrbEnd; + UINT32 TrbNum; + BOOLEAN StartDone; + BOOLEAN EndDone; + BOOLEAN Finished; + EFI_USB_DATA_DIRECTION Direction; +} URB; + +// +// Size: 90 bytes +// +typedef struct _USB3_DEBUG_PORT_INSTANCE { + UINT32 Signature; + + UINT8 PciBusNumber; + UINT8 PciDeviceNumber; + UINT8 PciFunctionNumber; + + // + // The flag indicates debug capability is supported + // + BOOLEAN DebugSupport; + + // + // The flag indicates debug device is ready + // + BOOLEAN Ready; + + // + // The flag indicates the instance is from HOB + // + BOOLEAN FromHob; + + // + // PciIo protocol event + // + EFI_PHYSICAL_ADDRESS PciIoEvent; + + // + // XHCI MMIO Base address + // + EFI_PHYSICAL_ADDRESS XhcMmioBase; + + // + // XHCI OP RegisterBase address + // + EFI_PHYSICAL_ADDRESS XhciOpRegister; + + // + // XHCI Debug Register Base Address + // + EFI_PHYSICAL_ADDRESS DebugCapabilityBase; + + // + // XHCI Debug Capability offset + // + UINT64 DebugCapabilityOffset; + + // + // XHCI Debug Context Address + // + EFI_PHYSICAL_ADDRESS DebugCapabilityContext; + + // + // Transfer Ring + // + TRANSFER_RING TransferRingOut; + TRANSFER_RING TransferRingIn; + + // + // EventRing + // + EVENT_RING EventRing; + + // + // URB + // + URB Urb; +} USB3_DEBUG_PORT_INSTANCE; + +#pragma pack() + +/** + Clear one bit of the debug register while keeping other bits. + + @param Xhc The XHCI Instance. + @param Offset The offset of the debug register. + @param Bit The bit mask of the register to set. + +**/ +VOID +XhcClearDebugRegBit ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset, + IN UINT32 Bit + ); + +/** + Clear one bit of the MMIO register while keeping other bits. + + @param Xhc The XHCI Instance. + @param Offset The offset of the MMIO register. + @param Bit The bit mask of the register to set. + +**/ +VOID +XhcClearMmioRegBit ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset, + IN UINT32 Bit + ); + +/** + Read XHCI debug register. + + @param Xhc The XHCI Instance. + @param Offset The offset of the debug register. + + @return The register content read + +**/ +UINT32 +XhcReadDebugReg ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset + ); + +/** + Read XHCI MMIO register. + + @param Xhc The XHCI Instance. + @param Offset The offset of the MMIO register. + + @return The register content read + +**/ +UINT32 +XhcReadMmioReg ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset + ); + +/** + Set one bit of the debug register while keeping other bits. + + @param Xhc The XHCI Instance. + @param Offset The offset of the debug register. + @param Bit The bit mask of the register to set. + +**/ +VOID +XhcSetDebugRegBit ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset, + IN UINT32 Bit + ); + +/** + Set one bit of the MMIO register while keeping other bits. + + @param Xhc The XHCI Instance. + @param Offset The offset of the MMIO register. + @param Bit The bit mask of the register to set. + +**/ +VOID +XhcSetMmioRegBit ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset, + IN UINT32 Bit + ); + +/** + Wait the MMIO register's bit as specified by Bit + to be set (or clear). + + @param Xhc The XHCI Instance. + @param Offset The offset of the MMIO register. + @param Bit The bit of the register to wait for. + @param WaitToSet Wait the bit to set or clear. + @param Timeout The time to wait before abort (in millisecond, ms). + + @retval EFI_SUCCESS The bit successfully changed by host controller. + @retval EFI_TIMEOUT The time out occurred. + +**/ +EFI_STATUS +XhcWaitMmioRegBit ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset, + IN UINT32 Bit, + IN BOOLEAN WaitToSet, + IN UINT32 Timeout + ); + +/** + Write the data to the debug register. + + @param Xhc The XHCI Instance. + @param Offset The offset of the debug register. + @param Data The data to write. + +**/ +VOID +XhcWriteDebugReg ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset, + IN UINT32 Data + ); + +/** + Write the data to the MMIO register. + + @param Xhc The XHCI Instance. + @param Offset The offset of the MMIO register. + @param Data The data to write. + +**/ +VOID +XhcWriteMmioReg ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN UINT32 Offset, + IN UINT32 Data + ); + +/** + Discover the USB3 debug device. + + @param[in] Instance Pointer to USB3 debug port object instance. + + @retval RETURN_SUCCESS The USB3 debug device was found. + @retval RETURN_DEVICE_ERROR The USB3 debug device was not found. + +**/ +RETURN_STATUS +DiscoverUsb3DebugPort( + IN USB3_DEBUG_PORT_INSTANCE *Instance + ); + +/** + Initialize the USB3 debug Device hardware. + + @param[in] Instance Pointer to USB3 debug port object instance. + + @retval RETURN_SUCCESS The USB3 debug device was initialized successf= ully. + @retval !RETURN_SUCCESS Error. + +**/ +RETURN_STATUS +InitializeUsb3DebugPort ( + IN USB3_DEBUG_PORT_INSTANCE *Instance + ); + +/** + Return XHCI MMIO base address. + +**/ +EFI_PHYSICAL_ADDRESS +GetXhciBaseAddress ( + VOID + ); + +/** + Return XHCI debug instance address. + +**/ +USB3_DEBUG_PORT_INSTANCE * +GetUsb3DebugPortInstance ( + VOID + ); + +/** + Send data over the USB3 debug cable. + + @param[out] Data Pointer to data + @param[in, out] Length Pointer to data length + +**/ +VOID +Usb3DbgOut ( + OUT UINT8 *Data, + IN OUT UINTN *Length + ); + +/** + Receive data over the USB3 debug cable. + + @param[out] Data Pointer to data + @param[in, out] Length Pointer to data length + +**/ +RETURN_STATUS +Usb3DbgIn ( + OUT UINT8 *Data, + IN OUT UINTN *Length + ); + +/** + Verifies if the bit positions specified by a mask are set in a register. + + @param[in, out] Register UNITN register + @param[in] BitMask 32-bit mask + + @return BOOLEAN - TRUE if all bits specified by the mask are enabled. + - FALSE even if one of the bits specified by the mask + is not enabled. +**/ +BOOLEAN +XhcIsBitSet( + UINTN Register, + UINT32 BitMask + ); + +/** + Sets bits as per the enabled bit positions in the mask. + + @param[in, out] Register UINTN register + @param[in] BitMask 32-bit mask +**/ +VOID +XhcSetR32Bit( + UINTN Register, + UINT32 BitMask + ); + +/** + Clears bits as per the enabled bit positions in the mask. + + @param[in, out] Register UINTN register + @param[in] BitMask 32-bit mask +**/ +VOID +XhcClrR32Bit( + UINTN Register, + UINT32 BitMask + ); + +/** + Initialize USB3 debug port. + + This method invokes various internal functions to facilitate + detection and initialization of USB3 debug port. + + @retval RETURN_SUCCESS The serial device was initialized. +**/ +RETURN_STATUS +EFIAPI +USB3Initialize ( + VOID + ); + +/** + Return command register value in XHCI controller. + +**/ +UINT16 +GetXhciPciCommand ( + VOID + ); + +/** + Allocate aligned memory for XHC's usage. + + @param BufferSize The size, in bytes, of the Buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID* +AllocateAlignBuffer ( + IN UINTN BufferSize + ); + +/** + Check whether AllocatePages in permanent memory is ready. + + @retval TRUE AllocatePages in permanent memory is ready. + @retval FALSE AllocatePages in permanent memory is not ready. + +**/ +BOOLEAN +IsAllocatePagesReady ( + VOID + ); + +/** + The real function to initialize USB3 debug port. + + This method invokes various internal functions to facilitate + detection and initialization of USB3 debug port. + + @retval RETURN_SUCCESS The serial device was initialized. +**/ +RETURN_STATUS +EFIAPI +USB3InitializeReal ( + VOID + ); + +/** + Update XHC hardware address when MMIO base is changed. + + @param Instance The XHCI Instance. + @param XhcMmioBase XHCI MMIO base address. + +**/ +VOID +FixUsb3InstanceResource ( + IN OUT USB3_DEBUG_PORT_INSTANCE *Instance, + IN EFI_PHYSICAL_ADDRESS XhcMmioBase + ); + +/** + Save USB3 instance address. + + @param[in] Instance The XHCI Instance. + +**/ +VOID +SaveUsb3InstanceAddress ( + IN USB3_DEBUG_PORT_INSTANCE *Instance + ); + +/** + Submits bulk transfer to a bulk endpoint of a USB device. + + @param Xhc The instance of debug device. + @param Direction The direction of data transfer. + @param Data Array of pointers to the buffers of data t= o transmit + from or receive into. + @param DataLength The lenght of the data buffer. + @param Timeout Indicates the maximum time, in millisecond= , which + the transfer is allowed to complete. + @param TransferResult Transfer result. + + @retval EFI_SUCCESS The transfer was completed successfully. + @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resourc= e. + @retval EFI_INVALID_PARAMETER Some parameters are invalid. + @retval EFI_TIMEOUT The transfer failed due to timeout. + @retval EFI_DEVICE_ERROR The transfer failed due to host controller= error. + +**/ +EFI_STATUS +EFIAPI +XhcDataTransfer ( + IN USB3_DEBUG_PORT_INSTANCE *Xhc, + IN EFI_USB_DATA_DIRECTION Direction, + IN OUT VOID *Data, + IN OUT UINTN *DataLength, + IN UINTN Timeout, + OUT UINT32 *TransferResult + ); + +#endif //__SERIAL_PORT_LIB_USB__ diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3De= bugPortLibNull.c b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/= Usb3DebugPortLibNull.c new file mode 100644 index 0000000000..319cebecbb --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPort= LibNull.c @@ -0,0 +1,103 @@ +/** @file + Usb Debug Port library NULL instance + + Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +/** + Initialize the USB3 debug port hardware. + + If no initialization is required, then return RETURN_SUCCESS. + If the serial device was successfully initialized, then return RETURN_SU= CCESS. + If the serial device could not be initialized, then return RETURN_DEVICE= _ERROR. + + @retval RETURN_SUCCESS The serial device was initialized. + @retval RETURN_DEVICE_ERROR The serial device could not be initialized. + +**/ +RETURN_STATUS +EFIAPI +Usb3DebugPortInitialize ( + VOID + ) +{ + return RETURN_SUCCESS; +} + +/** + Write data from buffer to USB3 debug port. + + Writes NumberOfBytes data bytes from Buffer to the serial device. + The number of bytes actually written to the serial device is returned. + If the return value is less than NumberOfBytes, then the write operation= failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer Pointer to the data buffer to be written. + @param NumberOfBytes Number of bytes to written to the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes written to the serial devic= e. + If this value is less than NumberOfBytes, then = the read operation failed. + +**/ +UINTN +EFIAPI +Usb3DebugPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + return 0; +} + + +/** + Read data from USB3 debug port and save the datas in buffer. + + Reads NumberOfBytes data bytes from a serial device into the buffer + specified by Buffer. The number of bytes actually read is returned. + If the return value is less than NumberOfBytes, then the rest operation = failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer Pointer to the data buffer to store the data re= ad from the serial device. + @param NumberOfBytes Number of bytes which will be read. + + @retval 0 Read data failed, no data is to be read. + @retval >0 Actual number of bytes read from serial device. + +**/ +UINTN +EFIAPI +Usb3DebugPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + return 0; +} + +/** + Polls a USB3 debug port to see if there is any data waiting to be read. + + Polls a serial device to see if there is any data waiting to be read. + If there is data waiting to be read from the serial device, then TRUE is= returned. + If there is no data waiting to be read from the serial device, then FALS= E is returned. + + @retval TRUE Data is waiting to be read from the serial devi= ce. + @retval FALSE There is no data waiting to be read from the se= rial device. + +**/ +BOOLEAN +EFIAPI +Usb3DebugPortPoll ( + VOID + ) +{ + return FALSE; +} diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3De= bugPortLibNull.inf b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLi= b/Usb3DebugPortLibNull.inf new file mode 100644 index 0000000000..f632150c26 --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPort= LibNull.inf @@ -0,0 +1,28 @@ +## @file +# Usb3 debug port library. +# +# Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D USB3DebugPortLibNull + FILE_GUID =3D 3E895F08-0A69-42a2-AF4A-3E9EFAA40361 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D Usb3DebugPortLib + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 IPF +# + +[Sources] + Usb3DebugPortLibNull.c + +[Packages] + MdePkg/MdePkg.dec + diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3De= bugPortLibPei.c b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/U= sb3DebugPortLibPei.c new file mode 100644 index 0000000000..a1e0bdbf6d --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPort= LibPei.c @@ -0,0 +1,236 @@ +/** @file + Usb Debug Port library instance + + Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Usb3DebugPortLibInternal.h" + +GUID gUsb3DbgGuid =3D USB3_DBG_GUID; + +/** + Return XHCI MMIO base address. + +**/ +EFI_PHYSICAL_ADDRESS +GetXhciBaseAddress ( + VOID + ) +{ + UINT8 Bus; + UINT8 Device; + UINT8 Function; + USB3_DEBUG_PORT_CONTROLLER UsbDebugPort; + EFI_PHYSICAL_ADDRESS Address; + UINT32 Low; + UINT32 High; + + UsbDebugPort.Controller =3D GetUsb3DebugPortController(); + Bus =3D UsbDebugPort.PciAddress.Bus; + Device =3D UsbDebugPort.PciAddress.Device; + Function =3D UsbDebugPort.PciAddress.Function; + Low =3D PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRE= SSREG_OFFSET)); + High =3D PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDR= ESSREG_OFFSET + 4)); + Address =3D (EFI_PHYSICAL_ADDRESS) (LShiftU64 ((UINT64) High, 32) | Low); + + // + // Mask other parts which are not part of base address + // + Address &=3D XHCI_BASE_ADDRESS_64_BIT_MASK; + return Address; +} + +/** + Return XHCI debug instance address. + +**/ +USB3_DEBUG_PORT_INSTANCE * +GetUsb3DebugPortInstance ( + VOID + ) +{ + USB3_DEBUG_PORT_INSTANCE *Instance; + EFI_PEI_HOB_POINTERS Hob; + EFI_PHYSICAL_ADDRESS XhcMmioBase; + + Hob.Raw =3D GetFirstGuidHob (&gUsb3DbgGuid); + if (Hob.Raw =3D=3D NULL) { + return NULL; + } + Instance =3D GET_GUID_HOB_DATA (Hob.Guid); + + // + // Update XHCI MMIO base address + // + XhcMmioBase =3D GetXhciBaseAddress (); + + FixUsb3InstanceResource (Instance, XhcMmioBase); + + return Instance; +} + +/** + Initialize USB3 debug port. + + This method invokes various internal functions to facilitate + detection and initialization of USB3 debug port. + + @retval RETURN_SUCCESS The serial device was initialized. +**/ +RETURN_STATUS +EFIAPI +USB3Initialize ( + VOID + ) +{ + return EFI_SUCCESS; +} + +/** + Initialize USB3 debug port. + + This method invokes various internal functions to facilitate + detection and initialization of USB3 debug port. + + @retval RETURN_SUCCESS The serial device was initialized. +**/ +RETURN_STATUS +EFIAPI +USB3InitializeReal ( + VOID + ) +{ + USB3_DEBUG_PORT_INSTANCE UsbDbg; + VOID *DataPtr; + EFI_PEI_HOB_POINTERS Hob; + + // + // USB Initilization has to be done only once. So this function should j= ust return when + // it is called more than once. + // + Hob.Raw =3D GetFirstGuidHob (&gUsb3DbgGuid); + if (Hob.Raw !=3D NULL) { + return RETURN_SUCCESS; + } + + // + // Initialize USB debug for PEI at the first time + // + SetMem (&UsbDbg, sizeof(UsbDbg), 0); + UsbDbg.FromHob =3D TRUE; + DiscoverUsb3DebugPort (&UsbDbg); + if (UsbDbg.DebugSupport) { + InitializeUsb3DebugPort (&UsbDbg); + } + + // + // Save Instance into HOB + // + DataPtr =3D BuildGuidDataHob ( + &gUsb3DbgGuid, + (VOID*) &UsbDbg, + sizeof (UsbDbg) + ); + + if (UsbDbg.DebugSupport) { + SaveUsb3InstanceAddress ((USB3_DEBUG_PORT_INSTANCE *) DataPtr); + } + + return RETURN_SUCCESS; +} + +/** + Allocate aligned memory for XHC's usage. + + @param BufferSize The size, in bytes, of the Buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID* +AllocateAlignBuffer ( + IN UINTN BufferSize + ) +{ + VOID *Buf; + EFI_PHYSICAL_ADDRESS Address; + CONST EFI_PEI_SERVICES **PeiServices; + EFI_STATUS Status; + VOID *MemoryDiscoveredPpi; + + Buf =3D NULL; + PeiServices =3D GetPeiServicesTablePointer (); + + // + // Make sure the allocated memory is physical memory. + // + Status =3D (*PeiServices)->LocatePpi ( + PeiServices, + &gEfiPeiMemoryDiscoveredPpiGuid, + 0, + NULL, + (VOID **) &MemoryDiscoveredPpi + ); + if (!EFI_ERROR (Status)) { + Status =3D (*PeiServices)->AllocatePages ( + PeiServices, + EfiACPIMemoryNVS, + EFI_SIZE_TO_PAGES (BufferSize), + &Address + ); + if (!EFI_ERROR (Status)) { + Buf =3D (VOID *)(UINTN) Address; + } + } + return Buf; +} + +/** + Check whether AllocatePages in permanent memory is ready. + + @retval TRUE AllocatePages in permanent memory is ready. + @retval FALSE AllocatePages in permanent memory is not ready. + +**/ +BOOLEAN +IsAllocatePagesReady ( + VOID + ) +{ + CONST EFI_PEI_SERVICES **PeiServices; + EFI_STATUS Status; + VOID *MemoryDiscoveredPpi; + + PeiServices =3D GetPeiServicesTablePointer (); + + // + // Make sure the allocated memory is physical memory. + // + Status =3D (*PeiServices)->LocatePpi ( + PeiServices, + &gEfiPeiMemoryDiscoveredPpiGuid, + 0, + NULL, + (VOID **) &MemoryDiscoveredPpi + ); + if (!EFI_ERROR (Status)) { + return TRUE; + } + + return FALSE; +} + diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3De= bugPortLibPei.inf b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib= /Usb3DebugPortLibPei.inf new file mode 100644 index 0000000000..bc65c06f72 --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPort= LibPei.inf @@ -0,0 +1,48 @@ +## @file +# Usb3 debug port library. +# +# Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D USB3DebugPortLibPei + FILE_GUID =3D 62C974F0-D0E0-4963-B93A-22FBCEB69AB4 + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D Usb3DebugPortLib|PEIM PEI_CORE + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 IPF +# + +[Sources] + Usb3DebugPortLibPei.c + Usb3DebugPortDataTransfer.c + Usb3DebugPortInitialize.c + MiscServices.c + Usb3DebugPortLibInternal.h + +[Packages] + MdePkg/MdePkg.dec + DebugFeaturePkg/DebugFeaturePkg.dec + +[LibraryClasses] + BaseLib + PcdLib + IoLib + PciLib + TimerLib + HobLib + Usb3DebugPortParameterLib + PeiServicesTablePointerLib + +[Ppis] + gEfiPeiMemoryDiscoveredPpiGuid ## CONSUMES + +[Pcd] + gEfiUsb3DebugPortTokenSpaceGuid.PcdXhciDefaultBaseAddress ## SOM= ETIMES_CONSUMES + gEfiUsb3DebugPortTokenSpaceGuid.PcdXhciHostWaitTimeout ## CON= SUMES diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3De= bugPortLibPeiIoMmu.c b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPort= Lib/Usb3DebugPortLibPeiIoMmu.c new file mode 100644 index 0000000000..68543c8562 --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPort= LibPeiIoMmu.c @@ -0,0 +1,440 @@ +/** @file + Usb Debug Port library instance + + Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Usb3DebugPortLibInternal.h" + +GUID gUsb3DbgGuid =3D USB3_DBG_GUID; + +/** + USB3 IOMMU PPI notify. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification= event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this f= unction. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +Usb3IoMmuPpiNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ) +{ + USB3_DEBUG_PORT_INSTANCE *Instance; + + Instance =3D GetUsb3DebugPortInstance (); + ASSERT (Instance !=3D NULL); + // + // Reinitialize USB3 debug port with granted DMA buffer from IOMMU PPI. + // + InitializeUsb3DebugPort (Instance); + + SaveUsb3InstanceAddress (Instance); + + return EFI_SUCCESS; +} + +EFI_PEI_NOTIFY_DESCRIPTOR mUsb3IoMmuPpiNotifyDesc =3D { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINA= TE_LIST), + &gEdkiiIoMmuPpiGuid, + Usb3IoMmuPpiNotify +}; + +/** + Allocates pages that are suitable for an OperationBusMasterCommonBuffer = or + OperationBusMasterCommonBuffer64 mapping. + + @param IoMmu Pointer to IOMMU PPI. + @param Pages The number of pages to allocate. + @param HostAddress A pointer to store the base system memory = address of the + allocated range. + @param DeviceAddress The resulting map address for the bus mast= er PCI controller to use to + access the hosts HostAddress. + @param Mapping A resulting value to pass to Unmap(). + + @retval EFI_SUCCESS The requested memory pages were allocated. + @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal = attribute bits are + MEMORY_WRITE_COMBINE and MEMORY_CACHED. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + +**/ +EFI_STATUS +IoMmuAllocateBuffer ( + IN EDKII_IOMMU_PPI *IoMmu, + IN UINTN Pages, + OUT VOID **HostAddress, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ) +{ + EFI_STATUS Status; + UINTN NumberOfBytes; + + *HostAddress =3D NULL; + *DeviceAddress =3D 0; + *Mapping =3D NULL; + + Status =3D IoMmu->AllocateBuffer ( + IoMmu, + EfiRuntimeServicesData, + Pages, + HostAddress, + 0 + ); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + + NumberOfBytes =3D EFI_PAGES_TO_SIZE (Pages); + Status =3D IoMmu->Map ( + IoMmu, + EdkiiIoMmuOperationBusMasterCommonBuffer, + *HostAddress, + &NumberOfBytes, + DeviceAddress, + Mapping + ); + if (EFI_ERROR (Status)) { + IoMmu->FreeBuffer (IoMmu, Pages, *HostAddress); + *HostAddress =3D NULL; + return EFI_OUT_OF_RESOURCES; + } + Status =3D IoMmu->SetAttribute ( + IoMmu, + *Mapping, + EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE + ); + if (EFI_ERROR (Status)) { + IoMmu->Unmap (IoMmu, *Mapping); + IoMmu->FreeBuffer (IoMmu, Pages, *HostAddress); + *Mapping =3D NULL; + *HostAddress =3D NULL; + return Status; + } + + return Status; +} + +/** + USB3 get IOMMU PPI. + + @return Pointer to IOMMU PPI. + +**/ +EDKII_IOMMU_PPI * +Usb3GetIoMmu ( + VOID + ) +{ + EFI_STATUS Status; + EDKII_IOMMU_PPI *IoMmu; + CONST EFI_PEI_SERVICES **PeiServices; + + PeiServices =3D GetPeiServicesTablePointer (); + + IoMmu =3D NULL; + Status =3D (*PeiServices)->LocatePpi ( + PeiServices, + &gEdkiiIoMmuPpiGuid, + 0, + NULL, + (VOID **) &IoMmu + ); + if (!EFI_ERROR (Status) && (IoMmu !=3D NULL)) { + return IoMmu; + } + + return NULL; +} + +/** + Return XHCI MMIO base address. + +**/ +EFI_PHYSICAL_ADDRESS +GetXhciBaseAddress ( + VOID + ) +{ + UINT8 Bus; + UINT8 Device; + UINT8 Function; + USB3_DEBUG_PORT_CONTROLLER UsbDebugPort; + EFI_PHYSICAL_ADDRESS Address; + UINT32 Low; + UINT32 High; + + UsbDebugPort.Controller =3D GetUsb3DebugPortController(); + Bus =3D UsbDebugPort.PciAddress.Bus; + Device =3D UsbDebugPort.PciAddress.Device; + Function =3D UsbDebugPort.PciAddress.Function; + Low =3D PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRE= SSREG_OFFSET)); + High =3D PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDR= ESSREG_OFFSET + 4)); + Address =3D (EFI_PHYSICAL_ADDRESS) (LShiftU64 ((UINT64) High, 32) | Low); + + // + // Mask other parts which are not part of base address + // + Address &=3D XHCI_BASE_ADDRESS_64_BIT_MASK; + return Address; +} + +/** + Return XHCI debug instance address. + +**/ +USB3_DEBUG_PORT_INSTANCE * +GetUsb3DebugPortInstance ( + VOID + ) +{ + USB3_DEBUG_PORT_INSTANCE *Instance; + EFI_PEI_HOB_POINTERS Hob; + EFI_PHYSICAL_ADDRESS XhcMmioBase; + + Hob.Raw =3D GetFirstGuidHob (&gUsb3DbgGuid); + if (Hob.Raw =3D=3D NULL) { + return NULL; + } + Instance =3D GET_GUID_HOB_DATA (Hob.Guid); + + // + // Update XHCI MMIO base address + // + XhcMmioBase =3D GetXhciBaseAddress (); + + FixUsb3InstanceResource (Instance, XhcMmioBase); + + return Instance; +} + +/** + Initialize USB3 debug port. + + This method invokes various internal functions to facilitate + detection and initialization of USB3 debug port. + + @retval RETURN_SUCCESS The serial device was initialized. +**/ +RETURN_STATUS +EFIAPI +USB3Initialize ( + VOID + ) +{ + return EFI_SUCCESS; +} + +/** + Initialize USB3 debug port. + + This method invokes various internal functions to facilitate + detection and initialization of USB3 debug port. + + @retval RETURN_SUCCESS The serial device was initialized. +**/ +RETURN_STATUS +EFIAPI +USB3InitializeReal ( + VOID + ) +{ + EFI_STATUS Status; + USB3_DEBUG_PORT_INSTANCE UsbDbg; + VOID *DataPtr; + EFI_PEI_HOB_POINTERS Hob; + CONST EFI_PEI_SERVICES **PeiServices; + + PeiServices =3D GetPeiServicesTablePointer (); + + // + // USB Initilization has to be done only once. So this function should j= ust return when + // it is called more than once. + // + Hob.Raw =3D GetFirstGuidHob (&gUsb3DbgGuid); + if (Hob.Raw !=3D NULL) { + return RETURN_SUCCESS; + } + + // + // Initialize USB debug for PEI at the first time + // + SetMem (&UsbDbg, sizeof(UsbDbg), 0); + UsbDbg.FromHob =3D TRUE; + DiscoverUsb3DebugPort (&UsbDbg); + if (UsbDbg.DebugSupport) { + InitializeUsb3DebugPort (&UsbDbg); + } + + if (UsbDbg.Ready && (Usb3GetIoMmu () =3D=3D NULL)) { + Status =3D (*PeiServices)->NotifyPpi (PeiServices, &mUsb3IoMmuPpiNotif= yDesc); + ASSERT_EFI_ERROR (Status); + } + + // + // Save Instance into HOB + // + DataPtr =3D BuildGuidDataHob ( + &gUsb3DbgGuid, + (VOID*) &UsbDbg, + sizeof (UsbDbg) + ); + + if (UsbDbg.DebugSupport) { + SaveUsb3InstanceAddress ((USB3_DEBUG_PORT_INSTANCE *) DataPtr); + } + + return RETURN_SUCCESS; +} + +/** + Allocate aligned memory for XHC's usage. + + @param BufferSize The size, in bytes, of the Buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID* +AllocateAlignBuffer ( + IN UINTN BufferSize + ) +{ + VOID *Buf; + EFI_PHYSICAL_ADDRESS Address; + CONST EFI_PEI_SERVICES **PeiServices; + EFI_STATUS Status; + VOID *MemoryDiscoveredPpi; + EDKII_IOMMU_PPI *IoMmu; + VOID *HostAddress; + VOID *Mapping; + + Buf =3D NULL; + PeiServices =3D GetPeiServicesTablePointer (); + + // + // Make sure the allocated memory is physical memory. + // + Status =3D (*PeiServices)->LocatePpi ( + PeiServices, + &gEfiPeiMemoryDiscoveredPpiGuid, + 0, + NULL, + (VOID **) &MemoryDiscoveredPpi + ); + if (!EFI_ERROR (Status)) { + IoMmu =3D Usb3GetIoMmu (); + if (IoMmu !=3D NULL) { + Status =3D IoMmuAllocateBuffer ( + IoMmu, + EFI_SIZE_TO_PAGES (BufferSize), + &HostAddress, + &Address, + &Mapping + ); + if (!EFI_ERROR (Status)) { + ASSERT (Address =3D=3D ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress= )); + Buf =3D (VOID *)(UINTN) Address; + } + } else { + Status =3D (*PeiServices)->AllocatePages ( + PeiServices, + EfiACPIMemoryNVS, + EFI_SIZE_TO_PAGES (BufferSize), + &Address + ); + if (!EFI_ERROR (Status)) { + Buf =3D (VOID *)(UINTN) Address; + } + } + } + return Buf; +} + +/** + Check whether AllocatePages in permanent memory is ready. + + @retval TRUE AllocatePages in permanent memory is ready. + @retval FALSE AllocatePages in permanent memory is not ready. + +**/ +BOOLEAN +IsAllocatePagesReady ( + VOID + ) +{ + CONST EFI_PEI_SERVICES **PeiServices; + EFI_STATUS Status; + VOID *MemoryDiscoveredPpi; + EDKII_IOMMU_PPI *IoMmu; + VOID *HostAddress; + + PeiServices =3D GetPeiServicesTablePointer (); + + // + // Make sure the allocated memory is physical memory. + // + Status =3D (*PeiServices)->LocatePpi ( + PeiServices, + &gEfiPeiMemoryDiscoveredPpiGuid, + 0, + NULL, + (VOID **) &MemoryDiscoveredPpi + ); + if (!EFI_ERROR (Status)) { + Status =3D (*PeiServices)->LocatePpi ( + PeiServices, + &gEdkiiIoMmuPpiGuid, + 0, + NULL, + (VOID **) &IoMmu + ); + if (!EFI_ERROR (Status)) { + Status =3D IoMmu->AllocateBuffer ( + IoMmu, + EfiRuntimeServicesData, + 1, + &HostAddress, + 0 + ); + if (EFI_ERROR (Status)) { + // + // DMA protection has been enabled, + // but DMA buffer could not be allocated yet. + // + return FALSE; + } + IoMmu->FreeBuffer ( + IoMmu, + 1, + HostAddress + ); + } + return TRUE; + } + + return FALSE; +} + diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3De= bugPortLibPeiIoMmu.inf b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPo= rtLib/Usb3DebugPortLibPeiIoMmu.inf new file mode 100644 index 0000000000..c351aa0234 --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPort= LibPeiIoMmu.inf @@ -0,0 +1,51 @@ +## @file +# Usb3 debug port library. +# +# Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D USB3DebugPortLibPeiIoMmu + FILE_GUID =3D C973C5E8-A0D8-4FEE-A0F0-7DA6C3C72451 + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D Usb3DebugPortLib|PEIM PEI_CORE + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 IPF +# + +[Sources] + Usb3DebugPortLibPeiIoMmu.c + Usb3DebugPortDataTransfer.c + Usb3DebugPortInitialize.c + MiscServices.c + Usb3DebugPortLibInternal.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + DebugFeaturePkg/DebugFeaturePkg.dec + +[LibraryClasses] + BaseLib + PcdLib + IoLib + PciLib + TimerLib + HobLib + Usb3DebugPortParameterLib + PeiServicesTablePointerLib + +[Ppis] + gEfiPeiMemoryDiscoveredPpiGuid ## CONSUMES + gEdkiiIoMmuPpiGuid ## SOMETIMES_CONSUMES + +[Pcd] + gEfiUsb3DebugPortTokenSpaceGuid.PcdXhciDefaultBaseAddress ## SOM= ETIMES_CONSUMES + gEfiUsb3DebugPortTokenSpaceGuid.PcdXhciHostWaitTimeout ## CON= SUMES diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortParameterL= ibPcd/Usb3DebugPortParameterLibPcd.c b/Platform/Intel/DebugFeaturePkg/Libra= ry/Usb3DebugPortParameterLibPcd/Usb3DebugPortParameterLibPcd.c new file mode 100644 index 0000000000..747c5dccc9 --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortParameterLibPcd/U= sb3DebugPortParameterLibPcd.c @@ -0,0 +1,58 @@ +/** @file + USB3 debug Port Parameter library instance based on PCD. + + Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + +/** + 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 =3D 0; + UsbDebugPort.PciAddress.Bus =3D PcdGet8(PcdUsbSerialXhciBus); + UsbDebugPort.PciAddress.Device =3D PcdGet8(PcdUsbSerialXhciDev); + UsbDebugPort.PciAddress.Function =3D PcdGet8(PcdUsbSerialXhciFunc); + + return UsbDebugPort.Controller; +} + +/** + Sets the USB 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 se= t. + +**/ +BOOLEAN +EFIAPI +SetUsb3DebugPortController ( + UINT32 Controller + ) +{ + return FALSE; +} diff --git a/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortParameterL= ibPcd/Usb3DebugPortParameterLibPcd.inf b/Platform/Intel/DebugFeaturePkg/Lib= rary/Usb3DebugPortParameterLibPcd/Usb3DebugPortParameterLibPcd.inf new file mode 100644 index 0000000000..48fdd4800c --- /dev/null +++ b/Platform/Intel/DebugFeaturePkg/Library/Usb3DebugPortParameterLibPcd/U= sb3DebugPortParameterLibPcd.inf @@ -0,0 +1,31 @@ +## @file +# USB3 debug Port Parameter library instance based on PCD. +# +# Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D Usb3DebugPortParameterLibPcd + FILE_GUID =3D 4990A700-4002-4d08-8E00-622720032662 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D Usb3DebugPortParameterLib + +[Sources] + Usb3DebugPortParameterLibPcd.c + +[LibraryClasses] + BaseLib + DebugLib + +[Packages] + MdePkg/MdePkg.dec + DebugFeaturePkg/DebugFeaturePkg.dec + +[Pcd] + gEfiUsb3DebugPortTokenSpaceGuid.PcdUsbSerialXhciBus ## CONSUMES + gEfiUsb3DebugPortTokenSpaceGuid.PcdUsbSerialXhciDev ## CONSUMES + gEfiUsb3DebugPortTokenSpaceGuid.PcdUsbSerialXhciFunc ## CONSUMES --=20 2.21.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#41556): https://edk2.groups.io/g/devel/message/41556 Mute This Topic: https://groups.io/mt/31828871/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat May 4 09:59:59 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+41557+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+41557+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1559090880; cv=none; d=zoho.com; s=zohoarc; b=EmVz3rifZagERyYph9FQKwoCA0u0Wzg+nXSWdk5JaP1PjTkQwpdpFILh5yYmzFg9UigqV3X8R2TUePbwdrknvd9ZBmwRF2SH44ma/oBEMN3fcyILL95/gaRxavg0x01hNo/lBlkyyrDsAdUmUqpG7XqxwmnF3JW/hrGb16ovFVc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559090880; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=aufc/twDu2uuPPJ9sEEwrIUULsQCihqDhwkDGCb0SW4=; b=GIq4OVHlOiNSUkoRjHYuAJz5qWbCpAxUTI3AW0vYejGr1Rt1EvOIM/akHei9x2pISE2q6i8LPO/aAeTzaAmaL4d0DGtpL+JxPIr3747u/eobg6IAmnr4jjtcrqVhWbqBTiMn+ySMH7I+Vbi1utYYMW270OSATkGrbIXKULBpsTA= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+41557+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1559090880976917.7557224838156; Tue, 28 May 2019 17:48:00 -0700 (PDT) Return-Path: X-Received: from mga04.intel.com (mga04.intel.com []) by groups.io with SMTP; Tue, 28 May 2019 17:47:59 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 May 2019 17:47:59 -0700 X-ExtLoop1: 1 X-Received: from ydong10-win10.ccr.corp.intel.com ([10.239.158.133]) by fmsmga006.fm.intel.com with ESMTP; 28 May 2019 17:47:59 -0700 From: "Dong, Eric" To: devel@edk2.groups.io Cc: Liming Gao Subject: [edk2-devel] [Patch 3/3] [edk2-platforms] Platform/Intel/DebugFeaturePkg/AcpiDebug: Change AcpiDebug module location. Date: Wed, 29 May 2019 08:47:54 +0800 Message-Id: <20190529004754.22332-4-eric.dong@intel.com> In-Reply-To: <20190529004754.22332-1-eric.dong@intel.com> References: <20190529004754.22332-1-eric.dong@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,eric.dong@intel.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1559090880; bh=IercjBeonF0kpCaBdXYAzadogLVrquL0x2VyG7SyRns=; h=Cc:Date:From:Reply-To:Subject:To; b=fNs3JJ6ot0pbCDzie4p7TUFomWjtjIhCrnFF+w4QU8HxakJO9UiSs3LyMn/XKYRp6rX M6vDLqsiUOgKAjU4HRoVFAPSGCT1vzHe5cr5DRdMqQpcfh8L5jO5Ph9l1Ij1HYF/AMfSw lO/gk6TOUfTi9r7WkkElTCSw3PQNlwUGaoQ= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" Move AcpiDebug module from AdvancedFeaturePkg to DebugFeaturePkg. Signed-off-by: Eric Dong Cc: Liming Gao --- .../AdvancedFeaturePkg/AdvancedFeaturePkg.dec | 6 ------ .../AdvancedFeaturePkg/AdvancedFeaturePkg.dsc | 3 --- .../AcpiDebug/AcpiDebug.asl | 0 .../AcpiDebug/AcpiDebug.c | 0 .../AcpiDebug/AcpiDebugDxe.inf | 8 ++++---- .../AcpiDebug/AcpiDebugSmm.inf | 8 ++++---- .../AcpiDebug/Readme.txt | 0 .../Intel/DebugFeaturePkg/DebugFeaturePkg.dec | 15 +++++++++++++-- .../Intel/DebugFeaturePkg/DebugFeaturePkg.dsc | 12 ++++++++++++ 9 files changed, 33 insertions(+), 19 deletions(-) rename Platform/Intel/{AdvancedFeaturePkg =3D> DebugFeaturePkg}/AcpiDebug/= AcpiDebug.asl (100%) rename Platform/Intel/{AdvancedFeaturePkg =3D> DebugFeaturePkg}/AcpiDebug/= AcpiDebug.c (100%) rename Platform/Intel/{AdvancedFeaturePkg =3D> DebugFeaturePkg}/AcpiDebug/= AcpiDebugDxe.inf (79%) rename Platform/Intel/{AdvancedFeaturePkg =3D> DebugFeaturePkg}/AcpiDebug/= AcpiDebugSmm.inf (80%) rename Platform/Intel/{AdvancedFeaturePkg =3D> DebugFeaturePkg}/AcpiDebug/= Readme.txt (100%) diff --git a/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dec b/Pla= tform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dec index b18f81ba39..44e5de64db 100644 --- a/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dec +++ b/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dec @@ -140,17 +140,11 @@ gAdvancedFeaturePkgTokenSpaceGuid =3D {0xa85= 14688, 0x6693, 0x4ab5, {0xaa, =20 [PcdsFixedAtBuild] gAdvancedFeaturePkgTokenSpaceGuid.PcdMaxSOLChannels|0x3|UINT8|0x40000009 - ## This PCD specifies AcpiDebug feature is enable/disable. - gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugEnable|FALSE|BOOLEAN|0x000= 00012 - ## This PCD specifies AcpiDebug buffer size. - gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugBufferSize|0x10000|UINT32|= 0x00000013 =20 [PcdsDynamic, PcdsDynamicEx] gAdvancedFeaturePkgTokenSpaceGuid.PcdIpmiIoBaseAddress|0xCA2|UINT16|0x90= 000022 gAdvancedFeaturePkgTokenSpaceGuid.PcdFRB2EnabledFlag|TRUE|BOOLEAN|0x1000= 0030 gAdvancedFeaturePkgTokenSpaceGuid.PcdFRBTimeoutValue|360|UINT16|0x100000= 40 - ## This PCD specifies AcpiDebug buffer address - gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugAddress|0|UINT32|0x00000014 =20 [PcdsFeatureFlag] gAdvancedFeaturePkgTokenSpaceGuid.PcdNetworkEnable |FALSE|BOOLE= AN|0xF00000A1 diff --git a/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc b/Pla= tform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc index 909e566445..ea1a00725d 100644 --- a/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc +++ b/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc @@ -148,6 +148,3 @@ AdvancedFeaturePkg/Ipmi/IpmiFru/IpmiFru.inf AdvancedFeaturePkg/Ipmi/BmcElog/BmcElog.inf AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcAcpi.inf - - AdvancedFeaturePkg/AcpiDebug/AcpiDebugDxe.inf - AdvancedFeaturePkg/AcpiDebug/AcpiDebugSmm.inf \ No newline at end of file diff --git a/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebug.asl b/Pl= atform/Intel/DebugFeaturePkg/AcpiDebug/AcpiDebug.asl similarity index 100% rename from Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebug.asl rename to Platform/Intel/DebugFeaturePkg/AcpiDebug/AcpiDebug.asl diff --git a/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebug.c b/Plat= form/Intel/DebugFeaturePkg/AcpiDebug/AcpiDebug.c similarity index 100% rename from Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebug.c rename to Platform/Intel/DebugFeaturePkg/AcpiDebug/AcpiDebug.c diff --git a/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebugDxe.inf b= /Platform/Intel/DebugFeaturePkg/AcpiDebug/AcpiDebugDxe.inf similarity index 79% rename from Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebugDxe.inf rename to Platform/Intel/DebugFeaturePkg/AcpiDebug/AcpiDebugDxe.inf index fd701df3af..7473126b11 100644 --- a/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebugDxe.inf +++ b/Platform/Intel/DebugFeaturePkg/AcpiDebug/AcpiDebugDxe.inf @@ -32,12 +32,12 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec - AdvancedFeaturePkg/AdvancedFeaturePkg.dec + DebugFeaturePkg/DebugFeaturePkg.dec =20 [Pcd] - gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugEnable ## CONSUMES - gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugBufferSize ## CONSUMES - gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugAddress ## PRODUCES + gDebugFeaturePkgTokenSpaceGuid.PcdAcpiDebugEnable ## CONSUMES + gDebugFeaturePkgTokenSpaceGuid.PcdAcpiDebugBufferSize ## CONSUMES + gDebugFeaturePkgTokenSpaceGuid.PcdAcpiDebugAddress ## PRODUCES =20 [Sources] AcpiDebug.c diff --git a/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebugSmm.inf b= /Platform/Intel/DebugFeaturePkg/AcpiDebug/AcpiDebugSmm.inf similarity index 80% rename from Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebugSmm.inf rename to Platform/Intel/DebugFeaturePkg/AcpiDebug/AcpiDebugSmm.inf index 26122abc6c..679f9eb014 100644 --- a/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/AcpiDebugSmm.inf +++ b/Platform/Intel/DebugFeaturePkg/AcpiDebug/AcpiDebugSmm.inf @@ -33,12 +33,12 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec - AdvancedFeaturePkg/AdvancedFeaturePkg.dec + DebugFeaturePkg/DebugFeaturePkg.dec =20 [Pcd] - gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugEnable ## CONSUMES - gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugBufferSize ## CONSUMES - gAdvancedFeaturePkgTokenSpaceGuid.PcdAcpiDebugAddress ## PRODUCES + gDebugFeaturePkgTokenSpaceGuid.PcdAcpiDebugEnable ## CONSUMES + gDebugFeaturePkgTokenSpaceGuid.PcdAcpiDebugBufferSize ## CONSUMES + gDebugFeaturePkgTokenSpaceGuid.PcdAcpiDebugAddress ## PRODUCES =20 [Sources] AcpiDebug.c diff --git a/Platform/Intel/AdvancedFeaturePkg/AcpiDebug/Readme.txt b/Platf= orm/Intel/DebugFeaturePkg/AcpiDebug/Readme.txt similarity index 100% rename from Platform/Intel/AdvancedFeaturePkg/AcpiDebug/Readme.txt rename to Platform/Intel/DebugFeaturePkg/AcpiDebug/Readme.txt diff --git a/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dec b/Platform/= Intel/DebugFeaturePkg/DebugFeaturePkg.dec index 63a6ed03b7..5bcbc0ef6b 100644 --- a/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dec +++ b/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dec @@ -26,7 +26,8 @@ Usb3DebugPortParameterLib|Include/Library/Usb3DebugPortParameterLib.h =20 [Guids] - gEfiUsb3DebugPortTokenSpaceGuid =3D { 0x87e7378b, 0xc59d, 0x4a16, { 0xa4= , 0x21, 0x2c, 0xdb, 0x78, 0x26, 0xb1, 0xca } } + gEfiUsb3DebugPortTokenSpaceGuid =3D { 0x87e7378b, 0xc59d, 0x4a16, { = 0xa4, 0x21, 0x2c, 0xdb, 0x78, 0x26, 0xb1, 0xca } } + gDebugFeaturePkgTokenSpaceGuid =3D { 0xdbf3ac70, 0x3f73, 0x40aa, { = 0xbd, 0xd6, 0xac, 0xf2, 0x1a, 0x1b, 0x2f, 0xe2 } } =20 [PcdsFeatureFlag] ## This PCD specifies whether StatusCode is reported via USB3 Serial por= t. @@ -50,4 +51,14 @@ ## This PCD sepcifies the start index in CMOS, it will occupy 1 bytes sp= ace. gEfiUsb3DebugPortTokenSpaceGuid.PcdUsb3DebugPortDeviceIndex|0x5A|UINT8|0= x10000025 ## This PCD sepcifies the start index in CMOS, it will occupy 1 bytes sp= ace. - gEfiUsb3DebugPortTokenSpaceGuid.PcdUsb3DebugPortFunctionIndex|0x5B|UINT8= |0x10000026 \ No newline at end of file + gEfiUsb3DebugPortTokenSpaceGuid.PcdUsb3DebugPortFunctionIndex|0x5B|UINT8= |0x10000026 + + ## This PCD specifies AcpiDebug feature is enable/disable. + gDebugFeaturePkgTokenSpaceGuid.PcdAcpiDebugEnable|FALSE|BOOLEAN|0x000000= 12 + ## This PCD specifies AcpiDebug buffer size. + gDebugFeaturePkgTokenSpaceGuid.PcdAcpiDebugBufferSize|0x10000|UINT32|0x0= 0000013 + +[PcdsDynamic, PcdsDynamicEx] + ## This PCD specifies AcpiDebug buffer address + gDebugFeaturePkgTokenSpaceGuid.PcdAcpiDebugAddress|0|UINT32|0x00000014 + diff --git a/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dsc b/Platform/= Intel/DebugFeaturePkg/DebugFeaturePkg.dsc index aeca73a8c8..8b077167db 100644 --- a/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dsc +++ b/Platform/Intel/DebugFeaturePkg/DebugFeaturePkg.dsc @@ -23,6 +23,10 @@ SKUID_IDENTIFIER =3D DEFAULT =20 [LibraryClasses] + # + # Entry point + # + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntry= Point.inf BaseLib|MdePkg/Library/BaseLib/BaseLib.inf BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf @@ -32,6 +36,10 @@ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplat= e.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/U= efiRuntimeServicesTableLib.inf =20 [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf @@ -57,6 +65,7 @@ [LibraryClasses.common.DXE_SMM_DRIVER] HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAlloc= ationLib.inf + SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableL= ib.inf =20 ##########################################################################= ######################### # @@ -84,3 +93,6 @@ DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibDxeIoMmu.inf DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibPei.inf DebugFeaturePkg/Library/Usb3DebugPortLib/Usb3DebugPortLibDxe.inf + + DebugFeaturePkg/AcpiDebug/AcpiDebugDxe.inf + DebugFeaturePkg/AcpiDebug/AcpiDebugSmm.inf \ No newline at end of file --=20 2.21.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#41557): https://edk2.groups.io/g/devel/message/41557 Mute This Topic: https://groups.io/mt/31828872/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-