]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c
ArmPkg: Apply uncrustify changes
[mirror_edk2.git] / ArmPkg / Library / ArmMmuLib / Arm / ArmMmuLibUpdate.c
CommitLineData
eaaaece4
AB
1/** @file\r
2* File managing the MMU for ARMv7 architecture\r
3*\r
a9e51860 4* Copyright (c) 2011-2021, Arm Limited. All rights reserved.<BR>\r
eaaaece4
AB
5*\r
6* SPDX-License-Identifier: BSD-2-Clause-Patent\r
7*\r
8**/\r
9\r
10#include <Uefi.h>\r
11\r
12#include <Library/ArmLib.h>\r
13#include <Library/BaseLib.h>\r
14#include <Library/BaseMemoryLib.h>\r
15#include <Library/DebugLib.h>\r
16#include <Library/CacheMaintenanceLib.h>\r
17#include <Library/MemoryAllocationLib.h>\r
18\r
19#include <Chipset/ArmV7.h>\r
20\r
429309e0 21#define __EFI_MEMORY_RWX 0 // no restrictions\r
eaaaece4 22\r
429309e0 23#define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | \\r
eaaaece4
AB
24 EFI_MEMORY_WC | \\r
25 EFI_MEMORY_WT | \\r
26 EFI_MEMORY_WB | \\r
27 EFI_MEMORY_UCE | \\r
28 EFI_MEMORY_WP)\r
29\r
30STATIC\r
31EFI_STATUS\r
32ConvertSectionToPages (\r
33 IN EFI_PHYSICAL_ADDRESS BaseAddress\r
34 )\r
35{\r
429309e0
MK
36 UINT32 FirstLevelIdx;\r
37 UINT32 SectionDescriptor;\r
38 UINT32 PageTableDescriptor;\r
39 UINT32 PageDescriptor;\r
40 UINT32 Index;\r
eaaaece4 41\r
429309e0
MK
42 volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;\r
43 volatile ARM_PAGE_TABLE_ENTRY *PageTable;\r
eaaaece4
AB
44\r
45 DEBUG ((DEBUG_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress));\r
46\r
47 // Obtain page table base\r
48 FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();\r
49\r
50 // Calculate index into first level translation table for start of modification\r
429309e0 51 FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;\r
eaaaece4
AB
52 ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);\r
53\r
54 // Get section attributes and convert to page attributes\r
55 SectionDescriptor = FirstLevelTable[FirstLevelIdx];\r
429309e0 56 PageDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (SectionDescriptor, FALSE);\r
eaaaece4
AB
57\r
58 // Allocate a page table for the 4KB entries (we use up a full page even though we only need 1KB)\r
59 PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)AllocatePages (1);\r
60 if (PageTable == NULL) {\r
61 return EFI_OUT_OF_RESOURCES;\r
62 }\r
63\r
64 // Write the page table entries out\r
65 for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {\r
429309e0 66 PageTable[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS (BaseAddress + (Index << 12)) | PageDescriptor;\r
eaaaece4
AB
67 }\r
68\r
69 // Formulate page table entry, Domain=0, NS=0\r
70 PageTableDescriptor = (((UINTN)PageTable) & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;\r
71\r
72 // Write the page table entry out, replacing section entry\r
73 FirstLevelTable[FirstLevelIdx] = PageTableDescriptor;\r
74\r
75 return EFI_SUCCESS;\r
76}\r
77\r
78STATIC\r
79EFI_STATUS\r
80UpdatePageEntries (\r
429309e0
MK
81 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
82 IN UINT64 Length,\r
83 IN UINT64 Attributes,\r
84 OUT BOOLEAN *FlushTlbs OPTIONAL\r
eaaaece4
AB
85 )\r
86{\r
429309e0
MK
87 EFI_STATUS Status;\r
88 UINT32 EntryValue;\r
89 UINT32 EntryMask;\r
90 UINT32 FirstLevelIdx;\r
91 UINT32 Offset;\r
92 UINT32 NumPageEntries;\r
93 UINT32 Descriptor;\r
94 UINT32 p;\r
95 UINT32 PageTableIndex;\r
96 UINT32 PageTableEntry;\r
97 UINT32 CurrentPageTableEntry;\r
98 VOID *Mva;\r
99\r
100 volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;\r
101 volatile ARM_PAGE_TABLE_ENTRY *PageTable;\r
eaaaece4
AB
102\r
103 Status = EFI_SUCCESS;\r
104\r
105 // EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)\r
106 // EntryValue: values at bit positions specified by EntryMask\r
107 EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK | TT_DESCRIPTOR_PAGE_AP_MASK;\r
a9e51860 108 if ((Attributes & EFI_MEMORY_XP) != 0) {\r
eaaaece4
AB
109 EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN;\r
110 } else {\r
111 EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE;\r
112 }\r
113\r
114 // Although the PI spec is unclear on this, the GCD guarantees that only\r
115 // one Attribute bit is set at a time, so the order of the conditionals below\r
116 // is irrelevant. If no memory attribute is specified, we preserve whatever\r
117 // memory type is set in the page tables, and update the permission attributes\r
118 // only.\r
a9e51860 119 if ((Attributes & EFI_MEMORY_UC) != 0) {\r
eaaaece4
AB
120 // modify cacheability attributes\r
121 EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\r
122 // map to strongly ordered\r
123 EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0\r
a9e51860 124 } else if ((Attributes & EFI_MEMORY_WC) != 0) {\r
eaaaece4
AB
125 // modify cacheability attributes\r
126 EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\r
b8de64be 127 // map to normal non-cacheable\r
eaaaece4 128 EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0\r
a9e51860 129 } else if ((Attributes & EFI_MEMORY_WT) != 0) {\r
eaaaece4
AB
130 // modify cacheability attributes\r
131 EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\r
132 // write through with no-allocate\r
133 EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0\r
a9e51860 134 } else if ((Attributes & EFI_MEMORY_WB) != 0) {\r
eaaaece4
AB
135 // modify cacheability attributes\r
136 EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;\r
137 // write back (with allocate)\r
138 EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1\r
a9e51860 139 } else if ((Attributes & CACHE_ATTRIBUTE_MASK) != 0) {\r
eaaaece4
AB
140 // catch unsupported memory type attributes\r
141 ASSERT (FALSE);\r
142 return EFI_UNSUPPORTED;\r
143 }\r
144\r
a9e51860 145 if ((Attributes & EFI_MEMORY_RO) != 0) {\r
eaaaece4
AB
146 EntryValue |= TT_DESCRIPTOR_PAGE_AP_RO_RO;\r
147 } else {\r
148 EntryValue |= TT_DESCRIPTOR_PAGE_AP_RW_RW;\r
149 }\r
150\r
151 // Obtain page table base\r
152 FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();\r
153\r
154 // Calculate number of 4KB page table entries to change\r
2bdc9042 155 NumPageEntries = (UINT32)(Length / TT_DESCRIPTOR_PAGE_SIZE);\r
eaaaece4
AB
156\r
157 // Iterate for the number of 4KB pages to change\r
158 Offset = 0;\r
429309e0 159 for (p = 0; p < NumPageEntries; p++) {\r
eaaaece4
AB
160 // Calculate index into first level translation table for page table value\r
161\r
429309e0 162 FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (BaseAddress + Offset) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;\r
eaaaece4
AB
163 ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);\r
164\r
165 // Read the descriptor from the first level page table\r
166 Descriptor = FirstLevelTable[FirstLevelIdx];\r
167\r
168 // Does this descriptor need to be converted from section entry to 4K pages?\r
429309e0 169 if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (Descriptor)) {\r
eaaaece4 170 Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT);\r
429309e0 171 if (EFI_ERROR (Status)) {\r
eaaaece4
AB
172 // Exit for loop\r
173 break;\r
174 }\r
175\r
176 // Re-read descriptor\r
177 Descriptor = FirstLevelTable[FirstLevelIdx];\r
178 if (FlushTlbs != NULL) {\r
179 *FlushTlbs = TRUE;\r
180 }\r
181 }\r
182\r
183 // Obtain page table base address\r
429309e0 184 PageTable = (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS (Descriptor);\r
eaaaece4
AB
185\r
186 // Calculate index into the page table\r
187 PageTableIndex = ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;\r
188 ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);\r
189\r
190 // Get the entry\r
191 CurrentPageTableEntry = PageTable[PageTableIndex];\r
192\r
193 // Mask off appropriate fields\r
194 PageTableEntry = CurrentPageTableEntry & ~EntryMask;\r
195\r
196 // Mask in new attributes and/or permissions\r
197 PageTableEntry |= EntryValue;\r
198\r
199 if (CurrentPageTableEntry != PageTableEntry) {\r
200 Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SECTION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT));\r
201\r
202 // Only need to update if we are changing the entry\r
203 PageTable[PageTableIndex] = PageTableEntry;\r
204 ArmUpdateTranslationTableEntry ((VOID *)&PageTable[PageTableIndex], Mva);\r
205 }\r
206\r
429309e0 207 Status = EFI_SUCCESS;\r
eaaaece4 208 Offset += TT_DESCRIPTOR_PAGE_SIZE;\r
eaaaece4
AB
209 } // End first level translation table loop\r
210\r
211 return Status;\r
212}\r
213\r
214STATIC\r
215EFI_STATUS\r
216UpdateSectionEntries (\r
429309e0
MK
217 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
218 IN UINT64 Length,\r
219 IN UINT64 Attributes\r
eaaaece4
AB
220 )\r
221{\r
429309e0
MK
222 EFI_STATUS Status;\r
223 UINT32 EntryMask;\r
224 UINT32 EntryValue;\r
225 UINT32 FirstLevelIdx;\r
226 UINT32 NumSections;\r
227 UINT32 i;\r
228 UINT32 CurrentDescriptor;\r
229 UINT32 Descriptor;\r
230 VOID *Mva;\r
231 volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;\r
eaaaece4 232\r
146af6a4
PG
233 Status = EFI_SUCCESS;\r
234\r
eaaaece4
AB
235 // EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)\r
236 // EntryValue: values at bit positions specified by EntryMask\r
237\r
238 // Make sure we handle a section range that is unmapped\r
239 EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK | TT_DESCRIPTOR_SECTION_XN_MASK |\r
240 TT_DESCRIPTOR_SECTION_AP_MASK;\r
241 EntryValue = TT_DESCRIPTOR_SECTION_TYPE_SECTION;\r
242\r
243 // Although the PI spec is unclear on this, the GCD guarantees that only\r
244 // one Attribute bit is set at a time, so the order of the conditionals below\r
245 // is irrelevant. If no memory attribute is specified, we preserve whatever\r
246 // memory type is set in the page tables, and update the permission attributes\r
247 // only.\r
a9e51860 248 if ((Attributes & EFI_MEMORY_UC) != 0) {\r
eaaaece4
AB
249 // modify cacheability attributes\r
250 EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\r
251 // map to strongly ordered\r
252 EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0\r
a9e51860 253 } else if ((Attributes & EFI_MEMORY_WC) != 0) {\r
eaaaece4
AB
254 // modify cacheability attributes\r
255 EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\r
b8de64be 256 // map to normal non-cacheable\r
eaaaece4 257 EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0\r
a9e51860 258 } else if ((Attributes & EFI_MEMORY_WT) != 0) {\r
eaaaece4
AB
259 // modify cacheability attributes\r
260 EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\r
261 // write through with no-allocate\r
262 EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0\r
a9e51860 263 } else if ((Attributes & EFI_MEMORY_WB) != 0) {\r
eaaaece4
AB
264 // modify cacheability attributes\r
265 EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;\r
266 // write back (with allocate)\r
267 EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1\r
a9e51860 268 } else if ((Attributes & CACHE_ATTRIBUTE_MASK) != 0) {\r
eaaaece4
AB
269 // catch unsupported memory type attributes\r
270 ASSERT (FALSE);\r
271 return EFI_UNSUPPORTED;\r
272 }\r
273\r
a9e51860 274 if ((Attributes & EFI_MEMORY_RO) != 0) {\r
eaaaece4
AB
275 EntryValue |= TT_DESCRIPTOR_SECTION_AP_RO_RO;\r
276 } else {\r
277 EntryValue |= TT_DESCRIPTOR_SECTION_AP_RW_RW;\r
278 }\r
279\r
a9e51860 280 if ((Attributes & EFI_MEMORY_XP) != 0) {\r
eaaaece4
AB
281 EntryValue |= TT_DESCRIPTOR_SECTION_XN_MASK;\r
282 }\r
283\r
284 // obtain page table base\r
285 FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();\r
286\r
287 // calculate index into first level translation table for start of modification\r
429309e0 288 FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;\r
eaaaece4
AB
289 ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);\r
290\r
291 // calculate number of 1MB first level entries this applies to\r
2bdc9042 292 NumSections = (UINT32)(Length / TT_DESCRIPTOR_SECTION_SIZE);\r
eaaaece4
AB
293\r
294 // iterate through each descriptor\r
429309e0 295 for (i = 0; i < NumSections; i++) {\r
eaaaece4
AB
296 CurrentDescriptor = FirstLevelTable[FirstLevelIdx + i];\r
297\r
298 // has this descriptor already been converted to pages?\r
429309e0 299 if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE (CurrentDescriptor)) {\r
eaaaece4
AB
300 // forward this 1MB range to page table function instead\r
301 Status = UpdatePageEntries (\r
302 (FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT,\r
303 TT_DESCRIPTOR_SECTION_SIZE,\r
304 Attributes,\r
429309e0
MK
305 NULL\r
306 );\r
eaaaece4
AB
307 } else {\r
308 // still a section entry\r
309\r
310 if (CurrentDescriptor != 0) {\r
311 // mask off appropriate fields\r
312 Descriptor = CurrentDescriptor & ~EntryMask;\r
313 } else {\r
314 Descriptor = ((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT;\r
315 }\r
316\r
317 // mask in new attributes and/or permissions\r
318 Descriptor |= EntryValue;\r
319\r
320 if (CurrentDescriptor != Descriptor) {\r
321 Mva = (VOID *)(UINTN)(((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT);\r
322\r
323 // Only need to update if we are changing the descriptor\r
324 FirstLevelTable[FirstLevelIdx + i] = Descriptor;\r
325 ArmUpdateTranslationTableEntry ((VOID *)&FirstLevelTable[FirstLevelIdx + i], Mva);\r
326 }\r
327\r
328 Status = EFI_SUCCESS;\r
329 }\r
330 }\r
331\r
332 return Status;\r
333}\r
334\r
335EFI_STATUS\r
336ArmSetMemoryAttributes (\r
429309e0
MK
337 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
338 IN UINT64 Length,\r
339 IN UINT64 Attributes\r
eaaaece4
AB
340 )\r
341{\r
429309e0
MK
342 EFI_STATUS Status;\r
343 UINT64 ChunkLength;\r
344 BOOLEAN FlushTlbs;\r
eaaaece4
AB
345\r
346 if (BaseAddress > (UINT64)MAX_ADDRESS) {\r
347 return EFI_UNSUPPORTED;\r
348 }\r
349\r
350 Length = MIN (Length, (UINT64)MAX_ADDRESS - BaseAddress + 1);\r
351 if (Length == 0) {\r
352 return EFI_SUCCESS;\r
353 }\r
354\r
355 FlushTlbs = FALSE;\r
356 while (Length > 0) {\r
357 if ((BaseAddress % TT_DESCRIPTOR_SECTION_SIZE == 0) &&\r
429309e0
MK
358 (Length >= TT_DESCRIPTOR_SECTION_SIZE))\r
359 {\r
eaaaece4
AB
360 ChunkLength = Length - Length % TT_DESCRIPTOR_SECTION_SIZE;\r
361\r
429309e0
MK
362 DEBUG ((\r
363 DEBUG_PAGE,\r
eaaaece4 364 "SetMemoryAttributes(): MMU section 0x%lx length 0x%lx to %lx\n",\r
429309e0
MK
365 BaseAddress,\r
366 ChunkLength,\r
367 Attributes\r
368 ));\r
eaaaece4
AB
369\r
370 Status = UpdateSectionEntries (BaseAddress, ChunkLength, Attributes);\r
371\r
372 FlushTlbs = TRUE;\r
373 } else {\r
eaaaece4
AB
374 //\r
375 // Process page by page until the next section boundary, but only if\r
376 // we have more than a section's worth of area to deal with after that.\r
377 //\r
378 ChunkLength = TT_DESCRIPTOR_SECTION_SIZE -\r
379 (BaseAddress % TT_DESCRIPTOR_SECTION_SIZE);\r
380 if (ChunkLength + TT_DESCRIPTOR_SECTION_SIZE > Length) {\r
381 ChunkLength = Length;\r
382 }\r
383\r
429309e0
MK
384 DEBUG ((\r
385 DEBUG_PAGE,\r
eaaaece4 386 "SetMemoryAttributes(): MMU page 0x%lx length 0x%lx to %lx\n",\r
429309e0
MK
387 BaseAddress,\r
388 ChunkLength,\r
389 Attributes\r
390 ));\r
eaaaece4 391\r
429309e0
MK
392 Status = UpdatePageEntries (\r
393 BaseAddress,\r
394 ChunkLength,\r
395 Attributes,\r
396 &FlushTlbs\r
397 );\r
eaaaece4
AB
398 }\r
399\r
400 if (EFI_ERROR (Status)) {\r
401 break;\r
402 }\r
403\r
404 BaseAddress += ChunkLength;\r
429309e0 405 Length -= ChunkLength;\r
eaaaece4
AB
406 }\r
407\r
408 if (FlushTlbs) {\r
409 ArmInvalidateTlb ();\r
410 }\r
429309e0 411\r
eaaaece4
AB
412 return Status;\r
413}\r
414\r
415EFI_STATUS\r
416ArmSetMemoryRegionNoExec (\r
429309e0
MK
417 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
418 IN UINT64 Length\r
eaaaece4
AB
419 )\r
420{\r
421 return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_XP);\r
422}\r
423\r
424EFI_STATUS\r
425ArmClearMemoryRegionNoExec (\r
429309e0
MK
426 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
427 IN UINT64 Length\r
eaaaece4
AB
428 )\r
429{\r
430 return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX);\r
431}\r
432\r
433EFI_STATUS\r
434ArmSetMemoryRegionReadOnly (\r
429309e0
MK
435 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
436 IN UINT64 Length\r
eaaaece4
AB
437 )\r
438{\r
439 return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_RO);\r
440}\r
441\r
442EFI_STATUS\r
443ArmClearMemoryRegionReadOnly (\r
429309e0
MK
444 IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
445 IN UINT64 Length\r
eaaaece4
AB
446 )\r
447{\r
448 return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX);\r
449}\r