]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ArmPkg / Drivers / CpuDxe / CpuMmuCommon.c
CommitLineData
591fb378
OM
1/** @file\r
2*\r
3* Copyright (c) 2013, ARM Limited. All rights reserved.\r
b7a09b71 4* Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
591fb378 5*\r
4059386c 6* SPDX-License-Identifier: BSD-2-Clause-Patent\r
591fb378
OM
7*\r
8**/\r
9\r
10#include "CpuDxe.h"\r
11\r
12/**\r
13 Searches memory descriptors covered by given memory range.\r
14\r
15 This function searches into the Gcd Memory Space for descriptors\r
16 (from StartIndex to EndIndex) that contains the memory range\r
17 specified by BaseAddress and Length.\r
18\r
19 @param MemorySpaceMap Gcd Memory Space Map as array.\r
20 @param NumberOfDescriptors Number of descriptors in map.\r
21 @param BaseAddress BaseAddress for the requested range.\r
22 @param Length Length for the requested range.\r
23 @param StartIndex Start index into the Gcd Memory Space Map.\r
24 @param EndIndex End index into the Gcd Memory Space Map.\r
25\r
26 @retval EFI_SUCCESS Search successfully.\r
27 @retval EFI_NOT_FOUND The requested descriptors does not exist.\r
28\r
29**/\r
30EFI_STATUS\r
31SearchGcdMemorySpaces (\r
429309e0
MK
32 IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,\r
33 IN UINTN NumberOfDescriptors,\r
34 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
35 IN UINT64 Length,\r
36 OUT UINTN *StartIndex,\r
37 OUT UINTN *EndIndex\r
591fb378
OM
38 )\r
39{\r
429309e0 40 UINTN Index;\r
591fb378
OM
41\r
42 *StartIndex = 0;\r
43 *EndIndex = 0;\r
44 for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
45 if ((BaseAddress >= MemorySpaceMap[Index].BaseAddress) &&\r
429309e0
MK
46 (BaseAddress < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length)))\r
47 {\r
591fb378
OM
48 *StartIndex = Index;\r
49 }\r
429309e0 50\r
591fb378 51 if (((BaseAddress + Length - 1) >= MemorySpaceMap[Index].BaseAddress) &&\r
429309e0
MK
52 ((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length)))\r
53 {\r
591fb378
OM
54 *EndIndex = Index;\r
55 return EFI_SUCCESS;\r
56 }\r
57 }\r
429309e0 58\r
591fb378
OM
59 return EFI_NOT_FOUND;\r
60}\r
61\r
591fb378
OM
62/**\r
63 Sets the attributes for a specified range in Gcd Memory Space Map.\r
64\r
65 This function sets the attributes for a specified range in\r
66 Gcd Memory Space Map.\r
67\r
68 @param MemorySpaceMap Gcd Memory Space Map as array\r
69 @param NumberOfDescriptors Number of descriptors in map\r
70 @param BaseAddress BaseAddress for the range\r
71 @param Length Length for the range\r
72 @param Attributes Attributes to set\r
73\r
74 @retval EFI_SUCCESS Memory attributes set successfully\r
75 @retval EFI_NOT_FOUND The specified range does not exist in Gcd Memory Space\r
76\r
77**/\r
78EFI_STATUS\r
79SetGcdMemorySpaceAttributes (\r
429309e0
MK
80 IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,\r
81 IN UINTN NumberOfDescriptors,\r
82 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
83 IN UINT64 Length,\r
84 IN UINT64 Attributes\r
591fb378
OM
85 )\r
86{\r
87 EFI_STATUS Status;\r
88 UINTN Index;\r
89 UINTN StartIndex;\r
90 UINTN EndIndex;\r
91 EFI_PHYSICAL_ADDRESS RegionStart;\r
92 UINT64 RegionLength;\r
93\r
429309e0
MK
94 DEBUG ((\r
95 DEBUG_GCD,\r
96 "SetGcdMemorySpaceAttributes[0x%lX; 0x%lX] = 0x%lX\n",\r
97 BaseAddress,\r
98 BaseAddress + Length,\r
99 Attributes\r
100 ));\r
591fb378 101\r
047c0cbb
OM
102 // We do not support a smaller granularity than 4KB on ARM Architecture\r
103 if ((Length & EFI_PAGE_MASK) != 0) {\r
429309e0
MK
104 DEBUG ((\r
105 DEBUG_WARN,\r
106 "Warning: We do not support smaller granularity than 4KB on ARM Architecture (passed length: 0x%lX).\n",\r
107 Length\r
108 ));\r
047c0cbb
OM
109 }\r
110\r
591fb378
OM
111 //\r
112 // Get all memory descriptors covered by the memory range\r
113 //\r
114 Status = SearchGcdMemorySpaces (\r
115 MemorySpaceMap,\r
116 NumberOfDescriptors,\r
117 BaseAddress,\r
118 Length,\r
119 &StartIndex,\r
120 &EndIndex\r
121 );\r
122 if (EFI_ERROR (Status)) {\r
123 return Status;\r
124 }\r
125\r
126 //\r
127 // Go through all related descriptors and set attributes accordingly\r
128 //\r
129 for (Index = StartIndex; Index <= EndIndex; Index++) {\r
130 if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {\r
131 continue;\r
132 }\r
429309e0 133\r
591fb378
OM
134 //\r
135 // Calculate the start and end address of the overlapping range\r
136 //\r
137 if (BaseAddress >= MemorySpaceMap[Index].BaseAddress) {\r
138 RegionStart = BaseAddress;\r
139 } else {\r
140 RegionStart = MemorySpaceMap[Index].BaseAddress;\r
141 }\r
429309e0 142\r
591fb378
OM
143 if ((BaseAddress + Length - 1) < (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length)) {\r
144 RegionLength = BaseAddress + Length - RegionStart;\r
145 } else {\r
146 RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;\r
147 }\r
429309e0 148\r
591fb378
OM
149 //\r
150 // Set memory attributes according to MTRR attribute and the original attribute of descriptor\r
151 //\r
152 gDS->SetMemorySpaceAttributes (\r
153 RegionStart,\r
154 RegionLength,\r
155 (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes)\r
156 );\r
157 }\r
158\r
159 return EFI_SUCCESS;\r
160}\r
161\r
162/**\r
163 This function modifies the attributes for the memory region specified by BaseAddress and\r
164 Length from their current attributes to the attributes specified by Attributes.\r
165\r
166 @param This The EFI_CPU_ARCH_PROTOCOL instance.\r
167 @param BaseAddress The physical address that is the start address of a memory region.\r
168 @param Length The size in bytes of the memory region.\r
169 @param Attributes The bit mask of attributes to set for the memory region.\r
170\r
171 @retval EFI_SUCCESS The attributes were set for the memory region.\r
172 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by\r
173 BaseAddress and Length cannot be modified.\r
174 @retval EFI_INVALID_PARAMETER Length is zero.\r
175 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of\r
176 the memory resource range.\r
177 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory\r
178 resource range specified by BaseAddress and Length.\r
179 The bit mask of attributes is not support for the memory resource\r
180 range specified by BaseAddress and Length.\r
181\r
182**/\r
183EFI_STATUS\r
184EFIAPI\r
185CpuSetMemoryAttributes (\r
429309e0
MK
186 IN EFI_CPU_ARCH_PROTOCOL *This,\r
187 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
188 IN UINT64 Length,\r
189 IN UINT64 EfiAttributes\r
591fb378
OM
190 )\r
191{\r
2e969d2e
OM
192 EFI_STATUS Status;\r
193 UINTN ArmAttributes;\r
194 UINTN RegionBaseAddress;\r
195 UINTN RegionLength;\r
196 UINTN RegionArmAttributes;\r
591fb378 197\r
3b44bb55
AB
198 if (mIsFlushingGCD) {\r
199 return EFI_SUCCESS;\r
200 }\r
201\r
591fb378
OM
202 if ((BaseAddress & (SIZE_4KB - 1)) != 0) {\r
203 // Minimum granularity is SIZE_4KB (4KB on ARM)\r
ff5fef14 204 DEBUG ((DEBUG_PAGE, "CpuSetMemoryAttributes(%lx, %lx, %lx): Minimum granularity is SIZE_4KB\n", BaseAddress, Length, EfiAttributes));\r
591fb378
OM
205 return EFI_UNSUPPORTED;\r
206 }\r
207\r
2e969d2e
OM
208 // Convert the 'Attribute' into ARM Attribute\r
209 ArmAttributes = EfiAttributeToArmAttribute (EfiAttributes);\r
210\r
211 // Get the region starting from 'BaseAddress' and its 'Attribute'\r
212 RegionBaseAddress = BaseAddress;\r
429309e0 213 Status = GetMemoryRegion (&RegionBaseAddress, &RegionLength, &RegionArmAttributes);\r
2e969d2e
OM
214\r
215 // Data & Instruction Caches are flushed when we set new memory attributes.\r
216 // So, we only set the attributes if the new region is different.\r
217 if (EFI_ERROR (Status) || (RegionArmAttributes != ArmAttributes) ||\r
218 ((BaseAddress + Length) > (RegionBaseAddress + RegionLength)))\r
219 {\r
d9c0d991 220 return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes);\r
2e969d2e
OM
221 } else {\r
222 return EFI_SUCCESS;\r
223 }\r
591fb378 224}\r