> -----Original Message----- > From: Ashish Singhal [mailto:ashishsin...@nvidia.com] > Sent: Wednesday, October 16, 2019 1:21 AM > To: devel@edk2.groups.io; Wu, Hao A; Ni, Ray; jbra...@nvidia.com > Cc: Ashish Singhal > Subject: [PATCH v4 2/2] MdeModulePkg/XhciPei: Fix Aligned Page > Allocation > > Add support for allocating aligned pages at an alignment higher > than 4K. The new function allocated memory taking into account > the padding required and then frees up unused pages before mapping > it. >
Hello Ashish, Please grant me some time to verify this patch. I will provide updates no later than early next week. Sorry for the possible delay. Best Regards, Hao Wu > Change-Id: I32d36bfbff0eee93d14a9a1a86e5ce7635251b64 > Signed-off-by: Ashish Singhal <ashishsin...@nvidia.com> > --- > MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c | 128 > ++++++++++++++++++++++++++++++++ > MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c | 25 +------ > MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h | 28 +++++++ > 3 files changed, 160 insertions(+), 21 deletions(-) > > diff --git a/MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c > b/MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c > index 71d6113..c4d93ae 100644 > --- a/MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c > +++ b/MdeModulePkg/Bus/Pci/XhciPei/DmaMem.c > @@ -225,6 +225,134 @@ IoMmuFreeBuffer ( > } > > /** > + Allocates aligned pages that are suitable for an > OperationBusMasterCommonBuffer or > + OperationBusMasterCommonBuffer64 mapping. > + > + @param Pages The number of pages to allocate. > + @param Alignment The requested alignment of the allocation. > Must be a power of two. > + @param HostAddress A pointer to store the base system memory > address of the > + allocated range. > + @param DeviceAddress The resulting map address for the bus master > PCI controller to use to > + access the hosts HostAddress. > + @param Mapping A resulting value to pass to Unmap(). > + > + @retval EFI_SUCCESS The requested memory pages were allocated. > + @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal > attribute bits are > + MEMORY_WRITE_COMBINE and MEMORY_CACHED. > + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. > + @retval EFI_OUT_OF_RESOURCES The memory pages could not be > allocated. > + > +**/ > +EFI_STATUS > +IoMmuAllocateAlignedBuffer ( > + IN UINTN Pages, > + IN UINTN Alignment, > + OUT VOID **HostAddress, > + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, > + OUT VOID **Mapping > + ) > +{ > + EFI_STATUS Status; > + VOID *Memory; > + UINTN AlignedMemory; > + UINTN AlignmentMask; > + UINTN UnalignedPages; > + UINTN RealPages; > + UINTN NumberOfBytes; > + EFI_PHYSICAL_ADDRESS HostPhyAddress; > + > + *HostAddress = NULL; > + *DeviceAddress = 0; > + AlignmentMask = Alignment - 1; > + > + // > + // Calculate the total number of pages since alignment is larger than page > size. > + // > + RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); > + > + // > + // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not > overflow. > + // > + ASSERT (RealPages > Pages); > + > + if (mIoMmu != NULL) { > + Status = mIoMmu->AllocateBuffer ( > + mIoMmu, > + EfiBootServicesData, > + RealPages, > + HostAddress, > + 0 > + ); > + if (EFI_ERROR (Status)) { > + return EFI_OUT_OF_RESOURCES; > + } > + Memory = *HostAddress; > + AlignedMemory = ((UINTN) Memory + AlignmentMask) & > ~AlignmentMask; > + UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) > Memory); > + if (UnalignedPages > 0) { > + // > + // Free first unaligned page(s). > + // > + Status = mIoMmu->FreeBuffer ( > + mIoMmu, > + UnalignedPages, > + Memory); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + } > + Memory = (VOID *)(UINTN)(AlignedMemory + EFI_PAGES_TO_SIZE > (Pages)); > + UnalignedPages = RealPages - Pages - UnalignedPages; > + if (UnalignedPages > 0) { > + // > + // Free last unaligned page(s). > + // > + Status = mIoMmu->FreeBuffer ( > + mIoMmu, > + UnalignedPages, > + Memory); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + } > + *HostAddress = (VOID *) AlignedMemory; > + NumberOfBytes = EFI_PAGES_TO_SIZE(Pages); > + Status = mIoMmu->Map ( > + mIoMmu, > + EdkiiIoMmuOperationBusMasterCommonBuffer, > + *HostAddress, > + &NumberOfBytes, > + DeviceAddress, > + Mapping > + ); > + if (EFI_ERROR (Status)) { > + return EFI_OUT_OF_RESOURCES; > + } > + Status = mIoMmu->SetAttribute ( > + mIoMmu, > + *Mapping, > + EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + } else { > + Status = PeiServicesAllocatePages ( > + EfiBootServicesData, > + RealPages, > + &HostPhyAddress > + ); > + if (EFI_ERROR (Status)) { > + return EFI_OUT_OF_RESOURCES; > + } > + *HostAddress = (VOID *)(((UINTN) HostPhyAddress + AlignmentMask) & > ~AlignmentMask); > + *DeviceAddress = ((UINTN) HostPhyAddress + AlignmentMask) & > ~AlignmentMask; > + *Mapping = NULL; > + } > + return Status; > +} > + > +/** > Initialize IOMMU. > **/ > VOID > diff --git a/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c > b/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c > index 56c0b90..01f42285 100644 > --- a/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c > +++ b/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c > @@ -562,11 +562,7 @@ UsbHcAllocateAlignedPages ( > { > EFI_STATUS Status; > VOID *Memory; > - UINTN AlignedMemory; > - UINTN AlignmentMask; > EFI_PHYSICAL_ADDRESS DeviceMemory; > - UINTN AlignedDeviceMemory; > - UINTN RealPages; > > // > // Alignment must be a power of two or zero. > @@ -582,18 +578,9 @@ UsbHcAllocateAlignedPages ( > } > > if (Alignment > EFI_PAGE_SIZE) { > - // > - // Calculate the total number of pages since alignment is larger than > page > size. > - // > - AlignmentMask = Alignment - 1; > - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); > - // > - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not > overflow. > - // > - ASSERT (RealPages > Pages); > - > - Status = IoMmuAllocateBuffer ( > + Status = IoMmuAllocateAlignedBuffer ( > Pages, > + Alignment, > &Memory, > &DeviceMemory, > Mapping > @@ -601,8 +588,6 @@ UsbHcAllocateAlignedPages ( > if (EFI_ERROR (Status)) { > return EFI_OUT_OF_RESOURCES; > } > - AlignedMemory = ((UINTN) Memory + AlignmentMask) & > ~AlignmentMask; > - AlignedDeviceMemory = ((UINTN) DeviceMemory + AlignmentMask) & > ~AlignmentMask; > } else { > // > // Do not over-allocate pages in this case. > @@ -616,12 +601,10 @@ UsbHcAllocateAlignedPages ( > if (EFI_ERROR (Status)) { > return EFI_OUT_OF_RESOURCES; > } > - AlignedMemory = (UINTN) Memory; > - AlignedDeviceMemory = (UINTN) DeviceMemory; > } > > - *HostAddress = (VOID *) AlignedMemory; > - *DeviceAddress = (EFI_PHYSICAL_ADDRESS) AlignedDeviceMemory; > + *HostAddress = Memory; > + *DeviceAddress = DeviceMemory; > > return EFI_SUCCESS; > } > diff --git a/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h > b/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h > index 480e13b..03a55f3 100644 > --- a/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h > +++ b/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h > @@ -342,4 +342,32 @@ IoMmuFreeBuffer ( > IN VOID *Mapping > ); > > +/** > + Allocates aligned pages that are suitable for an > OperationBusMasterCommonBuffer or > + OperationBusMasterCommonBuffer64 mapping. > + > + @param Pages The number of pages to allocate. > + @param Alignment The requested alignment of the allocation. > Must be a power of two. > + @param HostAddress A pointer to store the base system memory > address of the > + allocated range. > + @param DeviceAddress The resulting map address for the bus master > PCI controller to use to > + access the hosts HostAddress. > + @param Mapping A resulting value to pass to Unmap(). > + > + @retval EFI_SUCCESS The requested memory pages were allocated. > + @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal > attribute bits are > + MEMORY_WRITE_COMBINE and MEMORY_CACHED. > + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. > + @retval EFI_OUT_OF_RESOURCES The memory pages could not be > allocated. > + > +**/ > +EFI_STATUS > +IoMmuAllocateAlignedBuffer ( > + IN UINTN Pages, > + IN UINTN Alignment, > + OUT VOID **HostAddress, > + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, > + OUT VOID **Mapping > + ); > + > #endif > -- > 2.7.4 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#49048): https://edk2.groups.io/g/devel/message/49048 Mute This Topic: https://groups.io/mt/34547970/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-