]> git.proxmox.com Git - mirror_edk2.git/blame - ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLibConstructor.c
ArmVirtPkg/FdtPciHostBridgeLib: map ECAM and I/O spaces in GCD memory map
[mirror_edk2.git] / ArmVirtPkg / Library / QemuVirtMemInfoLib / QemuVirtMemInfoPeiLibConstructor.c
CommitLineData
04865126
AB
1/** @file\r
2\r
3 Copyright (c) 2014-2017, Linaro Limited. All rights reserved.\r
4\r
5 This program and the accompanying materials are licensed and made available\r
6 under the terms and conditions of the BSD License which accompanies this\r
7 distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <Base.h>\r
16#include <Library/DebugLib.h>\r
17#include <Library/PcdLib.h>\r
18#include <libfdt.h>\r
19\r
20RETURN_STATUS\r
21EFIAPI\r
22QemuVirtMemInfoPeiLibConstructor (\r
23 VOID\r
24 )\r
25{\r
26 VOID *DeviceTreeBase;\r
27 INT32 Node, Prev;\r
28 UINT64 NewBase, CurBase;\r
29 UINT64 NewSize, CurSize;\r
30 CONST CHAR8 *Type;\r
31 INT32 Len;\r
32 CONST UINT64 *RegProp;\r
33 RETURN_STATUS PcdStatus;\r
34\r
35 NewBase = 0;\r
36 NewSize = 0;\r
37\r
38 DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);\r
39 ASSERT (DeviceTreeBase != NULL);\r
40\r
41 //\r
42 // Make sure we have a valid device tree blob\r
43 //\r
44 ASSERT (fdt_check_header (DeviceTreeBase) == 0);\r
45\r
46 //\r
47 // Look for the lowest memory node\r
48 //\r
49 for (Prev = 0;; Prev = Node) {\r
50 Node = fdt_next_node (DeviceTreeBase, Prev, NULL);\r
51 if (Node < 0) {\r
52 break;\r
53 }\r
54\r
55 //\r
56 // Check for memory node\r
57 //\r
58 Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);\r
59 if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {\r
60 //\r
61 // Get the 'reg' property of this node. For now, we will assume\r
62 // two 8 byte quantities for base and size, respectively.\r
63 //\r
64 RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);\r
65 if (RegProp != 0 && Len == (2 * sizeof (UINT64))) {\r
66\r
67 CurBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));\r
68 CurSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));\r
69\r
70 DEBUG ((DEBUG_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n",\r
71 __FUNCTION__, CurBase, CurBase + CurSize - 1));\r
72\r
73 if (NewBase > CurBase || NewBase == 0) {\r
74 NewBase = CurBase;\r
75 NewSize = CurSize;\r
76 }\r
77 } else {\r
78 DEBUG ((DEBUG_ERROR, "%a: Failed to parse FDT memory node\n",\r
79 __FUNCTION__));\r
80 }\r
81 }\r
82 }\r
83\r
84 //\r
85 // Make sure the start of DRAM matches our expectation\r
86 //\r
87 ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase);\r
88 PcdStatus = PcdSet64S (PcdSystemMemorySize, NewSize);\r
89 ASSERT_RETURN_ERROR (PcdStatus);\r
90\r
91 //\r
92 // We need to make sure that the machine we are running on has at least\r
93 // 128 MB of memory configured, and is currently executing this binary from\r
94 // NOR flash. This prevents a device tree image in DRAM from getting\r
95 // clobbered when our caller installs permanent PEI RAM, before we have a\r
96 // chance of marking its location as reserved or copy it to a freshly\r
97 // allocated block in the permanent PEI RAM in the platform PEIM.\r
98 //\r
99 ASSERT (NewSize >= SIZE_128MB);\r
100 ASSERT (\r
101 (((UINT64)PcdGet64 (PcdFdBaseAddress) +\r
102 (UINT64)PcdGet32 (PcdFdSize)) <= NewBase) ||\r
103 ((UINT64)PcdGet64 (PcdFdBaseAddress) >= (NewBase + NewSize)));\r
104\r
105 return RETURN_SUCCESS;\r
106}\r