/** @file
|
Usb3 Debug Port library instance
|
|
Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.<BR>
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
**/
|
|
#include <Base.h>
|
|
#include <PiDxe.h>
|
#include <Library/SerialPortLib.h>
|
#include <Library/BaseMemoryLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiLib.h>
|
#include <Library/PciLib.h>
|
#include <Library/PcdLib.h>
|
#include <Library/TimerLib.h>
|
#include <Library/Usb3DebugPortParamLib.h>
|
#include <Protocol/SmmBase2.h>
|
#include <Protocol/SmmAccess2.h>
|
#include <Protocol/IoMmu.h>
|
#include <Protocol/PciIo.h>
|
#include <Protocol/DxeSmmReadyToLock.h>
|
#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 = USB3_DBG_GUID;
|
|
USB3_DEBUG_PORT_CONTROLLER mUsb3DebugPort;
|
USB3_DEBUG_PORT_INSTANCE *mUsb3Instance = NULL;
|
EFI_PCI_IO_PROTOCOL *mUsb3PciIo = 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 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 = (VOID *) (UINTN) Address;
|
Status = PciIo->Map (
|
PciIo,
|
EfiPciIoOperationBusMasterCommonBuffer,
|
HostAddress,
|
&NumberOfBytes,
|
&DeviceAddress,
|
&Mapping
|
);
|
ASSERT_EFI_ERROR (Status);
|
ASSERT (DeviceAddress == ((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)->DbcInfoContext.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 being invoked.
|
@param[in] Context The pointer to the notification function's context,
|
which is implementation-dependent.
|
|
**/
|
VOID
|
EFIAPI
|
Usb3DxeSmmReadyToLockNotify (
|
IN EFI_EVENT Event,
|
IN VOID *Context
|
)
|
{
|
ASSERT (mUsb3Instance != 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 = NULL;
|
Status = gBS->LocateProtocol (
|
&gEdkiiIoMmuProtocolGuid,
|
NULL,
|
(VOID **) &IoMmu
|
);
|
if (!EFI_ERROR (Status) && (IoMmu != NULL)) {
|
return IoMmu;
|
}
|
|
return NULL;
|
}
|
|
/**
|
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;
|
EFI_EVENT SmmReadyToLockEvent;
|
|
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);
|
if ((PciBusNumber == mUsb3DebugPort.PciAddress.Bus) &&
|
(PciDeviceNumber == mUsb3DebugPort.PciAddress.Device) &&
|
(PciFunctionNumber == mUsb3DebugPort.PciAddress.Function)) {
|
//
|
// Found the PciIo for USB3 debug port.
|
//
|
ASSERT (mUsb3Instance != NULL);
|
if (Usb3GetIoMmu () != NULL) {
|
Usb3MapDmaBuffers (mUsb3Instance, PciIo);
|
|
if (mUsb3Instance->FromHob) {
|
mUsb3PciIo = 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 == 0) {
|
mUsb3DebugPort.Controller = GetUsb3DebugPortController();
|
}
|
|
Bus = mUsb3DebugPort.PciAddress.Bus;
|
Device = mUsb3DebugPort.PciAddress.Device;
|
Function = mUsb3DebugPort.PciAddress.Function;
|
|
Low = PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET));
|
High = PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4));
|
Address = (EFI_PHYSICAL_ADDRESS) (LShiftU64 ((UINT64) High, 32) | Low);
|
//
|
// Mask other parts which are not part of base address
|
//
|
Address &= 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 = NULL;
|
|
XhcMmioBase = GetXhciBaseAddress ();
|
|
if ((XhcMmioBase == 0) || (XhcMmioBase == XHCI_BASE_ADDRESS_64_BIT_MASK)) {
|
return NULL;
|
}
|
|
if (mUsb3Instance != NULL) {
|
FixUsb3InstanceResource (mUsb3Instance, XhcMmioBase);
|
return mUsb3Instance;
|
}
|
|
Command = GetXhciPciCommand ();
|
|
UsbDebugPort.Controller = GetUsb3DebugPortController();
|
Bus = UsbDebugPort.PciAddress.Bus;
|
Device = UsbDebugPort.PciAddress.Device;
|
Function = UsbDebugPort.PciAddress.Function;
|
|
//
|
// Set Command Register
|
//
|
if ((Command & EFI_PCI_COMMAND_MEMORY_SPACE) == 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 = XhcMmioBase + (MmioRead32 ((UINTN)(XhcMmioBase + XHC_HCCPARAMS_OFFSET)) >> 16) * 4;
|
|
//
|
// Search XHCI debug capability
|
//
|
Flag = FALSE;
|
Capability = MmioRead32 ((UINTN)CapabilityPointer);
|
while (TRUE) {
|
if ((Capability & XHC_CAPABILITY_ID_MASK) == PCI_CAPABILITY_ID_DEBUG_PORT) {
|
Flag = TRUE;
|
break;
|
}
|
if ((((Capability & XHC_NEXT_CAPABILITY_MASK) >> 8) & XHC_CAPABILITY_ID_MASK) == 0) {
|
//
|
// Reach the end of list, quit
|
//
|
break;
|
}
|
CapabilityPointer += ((Capability & XHC_NEXT_CAPABILITY_MASK) >> 8) * 4;
|
Capability = MmioRead32 ((UINTN)CapabilityPointer);
|
}
|
|
if (Flag) {
|
Instance = (USB3_DEBUG_PORT_INSTANCE *)(UINTN) MmioRead32 ((UINTN) (CapabilityPointer + XHC_DC_DCDDI2));
|
|
if (Instance != 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 == NULL) || (gBS == NULL)) {
|
//
|
// gST and gBS have not been initialized yet
|
//
|
return EFI_DEVICE_ERROR;
|
}
|
|
Status = EfiGetSystemConfigurationTable (&gUsb3DbgGuid, (VOID **) &mUsb3Instance);
|
if (!EFI_ERROR (Status)) {
|
goto Done;
|
}
|
|
//
|
// It is first time to run DXE instance, copy Instance from Hob to ACPINvs
|
// NOTE: Hob is not ready at this time, so copy it from XHCI register.
|
//
|
Instance = GetUsb3DebugPortInstance ();
|
if (Instance == NULL) {
|
//
|
// Initialize USB debug
|
//
|
SetMem (&UsbDbg, sizeof(UsbDbg), 0);
|
DiscoverUsb3DebugPort (&UsbDbg);
|
if (UsbDbg.DebugSupport) {
|
InitializeUsb3DebugPort (&UsbDbg);
|
}
|
Instance = &UsbDbg;
|
}
|
Address = SIZE_4GB;
|
Status = 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 = (USB3_DEBUG_PORT_INSTANCE *)(UINTN)Address;
|
|
Status = gBS->InstallConfigurationTable (&gUsb3DbgGuid, mUsb3Instance);
|
if (EFI_ERROR (Status)) {
|
return Status;
|
}
|
|
if (mUsb3Instance->DebugSupport) {
|
SaveUsb3InstanceAddress (mUsb3Instance);
|
}
|
|
Done:
|
if ((mUsb3Instance != NULL) && mUsb3Instance->Ready && (mUsb3Instance->PciIoEvent == 0)) {
|
Status = Usb3NamedEventListen (
|
&gEfiPciIoProtocolGuid,
|
TPL_NOTIFY,
|
Usb3PciIoNotify,
|
&Event
|
);
|
if (!EFI_ERROR (Status)) {
|
mUsb3Instance->PciIoEvent = (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 = GetUsb3DebugPortController();
|
Bus = UsbDebugPort.PciAddress.Bus;
|
Device = UsbDebugPort.PciAddress.Device;
|
Function = UsbDebugPort.PciAddress.Function;
|
|
Mask = 0xFFFFFFF0;
|
MmioSize = 0;
|
|
XhcMmioBase = GetXhciBaseAddress ();
|
|
//
|
// Disable MSE
|
//
|
Command = PciRead16 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_COMMAND_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_OFFSET), 0xFFFFFFFF);
|
Value = 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 = (~(Value & Mask)) + 1;
|
break;
|
case 0x4:
|
//
|
// Memory space: anywhere in 64 bit address space
|
//
|
MmioSize = Value & Mask;
|
PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4), 0xFFFFFFFF);
|
Value = PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4));
|
//
|
// Fix the length to support some spefic 64 bit BAR
|
//
|
Value |= ((UINT32)(-1) << HighBitSet32 (Value));
|
//
|
// Calculate the size of 64bit bar
|
//
|
MmioSize |= LShiftU64 ((UINT64) Value, 32);
|
MmioSize = (~(MmioSize)) + 1;
|
break;
|
default:
|
//
|
// Unknown BAR type
|
//
|
MmioSize = (~(Value & Mask)) + 1;
|
break;
|
};
|
|
|
//
|
// Restore MMIO address
|
//
|
PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET), (UINT32)XhcMmioBase);
|
PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 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 ACPINvs.
|
// We must do it in constructor because it depends on UefiBootServicesTableLib.
|
//
|
if (FeaturePcdGet (PcdUsb3DebugFeatureEnable)) {
|
USB3InitializeReal ();
|
}
|
|
mUsb3MmioSize = CalculateMmioSize ();
|
|
if (gBS != NULL) {
|
SmmBase = NULL;
|
Status = gBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, (VOID **)&SmmBase);
|
if (!EFI_ERROR (Status)) {
|
SmmBase->InSmm(SmmBase, &mUsb3InSmm);
|
}
|
|
if (mUsb3InSmm) {
|
//
|
// Get SMRAM information
|
//
|
SmmAccess = NULL;
|
Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);
|
if (!EFI_ERROR (Status)) {
|
Size = sizeof (mSmramCheckRanges);
|
|
Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramCheckRanges);
|
if (!EFI_ERROR (Status)) {
|
mSmramCheckRangeCount = 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 != NULL) && (mUsb3Instance->PciIoEvent != 0)) {
|
//
|
// Close the event created.
|
//
|
gBS->CloseEvent ((EFI_EVENT) (UINTN) mUsb3Instance->PciIoEvent);
|
mUsb3Instance->PciIoEvent = 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 = NULL;
|
Status = 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 = NULL;
|
|
if (gBS != NULL) {
|
if (mUsb3PciIo != NULL) {
|
Usb3AllocateDmaBuffer (
|
mUsb3PciIo,
|
EFI_SIZE_TO_PAGES (BufferSize),
|
&Buf
|
);
|
} else {
|
Address = 0xFFFFFFFF;
|
Status = gBS->AllocatePages (
|
AllocateMaxAddress,
|
EfiACPIMemoryNVS,
|
EFI_SIZE_TO_PAGES (BufferSize),
|
&Address
|
);
|
if (!EFI_ERROR (Status)) {
|
Buf = (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 != NULL) {
|
return TRUE;
|
}
|
|
return FALSE;
|
}
|
|