\r
//\r
// According to XHCI 1.1 spec November 2017,\r
- // bit 10~13 of the root port status register identifies the speed of the attached device.\r
+ // Section 7.2 xHCI Support Protocol Capability\r
//\r
- switch ((State & XHC_PORTSC_PS) >> 10) {\r
- case 2:\r
- PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;\r
- break;\r
+ PortStatus->PortStatus = XhcCheckUsbPortSpeedUsedPsic (Xhc, ((State & XHC_PORTSC_PS) >> 10));\r
+ if (PortStatus->PortStatus == 0) {\r
+ //\r
+ // According to XHCI 1.1 spec November 2017,\r
+ // bit 10~13 of the root port status register identifies the speed of the attached device.\r
+ //\r
+ switch ((State & XHC_PORTSC_PS) >> 10) {\r
+ case 2:\r
+ PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;\r
+ break;\r
\r
- case 3:\r
- PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED;\r
- break;\r
+ case 3:\r
+ PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED;\r
+ break;\r
\r
- case 4:\r
- case 5:\r
- PortStatus->PortStatus |= USB_PORT_STAT_SUPER_SPEED;\r
- break;\r
+ case 4:\r
+ case 5:\r
+ PortStatus->PortStatus |= USB_PORT_STAT_SUPER_SPEED;\r
+ break;\r
\r
- default:\r
- break;\r
+ default:\r
+ break;\r
+ }\r
}\r
\r
//\r
Xhc->ExtCapRegBase = ExtCapReg << 2;\r
Xhc->UsbLegSupOffset = XhcGetCapabilityAddr (Xhc, XHC_CAP_USB_LEGACY);\r
Xhc->DebugCapSupOffset = XhcGetCapabilityAddr (Xhc, XHC_CAP_USB_DEBUG);\r
+ Xhc->Usb2SupOffset = XhcGetSupportedProtocolCapabilityAddr (Xhc, XHC_SUPPORTED_PROTOCOL_DW0_MAJOR_REVISION_USB2);\r
+ Xhc->Usb3SupOffset = XhcGetSupportedProtocolCapabilityAddr (Xhc, XHC_SUPPORTED_PROTOCOL_DW0_MAJOR_REVISION_USB3);\r
\r
DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: Capability length 0x%x\n", Xhc->CapLength));\r
DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: HcSParams1 0x%x\n", Xhc->HcSParams1));\r
DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: RTSOff 0x%x\n", Xhc->RTSOff));\r
DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: UsbLegSupOffset 0x%x\n", Xhc->UsbLegSupOffset));\r
DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: DebugCapSupOffset 0x%x\n", Xhc->DebugCapSupOffset));\r
+ DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: Usb2SupOffset 0x%x\n", Xhc->Usb2SupOffset));\r
+ DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: Usb3SupOffset 0x%x\n", Xhc->Usb3SupOffset));\r
\r
//\r
// Create AsyncRequest Polling Timer\r
return 0xFFFFFFFF;\r
}\r
\r
+/**\r
+ Calculate the offset of the xHCI Supported Protocol Capability.\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param MajorVersion The USB Major Version in xHCI Support Protocol Capability Field\r
+\r
+ @return The offset of xHCI Supported Protocol capability register.\r
+\r
+**/\r
+UINT32\r
+XhcGetSupportedProtocolCapabilityAddr (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 MajorVersion\r
+ )\r
+{\r
+ UINT32 ExtCapOffset;\r
+ UINT8 NextExtCapReg;\r
+ UINT32 Data;\r
+ UINT32 NameString;\r
+ XHC_SUPPORTED_PROTOCOL_DW0 UsbSupportDw0;\r
+\r
+ if (Xhc == NULL) {\r
+ return 0;\r
+ }\r
+\r
+ ExtCapOffset = 0;\r
+\r
+ do {\r
+ //\r
+ // Check if the extended capability register's capability id is USB Legacy Support.\r
+ //\r
+ Data = XhcReadExtCapReg (Xhc, ExtCapOffset);\r
+ UsbSupportDw0.Dword = Data;\r
+ if ((Data & 0xFF) == XHC_CAP_USB_SUPPORTED_PROTOCOL) {\r
+ if (UsbSupportDw0.Data.RevMajor == MajorVersion) {\r
+ NameString = XhcReadExtCapReg (Xhc, ExtCapOffset + XHC_SUPPORTED_PROTOCOL_NAME_STRING_OFFSET);\r
+ if (NameString == XHC_SUPPORTED_PROTOCOL_NAME_STRING_VALUE) {\r
+ //\r
+ // Ensure Name String field is xHCI supported protocols in xHCI Supported Protocol Capability Offset 04h\r
+ //\r
+ return ExtCapOffset;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // If not, then traverse all of the ext capability registers till finding out it.\r
+ //\r
+ NextExtCapReg = (UINT8)((Data >> 8) & 0xFF);\r
+ ExtCapOffset += (NextExtCapReg << 2);\r
+ } while (NextExtCapReg != 0);\r
+\r
+ return 0xFFFFFFFF;\r
+}\r
+\r
+/**\r
+ Find PortSpeed value match Protocol Speed ID Value (PSIV).\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param ExtCapOffset The USB Major Version in xHCI Support Protocol Capability Field\r
+ @param PortSpeed The Port Speed Field in USB PortSc register\r
+\r
+ @return The Protocol Speed ID (PSI) from xHCI Supported Protocol capability register.\r
+\r
+**/\r
+UINT32\r
+XhciPsivGetPsid (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 ExtCapOffset,\r
+ IN UINT8 PortSpeed\r
+ )\r
+{\r
+ XHC_SUPPORTED_PROTOCOL_DW2 PortId;\r
+ XHC_SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID Reg;\r
+ UINT32 Count;\r
+\r
+ if ((Xhc == NULL) || (ExtCapOffset == 0xFFFFFFFF)) {\r
+ return 0;\r
+ }\r
+\r
+ //\r
+ // According to XHCI 1.1 spec November 2017,\r
+ // Section 7.2 xHCI Supported Protocol Capability\r
+ // 1. Get the PSIC(Protocol Speed ID Count) value.\r
+ // 2. The PSID register boundary should be Base address + PSIC * 0x04\r
+ //\r
+ PortId.Dword = XhcReadExtCapReg (Xhc, ExtCapOffset + XHC_SUPPORTED_PROTOCOL_DW2_OFFSET);\r
+\r
+ for (Count = 0; Count < PortId.Data.Psic; Count++) {\r
+ Reg.Dword = XhcReadExtCapReg (Xhc, ExtCapOffset + XHC_SUPPORTED_PROTOCOL_PSI_OFFSET + (Count << 2));\r
+ if (Reg.Data.Psiv == PortSpeed) {\r
+ return Reg.Dword;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+/**\r
+ Find PortSpeed value match case in XHCI Supported Protocol Capability\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param PortSpeed The Port Speed Field in USB PortSc register\r
+\r
+ @return The USB Port Speed.\r
+\r
+**/\r
+UINT16\r
+XhcCheckUsbPortSpeedUsedPsic (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 PortSpeed\r
+ )\r
+{\r
+ XHC_SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID SpField;\r
+ UINT16 UsbSpeedIdMap;\r
+\r
+ if (Xhc == NULL) {\r
+ return 0;\r
+ }\r
+\r
+ SpField.Dword = 0;\r
+ UsbSpeedIdMap = 0;\r
+\r
+ //\r
+ // Check xHCI Supported Protocol Capability, find the PSIV field to match\r
+ // PortSpeed definition when the Major Revision is 03h.\r
+ //\r
+ if (Xhc->Usb3SupOffset != 0xFFFFFFFF) {\r
+ SpField.Dword = XhciPsivGetPsid (Xhc, Xhc->Usb3SupOffset, PortSpeed);\r
+ if (SpField.Dword != 0) {\r
+ //\r
+ // Found the corresponding PORTSC value in PSIV field of USB3 offset.\r
+ //\r
+ UsbSpeedIdMap = USB_PORT_STAT_SUPER_SPEED;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Check xHCI Supported Protocol Capability, find the PSIV field to match\r
+ // PortSpeed definition when the Major Revision is 02h.\r
+ //\r
+ if ((UsbSpeedIdMap == 0) && (Xhc->Usb2SupOffset != 0xFFFFFFFF)) {\r
+ SpField.Dword = XhciPsivGetPsid (Xhc, Xhc->Usb2SupOffset, PortSpeed);\r
+ if (SpField.Dword != 0) {\r
+ //\r
+ // Found the corresponding PORTSC value in PSIV field of USB2 offset.\r
+ //\r
+ if (SpField.Data.Psie == 2) {\r
+ //\r
+ // According to XHCI 1.1 spec November 2017,\r
+ // Section 7.2.1 the Protocol Speed ID Exponent (PSIE) field definition,\r
+ // PSIE value shall be applied to Protocol Speed ID Mantissa when calculating, value 2 shall represent bit rate in Mb/s\r
+ //\r
+ if (SpField.Data.Psim == XHC_SUPPORTED_PROTOCOL_USB2_HIGH_SPEED_PSIM) {\r
+ //\r
+ // PSIM shows as default High-speed protocol, apply to High-speed mapping\r
+ //\r
+ UsbSpeedIdMap = USB_PORT_STAT_HIGH_SPEED;\r
+ }\r
+ } else if (SpField.Data.Psie == 1) {\r
+ //\r
+ // According to XHCI 1.1 spec November 2017,\r
+ // Section 7.2.1 the Protocol Speed ID Exponent (PSIE) field definition,\r
+ // PSIE value shall be applied to Protocol Speed ID Mantissa when calculating, value 1 shall represent bit rate in Kb/s\r
+ //\r
+ if (SpField.Data.Psim == XHC_SUPPORTED_PROTOCOL_USB2_LOW_SPEED_PSIM) {\r
+ //\r
+ // PSIM shows as default Low-speed protocol, apply to Low-speed mapping\r
+ //\r
+ UsbSpeedIdMap = USB_PORT_STAT_LOW_SPEED;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return UsbSpeedIdMap;\r
+}\r
+\r
/**\r
Whether the XHCI host controller is halted.\r
\r
#define USB_HUB_CLASS_CODE 0x09\r
#define USB_HUB_SUBCLASS_CODE 0x00\r
\r
-#define XHC_CAP_USB_LEGACY 0x01\r
-#define XHC_CAP_USB_DEBUG 0x0A\r
+#define XHC_CAP_USB_LEGACY 0x01\r
+#define XHC_CAP_USB_DEBUG 0x0A\r
+#define XHC_CAP_USB_SUPPORTED_PROTOCOL 0x02\r
\r
// ============================================//\r
// XHCI register offset //\r
#define USBLEGSP_BIOS_SEMAPHORE BIT16 // HC BIOS Owned Semaphore\r
#define USBLEGSP_OS_SEMAPHORE BIT24 // HC OS Owned Semaphore\r
\r
+//\r
+// xHCI Supported Protocol Capability\r
+//\r
+#define XHC_SUPPORTED_PROTOCOL_DW0_MAJOR_REVISION_USB2 0x02\r
+#define XHC_SUPPORTED_PROTOCOL_DW0_MAJOR_REVISION_USB3 0x03\r
+#define XHC_SUPPORTED_PROTOCOL_NAME_STRING_OFFSET 0x04\r
+#define XHC_SUPPORTED_PROTOCOL_NAME_STRING_VALUE 0x20425355\r
+#define XHC_SUPPORTED_PROTOCOL_DW2_OFFSET 0x08\r
+#define XHC_SUPPORTED_PROTOCOL_PSI_OFFSET 0x10\r
+#define XHC_SUPPORTED_PROTOCOL_USB2_HIGH_SPEED_PSIM 480\r
+#define XHC_SUPPORTED_PROTOCOL_USB2_LOW_SPEED_PSIM 1500\r
+\r
#pragma pack (1)\r
typedef struct {\r
UINT8 MaxSlots; // Number of Device Slots\r
HCCPARAMS Data;\r
} XHC_HCCPARAMS;\r
\r
+//\r
+// xHCI Supported Protocol Cabability\r
+//\r
+typedef struct {\r
+ UINT8 CapId;\r
+ UINT8 NextExtCapReg;\r
+ UINT8 RevMinor;\r
+ UINT8 RevMajor;\r
+} SUPPORTED_PROTOCOL_DW0;\r
+\r
+typedef union {\r
+ UINT32 Dword;\r
+ SUPPORTED_PROTOCOL_DW0 Data;\r
+} XHC_SUPPORTED_PROTOCOL_DW0;\r
+\r
+typedef struct {\r
+ UINT32 NameString;\r
+} XHC_SUPPORTED_PROTOCOL_DW1;\r
+\r
+typedef struct {\r
+ UINT8 CompPortOffset;\r
+ UINT8 CompPortCount;\r
+ UINT16 ProtocolDef : 12;\r
+ UINT16 Psic : 4;\r
+} SUPPORTED_PROTOCOL_DW2;\r
+\r
+typedef union {\r
+ UINT32 Dword;\r
+ SUPPORTED_PROTOCOL_DW2 Data;\r
+} XHC_SUPPORTED_PROTOCOL_DW2;\r
+\r
+typedef struct {\r
+ UINT16 Psiv : 4;\r
+ UINT16 Psie : 2;\r
+ UINT16 Plt : 2;\r
+ UINT16 Pfd : 1;\r
+ UINT16 RsvdP : 5;\r
+ UINT16 Lp : 2;\r
+ UINT16 Psim;\r
+} SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID;\r
+\r
+typedef union {\r
+ UINT32 Dword;\r
+ SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID Data;\r
+} XHC_SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID;\r
+\r
#pragma pack ()\r
\r
//\r
IN UINT8 CapId\r
);\r
\r
+/**\r
+ Calculate the offset of the xHCI Supported Protocol Capability.\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param MajorVersion The USB Major Version in xHCI Support Protocol Capability Field\r
+\r
+ @return The offset of xHCI Supported Protocol capability register.\r
+\r
+**/\r
+UINT32\r
+XhcGetSupportedProtocolCapabilityAddr (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 MajorVersion\r
+ );\r
+\r
+/**\r
+ Find SpeedField value match with Port Speed ID value.\r
+\r
+ @param Xhc The XHCI Instance.\r
+ @param Speed The Port Speed filed in USB PortSc register\r
+\r
+ @return The USB Port Speed.\r
+\r
+**/\r
+UINT16\r
+XhcCheckUsbPortSpeedUsedPsic (\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 Speed\r
+ );\r
+\r
#endif\r