UINT8 Reserved3;\r
}USB_DEBUG_PORT_REGISTER;\r
\r
+//\r
+// The state machine of usb debug port\r
+//\r
+#define USBDBG_NO_DEV 0 // No device present at debug port\r
+#define USBDBG_NO_DBG_CAB 1 // The device attached is not usb debug cable\r
+#define USBDBG_DBG_CAB 2 // The device attached is usb debug cable\r
+#define USBDBG_INIT_DONE 4 // The usb debug cable device is initialized\r
+#define USBDBG_RESET 8 // The system is reset\r
+\r
#pragma pack(1)\r
//\r
// The internal data structure of DEBUG_PORT_HANDLE, which stores some\r
// The usb debug port memory BAR number in EHCI configuration space.\r
//\r
UINT8 DebugPortBarNumber;\r
- BOOLEAN Initialized;\r
+ UINT8 Initialized;\r
//\r
// The offset of usb debug port registers in EHCI memory range.\r
//\r
//\r
// The usb debug port memory BAR address.\r
//\r
- UINTN UsbDebugPortMemoryBase;\r
+ UINT32 UsbDebugPortMemoryBase;\r
//\r
// The EHCI memory BAR address.\r
//\r
- UINTN EhciMemoryBase;\r
+ UINT32 EhciMemoryBase;\r
//\r
// The Bulk In endpoint toggle bit.\r
//\r
//\r
// Wait for completing the request\r
//\r
- while ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & (UINT32)BIT16) == 0);\r
+ while ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & (UINT32)BIT16) == 0) {\r
+ if ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE))\r
+ != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE)) {\r
+ return RETURN_DEVICE_ERROR;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Clearing DONE bit by writing 1\r
+ //\r
+ MmioOr32((UINTN)&DebugPortRegister->ControlStatus, BIT16);\r
\r
//\r
// Check if the request is executed successfully or not.\r
//\r
// Wait for completing the request\r
//\r
- while ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & BIT16) == 0);\r
+ while ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & BIT16) == 0) {\r
+ if ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE))\r
+ != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE)) {\r
+ return RETURN_DEVICE_ERROR;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Clearing DONE bit by writing 1\r
+ //\r
+ MmioOr32((UINTN)&DebugPortRegister->ControlStatus, BIT16);\r
\r
//\r
// Check if the request is executed successfully or not.\r
)\r
{\r
UINT16 PciCmd;\r
- UINTN UsbDebugPortMemoryBase;\r
- UINTN EhciMemoryBase;\r
+ UINT32 UsbDebugPortMemoryBase;\r
+ UINT32 EhciMemoryBase;\r
BOOLEAN Status;\r
USB_DEBUG_PORT_REGISTER *UsbDebugPortRegister;\r
\r
//\r
PciCmd = PciRead16 (PcdGet32(PcdUsbEhciPciAddress) + PCI_COMMAND_OFFSET);\r
if (((PciCmd & EFI_PCI_COMMAND_MEMORY_SPACE) == 0) || ((PciCmd & EFI_PCI_COMMAND_BUS_MASTER) == 0)) {\r
+ PciCmd |= EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER;\r
+ PciWrite16(PcdGet32(PcdUsbEhciPciAddress) + PCI_COMMAND_OFFSET, PciCmd);\r
Status = TRUE;\r
}\r
\r
//\r
- // Check if the debug port is enabled and owned by myself.\r
+ // If the owner and in_use bit is not set, it means system is doing cold/warm boot or EHCI host controller is reset by system software.\r
//\r
- UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(Handle->UsbDebugPortMemoryBase + Handle->DebugPortOffset);\r
- if ((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) &\r
- (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_ENABLE | USB_DEBUG_PORT_IN_USE)) == 0) {\r
+ UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UINTN)(Handle->UsbDebugPortMemoryBase + Handle->DebugPortOffset);\r
+ if ((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_ENABLE | USB_DEBUG_PORT_IN_USE))\r
+ != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_ENABLE | USB_DEBUG_PORT_IN_USE)) {\r
+ Status = TRUE;\r
+ }\r
+\r
+ if (Handle->Initialized == USBDBG_RESET) {\r
+ Status = TRUE;\r
+ } else if (Handle->Initialized != USBDBG_INIT_DONE) {\r
Status = TRUE;\r
}\r
return Status;\r
UINT8 DebugPortNumber;\r
UINT8 Length;\r
\r
- UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(Handle->UsbDebugPortMemoryBase + Handle->DebugPortOffset);\r
+ UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UINTN)(Handle->UsbDebugPortMemoryBase + Handle->DebugPortOffset);\r
PciCmd = PciRead16 (PcdGet32(PcdUsbEhciPciAddress) + PCI_COMMAND_OFFSET);\r
- UsbHCSParam = (UINT32 *)(Handle->EhciMemoryBase + 0x04);\r
- UsbCmd = (UINT32 *)(Handle->EhciMemoryBase + 0x20);\r
- UsbStatus = (UINT32 *)(Handle->EhciMemoryBase + 0x24);\r
+ UsbHCSParam = (UINT32 *)(UINTN)(Handle->EhciMemoryBase + 0x04);\r
+ UsbCmd = (UINT32 *)(UINTN)(Handle->EhciMemoryBase + 0x20);\r
+ UsbStatus = (UINT32 *)(UINTN)(Handle->EhciMemoryBase + 0x24);\r
\r
//\r
- // initialize the data toggle used by bulk in/out endpoint.\r
+ // Check if the debug port is enabled and owned by myself.\r
//\r
- Handle->BulkInToggle = 0;\r
- Handle->BulkOutToggle = 0;\r
+ if (((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE))\r
+ != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE)) || (Handle->Initialized == USBDBG_RESET)) {\r
+ //\r
+ // If the host controller is not halted, then halt it.\r
+ //\r
+ if ((MmioRead32((UINTN)UsbStatus) & BIT12) == 0) {\r
+ MmioAnd32((UINTN)UsbCmd, (UINT32)~BIT0);\r
+ while ((MmioRead32((UINTN)UsbStatus) & BIT12) == 0);\r
+ }\r
+ //\r
+ // reset the host controller.\r
+ //\r
+ MmioOr32((UINTN)UsbCmd, BIT1);\r
+ //\r
+ // ensure that the host controller is reset.\r
+ //\r
+ while (MmioRead32((UINTN)UsbCmd) & BIT1);\r
\r
- //\r
- // Enable Ehci Memory Space Access\r
- //\r
- if (((PciCmd & EFI_PCI_COMMAND_MEMORY_SPACE) == 0) || ((PciCmd & EFI_PCI_COMMAND_BUS_MASTER) == 0)) {\r
- PciCmd |= EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER;\r
- PciWrite16(PcdGet32(PcdUsbEhciPciAddress) + PCI_COMMAND_OFFSET, PciCmd);\r
- }\r
+ //\r
+ // Start the host controller if it's not running\r
+ //\r
+ if (MmioRead32((UINTN)UsbStatus) & BIT12) {\r
+ MmioOr32((UINTN)UsbCmd, BIT0);\r
+ // ensure that the host controller is started (HALTED bit must be cleared)\r
+ while (MmioRead32((UINTN)UsbStatus) & BIT12);\r
+ }\r
\r
- //\r
- // If the host controller is not halted, then halt it.\r
- //\r
- if ((MmioRead32((UINTN)UsbStatus) & BIT12) == 0) {\r
- MmioAnd32((UINTN)UsbCmd, (UINT32)~BIT0);\r
- while ((MmioRead32((UINTN)UsbStatus) & BIT12) == 0);\r
- }\r
- //\r
- // reset the host controller.\r
- //\r
- MmioOr32((UINTN)UsbCmd, BIT1);\r
- //\r
- // ensure that the host controller is reset.\r
- //\r
- while (MmioRead32((UINTN)UsbCmd) & BIT1);\r
+ //\r
+ // First get the ownership of port 0.\r
+ //\r
+ MmioOr32((UINTN)&UsbDebugPortRegister->ControlStatus, USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE);\r
\r
- //\r
- // Start the host controller if it's not running\r
- //\r
- if (MmioRead32((UINTN)UsbStatus) & BIT12) {\r
- MmioOr32((UINTN)UsbCmd, BIT0);\r
- // ensure that the host controller is started (HALTED bit must be cleared)\r
- while (MmioRead32((UINTN)UsbStatus) & BIT12);\r
+ MicroSecondDelay (200000);\r
}\r
-\r
- //\r
- // First get the ownership of port 0.\r
- //\r
- MmioOr32((UINTN)&UsbDebugPortRegister->ControlStatus, USB_DEBUG_PORT_OWNER);\r
-\r
- MicroSecondDelay (200000);\r
-\r
//\r
// Find out which port is used as debug port.\r
//\r
DebugPortNumber = (UINT8)((MmioRead32((UINTN)UsbHCSParam) & 0x00F00000) >> 20);\r
//\r
- // Should find a non low-speed device is connected\r
+ // Should find a device is connected at debug port\r
//\r
- PortStatus = (UINT32 *)(Handle->EhciMemoryBase + 0x64 + (DebugPortNumber - 1) * 4);\r
- if (!(MmioRead32((UINTN)PortStatus) & BIT0) || ((MmioRead32((UINTN)PortStatus) & USB_PORT_LINE_STATUS_MASK) == USB_PORT_LINE_STATUS_LS)) {\r
+ PortStatus = (UINT32 *)(UINTN)(Handle->EhciMemoryBase + 0x64 + (DebugPortNumber - 1) * 4);\r
+ if (!(MmioRead32((UINTN)PortStatus) & BIT0)) {\r
+ Handle->Initialized = USBDBG_NO_DEV;\r
return RETURN_NOT_FOUND;\r
}\r
\r
- //\r
- // Reset the debug port\r
- //\r
- MmioOr32((UINTN)PortStatus, BIT8);\r
- MicroSecondDelay (200000);\r
- MmioAnd32((UINTN)PortStatus, (UINT32)~BIT8);\r
- while (MmioRead32((UINTN)PortStatus) & BIT8);\r
+ if (Handle->Initialized != USBDBG_INIT_DONE) {\r
+ //\r
+ // Reset the debug port\r
+ //\r
+ MmioOr32((UINTN)PortStatus, BIT8);\r
+ MicroSecondDelay (500000);\r
+ MmioAnd32((UINTN)PortStatus, (UINT32)~BIT8);\r
+ while (MmioRead32((UINTN)PortStatus) & BIT8);\r
\r
- //\r
- // The port enabled bit should be set by HW.\r
- //\r
- if ((MmioRead32((UINTN)PortStatus) & BIT2) == 0) {\r
- return RETURN_DEVICE_ERROR;\r
- }\r
+ //\r
+ // The port enabled bit should be set by HW.\r
+ //\r
+ if ((MmioRead32((UINTN)PortStatus) & BIT2) == 0) {\r
+ Handle->Initialized = USBDBG_NO_DBG_CAB;\r
+ return RETURN_DEVICE_ERROR;\r
+ }\r
\r
- //\r
- // Enable Usb Debug Port Capability\r
- //\r
- MmioOr32((UINTN)&UsbDebugPortRegister->ControlStatus, USB_DEBUG_PORT_ENABLE | USB_DEBUG_PORT_IN_USE);\r
+ //\r
+ // Enable Usb Debug Port Capability\r
+ //\r
+ MmioOr32((UINTN)&UsbDebugPortRegister->ControlStatus, USB_DEBUG_PORT_ENABLE);\r
\r
- //\r
- // Start to communicate with Usb Debug Device to see if the attached device is usb debug device or not.\r
- //\r
- Length = (UINT8)sizeof (USB_DEBUG_PORT_DESCRIPTOR);\r
+ //\r
+ // initialize the data toggle used by bulk in/out endpoint.\r
+ //\r
+ Handle->BulkInToggle = 0;\r
+ Handle->BulkOutToggle = 0;\r
\r
- //\r
- // It's not a dedicated usb debug device, should use address 0 to get debug descriptor.\r
- //\r
- Status = UsbDebugPortControlTransfer (UsbDebugPortRegister, &mGetDebugDescriptor, 0x0, 0x0, (UINT8*)&UsbDebugPortDescriptor, &Length);\r
- if (RETURN_ERROR(Status)) {\r
//\r
- // The device is not a usb debug device.\r
+ // set usb debug device address as 0x7F.\r
//\r
- return Status;\r
- }\r
+ Status = UsbDebugPortControlTransfer (UsbDebugPortRegister, &mSetDebugAddress, 0x0, 0x0, NULL, NULL);\r
+ if (RETURN_ERROR(Status)) {\r
+ //\r
+ // The device can not work well.\r
+ //\r
+ Handle->Initialized = USBDBG_NO_DBG_CAB;\r
+ return Status;\r
+ }\r
\r
- if (Length != sizeof(USB_DEBUG_PORT_DESCRIPTOR)) {\r
- return RETURN_DEVICE_ERROR;\r
- }\r
+ //\r
+ // Start to communicate with Usb Debug Device to see if the attached device is usb debug device or not.\r
+ //\r
+ Length = (UINT8)sizeof (USB_DEBUG_PORT_DESCRIPTOR);\r
\r
- //\r
- // set usb debug device address as 0x7F.\r
- //\r
- Status = UsbDebugPortControlTransfer (UsbDebugPortRegister, &mSetDebugAddress, 0x0, 0x0, NULL, NULL);\r
- if (RETURN_ERROR(Status)) {\r
//\r
- // The device can not work well.\r
+ // Get debug descriptor.\r
//\r
- return Status;\r
+ Status = UsbDebugPortControlTransfer (UsbDebugPortRegister, &mGetDebugDescriptor, 0x7F, 0x0, (UINT8*)&UsbDebugPortDescriptor, &Length);\r
+ if (RETURN_ERROR(Status)) {\r
+ //\r
+ // The device is not a usb debug device.\r
+ //\r
+ Handle->Initialized = USBDBG_NO_DBG_CAB;\r
+ return Status;\r
+ }\r
+\r
+ if (Length != sizeof(USB_DEBUG_PORT_DESCRIPTOR)) {\r
+ Handle->Initialized = USBDBG_NO_DBG_CAB;\r
+ return RETURN_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // enable the usb debug feature.\r
+ //\r
+ Status = UsbDebugPortControlTransfer (UsbDebugPortRegister, &mSetDebugFeature, 0x7F, 0x0, NULL, NULL);\r
+ if (RETURN_ERROR(Status)) {\r
+ //\r
+ // The device can not work well.\r
+ //\r
+ Handle->Initialized = USBDBG_NO_DBG_CAB;\r
+ return Status;\r
+ }\r
+ \r
+ Handle->Initialized = USBDBG_DBG_CAB;\r
}\r
\r
//\r
- // enable the usb debug feature.\r
+ // Set initialized flag\r
//\r
- Status = UsbDebugPortControlTransfer (UsbDebugPortRegister, &mSetDebugFeature, 0x7F, 0x0, NULL, NULL);\r
+ Handle->Initialized = USBDBG_INIT_DONE;\r
\r
- return Status;\r
+ return RETURN_SUCCESS;\r
}\r
\r
/**\r
UsbDebugPortHandle = (USB_DEBUG_PORT_HANDLE *)Handle;\r
}\r
\r
- //\r
- // Check if debug port is ready\r
- //\r
- if (!UsbDebugPortHandle->Initialized) {\r
- return 0;\r
- }\r
-\r
if (NeedReinitializeHardware(UsbDebugPortHandle)) {\r
Status = InitializeUsbDebugHardware (UsbDebugPortHandle);\r
if (RETURN_ERROR(Status)) {\r
}\r
}\r
\r
- UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UsbDebugPortHandle->UsbDebugPortMemoryBase + UsbDebugPortHandle->DebugPortOffset);\r
+ UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UINTN)(UsbDebugPortHandle->UsbDebugPortMemoryBase + UsbDebugPortHandle->DebugPortOffset);\r
\r
//\r
// First read data from buffer, then read debug port hw to get received data.\r
UsbDebugPortHandle = (USB_DEBUG_PORT_HANDLE *)Handle;\r
}\r
\r
- //\r
- // Check if debug port is ready\r
- //\r
- if (!UsbDebugPortHandle->Initialized) {\r
- return 0;\r
- }\r
-\r
if (NeedReinitializeHardware(UsbDebugPortHandle)) {\r
Status = InitializeUsbDebugHardware (UsbDebugPortHandle);\r
if (RETURN_ERROR(Status)) {\r
}\r
}\r
\r
- UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UsbDebugPortHandle->UsbDebugPortMemoryBase + UsbDebugPortHandle->DebugPortOffset);\r
+ UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UINTN)(UsbDebugPortHandle->UsbDebugPortMemoryBase + UsbDebugPortHandle->DebugPortOffset);\r
\r
while ((Total < NumberOfBytes)) {\r
if (NumberOfBytes - Total > USB_DEBUG_PORT_MAX_PACKET_SIZE) {\r
UsbDebugPortHandle = (USB_DEBUG_PORT_HANDLE *)Handle;\r
}\r
\r
- //\r
- // Check if debug port is ready\r
- //\r
- if (!UsbDebugPortHandle->Initialized) {\r
- return 0;\r
- }\r
-\r
if (NeedReinitializeHardware(UsbDebugPortHandle)) {\r
Status = InitializeUsbDebugHardware(UsbDebugPortHandle);\r
if (RETURN_ERROR(Status)) {\r
return TRUE;\r
}\r
\r
- UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UsbDebugPortHandle->UsbDebugPortMemoryBase + UsbDebugPortHandle->DebugPortOffset);\r
+ UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(UINTN)(UsbDebugPortHandle->UsbDebugPortMemoryBase + UsbDebugPortHandle->DebugPortOffset);\r
\r
UsbDebugPortRegister->TokenPid = INPUT_PID;\r
if (UsbDebugPortHandle->BulkInToggle == 0) {\r
//\r
// Wait for completing the request\r
//\r
- while ((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & (UINT32)BIT16) == 0);\r
+ while ((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & (UINT32)BIT16) == 0) {\r
+ if ((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE))\r
+ != (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_ENABLE)) {\r
+ return FALSE;\r
+ }\r
+ }\r
\r
if ((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus)) & BIT6) {\r
return FALSE;\r
{\r
RETURN_STATUS Status;\r
USB_DEBUG_PORT_HANDLE Handle;\r
-\r
- if (Function == NULL && Context != NULL) {\r
+\r if (Function == NULL && Context != NULL) {\r
return (DEBUG_PORT_HANDLE *) Context;\r
}\r
\r
\r
Status = CalculateUsbDebugPortBar(&Handle.DebugPortOffset, &Handle.DebugPortBarNumber);\r
if (RETURN_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "USB Debug Port: the pci device pointed by PcdUsbEhciPciAddress is not EHCI host controller or does not support debug port capability!\n"));\r
+ DEBUG ((EFI_D_ERROR, "UsbDbg: the pci device pointed by PcdUsbEhciPciAddress is not EHCI host controller or does not support debug port capability!\n"));\r
goto Exit;\r
}\r
\r
Handle.UsbDebugPortMemoryBase = 0xFFFFFC00 & PciRead32(PcdGet32(PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET + Handle.DebugPortBarNumber * 4);\r
}\r
\r
- Status = InitializeUsbDebugHardware (&Handle);\r
- if (RETURN_ERROR(Status)) {\r
- DEBUG ((EFI_D_ERROR, "USB Debug Port: Initialization failed, please check if USB debug cable is plugged into EHCI debug port correctly!\n"));\r
- goto Exit;\r
- }\r
+ Handle.Initialized = USBDBG_RESET;\r
\r
- //\r
- // Set debug port initialized successfully flag\r
- //\r
- Handle.Initialized = TRUE;\r
+ if (NeedReinitializeHardware(&Handle)) {\r
+ DEBUG ((EFI_D_ERROR, "UsbDbg: Start EHCI debug port initialization!\n"));\r
+ Status = InitializeUsbDebugHardware (&Handle);\r
+ if (RETURN_ERROR(Status)) {\r
+ DEBUG ((EFI_D_ERROR, "UsbDbg: Initialization failed, please check if USB debug cable is plugged into EHCI debug port correctly!\n"));\r
+ goto Exit;\r
+ }\r
+ }\r
\r
Exit:\r
\r