On Fri, 3 Nov 2023 at 03:53, John Chew <yuinyee.c...@starfivetech.com> wrote: > > The buffer address passed into the read/write block function sometimes > larger than 4GB. This driver only support 32-bit DMA addressing. > MMC timeout will occur if DMA buffer is allocated in 64-bit address. > > Cc: Sunil V L <suni...@ventanamicro.com> > Cc: Leif Lindholm <quic_llind...@quicinc.com> > Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org> > Cc: Michael D Kinney <michael.d.kin...@intel.com> > Cc: Li Yong <yong...@intel.com> > Signed-off-by: John Chew <yuinyee.c...@starfivetech.com>
This logic does not belong in the driver. Please investigate whether it is possible to migrate this driver to the DMA libraries in EmbeddedPkg, which already support DMA address limits and translation. That should allow you to remove all explicit cache maintenance, and potentially reuse this IP with coherent DMA too. > --- > Silicon/Synopsys/DesignWare/Drivers/DwEmmcDxe/DwEmmcDxe.c | 79 > ++++++++++++++++---- > 1 file changed, 64 insertions(+), 15 deletions(-) > > diff --git a/Silicon/Synopsys/DesignWare/Drivers/DwEmmcDxe/DwEmmcDxe.c > b/Silicon/Synopsys/DesignWare/Drivers/DwEmmcDxe/DwEmmcDxe.c > index 39e4d994fcd4..8233639b0ce8 100644 > --- a/Silicon/Synopsys/DesignWare/Drivers/DwEmmcDxe/DwEmmcDxe.c > +++ b/Silicon/Synopsys/DesignWare/Drivers/DwEmmcDxe/DwEmmcDxe.c > @@ -601,27 +601,57 @@ DwEmmcWaitDmaComplete ( > return Status; > } > > +STATIC > +UINT32 * > +AllocateMemoryBelow4G ( > + IN UINTN Size > + ) > +{ > + UINTN Pages; > + EFI_PHYSICAL_ADDRESS Address; > + EFI_STATUS Status; > + UINT32 *Buffer; > + > + Pages = EFI_SIZE_TO_PAGES (Size); > + Address = 0xFFFFFFFF; > + > + Status = gBS->AllocatePages ( > + AllocateMaxAddress, > + EfiBootServicesData, > + Pages, > + &Address > + ); > + ASSERT_EFI_ERROR (Status); > + > + Buffer = (UINT32 *)(UINTN)Address; > + ZeroMem (Buffer, Size); > + > + return Buffer; > +} > + > EFI_STATUS > DwEmmcReadBlockData ( > - IN EFI_MMC_HOST_PROTOCOL *This, > - IN EFI_LBA Lba, > - IN UINTN Length, > - IN UINT32* Buffer > + IN EFI_MMC_HOST_PROTOCOL *This, > + IN EFI_LBA Lba, > + IN UINTN Length, > + IN UINT32* Buffer > ) > { > EFI_STATUS Status; > UINT32 DescPages, CountPerPage, Count; > EFI_TPL Tpl; > + UINT32 *DmaBuf; > > Tpl = gBS->RaiseTPL (TPL_NOTIFY); > + DmaBuf = AllocateMemoryBelow4G(Length); > > CountPerPage = EFI_PAGE_SIZE / 16; > Count = (Length + DWEMMC_DMA_BUF_SIZE - 1) / DWEMMC_DMA_BUF_SIZE; > DescPages = (Count + CountPerPage - 1) / CountPerPage; > > - InvalidateDataCacheRange (Buffer, Length); > + InvalidateDataCacheRange (DmaBuf, Length); > > - Status = PrepareDmaData (gpIdmacDesc, Length, Buffer); > + Status = PrepareDmaData (gpIdmacDesc, Length, DmaBuf); > if (EFI_ERROR (Status)) { > goto out; > } > @@ -637,11 +667,14 @@ DwEmmcReadBlockData ( > Status = DwEmmcWaitDmaComplete(This, 1); > > if (DWMCI_SD_READ_MASK(mDwEmmcArgument) && (FixedPcdGetBool > (PcdDwEmmcDxeCPULittleEndian))) { > - Buffer[3] = SwapBytes32(Buffer[3]); > - Buffer[4] = SwapBytes32(Buffer[4]); > + DmaBuf[3] = SwapBytes32(DmaBuf[3]); > + DmaBuf[4] = SwapBytes32(DmaBuf[4]); > } > > + CopyMem(Buffer, DmaBuf, Length); > + > out: > + FreePages (DmaBuf, EFI_SIZE_TO_PAGES(Length)); > // Restore Tpl > gBS->RestoreTPL (Tpl); > return Status; > @@ -649,25 +682,29 @@ out: > > EFI_STATUS > DwEmmcWriteBlockData ( > - IN EFI_MMC_HOST_PROTOCOL *This, > - IN EFI_LBA Lba, > - IN UINTN Length, > - IN UINT32* Buffer > + IN EFI_MMC_HOST_PROTOCOL *This, > + IN EFI_LBA Lba, > + IN UINTN Length, > + IN UINT32* Buffer > ) > { > EFI_STATUS Status; > UINT32 DescPages, CountPerPage, Count; > EFI_TPL Tpl; > + UINT32 *DmaBuf; > > Tpl = gBS->RaiseTPL (TPL_NOTIFY); > > + DmaBuf = AllocateMemoryBelow4G(Length); > + CopyMem(DmaBuf, Buffer, Length); > + > CountPerPage = EFI_PAGE_SIZE / 16; > Count = (Length + DWEMMC_DMA_BUF_SIZE - 1) / DWEMMC_DMA_BUF_SIZE; > DescPages = (Count + CountPerPage - 1) / CountPerPage; > > - WriteBackDataCacheRange (Buffer, Length); > + WriteBackDataCacheRange (DmaBuf, Length); > > - Status = PrepareDmaData (gpIdmacDesc, Length, Buffer); > + Status = PrepareDmaData (gpIdmacDesc, Length, DmaBuf); > if (EFI_ERROR (Status)) { > goto out; > } > @@ -683,6 +720,7 @@ DwEmmcWriteBlockData ( > Status = DwEmmcWaitDmaComplete(This, 0); > > out: > + FreePages (DmaBuf, EFI_SIZE_TO_PAGES(Length)); > // Restore Tpl > gBS->RestoreTPL (Tpl); > return Status; > @@ -772,6 +810,7 @@ DwEmmcDxeInitialize ( > { > EFI_STATUS Status; > EFI_HANDLE Handle; > + EFI_PHYSICAL_ADDRESS Address; > > if (!FixedPcdGetBool (PcdDwPermitObsoleteDrivers)) { > ASSERT (FALSE); > @@ -781,7 +820,17 @@ DwEmmcDxeInitialize ( > Handle = NULL; > > DwEmmcAdjustFifoThreshold (); > - gpIdmacDesc = (DWEMMC_IDMAC_DESCRIPTOR *)AllocatePages > (DWEMMC_MAX_DESC_PAGES); > + > + Address = 0xffffffff; > + Status = gBS->AllocatePages ( > + AllocateMaxAddress, > + EfiBootServicesData, > + DWEMMC_MAX_DESC_PAGES, > + &Address > + ); > + gpIdmacDesc = (DWEMMC_IDMAC_DESCRIPTOR *)(UINTN)Address; > + ZeroMem (gpIdmacDesc, DWEMMC_MAX_DESC_PAGES); > + > if (gpIdmacDesc == NULL) { > return EFI_BUFFER_TOO_SMALL; > } > -- > 2.34.1 > > > > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#111612): https://edk2.groups.io/g/devel/message/111612 Mute This Topic: https://groups.io/mt/102357283/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-