- if (((UINTN)HostAddress & (gCacheAlignment - 1)) != 0) {\r
- Map->DoubleBuffer = TRUE;\r
- Status = DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (*NumberOfBytes), &Buffer);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
+ if ((((UINTN)HostAddress & (mCpu->DmaBufferAlignment - 1)) != 0) ||\r
+ ((*NumberOfBytes & (mCpu->DmaBufferAlignment - 1)) != 0)) {\r
+\r
+ // Get the cacheability of the region\r
+ Status = gDS->GetMemorySpaceDescriptor (*DeviceAddress, &GcdDescriptor);\r
+ if (EFI_ERROR(Status)) {\r
+ goto FreeMapInfo;\r
+ }\r
+\r
+ // If the mapped buffer is not an uncached buffer\r
+ if ((GcdDescriptor.Attributes & (EFI_MEMORY_WB | EFI_MEMORY_WT)) != 0) {\r
+ //\r
+ // Operations of type MapOperationBusMasterCommonBuffer are only allowed\r
+ // on uncached buffers.\r
+ //\r
+ if (Operation == MapOperationBusMasterCommonBuffer) {\r
+ DEBUG ((EFI_D_ERROR,\r
+ "%a: Operation type 'MapOperationBusMasterCommonBuffer' is only supported\n"\r
+ "on memory regions that were allocated using DmaAllocateBuffer ()\n",\r
+ __FUNCTION__));\r
+ Status = EFI_UNSUPPORTED;\r
+ goto FreeMapInfo;\r
+ }\r
+\r
+ //\r
+ // If the buffer does not fill entire cache lines we must double buffer into\r
+ // uncached memory. Device (PCI) address becomes uncached page.\r
+ //\r
+ Map->DoubleBuffer = TRUE;\r
+ Status = DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (*NumberOfBytes), &Buffer);\r
+ if (EFI_ERROR (Status)) {\r
+ goto FreeMapInfo;\r
+ }\r
+\r
+ if (Operation == MapOperationBusMasterRead) {\r
+ CopyMem (Buffer, HostAddress, *NumberOfBytes);\r
+ }\r
+\r
+ *DeviceAddress = (PHYSICAL_ADDRESS)(UINTN)Buffer;\r
+ } else {\r
+ Map->DoubleBuffer = FALSE;\r