Reviewed-by: Hao A Wu <[email protected]> A couple of minor modifications will be done during merging: 1) " XHCI 1.1 spec November 2019" -> " XHCI 1.1 spec November 2017"; 2) Space indent refine according to the uncrustify tool report.
Best Regards, Hao Wu > -----Original Message----- > From: Chiu, Ian <[email protected]> > Sent: Wednesday, June 22, 2022 7:33 PM > To: [email protected] > Cc: Chiu, Ian <[email protected]>; Huang, Jenny <[email protected]>; > Shih, More <[email protected]>; Wu, Hao A <[email protected]>; Ni, > Ray <[email protected]> > Subject: [PATCH v3] MdeModulePkg/XhciDxe: Add access xHCI Extended > Capabilities Pointer > > From: Ian Chiu <[email protected]> > > Add support process Port Speed field value of PORTSC according to > Supported Protocol Capability (define in xHCI spec 1.1) > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3914 > > The value of Port Speed field in PORTSC bit[10:13] (xHCI spec 1.1 section > 5.4.8) should be change to use this value to query thru Protocol Speed ID > (PSI) > (xHCI spec 1.1 section 7.2.1) in xHCI Supported Protocol Capability and > return the value according the Protocol Speed ID (PSIV) Dword. > > With this mechanism may able to detect more kind of Protocol Speed in > USB3 and also compatiable with three kind of speed of USB2. > > Cc: Jenny Huang <[email protected]> > Cc: More Shih <[email protected]> > Cc: Hao A Wu <[email protected]> > Cc: Ray Ni <[email protected]> > Signed-off-by: Ian Chiu <[email protected]> > --- > MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c | 41 +++-- > MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h | 2 + > MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c | 178 ++++++++++++++++++++ > MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h | 92 +++++++++- > 4 files changed, 296 insertions(+), 17 deletions(-) > > diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c > b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c > index 381d7a9536..446f88bd60 100644 > --- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c > +++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c > @@ -398,25 +398,32 @@ XhcGetRootHubPortStatus ( > State = XhcReadOpReg (Xhc, Offset); //- // According to XHCI 1.1 spec > November 2017,- // bit 10~13 of the root port status register identifies the > speed of the attached device.+ // According to XHCI 1.1 spec November > 2019,+ // Section 7.2 xHCI Support Protocol Capability //- switch ((State > & > XHC_PORTSC_PS) >> 10) {- case 2:- PortStatus->PortStatus |= > USB_PORT_STAT_LOW_SPEED;- break;+ PortStatus->PortStatus = > XhcCheckUsbPortSpeedUsedPsic (Xhc, ((State & XHC_PORTSC_PS) >> 10));+ if > (PortStatus->PortStatus == 0) {+ //+ // According to XHCI 1.1 spec > November 2017,+ // bit 10~13 of the root port status register identifies > the > speed of the attached device.+ //+ switch ((State & XHC_PORTSC_PS) >> > 10) {+ case 2:+ PortStatus->PortStatus |= > USB_PORT_STAT_LOW_SPEED;+ break; - case 3:- PortStatus- > >PortStatus |= USB_PORT_STAT_HIGH_SPEED;- break;+ case 3:+ > PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED;+ break; - case > 4:- case 5:- PortStatus->PortStatus |= USB_PORT_STAT_SUPER_SPEED;- > break;+ case 4:+ case 5:+ PortStatus->PortStatus |= > USB_PORT_STAT_SUPER_SPEED;+ break; - default:- break;+ > default:+ break;+ } } //@@ -1826,6 +1833,8 @@ XhcCreateUsbHc ( > Xhc->ExtCapRegBase = ExtCapReg << 2; Xhc->UsbLegSupOffset = > XhcGetCapabilityAddr (Xhc, XHC_CAP_USB_LEGACY); Xhc- > >DebugCapSupOffset = XhcGetCapabilityAddr (Xhc, XHC_CAP_USB_DEBUG);+ > Xhc->Usb2SupOffset = XhcGetSupportedProtocolCapabilityAddr (Xhc, > XHC_SUPPORTED_PROTOCOL_DW0_MAJOR_REVISION_USB2);+ Xhc- > >Usb3SupOffset = XhcGetSupportedProtocolCapabilityAddr (Xhc, > XHC_SUPPORTED_PROTOCOL_DW0_MAJOR_REVISION_USB3); DEBUG > ((DEBUG_INFO, "XhcCreateUsb3Hc: Capability length 0x%x\n", Xhc- > >CapLength)); DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: HcSParams1 > 0x%x\n", Xhc->HcSParams1));@@ -1835,6 +1844,8 @@ XhcCreateUsbHc ( > DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: RTSOff 0x%x\n", Xhc->RTSOff)); > DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: UsbLegSupOffset 0x%x\n", Xhc- > >UsbLegSupOffset)); DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: > DebugCapSupOffset 0x%x\n", Xhc->DebugCapSupOffset));+ DEBUG > ((DEBUG_INFO, "XhcCreateUsb3Hc: Usb2SupOffset 0x%x\n", Xhc- > >Usb2SupOffset));+ DEBUG ((DEBUG_INFO, "XhcCreateUsb3Hc: > Usb3SupOffset 0x%x\n", Xhc->Usb3SupOffset)); // // Create AsyncRequest > Polling Timerdiff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h > b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h > index 5054d796b1..ca223bd20c 100644 > --- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h > +++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h > @@ -227,6 +227,8 @@ struct _USB_XHCI_INSTANCE { > UINT32 ExtCapRegBase; UINT32 > UsbLegSupOffset; > UINT32 DebugCapSupOffset;+ UINT32 > Usb2SupOffset;+ UINT32 Usb3SupOffset; UINT64 > *DCBAA; VOID *DCBAAMap; UINT32 > MaxSlotsEn;diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c > b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c > index 80be3311d4..e11db59871 100644 > --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c > +++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c > @@ -575,6 +575,184 @@ XhcGetCapabilityAddr ( > return 0xFFFFFFFF; } +/**+ Calculate the offset of the xHCI Supported > Protocol Capability.++ @param Xhc The XHCI Instance.+ @param > MajorVersion The USB Major Version in xHCI Support Protocol Capability > Field++ @return The offset of xHCI Supported Protocol capability > register.++**/+UINT32+XhcGetSupportedProtocolCapabilityAddr (+ IN > USB_XHCI_INSTANCE *Xhc,+ IN UINT8 MajorVersion+ )+{+ UINT32 > ExtCapOffset;+ UINT8 NextExtCapReg;+ UINT32 > Data;+ UINT32 NameString;+ > XHC_SUPPORTED_PROTOCOL_DW0 UsbSupportDw0;++ if (Xhc == NULL) {+ > return 0;+ }++ ExtCapOffset = 0;++ do {+ //+ // Check if the extended > capability register's capability id is USB Legacy Support.+ //+ Data > = XhcReadExtCapReg (Xhc, ExtCapOffset);+ UsbSupportDw0.Dword = Data;+ > if ((Data & 0xFF) == XHC_CAP_USB_SUPPORTED_PROTOCOL) {+ if > (UsbSupportDw0.Data.RevMajor == MajorVersion) {+ NameString = > XhcReadExtCapReg (Xhc, ExtCapOffset + > XHC_SUPPORTED_PROTOCOL_NAME_STRING_OFFSET);+ if (NameString > == XHC_SUPPORTED_PROTOCOL_NAME_STRING_VALUE) {+ //+ // > Ensure Name String field is xHCI supported protocols in xHCI Supported > Protocol Capability Offset 04h+ //+ return > ExtCapOffset;+ }+ }+ }++ //+ // If not, then traverse > all of the ext > capability registers till finding out it.+ //+ NextExtCapReg = > (UINT8)((Data >> 8) & 0xFF);+ ExtCapOffset += (NextExtCapReg << 2);+ } > while (NextExtCapReg != 0);++ return 0xFFFFFFFF;+}++/**+ Find PortSpeed > value match Protocol Speed ID Value (PSIV).++ @param Xhc The XHCI > Instance.+ @param ExtCapOffset The USB Major Version in xHCI Support > Protocol Capability Field+ @param PortSpeed The Port Speed Field in > USB PortSc register++ @return The Protocol Speed ID (PSI) from xHCI > Supported Protocol capability register.++**/+UINT32+XhciPsivGetPsid (+ IN > USB_XHCI_INSTANCE *Xhc,+ IN UINT32 ExtCapOffset,+ IN UINT8 > PortSpeed+ )+{+ XHC_SUPPORTED_PROTOCOL_DW2 PortId;+ > XHC_SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID Reg;+ UINT32 > Count;++ if ((Xhc == NULL) || (ExtCapOffset == 0xFFFFFFFF)) {+ return > 0;+ }++ //+ // According to XHCI 1.1 spec November 2019,+ // Section 7.2 > xHCI Supported Protocol Capability+ // 1. Get the PSIC(Protocol Speed ID > Count) value.+ // 2. The PSID register boundary should be Base address + > PSIC * 0x04+ //+ PortId.Dword = XhcReadExtCapReg (Xhc, ExtCapOffset + > XHC_SUPPORTED_PROTOCOL_DW2_OFFSET);++ for (Count = 0; Count < > PortId.Data.Psic; Count++) {+ Reg.Dword = XhcReadExtCapReg (Xhc, > ExtCapOffset + XHC_SUPPORTED_PROTOCOL_PSI_OFFSET + (Count << 2));+ > if (Reg.Data.Psiv == PortSpeed) {+ return Reg.Dword;+ }+ }++ return > 0;+}++/**+ Find PortSpeed value match case in XHCI Supported Protocol > Capability++ @param Xhc The XHCI Instance.+ @param PortSpeed > The Port Speed Field in USB PortSc register++ @return The USB Port > Speed.++**/+UINT16+XhcCheckUsbPortSpeedUsedPsic (+ IN > USB_XHCI_INSTANCE *Xhc,+ IN UINT8 PortSpeed+ )+{+ > XHC_SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID SpField;+ UINT16 > UsbSpeedIdMap;++ if (Xhc == NULL) {+ return 0;+ }++ SpField.Dword = 0;+ > UsbSpeedIdMap = 0;++ //+ // Check xHCI Supported Protocol Capability > which Revision Major number is 03h+ // and find the PSIV field to match > PortSpeed.+ //+ if (Xhc->Usb3SupOffset != 0xFFFFFFFF) {+ SpField.Dword = > XhciPsivGetPsid (Xhc, Xhc->Usb3SupOffset, PortSpeed);+ if > (SpField.Dword != 0) {+ //+ // Found the corresponding PORTSC value > in PSIV field of USB3 offset.+ //+ UsbSpeedIdMap = > USB_PORT_STAT_SUPER_SPEED;+ }+ }++ //+ // Check xHCI Supported > Protocol Capability which Revision Major number is 02h+ // and find the > PSIV field to match PortSpeed.+ //+ if ((UsbSpeedIdMap == 0) && (Xhc- > >Usb2SupOffset != 0xFFFFFFFF)) {+ SpField.Dword = XhciPsivGetPsid (Xhc, > Xhc->Usb2SupOffset, PortSpeed);+ if (SpField.Dword != 0) {+ //+ > // > Found the corresponding PORTSC value in PSIV field of USB2 offset.+ //+ > if (SpField.Data.Psie == 2) {+ //+ // According to XHCI 1.1 spec > November 2019,+ // Section 7.2.1 the Protocol Speed ID Exponent (PSIE) > field definition,+ // PSIE value shall be applied to Protocol Speed ID > Mantissa when calculating, value 2 shall represent bit rate is Mb/s+ > //+ > if (SpField.Data.Psim == > XHC_SUPPORTED_PROTOCOL_USB2_HIGH_SPEED_PSIM) {+ //+ // > PSIM shows as default High-speed protocol, apply to High-speed mapping+ > //+ UsbSpeedIdMap = USB_PORT_STAT_HIGH_SPEED;+ }+ } else > if (SpField.Data.Psie == 1) {+ //+ // According to XHCI 1.1 spec > November 2019,+ // Section 7.2.1 the Protocol Speed ID Exponent (PSIE) > field definition,+ // PSIE value shall be applied to Protocol Speed ID > Mantissa when calculating, value 1 shall represent bit rate is Kb/s+ > //+ > if (SpField.Data.Psim == > XHC_SUPPORTED_PROTOCOL_USB2_LOW_SPEED_PSIM) {+ //+ // > PSIM shows as default Low-speed protocol, apply to Low-speed mapping+ > //+ UsbSpeedIdMap = > USB_PORT_STAT_LOW_SPEED;+ }+ }+ }+ }++ return > UsbSpeedIdMap;+}+ /** Whether the XHCI host controller is halted. diff -- > git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h > b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h > index 4950eed272..94b53c8335 100644 > --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h > +++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h > @@ -25,8 +25,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > #define USB_HUB_CLASS_CODE 0x09 #define USB_HUB_SUBCLASS_CODE > 0x00 -#define XHC_CAP_USB_LEGACY 0x01-#define XHC_CAP_USB_DEBUG > 0x0A+#define XHC_CAP_USB_LEGACY 0x01+#define > XHC_CAP_USB_DEBUG 0x0A+#define > XHC_CAP_USB_SUPPORTED_PROTOCOL 0x02 // > ============================================// // XHCI register > offset //@@ -74,6 +75,18 @@ SPDX-License-Identifier: BSD-2-Clause- > Patent > #define USBLEGSP_BIOS_SEMAPHORE BIT16 // HC BIOS Owned > Semaphore #define USBLEGSP_OS_SEMAPHORE BIT24 // HC OS > Owned Semaphore +//+// xHCI Supported Protocol Capability+//+#define > XHC_SUPPORTED_PROTOCOL_DW0_MAJOR_REVISION_USB2 0x02+#define > XHC_SUPPORTED_PROTOCOL_DW0_MAJOR_REVISION_USB3 0x03+#define > XHC_SUPPORTED_PROTOCOL_NAME_STRING_OFFSET 0x04+#define > XHC_SUPPORTED_PROTOCOL_NAME_STRING_VALUE > 0x20425355+#define XHC_SUPPORTED_PROTOCOL_DW2_OFFSET > 0x08+#define XHC_SUPPORTED_PROTOCOL_PSI_OFFSET > 0x10+#define XHC_SUPPORTED_PROTOCOL_USB2_HIGH_SPEED_PSIM > 480+#define XHC_SUPPORTED_PROTOCOL_USB2_LOW_SPEED_PSIM 1500+ > #pragma pack (1) typedef struct { UINT8 MaxSlots; > // Number > of Device Slots@@ -130,6 +143,52 @@ typedef union { > HCCPARAMS Data; } XHC_HCCPARAMS; +//+// xHCI Supported Protocol > Cabability+//+typedef struct {+ UINT8 CapId;+ UINT8 NextExtCapReg;+ > UINT8 RevMinor;+ UINT8 RevMajor;+} > SUPPORTED_PROTOCOL_DW0;++typedef union {+ UINT32 > Dword;+ SUPPORTED_PROTOCOL_DW0 Data;+} > XHC_SUPPORTED_PROTOCOL_DW0;++typedef struct {+ UINT32 > NameString;+} XHC_SUPPORTED_PROTOCOL_DW1;++typedef struct {+ UINT8 > CompPortOffset;+ UINT8 CompPortCount;+ UINT16 ProtocolDef : 12;+ > UINT16 Psic : 4;+} SUPPORTED_PROTOCOL_DW2;++typedef union {+ > UINT32 Dword;+ SUPPORTED_PROTOCOL_DW2 Data;+} > XHC_SUPPORTED_PROTOCOL_DW2;++typedef struct {+ UINT16 Psiv : 4;+ > UINT16 Psie : 2;+ UINT16 Plt : 2;+ UINT16 Pfd : 1;+ UINT16 > RsvdP : > 5;+ UINT16 Lp : 2;+ UINT16 Psim;+} > SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID;++typedef union {+ UINT32 > Dword;+ SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID Data;+} > XHC_SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID;+ #pragma pack () //@@ > -546,4 +605,33 @@ XhcGetCapabilityAddr ( > IN UINT8 CapId ); +/**+ Calculate the offset of the xHCI > Supported Protocol Capability.++ @param Xhc The XHCI Instance.+ > @param MajorVersion The USB Major Version in xHCI Support Protocol > Capability Field++ @return The offset of xHCI Supported Protocol capability > register.++**/+UINT32+XhcGetSupportedProtocolCapabilityAddr (+ IN > USB_XHCI_INSTANCE *Xhc,+ IN UINT8 MajorVersion+ );++/**+ Find > SpeedField value match with Port Speed ID value.++ @param Xhc The > XHCI Instance.+ @param Speed The Port Speed filed in USB PortSc > register++ @return The USB Port > Speed.++**/+UINT16+XhcCheckUsbPortSpeedUsedPsic (+ IN > USB_XHCI_INSTANCE *Xhc,+ IN UINT8 Speed+ ); #endif-- > 2.26.2.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90704): https://edk2.groups.io/g/devel/message/90704 Mute This Topic: https://groups.io/mt/91919638/21656 Group Owner: [email protected] Unsubscribe: https://edk2.groups.io/g/devel/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
