3 Copyright (c) 2014-2017, Linaro Limited. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/DebugLib.h>
11 #include <Library/PcdLib.h>
16 QemuVirtMemInfoPeiLibConstructor (
22 UINT64 NewBase
, CurBase
;
23 UINT64 NewSize
, CurSize
;
26 CONST UINT64
*RegProp
;
27 RETURN_STATUS PcdStatus
;
32 DeviceTreeBase
= (VOID
*)(UINTN
)PcdGet64 (PcdDeviceTreeInitialBaseAddress
);
33 ASSERT (DeviceTreeBase
!= NULL
);
36 // Make sure we have a valid device tree blob
38 ASSERT (fdt_check_header (DeviceTreeBase
) == 0);
41 // Look for the lowest memory node
43 for (Prev
= 0; ; Prev
= Node
) {
44 Node
= fdt_next_node (DeviceTreeBase
, Prev
, NULL
);
50 // Check for memory node
52 Type
= fdt_getprop (DeviceTreeBase
, Node
, "device_type", &Len
);
53 if (Type
&& (AsciiStrnCmp (Type
, "memory", Len
) == 0)) {
55 // Get the 'reg' property of this node. For now, we will assume
56 // two 8 byte quantities for base and size, respectively.
58 RegProp
= fdt_getprop (DeviceTreeBase
, Node
, "reg", &Len
);
59 if ((RegProp
!= 0) && (Len
== (2 * sizeof (UINT64
)))) {
60 CurBase
= fdt64_to_cpu (ReadUnaligned64 (RegProp
));
61 CurSize
= fdt64_to_cpu (ReadUnaligned64 (RegProp
+ 1));
65 "%a: System RAM @ 0x%lx - 0x%lx\n",
71 if ((NewBase
> CurBase
) || (NewBase
== 0)) {
78 "%a: Failed to parse FDT memory node\n",
86 // Make sure the start of DRAM matches our expectation
88 ASSERT (FixedPcdGet64 (PcdSystemMemoryBase
) == NewBase
);
89 PcdStatus
= PcdSet64S (PcdSystemMemorySize
, NewSize
);
90 ASSERT_RETURN_ERROR (PcdStatus
);
93 // We need to make sure that the machine we are running on has at least
94 // 128 MB of memory configured, and is currently executing this binary from
95 // NOR flash. This prevents a device tree image in DRAM from getting
96 // clobbered when our caller installs permanent PEI RAM, before we have a
97 // chance of marking its location as reserved or copy it to a freshly
98 // allocated block in the permanent PEI RAM in the platform PEIM.
100 ASSERT (NewSize
>= SIZE_128MB
);
102 (((UINT64
)PcdGet64 (PcdFdBaseAddress
) +
103 (UINT64
)PcdGet32 (PcdFdSize
)) <= NewBase
) ||
104 ((UINT64
)PcdGet64 (PcdFdBaseAddress
) >= (NewBase
+ NewSize
))
107 return RETURN_SUCCESS
;