* [PATCH] MdeModulePkg/XhciDxe: Add a parameter to indicate whether the memory allocation is for TRB Ring or not.
@ 2022-10-17 14:08 Jiading Zhang
2022-10-18 3:06 ` [edk2-devel] " Jiading Zhang
0 siblings, 1 reply; 4+ messages in thread
From: Jiading Zhang @ 2022-10-17 14:08 UTC (permalink / raw)
To: devel
[-- Attachment #1: Type: text/plain, Size: 9268 bytes --]
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.
Signed-off-by: jdzhang <jdzhang@kunluntech.com.cn>
---
MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c | 37 +++++++++++++++++++-----
MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h | 10 +++++--
MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c | 16 +++++-----
3 files changed, 44 insertions(+), 19 deletions(-)
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
index 99fb3521d5..24714502cd 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
@@ -132,8 +132,9 @@ UsbHcFreeMemBlock (
/**
Alloc some memory from the block.
- @param Block The memory block to allocate memory from.
- @param Units Number of memory units to allocate.
+ @param Block The memory block to allocate memory from.
+ @param Units Number of memory units to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The pointer to the allocated memory. If couldn't allocate the needed memory,
the return value is NULL.
@@ -142,7 +143,8 @@ UsbHcFreeMemBlock (
VOID *
UsbHcAllocMemFromBlock (
IN USBHC_MEM_BLOCK *Block,
- IN UINTN Units
+ IN UINTN Units,
+ IN BOOLEAN AllocationForTrbRing
)
{
UINTN Byte;
@@ -151,12 +153,15 @@ UsbHcAllocMemFromBlock (
UINT8 StartBit;
UINTN Available;
UINTN Count;
+ UINTN MemUnitAddr;
+ UINTN AlignmentMask;
ASSERT ((Block != 0) && (Units != 0));
StartByte = 0;
StartBit = 0;
Available = 0;
+ AlignmentMask = ~((UINTN)USBHC_MEM_TRB_RINGS_BOUNDARY - 1);
for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) {
//
@@ -165,6 +170,20 @@ UsbHcAllocMemFromBlock (
// Available counts the consective number of zero bit.
//
if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) {
+ if (AllocationForTrbRing && (Available != 0)) {
+ MemUnitAddr = (UINTN)Block->BufHost + (Byte * 8 + Bit) * USBHC_MEM_UNIT;
+ if ((MemUnitAddr & AlignmentMask) != ((MemUnitAddr - USBHC_MEM_UNIT) & AlignmentMask)) {
+ //
+ // If the TRB Ring memory cross 64K-byte boundary, then restart the
+ // search starting at current memory unit.
+ // Doing so is to meet the TRB Ring boundary requirement in XHCI spec.
+ //
+ Available = 0;
+ StartByte = Byte;
+ StartBit = Bit;
+ }
+ }
+
Available++;
if (Available >= Units) {
@@ -438,8 +457,9 @@ UsbHcFreeMemPool (
Allocate some memory from the host controller's memory pool
which can be used to communicate with host controller.
- @param Pool The host controller's memory pool.
- @param Size Size of the memory to allocate.
+ @param Pool The host controller's memory pool.
+ @param Size Size of the memory to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The allocated memory or NULL.
@@ -447,7 +467,8 @@ UsbHcFreeMemPool (
VOID *
UsbHcAllocateMem (
IN USBHC_MEM_POOL *Pool,
- IN UINTN Size
+ IN UINTN Size,
+ IN BOOLEAN AllocationForRing
)
{
USBHC_MEM_BLOCK *Head;
@@ -466,7 +487,7 @@ UsbHcAllocateMem (
// First check whether current memory blocks can satisfy the allocation.
//
for (Block = Head; Block != NULL; Block = Block->Next) {
- Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT);
+ Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT, AllocationForRing);
if (Mem != NULL) {
ZeroMem (Mem, Size);
@@ -501,7 +522,7 @@ UsbHcAllocateMem (
// Add the new memory block to the pool, then allocate memory from it
//
UsbHcInsertMemBlockToPool (Head, NewBlock);
- Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT);
+ Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT, AllocationForRing);
if (Mem != NULL) {
ZeroMem (Mem, Size);
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
index 48ae86141c..dfea0e52b3 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
@@ -48,6 +48,8 @@ typedef struct _USBHC_MEM_POOL {
#define USBHC_MEM_ROUND(Len) (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK))
+#define USBHC_MEM_TRB_RINGS_BOUNDARY SIZE_64KB
+
//
// Advance the byte and bit to the next bit, adjust byte accordingly.
//
@@ -92,8 +94,9 @@ UsbHcFreeMemPool (
Allocate some memory from the host controller's memory pool
which can be used to communicate with host controller.
- @param Pool The host controller's memory pool.
- @param Size Size of the memory to allocate.
+ @param Pool The host controller's memory pool.
+ @param Size Size of the memory to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The allocated memory or NULL.
@@ -101,7 +104,8 @@ UsbHcFreeMemPool (
VOID *
UsbHcAllocateMem (
IN USBHC_MEM_POOL *Pool,
- IN UINTN Size
+ IN UINTN Size,
+ IN BOOLEAN AllocationForRing
);
/**
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
index 4ae0297607..13b0400e83 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
@@ -506,7 +506,7 @@ XhcInitSched (
// Software shall set Device Context Base Address Array entries for unallocated Device Slots to '0'.
//
Entries = (Xhc->MaxSlotsEn + 1) * sizeof (UINT64);
- Dcbaa = UsbHcAllocateMem (Xhc->MemPool, Entries);
+ Dcbaa = UsbHcAllocateMem (Xhc->MemPool, Entries, FALSE);
ASSERT (Dcbaa != NULL);
ZeroMem (Dcbaa, Entries);
@@ -795,7 +795,7 @@ CreateEventRing (
ASSERT (EventRing != NULL);
Size = sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER;
- Buf = UsbHcAllocateMem (Xhc->MemPool, Size);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, Size, TRUE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, Size);
@@ -814,7 +814,7 @@ CreateEventRing (
EventRing->EventRingCCS = 1;
Size = sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER;
- Buf = UsbHcAllocateMem (Xhc->MemPool, Size);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, Size, FALSE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, Size);
@@ -892,7 +892,7 @@ CreateTransferRing (
LINK_TRB *EndTrb;
EFI_PHYSICAL_ADDRESS PhyAddr;
- Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum, TRUE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum);
@@ -2182,7 +2182,7 @@ XhcInitializeDeviceSlot (
// 4.3.3 Device Slot Initialization
// 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.
//
- InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT));
+ InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT), FALSE);
ASSERT (InputContext != NULL);
ASSERT (((UINTN)InputContext & 0x3F) == 0);
ZeroMem (InputContext, sizeof (INPUT_CONTEXT));
@@ -2284,7 +2284,7 @@ XhcInitializeDeviceSlot (
//
// 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.
//
- OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT));
+ OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT), FALSE);
ASSERT (OutputContext != NULL);
ASSERT (((UINTN)OutputContext & 0x3F) == 0);
ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT));
@@ -2398,7 +2398,7 @@ XhcInitializeDeviceSlot64 (
// 4.3.3 Device Slot Initialization
// 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.
//
- InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64));
+ InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64), FALSE);
ASSERT (InputContext != NULL);
ASSERT (((UINTN)InputContext & 0x3F) == 0);
ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));
@@ -2500,7 +2500,7 @@ XhcInitializeDeviceSlot64 (
//
// 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.
//
- OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64));
+ OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64), FALSE);
ASSERT (OutputContext != NULL);
ASSERT (((UINTN)OutputContext & 0x3F) == 0);
ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT_64));
--
2.20.1.windows.1
[-- Attachment #2: Type: text/html, Size: 14590 bytes --]
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [edk2-devel] [PATCH] MdeModulePkg/XhciDxe: Add a parameter to indicate whether the memory allocation is for TRB Ring or not.
2022-10-17 14:08 [PATCH] MdeModulePkg/XhciDxe: Add a parameter to indicate whether the memory allocation is for TRB Ring or not Jiading Zhang
@ 2022-10-18 3:06 ` Jiading Zhang
2022-10-18 5:42 ` Wu, Hao A
0 siblings, 1 reply; 4+ messages in thread
From: Jiading Zhang @ 2022-10-18 3:06 UTC (permalink / raw)
To: Jiading Zhang, devel
[-- Attachment #1.1: Type: text/plain, Size: 9476 bytes --]
Hi,
I renamed the parameter from ‘AllocationForTrbRing’ to ‘AllocationForRing’ in UsbHcAllocMemFromBlock, which matchs the description comment. And the attachment is the updated patch file.
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 Rings or not. It will ensure the allocation not crossing 64K boundary in UsbHcAllocMemFromBlock if the memory is allocated for TRB Rings.
Signed-off-by: jdzhang <jdzhang@kunluntech.com.cn>
---
MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c | 37 +++++++++++++++++++-----
MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h | 10 +++++--
MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c | 16 +++++-----
3 files changed, 44 insertions(+), 19 deletions(-)
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
index 99fb3521d5..4373b2c99e 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
@@ -132,8 +132,9 @@ UsbHcFreeMemBlock (
/**
Alloc some memory from the block.
- @param Block The memory block to allocate memory from.
- @param Units Number of memory units to allocate.
+ @param Block The memory block to allocate memory from.
+ @param Units Number of memory units to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The pointer to the allocated memory. If couldn't allocate the needed memory,
the return value is NULL.
@@ -142,7 +143,8 @@ UsbHcFreeMemBlock (
VOID *
UsbHcAllocMemFromBlock (
IN USBHC_MEM_BLOCK *Block,
- IN UINTN Units
+ IN UINTN Units,
+ IN BOOLEAN AllocationForRing
)
{
UINTN Byte;
@@ -151,12 +153,15 @@ UsbHcAllocMemFromBlock (
UINT8 StartBit;
UINTN Available;
UINTN Count;
+ UINTN MemUnitAddr;
+ UINTN AlignmentMask;
ASSERT ((Block != 0) && (Units != 0));
StartByte = 0;
StartBit = 0;
Available = 0;
+ AlignmentMask = ~((UINTN)USBHC_MEM_TRB_RINGS_BOUNDARY - 1);
for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) {
//
@@ -165,6 +170,20 @@ UsbHcAllocMemFromBlock (
// Available counts the consective number of zero bit.
//
if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) {
+ if (AllocationForRing && (Available != 0)) {
+ MemUnitAddr = (UINTN)Block->BufHost + (Byte * 8 + Bit) * USBHC_MEM_UNIT;
+ if ((MemUnitAddr & AlignmentMask) != ((MemUnitAddr - USBHC_MEM_UNIT) & AlignmentMask)) {
+ //
+ // If the TRB Ring memory cross 64K-byte boundary, then restart the
+ // search starting at current memory unit.
+ // Doing so is to meet the TRB Ring boundary requirement in XHCI spec.
+ //
+ Available = 0;
+ StartByte = Byte;
+ StartBit = Bit;
+ }
+ }
+
Available++;
if (Available >= Units) {
@@ -438,8 +457,9 @@ UsbHcFreeMemPool (
Allocate some memory from the host controller's memory pool
which can be used to communicate with host controller.
- @param Pool The host controller's memory pool.
- @param Size Size of the memory to allocate.
+ @param Pool The host controller's memory pool.
+ @param Size Size of the memory to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The allocated memory or NULL.
@@ -447,7 +467,8 @@ UsbHcFreeMemPool (
VOID *
UsbHcAllocateMem (
IN USBHC_MEM_POOL *Pool,
- IN UINTN Size
+ IN UINTN Size,
+ IN BOOLEAN AllocationForRing
)
{
USBHC_MEM_BLOCK *Head;
@@ -466,7 +487,7 @@ UsbHcAllocateMem (
// First check whether current memory blocks can satisfy the allocation.
//
for (Block = Head; Block != NULL; Block = Block->Next) {
- Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT);
+ Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT, AllocationForRing);
if (Mem != NULL) {
ZeroMem (Mem, Size);
@@ -501,7 +522,7 @@ UsbHcAllocateMem (
// Add the new memory block to the pool, then allocate memory from it
//
UsbHcInsertMemBlockToPool (Head, NewBlock);
- Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT);
+ Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT, AllocationForRing);
if (Mem != NULL) {
ZeroMem (Mem, Size);
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
index 48ae86141c..dfea0e52b3 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
@@ -48,6 +48,8 @@ typedef struct _USBHC_MEM_POOL {
#define USBHC_MEM_ROUND(Len) (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK))
+#define USBHC_MEM_TRB_RINGS_BOUNDARY SIZE_64KB
+
//
// Advance the byte and bit to the next bit, adjust byte accordingly.
//
@@ -92,8 +94,9 @@ UsbHcFreeMemPool (
Allocate some memory from the host controller's memory pool
which can be used to communicate with host controller.
- @param Pool The host controller's memory pool.
- @param Size Size of the memory to allocate.
+ @param Pool The host controller's memory pool.
+ @param Size Size of the memory to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The allocated memory or NULL.
@@ -101,7 +104,8 @@ UsbHcFreeMemPool (
VOID *
UsbHcAllocateMem (
IN USBHC_MEM_POOL *Pool,
- IN UINTN Size
+ IN UINTN Size,
+ IN BOOLEAN AllocationForRing
);
/**
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
index 4ae0297607..13b0400e83 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
@@ -506,7 +506,7 @@ XhcInitSched (
// Software shall set Device Context Base Address Array entries for unallocated Device Slots to '0'.
//
Entries = (Xhc->MaxSlotsEn + 1) * sizeof (UINT64);
- Dcbaa = UsbHcAllocateMem (Xhc->MemPool, Entries);
+ Dcbaa = UsbHcAllocateMem (Xhc->MemPool, Entries, FALSE);
ASSERT (Dcbaa != NULL);
ZeroMem (Dcbaa, Entries);
@@ -795,7 +795,7 @@ CreateEventRing (
ASSERT (EventRing != NULL);
Size = sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER;
- Buf = UsbHcAllocateMem (Xhc->MemPool, Size);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, Size, TRUE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, Size);
@@ -814,7 +814,7 @@ CreateEventRing (
EventRing->EventRingCCS = 1;
Size = sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER;
- Buf = UsbHcAllocateMem (Xhc->MemPool, Size);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, Size, FALSE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, Size);
@@ -892,7 +892,7 @@ CreateTransferRing (
LINK_TRB *EndTrb;
EFI_PHYSICAL_ADDRESS PhyAddr;
- Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum, TRUE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum);
@@ -2182,7 +2182,7 @@ XhcInitializeDeviceSlot (
// 4.3.3 Device Slot Initialization
// 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.
//
- InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT));
+ InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT), FALSE);
ASSERT (InputContext != NULL);
ASSERT (((UINTN)InputContext & 0x3F) == 0);
ZeroMem (InputContext, sizeof (INPUT_CONTEXT));
@@ -2284,7 +2284,7 @@ XhcInitializeDeviceSlot (
//
// 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.
//
- OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT));
+ OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT), FALSE);
ASSERT (OutputContext != NULL);
ASSERT (((UINTN)OutputContext & 0x3F) == 0);
ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT));
@@ -2398,7 +2398,7 @@ XhcInitializeDeviceSlot64 (
// 4.3.3 Device Slot Initialization
// 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.
//
- InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64));
+ InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64), FALSE);
ASSERT (InputContext != NULL);
ASSERT (((UINTN)InputContext & 0x3F) == 0);
ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));
@@ -2500,7 +2500,7 @@ XhcInitializeDeviceSlot64 (
//
// 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.
//
- OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64));
+ OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64), FALSE);
ASSERT (OutputContext != NULL);
ASSERT (((UINTN)OutputContext & 0x3F) == 0);
ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT_64));
--
2.20.1.windows.1
[-- Attachment #1.2: Type: text/html, Size: 15020 bytes --]
[-- Attachment #2: 0001-MdeModulePkg-XhciDxe-Add-a-parameter-to-indicate-whe.patch --]
[-- Type: text/plain, Size: 9536 bytes --]
From dbb0f1fb7498393e7ae536be933279c4dee25d6d Mon Sep 17 00:00:00 2001
From: jdzhang <jdzhang@kunluntech.com.cn>
Date: Tue, 18 Oct 2022 10:56:02 +0800
Subject: [PATCH] MdeModulePkg/XhciDxe: Add a parameter to indicate whether the
memory allocation is for TRB Rings or not.
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 Rings or not. It will ensure the allocation not crossing 64K boundary in UsbHcAllocMemFromBlock if the memory is allocated for TRB Rings.
Signed-off-by: jdzhang <jdzhang@kunluntech.com.cn>
---
MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c | 37 +++++++++++++++++++-----
MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h | 10 +++++--
MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c | 16 +++++-----
3 files changed, 44 insertions(+), 19 deletions(-)
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
index 99fb3521d5..4373b2c99e 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
@@ -132,8 +132,9 @@ UsbHcFreeMemBlock (
/**
Alloc some memory from the block.
- @param Block The memory block to allocate memory from.
- @param Units Number of memory units to allocate.
+ @param Block The memory block to allocate memory from.
+ @param Units Number of memory units to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The pointer to the allocated memory. If couldn't allocate the needed memory,
the return value is NULL.
@@ -142,7 +143,8 @@ UsbHcFreeMemBlock (
VOID *
UsbHcAllocMemFromBlock (
IN USBHC_MEM_BLOCK *Block,
- IN UINTN Units
+ IN UINTN Units,
+ IN BOOLEAN AllocationForRing
)
{
UINTN Byte;
@@ -151,12 +153,15 @@ UsbHcAllocMemFromBlock (
UINT8 StartBit;
UINTN Available;
UINTN Count;
+ UINTN MemUnitAddr;
+ UINTN AlignmentMask;
ASSERT ((Block != 0) && (Units != 0));
StartByte = 0;
StartBit = 0;
Available = 0;
+ AlignmentMask = ~((UINTN)USBHC_MEM_TRB_RINGS_BOUNDARY - 1);
for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) {
//
@@ -165,6 +170,20 @@ UsbHcAllocMemFromBlock (
// Available counts the consective number of zero bit.
//
if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) {
+ if (AllocationForRing && (Available != 0)) {
+ MemUnitAddr = (UINTN)Block->BufHost + (Byte * 8 + Bit) * USBHC_MEM_UNIT;
+ if ((MemUnitAddr & AlignmentMask) != ((MemUnitAddr - USBHC_MEM_UNIT) & AlignmentMask)) {
+ //
+ // If the TRB Ring memory cross 64K-byte boundary, then restart the
+ // search starting at current memory unit.
+ // Doing so is to meet the TRB Ring boundary requirement in XHCI spec.
+ //
+ Available = 0;
+ StartByte = Byte;
+ StartBit = Bit;
+ }
+ }
+
Available++;
if (Available >= Units) {
@@ -438,8 +457,9 @@ UsbHcFreeMemPool (
Allocate some memory from the host controller's memory pool
which can be used to communicate with host controller.
- @param Pool The host controller's memory pool.
- @param Size Size of the memory to allocate.
+ @param Pool The host controller's memory pool.
+ @param Size Size of the memory to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The allocated memory or NULL.
@@ -447,7 +467,8 @@ UsbHcFreeMemPool (
VOID *
UsbHcAllocateMem (
IN USBHC_MEM_POOL *Pool,
- IN UINTN Size
+ IN UINTN Size,
+ IN BOOLEAN AllocationForRing
)
{
USBHC_MEM_BLOCK *Head;
@@ -466,7 +487,7 @@ UsbHcAllocateMem (
// First check whether current memory blocks can satisfy the allocation.
//
for (Block = Head; Block != NULL; Block = Block->Next) {
- Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT);
+ Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT, AllocationForRing);
if (Mem != NULL) {
ZeroMem (Mem, Size);
@@ -501,7 +522,7 @@ UsbHcAllocateMem (
// Add the new memory block to the pool, then allocate memory from it
//
UsbHcInsertMemBlockToPool (Head, NewBlock);
- Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT);
+ Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT, AllocationForRing);
if (Mem != NULL) {
ZeroMem (Mem, Size);
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
index 48ae86141c..dfea0e52b3 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
@@ -48,6 +48,8 @@ typedef struct _USBHC_MEM_POOL {
#define USBHC_MEM_ROUND(Len) (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK))
+#define USBHC_MEM_TRB_RINGS_BOUNDARY SIZE_64KB
+
//
// Advance the byte and bit to the next bit, adjust byte accordingly.
//
@@ -92,8 +94,9 @@ UsbHcFreeMemPool (
Allocate some memory from the host controller's memory pool
which can be used to communicate with host controller.
- @param Pool The host controller's memory pool.
- @param Size Size of the memory to allocate.
+ @param Pool The host controller's memory pool.
+ @param Size Size of the memory to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The allocated memory or NULL.
@@ -101,7 +104,8 @@ UsbHcFreeMemPool (
VOID *
UsbHcAllocateMem (
IN USBHC_MEM_POOL *Pool,
- IN UINTN Size
+ IN UINTN Size,
+ IN BOOLEAN AllocationForRing
);
/**
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
index 4ae0297607..13b0400e83 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
@@ -506,7 +506,7 @@ XhcInitSched (
// Software shall set Device Context Base Address Array entries for unallocated Device Slots to '0'.
//
Entries = (Xhc->MaxSlotsEn + 1) * sizeof (UINT64);
- Dcbaa = UsbHcAllocateMem (Xhc->MemPool, Entries);
+ Dcbaa = UsbHcAllocateMem (Xhc->MemPool, Entries, FALSE);
ASSERT (Dcbaa != NULL);
ZeroMem (Dcbaa, Entries);
@@ -795,7 +795,7 @@ CreateEventRing (
ASSERT (EventRing != NULL);
Size = sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER;
- Buf = UsbHcAllocateMem (Xhc->MemPool, Size);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, Size, TRUE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, Size);
@@ -814,7 +814,7 @@ CreateEventRing (
EventRing->EventRingCCS = 1;
Size = sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER;
- Buf = UsbHcAllocateMem (Xhc->MemPool, Size);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, Size, FALSE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, Size);
@@ -892,7 +892,7 @@ CreateTransferRing (
LINK_TRB *EndTrb;
EFI_PHYSICAL_ADDRESS PhyAddr;
- Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum, TRUE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum);
@@ -2182,7 +2182,7 @@ XhcInitializeDeviceSlot (
// 4.3.3 Device Slot Initialization
// 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.
//
- InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT));
+ InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT), FALSE);
ASSERT (InputContext != NULL);
ASSERT (((UINTN)InputContext & 0x3F) == 0);
ZeroMem (InputContext, sizeof (INPUT_CONTEXT));
@@ -2284,7 +2284,7 @@ XhcInitializeDeviceSlot (
//
// 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.
//
- OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT));
+ OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT), FALSE);
ASSERT (OutputContext != NULL);
ASSERT (((UINTN)OutputContext & 0x3F) == 0);
ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT));
@@ -2398,7 +2398,7 @@ XhcInitializeDeviceSlot64 (
// 4.3.3 Device Slot Initialization
// 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.
//
- InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64));
+ InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64), FALSE);
ASSERT (InputContext != NULL);
ASSERT (((UINTN)InputContext & 0x3F) == 0);
ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));
@@ -2500,7 +2500,7 @@ XhcInitializeDeviceSlot64 (
//
// 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.
//
- OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64));
+ OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64), FALSE);
ASSERT (OutputContext != NULL);
ASSERT (((UINTN)OutputContext & 0x3F) == 0);
ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT_64));
--
2.20.1.windows.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [edk2-devel] [PATCH] MdeModulePkg/XhciDxe: Add a parameter to indicate whether the memory allocation is for TRB Ring or not.
2022-10-18 3:06 ` [edk2-devel] " Jiading Zhang
@ 2022-10-18 5:42 ` Wu, Hao A
2022-10-20 4:09 ` Wu, Hao A
0 siblings, 1 reply; 4+ messages in thread
From: Wu, Hao A @ 2022-10-18 5:42 UTC (permalink / raw)
To: devel@edk2.groups.io, jdzhang@kunluntech.com.cn
[-- Attachment #1: Type: text/plain, Size: 10145 bytes --]
Thanks.
Will rename the commit title to “MdeModulePkg/XhciDxe: Add boundary check for TRB ring allocation” to pass the CI test.
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
Will wait a couple of days before merging to see if comments from other reviewers.
Best Regards,
Hao Wu
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Jiading Zhang
Sent: Tuesday, October 18, 2022 11:07 AM
To: Jiading Zhang <jdzhang@kunluntech.com.cn>; devel@edk2.groups.io
Subject: Re: [edk2-devel] [PATCH] MdeModulePkg/XhciDxe: Add a parameter to indicate whether the memory allocation is for TRB Ring or not.
Hi,
I renamed the parameter from ‘AllocationForTrbRing’ to ‘AllocationForRing’ in UsbHcAllocMemFromBlock, which matchs the description comment. And the attachment is the updated patch file.
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 Rings or not. It will ensure the allocation not crossing 64K boundary in UsbHcAllocMemFromBlock if the memory is allocated for TRB Rings.
Signed-off-by: jdzhang <jdzhang@kunluntech.com.cn<mailto:jdzhang@kunluntech.com.cn>>
---
MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c | 37 +++++++++++++++++++-----
MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h | 10 +++++--
MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c | 16 +++++-----
3 files changed, 44 insertions(+), 19 deletions(-)
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
index 99fb3521d5..4373b2c99e 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
@@ -132,8 +132,9 @@ UsbHcFreeMemBlock (
/**
Alloc some memory from the block.
- @param Block The memory block to allocate memory from.
- @param Units Number of memory units to allocate.
+ @param Block The memory block to allocate memory from.
+ @param Units Number of memory units to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The pointer to the allocated memory. If couldn't allocate the needed memory,
the return value is NULL.
@@ -142,7 +143,8 @@ UsbHcFreeMemBlock (
VOID *
UsbHcAllocMemFromBlock (
IN USBHC_MEM_BLOCK *Block,
- IN UINTN Units
+ IN UINTN Units,
+ IN BOOLEAN AllocationForRing
)
{
UINTN Byte;
@@ -151,12 +153,15 @@ UsbHcAllocMemFromBlock (
UINT8 StartBit;
UINTN Available;
UINTN Count;
+ UINTN MemUnitAddr;
+ UINTN AlignmentMask;
ASSERT ((Block != 0) && (Units != 0));
StartByte = 0;
StartBit = 0;
Available = 0;
+ AlignmentMask = ~((UINTN)USBHC_MEM_TRB_RINGS_BOUNDARY - 1);
for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) {
//
@@ -165,6 +170,20 @@ UsbHcAllocMemFromBlock (
// Available counts the consective number of zero bit.
//
if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) {
+ if (AllocationForRing && (Available != 0)) {
+ MemUnitAddr = (UINTN)Block->BufHost + (Byte * 8 + Bit) * USBHC_MEM_UNIT;
+ if ((MemUnitAddr & AlignmentMask) != ((MemUnitAddr - USBHC_MEM_UNIT) & AlignmentMask)) {
+ //
+ // If the TRB Ring memory cross 64K-byte boundary, then restart the
+ // search starting at current memory unit.
+ // Doing so is to meet the TRB Ring boundary requirement in XHCI spec.
+ //
+ Available = 0;
+ StartByte = Byte;
+ StartBit = Bit;
+ }
+ }
+
Available++;
if (Available >= Units) {
@@ -438,8 +457,9 @@ UsbHcFreeMemPool (
Allocate some memory from the host controller's memory pool
which can be used to communicate with host controller.
- @param Pool The host controller's memory pool.
- @param Size Size of the memory to allocate.
+ @param Pool The host controller's memory pool.
+ @param Size Size of the memory to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The allocated memory or NULL.
@@ -447,7 +467,8 @@ UsbHcFreeMemPool (
VOID *
UsbHcAllocateMem (
IN USBHC_MEM_POOL *Pool,
- IN UINTN Size
+ IN UINTN Size,
+ IN BOOLEAN AllocationForRing
)
{
USBHC_MEM_BLOCK *Head;
@@ -466,7 +487,7 @@ UsbHcAllocateMem (
// First check whether current memory blocks can satisfy the allocation.
//
for (Block = Head; Block != NULL; Block = Block->Next) {
- Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT);
+ Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT, AllocationForRing);
if (Mem != NULL) {
ZeroMem (Mem, Size);
@@ -501,7 +522,7 @@ UsbHcAllocateMem (
// Add the new memory block to the pool, then allocate memory from it
//
UsbHcInsertMemBlockToPool (Head, NewBlock);
- Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT);
+ Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT, AllocationForRing);
if (Mem != NULL) {
ZeroMem (Mem, Size);
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
index 48ae86141c..dfea0e52b3 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
@@ -48,6 +48,8 @@ typedef struct _USBHC_MEM_POOL {
#define USBHC_MEM_ROUND(Len) (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK))
+#define USBHC_MEM_TRB_RINGS_BOUNDARY SIZE_64KB
+
//
// Advance the byte and bit to the next bit, adjust byte accordingly.
//
@@ -92,8 +94,9 @@ UsbHcFreeMemPool (
Allocate some memory from the host controller's memory pool
which can be used to communicate with host controller.
- @param Pool The host controller's memory pool.
- @param Size Size of the memory to allocate.
+ @param Pool The host controller's memory pool.
+ @param Size Size of the memory to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The allocated memory or NULL.
@@ -101,7 +104,8 @@ UsbHcFreeMemPool (
VOID *
UsbHcAllocateMem (
IN USBHC_MEM_POOL *Pool,
- IN UINTN Size
+ IN UINTN Size,
+ IN BOOLEAN AllocationForRing
);
/**
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
index 4ae0297607..13b0400e83 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
@@ -506,7 +506,7 @@ XhcInitSched (
// Software shall set Device Context Base Address Array entries for unallocated Device Slots to '0'.
//
Entries = (Xhc->MaxSlotsEn + 1) * sizeof (UINT64);
- Dcbaa = UsbHcAllocateMem (Xhc->MemPool, Entries);
+ Dcbaa = UsbHcAllocateMem (Xhc->MemPool, Entries, FALSE);
ASSERT (Dcbaa != NULL);
ZeroMem (Dcbaa, Entries);
@@ -795,7 +795,7 @@ CreateEventRing (
ASSERT (EventRing != NULL);
Size = sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER;
- Buf = UsbHcAllocateMem (Xhc->MemPool, Size);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, Size, TRUE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, Size);
@@ -814,7 +814,7 @@ CreateEventRing (
EventRing->EventRingCCS = 1;
Size = sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER;
- Buf = UsbHcAllocateMem (Xhc->MemPool, Size);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, Size, FALSE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, Size);
@@ -892,7 +892,7 @@ CreateTransferRing (
LINK_TRB *EndTrb;
EFI_PHYSICAL_ADDRESS PhyAddr;
- Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum, TRUE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum);
@@ -2182,7 +2182,7 @@ XhcInitializeDeviceSlot (
// 4.3.3 Device Slot Initialization
// 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.
//
- InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT));
+ InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT), FALSE);
ASSERT (InputContext != NULL);
ASSERT (((UINTN)InputContext & 0x3F) == 0);
ZeroMem (InputContext, sizeof (INPUT_CONTEXT));
@@ -2284,7 +2284,7 @@ XhcInitializeDeviceSlot (
//
// 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.
//
- OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT));
+ OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT), FALSE);
ASSERT (OutputContext != NULL);
ASSERT (((UINTN)OutputContext & 0x3F) == 0);
ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT));
@@ -2398,7 +2398,7 @@ XhcInitializeDeviceSlot64 (
// 4.3.3 Device Slot Initialization
// 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.
//
- InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64));
+ InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64), FALSE);
ASSERT (InputContext != NULL);
ASSERT (((UINTN)InputContext & 0x3F) == 0);
ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));
@@ -2500,7 +2500,7 @@ XhcInitializeDeviceSlot64 (
//
// 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.
//
- OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64));
+ OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64), FALSE);
ASSERT (OutputContext != NULL);
ASSERT (((UINTN)OutputContext & 0x3F) == 0);
ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT_64));
--
2.20.1.windows.1
[-- Attachment #2: Type: text/html, Size: 27276 bytes --]
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [edk2-devel] [PATCH] MdeModulePkg/XhciDxe: Add a parameter to indicate whether the memory allocation is for TRB Ring or not.
2022-10-18 5:42 ` Wu, Hao A
@ 2022-10-20 4:09 ` Wu, Hao A
0 siblings, 0 replies; 4+ messages in thread
From: Wu, Hao A @ 2022-10-20 4:09 UTC (permalink / raw)
To: devel@edk2.groups.io, jdzhang@kunluntech.com.cn
[-- Attachment #1: Type: text/plain, Size: 10727 bytes --]
Merged via:
PR - https://github.com/tianocore/edk2/pull/3504
Commit - https://github.com/tianocore/edk2/commit/c6720db5ddffec747bb0b2830e528511b1a4bfb2
Best Regards,
Hao Wu
From: Wu, Hao A
Sent: Tuesday, October 18, 2022 1:42 PM
To: devel@edk2.groups.io; jdzhang@kunluntech.com.cn
Subject: RE: [edk2-devel] [PATCH] MdeModulePkg/XhciDxe: Add a parameter to indicate whether the memory allocation is for TRB Ring or not.
Thanks.
Will rename the commit title to “MdeModulePkg/XhciDxe: Add boundary check for TRB ring allocation” to pass the CI test.
Reviewed-by: Hao A Wu <hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>
Will wait a couple of days before merging to see if comments from other reviewers.
Best Regards,
Hao Wu
From: devel@edk2.groups.io<mailto:devel@edk2.groups.io> <devel@edk2.groups.io<mailto:devel@edk2.groups.io>> On Behalf Of Jiading Zhang
Sent: Tuesday, October 18, 2022 11:07 AM
To: Jiading Zhang <jdzhang@kunluntech.com.cn<mailto:jdzhang@kunluntech.com.cn>>; devel@edk2.groups.io<mailto:devel@edk2.groups.io>
Subject: Re: [edk2-devel] [PATCH] MdeModulePkg/XhciDxe: Add a parameter to indicate whether the memory allocation is for TRB Ring or not.
Hi,
I renamed the parameter from ‘AllocationForTrbRing’ to ‘AllocationForRing’ in UsbHcAllocMemFromBlock, which matchs the description comment. And the attachment is the updated patch file.
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 Rings or not. It will ensure the allocation not crossing 64K boundary in UsbHcAllocMemFromBlock if the memory is allocated for TRB Rings.
Signed-off-by: jdzhang <jdzhang@kunluntech.com.cn<mailto:jdzhang@kunluntech.com.cn>>
---
MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c | 37 +++++++++++++++++++-----
MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h | 10 +++++--
MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c | 16 +++++-----
3 files changed, 44 insertions(+), 19 deletions(-)
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
index 99fb3521d5..4373b2c99e 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c
@@ -132,8 +132,9 @@ UsbHcFreeMemBlock (
/**
Alloc some memory from the block.
- @param Block The memory block to allocate memory from.
- @param Units Number of memory units to allocate.
+ @param Block The memory block to allocate memory from.
+ @param Units Number of memory units to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The pointer to the allocated memory. If couldn't allocate the needed memory,
the return value is NULL.
@@ -142,7 +143,8 @@ UsbHcFreeMemBlock (
VOID *
UsbHcAllocMemFromBlock (
IN USBHC_MEM_BLOCK *Block,
- IN UINTN Units
+ IN UINTN Units,
+ IN BOOLEAN AllocationForRing
)
{
UINTN Byte;
@@ -151,12 +153,15 @@ UsbHcAllocMemFromBlock (
UINT8 StartBit;
UINTN Available;
UINTN Count;
+ UINTN MemUnitAddr;
+ UINTN AlignmentMask;
ASSERT ((Block != 0) && (Units != 0));
StartByte = 0;
StartBit = 0;
Available = 0;
+ AlignmentMask = ~((UINTN)USBHC_MEM_TRB_RINGS_BOUNDARY - 1);
for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) {
//
@@ -165,6 +170,20 @@ UsbHcAllocMemFromBlock (
// Available counts the consective number of zero bit.
//
if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) {
+ if (AllocationForRing && (Available != 0)) {
+ MemUnitAddr = (UINTN)Block->BufHost + (Byte * 8 + Bit) * USBHC_MEM_UNIT;
+ if ((MemUnitAddr & AlignmentMask) != ((MemUnitAddr - USBHC_MEM_UNIT) & AlignmentMask)) {
+ //
+ // If the TRB Ring memory cross 64K-byte boundary, then restart the
+ // search starting at current memory unit.
+ // Doing so is to meet the TRB Ring boundary requirement in XHCI spec.
+ //
+ Available = 0;
+ StartByte = Byte;
+ StartBit = Bit;
+ }
+ }
+
Available++;
if (Available >= Units) {
@@ -438,8 +457,9 @@ UsbHcFreeMemPool (
Allocate some memory from the host controller's memory pool
which can be used to communicate with host controller.
- @param Pool The host controller's memory pool.
- @param Size Size of the memory to allocate.
+ @param Pool The host controller's memory pool.
+ @param Size Size of the memory to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The allocated memory or NULL.
@@ -447,7 +467,8 @@ UsbHcFreeMemPool (
VOID *
UsbHcAllocateMem (
IN USBHC_MEM_POOL *Pool,
- IN UINTN Size
+ IN UINTN Size,
+ IN BOOLEAN AllocationForRing
)
{
USBHC_MEM_BLOCK *Head;
@@ -466,7 +487,7 @@ UsbHcAllocateMem (
// First check whether current memory blocks can satisfy the allocation.
//
for (Block = Head; Block != NULL; Block = Block->Next) {
- Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT);
+ Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT, AllocationForRing);
if (Mem != NULL) {
ZeroMem (Mem, Size);
@@ -501,7 +522,7 @@ UsbHcAllocateMem (
// Add the new memory block to the pool, then allocate memory from it
//
UsbHcInsertMemBlockToPool (Head, NewBlock);
- Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT);
+ Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT, AllocationForRing);
if (Mem != NULL) {
ZeroMem (Mem, Size);
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
index 48ae86141c..dfea0e52b3 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h
@@ -48,6 +48,8 @@ typedef struct _USBHC_MEM_POOL {
#define USBHC_MEM_ROUND(Len) (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK))
+#define USBHC_MEM_TRB_RINGS_BOUNDARY SIZE_64KB
+
//
// Advance the byte and bit to the next bit, adjust byte accordingly.
//
@@ -92,8 +94,9 @@ UsbHcFreeMemPool (
Allocate some memory from the host controller's memory pool
which can be used to communicate with host controller.
- @param Pool The host controller's memory pool.
- @param Size Size of the memory to allocate.
+ @param Pool The host controller's memory pool.
+ @param Size Size of the memory to allocate.
+ @param AllocationForRing The allocated memory is for Ring or not.
@return The allocated memory or NULL.
@@ -101,7 +104,8 @@ UsbHcFreeMemPool (
VOID *
UsbHcAllocateMem (
IN USBHC_MEM_POOL *Pool,
- IN UINTN Size
+ IN UINTN Size,
+ IN BOOLEAN AllocationForRing
);
/**
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
index 4ae0297607..13b0400e83 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
@@ -506,7 +506,7 @@ XhcInitSched (
// Software shall set Device Context Base Address Array entries for unallocated Device Slots to '0'.
//
Entries = (Xhc->MaxSlotsEn + 1) * sizeof (UINT64);
- Dcbaa = UsbHcAllocateMem (Xhc->MemPool, Entries);
+ Dcbaa = UsbHcAllocateMem (Xhc->MemPool, Entries, FALSE);
ASSERT (Dcbaa != NULL);
ZeroMem (Dcbaa, Entries);
@@ -795,7 +795,7 @@ CreateEventRing (
ASSERT (EventRing != NULL);
Size = sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER;
- Buf = UsbHcAllocateMem (Xhc->MemPool, Size);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, Size, TRUE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, Size);
@@ -814,7 +814,7 @@ CreateEventRing (
EventRing->EventRingCCS = 1;
Size = sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER;
- Buf = UsbHcAllocateMem (Xhc->MemPool, Size);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, Size, FALSE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, Size);
@@ -892,7 +892,7 @@ CreateTransferRing (
LINK_TRB *EndTrb;
EFI_PHYSICAL_ADDRESS PhyAddr;
- Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum);
+ Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum, TRUE);
ASSERT (Buf != NULL);
ASSERT (((UINTN)Buf & 0x3F) == 0);
ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum);
@@ -2182,7 +2182,7 @@ XhcInitializeDeviceSlot (
// 4.3.3 Device Slot Initialization
// 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.
//
- InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT));
+ InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT), FALSE);
ASSERT (InputContext != NULL);
ASSERT (((UINTN)InputContext & 0x3F) == 0);
ZeroMem (InputContext, sizeof (INPUT_CONTEXT));
@@ -2284,7 +2284,7 @@ XhcInitializeDeviceSlot (
//
// 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.
//
- OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT));
+ OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT), FALSE);
ASSERT (OutputContext != NULL);
ASSERT (((UINTN)OutputContext & 0x3F) == 0);
ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT));
@@ -2398,7 +2398,7 @@ XhcInitializeDeviceSlot64 (
// 4.3.3 Device Slot Initialization
// 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'.
//
- InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64));
+ InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64), FALSE);
ASSERT (InputContext != NULL);
ASSERT (((UINTN)InputContext & 0x3F) == 0);
ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));
@@ -2500,7 +2500,7 @@ XhcInitializeDeviceSlot64 (
//
// 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'.
//
- OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64));
+ OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64), FALSE);
ASSERT (OutputContext != NULL);
ASSERT (((UINTN)OutputContext & 0x3F) == 0);
ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT_64));
--
2.20.1.windows.1
[-- Attachment #2: Type: text/html, Size: 28636 bytes --]
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-10-20 4:09 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-10-17 14:08 [PATCH] MdeModulePkg/XhciDxe: Add a parameter to indicate whether the memory allocation is for TRB Ring or not Jiading Zhang
2022-10-18 3:06 ` [edk2-devel] " Jiading Zhang
2022-10-18 5:42 ` Wu, Hao A
2022-10-20 4:09 ` Wu, Hao A
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox