/** @file\r
Debug Port Library implementation based on usb3 debug port.\r
\r
- Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
#include "DebugCommunicationLibUsb3Internal.h"\r
EFI_STATUS\r
EFIAPI\r
XhcSyncTrsRing (\r
- IN USB3_DEBUG_PORT_HANDLE *Handle,\r
- IN TRANSFER_RING *TrsRing\r
+ IN USB3_DEBUG_PORT_HANDLE *Handle,\r
+ IN TRANSFER_RING *TrsRing\r
)\r
{\r
- UINTN Index;\r
- TRB_TEMPLATE *TrsTrb;\r
- UINT32 CycleBit;\r
+ UINTN Index;\r
+ TRB_TEMPLATE *TrsTrb;\r
+ UINT32 CycleBit;\r
\r
ASSERT (TrsRing != NULL);\r
\r
//\r
// Calculate the latest RingEnqueue and RingPCS\r
//\r
- TrsTrb = (TRB_TEMPLATE *)(UINTN) TrsRing->RingEnqueue;\r
+ TrsTrb = (TRB_TEMPLATE *)(UINTN)TrsRing->RingEnqueue;\r
\r
ASSERT (TrsTrb != NULL);\r
- \r
+\r
for (Index = 0; Index < TrsRing->TrbNumber; Index++) {\r
if (TrsTrb->CycleBit != (TrsRing->RingPCS & BIT0)) {\r
break;\r
}\r
+\r
TrsTrb++;\r
- if ((UINT8) TrsTrb->Type == TRB_TYPE_LINK) {\r
- ASSERT (((LINK_TRB*)TrsTrb)->TC != 0);\r
+ if ((UINT8)TrsTrb->Type == TRB_TYPE_LINK) {\r
+ ASSERT (((LINK_TRB *)TrsTrb)->TC != 0);\r
//\r
// set cycle bit in Link TRB as normal\r
//\r
- ((LINK_TRB*)TrsTrb)->CycleBit = TrsRing->RingPCS & BIT0;\r
+ ((LINK_TRB *)TrsTrb)->CycleBit = TrsRing->RingPCS & BIT0;\r
//\r
// Toggle PCS maintained by software\r
//\r
TrsTrb = (TRB_TEMPLATE *)(UINTN)((TrsTrb->Parameter1 | LShiftU64 ((UINT64)TrsTrb->Parameter2, 32)) & ~0x0F);\r
}\r
}\r
+\r
ASSERT (Index != TrsRing->TrbNumber);\r
\r
- if ((EFI_PHYSICAL_ADDRESS)(UINTN) TrsTrb != TrsRing->RingEnqueue) {\r
- TrsRing->RingEnqueue = (EFI_PHYSICAL_ADDRESS)(UINTN) TrsTrb;\r
+ if ((EFI_PHYSICAL_ADDRESS)(UINTN)TrsTrb != TrsRing->RingEnqueue) {\r
+ TrsRing->RingEnqueue = (EFI_PHYSICAL_ADDRESS)(UINTN)TrsTrb;\r
}\r
\r
//\r
EFIAPI\r
XhcSyncEventRing (\r
IN USB3_DEBUG_PORT_HANDLE *Handle,\r
- IN EVENT_RING *EvtRing\r
+ IN EVENT_RING *EvtRing\r
)\r
{\r
- UINTN Index;\r
- TRB_TEMPLATE *EvtTrb1;\r
+ UINTN Index;\r
+ TRB_TEMPLATE *EvtTrb1;\r
\r
ASSERT (EvtRing != NULL);\r
\r
// Calculate the EventRingEnqueue and EventRingCCS.\r
// Note: only support single Segment\r
//\r
- EvtTrb1 = (TRB_TEMPLATE *)(UINTN) EvtRing->EventRingDequeue;\r
+ EvtTrb1 = (TRB_TEMPLATE *)(UINTN)EvtRing->EventRingDequeue;\r
\r
for (Index = 0; Index < EvtRing->TrbNumber; Index++) {\r
if (EvtTrb1->CycleBit != EvtRing->EventRingCCS) {\r
\r
EvtTrb1++;\r
\r
- if ((UINTN)EvtTrb1 >= ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) {\r
- EvtTrb1 = (TRB_TEMPLATE *)(UINTN) EvtRing->EventRingSeg0;\r
+ if ((UINTN)EvtTrb1 >= ((UINTN)EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) {\r
+ EvtTrb1 = (TRB_TEMPLATE *)(UINTN)EvtRing->EventRingSeg0;\r
EvtRing->EventRingCCS = (EvtRing->EventRingCCS) ? 0 : 1;\r
}\r
}\r
EFI_STATUS\r
EFIAPI\r
XhcCheckNewEvent (\r
- IN USB3_DEBUG_PORT_HANDLE *Handle,\r
- IN EVENT_RING *EvtRing,\r
- OUT TRB_TEMPLATE **NewEvtTrb\r
+ IN USB3_DEBUG_PORT_HANDLE *Handle,\r
+ IN EVENT_RING *EvtRing,\r
+ OUT TRB_TEMPLATE **NewEvtTrb\r
)\r
{\r
- EFI_STATUS Status;\r
- TRB_TEMPLATE *EvtTrb;\r
+ EFI_STATUS Status;\r
\r
ASSERT (EvtRing != NULL);\r
\r
- EvtTrb = (TRB_TEMPLATE *)(UINTN) EvtRing->EventRingDequeue;\r
- *NewEvtTrb = (TRB_TEMPLATE *)(UINTN) EvtRing->EventRingDequeue;\r
+ *NewEvtTrb = (TRB_TEMPLATE *)(UINTN)EvtRing->EventRingDequeue;\r
\r
if (EvtRing->EventRingDequeue == EvtRing->EventRingEnqueue) {\r
return EFI_NOT_READY;\r
\r
EvtRing->EventRingDequeue += sizeof (TRB_TEMPLATE);\r
//\r
- // If the dequeue pointer is beyond the ring, then roll-back it to the begining of the ring.\r
+ // If the dequeue pointer is beyond the ring, then roll-back it to the beginning of the ring.\r
//\r
- if ((UINTN)EvtRing->EventRingDequeue >= ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) {\r
+ if ((UINTN)EvtRing->EventRingDequeue >= ((UINTN)EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) {\r
EvtRing->EventRingDequeue = EvtRing->EventRingSeg0;\r
}\r
\r
**/\r
BOOLEAN\r
IsTrbInTrsRing (\r
- IN TRANSFER_RING *Ring,\r
- IN TRB_TEMPLATE *Trb\r
+ IN TRANSFER_RING *Ring,\r
+ IN TRB_TEMPLATE *Trb\r
)\r
{\r
TRB_TEMPLATE *CheckedTrb;\r
UINTN Index;\r
- \r
- CheckedTrb = (TRB_TEMPLATE *)(UINTN) Ring->RingSeg0;\r
- \r
+\r
+ CheckedTrb = (TRB_TEMPLATE *)(UINTN)Ring->RingSeg0;\r
+\r
ASSERT (Ring->TrbNumber == TR_RING_TRB_NUMBER);\r
\r
for (Index = 0; Index < Ring->TrbNumber; Index++) {\r
if (Trb == CheckedTrb) {\r
return TRUE;\r
}\r
+\r
CheckedTrb++;\r
}\r
\r
**/\r
VOID\r
XhcCheckUrbResult (\r
- IN USB3_DEBUG_PORT_HANDLE *Handle,\r
- IN URB *Urb\r
+ IN USB3_DEBUG_PORT_HANDLE *Handle,\r
+ IN URB *Urb\r
)\r
{\r
- EVT_TRB_TRANSFER *EvtTrb;\r
- TRB_TEMPLATE *TRBPtr;\r
- UINTN Index;\r
- EFI_STATUS Status;\r
- URB *CheckedUrb;\r
- UINT64 XhcDequeue;\r
- UINT32 High;\r
- UINT32 Low;\r
- \r
+ EVT_TRB_TRANSFER *EvtTrb;\r
+ TRB_TEMPLATE *TRBPtr;\r
+ UINTN Index;\r
+ EFI_STATUS Status;\r
+ URB *CheckedUrb;\r
+ UINT64 XhcDequeue;\r
+ UINT32 High;\r
+ UINT32 Low;\r
+\r
ASSERT ((Handle != NULL) && (Urb != NULL));\r
\r
if (Urb->Finished) {\r
}\r
\r
EvtTrb = NULL;\r
- \r
+\r
//\r
// Traverse the event ring to find out all new events from the previous check.\r
//\r
XhcSyncEventRing (Handle, &Handle->EventRing);\r
- \r
- for (Index = 0; Index < Handle->EventRing.TrbNumber; Index++) {\r
\r
+ for (Index = 0; Index < Handle->EventRing.TrbNumber; Index++) {\r
Status = XhcCheckNewEvent (Handle, &Handle->EventRing, ((TRB_TEMPLATE **)&EvtTrb));\r
if (Status == EFI_NOT_READY) {\r
//\r
//\r
goto EXIT;\r
}\r
- \r
+\r
if ((EvtTrb->Type != TRB_TYPE_COMMAND_COMPLT_EVENT) && (EvtTrb->Type != TRB_TYPE_TRANS_EVENT)) {\r
continue;\r
}\r
- \r
- TRBPtr = (TRB_TEMPLATE *)(UINTN)(EvtTrb->TRBPtrLo | LShiftU64 ((UINT64) EvtTrb->TRBPtrHi, 32));\r
- \r
+\r
+ TRBPtr = (TRB_TEMPLATE *)(UINTN)(EvtTrb->TRBPtrLo | LShiftU64 ((UINT64)EvtTrb->TRBPtrHi, 32));\r
+\r
if (IsTrbInTrsRing ((TRANSFER_RING *)(UINTN)(Urb->Ring), TRBPtr)) {\r
CheckedUrb = Urb;\r
} else if (IsTrbInTrsRing ((TRANSFER_RING *)(UINTN)(Handle->UrbIn.Ring), TRBPtr)) {\r
// If it is read event and it should be generated by poll, and current operation is write, we need save data into internal buffer.\r
// Internal buffer is used by next read.\r
//\r
- Handle->DataCount = (UINT8) (Handle->UrbIn.DataLen - EvtTrb->Length);\r
+ Handle->DataCount = (UINT8)(Handle->UrbIn.DataLen - EvtTrb->Length);\r
CopyMem ((VOID *)(UINTN)Handle->Data, (VOID *)(UINTN)Handle->UrbIn.Data, Handle->DataCount);\r
//\r
// Fill this TRB complete with CycleBit, otherwise next read will fail with old TRB.\r
} else {\r
continue;\r
}\r
- \r
+\r
if ((EvtTrb->Completecode == TRB_COMPLETION_SHORT_PACKET) ||\r
- (EvtTrb->Completecode == TRB_COMPLETION_SUCCESS)) {\r
+ (EvtTrb->Completecode == TRB_COMPLETION_SUCCESS))\r
+ {\r
//\r
// The length of data which were transferred.\r
//\r
- CheckedUrb->Completed += (((TRANSFER_TRB_NORMAL*)TRBPtr)->Length - EvtTrb->Length);\r
+ CheckedUrb->Completed += (((TRANSFER_TRB_NORMAL *)TRBPtr)->Length - EvtTrb->Length);\r
} else {\r
- CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;\r
+ CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;\r
}\r
+\r
//\r
// This Urb has been processed\r
//\r
// Some 3rd party XHCI external cards don't support single 64-bytes width register access,\r
// So divide it to two 32-bytes width register access.\r
//\r
- Low = XhcReadDebugReg (Handle, XHC_DC_DCERDP);\r
- High = XhcReadDebugReg (Handle, XHC_DC_DCERDP + 4);\r
- XhcDequeue = (UINT64)(LShiftU64((UINT64)High, 32) | Low);\r
+ Low = XhcReadDebugReg (Handle, XHC_DC_DCERDP);\r
+ High = XhcReadDebugReg (Handle, XHC_DC_DCERDP + 4);\r
+ XhcDequeue = (UINT64)(LShiftU64 ((UINT64)High, 32) | Low);\r
\r
if ((XhcDequeue & (~0x0F)) != ((UINT64)(UINTN)Handle->EventRing.EventRingDequeue & (~0x0F))) {\r
//\r
EFI_STATUS\r
EFIAPI\r
XhcRingDoorBell (\r
- IN USB3_DEBUG_PORT_HANDLE *Handle,\r
- IN URB *Urb\r
+ IN USB3_DEBUG_PORT_HANDLE *Handle,\r
+ IN URB *Urb\r
)\r
{\r
- UINT32 Dcdb;\r
+ UINT32 Dcdb;\r
\r
//\r
// 7.6.8.2 DCDB Register\r
- // \r
+ //\r
Dcdb = (Urb->Direction == EfiUsbDataIn) ? 0x100 : 0x0;\r
- \r
+\r
XhcWriteDebugReg (\r
Handle,\r
XHC_DC_DCDB,\r
**/\r
VOID\r
XhcExecTransfer (\r
- IN USB3_DEBUG_PORT_HANDLE *Handle,\r
- IN URB *Urb,\r
- IN UINTN Timeout\r
+ IN USB3_DEBUG_PORT_HANDLE *Handle,\r
+ IN URB *Urb,\r
+ IN UINTN Timeout\r
)\r
{\r
- TRANSFER_RING *Ring;\r
- TRB_TEMPLATE *Trb;\r
- UINTN Loop;\r
- UINTN Index;\r
+ TRANSFER_RING *Ring;\r
+ TRB_TEMPLATE *Trb;\r
+ UINTN Loop;\r
+ UINTN Index;\r
\r
Loop = Timeout / XHC_DEBUG_PORT_1_MILLISECOND;\r
if (Timeout == 0) {\r
Loop = 0xFFFFFFFF;\r
}\r
+\r
XhcRingDoorBell (Handle, Urb);\r
//\r
// Event Ring Not Empty bit can only be set to 1 by XHC after ringing door bell with some delay.\r
if (Urb->Finished) {\r
break;\r
}\r
+\r
MicroSecondDelay (XHC_DEBUG_PORT_1_MILLISECOND);\r
}\r
+\r
if (Index == Loop) {\r
//\r
// If time out occurs.\r
//\r
Urb->Result |= EFI_USB_ERR_TIMEOUT;\r
- } \r
+ }\r
+\r
//\r
// If URB transfer is error, restore transfer ring to original value before URB transfer\r
// This will make the current transfer TRB is always at the latest unused one in transfer ring.\r
//\r
- Ring = (TRANSFER_RING *)(UINTN) Urb->Ring;\r
+ Ring = (TRANSFER_RING *)(UINTN)Urb->Ring;\r
if ((Urb->Result != EFI_USB_NOERROR) && (Urb->Direction == EfiUsbDataIn)) {\r
//\r
// Adjust Enqueue pointer\r
//\r
// Clear CCS flag for next use\r
//\r
- Trb = (TRB_TEMPLATE *)(UINTN) Urb->Trb;\r
+ Trb = (TRB_TEMPLATE *)(UINTN)Urb->Trb;\r
Trb->CycleBit = ((~Ring->RingPCS) & BIT0);\r
} else {\r
//\r
**/\r
EFI_STATUS\r
XhcCreateTransferTrb (\r
- IN USB3_DEBUG_PORT_HANDLE *Handle,\r
- IN URB *Urb\r
+ IN USB3_DEBUG_PORT_HANDLE *Handle,\r
+ IN URB *Urb\r
)\r
{\r
- TRANSFER_RING *EPRing;\r
- TRB *Trb;\r
+ TRANSFER_RING *EPRing;\r
+ TRB *Trb;\r
\r
if (Urb->Direction == EfiUsbDataIn) {\r
EPRing = &Handle->TransferRingIn;\r
} else {\r
EPRing = &Handle->TransferRingOut;\r
}\r
- \r
- Urb->Ring = (EFI_PHYSICAL_ADDRESS)(UINTN) EPRing;\r
+\r
+ Urb->Ring = (EFI_PHYSICAL_ADDRESS)(UINTN)EPRing;\r
XhcSyncTrsRing (Handle, EPRing);\r
\r
- Urb->Trb = EPRing->RingEnqueue;\r
- Trb = (TRB *)(UINTN)EPRing->RingEnqueue;\r
+ Urb->Trb = EPRing->RingEnqueue;\r
+ Trb = (TRB *)(UINTN)EPRing->RingEnqueue;\r
Trb->TrbNormal.TRBPtrLo = XHC_LOW_32BIT (Urb->Data);\r
Trb->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT (Urb->Data);\r
Trb->TrbNormal.Length = Urb->DataLen;\r
Trb->TrbNormal.ISP = 1;\r
Trb->TrbNormal.IOC = 1;\r
Trb->TrbNormal.Type = TRB_TYPE_NORMAL;\r
- \r
+\r
//\r
// Update the cycle bit to indicate this TRB has been consumed.\r
//\r
Trb->TrbNormal.CycleBit = EPRing->RingPCS & BIT0;\r
- \r
+\r
return EFI_SUCCESS;\r
}\r
\r
@return Created URB or NULL\r
\r
**/\r
-URB*\r
+URB *\r
XhcCreateUrb (\r
- IN USB3_DEBUG_PORT_HANDLE *Handle,\r
- IN EFI_USB_DATA_DIRECTION Direction,\r
- IN VOID *Data,\r
- IN UINTN DataLen\r
+ IN USB3_DEBUG_PORT_HANDLE *Handle,\r
+ IN EFI_USB_DATA_DIRECTION Direction,\r
+ IN VOID *Data,\r
+ IN UINTN DataLen\r
)\r
{\r
- EFI_STATUS Status;\r
- URB *Urb;\r
- EFI_PHYSICAL_ADDRESS UrbData;\r
- \r
+ EFI_STATUS Status;\r
+ URB *Urb;\r
+ EFI_PHYSICAL_ADDRESS UrbData;\r
+\r
if (Direction == EfiUsbDataIn) {\r
Urb = &Handle->UrbIn;\r
} else {\r
Urb = &Handle->UrbOut;\r
}\r
\r
- UrbData = Urb->Data;\r
- \r
+ UrbData = Urb->Data;\r
+\r
ZeroMem (Urb, sizeof (URB));\r
Urb->Direction = Direction;\r
- \r
+\r
//\r
// Allocate memory to move data from CAR or SMRAM to normal memory\r
// to make XHCI DMA successfully\r
// re-use the pre-allocate buffer in PEI to avoid DXE memory service or gBS are not ready\r
//\r
- Urb->Data = UrbData;\r
- \r
+ Urb->Data = UrbData;\r
+\r
if (Direction == EfiUsbDataIn) {\r
//\r
// Do not break URB data in buffer as it may contain the data which were just put in via DMA by XHC\r
//\r
- Urb->DataLen = (UINT32) DataLen;\r
+ Urb->DataLen = (UINT32)DataLen;\r
} else {\r
//\r
// Put data into URB data out buffer which will create TRBs\r
//\r
- ZeroMem ((VOID*)(UINTN) Urb->Data, DataLen);\r
- CopyMem ((VOID*)(UINTN) Urb->Data, Data, DataLen);\r
- Urb->DataLen = (UINT32) DataLen;\r
+ ZeroMem ((VOID *)(UINTN)Urb->Data, DataLen);\r
+ CopyMem ((VOID *)(UINTN)Urb->Data, Data, DataLen);\r
+ Urb->DataLen = (UINT32)DataLen;\r
}\r
- \r
+\r
Status = XhcCreateTransferTrb (Handle, Urb);\r
ASSERT_EFI_ERROR (Status);\r
\r
@param Direction The direction of data transfer.\r
@param Data Array of pointers to the buffers of data to transmit\r
from or receive into.\r
- @param DataLength The lenght of the data buffer.\r
+ @param DataLength The length of the data buffer.\r
@param Timeout Indicates the maximum time, in microsecond, which\r
the transfer is allowed to complete.\r
\r
EFI_STATUS\r
EFIAPI\r
XhcDataTransfer (\r
- IN USB3_DEBUG_PORT_HANDLE *Handle,\r
- IN EFI_USB_DATA_DIRECTION Direction,\r
- IN OUT VOID *Data,\r
- IN OUT UINTN *DataLength,\r
- IN UINTN Timeout\r
+ IN USB3_DEBUG_PORT_HANDLE *Handle,\r
+ IN EFI_USB_DATA_DIRECTION Direction,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN UINTN Timeout\r
)\r
{\r
- URB *Urb;\r
- EFI_STATUS Status;\r
- \r
+ URB *Urb;\r
+ EFI_STATUS Status;\r
+\r
//\r
// Validate the parameters\r
//\r
\r
XhcExecTransfer (Handle, Urb, Timeout);\r
\r
- *DataLength = Urb->Completed;\r
+ //\r
+ // Make sure the data received from HW can fit in the received buffer.\r
+ //\r
+ if (Urb->Completed > *DataLength) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ *DataLength = Urb->Completed;\r
\r
Status = EFI_TIMEOUT;\r
if (Urb->Result == EFI_USB_NOERROR) {\r
Status = EFI_SUCCESS;\r
}\r
- \r
+\r
if (Direction == EfiUsbDataIn) {\r
//\r
// Move data from internal buffer to outside buffer (outside buffer may be in SMRAM...)\r
\r
return Status;\r
}\r
-\r