TianoCore EDK2 master
Loading...
Searching...
No Matches
QemuVirtMemInfoPeiLibConstructor.c
Go to the documentation of this file.
1
9#include <Uefi.h>
10#include <Pi/PiMultiPhase.h>
11#include <Library/BaseLib.h>
12#include <Library/DebugLib.h>
13#include <Library/HobLib.h>
14#include <libfdt.h>
15
16RETURN_STATUS
17EFIAPI
18QemuVirtMemInfoPeiLibConstructor (
19 VOID
20 )
21{
22 VOID *DeviceTreeBase;
23 INT32 Node, Prev;
24 UINT64 NewBase, CurBase;
25 UINT64 NewSize, CurSize;
26 CONST CHAR8 *Type;
27 INT32 Len;
28 CONST UINT64 *RegProp;
29 VOID *Hob;
30
31 NewBase = 0;
32 NewSize = 0;
33
34 DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
35 ASSERT (DeviceTreeBase != NULL);
36
37 //
38 // Make sure we have a valid device tree blob
39 //
40 ASSERT (fdt_check_header (DeviceTreeBase) == 0);
41
42 //
43 // Look for the lowest memory node
44 //
45 for (Prev = 0; ; Prev = Node) {
46 Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
47 if (Node < 0) {
48 break;
49 }
50
51 //
52 // Check for memory node
53 //
54 Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
55 if (Type && (AsciiStrnCmp (Type, "memory", Len) == 0)) {
56 //
57 // Get the 'reg' property of this node. For now, we will assume
58 // two 8 byte quantities for base and size, respectively.
59 //
60 RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
61 if ((RegProp != 0) && (Len == (2 * sizeof (UINT64)))) {
62 CurBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
63 CurSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));
64
65 DEBUG ((
66 DEBUG_INFO,
67 "%a: System RAM @ 0x%lx - 0x%lx\n",
68 __func__,
69 CurBase,
70 CurBase + CurSize - 1
71 ));
72
73 if ((NewBase > CurBase) || (NewBase == 0)) {
74 NewBase = CurBase;
75 NewSize = CurSize;
76 }
77 } else {
78 DEBUG ((
79 DEBUG_ERROR,
80 "%a: Failed to parse FDT memory node\n",
81 __func__
82 ));
83 }
84 }
85 }
86
87 //
88 // Make sure the start of DRAM matches our expectation
89 //
90 ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase);
91
92 Hob = BuildGuidDataHob (
93 &gArmVirtSystemMemorySizeGuid,
94 &NewSize,
95 sizeof NewSize
96 );
97 ASSERT (Hob != NULL);
98
99 //
100 // We need to make sure that the machine we are running on has at least
101 // 128 MB of memory configured, and is currently executing this binary from
102 // NOR flash. This prevents a device tree image in DRAM from getting
103 // clobbered when our caller installs permanent PEI RAM, before we have a
104 // chance of marking its location as reserved or copy it to a freshly
105 // allocated block in the permanent PEI RAM in the platform PEIM.
106 //
107 ASSERT (NewSize >= SIZE_128MB);
108 ASSERT (
109 (((UINT64)PcdGet64 (PcdFdBaseAddress) +
110 (UINT64)PcdGet32 (PcdFdSize)) <= NewBase) ||
111 ((UINT64)PcdGet64 (PcdFdBaseAddress) >= (NewBase + NewSize))
112 );
113
114 return RETURN_SUCCESS;
115}
UINT64 UINTN
VOID *EFIAPI BuildGuidDataHob(IN CONST EFI_GUID *Guid, IN VOID *Data, IN UINTN DataLength)
Definition: HobLib.c:375
UINT64 EFIAPI ReadUnaligned64(IN CONST UINT64 *Buffer)
Definition: Unaligned.c:204
INTN EFIAPI AsciiStrnCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString, IN UINTN Length)
Definition: String.c:872
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define RETURN_SUCCESS
Definition: Base.h:1066
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define FixedPcdGet64(TokenName)
Definition: PcdLib.h:106
#define PcdGet32(TokenName)
Definition: PcdLib.h:362