OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
MemoryAttributes.c
Go to the documentation of this file.
1
15#include <Uefi.h>
16
17#include <Guid/MemoryAttributesTable.h>
18#include <Library/BaseMemoryLib.h>
19#include <Library/BaseOverflowLib.h>
20#include <Library/DebugLib.h>
21#include <Library/MemoryAllocationLib.h>
22#include <Library/OcMemoryLib.h>
23#include <Library/UefiBootServicesTableLib.h>
24#include <Library/UefiLib.h>
25
31STATIC
32UINT32
34 IN EFI_MEMORY_DESCRIPTOR *MemoryAttribte
35 )
36{
37 ASSERT (
38 MemoryAttribte->Type == EfiRuntimeServicesCode
39 || MemoryAttribte->Type == EfiRuntimeServicesData
40 );
41
42 //
43 // Use code for write-protected areas.
44 //
45 if ((MemoryAttribte->Attribute & EFI_MEMORY_RO) != 0) {
46 return EfiRuntimeServicesCode;
47 }
48
49 //
50 // Use data for executable-protected areas.
51 //
52 if ((MemoryAttribte->Attribute & EFI_MEMORY_XP) != 0) {
53 return EfiRuntimeServicesData;
54 }
55
56 //
57 // Use whatever is set.
58 //
59 return MemoryAttribte->Type;
60}
61
75STATIC
76EFI_STATUS
78 IN OUT EFI_MEMORY_DESCRIPTOR **RetMemoryMapEntry,
79 IN OUT UINTN *CurrentEntryIndex,
80 IN OUT UINTN *CurrentEntryCount,
81 IN UINTN TotalEntryCount,
82 IN EFI_MEMORY_DESCRIPTOR *MemoryAttribute,
83 IN UINTN DescriptorSize
84
85 )
86{
87 EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
88 EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry;
89 UINTN DiffPages;
90
91 MemoryMapEntry = *RetMemoryMapEntry;
92
93 //
94 // Memory attribute starts after our descriptor.
95 // Shorten the existing descriptor and insert the new one after it.
96 // [DESC1] -> [DESC1][DESC2]
97 //
98 if (MemoryAttribute->PhysicalStart > MemoryMapEntry->PhysicalStart) {
99 if (*CurrentEntryCount == TotalEntryCount) {
100 return EFI_OUT_OF_RESOURCES;
101 }
102
103 NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
104 DiffPages = (UINTN)EFI_SIZE_TO_PAGES (MemoryAttribute->PhysicalStart - MemoryMapEntry->PhysicalStart);
105 CopyMem (
106 NewMemoryMapEntry,
107 MemoryMapEntry,
108 DescriptorSize * (*CurrentEntryCount - *CurrentEntryIndex)
109 );
110 MemoryMapEntry->NumberOfPages = DiffPages;
111 NewMemoryMapEntry->PhysicalStart = MemoryAttribute->PhysicalStart;
112 NewMemoryMapEntry->NumberOfPages -= DiffPages;
113
114 MemoryMapEntry = NewMemoryMapEntry;
115
116 //
117 // Current processed entry is now the one we inserted.
118 //
119 ++(*CurrentEntryIndex);
120 ++(*CurrentEntryCount);
121 }
122
123 ASSERT (MemoryAttribute->PhysicalStart == MemoryMapEntry->PhysicalStart);
124
125 //
126 // Memory attribute matches our descriptor.
127 // Simply update its protection.
128 // [DESC1] -> [DESC1*]
129 //
130 if (MemoryMapEntry->NumberOfPages == MemoryAttribute->NumberOfPages) {
131 MemoryMapEntry->Type = OcRealMemoryType (MemoryAttribute);
132 *RetMemoryMapEntry = MemoryMapEntry;
133 return EFI_SUCCESS;
134 }
135
136 //
137 // Memory attribute is shorter than our descriptor.
138 // Shorten current descriptor, update its type, and inseret the new one after it.
139 // [DESC1] -> [DESC1*][DESC2]
140 //
141 if (*CurrentEntryCount == TotalEntryCount) {
142 return EFI_OUT_OF_RESOURCES;
143 }
144
145 NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
146 CopyMem (
147 NewMemoryMapEntry,
148 MemoryMapEntry,
149 DescriptorSize * (*CurrentEntryCount - *CurrentEntryIndex)
150 );
151 MemoryMapEntry->Type = OcRealMemoryType (MemoryAttribute);
152 MemoryMapEntry->NumberOfPages = MemoryAttribute->NumberOfPages;
153 NewMemoryMapEntry->PhysicalStart += EFI_PAGES_TO_SIZE (MemoryAttribute->NumberOfPages);
154 NewMemoryMapEntry->NumberOfPages -= MemoryAttribute->NumberOfPages;
155
156 //
157 // Current processed entry is now the one we need to process.
158 //
159 ++(*CurrentEntryIndex);
160 ++(*CurrentEntryCount);
161
162 *RetMemoryMapEntry = NewMemoryMapEntry;
163
164 return EFI_SUCCESS;
165}
166
167STATIC
168EFI_STATUS
170 IN OUT EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable,
171 IN OUT EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry OPTIONAL,
172 IN UINTN MaxDescriptors,
173 IN EFI_MEMORY_DESCRIPTOR *MemoryMapEntry,
174 IN EFI_PHYSICAL_ADDRESS CurrentMapAddress
175 )
176{
177 EFI_PHYSICAL_ADDRESS NextMatAddress;
178
179 //
180 // Simply abort on failing to write any new entry.
181 //
182 if (MemoryAttributesTable->NumberOfEntries >= MaxDescriptors) {
183 return EFI_OUT_OF_RESOURCES;
184 }
185
186 if (MemoryAttributesEntry != NULL) {
187 //
188 // Insert to the middle of MAT table at current MAT entry position.
189 // Assert that this MAT entry follows this map entry.
190 //
191 ASSERT (MemoryAttributesEntry->PhysicalStart > CurrentMapAddress);
192
193 //
194 // Create a free MAT entry inbetween.
195 //
196 CopyMem (
197 NEXT_MEMORY_DESCRIPTOR (MemoryAttributesEntry, MemoryAttributesTable->DescriptorSize),
198 MemoryAttributesEntry,
199 MemoryAttributesTable->NumberOfEntries * MemoryAttributesTable->DescriptorSize
200 - ((UINTN)MemoryAttributesEntry - (UINTN)MemoryAttributesTable - sizeof (*MemoryAttributesTable))
201 );
202
203 //
204 // Calculate the location of the next MAT entry to get the size of this one.
205 // This MAT entry will either:
206 // - fill the whole gap right away, by reaching the next MAT entry.
207 // MA: [ GAP ][ MAT ]
208 // MM: [ MAP ]
209 // - fill part of the gap up to MAP entry end.
210 // MA: [ GAP ][ MAT ]
211 // MM: [ MAP ][ OTHER MAP ]
212 //
213 NextMatAddress = LAST_DESCRIPTOR_ADDR (MemoryMapEntry) + 1;
214 if (MemoryAttributesEntry->PhysicalStart < NextMatAddress) {
215 NextMatAddress = MemoryAttributesEntry->PhysicalStart;
216 }
217 } else {
218 //
219 // Append to the end of MAT table.
220 //
221 MemoryAttributesEntry = (VOID *)((UINTN)MemoryAttributesTable + sizeof (*MemoryAttributesTable)
222 + MemoryAttributesTable->NumberOfEntries * MemoryAttributesTable->DescriptorSize);
223 NextMatAddress = LAST_DESCRIPTOR_ADDR (MemoryMapEntry) + 1;
224 }
225
226 //
227 // Write the new attribute.
228 //
229 MemoryAttributesEntry->Type = OcRealMemoryType (MemoryMapEntry);
230 MemoryAttributesEntry->PhysicalStart = CurrentMapAddress;
231 MemoryAttributesEntry->VirtualStart = 0;
232 MemoryAttributesEntry->NumberOfPages = EFI_SIZE_TO_PAGES (NextMatAddress - CurrentMapAddress);
233 MemoryAttributesEntry->Attribute = EFI_MEMORY_RUNTIME;
234 if (MemoryAttributesEntry->Type == EfiRuntimeServicesCode) {
235 MemoryAttributesEntry->Attribute |= EFI_MEMORY_RO;
236 } else {
237 MemoryAttributesEntry->Attribute |= EFI_MEMORY_XP;
238 }
239
240 ++MemoryAttributesTable->NumberOfEntries;
241
242 return EFI_SUCCESS;
243}
244
259STATIC
260EFI_STATUS
262 IN OUT EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable,
263 IN OUT EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry,
264 IN UINTN MaxDescriptors,
265 IN UINTN MemoryMapDescriptors,
266 IN EFI_MEMORY_DESCRIPTOR *MemoryMap,
267 IN UINTN DescriptorSize
268 )
269{
270 EFI_STATUS Status;
271 UINTN MapIndex;
272 UINTN MatIndex;
273 EFI_PHYSICAL_ADDRESS NextMapAddress;
274 EFI_PHYSICAL_ADDRESS LastMatAddress;
275 EFI_PHYSICAL_ADDRESS CurrentMapAddress;
276
277 MatIndex = 0;
278 Status = EFI_NOT_FOUND;
279
280 for (MapIndex = 0; MapIndex < MemoryMapDescriptors; ++MapIndex) {
281 //
282 // Skip MAP entries, which are not RTCode or RTData.
283 //
284 if ( (MemoryMap->Type != EfiRuntimeServicesCode)
285 && (MemoryMap->Type != EfiRuntimeServicesData))
286 {
287 goto NEXT_MEMORY_MAP_DESCRIPTOR;
288 }
289
290 NextMapAddress = LAST_DESCRIPTOR_ADDR (MemoryMap) + 1;
291 CurrentMapAddress = MemoryMap->PhysicalStart;
292
293 //
294 // Iterate MAT entries till we are over them or till
295 // we finish iterating this MAP entry memory.
296 //
297 while ( MatIndex < MemoryAttributesTable->NumberOfEntries
298 && CurrentMapAddress < NextMapAddress)
299 {
300 //
301 // Skip MAT entries, which are not RTCode or RTData.
302 //
303 if ( (MemoryAttributesEntry->Type != EfiRuntimeServicesCode)
304 && (MemoryAttributesEntry->Type != EfiRuntimeServicesData))
305 {
306 goto NEXT_MEMORY_ATTRIBUTE_DESCRIPTOR;
307 }
308
309 //
310 // Skip MAT entries which end before this MAP entry. This should
311 // not happen normally, as each MAT entry is supposed to be within
312 // a single RTCode/RTData MAP entry according to UEFI spec, and
313 // our memory map is sorted.
314 //
315 LastMatAddress = LAST_DESCRIPTOR_ADDR (MemoryAttributesEntry);
316 if (LastMatAddress < MemoryMap->PhysicalStart) {
317 goto NEXT_MEMORY_ATTRIBUTE_DESCRIPTOR;
318 }
319
320 //
321 // Advance MAP iterator if we found a MAT entry that follows the
322 // current MAP entry address.
323 //
324 if (CurrentMapAddress == MemoryAttributesEntry->PhysicalStart) {
325 //
326 // MAT is required to be smaller or equal than MAP by UEFI spec.
327 // For now just assert on this, but if we find anybody violating this,
328 // we will have to adapt this code.
329 //
330 ASSERT (MemoryAttributesEntry->NumberOfPages <= MemoryMap->NumberOfPages);
331 CurrentMapAddress = LastMatAddress + 1;
332 goto NEXT_MEMORY_ATTRIBUTE_DESCRIPTOR;
333 }
334
335 //
336 // At this step we have a hole between the current MAP entry address
337 // and the MAT entry. Fill it in.
338 //
339 Status = OcExpandAttributeWrite (
340 MemoryAttributesTable,
341 MemoryAttributesEntry,
342 MaxDescriptors,
343 MemoryMap,
344 CurrentMapAddress
345 );
346 if (EFI_ERROR (Status)) {
347 return Status;
348 }
349
350 //
351 // Advance MAP iterator with the entry we have just added and continue
352 // processing the next MAT entry.
353 //
354 CurrentMapAddress = LAST_DESCRIPTOR_ADDR (MemoryAttributesEntry) + 1;
355
356NEXT_MEMORY_ATTRIBUTE_DESCRIPTOR:
357 MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR (
358 MemoryAttributesEntry,
359 MemoryAttributesTable->DescriptorSize
360 );
361 ++MatIndex;
362 }
363
364 //
365 // We completed to process this MAP entry, proceed to the next one.
366 //
367 if (CurrentMapAddress == NextMapAddress) {
368 goto NEXT_MEMORY_MAP_DESCRIPTOR;
369 }
370
371 //
372 // We have finished processing all the available MAT entries,
373 // but this MAP entry has more memory, which is not reflected
374 // in the MAT table. Add this memory and continue processing
375 // the next MAP entry.
376 //
377 ASSERT (CurrentMapAddress < NextMapAddress);
378 ASSERT (MatIndex == MemoryAttributesTable->NumberOfEntries);
379 Status = OcExpandAttributeWrite (
380 MemoryAttributesTable,
381 NULL,
382 MaxDescriptors,
383 MemoryMap,
384 CurrentMapAddress
385 );
386 if (EFI_ERROR (Status)) {
387 return Status;
388 }
389
390 //
391 // Increment MatIndex to ensure that we no longer enter the MAT entry
392 // loop on the next iteration. Do not care updating CurrentMapAddress
393 // as we will overwrite it immediate on the next MAP entry iteration.
394 // Do not care updating MemoryAttribute as we will no longer use it.
395 //
396 ++MatIndex;
397
398NEXT_MEMORY_MAP_DESCRIPTOR:
399 MemoryMap = NEXT_MEMORY_DESCRIPTOR (
400 MemoryMap,
401 DescriptorSize
402 );
403 }
404
405 return Status;
406}
407
408EFI_MEMORY_ATTRIBUTES_TABLE *
410 OUT EFI_MEMORY_DESCRIPTOR **MemoryAttributesEntry OPTIONAL
411 )
412{
413 EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
414 UINTN Index;
415
416 for (Index = 0; Index < gST->NumberOfTableEntries; ++Index) {
417 if (CompareGuid (&gST->ConfigurationTable[Index].VendorGuid, &gEfiMemoryAttributesTableGuid)) {
418 MemoryAttributesTable = gST->ConfigurationTable[Index].VendorTable;
419 if (MemoryAttributesEntry != NULL) {
420 *MemoryAttributesEntry = (EFI_MEMORY_DESCRIPTOR *)(MemoryAttributesTable + 1);
421 }
422
423 return MemoryAttributesTable;
424 }
425 }
426
427 return NULL;
428}
429
430EFI_STATUS
432 IN EFI_PHYSICAL_ADDRESS Address,
433 IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL
434 )
435{
436 EFI_STATUS Status;
437 EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
438 EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry;
439 UINTN MaxDescriptors;
440 UINTN MemoryMapSize;
441 EFI_MEMORY_DESCRIPTOR *MemoryMap;
442 UINTN DescriptorSize;
443 UINTN MapKey;
444 UINT32 DescriptorVersion;
445
446 MemoryAttributesTable = OcGetMemoryAttributes (&MemoryAttributesEntry);
447 if ((MemoryAttributesTable == NULL) || (MemoryAttributesTable->NumberOfEntries == 0)) {
448 return EFI_UNSUPPORTED;
449 }
450
451 //
452 // MAT is normally sorted, and so far nobody had issues
453 // caused by unsorted MAT, but we do not want to risk.
454 //
456 MemoryAttributesTable->NumberOfEntries * MemoryAttributesTable->DescriptorSize,
457 MemoryAttributesEntry,
458 MemoryAttributesTable->DescriptorSize
459 );
460
461 //
462 // Some boards create entry duplicates and lose all non-PE entries
463 // after loading runtime drivers after EndOfDxe.
464 // REF: https://github.com/acidanthera/bugtracker/issues/491#issuecomment-609014334
465 //
466 MaxDescriptors = MemoryAttributesTable->NumberOfEntries;
467 Status = OcDeduplicateDescriptors (
468 &MemoryAttributesTable->NumberOfEntries,
469 MemoryAttributesEntry,
470 MemoryAttributesTable->DescriptorSize
471 );
472 if (!EFI_ERROR (Status)) {
473 //
474 // Statically allocate memory for the memory map to avoid allocations.
475 //
476 STATIC UINT8 mMemoryMap[OC_DEFAULT_MEMORY_MAP_SIZE];
477
478 //
479 // Assume effected and add missing entries.
480 //
481 if (GetMemoryMap == NULL) {
482 GetMemoryMap = gBS->GetMemoryMap;
483 }
484
485 MemoryMapSize = sizeof (mMemoryMap);
486 MemoryMap = (EFI_MEMORY_DESCRIPTOR *)mMemoryMap;
487
488 Status = GetMemoryMap (
489 &MemoryMapSize,
490 MemoryMap,
491 &MapKey,
492 &DescriptorSize,
493 &DescriptorVersion
494 );
495
496 if (!EFI_ERROR (Status)) {
498 MemoryMapSize,
499 MemoryMap,
500 DescriptorSize
501 );
502
504 MemoryAttributesTable,
505 MemoryAttributesEntry,
506 MaxDescriptors,
507 MemoryMapSize / DescriptorSize,
508 MemoryMap,
509 DescriptorSize
510 );
511 } else {
512 //
513 // TODO: Scream in fear here? We cannot log, but for a fatal error it is "fine".
514 //
515 }
516 }
517
518 //
519 // Some types of firmware do not update MAT after loading runtime drivers after EndOfDxe.
520 // Since the memory used to allocate runtime driver resides in BINs, MAT has whatever
521 // permissions designated for unused memory. Mark unused memory containing our driver
522 // as executable here.
523 // REF: https://github.com/acidanthera/bugtracker/issues/491#issuecomment-606835337
524 //
525 if (Address != 0) {
526 Status = OcUpdateDescriptors (
527 MemoryAttributesTable->NumberOfEntries * MemoryAttributesTable->DescriptorSize,
528 MemoryAttributesEntry,
529 MemoryAttributesTable->DescriptorSize,
530 Address,
531 EfiRuntimeServicesCode,
532 EFI_MEMORY_RO,
533 EFI_MEMORY_XP
534 );
535 }
536
537 return Status;
538}
539
540UINTN
542 VOID
543 )
544{
545 UINTN Index;
546 UINTN DescriptorCount;
547 CONST EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
548 EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry;
549
550 MemoryAttributesTable = OcGetMemoryAttributes (&MemoryAttributesEntry);
551 if (MemoryAttributesTable == NULL) {
552 return 0;
553 }
554
555 DescriptorCount = 0;
556 for (Index = 0; Index < MemoryAttributesTable->NumberOfEntries; ++Index) {
557 if ( (MemoryAttributesEntry->Type == EfiRuntimeServicesCode)
558 || (MemoryAttributesEntry->Type == EfiRuntimeServicesData))
559 {
560 ++DescriptorCount;
561 }
562
563 MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR (
564 MemoryAttributesEntry,
565 MemoryAttributesTable->DescriptorSize
566 );
567 }
568
569 return DescriptorCount;
570}
571
572EFI_STATUS
574 IN UINTN MaxMemoryMapSize,
575 IN OUT UINTN *MemoryMapSize,
576 IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
577 IN UINTN DescriptorSize
578 )
579{
580 EFI_STATUS Status;
581 CONST EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
582 EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry;
583 EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
584 EFI_MEMORY_DESCRIPTOR *LastAttributeEntry;
585 UINTN LastAttributeIndex;
586 UINTN Index;
587 UINTN Index2;
588 UINTN CurrentEntryCount;
589 UINTN TotalEntryCount;
590 UINTN AttributeCount;
591 BOOLEAN CanSplit;
592 BOOLEAN InDescAttrs;
593
594 ASSERT (MaxMemoryMapSize >= *MemoryMapSize);
595
596 MemoryAttributesTable = OcGetMemoryAttributes (&MemoryAttributesEntry);
597 if (MemoryAttributesTable == NULL) {
598 return EFI_UNSUPPORTED;
599 }
600
601 LastAttributeEntry = MemoryAttributesEntry;
602 LastAttributeIndex = 0;
603 MemoryMapEntry = MemoryMap;
604 CurrentEntryCount = *MemoryMapSize / DescriptorSize;
605 TotalEntryCount = MaxMemoryMapSize / DescriptorSize;
606 AttributeCount = MemoryAttributesTable->NumberOfEntries;
607
608 //
609 // We assume that the memory map and attribute table are sorted.
610 //
611 Index = 0;
612 while (Index < CurrentEntryCount) {
613 //
614 // Split entry by as many attributes as possible.
615 //
616 CanSplit = TRUE;
617 while (( MemoryMapEntry->Type == EfiRuntimeServicesCode
618 || MemoryMapEntry->Type == EfiRuntimeServicesData) && CanSplit)
619 {
620 //
621 // Find corresponding memory attribute.
622 //
623 InDescAttrs = FALSE;
624 MemoryAttributesEntry = LastAttributeEntry;
625 for (Index2 = LastAttributeIndex; Index2 < AttributeCount; ++Index2) {
626 if ( (MemoryAttributesEntry->Type == EfiRuntimeServicesCode)
627 || (MemoryAttributesEntry->Type == EfiRuntimeServicesData))
628 {
629 //
630 // UEFI spec says attribute entries are fully within memory map entries.
631 // Find first one of a different type.
632 //
634 MemoryMapEntry,
635 MemoryAttributesEntry->PhysicalStart,
636 EFI_PAGES_TO_SIZE (MemoryAttributesEntry->NumberOfPages)
637 ))
638 {
639 //
640 // We are within descriptor attribute sequence.
641 //
642 InDescAttrs = TRUE;
643 //
644 // No need to process the attribute of the same type.
645 //
646 if (OcRealMemoryType (MemoryAttributesEntry) != MemoryMapEntry->Type) {
647 //
648 // Start with the next attribute on the second iteration.
649 //
650 LastAttributeEntry = NEXT_MEMORY_DESCRIPTOR (
651 MemoryAttributesEntry,
652 MemoryAttributesTable->DescriptorSize
653 );
654 LastAttributeIndex = Index2 + 1;
655 break;
656 }
657 } else if (InDescAttrs) {
658 //
659 // Reached the end of descriptor attribute sequence, abort.
660 //
661 InDescAttrs = FALSE;
662 break;
663 }
664 }
665
666 MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR (
667 MemoryAttributesEntry,
668 MemoryAttributesTable->DescriptorSize
669 );
670 }
671
672 if ((Index2 < AttributeCount) && InDescAttrs) {
673 //
674 // Split current memory map entry.
675 //
677 &MemoryMapEntry,
678 &Index,
679 &CurrentEntryCount,
680 TotalEntryCount,
681 MemoryAttributesEntry,
682 DescriptorSize
683 );
684 if (EFI_ERROR (Status)) {
685 *MemoryMapSize = CurrentEntryCount * DescriptorSize;
686 return Status;
687 }
688
689 continue;
690 } else {
691 //
692 // Did not find a suitable attribute or processed all the attributes.
693 //
694 CanSplit = FALSE;
695 }
696 }
697
698 MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (
699 MemoryMapEntry,
700 DescriptorSize
701 );
702 ++Index;
703 }
704
705 *MemoryMapSize = CurrentEntryCount * DescriptorSize;
706 return EFI_SUCCESS;
707}
EFI_MEMORY_ATTRIBUTES_TABLE * OcGetMemoryAttributes(OUT EFI_MEMORY_DESCRIPTOR **MemoryAttributesEntry OPTIONAL)
STATIC EFI_STATUS OcSplitMemoryEntryByAttribute(IN OUT EFI_MEMORY_DESCRIPTOR **RetMemoryMapEntry, IN OUT UINTN *CurrentEntryIndex, IN OUT UINTN *CurrentEntryCount, IN UINTN TotalEntryCount, IN EFI_MEMORY_DESCRIPTOR *MemoryAttribute, IN UINTN DescriptorSize)
STATIC UINT32 OcRealMemoryType(IN EFI_MEMORY_DESCRIPTOR *MemoryAttribte)
STATIC EFI_STATUS OcExpandAttributeWrite(IN OUT EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable, IN OUT EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry OPTIONAL, IN UINTN MaxDescriptors, IN EFI_MEMORY_DESCRIPTOR *MemoryMapEntry, IN EFI_PHYSICAL_ADDRESS CurrentMapAddress)
EFI_STATUS OcRebuildAttributes(IN EFI_PHYSICAL_ADDRESS Address, IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL)
STATIC EFI_STATUS OcExpandAttributesByMap(IN OUT EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable, IN OUT EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry, IN UINTN MaxDescriptors, IN UINTN MemoryMapDescriptors, IN EFI_MEMORY_DESCRIPTOR *MemoryMap, IN UINTN DescriptorSize)
UINTN OcCountSplitDescriptors(VOID)
EFI_STATUS OcSplitMemoryMapByAttributes(IN UINTN MaxMemoryMapSize, IN OUT UINTN *MemoryMapSize, IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, IN UINTN DescriptorSize)
EFI_SYSTEM_TABLE * gST
EFI_BOOT_SERVICES * gBS
#define AREA_WITHIN_DESCRIPTOR(Desc, Area, AreaSize)
Definition OcMemoryLib.h:39
#define LAST_DESCRIPTOR_ADDR(Desc)
Definition OcMemoryLib.h:32
EFI_STATUS OcDeduplicateDescriptors(IN OUT UINT32 *EntryCount, IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, IN UINTN DescriptorSize)
Definition MemoryMap.c:438
VOID OcSortMemoryMap(IN UINTN MemoryMapSize, IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, IN UINTN DescriptorSize)
Definition MemoryMap.c:302
#define OC_DEFAULT_MEMORY_MAP_SIZE
Definition OcMemoryLib.h:51
EFI_STATUS OcUpdateDescriptors(IN UINTN MemoryMapSize, IN EFI_MEMORY_DESCRIPTOR *MemoryMap, IN UINTN DescriptorSize, IN EFI_PHYSICAL_ADDRESS Address, IN EFI_MEMORY_TYPE Type, IN UINT64 SetAttributes, IN UINT64 DropAttributes)
Definition MemoryMap.c:505
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
#define ASSERT(x)
Definition coder.h:55