From mboxrd@z Thu Jan 1 00:00:00 1970 Subject: [PATCH] MdeModulePkg/XhciDxe: Allocate the Ring segments at 64K aligned address to avoid the Rings crossing a 64K byte boundary. To: devel@edk2.groups.io From: "Jiading Zhang" X-Originating-Location: Beijing, CN (218.247.145.3) X-Originating-Platform: Windows Chrome 106 User-Agent: GROUPS.IO Web Poster MIME-Version: 1.0 Date: Mon, 10 Oct 2022 19:21:11 -0700 Message-ID: Content-Type: multipart/alternative; boundary="i7HkbBfpkBXUGakT6wxi" --i7HkbBfpkBXUGakT6wxi Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable According the Xhci Spec, TRB Rings may be larger than a Page, however they = shall not cross a 64K byte boundary, so allocate the rings at 64K aligned a= ddress to avoid they crossing a 64K byte boundary. Signed-off-by: jdzhang --- MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c | 112 +++++++++++------------ MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h |=C2=A0 =C2=A04 + 2 files changed, 56 insertions(+), 60 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pc= i/XhciDxe/XhciSched.c index 4ae0297607..b020bb064b 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c +++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c @@ -473,7 +473,6 @@ XhcInitSched ( { VOID=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *Dcbaa; EFI_PHYSICAL_ADDRESS=C2=A0 DcbaaPhy; -=C2=A0 UINT64=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 CmdRi= ng; EFI_PHYSICAL_ADDRESS=C2=A0 CmdRingPhy; UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Entries; UINT32=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 MaxScratchpad= Bufs; @@ -602,8 +601,7 @@ XhcInitSched ( // Transfer Ring it checks for a Cycle bit transition. If a transition dete= cted, the ring is empty. // So we set RCS as inverted PCS init value to let Command Ring empty // -=C2=A0 CmdRing=C2=A0 =C2=A0 =3D (UINT64)(UINTN)Xhc->CmdRing.RingSeg0; -=C2=A0 CmdRingPhy =3D UsbHcGetPciAddrForHostAddr (Xhc->MemPool, (VOID *)(U= INTN)CmdRing, sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER); +=C2=A0 CmdRingPhy =3D (UINT64)(UINTN)Xhc->CmdRing.RingPhy; ASSERT ((CmdRingPhy & 0x3F) =3D=3D 0); CmdRingPhy |=3D XHC_CRCR_RCS; // @@ -790,23 +788,28 @@ CreateEventRing ( EVENT_RING_SEG_TABLE_ENTRY=C2=A0 *ERSTBase; UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0Size; EFI_PHYSICAL_ADDRESS=C2=A0 =C2=A0 =C2=A0 =C2=A0 ERSTPhy; -=C2=A0 EFI_PHYSICAL_ADDRESS=C2=A0 =C2=A0 =C2=A0 =C2=A0 DequeuePhy; +=C2=A0 EFI_STATUS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 Status; ASSERT (EventRing !=3D NULL); - + +=C2=A0 //To meet the 64KB Boundary Requirement in xhci spec chapter 6=C2= =A0 Table 6-1, allocate the Ring segments at 64K aligned address. Size =3D sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER; -=C2=A0 Buf=C2=A0 =3D UsbHcAllocateMem (Xhc->MemPool, Size); -=C2=A0 ASSERT (Buf !=3D NULL); -=C2=A0 ASSERT (((UINTN)Buf & 0x3F) =3D=3D 0); -=C2=A0 ZeroMem (Buf, Size); +=C2=A0 Status =3D UsbHcAllocateAlignedPages ( +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Xhc->PciIo, +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0EFI_SIZE_TO_PAGES (Size), +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIZE_64KB, +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(VOID **) &(EventRing->EventRingS= eg0), +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&(EventRing->EventRingPhy), +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&(EventRing->EventRingMap) +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0); +=C2=A0 ASSERT_EFI_ERROR (Status); + +=C2=A0 ZeroMem (EventRing->EventRingSeg0, Size); -=C2=A0 EventRing->EventRingSeg0=C2=A0 =C2=A0 =3D Buf; EventRing->TrbNumber=C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D EVENT_RING_TRB_NUMBER; EventRing->EventRingDequeue =3D (TRB_TEMPLATE *)EventRing->EventRingSeg0; EventRing->EventRingEnqueue =3D (TRB_TEMPLATE *)EventRing->EventRingSeg0; -=C2=A0 DequeuePhy =3D UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Buf, Size)= ; - // // Software maintains an Event Ring Consumer Cycle State (CCS) bit, initial= izing it to '1' // and toggling it every time the Event Ring Dequeue Pointer wraps back to = the beginning of the Event Ring. @@ -821,8 +824,8 @@ CreateEventRing ( ERSTBase=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D (EVENT_RING_SE= G_TABLE_ENTRY *)Buf; EventRing->ERSTBase=C2=A0 =C2=A0=3D ERSTBase; -=C2=A0 ERSTBase->PtrLo=C2=A0 =C2=A0 =C2=A0 =C2=A0=3D XHC_LOW_32BIT (Dequeu= ePhy); -=C2=A0 ERSTBase->PtrHi=C2=A0 =C2=A0 =C2=A0 =C2=A0=3D XHC_HIGH_32BIT (Deque= uePhy); +=C2=A0 ERSTBase->PtrLo=C2=A0 =C2=A0 =C2=A0 =C2=A0=3D XHC_LOW_32BIT (EventR= ing->EventRingPhy); +=C2=A0 ERSTBase->PtrHi=C2=A0 =C2=A0 =C2=A0 =C2=A0=3D XHC_HIGH_32BIT (Event= Ring->EventRingPhy); ERSTBase->RingTrbSize =3D EVENT_RING_TRB_NUMBER; ERSTPhy =3D UsbHcGetPciAddrForHostAddr (Xhc->MemPool, ERSTBase, Size); @@ -844,12 +847,12 @@ CreateEventRing ( XhcWriteRuntimeReg ( Xhc, XHC_ERDP_OFFSET, -=C2=A0 =C2=A0 XHC_LOW_32BIT ((UINT64)(UINTN)DequeuePhy) +=C2=A0 =C2=A0 XHC_LOW_32BIT ((UINT64)(UINTN)EventRing->EventRingPhy) ); XhcWriteRuntimeReg ( Xhc, XHC_ERDP_OFFSET + 4, -=C2=A0 =C2=A0 XHC_HIGH_32BIT ((UINT64)(UINTN)DequeuePhy) +=C2=A0 =C2=A0 XHC_HIGH_32BIT ((UINT64)(UINTN)EventRing->EventRingPhy) ); // // Program the Interrupter Event Ring Segment Table Base Address (ERSTBA) r= egister(5.5.2.3.2) @@ -888,16 +891,24 @@ CreateTransferRing ( OUT TRANSFER_RING=C2=A0 =C2=A0 =C2=A0 *TransferRing ) { -=C2=A0 VOID=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = *Buf; +=C2=A0 UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= Size; LINK_TRB=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *EndTrb; -=C2=A0 EFI_PHYSICAL_ADDRESS=C2=A0 PhyAddr; - -=C2=A0 Buf =3D UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * Trb= Num); -=C2=A0 ASSERT (Buf !=3D NULL); -=C2=A0 ASSERT (((UINTN)Buf & 0x3F) =3D=3D 0); -=C2=A0 ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum); +=C2=A0 EFI_STATUS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Status; + +=C2=A0 //To meet the 64KB Boundary Requirement in xhci spec chapter 6=C2= =A0 Table 6-1, allocate the Ring segments at 64K aligned address. +=C2=A0 Size =3D sizeof (TRB_TEMPLATE) * TrbNum; +=C2=A0 Status =3D UsbHcAllocateAlignedPages ( +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Xhc->PciIo, +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0EFI_SIZE_TO_PAGES (Size), +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIZE_64KB, +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(VOID **) &(TransferRing->RingSeg= 0), +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&(TransferRing->RingPhy), +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&(TransferRing->RingMap) +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0); +=C2=A0 ASSERT_EFI_ERROR (Status); + +=C2=A0 ZeroMem (TransferRing->RingSeg0, Size); -=C2=A0 TransferRing->RingSeg0=C2=A0 =C2=A0 =3D Buf; TransferRing->TrbNumber=C2=A0 =C2=A0=3D TrbNum; TransferRing->RingEnqueue =3D (TRB_TEMPLATE *)TransferRing->RingSeg0; TransferRing->RingDequeue =3D (TRB_TEMPLATE *)TransferRing->RingSeg0; @@ -907,11 +918,10 @@ CreateTransferRing ( // To form a ring (or circular queue) a Link TRB may be inserted at the end= of a ring to // point to the first TRB in the ring. // -=C2=A0 EndTrb=C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D (LINK_TRB *)((UINTN)Buf + siz= eof (TRB_TEMPLATE) * (TrbNum - 1)); +=C2=A0 EndTrb=C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D (LINK_TRB *)((UINTN)TransferR= ing->RingSeg0 + sizeof (TRB_TEMPLATE) * (TrbNum - 1)); EndTrb->Type=C2=A0 =3D TRB_TYPE_LINK; -=C2=A0 PhyAddr=C2=A0 =C2=A0 =C2=A0 =C2=A0=3D UsbHcGetPciAddrForHostAddr (X= hc->MemPool, Buf, sizeof (TRB_TEMPLATE) * TrbNum); -=C2=A0 EndTrb->PtrLo =3D XHC_LOW_32BIT (PhyAddr); -=C2=A0 EndTrb->PtrHi =3D XHC_HIGH_32BIT (PhyAddr); +=C2=A0 EndTrb->PtrLo =3D XHC_LOW_32BIT (TransferRing->RingPhy); +=C2=A0 EndTrb->PtrHi =3D XHC_HIGH_32BIT (TransferRing->RingPhy); // // Toggle Cycle (TC). When set to '1', the xHC shall toggle its interpretat= ion of the Cycle bit. // @@ -943,7 +953,7 @@ XhcFreeEventRing ( // // Free EventRing Segment 0 // -=C2=A0 UsbHcFreeMem (Xhc->MemPool, EventRing->EventRingSeg0, sizeof (TRB_T= EMPLATE) * EVENT_RING_TRB_NUMBER); +=C2=A0 UsbHcFreeAlignedPages (Xhc->PciIo, (VOID *)(UINTN)EventRing->EventR= ingSeg0, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER),= (VOID *)EventRing->EventRingMap); // // Free ESRT table @@ -984,7 +994,7 @@ XhcFreeSched ( } if (Xhc->CmdRing.RingSeg0 !=3D NULL) { -=C2=A0 =C2=A0 UsbHcFreeMem (Xhc->MemPool, Xhc->CmdRing.RingSeg0, sizeof (T= RB_TEMPLATE) * CMD_RING_TRB_NUMBER); +=C2=A0 =C2=A0 UsbHcFreeAlignedPages (Xhc->PciIo, (VOID *)(UINTN)Xhc->CmdRi= ng.RingSeg0, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER= ), (VOID *)Xhc->CmdRing.RingMap); Xhc->CmdRing.RingSeg0 =3D NULL; } @@ -1041,8 +1051,7 @@ IsTransferRingTrb ( if (CheckedTrb->Type =3D=3D TRB_TYPE_LINK) { LinkTrb=C2=A0 =C2=A0 =3D (LINK_TRB *)CheckedTrb; PhyAddr=C2=A0 =C2=A0 =3D (EFI_PHYSICAL_ADDRESS)(LinkTrb->PtrLo | LShiftU64 = ((UINT64)LinkTrb->PtrHi, 32)); -=C2=A0 =C2=A0 =C2=A0 CheckedTrb =3D (TRB_TEMPLATE *)(UINTN)UsbHcGetHostAdd= rForPciAddr (Xhc->MemPool, (VOID *)(UINTN)PhyAddr, sizeof (TRB_TEMPLATE)); -=C2=A0 =C2=A0 =C2=A0 ASSERT (CheckedTrb =3D=3D Urb->Ring->RingSeg0); +=C2=A0 =C2=A0 =C2=A0 ASSERT (PhyAddr =3D=3D Urb->Ring->RingPhy); } } @@ -1150,8 +1159,7 @@ XhcCheckUrbResult ( // Need convert pci device address to host address // PhyAddr =3D (EFI_PHYSICAL_ADDRESS)(EvtTrb->TRBPtrLo | LShiftU64 ((UINT64)Ev= tTrb->TRBPtrHi, 32)); -=C2=A0 =C2=A0 TRBPtr=C2=A0 =3D (TRB_TEMPLATE *)(UINTN)UsbHcGetHostAddrForP= ciAddr (Xhc->MemPool, (VOID *)(UINTN)PhyAddr, sizeof (TRB_TEMPLATE)); - +=C2=A0 =C2=A0 TRBPtr=C2=A0 =3D (TRB_TEMPLATE *)((UINTN)(VOID*)Xhc->EventRi= ng.EventRingSeg0 + (UINTN)(PhyAddr - Xhc->EventRing.EventRingPhy)); // // Update the status of URB including the pending URB, the URB that is curr= ently checked, // and URBs in the XHCI's async interrupt transfer list. @@ -1255,7 +1263,7 @@ EXIT: High=C2=A0 =C2=A0 =C2=A0 =C2=A0=3D XhcReadRuntimeReg (Xhc, XHC_ERDP_OFFSET = + 4); XhcDequeue =3D (UINT64)(LShiftU64 ((UINT64)High, 32) | Low); -=C2=A0 PhyAddr =3D UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->EventRin= g.EventRingDequeue, sizeof (TRB_TEMPLATE)); +=C2=A0 PhyAddr =3D Xhc->EventRing.EventRingPhy + (UINT64)((UINTN)(VOID *)(= Xhc->EventRing.EventRingDequeue) - (UINTN)(Xhc->EventRing.EventRingSeg0)); if ((XhcDequeue & (~0x0F)) !=3D (PhyAddr & (~0x0F))) { // @@ -2273,11 +2281,7 @@ XhcInitializeDeviceSlot ( // // Init the DCS(dequeue cycle state) as the transfer ring's CCS // -=C2=A0 PhyAddr =3D UsbHcGetPciAddrForHostAddr ( -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Xhc->MemPool, -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ((TRANSFER_RING *)(UINTN)= Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0, -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sizeof (TRB_TEMPLATE) * T= R_RING_TRB_NUMBER -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ); +=C2=A0 PhyAddr =3D ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].End= pointTransferRing[0])->RingPhy; InputContext->EP[0].PtrLo =3D XHC_LOW_32BIT (PhyAddr) | BIT0; InputContext->EP[0].PtrHi =3D XHC_HIGH_32BIT (PhyAddr); @@ -2489,11 +2493,7 @@ XhcInitializeDeviceSlot64 ( // // Init the DCS(dequeue cycle state) as the transfer ring's CCS // -=C2=A0 PhyAddr =3D UsbHcGetPciAddrForHostAddr ( -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Xhc->MemPool, -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ((TRANSFER_RING *)(UINTN)= Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0, -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sizeof (TRB_TEMPLATE) * T= R_RING_TRB_NUMBER -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ); +=C2=A0 PhyAddr =3D ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].End= pointTransferRing[0])->RingPhy; InputContext->EP[0].PtrLo =3D XHC_LOW_32BIT (PhyAddr) | BIT0; InputContext->EP[0].PtrHi =3D XHC_HIGH_32BIT (PhyAddr); @@ -2623,7 +2623,7 @@ XhcDisableSlotCmd ( if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] !=3D NULL) { RingSeg =3D ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTra= nsferRing[Index])->RingSeg0; if (RingSeg !=3D NULL) { -=C2=A0 =C2=A0 =C2=A0 =C2=A0 UsbHcFreeMem (Xhc->MemPool, RingSeg, sizeof (T= RB_TEMPLATE) * TR_RING_TRB_NUMBER); +=C2=A0 =C2=A0 =C2=A0 =C2=A0 UsbHcFreeAlignedPages (Xhc->PciIo, (VOID *)(UI= NTN)RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER)= , ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[= Index])->RingMap); } FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]); @@ -2734,7 +2734,7 @@ XhcDisableSlotCmd64 ( if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] !=3D NULL) { RingSeg =3D ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTra= nsferRing[Index])->RingSeg0; if (RingSeg !=3D NULL) { -=C2=A0 =C2=A0 =C2=A0 =C2=A0 UsbHcFreeMem (Xhc->MemPool, RingSeg, sizeof (T= RB_TEMPLATE) * TR_RING_TRB_NUMBER); +=C2=A0 =C2=A0 =C2=A0 =C2=A0 UsbHcFreeAlignedPages (Xhc->PciIo, (VOID *)(UI= NTN)RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER)= ,((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[I= ndex])->RingMap); } FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]); @@ -2954,11 +2954,7 @@ XhcInitializeEndpointContext ( continue; } -=C2=A0 =C2=A0 PhyAddr =3D UsbHcGetPciAddrForHostAddr ( -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Xhc->MemPool, -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ((TRANSFER_RING *)= (UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0, -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sizeof (TRB_TEMPLA= TE) * TR_RING_TRB_NUMBER -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ); +=C2=A0 =C2=A0 PhyAddr =3D ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[Slot= Id].EndpointTransferRing[Dci-1])->RingPhy; PhyAddr=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 &=3D ~((EFI_PHYSICAL_ADDRESS)0x0F); PhyAddr=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 |=3D (EFI_PHYSICAL_ADDRESS)((TRANSFER_RING *)(UINTN)Xhc->UsbDevC= ontext[SlotId].EndpointTransferRing[Dci-1])->RingPCS; InputContext->EP[Dci-1].PtrLo =3D XHC_LOW_32BIT (PhyAddr); @@ -3153,11 +3149,7 @@ XhcInitializeEndpointContext64 ( continue; } -=C2=A0 =C2=A0 PhyAddr =3D UsbHcGetPciAddrForHostAddr ( -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Xhc->MemPool, -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ((TRANSFER_RING *)= (UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0, -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sizeof (TRB_TEMPLA= TE) * TR_RING_TRB_NUMBER -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ); +=C2=A0 =C2=A0 PhyAddr =3D ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[Slot= Id].EndpointTransferRing[Dci-1])->RingPhy; PhyAddr=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 &=3D ~((EFI_PHYSICAL_ADDRESS)0x0F); PhyAddr=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 |=3D (EFI_PHYSICAL_ADDRESS)((TRANSFER_RING *)(UINTN)Xhc->UsbDevC= ontext[SlotId].EndpointTransferRing[Dci-1])->RingPCS; InputContext->EP[Dci-1].PtrLo =3D XHC_LOW_32BIT (PhyAddr); @@ -3503,7 +3495,7 @@ XhcSetTrDequeuePointer ( // Send stop endpoint command to transit Endpoint from running to stop stat= e // ZeroMem (&CmdSetTRDeq, sizeof (CmdSetTRDeq)); -=C2=A0 PhyAddr=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D UsbHcGe= tPciAddrForHostAddr (Xhc->MemPool, Urb->Ring->RingEnqueue, sizeof (CMD_SET_= TR_DEQ_POINTER)); +=C2=A0 PhyAddr=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D Urb->Ri= ng->RingPhy + (UINT64)((UINTN)(VOID *)(Xhc->EventRing.EventRingEnqueue) - (= UINTN)(Xhc->EventRing.EventRingSeg0)); CmdSetTRDeq.PtrLo=C2=A0 =C2=A0 =3D XHC_LOW_32BIT (PhyAddr) | Urb->Ring->Rin= gPCS; CmdSetTRDeq.PtrHi=C2=A0 =C2=A0 =3D XHC_HIGH_32BIT (PhyAddr); CmdSetTRDeq.CycleBit =3D 1; @@ -3661,7 +3653,7 @@ XhcSetInterface ( if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] !=3D NULL) { RingSeg =3D ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTra= nsferRing[Dci - 1])->RingSeg0; if (RingSeg !=3D NULL) { -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 UsbHcFreeMem (Xhc->MemPool, RingSeg, si= zeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER); +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 UsbHcFreeAlignedPages (Xhc->PciIo, (VOI= D *)(UINTN)RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_RING_TRB_= NUMBER), ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransf= erRing[Dci - 1])->RingMap); } FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1]); @@ -3867,7 +3859,7 @@ XhcSetInterface64 ( if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] !=3D NULL) { RingSeg =3D ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTra= nsferRing[Dci - 1])->RingSeg0; if (RingSeg !=3D NULL) { -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 UsbHcFreeMem (Xhc->MemPool, RingSeg, si= zeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER); +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 UsbHcFreeAlignedPages (Xhc->PciIo, (VOI= D *)(UINTN)RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_RING_TRB_= NUMBER), ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransf= erRing[Dci - 1])->RingMap); } FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1]); diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h b/MdeModulePkg/Bus/Pc= i/XhciDxe/XhciSched.h index 7c85f7993b..e9792b5941 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h +++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h @@ -144,6 +144,8 @@ typedef struct _TRANSFER_RING { TRB_TEMPLATE=C2=A0 =C2=A0 *RingEnqueue; TRB_TEMPLATE=C2=A0 =C2=A0 *RingDequeue; UINT32=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 RingPCS; +=C2=A0 EFI_PHYSICAL_ADDRESS=C2=A0 RingPhy; +=C2=A0 VOID=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *RingMap; } TRANSFER_RING; typedef struct _EVENT_RING { @@ -153,6 +155,8 @@ typedef struct _EVENT_RING { TRB_TEMPLATE=C2=A0 =C2=A0 *EventRingEnqueue; TRB_TEMPLATE=C2=A0 =C2=A0 *EventRingDequeue; UINT32=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 EventRingCCS; +=C2=A0 EFI_PHYSICAL_ADDRESS=C2=A0 EventRingPhy; +=C2=A0 VOID=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *EventRingMap; } EVENT_RING; // -- 2.20.1.windows.1 --i7HkbBfpkBXUGakT6wxi Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable
According the Xhci Spec, TRB Rings may be larger than a Page, however = they shall not cross a 64K byte boundary, so allocate the rings at 64K alig= ned address to avoid they crossing a 64K byte boundary.
 
Signed-off-by: jdzhang <jdzhang@kunluntech.com.cn>
---
 MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c | 112 +++++++++++------= ------
 MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h |   4 +
 2 files changed, 56 insertions(+), 60 deletions(-)
 
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/B= us/Pci/XhciDxe/XhciSched.c
index 4ae0297607..b020bb064b 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
@@ -473,7 +473,6 @@ XhcInitSched (
 {
   VOID              &nbs= p;   *Dcbaa;
   EFI_PHYSICAL_ADDRESS  DcbaaPhy;
-  UINT64                = CmdRing;
   EFI_PHYSICAL_ADDRESS  CmdRingPhy;
   UINTN              &nb= sp;  Entries;
   UINT32              &n= bsp; MaxScratchpadBufs;
@@ -602,8 +601,7 @@ XhcInitSched (
   // Transfer Ring it checks for a Cycle bit transition. If= a transition detected, the ring is empty.
   // So we set RCS as inverted PCS init value to let Comman= d Ring empty
   //
-  CmdRing    =3D (UINT64)(UINTN)Xhc->CmdRing.RingSe= g0;
-  CmdRingPhy =3D UsbHcGetPciAddrForHostAddr (Xhc->MemPool, (V= OID *)(UINTN)CmdRing, sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER);
+  CmdRingPhy =3D (UINT64)(UINTN)Xhc->CmdRing.RingPhy;
   ASSERT ((CmdRingPhy & 0x3F) =3D=3D 0);
   CmdRingPhy |=3D XHC_CRCR_RCS;
   //
@@ -790,23 +788,28 @@ CreateEventRing (
   EVENT_RING_SEG_TABLE_ENTRY  *ERSTBase;
   UINTN              &nb= sp;        Size;
   EFI_PHYSICAL_ADDRESS        ERSTPhy;<= /div>
-  EFI_PHYSICAL_ADDRESS        DequeuePhy;
+  EFI_STATUS              &nb= sp;   Status;
 
   ASSERT (EventRing !=3D NULL);
-
+  
+  //To meet the 64KB Boundary Requirement in xhci spec chapter 6=   Table 6-1, allocate the Ring segments at 64K aligned address.
   Size =3D sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER;
-  Buf  =3D UsbHcAllocateMem (Xhc->MemPool, Size);
-  ASSERT (Buf !=3D NULL);
-  ASSERT (((UINTN)Buf & 0x3F) =3D=3D 0);
-  ZeroMem (Buf, Size);
+  Status =3D UsbHcAllocateAlignedPages (
+           Xhc->PciIo,
+           EFI_SIZE_TO_PAGES (Size),
+           SIZE_64KB,
+           (VOID **) &(EventRing-&g= t;EventRingSeg0),
+           &(EventRing->EventRin= gPhy),
+           &(EventRing->EventRin= gMap)
+           );
+  ASSERT_EFI_ERROR (Status);
+  
+  ZeroMem (EventRing->EventRingSeg0, Size);
 
-  EventRing->EventRingSeg0    =3D Buf;
   EventRing->TrbNumber        =3D EV= ENT_RING_TRB_NUMBER;
   EventRing->EventRingDequeue =3D (TRB_TEMPLATE *)EventR= ing->EventRingSeg0;
   EventRing->EventRingEnqueue =3D (TRB_TEMPLATE *)EventR= ing->EventRingSeg0;
 
-  DequeuePhy =3D UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Bu= f, Size);
-
   //
   // Software maintains an Event Ring Consumer Cycle State = (CCS) bit, initializing it to '1'
   // and toggling it every time the Event Ring Dequeue Poin= ter wraps back to the beginning of the Event Ring.
@@ -821,8 +824,8 @@ CreateEventRing (
 
   ERSTBase              = =3D (EVENT_RING_SEG_TABLE_ENTRY *)Buf;
   EventRing->ERSTBase   =3D ERSTBase;
-  ERSTBase->PtrLo       =3D XHC_LOW_32BIT= (DequeuePhy);
-  ERSTBase->PtrHi       =3D XHC_HIGH_32BI= T (DequeuePhy);
+  ERSTBase->PtrLo       =3D XHC_LOW_32BIT= (EventRing->EventRingPhy);
+  ERSTBase->PtrHi       =3D XHC_HIGH_32BI= T (EventRing->EventRingPhy);
   ERSTBase->RingTrbSize =3D EVENT_RING_TRB_NUMBER;
 
   ERSTPhy =3D UsbHcGetPciAddrForHostAddr (Xhc->MemPool, = ERSTBase, Size);
@@ -844,12 +847,12 @@ CreateEventRing (
   XhcWriteRuntimeReg (
     Xhc,
     XHC_ERDP_OFFSET,
-    XHC_LOW_32BIT ((UINT64)(UINTN)DequeuePhy)
+    XHC_LOW_32BIT ((UINT64)(UINTN)EventRing->EventRingPh= y)
     );
   XhcWriteRuntimeReg (
     Xhc,
     XHC_ERDP_OFFSET + 4,
-    XHC_HIGH_32BIT ((UINT64)(UINTN)DequeuePhy)
+    XHC_HIGH_32BIT ((UINT64)(UINTN)EventRing->EventRingP= hy)
     );
   //
   // Program the Interrupter Event Ring Segment Table Base = Address (ERSTBA) register(5.5.2.3.2)
@@ -888,16 +891,24 @@ CreateTransferRing (
   OUT TRANSFER_RING      *TransferRing
   )
 {
-  VOID                &n= bsp; *Buf;
+  UINTN                &= nbsp;Size;
   LINK_TRB              = *EndTrb;
-  EFI_PHYSICAL_ADDRESS  PhyAddr;
-
-  Buf =3D UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLAT= E) * TrbNum);
-  ASSERT (Buf !=3D NULL);
-  ASSERT (((UINTN)Buf & 0x3F) =3D=3D 0);
-  ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum);
+  EFI_STATUS            Status;
+  
+  //To meet the 64KB Boundary Requirement in xhci spec chapter 6=   Table 6-1, allocate the Ring segments at 64K aligned address.
+  Size =3D sizeof (TRB_TEMPLATE) * TrbNum;
+  Status =3D UsbHcAllocateAlignedPages (
+           Xhc->PciIo,
+           EFI_SIZE_TO_PAGES (Size),
+           SIZE_64KB,
+           (VOID **) &(TransferRing= ->RingSeg0),
+           &(TransferRing->RingP= hy),
+           &(TransferRing->RingM= ap)
+           );
+  ASSERT_EFI_ERROR (Status);
+      
+  ZeroMem (TransferRing->RingSeg0, Size);
 
-  TransferRing->RingSeg0    =3D Buf;
   TransferRing->TrbNumber   =3D TrbNum;
   TransferRing->RingEnqueue =3D (TRB_TEMPLATE *)Transfer= Ring->RingSeg0;
   TransferRing->RingDequeue =3D (TRB_TEMPLATE *)Transfer= Ring->RingSeg0;
@@ -907,11 +918,10 @@ CreateTransferRing (
   // To form a ring (or circular queue) a Link TRB may be i= nserted at the end of a ring to
   // point to the first TRB in the ring.
   //
-  EndTrb        =3D (LINK_TRB *)((UINTN)Buf = + sizeof (TRB_TEMPLATE) * (TrbNum - 1));
+  EndTrb        =3D (LINK_TRB *)((UINTN)Tran= sferRing->RingSeg0 + sizeof (TRB_TEMPLATE) * (TrbNum - 1));
   EndTrb->Type  =3D TRB_TYPE_LINK;
-  PhyAddr       =3D UsbHcGetPciAddrForHostAd= dr (Xhc->MemPool, Buf, sizeof (TRB_TEMPLATE) * TrbNum);
-  EndTrb->PtrLo =3D XHC_LOW_32BIT (PhyAddr);
-  EndTrb->PtrHi =3D XHC_HIGH_32BIT (PhyAddr);
+  EndTrb->PtrLo =3D XHC_LOW_32BIT (TransferRing->RingPhy);=
+  EndTrb->PtrHi =3D XHC_HIGH_32BIT (TransferRing->RingPhy)= ;
   //
   // Toggle Cycle (TC). When set to '1', the xHC shall togg= le its interpretation of the Cycle bit.
   //
@@ -943,7 +953,7 @@ XhcFreeEventRing (
   //
   // Free EventRing Segment 0
   //
-  UsbHcFreeMem (Xhc->MemPool, EventRing->EventRingSeg0, si= zeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER);
+  UsbHcFreeAlignedPages (Xhc->PciIo, (VOID *)(UINTN)EventRing= ->EventRingSeg0, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * EVENT_RING_T= RB_NUMBER), (VOID *)EventRing->EventRingMap);
 
   //
   // Free ESRT table
@@ -984,7 +994,7 @@ XhcFreeSched (
   }
 
   if (Xhc->CmdRing.RingSeg0 !=3D NULL) {
-    UsbHcFreeMem (Xhc->MemPool, Xhc->CmdRing.RingSeg0= , sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER);
+    UsbHcFreeAlignedPages (Xhc->PciIo, (VOID *)(UINTN)Xh= c->CmdRing.RingSeg0, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * CMD_RING= _TRB_NUMBER), (VOID *)Xhc->CmdRing.RingMap);
     Xhc->CmdRing.RingSeg0 =3D NULL;
   }
 
@@ -1041,8 +1051,7 @@ IsTransferRingTrb (
     if (CheckedTrb->Type =3D=3D TRB_TYPE_LINK) {
       LinkTrb    =3D (LINK_TRB *)Checke= dTrb;
       PhyAddr    =3D (EFI_PHYSICAL_ADDR= ESS)(LinkTrb->PtrLo | LShiftU64 ((UINT64)LinkTrb->PtrHi, 32));
-      CheckedTrb =3D (TRB_TEMPLATE *)(UINTN)UsbHcGetHo= stAddrForPciAddr (Xhc->MemPool, (VOID *)(UINTN)PhyAddr, sizeof (TRB_TEMP= LATE));
-      ASSERT (CheckedTrb =3D=3D Urb->Ring->RingS= eg0);
+      ASSERT (PhyAddr =3D=3D Urb->Ring->RingPhy)= ;
     }
   }
 
@@ -1150,8 +1159,7 @@ XhcCheckUrbResult (
     // Need convert pci device address to host address=
     //
     PhyAddr =3D (EFI_PHYSICAL_ADDRESS)(EvtTrb->TRBP= trLo | LShiftU64 ((UINT64)EvtTrb->TRBPtrHi, 32));
-    TRBPtr  =3D (TRB_TEMPLATE *)(UINTN)UsbHcGetHostAdd= rForPciAddr (Xhc->MemPool, (VOID *)(UINTN)PhyAddr, sizeof (TRB_TEMPLATE)= );
-
+    TRBPtr  =3D (TRB_TEMPLATE *)((UINTN)(VOID*)Xhc->= ;EventRing.EventRingSeg0 + (UINTN)(PhyAddr - Xhc->EventRing.EventRingPhy= ));
     //
     // Update the status of URB including the pending = URB, the URB that is currently checked,
     // and URBs in the XHCI's async interrupt transfer= list.
@@ -1255,7 +1263,7 @@ EXIT:
   High       =3D XhcReadRuntimeReg (Xhc= , XHC_ERDP_OFFSET + 4);
   XhcDequeue =3D (UINT64)(LShiftU64 ((UINT64)High, 32) | Lo= w);
 
-  PhyAddr =3D UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc-&= gt;EventRing.EventRingDequeue, sizeof (TRB_TEMPLATE));
+  PhyAddr =3D Xhc->EventRing.EventRingPhy + (UINT64)((UINTN)(= VOID *)(Xhc->EventRing.EventRingDequeue) - (UINTN)(Xhc->EventRing.Eve= ntRingSeg0));
 
   if ((XhcDequeue & (~0x0F)) !=3D (PhyAddr & (~0x0F= ))) {
     //
@@ -2273,11 +2281,7 @@ XhcInitializeDeviceSlot (
   //
   // Init the DCS(dequeue cycle state) as the transfer ring= 's CCS
   //
-  PhyAddr =3D UsbHcGetPciAddrForHostAddr (
-              Xhc->MemPool,
-              ((TRANSFER_RING *)(U= INTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0,
-              sizeof (TRB_TEMPLATE= ) * TR_RING_TRB_NUMBER
-              );
+  PhyAddr =3D ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[Slo= tId].EndpointTransferRing[0])->RingPhy;
   InputContext->EP[0].PtrLo =3D XHC_LOW_32BIT (PhyAddr) = | BIT0;
   InputContext->EP[0].PtrHi =3D XHC_HIGH_32BIT (PhyAddr)= ;
 
@@ -2489,11 +2493,7 @@ XhcInitializeDeviceSlot64 (
   //
   // Init the DCS(dequeue cycle state) as the transfer ring= 's CCS
   //
-  PhyAddr =3D UsbHcGetPciAddrForHostAddr (
-              Xhc->MemPool,
-              ((TRANSFER_RING *)(U= INTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0,
-              sizeof (TRB_TEMPLATE= ) * TR_RING_TRB_NUMBER
-              );
+  PhyAddr =3D ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[Slo= tId].EndpointTransferRing[0])->RingPhy;
   InputContext->EP[0].PtrLo =3D XHC_LOW_32BIT (PhyAddr) = | BIT0;
   InputContext->EP[0].PtrHi =3D XHC_HIGH_32BIT (PhyAddr)= ;
 
@@ -2623,7 +2623,7 @@ XhcDisableSlotCmd (
     if (Xhc->UsbDevContext[SlotId].EndpointTransfer= Ring[Index] !=3D NULL) {
       RingSeg =3D ((TRANSFER_RING *)(UINTN)Xhc-&g= t;UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0;
       if (RingSeg !=3D NULL) {
-        UsbHcFreeMem (Xhc->MemPool, RingSeg, s= izeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER);
+        UsbHcFreeAlignedPages (Xhc->PciIo, (VO= ID *)(UINTN)RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_RING_TRB= _NUMBER), ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTr= ansferRing[Index])->RingMap);
       }
 
       FreePool (Xhc->UsbDevContext[SlotId].End= pointTransferRing[Index]);
@@ -2734,7 +2734,7 @@ XhcDisableSlotCmd64 (
     if (Xhc->UsbDevContext[SlotId].EndpointTransfer= Ring[Index] !=3D NULL) {
       RingSeg =3D ((TRANSFER_RING *)(UINTN)Xhc-&g= t;UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0;
       if (RingSeg !=3D NULL) {
-        UsbHcFreeMem (Xhc->MemPool, RingSeg, s= izeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER);
+        UsbHcFreeAlignedPages (Xhc->PciIo, (VO= ID *)(UINTN)RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_RING_TRB= _NUMBER),((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTra= nsferRing[Index])->RingMap);
       }
 
       FreePool (Xhc->UsbDevContext[SlotId].End= pointTransferRing[Index]);
@@ -2954,11 +2954,7 @@ XhcInitializeEndpointContext (
         continue;
     }
 
-    PhyAddr =3D UsbHcGetPciAddrForHostAddr (
-                Xhc->MemPo= ol,
-                ((TRANSFER_RI= NG *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->= RingSeg0,
-                sizeof (TRB_T= EMPLATE) * TR_RING_TRB_NUMBER
-                );
+    PhyAddr =3D ((TRANSFER_RING *)(UINTN)Xhc->UsbDevCont= ext[SlotId].EndpointTransferRing[Dci-1])->RingPhy;
     PhyAddr            &= nbsp;         &=3D ~((EFI_PHYSICAL_ADDRESS)0x0F);
     PhyAddr            &= nbsp;         |=3D (EFI_PHYSICAL_ADDRESS)((TRANSFER_RIN= G *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->R= ingPCS;
     InputContext->EP[Dci-1].PtrLo =3D XHC_LOW_32BIT= (PhyAddr);
@@ -3153,11 +3149,7 @@ XhcInitializeEndpointContext64 (
         continue;
     }
 
-    PhyAddr =3D UsbHcGetPciAddrForHostAddr (
-                Xhc->MemPo= ol,
-                ((TRANSFER_RI= NG *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->= RingSeg0,
-                sizeof (TRB_T= EMPLATE) * TR_RING_TRB_NUMBER
-                );
+    PhyAddr =3D ((TRANSFER_RING *)(UINTN)Xhc->UsbDevCont= ext[SlotId].EndpointTransferRing[Dci-1])->RingPhy;
     PhyAddr            &= nbsp;         &=3D ~((EFI_PHYSICAL_ADDRESS)0x0F);
     PhyAddr            &= nbsp;         |=3D (EFI_PHYSICAL_ADDRESS)((TRANSFER_RIN= G *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->R= ingPCS;
     InputContext->EP[Dci-1].PtrLo =3D XHC_LOW_32BIT= (PhyAddr);
@@ -3503,7 +3495,7 @@ XhcSetTrDequeuePointer (
   // Send stop endpoint command to transit Endpoint from ru= nning to stop state
   //
   ZeroMem (&CmdSetTRDeq, sizeof (CmdSetTRDeq));
-  PhyAddr              =3D Us= bHcGetPciAddrForHostAddr (Xhc->MemPool, Urb->Ring->RingEnqueue, si= zeof (CMD_SET_TR_DEQ_POINTER));
+  PhyAddr              =3D Ur= b->Ring->RingPhy + (UINT64)((UINTN)(VOID *)(Xhc->EventRing.EventRi= ngEnqueue) - (UINTN)(Xhc->EventRing.EventRingSeg0));
   CmdSetTRDeq.PtrLo    =3D XHC_LOW_32BIT (PhyAddr= ) | Urb->Ring->RingPCS;
   CmdSetTRDeq.PtrHi    =3D XHC_HIGH_32BIT (PhyAdd= r);
   CmdSetTRDeq.CycleBit =3D 1;
@@ -3661,7 +3653,7 @@ XhcSetInterface (
       if (Xhc->UsbDevContext[SlotId].EndpointT= ransferRing[Dci - 1] !=3D NULL) {
         RingSeg =3D ((TRANSFER_RING *)(UINTN= )Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1])->RingSeg0;=
         if (RingSeg !=3D NULL) {
-          UsbHcFreeMem (Xhc->MemPool, Rin= gSeg, sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER);
+          UsbHcFreeAlignedPages (Xhc->Pci= Io, (VOID *)(UINTN)RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_R= ING_TRB_NUMBER), ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].End= pointTransferRing[Dci - 1])->RingMap);
         }
 
         FreePool (Xhc->UsbDevContext[Slot= Id].EndpointTransferRing[Dci - 1]);
@@ -3867,7 +3859,7 @@ XhcSetInterface64 (
       if (Xhc->UsbDevContext[SlotId].EndpointT= ransferRing[Dci - 1] !=3D NULL) {
         RingSeg =3D ((TRANSFER_RING *)(UINTN= )Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1])->RingSeg0;=
         if (RingSeg !=3D NULL) {
-          UsbHcFreeMem (Xhc->MemPool, Rin= gSeg, sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER);
+          UsbHcFreeAlignedPages (Xhc->Pci= Io, (VOID *)(UINTN)RingSeg, EFI_SIZE_TO_PAGES (sizeof (TRB_TEMPLATE) * TR_R= ING_TRB_NUMBER), ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].End= pointTransferRing[Dci - 1])->RingMap);
         }
 
         FreePool (Xhc->UsbDevContext[Slot= Id].EndpointTransferRing[Dci - 1]);
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h b/MdeModulePkg/B= us/Pci/XhciDxe/XhciSched.h
index 7c85f7993b..e9792b5941 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h
@@ -144,6 +144,8 @@ typedef struct _TRANSFER_RING {
   TRB_TEMPLATE    *RingEnqueue;
   TRB_TEMPLATE    *RingDequeue;
   UINT32          RingPCS;
+  EFI_PHYSICAL_ADDRESS  RingPhy;
+  VOID            *RingMap;
 } TRANSFER_RING;
 
 typedef struct _EVENT_RING {
@@ -153,6 +155,8 @@ typedef struct _EVENT_RING {
   TRB_TEMPLATE    *EventRingEnqueue;
   TRB_TEMPLATE    *EventRingDequeue;
   UINT32          EventRingCCS;
+  EFI_PHYSICAL_ADDRESS  EventRingPhy;
+  VOID            *EventRingMap;
 } EVENT_RING;
 
 //
-- 
2.20.1.windows.1
 
--i7HkbBfpkBXUGakT6wxi--