]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/Virt.c
7961b0524e11060640fb9404aac85bef9cef9215
[mirror_edk2.git] / ArmPlatformPkg / ArmVirtualizationPkg / Library / ArmVirtualizationPlatformLib / Virt.c
1 /** @file
2 *
3 * Copyright (c) 2011-2013, ARM Limited. All rights reserved.
4 * Copyright (c) 2014, Linaro Limited. All rights reserved.
5 * Copyright (c) 2014, Red Hat, Inc.
6 *
7 *
8 * This program and the accompanying materials
9 * are licensed and made available under the terms and conditions of the BSD License
10 * which accompanies this distribution. The full text of the license may be found at
11 * http://opensource.org/licenses/bsd-license.php
12 *
13 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 *
16 **/
17
18 #include <Library/IoLib.h>
19 #include <Library/ArmPlatformLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/PcdLib.h>
22 #include <ArmPlatform.h>
23 #include <libfdt.h>
24 #include <Pi/PiBootMode.h>
25 #include <Uefi/UefiBaseType.h>
26 #include <Uefi/UefiMultiPhase.h>
27 #include <Pi/PiHob.h>
28 #include <Library/HobLib.h>
29 #include <Guid/EarlyPL011BaseAddress.h>
30
31 /**
32 Return the current Boot Mode
33
34 This function returns the boot reason on the platform
35
36 @return Return the current Boot Mode of the platform
37
38 **/
39 EFI_BOOT_MODE
40 ArmPlatformGetBootMode (
41 VOID
42 )
43 {
44 return BOOT_WITH_FULL_CONFIGURATION;
45 }
46
47 /**
48 This function is called by PrePeiCore, in the SEC phase.
49 **/
50 RETURN_STATUS
51 ArmPlatformInitialize (
52 IN UINTN MpId
53 )
54 {
55 //
56 // We are relying on ArmPlatformInitializeSystemMemory () being called from
57 // InitializeMemory (), which only occurs if the following feature is disabled
58 //
59 ASSERT (!FeaturePcdGet (PcdSystemMemoryInitializeInSec));
60 return RETURN_SUCCESS;
61 }
62
63 /**
64 Initialize the system (or sometimes called permanent) memory
65
66 This memory is generally represented by the DRAM.
67
68 This function is called from InitializeMemory() in MemoryInitPeim, in the PEI
69 phase.
70 **/
71 VOID
72 ArmPlatformInitializeSystemMemory (
73 VOID
74 )
75 {
76 VOID *DeviceTreeBase;
77 INT32 Node, Prev;
78 UINT64 NewBase;
79 UINT64 NewSize;
80 BOOLEAN HaveMemory, HaveUART;
81 UINT64 *HobData;
82 CONST CHAR8 *Type;
83 CONST CHAR8 *Compatible;
84 CONST CHAR8 *CompItem;
85 INT32 Len;
86 CONST UINT64 *RegProp;
87 UINT64 UartBase;
88
89 NewBase = 0;
90 NewSize = 0;
91
92 HaveMemory = FALSE;
93 HaveUART = FALSE;
94
95 HobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *HobData);
96 ASSERT (HobData != NULL);
97 *HobData = 0;
98
99 DeviceTreeBase = (VOID *)(UINTN)FixedPcdGet64 (PcdDeviceTreeInitialBaseAddress);
100 ASSERT (DeviceTreeBase != NULL);
101
102 //
103 // Make sure we have a valid device tree blob
104 //
105 ASSERT (fdt_check_header (DeviceTreeBase) == 0);
106
107 //
108 // Look for a memory node
109 //
110 for (Prev = 0; !(HaveMemory && HaveUART); Prev = Node) {
111 Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
112 if (Node < 0) {
113 break;
114 }
115
116 //
117 // Check for memory node
118 //
119 Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
120 if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {
121 //
122 // Get the 'reg' property of this node. For now, we will assume
123 // two 8 byte quantities for base and size, respectively.
124 //
125 RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
126 if (RegProp != 0 && Len == (2 * sizeof (UINT64))) {
127
128 NewBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
129 NewSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));
130
131 //
132 // Make sure the start of DRAM matches our expectation
133 //
134 ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase);
135 PcdSet64 (PcdSystemMemorySize, NewSize);
136
137 DEBUG ((EFI_D_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n",
138 __FUNCTION__, NewBase, NewBase + NewSize - 1));
139 } else {
140 DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n",
141 __FUNCTION__));
142 }
143 HaveMemory = TRUE;
144 continue;
145 }
146
147 //
148 // Check for UART node
149 //
150 Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len);
151
152 //
153 // Iterate over the NULL-separated items in the compatible string
154 //
155 for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;
156 CompItem += 1 + AsciiStrLen (CompItem)) {
157
158 if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {
159 RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
160 ASSERT (Len == 16);
161
162 UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
163
164 DEBUG ((EFI_D_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__, UartBase));
165
166 *HobData = UartBase;
167
168 HaveUART = TRUE;
169 continue;
170 }
171 }
172 }
173
174 //
175 // We need to make sure that the machine we are running on has at least
176 // 128 MB of memory configured, and is currently executing this binary from
177 // NOR flash. This prevents a device tree image in DRAM from getting
178 // clobbered when our caller installs permanent PEI RAM, before we have a
179 // chance of marking its location as reserved or copy it to a freshly
180 // allocated block in the permanent PEI RAM in the platform PEIM.
181 //
182 ASSERT (NewSize >= SIZE_128MB);
183 ASSERT (
184 (((UINT64)PcdGet32 (PcdFdBaseAddress) +
185 (UINT64)PcdGet32 (PcdFdSize)) <= NewBase) ||
186 ((UINT64)PcdGet32 (PcdFdBaseAddress) >= (NewBase + NewSize)));
187 }
188
189 VOID
190 ArmPlatformGetPlatformPpiList (
191 OUT UINTN *PpiListSize,
192 OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
193 )
194 {
195 *PpiListSize = 0;
196 *PpiList = NULL;
197 }