3 * Copyright (c) 2013, ARM Limited. All rights reserved.
4 * Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
6 * SPDX-License-Identifier: BSD-2-Clause-Patent
13 Searches memory descriptors covered by given memory range.
15 This function searches into the Gcd Memory Space for descriptors
16 (from StartIndex to EndIndex) that contains the memory range
17 specified by BaseAddress and Length.
19 @param MemorySpaceMap Gcd Memory Space Map as array.
20 @param NumberOfDescriptors Number of descriptors in map.
21 @param BaseAddress BaseAddress for the requested range.
22 @param Length Length for the requested range.
23 @param StartIndex Start index into the Gcd Memory Space Map.
24 @param EndIndex End index into the Gcd Memory Space Map.
26 @retval EFI_SUCCESS Search successfully.
27 @retval EFI_NOT_FOUND The requested descriptors does not exist.
31 SearchGcdMemorySpaces (
32 IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR
*MemorySpaceMap
,
33 IN UINTN NumberOfDescriptors
,
34 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
36 OUT UINTN
*StartIndex
,
44 for (Index
= 0; Index
< NumberOfDescriptors
; Index
++) {
45 if ((BaseAddress
>= MemorySpaceMap
[Index
].BaseAddress
) &&
46 (BaseAddress
< (MemorySpaceMap
[Index
].BaseAddress
+ MemorySpaceMap
[Index
].Length
)))
51 if (((BaseAddress
+ Length
- 1) >= MemorySpaceMap
[Index
].BaseAddress
) &&
52 ((BaseAddress
+ Length
- 1) < (MemorySpaceMap
[Index
].BaseAddress
+ MemorySpaceMap
[Index
].Length
)))
63 Sets the attributes for a specified range in Gcd Memory Space Map.
65 This function sets the attributes for a specified range in
68 @param MemorySpaceMap Gcd Memory Space Map as array
69 @param NumberOfDescriptors Number of descriptors in map
70 @param BaseAddress BaseAddress for the range
71 @param Length Length for the range
72 @param Attributes Attributes to set
74 @retval EFI_SUCCESS Memory attributes set successfully
75 @retval EFI_NOT_FOUND The specified range does not exist in Gcd Memory Space
79 SetGcdMemorySpaceAttributes (
80 IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR
*MemorySpaceMap
,
81 IN UINTN NumberOfDescriptors
,
82 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
91 EFI_PHYSICAL_ADDRESS RegionStart
;
96 "SetGcdMemorySpaceAttributes[0x%lX; 0x%lX] = 0x%lX\n",
102 // We do not support a smaller granularity than 4KB on ARM Architecture
103 if ((Length
& EFI_PAGE_MASK
) != 0) {
106 "Warning: We do not support smaller granularity than 4KB on ARM Architecture (passed length: 0x%lX).\n",
112 // Get all memory descriptors covered by the memory range
114 Status
= SearchGcdMemorySpaces (
122 if (EFI_ERROR (Status
)) {
127 // Go through all related descriptors and set attributes accordingly
129 for (Index
= StartIndex
; Index
<= EndIndex
; Index
++) {
130 if (MemorySpaceMap
[Index
].GcdMemoryType
== EfiGcdMemoryTypeNonExistent
) {
135 // Calculate the start and end address of the overlapping range
137 if (BaseAddress
>= MemorySpaceMap
[Index
].BaseAddress
) {
138 RegionStart
= BaseAddress
;
140 RegionStart
= MemorySpaceMap
[Index
].BaseAddress
;
143 if ((BaseAddress
+ Length
- 1) < (MemorySpaceMap
[Index
].BaseAddress
+ MemorySpaceMap
[Index
].Length
)) {
144 RegionLength
= BaseAddress
+ Length
- RegionStart
;
146 RegionLength
= MemorySpaceMap
[Index
].BaseAddress
+ MemorySpaceMap
[Index
].Length
- RegionStart
;
150 // Set memory attributes according to MTRR attribute and the original attribute of descriptor
152 gDS
->SetMemorySpaceAttributes (
155 (MemorySpaceMap
[Index
].Attributes
& ~EFI_MEMORY_CACHETYPE_MASK
) | (MemorySpaceMap
[Index
].Capabilities
& Attributes
)
163 This function modifies the attributes for the memory region specified by BaseAddress and
164 Length from their current attributes to the attributes specified by Attributes.
166 @param This The EFI_CPU_ARCH_PROTOCOL instance.
167 @param BaseAddress The physical address that is the start address of a memory region.
168 @param Length The size in bytes of the memory region.
169 @param Attributes The bit mask of attributes to set for the memory region.
171 @retval EFI_SUCCESS The attributes were set for the memory region.
172 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
173 BaseAddress and Length cannot be modified.
174 @retval EFI_INVALID_PARAMETER Length is zero.
175 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
176 the memory resource range.
177 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
178 resource range specified by BaseAddress and Length.
179 The bit mask of attributes is not support for the memory resource
180 range specified by BaseAddress and Length.
185 CpuSetMemoryAttributes (
186 IN EFI_CPU_ARCH_PROTOCOL
*This
,
187 IN EFI_PHYSICAL_ADDRESS BaseAddress
,
189 IN UINT64 EfiAttributes
194 UINTN RegionBaseAddress
;
196 UINTN RegionArmAttributes
;
198 if (mIsFlushingGCD
) {
202 if ((BaseAddress
& (SIZE_4KB
- 1)) != 0) {
203 // Minimum granularity is SIZE_4KB (4KB on ARM)
204 DEBUG ((DEBUG_PAGE
, "CpuSetMemoryAttributes(%lx, %lx, %lx): Minimum granularity is SIZE_4KB\n", BaseAddress
, Length
, EfiAttributes
));
205 return EFI_UNSUPPORTED
;
208 // Convert the 'Attribute' into ARM Attribute
209 ArmAttributes
= EfiAttributeToArmAttribute (EfiAttributes
);
211 // Get the region starting from 'BaseAddress' and its 'Attribute'
212 RegionBaseAddress
= BaseAddress
;
213 Status
= GetMemoryRegion (&RegionBaseAddress
, &RegionLength
, &RegionArmAttributes
);
215 // Data & Instruction Caches are flushed when we set new memory attributes.
216 // So, we only set the attributes if the new region is different.
217 if (EFI_ERROR (Status
) || (RegionArmAttributes
!= ArmAttributes
) ||
218 ((BaseAddress
+ Length
) > (RegionBaseAddress
+ RegionLength
)))
220 return ArmSetMemoryAttributes (BaseAddress
, Length
, EfiAttributes
);