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>
---
 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 (#110600): https://edk2.groups.io/g/devel/message/110600
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]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to