23#define OUTPUT_PID 0xE1
34#define PCI_CAPABILITY_ID_DEBUG_PORT 0x0A
35#define USB_DEBUG_PORT_MAX_PACKET_SIZE 0x08
37#define USB_DEBUG_PORT_IN_USE BIT10
38#define USB_DEBUG_PORT_ENABLE BIT28
39#define USB_DEBUG_PORT_OWNER BIT30
41#define USB_PORT_LINE_STATUS_LS 0x400
42#define USB_PORT_LINE_STATUS_MASK 0xC00
51 UINT8 DebugInEndpoint;
52 UINT8 DebugOutEndpoint;
57 USB_REQ_GET_DESCRIPTOR,
99#define USBDBG_NO_DEV 0
100#define USBDBG_NO_DBG_CAB 1
101#define USBDBG_DBG_CAB 2
102#define USBDBG_INIT_DONE 4
103#define USBDBG_RESET 8
114 UINT8 DebugPortBarNumber;
119 UINT16 DebugPortOffset;
123 UINT32 UsbDebugPortMemoryBase;
127 UINT32 EhciMemoryBase;
173 OUT UINT16 *DebugPortOffset,
174 OUT UINT8 *DebugPortBarNumbar
189 if ((VendorId == 0xFFFF) || (DeviceId == 0xFFFF)) {
193 ProgInterface =
PciRead8 (
PcdGet32 (PcdUsbEhciPciAddress) + PCI_CLASSCODE_OFFSET);
194 SubClassCode =
PciRead8 (
PcdGet32 (PcdUsbEhciPciAddress) + PCI_CLASSCODE_OFFSET + 1);
195 BaseCode =
PciRead8 (
PcdGet32 (PcdUsbEhciPciAddress) + PCI_CLASSCODE_OFFSET + 2);
197 if ((ProgInterface !=
PCI_IF_EHCI) || (SubClassCode != PCI_CLASS_SERIAL_USB) || (BaseCode != PCI_CLASS_SERIAL)) {
204 PciStatus =
PciRead16 (
PcdGet32 (PcdUsbEhciPciAddress) + PCI_PRIMARY_STATUS_OFFSET);
216 CapabilityPtr =
PciRead8 (
PcdGet32 (PcdUsbEhciPciAddress) + PCI_CAPBILITY_POINTER_OFFSET);
221 while (CapabilityPtr != 0) {
223 if (CapabilityId == PCI_CAPABILITY_ID_DEBUG_PORT) {
227 CapabilityPtr =
PciRead8 (
PcdGet32 (PcdUsbEhciPciAddress) + CapabilityPtr + 1);
233 if (CapabilityPtr == 0) {
240 *DebugPortOffset = (UINT16)(
PciRead16 (
PcdGet32 (PcdUsbEhciPciAddress) + CapabilityPtr + 2) & 0x1FFF);
241 *DebugPortBarNumbar = (UINT8)((
PciRead16 (
PcdGet32 (PcdUsbEhciPciAddress) + CapabilityPtr + 2) >> 13) - 1);
266 IN OUT UINT8 *Buffer,
276 if (Length ==
NULL) {
282 DebugPortRegister->TokenPid = Token;
283 if (DataToggle != 0) {
284 DebugPortRegister->SendPid = DATA1_PID;
286 DebugPortRegister->SendPid = DATA0_PID;
289 DebugPortRegister->UsbAddress = (UINT8)(Addr & 0x7F);
290 DebugPortRegister->UsbEndPoint = (UINT8)(Ep & 0xF);
295 MmioAnd32 ((
UINTN)&DebugPortRegister->ControlStatus, (UINT32) ~BIT4);
300 MmioOr32 ((
UINTN)&DebugPortRegister->ControlStatus, (UINT32)BIT5);
305 while ((
MmioRead32 ((
UINTN)&DebugPortRegister->ControlStatus) & (UINT32)BIT16) == 0) {
306 if ((
MmioRead32 ((
UINTN)&DebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE))
307 != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE))
328 if (((
MmioRead32 ((
UINTN)&DebugPortRegister->ControlStatus)) & 0xF) > USB_DEBUG_PORT_MAX_PACKET_SIZE) {
332 *Length = (UINT8)(
MmioRead32 ((
UINTN)&DebugPortRegister->ControlStatus) & 0xF);
337 for (Index = 0; Index < *Length; Index++) {
338 Buffer[Index] = DebugPortRegister->DataBuffer[Index];
378 DebugPortRegister->TokenPid = Token;
379 if (DataToggle != 0) {
380 DebugPortRegister->SendPid = DATA1_PID;
382 DebugPortRegister->SendPid = DATA0_PID;
385 DebugPortRegister->UsbAddress = (UINT8)(Addr & 0x7F);
386 DebugPortRegister->UsbEndPoint = (UINT8)(Ep & 0xF);
391 MmioAnd32 ((
UINTN)&DebugPortRegister->ControlStatus, (UINT32) ~0xF);
392 MmioOr32 ((
UINTN)&DebugPortRegister->ControlStatus, Length & 0xF);
393 for (Index = 0; Index < Length; Index++) {
394 DebugPortRegister->DataBuffer[Index] = Buffer[Index];
409 while ((
MmioRead32 ((
UINTN)&DebugPortRegister->ControlStatus) & BIT16) == 0) {
410 if ((
MmioRead32 ((
UINTN)&DebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE))
411 != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE))
432 if (((
MmioRead32 ((
UINTN)&DebugPortRegister->ControlStatus)) & 0xF) > USB_DEBUG_PORT_MAX_PACKET_SIZE) {
462 IN OUT UINT8 *DataLength
465 RETURN_STATUS Status;
467 UINT8 ReturnStatus[8];
480 if (DataLength != 0) {
481 if ((SetupPacket->RequestType & BIT7) != 0) {
485 Status =
UsbDebugPortIn (DebugPortRegister, Data, DataLength, INPUT_PID, Addr, Ep, 1);
493 Status =
UsbDebugPortOut (DebugPortRegister, Data, *DataLength, OUTPUT_PID, Addr, Ep, 1);
503 if ((SetupPacket->RequestType & BIT7) != 0) {
512 Status =
UsbDebugPortIn (DebugPortRegister, ReturnStatus, &Temp, INPUT_PID, Addr, Ep, 1);
538 UINT32 UsbDebugPortMemoryBase;
539 UINT32 EhciMemoryBase;
545 EhciMemoryBase = 0xFFFFFC00 &
PciRead32 (
PcdGet32 (PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET);
546 if (EhciMemoryBase != Handle->EhciMemoryBase) {
547 Handle->EhciMemoryBase = EhciMemoryBase;
551 UsbDebugPortMemoryBase = 0xFFFFFC00 &
PciRead32 (
PcdGet32 (PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET + Handle->DebugPortBarNumber * 4);
552 if (UsbDebugPortMemoryBase != Handle->UsbDebugPortMemoryBase) {
553 Handle->UsbDebugPortMemoryBase = UsbDebugPortMemoryBase;
571 if ((
MmioRead32 ((
UINTN)&UsbDebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_ENABLE | USB_DEBUG_PORT_IN_USE))
572 != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_ENABLE | USB_DEBUG_PORT_IN_USE))
577 if (Handle->Initialized == USBDBG_RESET) {
579 }
else if (Handle->Initialized != USBDBG_INIT_DONE) {
607 RETURN_STATUS Status;
614 UINT8 DebugPortNumber;
618 UsbHCSParam = (UINT32 *)((
UINTN)Handle->EhciMemoryBase + 0x04);
619 UsbCmd = (UINT32 *)((
UINTN)Handle->EhciMemoryBase + 0x20);
620 UsbStatus = (UINT32 *)((
UINTN)Handle->EhciMemoryBase + 0x24);
625 if (((
MmioRead32 ((
UINTN)&UsbDebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE))
626 != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE)) || (Handle->Initialized == USBDBG_RESET))
630 "UsbDbg: Need to reset the host controller. ControlStatus = %08x\n",
637 DEBUG ((DEBUG_INFO,
"UsbDbg: Reset the host controller.\n"));
657 MmioOr32 ((
UINTN)&UsbDebugPortRegister->ControlStatus, USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE);
665 DebugPortNumber = (UINT8)((
MmioRead32 ((
UINTN)UsbHCSParam) & 0x00F00000) >> 20);
669 PortStatus = (UINT32 *)((
UINTN)Handle->EhciMemoryBase + 0x64 + (DebugPortNumber - 1) * 4);
671 Handle->Initialized = USBDBG_NO_DEV;
675 if ((Handle->Initialized != USBDBG_INIT_DONE) ||
676 ((
MmioRead32 ((
UINTN)&UsbDebugPortRegister->ControlStatus) & USB_DEBUG_PORT_ENABLE) == 0))
678 DEBUG ((DEBUG_INFO,
"UsbDbg: Reset the debug port.\n"));
692 Handle->Initialized = USBDBG_NO_DBG_CAB;
699 MmioOr32 ((
UINTN)&UsbDebugPortRegister->ControlStatus, USB_DEBUG_PORT_ENABLE);
704 Handle->BulkInToggle = 0;
705 Handle->BulkOutToggle = 0;
715 Handle->Initialized = USBDBG_NO_DBG_CAB;
727 Status =
UsbDebugPortControlTransfer (UsbDebugPortRegister, &mDebugCommunicationLibUsbGetDebugDescriptor, 0x7F, 0x0, (UINT8 *)&UsbDebugPortDescriptor, &Length);
732 Handle->Initialized = USBDBG_NO_DBG_CAB;
737 Handle->Initialized = USBDBG_NO_DBG_CAB;
744 Handle->InEndpoint = UsbDebugPortDescriptor.DebugInEndpoint;
745 Handle->OutEndpoint = UsbDebugPortDescriptor.DebugOutEndpoint;
755 Handle->Initialized = USBDBG_NO_DBG_CAB;
759 Handle->Initialized = USBDBG_DBG_CAB;
765 Handle->Initialized = USBDBG_INIT_DONE;
790 IN DEBUG_PORT_HANDLE Handle,
797 RETURN_STATUS Status;
800 if ((NumberOfBytes != 1) || (Buffer ==
NULL) || (Timeout != 0)) {
808 if (Handle ==
NULL) {
809 UsbDebugPortHandle = &mDebugCommunicationLibUsbDebugPortHandle;
824 if (UsbDebugPortHandle->DataCount < 1) {
827 *Buffer = UsbDebugPortHandle->Data[0];
828 for (Index = 0; Index < UsbDebugPortHandle->DataCount - 1; Index++) {
829 if ((Index + 1) >= USB_DEBUG_PORT_MAX_PACKET_SIZE) {
833 UsbDebugPortHandle->Data[Index] = UsbDebugPortHandle->Data[Index + 1];
836 UsbDebugPortHandle->DataCount = (UINT8)(UsbDebugPortHandle->DataCount - 1);
861 IN DEBUG_PORT_HANDLE Handle,
868 RETURN_STATUS Status;
873 if ((NumberOfBytes == 0) || (Buffer ==
NULL)) {
884 if (Handle ==
NULL) {
885 UsbDebugPortHandle = &mDebugCommunicationLibUsbDebugPortHandle;
897 UsbDebugPortRegister = (
USB_DEBUG_PORT_REGISTER *)((
UINTN)UsbDebugPortHandle->UsbDebugPortMemoryBase + UsbDebugPortHandle->DebugPortOffset);
899 while ((Total < NumberOfBytes)) {
900 if (NumberOfBytes - Total > USB_DEBUG_PORT_MAX_PACKET_SIZE) {
901 Sent = USB_DEBUG_PORT_MAX_PACKET_SIZE;
903 Sent = (UINT8)(NumberOfBytes - Total);
906 Status =
UsbDebugPortOut (UsbDebugPortRegister, Buffer + Total, Sent, OUTPUT_PID, 0x7F, UsbDebugPortHandle->OutEndpoint, UsbDebugPortHandle->BulkOutToggle);
912 ReceivedPid = (
MmioRead8 ((
UINTN)&UsbDebugPortRegister->ReceivedPid));
917 if (ReceivedPid == NAK_PID) {
920 UsbDebugPortHandle->BulkOutToggle ^= 1;
945 IN DEBUG_PORT_HANDLE Handle
952 RETURN_STATUS Status;
958 if (Handle ==
NULL) {
959 UsbDebugPortHandle = &mDebugCommunicationLibUsbDebugPortHandle;
975 if (UsbDebugPortHandle->DataCount != 0) {
979 UsbDebugPortRegister = (
USB_DEBUG_PORT_REGISTER *)((
UINTN)UsbDebugPortHandle->UsbDebugPortMemoryBase + UsbDebugPortHandle->DebugPortOffset);
981 UsbDebugPortRegister->TokenPid = INPUT_PID;
982 if (UsbDebugPortHandle->BulkInToggle == 0) {
983 UsbDebugPortRegister->SendPid = DATA0_PID;
985 UsbDebugPortRegister->SendPid = DATA1_PID;
988 UsbDebugPortRegister->UsbAddress = 0x7F;
989 UsbDebugPortRegister->UsbEndPoint = UsbDebugPortHandle->InEndpoint & 0x0F;
994 MmioAnd32 ((
UINTN)&UsbDebugPortRegister->ControlStatus, (UINT32) ~BIT4);
998 MmioOr32 ((
UINTN)&UsbDebugPortRegister->ControlStatus, (UINT32)BIT5);
1003 while ((
MmioRead32 ((
UINTN)&UsbDebugPortRegister->ControlStatus) & (UINT32)BIT16) == 0) {
1004 if ((
MmioRead32 ((
UINTN)&UsbDebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE))
1005 != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE))
1011 if ((
MmioRead32 ((
UINTN)&UsbDebugPortRegister->ControlStatus)) & BIT6) {
1015 Length = (UINT8)(
MmioRead32 ((
UINTN)&UsbDebugPortRegister->ControlStatus) & 0xF);
1021 UsbDebugPortHandle->BulkInToggle ^= 1;
1027 for (Index = 0; Index < Length; Index++) {
1028 UsbDebugPortHandle->Data[Index] = UsbDebugPortRegister->DataBuffer[Index];
1031 UsbDebugPortHandle->DataCount = Length;
1067 RETURN_STATUS Status;
1075 if ((Function ==
NULL) && (Context !=
NULL)) {
1076 return (DEBUG_PORT_HANDLE *)Context;
1083 DEBUG ((DEBUG_ERROR,
"UsbDbg: the pci device pointed by PcdUsbEhciPciAddress is not EHCI host controller or does not support debug port capability!\n"));
1087 Handle.EhciMemoryBase = 0xFFFFFC00 &
PciRead32 (
PcdGet32 (PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET);
1089 if (Handle.EhciMemoryBase == 0) {
1094 Handle.EhciMemoryBase = 0xFFFFFC00 &
PciRead32 (
PcdGet32 (PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET);
1097 Handle.UsbDebugPortMemoryBase = 0xFFFFFC00 &
PciRead32 (
PcdGet32 (PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET + Handle.DebugPortBarNumber * 4);
1099 if (Handle.UsbDebugPortMemoryBase == 0) {
1103 PciWrite32 (
PcdGet32 (PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET + Handle.DebugPortBarNumber * 4,
PcdGet32 (PcdUsbDebugPortMemorySpaceBase));
1104 Handle.UsbDebugPortMemoryBase = 0xFFFFFC00 &
PciRead32 (
PcdGet32 (PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET + Handle.DebugPortBarNumber * 4);
1107 Handle.Initialized = USBDBG_RESET;
1110 DEBUG ((DEBUG_ERROR,
"UsbDbg: Start EHCI debug port initialization!\n"));
1113 DEBUG ((DEBUG_ERROR,
"UsbDbg: Failed, please check if USB debug cable is plugged into EHCI debug port correctly!\n"));
1120 if (Function !=
NULL) {
1121 Function (Context, &Handle);
1126 return (DEBUG_PORT_HANDLE)(
UINTN)&mDebugCommunicationLibUsbDebugPortHandle;
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID(EFIAPI * DEBUG_PORT_CONTINUE)(IN VOID *Context, IN DEBUG_PORT_HANDLE DebugPortHandle)
RETURN_STATUS EFIAPI CalculateUsbDebugPortBar(OUT UINT16 *DebugPortOffset, OUT UINT8 *DebugPortBarNumbar)
RETURN_STATUS EFIAPI InitializeUsbDebugHardware(IN USB_DEBUG_PORT_HANDLE *Handle)
BOOLEAN EFIAPI NeedReinitializeHardware(IN USB_DEBUG_PORT_HANDLE *Handle)
DEBUG_PORT_HANDLE EFIAPI DebugPortInitialize(IN VOID *Context, IN DEBUG_PORT_CONTINUE Function)
UINTN EFIAPI DebugPortReadBuffer(IN DEBUG_PORT_HANDLE Handle, IN UINT8 *Buffer, IN UINTN NumberOfBytes, IN UINTN Timeout)
RETURN_STATUS EFIAPI UsbDebugPortOut(IN USB_DEBUG_PORT_REGISTER *DebugPortRegister, IN UINT8 *Buffer, IN UINT8 Length, IN UINT8 Token, IN UINT8 Addr, IN UINT8 Ep, IN UINT8 DataToggle)
BOOLEAN EFIAPI DebugPortPollBuffer(IN DEBUG_PORT_HANDLE Handle)
RETURN_STATUS EFIAPI UsbDebugPortIn(IN USB_DEBUG_PORT_REGISTER *DebugPortRegister, IN OUT UINT8 *Buffer, OUT UINT8 *Length, IN UINT8 Token, IN UINT8 Addr, IN UINT8 Ep, IN UINT8 DataToggle)
RETURN_STATUS EFIAPI UsbDebugPortControlTransfer(IN USB_DEBUG_PORT_REGISTER *DebugPortRegister, IN USB_DEVICE_REQUEST *SetupPacket, IN UINT8 Addr, IN UINT8 Ep, OUT UINT8 *Data, IN OUT UINT8 *DataLength)
UINTN EFIAPI DebugPortWriteBuffer(IN DEBUG_PORT_HANDLE Handle, IN UINT8 *Buffer, IN UINTN NumberOfBytes)
UINT32 EFIAPI MmioAnd32(IN UINTN Address, IN UINT32 AndData)
UINT32 EFIAPI MmioOr32(IN UINTN Address, IN UINT32 OrData)
UINT8 EFIAPI MmioRead8(IN UINTN Address)
UINT32 EFIAPI MmioRead32(IN UINTN Address)
#define RETURN_ERROR(StatusCode)
#define RETURN_DEVICE_ERROR
#define RETURN_UNSUPPORTED
#define RETURN_INVALID_PARAMETER
#define DEBUG(Expression)
UINT32 EFIAPI PciRead32(IN UINTN Address)
UINT8 EFIAPI PciRead8(IN UINTN Address)
UINT32 EFIAPI PciWrite32(IN UINTN Address, IN UINT32 Value)
UINT16 EFIAPI PciWrite16(IN UINTN Address, IN UINT16 Value)
UINT16 EFIAPI PciRead16(IN UINTN Address)
#define PcdGet16(TokenName)
#define PcdGet32(TokenName)
#define EFI_PCI_COMMAND_MEMORY_SPACE
0x0002
#define EFI_PCI_COMMAND_BUS_MASTER
0x0004
#define EFI_PCI_STATUS_CAPABILITY
0x0010
VOID EFIAPI Exit(IN EFI_STATUS Status)