mirror of https://github.com/acidanthera/audk.git
ArmPkg/ArmDmaLib: Fix coherency issues in DmaLib
Some coherencies issues were existing in the former version of DmaLib. These issues could have for consequences to not make the MdeModulePkg/Bus/Usb software stack not work. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12137 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
9201b04422
commit
e6d572ba03
|
@ -13,9 +13,10 @@
|
|||
|
||||
**/
|
||||
|
||||
#include <Base.h>
|
||||
#include <PiDxe.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/DmaLib.h>
|
||||
#include <Library/DxeServicesTableLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UncachedMemoryAllocationLib.h>
|
||||
|
@ -38,9 +39,6 @@ typedef struct {
|
|||
EFI_CPU_ARCH_PROTOCOL *gCpu;
|
||||
UINTN gCacheAlignment = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Provides the DMA controller-specific addresses needed to access system memory.
|
||||
|
||||
|
@ -74,13 +72,12 @@ DmaMap (
|
|||
EFI_STATUS Status;
|
||||
MAP_INFO_INSTANCE *Map;
|
||||
VOID *Buffer;
|
||||
EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
|
||||
|
||||
if ( HostAddress == NULL || NumberOfBytes == NULL ||
|
||||
DeviceAddress == NULL || Mapping == NULL ) {
|
||||
if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
if (Operation >= MapOperationMaximum) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
@ -97,6 +94,15 @@ DmaMap (
|
|||
|
||||
if ((((UINTN)HostAddress & (gCacheAlignment - 1)) != 0) ||
|
||||
((*NumberOfBytes % gCacheAlignment) != 0)) {
|
||||
|
||||
// Get the cacheability of the region
|
||||
Status = gDS->GetMemorySpaceDescriptor (HostAddress, &GcdDescriptor);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
// If the mapped buffer is not an uncached buffer
|
||||
if (GcdDescriptor.Attributes != EFI_MEMORY_UC) {
|
||||
//
|
||||
// If the buffer does not fill entire cache lines we must double buffer into
|
||||
// uncached memory. Device (PCI) address becomes uncached page.
|
||||
|
@ -107,28 +113,32 @@ DmaMap (
|
|||
return Status;
|
||||
}
|
||||
|
||||
*DeviceAddress = (PHYSICAL_ADDRESS)(UINTN)Buffer;
|
||||
if ((Operation == MapOperationBusMasterRead) || (Operation == MapOperationBusMasterCommonBuffer)) {
|
||||
CopyMem (Buffer, HostAddress, *NumberOfBytes);
|
||||
}
|
||||
|
||||
*DeviceAddress = (PHYSICAL_ADDRESS)(UINTN)Buffer;
|
||||
} else {
|
||||
Map->DoubleBuffer = FALSE;
|
||||
}
|
||||
} else {
|
||||
Map->DoubleBuffer = FALSE;
|
||||
|
||||
// Flush the Data Cache (should not have any effect if the memory region is uncached)
|
||||
gCpu->FlushDataCache (gCpu, *DeviceAddress, *NumberOfBytes, EfiCpuFlushTypeWriteBackInvalidate);
|
||||
|
||||
if ((Operation == MapOperationBusMasterRead) || (Operation == MapOperationBusMasterCommonBuffer)) {
|
||||
// In case the buffer is used for instance to send command to a PCI controller, we must ensure the memory is uncached
|
||||
Status = gDS->SetMemorySpaceAttributes (ALIGN_VALUE(*DeviceAddress - BASE_4KB - 1,BASE_4KB), ALIGN_VALUE(*NumberOfBytes,BASE_4KB), EFI_MEMORY_UC);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
}
|
||||
|
||||
Map->HostAddress = (UINTN)HostAddress;
|
||||
Map->DeviceAddress = *DeviceAddress;
|
||||
Map->NumberOfBytes = *NumberOfBytes;
|
||||
Map->Operation = Operation;
|
||||
|
||||
if (Map->DoubleBuffer) {
|
||||
if (Map->Operation == MapOperationBusMasterWrite) {
|
||||
CopyMem ((VOID *)(UINTN)Map->DeviceAddress, (VOID *)(UINTN)Map->HostAddress, Map->NumberOfBytes);
|
||||
}
|
||||
} else {
|
||||
// EfiCpuFlushTypeWriteBack, EfiCpuFlushTypeInvalidate
|
||||
if (Map->Operation == MapOperationBusMasterWrite || Map->Operation == MapOperationBusMasterRead) {
|
||||
gCpu->FlushDataCache (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, Map->NumberOfBytes, EfiCpuFlushTypeWriteBackInvalidate);
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -159,7 +169,7 @@ DmaUnmap (
|
|||
Map = (MAP_INFO_INSTANCE *)Mapping;
|
||||
|
||||
if (Map->DoubleBuffer) {
|
||||
if (Map->Operation == MapOperationBusMasterRead) {
|
||||
if ((Map->Operation == MapOperationBusMasterWrite) || (Map->Operation == MapOperationBusMasterCommonBuffer)) {
|
||||
CopyMem ((VOID *)(UINTN)Map->HostAddress, (VOID *)(UINTN)Map->DeviceAddress, Map->NumberOfBytes);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue