From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.88; helo=mga01.intel.com; envelope-from=ruiyu.ni@intel.com; receiver=edk2-devel@lists.01.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id A1A7222361E4A for ; Wed, 7 Feb 2018 23:21:29 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Feb 2018 23:27:13 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,477,1511856000"; d="scan'208";a="16887241" Received: from fmsmsx108.amr.corp.intel.com ([10.18.124.206]) by orsmga006.jf.intel.com with ESMTP; 07 Feb 2018 23:27:12 -0800 Received: from fmsmsx118.amr.corp.intel.com (10.18.116.18) by FMSMSX108.amr.corp.intel.com (10.18.124.206) with Microsoft SMTP Server (TLS) id 14.3.319.2; Wed, 7 Feb 2018 23:27:07 -0800 Received: from shsmsx102.ccr.corp.intel.com (10.239.4.154) by fmsmsx118.amr.corp.intel.com (10.18.116.18) with Microsoft SMTP Server (TLS) id 14.3.319.2; Wed, 7 Feb 2018 23:27:06 -0800 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.125]) by shsmsx102.ccr.corp.intel.com ([169.254.2.124]) with mapi id 14.03.0319.002; Thu, 8 Feb 2018 15:27:04 +0800 From: "Ni, Ruiyu" To: "Zeng, Star" , "edk2-devel@lists.01.org" CC: "Wu, Hao A" , "Yao, Jiewen" , "Zeng, Star" Thread-Topic: [edk2] [PATCH] SourceLevelDebugPkg DebugUsb3: Support IOMMU Thread-Index: AQHTn0VG/OIkr7MKi0C8wFKx685KZKOaHZ8Q Date: Thu, 8 Feb 2018 07:27:03 +0000 Deferred-Delivery: Thu, 8 Feb 2018 07:27:00 +0000 Message-ID: <734D49CCEBEEF84792F5B80ED585239D5BBA2200@SHSMSX104.ccr.corp.intel.com> References: <1517919786-16588-1-git-send-email-star.zeng@intel.com> In-Reply-To: <1517919786-16588-1-git-send-email-star.zeng@intel.com> Accept-Language: en-US, zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH] SourceLevelDebugPkg DebugUsb3: Support IOMMU X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 08 Feb 2018 07:21:30 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Ruiyu Ni Thanks/Ray > -----Original Message----- > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of > Star Zeng > Sent: Tuesday, February 6, 2018 8:23 PM > To: edk2-devel@lists.01.org > Cc: Ni, Ruiyu ; Wu, Hao A ; Yao, > Jiewen ; Zeng, Star > Subject: [edk2] [PATCH] SourceLevelDebugPkg DebugUsb3: Support IOMMU >=20 > For PEI, allocate granted DMA buffer from IOMMU PPI. > For DXE, map DMA buffer by PciIo. >=20 > Cc: Jiewen Yao > Cc: Ruiyu Ni > Cc: Hao Wu > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Star Zeng > --- > .../DebugCommunicationLibUsb3Common.c | 219 +++++------ > .../DebugCommunicationLibUsb3Dxe.c | 433 > ++++++++++++++++++++- > .../DebugCommunicationLibUsb3Dxe.inf | 12 +- > .../DebugCommunicationLibUsb3Internal.h | 60 ++- > .../DebugCommunicationLibUsb3Pei.c | 233 ++++++++++- > .../DebugCommunicationLibUsb3Pei.inf | 8 +- > 6 files changed, 838 insertions(+), 127 deletions(-) >=20 > diff --git > a/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Common.c > b/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Common.c > index 49bad6b5864d..80532e56acc5 100644 > --- > a/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Common.c > +++ > b/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > muni > +++ cationLibUsb3Common.c > @@ -14,11 +14,6 @@ >=20 > #include "DebugCommunicationLibUsb3Internal.h" >=20 > -// > -// The global variable which can be used after memory is ready. > -// > -USB3_DEBUG_PORT_HANDLE > mDebugCommunicationLibUsb3DebugPortHandle; > - > UINT16 mString0Desc[] =3D { > // String Descriptor Type + Length > ( USB_DESC_TYPE_STRING << 8 ) + STRING0_DESC_LEN, @@ -85,7 +80,7 > @@ XhcClearR32Bit( > Write the data to the XHCI debug register. >=20 > @param Handle Debug port handle. > - @param Offset The offset of the runtime register. > + @param Offset The offset of the debug register. > @param Data The data to write. >=20 > **/ > @@ -129,16 +124,16 @@ XhcReadDebugReg ( > } >=20 > /** > - Set one bit of the runtime register while keeping other bits. > + Set one bit of the debug register while keeping other bits. >=20 > @param Handle Debug port handle. > - @param Offset The offset of the runtime register. > + @param Offset The offset of the debug register. > @param Bit The bit mask of the register to set. >=20 > **/ > VOID > XhcSetDebugRegBit ( > - IN USB3_DEBUG_PORT_HANDLE *Handle, > + IN USB3_DEBUG_PORT_HANDLE *Handle, > IN UINT32 Offset, > IN UINT32 Bit > ) > @@ -151,6 +146,28 @@ XhcSetDebugRegBit ( } >=20 > /** > + Clear one bit of the debug register while keeping other bits. > + > + @param Handle Debug port handle. > + @param Offset The offset of the debug register. > + @param Bit The bit mask of the register to clear. > + > +**/ > +VOID > +XhcClearDebugRegBit ( > + IN USB3_DEBUG_PORT_HANDLE *Handle, > + IN UINT32 Offset, > + IN UINT32 Bit > + ) > +{ > + UINT32 Data; > + > + Data =3D XhcReadDebugReg (Handle, Offset); > + Data &=3D ~Bit; > + XhcWriteDebugReg (Handle, Offset, Data); } > + > +/** > Program and eanble XHCI MMIO base address. >=20 > @return XHCI MMIO base address. > @@ -199,7 +216,7 @@ UpdateXhcResource ( > IN EFI_PHYSICAL_ADDRESS XhciMmioBase > ) > { > - if ((Handle =3D=3D NULL) || (Handle->XhciMmioBase =3D=3D XhciMmioBase)= ) { > + if (Handle =3D=3D NULL) { > return; > } >=20 > @@ -216,7 +233,7 @@ UpdateXhcResource ( >=20 > @param Handle Debug port handle. >=20 > - @retval RETURN_UNSUPPORTED The usb host controller does not > supported usb debug port capability. > + @retval RETURN_UNSUPPORTED The usb host controller does not support > usb debug port capability. > @retval RETURN_SUCCESS Get bar and offset successfully. >=20 > **/ > @@ -236,6 +253,14 @@ CalculateUsbDebugPortMmioBase ( > EFI_PHYSICAL_ADDRESS CapabilityPointer; > UINT8 CapLength; >=20 > + if (Handle->Initialized !=3D USB3DBG_UNINITIALIZED) { > + if (Handle->Initialized =3D=3D USB3DBG_NO_DBG_CAB) { > + return RETURN_UNSUPPORTED; > + } else { > + return RETURN_SUCCESS; > + } > + } > + > VendorId =3D PciRead16 (PcdGet32(PcdUsbXhciPciAddress) + > PCI_VENDOR_ID_OFFSET); > DeviceId =3D PciRead16 (PcdGet32(PcdUsbXhciPciAddress) + > PCI_DEVICE_ID_OFFSET); >=20 > @@ -288,6 +313,7 @@ CalculateUsbDebugPortMmioBase ( > Handle->DebugCapabilityBase =3D CapabilityPointer; > Handle->DebugCapabilityOffset =3D CapabilityPointer - Handle- > >XhciMmioBase; > Handle->XhciOpRegister =3D Handle->XhciMmioBase + CapLength; > + Handle->DebugSupport =3D TRUE; > Handle->Initialized =3D USB3DBG_DBG_CAB; > return RETURN_SUCCESS; >=20 > @@ -326,6 +352,9 @@ NeedReinitializeHardware( > Dcctrl =3D XhcReadDebugReg (Handle, XHC_DC_DCCTRL); > if ((Dcctrl & BIT0) =3D=3D 0) { > Result =3D TRUE; > + } else if (!Handle->Ready) { > + Handle->Ready =3D TRUE; > + Handle->Initialized =3D USB3DBG_ENABLED; > } >=20 > return Result; > @@ -678,6 +707,13 @@ InitializeUsbDebugHardware ( > } >=20 > // > + // Clear DCE bit and LSE bit in DCCTRL // if ((XhcReadDebugReg > + (Handle, XHC_DC_DCCTRL) & (BIT1|BIT31)) =3D=3D (BIT1|BIT31)) { > + XhcClearDebugRegBit (Handle, XHC_DC_DCCTRL, BIT1|BIT31); } > + > + // > // Construct the buffer for read, poll and write. > // > Handle->UrbIn.Data =3D (EFI_PHYSICAL_ADDRESS)(UINTN) Buffer; @@ - > 746,6 +782,35 @@ Enable: > } >=20 > /** > + Discover and initialize usb debug port. > + > + @param Handle Debug port handle. > + > +**/ > +VOID > +DiscoverInitializeUsbDebugPort ( > + IN USB3_DEBUG_PORT_HANDLE *Handle > + ) > +{ > + EFI_STATUS Status; > + EFI_PHYSICAL_ADDRESS XhciMmioBase; > + > + // > + // Read 64-bit MMIO base address > + // > + XhciMmioBase =3D ProgramXhciBaseAddress (); Handle->XhciMmioBase =3D > + XhciMmioBase; > + > + Status =3D CalculateUsbDebugPortMmioBase (Handle); > + if (!RETURN_ERROR (Status)) { > + UpdateXhcResource (Handle, XhciMmioBase); > + if (NeedReinitializeHardware (Handle)) { > + InitializeUsbDebugHardware (Handle); > + } > + } > +} > + > +/** > Read data from debug device and save the data in buffer. >=20 > Reads NumberOfBytes data bytes from a debug device into the buffer @@ > -772,7 +837,6 @@ DebugPortReadBuffer ( > ) > { > USB3_DEBUG_PORT_HANDLE *UsbDebugPortHandle; > - RETURN_STATUS Status; > UINT8 Index; > UINT8 *Data; >=20 > @@ -780,25 +844,17 @@ DebugPortReadBuffer ( > return 0; > } >=20 > - // > - // If Handle is NULL, it means memory is ready for use. > - // Use global variable to store handle value. > - // > - if (Handle =3D=3D NULL) { > - UsbDebugPortHandle =3D > &mDebugCommunicationLibUsb3DebugPortHandle; > - } else { > - UsbDebugPortHandle =3D (USB3_DEBUG_PORT_HANDLE *)Handle; > + UsbDebugPortHandle =3D GetUsb3DebugPortInstance (); if > + (UsbDebugPortHandle =3D=3D NULL) { > + return 0; > } > - > - if (UsbDebugPortHandle->Initialized =3D=3D USB3DBG_NO_DBG_CAB) { > + > + if (UsbDebugPortHandle->Initialized !=3D USB3DBG_ENABLED) { > return 0; > } > - > - if (NeedReinitializeHardware(UsbDebugPortHandle)) { > - Status =3D InitializeUsbDebugHardware (UsbDebugPortHandle); > - if (RETURN_ERROR(Status)) { > - return 0; > - } > + > + if (UsbDebugPortHandle->InNotify) { > + return 0; > } >=20 > Data =3D (UINT8 *)(UINTN)UsbDebugPortHandle->Data; > @@ -851,7 +907,6 @@ DebugPortWriteBuffer ( > RETURN_STATUS Status; > UINTN Sent; > UINTN Total; > - EFI_PHYSICAL_ADDRESS XhciMmioBase; > UINTN Index; >=20 > if (NumberOfBytes =3D=3D 0 || Buffer =3D=3D NULL) { @@ -861,39 +916,24= @@ > DebugPortWriteBuffer ( > Sent =3D 0; > Total =3D 0; >=20 > - // > - // If Handle is NULL, it means memory is ready for use. > - // Use global variable to store handle value. > - // > - if (Handle =3D=3D NULL) { > - UsbDebugPortHandle =3D > &mDebugCommunicationLibUsb3DebugPortHandle; > - } else { > - UsbDebugPortHandle =3D (USB3_DEBUG_PORT_HANDLE *)Handle; > - } > - > - if (UsbDebugPortHandle->Initialized =3D=3D USB3DBG_NO_DBG_CAB) { > + UsbDebugPortHandle =3D GetUsb3DebugPortInstance (); if > + (UsbDebugPortHandle =3D=3D NULL) { > return 0; > } >=20 > - // > - // MMIO base address is possible to clear, set it if it is cleared. > (XhciMemorySpaceClose in PchUsbCommon.c) > - // > - XhciMmioBase =3D ProgramXhciBaseAddress (); > - > - UpdateXhcResource (UsbDebugPortHandle, XhciMmioBase); > + if (UsbDebugPortHandle->Initialized !=3D USB3DBG_ENABLED) { > + return 0; > + } >=20 > - if (NeedReinitializeHardware(UsbDebugPortHandle)) { > - Status =3D InitializeUsbDebugHardware (UsbDebugPortHandle); > - if (RETURN_ERROR(Status)) { > - return 0; > - } > + if (UsbDebugPortHandle->InNotify) { > + return 0; > } >=20 > // > // When host is trying to send data, write will be blocked. > // Poll to see if there is any data sent by host at first. > // > - DebugPortPollBuffer (Handle); > + DebugPortPollBuffer (UsbDebugPortHandle); >=20 > Index =3D 0; > while ((Total < NumberOfBytes)) { > @@ -930,33 +970,20 @@ DebugPortPollBuffer ( { > USB3_DEBUG_PORT_HANDLE *UsbDebugPortHandle; > UINTN Length; > - RETURN_STATUS Status; > - EFI_PHYSICAL_ADDRESS XhciMmioBase; >=20 > - // > - // If Handle is NULL, it means memory is ready for use. > - // Use global variable to store handle value. > - // > - if (Handle =3D=3D NULL) { > - UsbDebugPortHandle =3D > &mDebugCommunicationLibUsb3DebugPortHandle; > - } else { > - UsbDebugPortHandle =3D (USB3_DEBUG_PORT_HANDLE *)Handle; > + UsbDebugPortHandle =3D GetUsb3DebugPortInstance (); if > + (UsbDebugPortHandle =3D=3D NULL) { > + return FALSE; > } >=20 > - if (UsbDebugPortHandle->Initialized =3D=3D USB3DBG_NO_DBG_CAB) { > - return 0; > + if (UsbDebugPortHandle->Initialized !=3D USB3DBG_ENABLED) { > + return FALSE; > } >=20 > - XhciMmioBase =3D ProgramXhciBaseAddress (); > - UpdateXhcResource (UsbDebugPortHandle, XhciMmioBase); > - > - if (NeedReinitializeHardware(UsbDebugPortHandle)) { > - Status =3D InitializeUsbDebugHardware(UsbDebugPortHandle); > - if (RETURN_ERROR(Status)) { > - return FALSE; > - } > + if (UsbDebugPortHandle->InNotify) { > + return FALSE; > } > - > + > // > // If the data buffer is not empty, then return TRUE directly. > // Otherwise initialize a usb read transaction and read data to intern= al data > buffer. > @@ -969,7 +996,7 @@ DebugPortPollBuffer ( > // Read data as much as we can > // > Length =3D XHCI_DEBUG_DEVICE_MAX_PACKET_SIZE; > - XhcDataTransfer (Handle, EfiUsbDataIn, (VOID > *)(UINTN)UsbDebugPortHandle->Data, &Length, > DATA_TRANSFER_POLL_TIMEOUT); > + XhcDataTransfer (UsbDebugPortHandle, EfiUsbDataIn, (VOID > + *)(UINTN)UsbDebugPortHandle->Data, &Length, > + DATA_TRANSFER_POLL_TIMEOUT); >=20 > if (Length > XHCI_DEBUG_DEVICE_MAX_PACKET_SIZE) { > return FALSE; > @@ -1017,50 +1044,16 @@ DebugPortInitialize ( > IN DEBUG_PORT_CONTINUE Function > ) > { > - RETURN_STATUS Status; > - USB3_DEBUG_PORT_HANDLE Handle; > USB3_DEBUG_PORT_HANDLE *UsbDebugPortHandle; >=20 > - // > - // Validate the PCD PcdDebugPortHandleBufferSize value > - // > - ASSERT (PcdGet16 (PcdDebugPortHandleBufferSize) =3D=3D sizeof > (USB3_DEBUG_PORT_HANDLE)); > - > - if (Function =3D=3D NULL && Context !=3D NULL) { > - UsbDebugPortHandle =3D (USB3_DEBUG_PORT_HANDLE *)Context; > - } else { > - ZeroMem(&Handle, sizeof (USB3_DEBUG_PORT_HANDLE)); > - UsbDebugPortHandle =3D &Handle; > - } > - > - if (Function =3D=3D NULL && Context !=3D NULL) { > - return (DEBUG_PORT_HANDLE *) Context; > + UsbDebugPortHandle =3D GetUsb3DebugPortInstance (); if > + (UsbDebugPortHandle =3D=3D NULL) { > + return NULL; > } > - > - // > - // Read 64-bit MMIO base address > - // > - UsbDebugPortHandle->XhciMmioBase =3D ProgramXhciBaseAddress (); > - > - Status =3D CalculateUsbDebugPortMmioBase (UsbDebugPortHandle); > - if (RETURN_ERROR (Status)) { > - goto Exit; > - } > - > - if (NeedReinitializeHardware(&Handle)) { > - Status =3D InitializeUsbDebugHardware (&Handle); > - if (RETURN_ERROR(Status)) { > - goto Exit; > - } > - } > - > -Exit: >=20 > if (Function !=3D NULL) { > - Function (Context, &Handle); > - } else { > - CopyMem(&mDebugCommunicationLibUsb3DebugPortHandle, &Handle, > sizeof (USB3_DEBUG_PORT_HANDLE)); > + Function (Context, UsbDebugPortHandle); > } >=20 > - return > (DEBUG_PORT_HANDLE)(UINTN)&mDebugCommunicationLibUsb3DebugPo > rtHandle; > + return (DEBUG_PORT_HANDLE)(UINTN)UsbDebugPortHandle; > } > diff --git > a/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Dxe.c > b/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Dxe.c > index c4a8a4768299..c08cad8ca382 100644 > --- > a/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Dxe.c > +++ > b/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > muni > +++ cationLibUsb3Dxe.c > @@ -1,7 +1,7 @@ > /** @file > Debug Port Library implementation based on usb3 debug port. >=20 > - Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
> + Copyright (c) 2014 - 2018, Intel Corporation. All rights > + reserved.
> This program and the accompanying materials > are licensed and made available under the terms and conditions of the = BSD > License > which accompanies this distribution. The full text of the license may= be > found at @@ -15,8 +15,329 @@ #include #include > #include > +#include > +#include > +#include > #include "DebugCommunicationLibUsb3Internal.h" >=20 > +GUID gUsb3DbgGuid =3D USB3_DBG_GUID; > + > +USB3_DEBUG_PORT_HANDLE *mUsb3Instance =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 = event > notifications. > + @param NotifyFunction Supplies the function to notify when the > event 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 the 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 Instance Pointer to USB3 debug port instance. > + @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. > + @param BackupBuffer Backup buffer address. > + > +**/ > +VOID > +Usb3MapOneDmaBuffer ( > + IN USB3_DEBUG_PORT_HANDLE *Instance, > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN EFI_PHYSICAL_ADDRESS Address, > + IN UINTN NumberOfBytes, > + IN EFI_PHYSICAL_ADDRESS BackupBuffer > + ) > +{ > + 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)); > + if (Instance->FromHob) { > + // > + // Reallocate the DMA buffer by AllocateAddress with > + // the memory type accessible by SMM. > + // > + CopyMem ((VOID *) (UINTN) BackupBuffer, (VOID *) (UINTN) Address, > NumberOfBytes); > + Status =3D gBS->FreePages (Address, EFI_SIZE_TO_PAGES > (NumberOfBytes)); > + ASSERT_EFI_ERROR (Status); > + Status =3D gBS->AllocatePages ( > + AllocateAddress, > + EfiACPIMemoryNVS, > + EFI_SIZE_TO_PAGES (NumberOfBytes), > + &Address > + ); > + ASSERT_EFI_ERROR (Status); > + CopyMem ((VOID *) (UINTN) Address, (VOID *) (UINTN) BackupBuffer, > +NumberOfBytes); > + } > +} > + > +/** > + 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_HANDLE *Instance, > + IN EFI_PCI_IO_PROTOCOL *PciIo > + ) > +{ > + EFI_STATUS Status; > + EDKII_IOMMU_PROTOCOL *IoMmu; > + EFI_PHYSICAL_ADDRESS BackupBuffer; > + UINTN BackupBufferSize; > + > + IoMmu =3D NULL; > + Status =3D gBS->LocateProtocol (&gEdkiiIoMmuProtocolGuid, NULL, (VOID > + **) &IoMmu); if (EFI_ERROR (Status) || (IoMmu =3D=3D NULL)) { > + // > + // No need to map the DMA buffers. > + // > + return; > + } > + > + // > + // Allocate backup buffer for the case that the USB3 // debug port > + instance and DMA buffers are from PEI HOB. > + // For this case, the DMA buffers need to be reallocated // by > + AllocateAddress with the memory type accessible by // SMM. > + // > + BackupBufferSize =3D MAX (XHCI_DEBUG_DEVICE_MAX_PACKET_SIZE * 2 + > USB3_DEBUG_PORT_WRITE_MAX_PACKET_SIZE, > + MAX (sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBE= R, > + MAX (sizeof (TRB_TEMPLATE) * > EVENT_RING_TRB_NUMBER, > + MAX (sizeof (EVENT_RING_SEG_TABLE_EN= TRY) * > ERST_NUMBER, > + MAX (sizeof (XHC_DC_CONTEXT), > + STRING0_DESC_LEN + > + MANU_DESC_LEN + PRODUCT_DESC_LEN + SERIAL_DESC_LEN))))); > + > + Status =3D gBS->AllocatePages ( > + AllocateAnyPages, > + EfiBootServicesData, > + EFI_SIZE_TO_PAGES (BackupBufferSize), > + &BackupBuffer > + ); > + ASSERT_EFI_ERROR (Status); > + > + Usb3MapOneDmaBuffer ( > + Instance, > + PciIo, > + Instance->UrbIn.Data, > + XHCI_DEBUG_DEVICE_MAX_PACKET_SIZE * 2 + > USB3_DEBUG_PORT_WRITE_MAX_PACKET_SIZE, > + BackupBuffer > + ); > + > + Usb3MapOneDmaBuffer ( > + Instance, > + PciIo, > + Instance->TransferRingIn.RingSeg0, > + sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER, > + BackupBuffer > + ); > + > + Usb3MapOneDmaBuffer ( > + Instance, > + PciIo, > + Instance->TransferRingOut.RingSeg0, > + sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER, > + BackupBuffer > + ); > + > + Usb3MapOneDmaBuffer ( > + Instance, > + PciIo, > + Instance->EventRing.EventRingSeg0, > + sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER, > + BackupBuffer > + ); > + > + Usb3MapOneDmaBuffer ( > + Instance, > + PciIo, > + Instance->EventRing.ERSTBase, > + sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER, > + BackupBuffer > + ); > + > + Usb3MapOneDmaBuffer ( > + Instance, > + PciIo, > + Instance->DebugCapabilityContext, > + sizeof (XHC_DC_CONTEXT), > + BackupBuffer > + ); > + > + Usb3MapOneDmaBuffer ( > + Instance, > + PciIo, > + ((XHC_DC_CONTEXT *) (UINTN) Instance->DebugCapabilityContext)- > >DbcInfoContext.String0DescAddress, > + STRING0_DESC_LEN + MANU_DESC_LEN + PRODUCT_DESC_LEN + > SERIAL_DESC_LEN, > + BackupBuffer > + ); > + > + gBS->FreePages (BackupBuffer, EFI_SIZE_TO_PAGES (BackupBufferSize)); > +} > + > +/** > + Invoke a notification event > + > + @param[in] Event Event whose notification function is= being > invoked. > + @param[in] Context The pointer to the notification func= tion'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; > + UINT32 PciAddress; > + > + 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, > &PciDeviceNumber, &PciFunctionNumber); > + ASSERT_EFI_ERROR (Status); > + PciAddress =3D (UINT32) ((PciBusNumber << 20) | (PciDeviceNumber <= < 15) > | (PciFunctionNumber << 12)); > + if (PciAddress =3D=3D PcdGet32(PcdUsbXhciPciAddress)) { > + // > + // Found the PciIo for USB3 debug port. > + // > + DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__)); > + mUsb3Instance->InNotify =3D TRUE; > + Usb3MapDmaBuffers (mUsb3Instance, PciIo); > + mUsb3Instance->InNotify =3D FALSE; > + gBS->CloseEvent ((EFI_EVENT) (UINTN) mUsb3Instance->PciIoEvent); > + break; > + } > + } > + > + gBS->FreePool (PciIoHandleBuffer); > + } > +} > + > +/** > + Return USB3 debug instance address. > + > +**/ > +USB3_DEBUG_PORT_HANDLE * > +GetUsb3DebugPortInstance ( > + VOID > + ) > +{ > + USB3_DEBUG_PORT_HANDLE *Instance; > + EFI_PEI_HOB_POINTERS Hob; > + > + Instance =3D NULL; > + > + if (mUsb3Instance !=3D NULL) { > + Instance =3D mUsb3Instance; > + goto Done; > + } > + > + Hob.Raw =3D GetFirstGuidHob (&gUsb3DbgGuid); if (Hob.Raw !=3D NULL) { > + Instance =3D GET_GUID_HOB_DATA (Hob.Guid); } > + > +Done: > + if (Instance !=3D NULL) { > + DiscoverInitializeUsbDebugPort (Instance); > + } > + return Instance; > +} > + > /** > Allocate aligned memory for XHC's usage. >=20 > @@ -51,3 +372,113 @@ AllocateAlignBuffer ( >=20 > return Buf; > } > + > +/** > + 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 > +DebugCommunicationUsb3DxeConstructor ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + USB3_DEBUG_PORT_HANDLE UsbDbg; > + USB3_DEBUG_PORT_HANDLE *Instance; > + EFI_PHYSICAL_ADDRESS Address; > + EFI_STATUS Status; > + EFI_EVENT Event; > + > + Instance =3D GetUsb3DebugPortInstance (); > + > + Status =3D EfiGetSystemConfigurationTable (&gUsb3DbgGuid, (VOID **) > + &mUsb3Instance); if (!EFI_ERROR (Status)) { > + goto Done; > + } > + > + if (Instance =3D=3D NULL) { > + // > + // Initialize USB debug > + // > + ZeroMem (&UsbDbg, sizeof (UsbDbg)); > + UsbDbg.Initialized =3D USB3DBG_UNINITIALIZED; > + > + DiscoverInitializeUsbDebugPort (&UsbDbg); > + > + Instance =3D &UsbDbg; > + } > + > + // > + // It is first time to run DXE instance, copy Instance from Hob to ACP= INvs. > + // > + Address =3D SIZE_4GB; > + Status =3D gBS->AllocatePages ( > + AllocateMaxAddress, > + EfiACPIMemoryNVS, > + EFI_SIZE_TO_PAGES (sizeof (USB3_DEBUG_PORT_HANDLE)), > + &Address > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + CopyMem ( > + (VOID *)(UINTN)Address, > + Instance, > + sizeof (USB3_DEBUG_PORT_HANDLE) > + ); > + mUsb3Instance =3D (USB3_DEBUG_PORT_HANDLE *)(UINTN)Address; > + > + Status =3D gBS->InstallConfigurationTable (&gUsb3DbgGuid, > + mUsb3Instance); if (EFI_ERROR (Status)) { > + return Status; > + } > + > +Done: > + if (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 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 > +DebugCommunicationUsb3DxeDestructor ( > + 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; > +} > + > diff --git > a/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Dxe.inf > b/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Dxe.inf > index 08b9ec12d298..c4e4282c98b4 100644 > --- > a/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Dxe.inf > +++ > b/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > muni > +++ cationLibUsb3Dxe.inf > @@ -1,7 +1,7 @@ > ## @file > # Debug Communication Library instance based on usb3 debug port. > # > -# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved. > +# Copyright (c) 2014 - 2018, Intel Corporation. All rights > +reserved.
> # > # This program and the accompanying materials # are licensed and made > available under the terms and conditions of the BSD License @@ -21,6 +21,= 8 > @@ [Defines] > MODULE_TYPE =3D DXE_DRIVER > VERSION_STRING =3D 1.0 > LIBRARY_CLASS =3D DebugCommunicationLib|DXE_CORE > DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER > UEFI_APPLICATION UEFI_DRIVER SMM_CORE > + CONSTRUCTOR =3D DebugCommunicationUsb3DxeConstructo= r > + DESTRUCTOR =3D DebugCommunicationUsb3DxeDestructor >=20 > # > # The following information is for reference only and not required by th= e > build tools. > @@ -54,7 +56,11 @@ [Pcd] >=20 > # The value of data buffer size used for USB debug port handle. > # It should be equal to sizeof (USB3_DEBUG_PORT_HANDLE). > - > gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize| > 239 ## SOMETIMES_CONSUMES > + > gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize| > 250 ## SOMETIMES_CONSUMES > + > +[Protocols] > + gEfiPciIoProtocolGuid ## CONSUMES > + gEdkiiIoMmuProtocolGuid ## CONSUMES >=20 > [LibraryClasses] > BaseLib > @@ -65,4 +71,4 @@ [LibraryClasses] > UefiBootServicesTableLib > UefiLib > BaseMemoryLib > - > \ No newline at end of file > + HobLib > diff --git > a/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Internal.h > b/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Internal.h > index 356485c5f697..66757dafaebe 100644 > --- > a/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Internal.h > +++ > b/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > muni > +++ cationLibUsb3Internal.h > @@ -1,7 +1,7 @@ > /** @file > Debug Port Library implementation based on usb3 debug port. >=20 > - Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
> + Copyright (c) 2014 - 2018, Intel Corporation. All rights > + reserved.
> This program and the accompanying materials > are licensed and made available under the terms and conditions of the = BSD > License > which accompanies this distribution. The full text of the license may= be > found at @@ -46,6 +46,7 @@ > #define USB3DBG_DBG_CAB 1 // The XHCI host controller supports > debug capability > #define USB3DBG_ENABLED 2 // The XHCI debug device is enabled > #define USB3DBG_NOT_ENABLED 4 // The XHCI debug device is not > enabled > +#define USB3DBG_UNINITIALIZED 255 // The XHCI debug device is > +uninitialized >=20 > #define USB3_DEBUG_PORT_WRITE_MAX_PACKET_SIZE 0x08 >=20 > @@ -456,7 +457,7 @@ typedef struct _USB3_DEBUG_PORT_INSTANCE { > UINT8 Initialized; >=20 > // > - // The flag indicates debug device is ready > + // The flag indicates debug capability is supported > // > BOOLEAN DebugSupport; >=20 > @@ -466,6 +467,26 @@ typedef struct _USB3_DEBUG_PORT_INSTANCE { > BOOLEAN Ready; >=20 > // > + // The flag indicates the instance is from HOB // > + BOOLEAN FromHob; > + > + // > + // IOMMU PPI Notify registered > + // > + BOOLEAN PpiNotifyRegistered; > + > + // > + // Prevent notification being interrupted by debug timer // > + BOOLEAN InNotify; > + > + // > + // PciIo protocol event > + // > + EFI_PHYSICAL_ADDRESS PciIoEvent; > + > + // > // The flag indicates if USB 3.0 ports has been turn off/on power > // > BOOLEAN ChangePortPower; > @@ -728,4 +749,39 @@ XhcDataTransfer ( > IN UINTN Timeout > ); >=20 > +/** > + Initialize usb debug port hardware. > + > + @param Handle Debug port handle. > + > + @retval TRUE The usb debug port hardware configuration is = changed. > + @retval FALSE The usb debug port hardware configuration is = not > changed. > + > +**/ > +RETURN_STATUS > +EFIAPI > +InitializeUsbDebugHardware ( > + IN USB3_DEBUG_PORT_HANDLE *Handle > + ); > + > +/** > + Discover and initialize usb debug port. > + > + @param Handle Debug port handle. > + > +**/ > +VOID > +DiscoverInitializeUsbDebugPort ( > + IN USB3_DEBUG_PORT_HANDLE *Handle > + ); > + > +/** > + Return USB3 debug instance address. > + > +**/ > +USB3_DEBUG_PORT_HANDLE * > +GetUsb3DebugPortInstance ( > + VOID > + ); > + > #endif //__SERIAL_PORT_LIB_USB__ > diff --git > a/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Pei.c > b/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Pei.c > index 902a3b626acc..8cb42a4ce367 100644 > --- > a/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Pei.c > +++ > b/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > muni > +++ cationLibUsb3Pei.c > @@ -1,7 +1,7 @@ > /** @file > Debug Port Library implementation based on usb3 debug port. >=20 > - Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.
> + Copyright (c) 2014 - 2018, Intel Corporation. All rights > + reserved.
> This program and the accompanying materials > are licensed and made available under the terms and conditions of the = BSD > License > which accompanies this distribution. The full text of the license may= be > found at @@ -14,13 +14,214 @@ >=20 > #include > #include > +#include > #include > +#include > #include "DebugCommunicationLibUsb3Internal.h" >=20 > +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 Notificati= on > event that > + caused this function to execute. > + @param[in] Ppi Pointer to the PPI data associated with this= function. > + > + @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_HANDLE *Instance; > + > + DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__)); > + > + Instance =3D GetUsb3DebugPortInstance (); > + > + Instance->InNotify =3D TRUE; > + > + // > + // Reinitialize USB3 debug port with granted DMA buffer from IOMMU PPI= . > + // > + InitializeUsbDebugHardware (Instance); > + > + // > + // Wait some time for host to be ready after re-initialization. > + // > + MicroSecondDelay (1000000); > + > + Instance->InNotify =3D FALSE; > + > + return EFI_SUCCESS; > +} > + > +EFI_PEI_NOTIFY_DESCRIPTOR mUsb3IoMmuPpiNotifyDesc =3D { > + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | > +EFI_PEI_PPI_DESCRIPTOR_TERMINATE_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 memor= y > address of the > + allocated range. > + @param DeviceAddress The resulting map address for the bus ma= ster > 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 allocate= d. > + @retval EFI_UNSUPPORTED Attributes is unsupported. The only lega= l > 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, > + EfiBootServicesData, > + 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; > + > + IoMmu =3D NULL; > + Status =3D PeiServicesLocatePpi ( > + &gEdkiiIoMmuPpiGuid, > + 0, > + NULL, > + (VOID **) &IoMmu > + ); > + if (!EFI_ERROR (Status) && (IoMmu !=3D NULL)) { > + return IoMmu; > + } > + > + return NULL; > +} > + > +/** > + Return USB3 debug instance address. > + > +**/ > +USB3_DEBUG_PORT_HANDLE * > +GetUsb3DebugPortInstance ( > + VOID > + ) > +{ > + USB3_DEBUG_PORT_HANDLE *Instance; > + EFI_PEI_HOB_POINTERS Hob; > + EFI_STATUS Status; > + > + Hob.Raw =3D GetFirstGuidHob (&gUsb3DbgGuid); if (Hob.Raw =3D=3D NULL)= { > + // > + // Save Instance into HOB > + // > + Instance =3D BuildGuidHob ( > + &gUsb3DbgGuid, > + sizeof (USB3_DEBUG_PORT_HANDLE) > + ); > + ASSERT (Instance !=3D NULL); > + ZeroMem (Instance, sizeof (USB3_DEBUG_PORT_HANDLE)); > + > + Instance->FromHob =3D TRUE; > + Instance->Initialized =3D USB3DBG_UNINITIALIZED; } else { > + Instance =3D GET_GUID_HOB_DATA (Hob.Guid); } > + > + if (!Instance->InNotify) { > + DiscoverInitializeUsbDebugPort (Instance); } > + > + if (Instance->Ready && > + !Instance->PpiNotifyRegistered && > + (Usb3GetIoMmu () =3D=3D NULL)) { > + Status =3D PeiServicesNotifyPpi (&mUsb3IoMmuPpiNotifyDesc); > + ASSERT_EFI_ERROR (Status); > + Instance->PpiNotifyRegistered =3D TRUE; } > + > + return Instance; > +} > + > /** > Allocate aligned memory for XHC's usage. >=20 > - @param BufferSize The size, in bytes, of the Buffer. > + @param BufferSize The size, in bytes, of the Buffer. >=20 > @return A pointer to the allocated buffer or NULL if allocation fails. >=20 > @@ -34,6 +235,9 @@ AllocateAlignBuffer ( > EFI_PHYSICAL_ADDRESS Address; > EFI_STATUS Status; > VOID *MemoryDiscoveredPpi; > + EDKII_IOMMU_PPI *IoMmu; > + VOID *HostAddress; > + VOID *Mapping; >=20 > Buf =3D NULL; >=20 > @@ -47,9 +251,28 @@ AllocateAlignBuffer ( > (VOID **) &MemoryDiscoveredPpi > ); > if (!EFI_ERROR (Status)) { > - Status =3D PeiServicesAllocatePages (EfiACPIMemoryNVS, > EFI_SIZE_TO_PAGES (BufferSize), &Address); > - if (!EFI_ERROR (Status)) { > - Buf =3D (VOID *)(UINTN) Address; > + 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) HostAddre= ss)); > + Buf =3D (VOID *)(UINTN) Address; > + } > + } else { > + Status =3D PeiServicesAllocatePages ( > + EfiACPIMemoryNVS, > + EFI_SIZE_TO_PAGES (BufferSize), > + &Address > + ); > + if (!EFI_ERROR (Status)) { > + Buf =3D (VOID *)(UINTN) Address; > + } > } > } > return Buf; > diff --git > a/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Pei.inf > b/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Pei.inf > index 2108face50d2..33074db49a78 100644 > --- > a/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > municationLibUsb3Pei.inf > +++ > b/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCom > muni > +++ cationLibUsb3Pei.inf > @@ -1,7 +1,7 @@ > ## @file > # Debug Communication Library instance based on usb3 debug port. > # > -# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved. > +# Copyright (c) 2014 - 2018, Intel Corporation. All rights > +reserved.
> # > # This program and the accompanying materials # are licensed and made > available under the terms and conditions of the BSD License @@ -41,6 +41,= 7 > @@ [Packages] >=20 > [Ppis] > gEfiPeiMemoryDiscoveredPpiGuid ## CONSUMES > + gEdkiiIoMmuPpiGuid ## CONSUMES >=20 > [Pcd] > # The memory BAR of ehci host controller, in which usb debug feature i= s > enabled. > @@ -57,7 +58,7 @@ [Pcd] >=20 > # The value of data buffer size used for USB debug port handle. > # It should be equal to sizeof (USB3_DEBUG_PORT_HANDLE). > - > gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize| > 239 ## SOMETIMES_CONSUMES > + > gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize| > 250 ## SOMETIMES_CONSUMES >=20 > [LibraryClasses] > BaseLib > @@ -67,6 +68,7 @@ [LibraryClasses] > TimerLib > BaseMemoryLib > PeiServicesLib > - > + HobLib > + > [Depex.common.PEIM] > gEfiPeiMemoryDiscoveredPpiGuid > -- > 2.7.0.windows.1 >=20 > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel