EmbeddedPkg/MmcDxe: Align the ExtCSD buffer
authorJun Nie <jun.nie@linaro.org>
Tue, 4 Jul 2017 15:43:16 +0000 (23:43 +0800)
committerLeif Lindholm <leif.lindholm@linaro.org>
Wed, 5 Jul 2017 15:07:54 +0000 (16:07 +0100)
ExtCSD structure may be read via DMA. So align it to
page to avoid data corruption.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jun Nie <jun.nie@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
EmbeddedPkg/Universal/MmcDxe/Mmc.c
EmbeddedPkg/Universal/MmcDxe/Mmc.h
EmbeddedPkg/Universal/MmcDxe/MmcIdentification.c

index 570e1d2..3b9dc18 100644 (file)
@@ -171,6 +171,9 @@ EFI_STATUS DestroyMmcHostInstance (
   if (MmcHostInstance->BlockIo.Media) {\r
     FreePool(MmcHostInstance->BlockIo.Media);\r
   }\r
+  if (MmcHostInstance->CardInfo.ECSDData) {\r
+    FreePages (MmcHostInstance->CardInfo.ECSDData, EFI_SIZE_TO_PAGES (sizeof (ECSD)));\r
+  }\r
   FreePool (MmcHostInstance);\r
 \r
   return Status;\r
index 8a7d5a3..f3e56ff 100644 (file)
@@ -319,7 +319,7 @@ typedef struct  {
   OCR       OCRData;\r
   CID       CIDData;\r
   CSD       CSDData;\r
-  ECSD      ECSDData;                         // MMC V4 extended card specific\r
+  ECSD      *ECSDData;                         // MMC V4 extended card specific\r
 } CARD_INFO;\r
 \r
 typedef struct _MMC_HOST_INSTANCE {\r
index c28207e..7f74c54 100644 (file)
@@ -13,6 +13,7 @@
 **/\r
 \r
 #include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
 #include <Library/TimerLib.h>\r
 \r
 #include "Mmc.h"\r
@@ -210,15 +211,19 @@ EmmcIdentificationMode (
   }\r
 \r
   // Fetch ECSD\r
+  MmcHostInstance->CardInfo.ECSDData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ECSD)));\r
+  if (MmcHostInstance->CardInfo.ECSDData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
   Status = Host->SendCommand (Host, MMC_CMD8, 0);\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): ECSD fetch error, Status=%r.\n", Status));\r
   }\r
 \r
-  Status = Host->ReadBlockData (Host, 0, 512, (UINT32 *)&(MmcHostInstance->CardInfo.ECSDData));\r
+  Status = Host->ReadBlockData (Host, 0, 512, (UINT32 *)MmcHostInstance->CardInfo.ECSDData);\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): ECSD read error, Status=%r.\n", Status));\r
-    return Status;\r
+    goto FreePageExit;\r
   }\r
 \r
   // Make sure device exiting data mode\r
@@ -226,7 +231,7 @@ EmmcIdentificationMode (
     Status = EmmcGetDeviceState (MmcHostInstance, &State);\r
     if (EFI_ERROR (Status)) {\r
       DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Failed to get device state, Status=%r.\n", Status));\r
-      return Status;\r
+      goto FreePageExit;\r
     }\r
   } while (State == EMMC_DATA_STATE);\r
 \r
@@ -237,12 +242,16 @@ EmmcIdentificationMode (
   Media->LogicalBlocksPerPhysicalBlock = 1;\r
   Media->IoAlign = 4;\r
   // Compute last block using bits [215:212] of the ECSD\r
-  Media->LastBlock = MmcHostInstance->CardInfo.ECSDData.SECTOR_COUNT - 1; // eMMC isn't supposed to report this for\r
+  Media->LastBlock = MmcHostInstance->CardInfo.ECSDData->SECTOR_COUNT - 1; // eMMC isn't supposed to report this for\r
   // Cards <2GB in size, but the model does.\r
 \r
   // Setup card type\r
   MmcHostInstance->CardInfo.CardType = EMMC_CARD;\r
   return EFI_SUCCESS;\r
+\r
+FreePageExit:\r
+  FreePages (MmcHostInstance->CardInfo.ECSDData, EFI_SIZE_TO_PAGES (sizeof (ECSD)));\r
+  return Status;\r
 }\r
 \r
 STATIC\r
@@ -258,7 +267,7 @@ InitializeEmmcDevice (
   UINT32     TimingMode[4] = {EMMCHS52DDR1V2, EMMCHS52DDR1V8, EMMCHS52, EMMCHS26};\r
 \r
   Host  = MmcHostInstance->MmcHost;\r
-  ECSDData = &MmcHostInstance->CardInfo.ECSDData;\r
+  ECSDData = MmcHostInstance->CardInfo.ECSDData;\r
   if (ECSDData->DEVICE_TYPE == EMMCBACKWARD)\r
     return EFI_SUCCESS;\r
 \r