<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>