return EFI_SUCCESS;\r
}\r
\r
-/**\r
- Searches memory descriptors covered by given memory range.\r
-\r
- This function searches into the Gcd Memory Space for descriptors\r
- (from StartIndex to EndIndex) that contains the memory range\r
- specified by BaseAddress and Length.\r
-\r
- @param MemorySpaceMap Gcd Memory Space Map as array.\r
- @param NumberOfDescriptors Number of descriptors in map.\r
- @param BaseAddress BaseAddress for the requested range.\r
- @param Length Length for the requested range.\r
- @param StartIndex Start index into the Gcd Memory Space Map.\r
- @param EndIndex End index into the Gcd Memory Space Map.\r
-\r
- @retval EFI_SUCCESS Search successfully.\r
- @retval EFI_NOT_FOUND The requested descriptors does not exist.\r
-\r
-**/\r
-EFI_STATUS\r
-SearchGcdMemorySpaces (\r
- IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,\r
- IN UINTN NumberOfDescriptors,\r
- IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
- IN UINT64 Length,\r
- OUT UINTN *StartIndex,\r
- OUT UINTN *EndIndex\r
- )\r
-{\r
- UINTN Index;\r
-\r
- *StartIndex = 0;\r
- *EndIndex = 0;\r
- for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
- if (BaseAddress >= MemorySpaceMap[Index].BaseAddress &&\r
- BaseAddress < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {\r
- *StartIndex = Index;\r
- }\r
- if (BaseAddress + Length - 1 >= MemorySpaceMap[Index].BaseAddress &&\r
- BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {\r
- *EndIndex = Index;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-\r
-/**\r
- Sets the attributes for a specified range in Gcd Memory Space Map.\r
-\r
- This function sets the attributes for a specified range in\r
- Gcd Memory Space Map.\r
-\r
- @param MemorySpaceMap Gcd Memory Space Map as array\r
- @param NumberOfDescriptors Number of descriptors in map\r
- @param BaseAddress BaseAddress for the range\r
- @param Length Length for the range\r
- @param Attributes Attributes to set\r
-\r
- @retval EFI_SUCCESS Memory attributes set successfully\r
- @retval EFI_NOT_FOUND The specified range does not exist in Gcd Memory Space\r
-\r
-**/\r
-EFI_STATUS\r
-SetGcdMemorySpaceAttributes (\r
- IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,\r
- IN UINTN NumberOfDescriptors,\r
- IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
- IN UINT64 Length,\r
- IN UINT64 Attributes\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- UINTN StartIndex;\r
- UINTN EndIndex;\r
- EFI_PHYSICAL_ADDRESS RegionStart;\r
- UINT64 RegionLength;\r
-\r
- //\r
- // Get all memory descriptors covered by the memory range\r
- //\r
- Status = SearchGcdMemorySpaces (\r
- MemorySpaceMap,\r
- NumberOfDescriptors,\r
- BaseAddress,\r
- Length,\r
- &StartIndex,\r
- &EndIndex\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Go through all related descriptors and set attributes accordingly\r
- //\r
- for (Index = StartIndex; Index <= EndIndex; Index++) {\r
- if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {\r
- continue;\r
- }\r
- //\r
- // Calculate the start and end address of the overlapping range\r
- //\r
- if (BaseAddress >= MemorySpaceMap[Index].BaseAddress) {\r
- RegionStart = BaseAddress;\r
- } else {\r
- RegionStart = MemorySpaceMap[Index].BaseAddress;\r
- }\r
- if (BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {\r
- RegionLength = BaseAddress + Length - RegionStart;\r
- } else {\r
- RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;\r
- }\r
- //\r
- // Set memory attributes according to MTRR attribute and the original attribute of descriptor\r
- //\r
- gDS->SetMemorySpaceAttributes (\r
- RegionStart,\r
- RegionLength,\r
- (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes)\r
- );\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
EFI_STATUS\r
SyncCacheConfigPage (\r
IN UINT32 SectionIndex,\r
\r
return Status;\r
}\r
-\r
-\r
-/**\r
- This function modifies the attributes for the memory region specified by BaseAddress and\r
- Length from their current attributes to the attributes specified by Attributes.\r
-\r
- @param This The EFI_CPU_ARCH_PROTOCOL instance.\r
- @param BaseAddress The physical address that is the start address of a memory region.\r
- @param Length The size in bytes of the memory region.\r
- @param Attributes The bit mask of attributes to set for the memory region.\r
-\r
- @retval EFI_SUCCESS The attributes were set for the memory region.\r
- @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by\r
- BaseAddress and Length cannot be modified.\r
- @retval EFI_INVALID_PARAMETER Length is zero.\r
- @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of\r
- the memory resource range.\r
- @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory\r
- resource range specified by BaseAddress and Length.\r
- The bit mask of attributes is not support for the memory resource\r
- range specified by BaseAddress and Length.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CpuSetMemoryAttributes (\r
- IN EFI_CPU_ARCH_PROTOCOL *This,\r
- IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
- IN UINT64 Length,\r
- IN UINT64 Attributes\r
- )\r
-{\r
- DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(%lx, %lx, %lx)\n", BaseAddress, Length, Attributes));\r
- if ( ((BaseAddress & ~TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK) != 0) || ((Length & ~TT_DESCRIPTOR_PAGE_BASE_ADDRESS_MASK) != 0)){\r
- // minimum granularity is SIZE_4KB (4KB on ARM)\r
- DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(%lx, %lx, %lx): minimum ganularity is SIZE_4KB\n", BaseAddress, Length, Attributes));\r
- return EFI_UNSUPPORTED;\r
- }\r
- \r
- return SetMemoryAttributes (BaseAddress, Length, Attributes, 0);\r
-}\r
-\r
-\r
-\r
-//\r
-// Add a new protocol to support \r
-//\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuConvertPagesToUncachedVirtualAddress (\r
- IN VIRTUAL_UNCACHED_PAGES_PROTOCOL *This,\r
- IN EFI_PHYSICAL_ADDRESS Address,\r
- IN UINTN Length,\r
- IN EFI_PHYSICAL_ADDRESS VirtualMask,\r
- OUT UINT64 *Attributes OPTIONAL\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;\r
- \r
- \r
- if (Attributes != NULL) {\r
- Status = gDS->GetMemorySpaceDescriptor (Address, &GcdDescriptor);\r
- if (!EFI_ERROR (Status)) {\r
- *Attributes = GcdDescriptor.Attributes;\r
- }\r
- }\r
-\r
- //\r
- // Make this address range page fault if accessed. If it is a DMA buffer than this would \r
- // be the PCI address. Code should always use the CPU address, and we will or in VirtualMask\r
- // to that address. \r
- //\r
- Status = SetMemoryAttributes (Address, Length, EFI_MEMORY_WP, 0);\r
- if (!EFI_ERROR (Status)) {\r
- Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_UC, VirtualMask);\r
- }\r
-\r
- DEBUG ((DEBUG_INFO | DEBUG_LOAD, "ConvertPagesToUncachedVirtualAddress()\n Unmapped 0x%08lx Mapped 0x%08lx 0x%x bytes\n", Address, Address | VirtualMask, Length));\r
-\r
- return Status;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuReconvertPages (\r
- IN VIRTUAL_UNCACHED_PAGES_PROTOCOL *This,\r
- IN EFI_PHYSICAL_ADDRESS Address,\r
- IN UINTN Length,\r
- IN EFI_PHYSICAL_ADDRESS VirtualMask,\r
- IN UINT64 Attributes\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- DEBUG ((DEBUG_INFO | DEBUG_LOAD, "CpuReconvertPages(%lx, %x, %lx, %lx)\n", Address, Length, VirtualMask, Attributes));\r
- \r
- //\r
- // Unmap the alaised Address\r
- //\r
- Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_WP, 0);\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Restore atttributes\r
- //\r
- Status = SetMemoryAttributes (Address, Length, Attributes, 0);\r
- }\r
- \r
- return Status;\r
-}\r
-\r
-\r
-VIRTUAL_UNCACHED_PAGES_PROTOCOL gVirtualUncachedPages = {\r
- CpuConvertPagesToUncachedVirtualAddress,\r
- CpuReconvertPages\r
-};\r
/** @file\r
\r
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+ Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
VOID\r
);\r
\r
+EFI_STATUS\r
+SetMemoryAttributes (\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length,\r
+ IN UINT64 Attributes,\r
+ IN EFI_PHYSICAL_ADDRESS VirtualMask\r
+ );\r
+\r
+EFI_STATUS\r
+SetGcdMemorySpaceAttributes (\r
+ IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,\r
+ IN UINTN NumberOfDescriptors,\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length,\r
+ IN UINT64 Attributes\r
+ );\r
+\r
extern VIRTUAL_UNCACHED_PAGES_PROTOCOL gVirtualUncachedPages;\r
\r
#endif // __CPU_DXE_ARM_EXCEPTION_H__\r
# DXE CPU driver\r
# \r
# Copyright (c) 2009, Apple Inc. All rights reserved.<BR>\r
-# Copyright (c) 2011-2012, ARM Limited. All rights reserved.\r
+# Copyright (c) 2011-2013, ARM Limited. All rights reserved.\r
#\r
# This program and the accompanying materials\r
# are licensed and made available under the terms and conditions of the BSD License\r
CpuDxe.c\r
CpuDxe.h\r
CpuMpCore.c\r
+ CpuMmuCommon.c\r
\r
#\r
# Prior to ARMv6 we have multiple stacks, one per mode\r
--- /dev/null
+/** @file\r
+*\r
+* Copyright (c) 2013, ARM Limited. All rights reserved.\r
+*\r
+* This program and the accompanying materials\r
+* are licensed and made available under the terms and conditions of the BSD License\r
+* which accompanies this distribution. The full text of the license may be found at\r
+* http://opensource.org/licenses/bsd-license.php\r
+*\r
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+*\r
+**/\r
+\r
+#include "CpuDxe.h"\r
+\r
+/**\r
+ Searches memory descriptors covered by given memory range.\r
+\r
+ This function searches into the Gcd Memory Space for descriptors\r
+ (from StartIndex to EndIndex) that contains the memory range\r
+ specified by BaseAddress and Length.\r
+\r
+ @param MemorySpaceMap Gcd Memory Space Map as array.\r
+ @param NumberOfDescriptors Number of descriptors in map.\r
+ @param BaseAddress BaseAddress for the requested range.\r
+ @param Length Length for the requested range.\r
+ @param StartIndex Start index into the Gcd Memory Space Map.\r
+ @param EndIndex End index into the Gcd Memory Space Map.\r
+\r
+ @retval EFI_SUCCESS Search successfully.\r
+ @retval EFI_NOT_FOUND The requested descriptors does not exist.\r
+\r
+**/\r
+EFI_STATUS\r
+SearchGcdMemorySpaces (\r
+ IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,\r
+ IN UINTN NumberOfDescriptors,\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length,\r
+ OUT UINTN *StartIndex,\r
+ OUT UINTN *EndIndex\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ *StartIndex = 0;\r
+ *EndIndex = 0;\r
+ for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
+ if ((BaseAddress >= MemorySpaceMap[Index].BaseAddress) &&\r
+ (BaseAddress < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))) {\r
+ *StartIndex = Index;\r
+ }\r
+ if (((BaseAddress + Length - 1) >= MemorySpaceMap[Index].BaseAddress) &&\r
+ ((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))) {\r
+ *EndIndex = Index;\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+/**\r
+ Sets the attributes for a specified range in Gcd Memory Space Map.\r
+\r
+ This function sets the attributes for a specified range in\r
+ Gcd Memory Space Map.\r
+\r
+ @param MemorySpaceMap Gcd Memory Space Map as array\r
+ @param NumberOfDescriptors Number of descriptors in map\r
+ @param BaseAddress BaseAddress for the range\r
+ @param Length Length for the range\r
+ @param Attributes Attributes to set\r
+\r
+ @retval EFI_SUCCESS Memory attributes set successfully\r
+ @retval EFI_NOT_FOUND The specified range does not exist in Gcd Memory Space\r
+\r
+**/\r
+EFI_STATUS\r
+SetGcdMemorySpaceAttributes (\r
+ IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,\r
+ IN UINTN NumberOfDescriptors,\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length,\r
+ IN UINT64 Attributes\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ UINTN StartIndex;\r
+ UINTN EndIndex;\r
+ EFI_PHYSICAL_ADDRESS RegionStart;\r
+ UINT64 RegionLength;\r
+\r
+ DEBUG ((DEBUG_GCD, "SetGcdMemorySpaceAttributes[0x%lX; 0x%lX] = 0x%lX\n",\r
+ BaseAddress, BaseAddress + Length, Attributes));\r
+\r
+ //\r
+ // Get all memory descriptors covered by the memory range\r
+ //\r
+ Status = SearchGcdMemorySpaces (\r
+ MemorySpaceMap,\r
+ NumberOfDescriptors,\r
+ BaseAddress,\r
+ Length,\r
+ &StartIndex,\r
+ &EndIndex\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Go through all related descriptors and set attributes accordingly\r
+ //\r
+ for (Index = StartIndex; Index <= EndIndex; Index++) {\r
+ if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {\r
+ continue;\r
+ }\r
+ //\r
+ // Calculate the start and end address of the overlapping range\r
+ //\r
+ if (BaseAddress >= MemorySpaceMap[Index].BaseAddress) {\r
+ RegionStart = BaseAddress;\r
+ } else {\r
+ RegionStart = MemorySpaceMap[Index].BaseAddress;\r
+ }\r
+ if ((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length)) {\r
+ RegionLength = BaseAddress + Length - RegionStart;\r
+ } else {\r
+ RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;\r
+ }\r
+ //\r
+ // Set memory attributes according to MTRR attribute and the original attribute of descriptor\r
+ //\r
+ gDS->SetMemorySpaceAttributes (\r
+ RegionStart,\r
+ RegionLength,\r
+ (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes)\r
+ );\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function modifies the attributes for the memory region specified by BaseAddress and\r
+ Length from their current attributes to the attributes specified by Attributes.\r
+\r
+ @param This The EFI_CPU_ARCH_PROTOCOL instance.\r
+ @param BaseAddress The physical address that is the start address of a memory region.\r
+ @param Length The size in bytes of the memory region.\r
+ @param Attributes The bit mask of attributes to set for the memory region.\r
+\r
+ @retval EFI_SUCCESS The attributes were set for the memory region.\r
+ @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by\r
+ BaseAddress and Length cannot be modified.\r
+ @retval EFI_INVALID_PARAMETER Length is zero.\r
+ @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of\r
+ the memory resource range.\r
+ @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory\r
+ resource range specified by BaseAddress and Length.\r
+ The bit mask of attributes is not support for the memory resource\r
+ range specified by BaseAddress and Length.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CpuSetMemoryAttributes (\r
+ IN EFI_CPU_ARCH_PROTOCOL *This,\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length,\r
+ IN UINT64 Attributes\r
+ )\r
+{\r
+ DEBUG ((EFI_D_PAGE, "CpuSetMemoryAttributes(%lx, %lx, %lx)\n", BaseAddress, Length, Attributes));\r
+\r
+ if ((BaseAddress & (SIZE_4KB - 1)) != 0) {\r
+ // Minimum granularity is SIZE_4KB (4KB on ARM)\r
+ DEBUG ((EFI_D_PAGE, "CpuSetMemoryAttributes(%lx, %lx, %lx): Minimum ganularity is SIZE_4KB\n", BaseAddress, Length, Attributes));\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ return SetMemoryAttributes (BaseAddress, Length, Attributes, 0);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CpuConvertPagesToUncachedVirtualAddress (\r
+ IN VIRTUAL_UNCACHED_PAGES_PROTOCOL *This,\r
+ IN EFI_PHYSICAL_ADDRESS Address,\r
+ IN UINTN Length,\r
+ IN EFI_PHYSICAL_ADDRESS VirtualMask,\r
+ OUT UINT64 *Attributes OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;\r
+\r
+ if (Attributes != NULL) {\r
+ Status = gDS->GetMemorySpaceDescriptor (Address, &GcdDescriptor);\r
+ if (!EFI_ERROR (Status)) {\r
+ *Attributes = GcdDescriptor.Attributes;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Make this address range page fault if accessed. If it is a DMA buffer than this would\r
+ // be the PCI address. Code should always use the CPU address, and we will or in VirtualMask\r
+ // to that address.\r
+ //\r
+ Status = SetMemoryAttributes (Address, Length, EFI_MEMORY_WP, 0);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_UC, VirtualMask);\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO | DEBUG_LOAD, "CpuConvertPagesToUncachedVirtualAddress()\n Unmapped 0x%08lx Mapped 0x%08lx 0x%x bytes\n", Address, Address | VirtualMask, Length));\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CpuReconvertPages (\r
+ IN VIRTUAL_UNCACHED_PAGES_PROTOCOL *This,\r
+ IN EFI_PHYSICAL_ADDRESS Address,\r
+ IN UINTN Length,\r
+ IN EFI_PHYSICAL_ADDRESS VirtualMask,\r
+ IN UINT64 Attributes\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ DEBUG ((DEBUG_INFO | DEBUG_LOAD, "CpuReconvertPages(%lx, %x, %lx, %lx)\n", Address, Length, VirtualMask, Attributes));\r
+\r
+ //\r
+ // Unmap the aliased Address\r
+ //\r
+ Status = SetMemoryAttributes (Address | VirtualMask, Length, EFI_MEMORY_WP, 0);\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Restore atttributes\r
+ //\r
+ Status = SetMemoryAttributes (Address, Length, Attributes, 0);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+VIRTUAL_UNCACHED_PAGES_PROTOCOL gVirtualUncachedPages = {\r
+ CpuConvertPagesToUncachedVirtualAddress,\r
+ CpuReconvertPages\r
+};\r