ArmPkg/CpuDxe: Added support to not set a memory region with the same attribute

Changing the attribute implies some cache management (clean & invalidate).
Preventing the cache management should improve the performance.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>



git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14568 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Olivier Martin
2013-08-19 17:38:39 +00:00
committed by oliviermartin
parent 6adbd5b4d2
commit 2e969d2e9e
4 changed files with 364 additions and 4 deletions

View File

@@ -178,18 +178,37 @@ CpuSetMemoryAttributes (
IN EFI_CPU_ARCH_PROTOCOL *This,
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes
IN UINT64 EfiAttributes
)
{
DEBUG ((EFI_D_PAGE, "CpuSetMemoryAttributes(%lx, %lx, %lx)\n", BaseAddress, Length, Attributes));
EFI_STATUS Status;
UINTN ArmAttributes;
UINTN RegionBaseAddress;
UINTN RegionLength;
UINTN RegionArmAttributes;
if ((BaseAddress & (SIZE_4KB - 1)) != 0) {
// Minimum granularity is SIZE_4KB (4KB on ARM)
DEBUG ((EFI_D_PAGE, "CpuSetMemoryAttributes(%lx, %lx, %lx): Minimum ganularity is SIZE_4KB\n", BaseAddress, Length, Attributes));
DEBUG ((EFI_D_PAGE, "CpuSetMemoryAttributes(%lx, %lx, %lx): Minimum ganularity is SIZE_4KB\n", BaseAddress, Length, EfiAttributes));
return EFI_UNSUPPORTED;
}
return SetMemoryAttributes (BaseAddress, Length, Attributes, 0);
// Convert the 'Attribute' into ARM Attribute
ArmAttributes = EfiAttributeToArmAttribute (EfiAttributes);
// Get the region starting from 'BaseAddress' and its 'Attribute'
RegionBaseAddress = BaseAddress;
Status = GetMemoryRegion (&RegionBaseAddress, &RegionLength, &RegionArmAttributes);
// Data & Instruction Caches are flushed when we set new memory attributes.
// So, we only set the attributes if the new region is different.
if (EFI_ERROR (Status) || (RegionArmAttributes != ArmAttributes) ||
((BaseAddress + Length) > (RegionBaseAddress + RegionLength)))
{
return SetMemoryAttributes (BaseAddress, Length, EfiAttributes, 0);
} else {
return EFI_SUCCESS;
}
}
EFI_STATUS