<div> </div>
<div>According the Xhci Spec, TRB Rings may be larger than a Page, however they shall not cross a 64K byte boundary, so add a parameter to indicate whether the memory allocation is for TRB or not. It will ensure the allocation not crossing 64K boundary in UsbHcAllocMemFromBlock if the memory is allocated for TRB.</div>
<div> </div>
<div>Signed-off-by: jdzhang <jdzhang@kunluntech.com.cn></div>
<div>---</div>
<div> MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c  | 37 +++++++++++++++++++-----</div>
<div> MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h  | 10 +++++--</div>
<div> MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c | 16 +++++-----</div>
<div> 3 files changed, 44 insertions(+), 19 deletions(-)</div>
<div> </div>
<div>diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c</div>
<div>index 99fb3521d5..24714502cd 100644</div>
<div>--- a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c</div>
<div>+++ b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c</div>
<div>@@ -132,8 +132,9 @@ UsbHcFreeMemBlock (</div>
<div> /**</div>
<div>   Alloc some memory from the block.</div>
<div> </div>
<div>-  @param  Block          The memory block to allocate memory from.</div>
<div>-  @param  Units          Number of memory units to allocate.</div>
<div>+  @param  Block                The memory block to allocate memory from.</div>
<div>+  @param  Units                Number of memory units to allocate.</div>
<div>+  @param  AllocationForRing    The allocated memory is for Ring or not.</div>
<div> </div>
<div>   @return The pointer to the allocated memory. If couldn't allocate the needed memory,</div>
<div>           the return value is NULL.</div>
<div>@@ -142,7 +143,8 @@ UsbHcFreeMemBlock (</div>
<div> VOID *</div>
<div> UsbHcAllocMemFromBlock (</div>
<div>   IN  USBHC_MEM_BLOCK  *Block,</div>
<div>-  IN  UINTN            Units</div>
<div>+  IN  UINTN            Units,</div>
<div>+  IN  BOOLEAN          AllocationForTrbRing</div>
<div>   )</div>
<div> {</div>
<div>   UINTN  Byte;</div>
<div>@@ -151,12 +153,15 @@ UsbHcAllocMemFromBlock (</div>
<div>   UINT8  StartBit;</div>
<div>   UINTN  Available;</div>
<div>   UINTN  Count;</div>
<div>+  UINTN  MemUnitAddr;</div>
<div>+  UINTN  AlignmentMask;</div>
<div> </div>
<div>   ASSERT ((Block != 0) && (Units != 0));</div>
<div> </div>
<div>   StartByte = 0;</div>
<div>   StartBit  = 0;</div>
<div>   Available = 0;</div>
<div>+  AlignmentMask = ~((UINTN)USBHC_MEM_TRB_RINGS_BOUNDARY - 1);</div>
<div> </div>
<div>   for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) {</div>
<div>     //</div>
<div>@@ -165,6 +170,20 @@ UsbHcAllocMemFromBlock (</div>
<div>     // Available counts the consective number of zero bit.</div>
<div>     //</div>
<div>     if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) {</div>
<div>+      if (AllocationForTrbRing && (Available != 0)) {</div>
<div>+        MemUnitAddr = (UINTN)Block->BufHost + (Byte * 8 + Bit) * USBHC_MEM_UNIT;</div>
<div>+        if ((MemUnitAddr & AlignmentMask) != ((MemUnitAddr - USBHC_MEM_UNIT) & AlignmentMask)) {</div>
<div>+          //</div>
<div>+          // If the TRB Ring memory cross 64K-byte boundary, then restart the</div>
<div>+          // search starting at current memory unit.</div>
<div>+          // Doing so is to meet the TRB Ring boundary requirement in XHCI spec. </div>
<div>+          //</div>
<div>+          Available = 0;</div>
<div>+          StartByte = Byte;</div>
<div>+          StartBit  = Bit;</div>
<div>+        }</div>
<div>+      }</div>
<div>+</div>
<div>       Available++;</div>
<div> </div>
<div>       if (Available >= Units) {</div>
<div>@@ -438,8 +457,9 @@ UsbHcFreeMemPool (</div>
<div>   Allocate some memory from the host controller's memory pool</div>
<div>   which can be used to communicate with host controller.</div>
<div> </div>
<div>-  @param  Pool           The host controller's memory pool.</div>
<div>-  @param  Size           Size of the memory to allocate.</div>
<div>+  @param  Pool                 The host controller's memory pool.</div>
<div>+  @param  Size                 Size of the memory to allocate.</div>
<div>+  @param  AllocationForRing    The allocated memory is for Ring or not.</div>
<div> </div>
<div>   @return The allocated memory or NULL.</div>
<div> </div>
<div>@@ -447,7 +467,8 @@ UsbHcFreeMemPool (</div>
<div> VOID *</div>
<div> UsbHcAllocateMem (</div>
<div>   IN  USBHC_MEM_POOL  *Pool,</div>
<div>-  IN  UINTN           Size</div>
<div>+  IN  UINTN           Size,</div>
<div>+  IN  BOOLEAN         AllocationForRing</div>
<div>   )</div>
<div> {</div>
<div>   USBHC_MEM_BLOCK  *Head;</div>
<div>@@ -466,7 +487,7 @@ UsbHcAllocateMem (</div>
<div>   // First check whether current memory blocks can satisfy the allocation.</div>
<div>   //</div>
<div>   for (Block = Head; Block != NULL; Block = Block->Next) {</div>
<div>-    Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT);</div>
<div>+    Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT, AllocationForRing);</div>
<div> </div>
<div>     if (Mem != NULL) {</div>
<div>       ZeroMem (Mem, Size);</div>
<div>@@ -501,7 +522,7 @@ UsbHcAllocateMem (</div>
<div>   // Add the new memory block to the pool, then allocate memory from it</div>
<div>   //</div>
<div>   UsbHcInsertMemBlockToPool (Head, NewBlock);</div>
<div>-  Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT);</div>
<div>+  Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT, AllocationForRing);</div>
<div> </div>
<div>   if (Mem != NULL) {</div>
<div>     ZeroMem (Mem, Size);</div>
<div>diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h</div>
<div>index 48ae86141c..dfea0e52b3 100644</div>
<div>--- a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h</div>
<div>+++ b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h</div>
<div>@@ -48,6 +48,8 @@ typedef struct _USBHC_MEM_POOL {</div>
<div> </div>
<div> #define USBHC_MEM_ROUND(Len)  (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK))</div>
<div> </div>
<div>+#define USBHC_MEM_TRB_RINGS_BOUNDARY    SIZE_64KB</div>
<div>+</div>
<div> //</div>
<div> // Advance the byte and bit to the next bit, adjust byte accordingly.</div>
<div> //</div>
<div>@@ -92,8 +94,9 @@ UsbHcFreeMemPool (</div>
<div>   Allocate some memory from the host controller's memory pool</div>
<div>   which can be used to communicate with host controller.</div>
<div> </div>
<div>-  @param  Pool  The host controller's memory pool.</div>
<div>-  @param  Size  Size of the memory to allocate.</div>
<div>+  @param  Pool                 The host controller's memory pool.</div>
<div>+  @param  Size                 Size of the memory to allocate.</div>
<div>+  @param  AllocationForRing    The allocated memory is for Ring or not.</div>
<div> </div>
<div>   @return The allocated memory or NULL.</div>
<div> </div>
<div>@@ -101,7 +104,8 @@ UsbHcFreeMemPool (</div>
<div> VOID *</div>
<div> UsbHcAllocateMem (</div>
<div>   IN  USBHC_MEM_POOL  *Pool,</div>
<div>-  IN  UINTN           Size</div>
<div>+  IN  UINTN           Size,</div>
<div>+  IN  BOOLEAN         AllocationForRing</div>
<div>   );</div>
<div> </div>
<div> /**</div>
<div>diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c</div>
<div>index 4ae0297607..13b0400e83 100644</div>
<div>--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c</div>
<div>+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c</div>
<div>@@ -506,7 +506,7 @@ XhcInitSched (</div>
<div>   // Software shall set Device Context Base Address Array entries for unallocated Device Slots to '0'.</div>
<div>   //</div>
<div>   Entries = (Xhc->MaxSlotsEn + 1) * sizeof (UINT64);</div>
<div>-  Dcbaa   = UsbHcAllocateMem (Xhc->MemPool, Entries);</div>
<div>+  Dcbaa   = UsbHcAllocateMem (Xhc->MemPool, Entries, FALSE);</div>
<div>   ASSERT (Dcbaa != NULL);</div>
<div>   ZeroMem (Dcbaa, Entries);</div>
<div> </div>
<div>@@ -795,7 +795,7 @@ CreateEventRing (</div>
<div>   ASSERT (EventRing != NULL);</div>
<div> </div>
<div>   Size = sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER;</div>
<div>-  Buf  = UsbHcAllocateMem (Xhc->MemPool, Size);</div>
<div>+  Buf  = UsbHcAllocateMem (Xhc->MemPool, Size, TRUE);</div>
<div>   ASSERT (Buf != NULL);</div>
<div>   ASSERT (((UINTN)Buf & 0x3F) == 0);</div>
<div>   ZeroMem (Buf, Size);</div>
<div>@@ -814,7 +814,7 @@ CreateEventRing (</div>
<div>   EventRing->EventRingCCS = 1;</div>
<div> </div>
<div>   Size = sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER;</div>
<div>-  Buf  = UsbHcAllocateMem (Xhc->MemPool, Size);</div>
<div>+  Buf  = UsbHcAllocateMem (Xhc->MemPool, Size, FALSE);</div>
<div>   ASSERT (Buf != NULL);</div>
<div>   ASSERT (((UINTN)Buf & 0x3F) == 0);</div>
<div>   ZeroMem (Buf, Size);</div>
<div>@@ -892,7 +892,7 @@ CreateTransferRing (</div>
<div>   LINK_TRB              *EndTrb;</div>
<div>   EFI_PHYSICAL_ADDRESS  PhyAddr;</div>
<div> </div>
<div>-  Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum);</div>
<div>+  Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum, TRUE);</div>
<div>   ASSERT (Buf != NULL);</div>
<div>   ASSERT (((UINTN)Buf & 0x3F) == 0);</div>
<div>   ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum);</div>
<div>@@ -2182,7 +2182,7 @@ XhcInitializeDeviceSlot (</div>
<div>   // 4.3.3 Device Slot Initialization</div>
<div>   // 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.</div>
<div>   //</div>
<div>-  InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT));</div>
<div>+  InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT), FALSE);</div>
<div>   ASSERT (InputContext != NULL);</div>
<div>   ASSERT (((UINTN)InputContext & 0x3F) == 0);</div>
<div>   ZeroMem (InputContext, sizeof (INPUT_CONTEXT));</div>
<div>@@ -2284,7 +2284,7 @@ XhcInitializeDeviceSlot (</div>
<div>   //</div>
<div>   // 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.</div>
<div>   //</div>
<div>-  OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT));</div>
<div>+  OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT), FALSE);</div>
<div>   ASSERT (OutputContext != NULL);</div>
<div>   ASSERT (((UINTN)OutputContext & 0x3F) == 0);</div>
<div>   ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT));</div>
<div>@@ -2398,7 +2398,7 @@ XhcInitializeDeviceSlot64 (</div>
<div>   // 4.3.3 Device Slot Initialization</div>
<div>   // 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.</div>
<div>   //</div>
<div>-  InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64));</div>
<div>+  InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64), FALSE);</div>
<div>   ASSERT (InputContext != NULL);</div>
<div>   ASSERT (((UINTN)InputContext & 0x3F) == 0);</div>
<div>   ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));</div>
<div>@@ -2500,7 +2500,7 @@ XhcInitializeDeviceSlot64 (</div>
<div>   //</div>
<div>   // 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.</div>
<div>   //</div>
<div>-  OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64));</div>
<div>+  OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64), FALSE);</div>
<div>   ASSERT (OutputContext != NULL);</div>
<div>   ASSERT (((UINTN)OutputContext & 0x3F) == 0);</div>
<div>   ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT_64));</div>
<div>-- </div>
<div>2.20.1.windows.1</div>
<div> </div>


 <div width="1" style="color:white;clear:both">_._,_._,_</div> <hr>   Groups.io Links:<p>   You receive all messages sent to this group.    <p> <a target="_blank" href="https://edk2.groups.io/g/devel/message/95294">View/Reply Online (#95294)</a> |    |  <a target="_blank" href="https://groups.io/mt/94385000/1813853">Mute This Topic</a>  | <a href="https://edk2.groups.io/g/devel/post">New Topic</a><br>    <a href="https://edk2.groups.io/g/devel/editsub/1813853">Your Subscription</a> | <a href="mailto:devel+owner@edk2.groups.io">Contact Group Owner</a> |  <a href="https://edk2.groups.io/g/devel/unsub">Unsubscribe</a>  [edk2-devel-archive@redhat.com]<br> <div width="1" style="color:white;clear:both">_._,_._,_</div>