From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smarthost01c.sbp.mail.zen.net.uk (smarthost01c.sbp.mail.zen.net.uk [212.23.1.5]) by mx.groups.io with SMTP id smtpd.web11.4066.1670618746779972422 for ; Fri, 09 Dec 2022 12:45:47 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=permerror, err=parse error for token &{10 18 sdn.klaviyomail.com}: permanent DNS error (domain: starlabs.systems, ip: 212.23.1.5, mailfrom: sean@starlabs.systems) Received: from [217.155.46.38] (helo=starbook..) by smarthost01c.sbp.mail.zen.net.uk with esmtp (Exim 4.90_1) (envelope-from ) id 1p3kFc-000547-A8; Fri, 09 Dec 2022 20:45:44 +0000 From: "Sean Rhodes" To: devel@edk2.groups.io Cc: Sean Rhodes Subject: [PATCH 3/3] MdeModulePkg/Bus/Pci/XhciDxe: Handle incorrect PSIV indices Date: Fri, 9 Dec 2022 20:45:40 +0000 Message-Id: <6c69b4c50a198bf4348066fbc8156b07520d6b77.1670618740.git.sean@starlabs.systems> X-Mailer: git-send-email 2.37.2 In-Reply-To: References: MIME-Version: 1.0 X-Originating-smarthost01c-IP: [217.155.46.38] Feedback-ID: 217.155.46.38 Content-Transfer-Encoding: quoted-printable On some platforms, including Sky Lake and Kaby Lake, the PSIV (Protocol Speed ID Value) indices are shared between Protocol Speed ID DWORD' in the extended capabilities registers for both USB2 (Full Speed) and USB3 (Super Speed). An example can be found below: XhcCheckUsbPortSpeedUsedPsic: checking for USB2 ext caps XhciPsivGetPsid: found 3 PSID entries XhciPsivGetPsid: looking for port speed 1 XhciPsivGetPsid: PSIV 1 PSIE 2 PLT 0 PSIM 12 XhciPsivGetPsid: PSIV 2 PSIE 1 PLT 0 PSIM 1500 XhciPsivGetPsid: PSIV 3 PSIE 2 PLT 0 PSIM 480 XhcCheckUsbPortSpeedUsedPsic: checking for USB3 ext caps XhciPsivGetPsid: found 3 PSID entries XhciPsivGetPsid: looking for port speed 1 XhciPsivGetPsid: PSIV 1 PSIE 3 PLT 0 PSIM 5 XhciPsivGetPsid: PSIV 2 PSIE 3 PLT 0 PSIM 10 XhciPsivGetPsid: PSIV 34 PSIE 2 PLT 0 PSIM 1248 The result is edk2 detecting USB2 devices as USB3 devices, which consequently causes enumeration to fail. To avoid incorrect detection, check the Compatible Port Offset to find the starting Port of Root Hubs that support the protocol. Signed-off-by: Sean Rhodes --- MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c | 2 +- MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c | 26 ++++++++++++++++++++++---- MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h | 3 ++- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c b/MdeModulePkg/Bus/Pci/Xhc= iDxe/Xhci.c index 8dd7a8fbb7..461b2cd9b5 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c +++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c @@ -405,7 +405,7 @@ XhcGetRootHubPortStatus ( // Section 7.2 xHCI Support Protocol Capability=0D //=0D if (PortSpeed > 0) {=0D - PortStatus->PortStatus =3D XhcCheckUsbPortSpeedUsedPsic (Xhc, PortSpee= d);=0D + PortStatus->PortStatus =3D XhcCheckUsbPortSpeedUsedPsic (Xhc, PortSpee= d, PortNumber);=0D // If no match found in ext cap reg, fall back to PORTSC=0D if (PortStatus->PortStatus =3D=3D 0) {=0D //=0D diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c b/MdeModulePkg/Bus/Pci/= XhciDxe/XhciReg.c index 2b4a4b2444..bca53e9ac0 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c +++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c @@ -636,6 +636,7 @@ XhcGetSupportedProtocolCapabilityAddr ( @param Xhc The XHCI Instance.=0D @param ExtCapOffset The USB Major Version in xHCI Support Protocol Ca= pability Field=0D @param PortSpeed The Port Speed Field in USB PortSc register=0D + @param PortNumber The Port Number (0-indexed)=0D =0D @return The Protocol Speed ID (PSI) from xHCI Supported Protocol capabil= ity register.=0D =0D @@ -644,12 +645,15 @@ UINT32 XhciPsivGetPsid (=0D IN USB_XHCI_INSTANCE *Xhc,=0D IN UINT32 ExtCapOffset,=0D - IN UINT8 PortSpeed=0D + IN UINT8 PortSpeed,=0D + IN UINT8 PortNumber=0D )=0D {=0D XHC_SUPPORTED_PROTOCOL_DW2 PortId;=0D XHC_SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID Reg;=0D UINT32 Count;=0D + UINT32 MinPortIndex;=0D + UINT32 MaxPortIndex;=0D =0D if ((Xhc =3D=3D NULL) || (ExtCapOffset =3D=3D 0xFFFFFFFF)) {=0D return 0;=0D @@ -663,6 +667,19 @@ XhciPsivGetPsid ( //=0D PortId.Dword =3D XhcReadExtCapReg (Xhc, ExtCapOffset + XHC_SUPPORTED_PRO= TOCOL_DW2_OFFSET);=0D =0D + //=0D + // According to XHCI 1.1 spec November 2017, valid values=0D + // for CompPortOffset are 1 to CompPortCount - 1.=0D + //=0D + // PortNumber is zero-indexed, so subtract 1.=0D + //=0D + MinPortIndex =3D PortId.Data.CompPortOffset - 1;=0D + MaxPortIndex =3D MinPortIndex + PortId.Data.CompPortCount - 1;=0D +=0D + if ((PortNumber < MinPortIndex) || (PortNumber > MaxPortIndex)) {=0D + return 0;=0D + }=0D +=0D for (Count =3D 0; Count < PortId.Data.Psic; Count++) {=0D Reg.Dword =3D XhcReadExtCapReg (Xhc, ExtCapOffset + XHC_SUPPORTED_PROT= OCOL_PSI_OFFSET + (Count << 2));=0D if (Reg.Data.Psiv =3D=3D PortSpeed) {=0D @@ -685,7 +702,8 @@ XhciPsivGetPsid ( UINT16=0D XhcCheckUsbPortSpeedUsedPsic (=0D IN USB_XHCI_INSTANCE *Xhc,=0D - IN UINT8 PortSpeed=0D + IN UINT8 PortSpeed,=0D + IN UINT8 PortNumber=0D )=0D {=0D XHC_SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID SpField;=0D @@ -703,7 +721,7 @@ XhcCheckUsbPortSpeedUsedPsic ( // PortSpeed definition when the Major Revision is 03h.=0D //=0D if (Xhc->Usb3SupOffset !=3D 0xFFFFFFFF) {=0D - SpField.Dword =3D XhciPsivGetPsid (Xhc, Xhc->Usb3SupOffset, PortSpeed)= ;=0D + SpField.Dword =3D XhciPsivGetPsid (Xhc, Xhc->Usb3SupOffset, PortSpeed,= PortNumber);=0D if (SpField.Dword !=3D 0) {=0D //=0D // Found the corresponding PORTSC value in PSIV field of USB3 offset= .=0D @@ -717,7 +735,7 @@ XhcCheckUsbPortSpeedUsedPsic ( // PortSpeed definition when the Major Revision is 02h.=0D //=0D if ((UsbSpeedIdMap =3D=3D 0) && (Xhc->Usb2SupOffset !=3D 0xFFFFFFFF)) {= =0D - SpField.Dword =3D XhciPsivGetPsid (Xhc, Xhc->Usb2SupOffset, PortSpeed)= ;=0D + SpField.Dword =3D XhciPsivGetPsid (Xhc, Xhc->Usb2SupOffset, PortSpeed,= PortNumber);=0D if (SpField.Dword !=3D 0) {=0D //=0D // Found the corresponding PORTSC value in PSIV field of USB2 offset= .=0D diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h b/MdeModulePkg/Bus/Pci/= XhciDxe/XhciReg.h index 5fe2ba4f0e..5fd5485a5e 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h +++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h @@ -632,7 +632,8 @@ XhcGetSupportedProtocolCapabilityAddr ( UINT16=0D XhcCheckUsbPortSpeedUsedPsic (=0D IN USB_XHCI_INSTANCE *Xhc,=0D - IN UINT8 Speed=0D + IN UINT8 Speed,=0D + IN UINT8 PortNumber=0D );=0D =0D #endif=0D --=20 2.37.2