From: "Sean Rhodes" <sean@starlabs.systems>
To: devel@edk2.groups.io
Cc: Sean Rhodes <sean@starlabs.systems>
Subject: [PATCH 3/3] MdeModulePkg/Bus/Pci/XhciDxe: Check port is compatible before getting PSIV
Date: Fri, 16 Dec 2022 08:58:06 +0000 [thread overview]
Message-ID: <c7e37678b5d46e196e1c473b63df023fcf619122.1671181085.git.sean@starlabs.systems> (raw)
In-Reply-To: <7bad2974b731b7cd8323582aa89ae4ed9f10702c.1671181085.git.sean@starlabs.systems>
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 <sean@starlabs.systems>
---
MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c | 2 +-
MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c | 35 +++++++++++++++++++++-----
MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h | 8 +++---
3 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c b/MdeModulePkg/Bus/Pci/XhciDxe/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
//
if (PortSpeed > 0) {
- PortStatus->PortStatus = XhcCheckUsbPortSpeedUsedPsic (Xhc, PortSpeed);
+ PortStatus->PortStatus = XhcCheckUsbPortSpeedUsedPsic (Xhc, PortSpeed, PortNumber);
// If no match found in ext cap reg, fall back to PORTSC
if (PortStatus->PortStatus == 0) {
//
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c
index 2b4a4b2444..5700fc5fb8 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.
@param ExtCapOffset The USB Major Version in xHCI Support Protocol Capability Field
@param PortSpeed The Port Speed Field in USB PortSc register
+ @param PortNumber The Port Number (0-indexed)
@return The Protocol Speed ID (PSI) from xHCI Supported Protocol capability register.
@@ -644,12 +645,15 @@ UINT32
XhciPsivGetPsid (
IN USB_XHCI_INSTANCE *Xhc,
IN UINT32 ExtCapOffset,
- IN UINT8 PortSpeed
+ IN UINT8 PortSpeed,
+ IN UINT8 PortNumber
)
{
XHC_SUPPORTED_PROTOCOL_DW2 PortId;
XHC_SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID Reg;
UINT32 Count;
+ UINT32 MinPortIndex;
+ UINT32 MaxPortIndex;
if ((Xhc == NULL) || (ExtCapOffset == 0xFFFFFFFF)) {
return 0;
@@ -663,6 +667,23 @@ XhciPsivGetPsid (
//
PortId.Dword = XhcReadExtCapReg (Xhc, ExtCapOffset + XHC_SUPPORTED_PROTOCOL_DW2_OFFSET);
+ //
+ // According to XHCI 1.1 spec November 2017, valid values
+ // for CompPortOffset are 1 to CompPortCount - 1.
+ //
+ // PortNumber is zero-indexed, so subtract 1.
+ //
+ if ((PortId.Data.CompPortOffset == 0) || (PortId.Data.CompPortCount == 0)) {
+ return 0;
+ }
+
+ MinPortIndex = PortId.Data.CompPortOffset - 1;
+ MaxPortIndex = MinPortIndex + PortId.Data.CompPortCount - 1;
+
+ if ((PortNumber < MinPortIndex) || (PortNumber > MaxPortIndex)) {
+ return 0;
+ }
+
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) {
@@ -676,8 +697,9 @@ XhciPsivGetPsid (
/**
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
+ @param Xhc The XHCI Instance.
+ @param PortSpeed The Port Speed Field in USB PortSc register
+ @param PortNumber The Port Number (0-indexed)
@return The USB Port Speed.
@@ -685,7 +707,8 @@ XhciPsivGetPsid (
UINT16
XhcCheckUsbPortSpeedUsedPsic (
IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 PortSpeed
+ IN UINT8 PortSpeed,
+ IN UINT8 PortNumber
)
{
XHC_SUPPORTED_PROTOCOL_PROTOCOL_SPEED_ID SpField;
@@ -703,7 +726,7 @@ XhcCheckUsbPortSpeedUsedPsic (
// PortSpeed definition when the Major Revision is 03h.
//
if (Xhc->Usb3SupOffset != 0xFFFFFFFF) {
- SpField.Dword = XhciPsivGetPsid (Xhc, Xhc->Usb3SupOffset, PortSpeed);
+ SpField.Dword = XhciPsivGetPsid (Xhc, Xhc->Usb3SupOffset, PortSpeed, PortNumber);
if (SpField.Dword != 0) {
//
// Found the corresponding PORTSC value in PSIV field of USB3 offset.
@@ -717,7 +740,7 @@ XhcCheckUsbPortSpeedUsedPsic (
// PortSpeed definition when the Major Revision is 02h.
//
if ((UsbSpeedIdMap == 0) && (Xhc->Usb2SupOffset != 0xFFFFFFFF)) {
- SpField.Dword = XhciPsivGetPsid (Xhc, Xhc->Usb2SupOffset, PortSpeed);
+ SpField.Dword = XhciPsivGetPsid (Xhc, Xhc->Usb2SupOffset, PortSpeed, PortNumber);
if (SpField.Dword != 0) {
//
// Found the corresponding PORTSC value in PSIV field of USB2 offset.
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h
index 5fe2ba4f0e..2e4f95f8ac 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h
@@ -623,8 +623,9 @@ XhcGetSupportedProtocolCapabilityAddr (
/**
Find SpeedField value match with Port Speed ID value.
- @param Xhc The XHCI Instance.
- @param Speed The Port Speed filed in USB PortSc register
+ @param Xhc The XHCI Instance.
+ @param Speed The Port Speed filed in USB PortSc register
+ @param PortNumber The Port Number (0-indexed)
@return The USB Port Speed.
@@ -632,7 +633,8 @@ XhcGetSupportedProtocolCapabilityAddr (
UINT16
XhcCheckUsbPortSpeedUsedPsic (
IN USB_XHCI_INSTANCE *Xhc,
- IN UINT8 Speed
+ IN UINT8 Speed,
+ IN UINT8 PortNumber
);
#endif
--
2.37.2
next prev parent reply other threads:[~2022-12-16 8:58 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-16 8:58 [PATCH 1/3] MdeModulePkg/BmBoot: Skip removable media if it is not present Sean Rhodes
2022-12-16 8:58 ` [PATCH 2/3] MdeModulePkg/XhciDxe/Xhci: Don't check for invalid PSIV Sean Rhodes
2022-12-19 6:16 ` Wu, Hao A
2022-12-21 0:48 ` [edk2-devel] " Wu, Hao A
2022-12-16 8:58 ` Sean Rhodes [this message]
2022-12-19 7:46 ` [edk2-devel] [PATCH 3/3] MdeModulePkg/Bus/Pci/XhciDxe: Check port is compatible before getting PSIV Wu, Hao A
2022-12-21 0:49 ` Wu, Hao A
2022-12-16 9:03 ` [edk2-devel] [PATCH 1/3] MdeModulePkg/BmBoot: Skip removable media if it is not present Ni, Ray
2023-01-28 19:01 ` Sean Rhodes
2023-02-13 10:01 ` Sheng Lean Tan
2023-02-13 11:56 ` Ni, Ray
2023-02-17 12:56 ` Sheng Lean Tan
[not found] ` <17449DF2E9A4F10E.28744@groups.io>
2023-03-06 9:57 ` Sheng Lean Tan
2023-03-07 11:32 ` Sheng Lean Tan
2023-03-08 8:54 ` Sheng Lean Tan
2023-03-08 8:57 ` Ni, Ray
2023-03-09 0:54 ` 回复: " gaoliming
2023-03-10 11:29 ` [edk2-devel] " Sheng Lean Tan
2023-03-15 16:41 ` Sheng Lean Tan
2023-03-17 3:03 ` 回复: " gaoliming
[not found] ` <174A9A2823F47D61.24021@groups.io>
2023-03-10 2:20 ` gaoliming
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c7e37678b5d46e196e1c473b63df023fcf619122.1671181085.git.sean@starlabs.systems \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox