[edk2-devel] [PATCH v4] MdeModulePkg/XhciDxe: Add access xHCI Extended Capabilities Pointer

Wu, Hao A hao.a.wu at intel.com
Mon Jun 27 02:53:53 UTC 2022


Merged via:
PR - https://github.com/tianocore/edk2/pull/3014
Commit - https://github.com/tianocore/edk2/commit/7f4eca4cc2e01d4160ef265f477f9d098d7d33df

Best Regards,
Hao Wu

> -----Original Message-----
> From: Wu, Hao A
> Sent: Thursday, June 23, 2022 2:50 PM
> To: devel at edk2.groups.io; Chiu, Ian <Ian.chiu at intel.com>
> Cc: Huang, Jenny <jenny.huang at intel.com>; Shih, More
> <more.shih at intel.com>; Ni, Ray <ray.ni at intel.com>
> Subject: RE: [edk2-devel] [PATCH v4] MdeModulePkg/XhciDxe: Add access
> xHCI Extended Capabilities Pointer
> 
> Reviewed-by: Hao A Wu <hao.a.wu at intel.com>
> 
> Best Regards,
> Hao Wu
> 
> > -----Original Message-----
> > From: devel at edk2.groups.io <devel at edk2.groups.io> On Behalf Of
> > ian.chiu at intel.com
> > Sent: Thursday, June 23, 2022 2:22 PM
> > To: devel at edk2.groups.io
> > Cc: Chiu, Ian <Ian.chiu at intel.com>; Huang, Jenny
> > <jenny.huang at intel.com>; Shih, More <more.shih at intel.com>; Wu, Hao A
> > <hao.a.wu at intel.com>; Ni, Ray <ray.ni at intel.com>
> > Subject: [edk2-devel] [PATCH v4] MdeModulePkg/XhciDxe: Add access xHCI
> > Extended Capabilities Pointer
> >
> > From: Ian Chiu <Ian.chiu at intel.com>
> >
> > 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 <jenny.huang at intel.com>
> > Cc: More Shih <more.shih at intel.com>
> > Cc: Hao A Wu <hao.a.wu at intel.com>
> > Cc: Ray Ni <ray.ni at intel.com>
> > Signed-off-by: Ian Chiu <Ian.chiu at intel.com>
> > ---
> >  MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c    |  39 +++--
> >  MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h    |   2 +
> >  MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c | 178 ++++++++++++++++++++
> > MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h |  92 +++++++++-
> >  4 files changed, 295 insertions(+), 16 deletions(-)
> >
> > diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
> > b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
> > index 381d7a9536..c05431ff30 100644
> > --- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
> > +++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
> > @@ -399,24 +399,31 @@ XhcGetRootHubPortStatus (
> >     //   // According to XHCI 1.1 spec November 2017,-  // bit 10~13 of the
> root
> > port status register identifies the speed of the attached device.+  // 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..2b4a4b2444 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 2017,+  //
> > 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, find the PSIV field to match+  // PortSpeed definition
> > when the Major Revision is 03h.+  //+  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, find the PSIV field to match+  // PortSpeed
> > definition when the Major Revision is 02h.+  //+  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 2017,+        // 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 in 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 2017,+        // 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 in 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 (#90711):
> > https://edk2.groups.io/g/devel/message/90711
> > Mute This Topic: https://groups.io/mt/91938253/1768737
> > Group Owner: devel+owner at edk2.groups.io
> > Unsubscribe: https://edk2.groups.io/g/devel/unsub [hao.a.wu at intel.com]
> > - =-=-=-=-=-=
> >



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#90763): https://edk2.groups.io/g/devel/message/90763
Mute This Topic: https://groups.io/mt/91938253/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list