mirror of https://github.com/acidanthera/audk.git
SourceLevelDebugPkg DebugUsb3: Support IOMMU
For PEI, allocate granted DMA buffer from IOMMU PPI. For DXE, map DMA buffer by PciIo. Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Cc: Hao Wu <hao.a.wu@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
This commit is contained in:
parent
f4043414da
commit
de8373fa07
|
@ -14,11 +14,6 @@
|
||||||
|
|
||||||
#include "DebugCommunicationLibUsb3Internal.h"
|
#include "DebugCommunicationLibUsb3Internal.h"
|
||||||
|
|
||||||
//
|
|
||||||
// The global variable which can be used after memory is ready.
|
|
||||||
//
|
|
||||||
USB3_DEBUG_PORT_HANDLE mDebugCommunicationLibUsb3DebugPortHandle;
|
|
||||||
|
|
||||||
UINT16 mString0Desc[] = {
|
UINT16 mString0Desc[] = {
|
||||||
// String Descriptor Type + Length
|
// String Descriptor Type + Length
|
||||||
( USB_DESC_TYPE_STRING << 8 ) + STRING0_DESC_LEN,
|
( USB_DESC_TYPE_STRING << 8 ) + STRING0_DESC_LEN,
|
||||||
|
@ -85,7 +80,7 @@ XhcClearR32Bit(
|
||||||
Write the data to the XHCI debug register.
|
Write the data to the XHCI debug register.
|
||||||
|
|
||||||
@param Handle Debug port handle.
|
@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.
|
@param Data The data to write.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -129,16 +124,16 @@ XhcReadDebugReg (
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set one bit of the runtime register while keeping other bits.
|
Set one bit of the debug register while keeping other bits.
|
||||||
|
|
||||||
@param Handle Debug port handle.
|
@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.
|
@param Bit The bit mask of the register to set.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
XhcSetDebugRegBit (
|
XhcSetDebugRegBit (
|
||||||
IN USB3_DEBUG_PORT_HANDLE *Handle,
|
IN USB3_DEBUG_PORT_HANDLE *Handle,
|
||||||
IN UINT32 Offset,
|
IN UINT32 Offset,
|
||||||
IN UINT32 Bit
|
IN UINT32 Bit
|
||||||
)
|
)
|
||||||
|
@ -150,6 +145,28 @@ XhcSetDebugRegBit (
|
||||||
XhcWriteDebugReg (Handle, Offset, Data);
|
XhcWriteDebugReg (Handle, Offset, Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
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 = XhcReadDebugReg (Handle, Offset);
|
||||||
|
Data &= ~Bit;
|
||||||
|
XhcWriteDebugReg (Handle, Offset, Data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Program and eanble XHCI MMIO base address.
|
Program and eanble XHCI MMIO base address.
|
||||||
|
|
||||||
|
@ -199,7 +216,7 @@ UpdateXhcResource (
|
||||||
IN EFI_PHYSICAL_ADDRESS XhciMmioBase
|
IN EFI_PHYSICAL_ADDRESS XhciMmioBase
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if ((Handle == NULL) || (Handle->XhciMmioBase == XhciMmioBase)) {
|
if (Handle == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +233,7 @@ UpdateXhcResource (
|
||||||
|
|
||||||
@param Handle Debug port handle.
|
@param Handle Debug port handle.
|
||||||
|
|
||||||
@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.
|
@retval RETURN_SUCCESS Get bar and offset successfully.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -236,6 +253,14 @@ CalculateUsbDebugPortMmioBase (
|
||||||
EFI_PHYSICAL_ADDRESS CapabilityPointer;
|
EFI_PHYSICAL_ADDRESS CapabilityPointer;
|
||||||
UINT8 CapLength;
|
UINT8 CapLength;
|
||||||
|
|
||||||
|
if (Handle->Initialized != USB3DBG_UNINITIALIZED) {
|
||||||
|
if (Handle->Initialized == USB3DBG_NO_DBG_CAB) {
|
||||||
|
return RETURN_UNSUPPORTED;
|
||||||
|
} else {
|
||||||
|
return RETURN_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VendorId = PciRead16 (PcdGet32(PcdUsbXhciPciAddress) + PCI_VENDOR_ID_OFFSET);
|
VendorId = PciRead16 (PcdGet32(PcdUsbXhciPciAddress) + PCI_VENDOR_ID_OFFSET);
|
||||||
DeviceId = PciRead16 (PcdGet32(PcdUsbXhciPciAddress) + PCI_DEVICE_ID_OFFSET);
|
DeviceId = PciRead16 (PcdGet32(PcdUsbXhciPciAddress) + PCI_DEVICE_ID_OFFSET);
|
||||||
|
|
||||||
|
@ -288,6 +313,7 @@ CalculateUsbDebugPortMmioBase (
|
||||||
Handle->DebugCapabilityBase = CapabilityPointer;
|
Handle->DebugCapabilityBase = CapabilityPointer;
|
||||||
Handle->DebugCapabilityOffset = CapabilityPointer - Handle->XhciMmioBase;
|
Handle->DebugCapabilityOffset = CapabilityPointer - Handle->XhciMmioBase;
|
||||||
Handle->XhciOpRegister = Handle->XhciMmioBase + CapLength;
|
Handle->XhciOpRegister = Handle->XhciMmioBase + CapLength;
|
||||||
|
Handle->DebugSupport = TRUE;
|
||||||
Handle->Initialized = USB3DBG_DBG_CAB;
|
Handle->Initialized = USB3DBG_DBG_CAB;
|
||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
|
|
||||||
|
@ -326,6 +352,9 @@ NeedReinitializeHardware(
|
||||||
Dcctrl = XhcReadDebugReg (Handle, XHC_DC_DCCTRL);
|
Dcctrl = XhcReadDebugReg (Handle, XHC_DC_DCCTRL);
|
||||||
if ((Dcctrl & BIT0) == 0) {
|
if ((Dcctrl & BIT0) == 0) {
|
||||||
Result = TRUE;
|
Result = TRUE;
|
||||||
|
} else if (!Handle->Ready) {
|
||||||
|
Handle->Ready = TRUE;
|
||||||
|
Handle->Initialized = USB3DBG_ENABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
|
@ -677,6 +706,13 @@ InitializeUsbDebugHardware (
|
||||||
MicroSecondDelay (10 * 1000);
|
MicroSecondDelay (10 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clear DCE bit and LSE bit in DCCTRL
|
||||||
|
//
|
||||||
|
if ((XhcReadDebugReg (Handle, XHC_DC_DCCTRL) & (BIT1|BIT31)) == (BIT1|BIT31)) {
|
||||||
|
XhcClearDebugRegBit (Handle, XHC_DC_DCCTRL, BIT1|BIT31);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Construct the buffer for read, poll and write.
|
// Construct the buffer for read, poll and write.
|
||||||
//
|
//
|
||||||
|
@ -745,6 +781,35 @@ Enable:
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
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 = ProgramXhciBaseAddress ();
|
||||||
|
Handle->XhciMmioBase = XhciMmioBase;
|
||||||
|
|
||||||
|
Status = 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.
|
Read data from debug device and save the data in buffer.
|
||||||
|
|
||||||
|
@ -772,7 +837,6 @@ DebugPortReadBuffer (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
USB3_DEBUG_PORT_HANDLE *UsbDebugPortHandle;
|
USB3_DEBUG_PORT_HANDLE *UsbDebugPortHandle;
|
||||||
RETURN_STATUS Status;
|
|
||||||
UINT8 Index;
|
UINT8 Index;
|
||||||
UINT8 *Data;
|
UINT8 *Data;
|
||||||
|
|
||||||
|
@ -780,25 +844,17 @@ DebugPortReadBuffer (
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
UsbDebugPortHandle = GetUsb3DebugPortInstance ();
|
||||||
// If Handle is NULL, it means memory is ready for use.
|
if (UsbDebugPortHandle == NULL) {
|
||||||
// Use global variable to store handle value.
|
|
||||||
//
|
|
||||||
if (Handle == NULL) {
|
|
||||||
UsbDebugPortHandle = &mDebugCommunicationLibUsb3DebugPortHandle;
|
|
||||||
} else {
|
|
||||||
UsbDebugPortHandle = (USB3_DEBUG_PORT_HANDLE *)Handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UsbDebugPortHandle->Initialized == USB3DBG_NO_DBG_CAB) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NeedReinitializeHardware(UsbDebugPortHandle)) {
|
if (UsbDebugPortHandle->Initialized != USB3DBG_ENABLED) {
|
||||||
Status = InitializeUsbDebugHardware (UsbDebugPortHandle);
|
return 0;
|
||||||
if (RETURN_ERROR(Status)) {
|
}
|
||||||
return 0;
|
|
||||||
}
|
if (UsbDebugPortHandle->InNotify) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data = (UINT8 *)(UINTN)UsbDebugPortHandle->Data;
|
Data = (UINT8 *)(UINTN)UsbDebugPortHandle->Data;
|
||||||
|
@ -848,10 +904,8 @@ DebugPortWriteBuffer (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
USB3_DEBUG_PORT_HANDLE *UsbDebugPortHandle;
|
USB3_DEBUG_PORT_HANDLE *UsbDebugPortHandle;
|
||||||
RETURN_STATUS Status;
|
|
||||||
UINTN Sent;
|
UINTN Sent;
|
||||||
UINTN Total;
|
UINTN Total;
|
||||||
EFI_PHYSICAL_ADDRESS XhciMmioBase;
|
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
|
|
||||||
if (NumberOfBytes == 0 || Buffer == NULL) {
|
if (NumberOfBytes == 0 || Buffer == NULL) {
|
||||||
|
@ -861,39 +915,24 @@ DebugPortWriteBuffer (
|
||||||
Sent = 0;
|
Sent = 0;
|
||||||
Total = 0;
|
Total = 0;
|
||||||
|
|
||||||
//
|
UsbDebugPortHandle = GetUsb3DebugPortInstance ();
|
||||||
// If Handle is NULL, it means memory is ready for use.
|
if (UsbDebugPortHandle == NULL) {
|
||||||
// Use global variable to store handle value.
|
|
||||||
//
|
|
||||||
if (Handle == NULL) {
|
|
||||||
UsbDebugPortHandle = &mDebugCommunicationLibUsb3DebugPortHandle;
|
|
||||||
} else {
|
|
||||||
UsbDebugPortHandle = (USB3_DEBUG_PORT_HANDLE *)Handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UsbDebugPortHandle->Initialized == USB3DBG_NO_DBG_CAB) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
if (UsbDebugPortHandle->Initialized != USB3DBG_ENABLED) {
|
||||||
// MMIO base address is possible to clear, set it if it is cleared. (XhciMemorySpaceClose in PchUsbCommon.c)
|
return 0;
|
||||||
//
|
}
|
||||||
XhciMmioBase = ProgramXhciBaseAddress ();
|
|
||||||
|
|
||||||
UpdateXhcResource (UsbDebugPortHandle, XhciMmioBase);
|
if (UsbDebugPortHandle->InNotify) {
|
||||||
|
return 0;
|
||||||
if (NeedReinitializeHardware(UsbDebugPortHandle)) {
|
|
||||||
Status = InitializeUsbDebugHardware (UsbDebugPortHandle);
|
|
||||||
if (RETURN_ERROR(Status)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// When host is trying to send data, write will be blocked.
|
// When host is trying to send data, write will be blocked.
|
||||||
// Poll to see if there is any data sent by host at first.
|
// Poll to see if there is any data sent by host at first.
|
||||||
//
|
//
|
||||||
DebugPortPollBuffer (Handle);
|
DebugPortPollBuffer (UsbDebugPortHandle);
|
||||||
|
|
||||||
Index = 0;
|
Index = 0;
|
||||||
while ((Total < NumberOfBytes)) {
|
while ((Total < NumberOfBytes)) {
|
||||||
|
@ -902,7 +941,7 @@ DebugPortWriteBuffer (
|
||||||
} else {
|
} else {
|
||||||
Sent = (UINT8)(NumberOfBytes - Total);
|
Sent = (UINT8)(NumberOfBytes - Total);
|
||||||
}
|
}
|
||||||
Status = XhcDataTransfer (UsbDebugPortHandle, EfiUsbDataOut, Buffer + Total, &Sent, DATA_TRANSFER_WRITE_TIMEOUT);
|
XhcDataTransfer (UsbDebugPortHandle, EfiUsbDataOut, Buffer + Total, &Sent, DATA_TRANSFER_WRITE_TIMEOUT);
|
||||||
Total += Sent;
|
Total += Sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -930,33 +969,20 @@ DebugPortPollBuffer (
|
||||||
{
|
{
|
||||||
USB3_DEBUG_PORT_HANDLE *UsbDebugPortHandle;
|
USB3_DEBUG_PORT_HANDLE *UsbDebugPortHandle;
|
||||||
UINTN Length;
|
UINTN Length;
|
||||||
RETURN_STATUS Status;
|
|
||||||
EFI_PHYSICAL_ADDRESS XhciMmioBase;
|
|
||||||
|
|
||||||
//
|
UsbDebugPortHandle = GetUsb3DebugPortInstance ();
|
||||||
// If Handle is NULL, it means memory is ready for use.
|
if (UsbDebugPortHandle == NULL) {
|
||||||
// Use global variable to store handle value.
|
return FALSE;
|
||||||
//
|
|
||||||
if (Handle == NULL) {
|
|
||||||
UsbDebugPortHandle = &mDebugCommunicationLibUsb3DebugPortHandle;
|
|
||||||
} else {
|
|
||||||
UsbDebugPortHandle = (USB3_DEBUG_PORT_HANDLE *)Handle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UsbDebugPortHandle->Initialized == USB3DBG_NO_DBG_CAB) {
|
if (UsbDebugPortHandle->Initialized != USB3DBG_ENABLED) {
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
XhciMmioBase = ProgramXhciBaseAddress ();
|
if (UsbDebugPortHandle->InNotify) {
|
||||||
UpdateXhcResource (UsbDebugPortHandle, XhciMmioBase);
|
return FALSE;
|
||||||
|
|
||||||
if (NeedReinitializeHardware(UsbDebugPortHandle)) {
|
|
||||||
Status = InitializeUsbDebugHardware(UsbDebugPortHandle);
|
|
||||||
if (RETURN_ERROR(Status)) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// If the data buffer is not empty, then return TRUE directly.
|
// If the data buffer is not empty, then return TRUE directly.
|
||||||
// Otherwise initialize a usb read transaction and read data to internal data buffer.
|
// Otherwise initialize a usb read transaction and read data to internal data buffer.
|
||||||
|
@ -969,7 +995,7 @@ DebugPortPollBuffer (
|
||||||
// Read data as much as we can
|
// Read data as much as we can
|
||||||
//
|
//
|
||||||
Length = XHCI_DEBUG_DEVICE_MAX_PACKET_SIZE;
|
Length = 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);
|
||||||
|
|
||||||
if (Length > XHCI_DEBUG_DEVICE_MAX_PACKET_SIZE) {
|
if (Length > XHCI_DEBUG_DEVICE_MAX_PACKET_SIZE) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1017,50 +1043,16 @@ DebugPortInitialize (
|
||||||
IN DEBUG_PORT_CONTINUE Function
|
IN DEBUG_PORT_CONTINUE Function
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
RETURN_STATUS Status;
|
|
||||||
USB3_DEBUG_PORT_HANDLE Handle;
|
|
||||||
USB3_DEBUG_PORT_HANDLE *UsbDebugPortHandle;
|
USB3_DEBUG_PORT_HANDLE *UsbDebugPortHandle;
|
||||||
|
|
||||||
//
|
UsbDebugPortHandle = GetUsb3DebugPortInstance ();
|
||||||
// Validate the PCD PcdDebugPortHandleBufferSize value
|
if (UsbDebugPortHandle == NULL) {
|
||||||
//
|
return NULL;
|
||||||
ASSERT (PcdGet16 (PcdDebugPortHandleBufferSize) == sizeof (USB3_DEBUG_PORT_HANDLE));
|
|
||||||
|
|
||||||
if (Function == NULL && Context != NULL) {
|
|
||||||
UsbDebugPortHandle = (USB3_DEBUG_PORT_HANDLE *)Context;
|
|
||||||
} else {
|
|
||||||
ZeroMem(&Handle, sizeof (USB3_DEBUG_PORT_HANDLE));
|
|
||||||
UsbDebugPortHandle = &Handle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Function == NULL && Context != NULL) {
|
|
||||||
return (DEBUG_PORT_HANDLE *) Context;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read 64-bit MMIO base address
|
|
||||||
//
|
|
||||||
UsbDebugPortHandle->XhciMmioBase = ProgramXhciBaseAddress ();
|
|
||||||
|
|
||||||
Status = CalculateUsbDebugPortMmioBase (UsbDebugPortHandle);
|
|
||||||
if (RETURN_ERROR (Status)) {
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NeedReinitializeHardware(&Handle)) {
|
|
||||||
Status = InitializeUsbDebugHardware (&Handle);
|
|
||||||
if (RETURN_ERROR(Status)) {
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Exit:
|
|
||||||
|
|
||||||
if (Function != NULL) {
|
if (Function != NULL) {
|
||||||
Function (Context, &Handle);
|
Function (Context, UsbDebugPortHandle);
|
||||||
} else {
|
|
||||||
CopyMem(&mDebugCommunicationLibUsb3DebugPortHandle, &Handle, sizeof (USB3_DEBUG_PORT_HANDLE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (DEBUG_PORT_HANDLE)(UINTN)&mDebugCommunicationLibUsb3DebugPortHandle;
|
return (DEBUG_PORT_HANDLE)(UINTN)UsbDebugPortHandle;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Debug Port Library implementation based on usb3 debug port.
|
Debug Port Library implementation based on usb3 debug port.
|
||||||
|
|
||||||
Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -15,8 +15,331 @@
|
||||||
#include <Base.h>
|
#include <Base.h>
|
||||||
#include <PiDxe.h>
|
#include <PiDxe.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/HobLib.h>
|
||||||
|
#include <Protocol/PciIo.h>
|
||||||
|
#include <Protocol/IoMmu.h>
|
||||||
#include "DebugCommunicationLibUsb3Internal.h"
|
#include "DebugCommunicationLibUsb3Internal.h"
|
||||||
|
|
||||||
|
GUID gUsb3DbgGuid = USB3_DBG_GUID;
|
||||||
|
|
||||||
|
USB3_DEBUG_PORT_HANDLE *mUsb3Instance = 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 != NULL);
|
||||||
|
ASSERT (NotifyFunction != NULL);
|
||||||
|
ASSERT (NotifyTpl <= TPL_HIGH_LEVEL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create event
|
||||||
|
//
|
||||||
|
Status = gBS->CreateEvent (
|
||||||
|
EVT_NOTIFY_SIGNAL,
|
||||||
|
NotifyTpl,
|
||||||
|
NotifyFunction,
|
||||||
|
NULL,
|
||||||
|
Event
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Register for an installation of protocol interface
|
||||||
|
//
|
||||||
|
Status = 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 = (VOID *) (UINTN) Address;
|
||||||
|
Status = PciIo->Map (
|
||||||
|
PciIo,
|
||||||
|
EfiPciIoOperationBusMasterCommonBuffer,
|
||||||
|
HostAddress,
|
||||||
|
&NumberOfBytes,
|
||||||
|
&DeviceAddress,
|
||||||
|
&Mapping
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
ASSERT (DeviceAddress == ((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 = gBS->FreePages (Address, EFI_SIZE_TO_PAGES (NumberOfBytes));
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
Status = 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 = NULL;
|
||||||
|
Status = gBS->LocateProtocol (&gEdkiiIoMmuProtocolGuid, NULL, (VOID **) &IoMmu);
|
||||||
|
if (EFI_ERROR (Status) || (IoMmu == 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 = MAX (XHCI_DEBUG_DEVICE_MAX_PACKET_SIZE * 2 + USB3_DEBUG_PORT_WRITE_MAX_PACKET_SIZE,
|
||||||
|
MAX (sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER,
|
||||||
|
MAX (sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER,
|
||||||
|
MAX (sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER,
|
||||||
|
MAX (sizeof (XHC_DC_CONTEXT),
|
||||||
|
STRING0_DESC_LEN + MANU_DESC_LEN + PRODUCT_DESC_LEN + SERIAL_DESC_LEN)))));
|
||||||
|
|
||||||
|
Status = 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 function'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;
|
||||||
|
|
||||||
|
ASSERT (mUsb3Instance != NULL);
|
||||||
|
|
||||||
|
Status = gBS->LocateHandleBuffer (
|
||||||
|
ByProtocol,
|
||||||
|
&gEfiPciIoProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
&PciIoHandleCount,
|
||||||
|
&PciIoHandleBuffer
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status) &&
|
||||||
|
(PciIoHandleBuffer != NULL) &&
|
||||||
|
(PciIoHandleCount != 0)) {
|
||||||
|
for (Index = 0; Index < PciIoHandleCount; Index++) {
|
||||||
|
Status = gBS->HandleProtocol (
|
||||||
|
PciIoHandleBuffer[Index],
|
||||||
|
&gEfiPciIoProtocolGuid,
|
||||||
|
(VOID **) &PciIo
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
Status = PciIo->GetLocation (PciIo, &PciSegment, &PciBusNumber, &PciDeviceNumber, &PciFunctionNumber);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
PciAddress = (UINT32) ((PciBusNumber << 20) | (PciDeviceNumber << 15) | (PciFunctionNumber << 12));
|
||||||
|
if (PciAddress == PcdGet32(PcdUsbXhciPciAddress)) {
|
||||||
|
//
|
||||||
|
// Found the PciIo for USB3 debug port.
|
||||||
|
//
|
||||||
|
DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));
|
||||||
|
mUsb3Instance->InNotify = TRUE;
|
||||||
|
Usb3MapDmaBuffers (mUsb3Instance, PciIo);
|
||||||
|
mUsb3Instance->InNotify = 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 = NULL;
|
||||||
|
|
||||||
|
if (mUsb3Instance != NULL) {
|
||||||
|
Instance = mUsb3Instance;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
Hob.Raw = GetFirstGuidHob (&gUsb3DbgGuid);
|
||||||
|
if (Hob.Raw != NULL) {
|
||||||
|
Instance = GET_GUID_HOB_DATA (Hob.Guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
Done:
|
||||||
|
if (Instance != NULL) {
|
||||||
|
DiscoverInitializeUsbDebugPort (Instance);
|
||||||
|
}
|
||||||
|
return Instance;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Allocate aligned memory for XHC's usage.
|
Allocate aligned memory for XHC's usage.
|
||||||
|
|
||||||
|
@ -51,3 +374,113 @@ AllocateAlignBuffer (
|
||||||
|
|
||||||
return Buf;
|
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 = GetUsb3DebugPortInstance ();
|
||||||
|
|
||||||
|
Status = EfiGetSystemConfigurationTable (&gUsb3DbgGuid, (VOID **) &mUsb3Instance);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Instance == NULL) {
|
||||||
|
//
|
||||||
|
// Initialize USB debug
|
||||||
|
//
|
||||||
|
ZeroMem (&UsbDbg, sizeof (UsbDbg));
|
||||||
|
UsbDbg.Initialized = USB3DBG_UNINITIALIZED;
|
||||||
|
|
||||||
|
DiscoverInitializeUsbDebugPort (&UsbDbg);
|
||||||
|
|
||||||
|
Instance = &UsbDbg;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// It is first time to run DXE instance, copy Instance from Hob to ACPINvs.
|
||||||
|
//
|
||||||
|
Address = SIZE_4GB;
|
||||||
|
Status = 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 = (USB3_DEBUG_PORT_HANDLE *)(UINTN)Address;
|
||||||
|
|
||||||
|
Status = gBS->InstallConfigurationTable (&gUsb3DbgGuid, mUsb3Instance);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Done:
|
||||||
|
if (mUsb3Instance->Ready && (mUsb3Instance->PciIoEvent == 0)) {
|
||||||
|
Status = Usb3NamedEventListen (
|
||||||
|
&gEfiPciIoProtocolGuid,
|
||||||
|
TPL_NOTIFY,
|
||||||
|
Usb3PciIoNotify,
|
||||||
|
&Event
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
mUsb3Instance->PciIoEvent = (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 != NULL) && (mUsb3Instance->PciIoEvent != 0)) {
|
||||||
|
//
|
||||||
|
// Close the event created.
|
||||||
|
//
|
||||||
|
gBS->CloseEvent ((EFI_EVENT) (UINTN) mUsb3Instance->PciIoEvent);
|
||||||
|
mUsb3Instance->PciIoEvent = 0;
|
||||||
|
}
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
## @file
|
## @file
|
||||||
# Debug Communication Library instance based on usb3 debug port.
|
# Debug Communication Library instance based on usb3 debug port.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
#
|
#
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -21,6 +21,8 @@
|
||||||
MODULE_TYPE = DXE_DRIVER
|
MODULE_TYPE = DXE_DRIVER
|
||||||
VERSION_STRING = 1.0
|
VERSION_STRING = 1.0
|
||||||
LIBRARY_CLASS = DebugCommunicationLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE
|
LIBRARY_CLASS = DebugCommunicationLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE
|
||||||
|
CONSTRUCTOR = DebugCommunicationUsb3DxeConstructor
|
||||||
|
DESTRUCTOR = DebugCommunicationUsb3DxeDestructor
|
||||||
|
|
||||||
#
|
#
|
||||||
# The following information is for reference only and not required by the build tools.
|
# The following information is for reference only and not required by the build tools.
|
||||||
|
@ -54,7 +56,11 @@
|
||||||
|
|
||||||
# The value of data buffer size used for USB debug port handle.
|
# The value of data buffer size used for USB debug port handle.
|
||||||
# It should be equal to sizeof (USB3_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
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
BaseLib
|
BaseLib
|
||||||
|
@ -65,4 +71,4 @@
|
||||||
UefiBootServicesTableLib
|
UefiBootServicesTableLib
|
||||||
UefiLib
|
UefiLib
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
|
HobLib
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Debug Port Library implementation based on usb3 debug port.
|
Debug Port Library implementation based on usb3 debug port.
|
||||||
|
|
||||||
Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
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_DBG_CAB 1 // The XHCI host controller supports debug capability
|
||||||
#define USB3DBG_ENABLED 2 // The XHCI debug device is enabled
|
#define USB3DBG_ENABLED 2 // The XHCI debug device is enabled
|
||||||
#define USB3DBG_NOT_ENABLED 4 // The XHCI debug device is not enabled
|
#define USB3DBG_NOT_ENABLED 4 // The XHCI debug device is not enabled
|
||||||
|
#define USB3DBG_UNINITIALIZED 255 // The XHCI debug device is uninitialized
|
||||||
|
|
||||||
#define USB3_DEBUG_PORT_WRITE_MAX_PACKET_SIZE 0x08
|
#define USB3_DEBUG_PORT_WRITE_MAX_PACKET_SIZE 0x08
|
||||||
|
|
||||||
|
@ -456,7 +457,7 @@ typedef struct _USB3_DEBUG_PORT_INSTANCE {
|
||||||
UINT8 Initialized;
|
UINT8 Initialized;
|
||||||
|
|
||||||
//
|
//
|
||||||
// The flag indicates debug device is ready
|
// The flag indicates debug capability is supported
|
||||||
//
|
//
|
||||||
BOOLEAN DebugSupport;
|
BOOLEAN DebugSupport;
|
||||||
|
|
||||||
|
@ -465,6 +466,26 @@ typedef struct _USB3_DEBUG_PORT_INSTANCE {
|
||||||
//
|
//
|
||||||
BOOLEAN Ready;
|
BOOLEAN Ready;
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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
|
// The flag indicates if USB 3.0 ports has been turn off/on power
|
||||||
//
|
//
|
||||||
|
@ -728,4 +749,39 @@ XhcDataTransfer (
|
||||||
IN UINTN Timeout
|
IN UINTN Timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
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__
|
#endif //__SERIAL_PORT_LIB_USB__
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Debug Port Library implementation based on usb3 debug port.
|
Debug Port Library implementation based on usb3 debug port.
|
||||||
|
|
||||||
Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -14,13 +14,215 @@
|
||||||
|
|
||||||
#include <PiPei.h>
|
#include <PiPei.h>
|
||||||
#include <Library/PeiServicesLib.h>
|
#include <Library/PeiServicesLib.h>
|
||||||
|
#include <Library/HobLib.h>
|
||||||
#include <Ppi/MemoryDiscovered.h>
|
#include <Ppi/MemoryDiscovered.h>
|
||||||
|
#include <Ppi/IoMmu.h>
|
||||||
#include "DebugCommunicationLibUsb3Internal.h"
|
#include "DebugCommunicationLibUsb3Internal.h"
|
||||||
|
|
||||||
|
GUID gUsb3DbgGuid = 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 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 = GetUsb3DebugPortInstance ();
|
||||||
|
ASSERT (Instance != NULL);
|
||||||
|
|
||||||
|
Instance->InNotify = 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 = FALSE;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_PEI_NOTIFY_DESCRIPTOR mUsb3IoMmuPpiNotifyDesc = {
|
||||||
|
(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 memory address of the
|
||||||
|
allocated range.
|
||||||
|
@param DeviceAddress The resulting map address for the bus master 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 = NULL;
|
||||||
|
*DeviceAddress = 0;
|
||||||
|
*Mapping = NULL;
|
||||||
|
|
||||||
|
Status = IoMmu->AllocateBuffer (
|
||||||
|
IoMmu,
|
||||||
|
EfiBootServicesData,
|
||||||
|
Pages,
|
||||||
|
HostAddress,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberOfBytes = EFI_PAGES_TO_SIZE (Pages);
|
||||||
|
Status = IoMmu->Map (
|
||||||
|
IoMmu,
|
||||||
|
EdkiiIoMmuOperationBusMasterCommonBuffer,
|
||||||
|
*HostAddress,
|
||||||
|
&NumberOfBytes,
|
||||||
|
DeviceAddress,
|
||||||
|
Mapping
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
IoMmu->FreeBuffer (IoMmu, Pages, *HostAddress);
|
||||||
|
*HostAddress = NULL;
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
Status = 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 = NULL;
|
||||||
|
*HostAddress = 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 = NULL;
|
||||||
|
Status = PeiServicesLocatePpi (
|
||||||
|
&gEdkiiIoMmuPpiGuid,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
(VOID **) &IoMmu
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status) && (IoMmu != 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 = GetFirstGuidHob (&gUsb3DbgGuid);
|
||||||
|
if (Hob.Raw == NULL) {
|
||||||
|
//
|
||||||
|
// Save Instance into HOB
|
||||||
|
//
|
||||||
|
Instance = BuildGuidHob (
|
||||||
|
&gUsb3DbgGuid,
|
||||||
|
sizeof (USB3_DEBUG_PORT_HANDLE)
|
||||||
|
);
|
||||||
|
ASSERT (Instance != NULL);
|
||||||
|
ZeroMem (Instance, sizeof (USB3_DEBUG_PORT_HANDLE));
|
||||||
|
|
||||||
|
Instance->FromHob = TRUE;
|
||||||
|
Instance->Initialized = USB3DBG_UNINITIALIZED;
|
||||||
|
} else {
|
||||||
|
Instance = GET_GUID_HOB_DATA (Hob.Guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Instance->InNotify) {
|
||||||
|
DiscoverInitializeUsbDebugPort (Instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Instance->Ready &&
|
||||||
|
!Instance->PpiNotifyRegistered &&
|
||||||
|
(Usb3GetIoMmu () == NULL)) {
|
||||||
|
Status = PeiServicesNotifyPpi (&mUsb3IoMmuPpiNotifyDesc);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
Instance->PpiNotifyRegistered = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Instance;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Allocate aligned memory for XHC's usage.
|
Allocate aligned memory for XHC's usage.
|
||||||
|
|
||||||
@param BufferSize The size, in bytes, of the Buffer.
|
@param BufferSize The size, in bytes, of the Buffer.
|
||||||
|
|
||||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||||
|
|
||||||
|
@ -34,6 +236,9 @@ AllocateAlignBuffer (
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
EFI_PHYSICAL_ADDRESS Address;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
VOID *MemoryDiscoveredPpi;
|
VOID *MemoryDiscoveredPpi;
|
||||||
|
EDKII_IOMMU_PPI *IoMmu;
|
||||||
|
VOID *HostAddress;
|
||||||
|
VOID *Mapping;
|
||||||
|
|
||||||
Buf = NULL;
|
Buf = NULL;
|
||||||
|
|
||||||
|
@ -47,9 +252,28 @@ AllocateAlignBuffer (
|
||||||
(VOID **) &MemoryDiscoveredPpi
|
(VOID **) &MemoryDiscoveredPpi
|
||||||
);
|
);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
Status = PeiServicesAllocatePages (EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES (BufferSize), &Address);
|
IoMmu = Usb3GetIoMmu ();
|
||||||
if (!EFI_ERROR (Status)) {
|
if (IoMmu != NULL) {
|
||||||
Buf = (VOID *)(UINTN) Address;
|
Status = IoMmuAllocateBuffer (
|
||||||
|
IoMmu,
|
||||||
|
EFI_SIZE_TO_PAGES (BufferSize),
|
||||||
|
&HostAddress,
|
||||||
|
&Address,
|
||||||
|
&Mapping
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
ASSERT (Address == ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress));
|
||||||
|
Buf = (VOID *)(UINTN) Address;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Status = PeiServicesAllocatePages (
|
||||||
|
EfiACPIMemoryNVS,
|
||||||
|
EFI_SIZE_TO_PAGES (BufferSize),
|
||||||
|
&Address
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
Buf = (VOID *)(UINTN) Address;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Buf;
|
return Buf;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
## @file
|
## @file
|
||||||
# Debug Communication Library instance based on usb3 debug port.
|
# Debug Communication Library instance based on usb3 debug port.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
#
|
#
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
[Ppis]
|
[Ppis]
|
||||||
gEfiPeiMemoryDiscoveredPpiGuid ## CONSUMES
|
gEfiPeiMemoryDiscoveredPpiGuid ## CONSUMES
|
||||||
|
gEdkiiIoMmuPpiGuid ## CONSUMES
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
# The memory BAR of ehci host controller, in which usb debug feature is enabled.
|
# The memory BAR of ehci host controller, in which usb debug feature is enabled.
|
||||||
|
@ -57,7 +58,7 @@
|
||||||
|
|
||||||
# The value of data buffer size used for USB debug port handle.
|
# The value of data buffer size used for USB debug port handle.
|
||||||
# It should be equal to sizeof (USB3_DEBUG_PORT_HANDLE).
|
# It should be equal to sizeof (USB3_DEBUG_PORT_HANDLE).
|
||||||
gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize|239 ## SOMETIMES_CONSUMES
|
gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize|250 ## SOMETIMES_CONSUMES
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
BaseLib
|
BaseLib
|
||||||
|
@ -67,6 +68,7 @@
|
||||||
TimerLib
|
TimerLib
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
PeiServicesLib
|
PeiServicesLib
|
||||||
|
HobLib
|
||||||
|
|
||||||
[Depex.common.PEIM]
|
[Depex.common.PEIM]
|
||||||
gEfiPeiMemoryDiscoveredPpiGuid
|
gEfiPeiMemoryDiscoveredPpiGuid
|
||||||
|
|
Loading…
Reference in New Issue