- )
-{
- MAP_INFO_INSTANCE *Map;
-
- if ( HostAddress == NULL || NumberOfBytes == NULL ||
- DeviceAddress == NULL || Mapping == NULL ) {
- return EFI_INVALID_PARAMETER;
- }
-
-
- if (Operation >= MapOperationMaximum) {
- return EFI_INVALID_PARAMETER;
- }
-
- *DeviceAddress = ConvertToPhysicalAddress (HostAddress);
-
- // Remember range so we can flush on the other side
- Map = AllocatePool (sizeof (MAP_INFO_INSTANCE));
- if (Map == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- *Mapping = Map;
-
- Map->HostAddress = (UINTN)HostAddress;
- Map->DeviceAddress = *DeviceAddress;
- Map->NumberOfBytes = *NumberOfBytes;
- Map->Operation = Operation;
-
- // EfiCpuFlushTypeWriteBack, EfiCpuFlushTypeInvalidate
- gCpu->FlushDataCache (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, *NumberOfBytes, EfiCpuFlushTypeWriteBackInvalidate);
-
- return EFI_SUCCESS;
-}
-
-
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ MAP_INFO_INSTANCE *Map;\r
+ VOID *Buffer;\r
+\r
+ if ( HostAddress == NULL || NumberOfBytes == NULL || \r
+ DeviceAddress == NULL || Mapping == NULL ) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ \r
+\r
+ if (Operation >= MapOperationMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *DeviceAddress = ConvertToPhysicalAddress (HostAddress);\r
+\r
+ // Remember range so we can flush on the other side\r
+ Map = AllocatePool (sizeof (MAP_INFO_INSTANCE));\r
+ if (Map == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ \r
+ *Mapping = Map;\r
+\r
+ 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
+ }\r
+ \r
+ *DeviceAddress = (PHYSICAL_ADDRESS)(UINTN)Buffer;\r
+ \r
+ } else {\r
+ Map->DoubleBuffer = FALSE;\r
+ }\r
+\r
+ *NumberOfBytes &= *NumberOfBytes & ~(gCacheAlignment - 1); // Only do it on full cache lines\r
+ \r
+ Map->HostAddress = (UINTN)HostAddress;\r
+ Map->DeviceAddress = *DeviceAddress;\r
+ Map->NumberOfBytes = *NumberOfBytes;\r
+ Map->Operation = Operation;\r
+\r
+ if (Map->DoubleBuffer) {\r
+ if (Map->Operation == MapOperationBusMasterWrite) {\r
+ CopyMem ((VOID *)(UINTN)Map->DeviceAddress, (VOID *)(UINTN)Map->HostAddress, Map->NumberOfBytes);\r
+ }\r
+ } else {\r
+ // EfiCpuFlushTypeWriteBack, EfiCpuFlushTypeInvalidate\r
+ if (Map->Operation == MapOperationBusMasterWrite || Map->Operation == MapOperationBusMasterRead) {\r
+ gCpu->FlushDataCache (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, Map->NumberOfBytes, EfiCpuFlushTypeWriteBackInvalidate);\r
+ }\r
+ }\r
+ \r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r