]> git.proxmox.com Git - mirror_edk2.git/blame - ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ArmVirtPkg / Library / PlatformPeiLib / PlatformPeiLib.c
CommitLineData
433b31dd
AB
1/** @file\r
2*\r
bb5420bb 3* Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
82662a3b 4* Copyright (c) 2014-2020, Linaro Limited. All rights reserved.\r
433b31dd 5*\r
9792fb0e 6* SPDX-License-Identifier: BSD-2-Clause-Patent\r
433b31dd
AB
7*\r
8**/\r
9\r
10#include <PiPei.h>\r
11\r
12#include <Library/MemoryAllocationLib.h>\r
13#include <Library/DebugLib.h>\r
14#include <Library/HobLib.h>\r
15#include <Library/PcdLib.h>\r
82662a3b 16#include <Library/PeiServicesLib.h>\r
433b31dd
AB
17#include <libfdt.h>\r
18\r
337d450e 19#include <Guid/EarlyPL011BaseAddress.h>\r
cc667df0 20#include <Guid/FdtHob.h>\r
337d450e 21\r
2b16a4fb 22STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpm2DiscoveredPpi = {\r
82662a3b
AB
23 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
24 &gOvmfTpmDiscoveredPpiGuid,\r
25 NULL\r
26};\r
27\r
2b16a4fb 28STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpm2InitializationDonePpi = {\r
82662a3b
AB
29 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
30 &gPeiTpmInitializationDonePpiGuid,\r
31 NULL\r
32};\r
33\r
433b31dd
AB
34EFI_STATUS\r
35EFIAPI\r
36PlatformPeim (\r
37 VOID\r
38 )\r
39{\r
2b16a4fb
MK
40 VOID *Base;\r
41 VOID *NewBase;\r
42 UINTN FdtSize;\r
43 UINTN FdtPages;\r
44 UINT64 *FdtHobData;\r
45 UINT64 *UartHobData;\r
46 INT32 Node, Prev;\r
47 INT32 Parent, Depth;\r
48 CONST CHAR8 *Compatible;\r
49 CONST CHAR8 *CompItem;\r
50 CONST CHAR8 *NodeStatus;\r
51 INT32 Len;\r
52 INT32 RangesLen;\r
53 INT32 StatusLen;\r
54 CONST UINT64 *RegProp;\r
55 CONST UINT32 *RangesProp;\r
56 UINT64 UartBase;\r
57 UINT64 TpmBase;\r
58 EFI_STATUS Status;\r
59\r
60 Base = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);\r
cc667df0 61 ASSERT (Base != NULL);\r
433b31dd
AB
62 ASSERT (fdt_check_header (Base) == 0);\r
63\r
2b16a4fb 64 FdtSize = fdt_totalsize (Base) + PcdGet32 (PcdDeviceTreeAllocationPadding);\r
616ea9da 65 FdtPages = EFI_SIZE_TO_PAGES (FdtSize);\r
2b16a4fb 66 NewBase = AllocatePages (FdtPages);\r
433b31dd 67 ASSERT (NewBase != NULL);\r
616ea9da 68 fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));\r
cc667df0
AB
69\r
70 FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);\r
71 ASSERT (FdtHobData != NULL);\r
72 *FdtHobData = (UINTN)NewBase;\r
433b31dd 73\r
337d450e
AB
74 UartHobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *UartHobData);\r
75 ASSERT (UartHobData != NULL);\r
76 *UartHobData = 0;\r
77\r
82662a3b
AB
78 TpmBase = 0;\r
79\r
f52b30e7
AB
80 //\r
81 // Set Parent to suppress incorrect compiler/analyzer warnings.\r
82 //\r
83 Parent = 0;\r
84\r
2b16a4fb 85 for (Prev = Depth = 0; ; Prev = Node) {\r
82662a3b 86 Node = fdt_next_node (Base, Prev, &Depth);\r
337d450e
AB
87 if (Node < 0) {\r
88 break;\r
89 }\r
90\r
82662a3b
AB
91 if (Depth == 1) {\r
92 Parent = Node;\r
93 }\r
94\r
337d450e
AB
95 Compatible = fdt_getprop (Base, Node, "compatible", &Len);\r
96\r
97 //\r
98 // Iterate over the NULL-separated items in the compatible string\r
99 //\r
100 for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;\r
2b16a4fb
MK
101 CompItem += 1 + AsciiStrLen (CompItem))\r
102 {\r
337d450e 103 if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {\r
83ae7589 104 NodeStatus = fdt_getprop (Base, Node, "status", &StatusLen);\r
2b16a4fb 105 if ((NodeStatus != NULL) && (AsciiStrCmp (NodeStatus, "okay") != 0)) {\r
83ae7589
AB
106 continue;\r
107 }\r
108\r
337d450e
AB
109 RegProp = fdt_getprop (Base, Node, "reg", &Len);\r
110 ASSERT (Len == 16);\r
111\r
112 UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));\r
113\r
c5b3a56e 114 DEBUG ((DEBUG_INFO, "%a: PL011 UART @ 0x%lx\n", __FUNCTION__, UartBase));\r
337d450e
AB
115\r
116 *UartHobData = UartBase;\r
117 break;\r
82662a3b 118 } else if (FeaturePcdGet (PcdTpm2SupportEnabled) &&\r
2b16a4fb
MK
119 (AsciiStrCmp (CompItem, "tcg,tpm-tis-mmio") == 0))\r
120 {\r
82662a3b
AB
121 RegProp = fdt_getprop (Base, Node, "reg", &Len);\r
122 ASSERT (Len == 8 || Len == 16);\r
123 if (Len == 8) {\r
124 TpmBase = fdt32_to_cpu (RegProp[0]);\r
125 } else if (Len == 16) {\r
126 TpmBase = fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RegProp));\r
127 }\r
128\r
129 if (Depth > 1) {\r
130 //\r
131 // QEMU/mach-virt may put the TPM on the platform bus, in which case\r
132 // we have to take its 'ranges' property into account to translate the\r
133 // MMIO address. This consists of a <child base, parent base, size>\r
134 // tuple, where the child base and the size use the same number of\r
135 // cells as the 'reg' property above, and the parent base uses 2 cells\r
136 //\r
137 RangesProp = fdt_getprop (Base, Parent, "ranges", &RangesLen);\r
138 ASSERT (RangesProp != NULL);\r
139\r
140 //\r
141 // a plain 'ranges' attribute without a value implies a 1:1 mapping\r
142 //\r
143 if (RangesLen != 0) {\r
144 //\r
145 // assume a single translated range with 2 cells for the parent base\r
146 //\r
147 if (RangesLen != Len + 2 * sizeof (UINT32)) {\r
2b16a4fb
MK
148 DEBUG ((\r
149 DEBUG_WARN,\r
82662a3b 150 "%a: 'ranges' property has unexpected size %d\n",\r
2b16a4fb
MK
151 __FUNCTION__,\r
152 RangesLen\r
153 ));\r
82662a3b
AB
154 break;\r
155 }\r
156\r
157 if (Len == 8) {\r
158 TpmBase -= fdt32_to_cpu (RangesProp[0]);\r
159 } else {\r
160 TpmBase -= fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RangesProp));\r
161 }\r
162\r
163 //\r
164 // advance RangesProp to the parent bus address\r
165 //\r
166 RangesProp = (UINT32 *)((UINT8 *)RangesProp + Len / 2);\r
2b16a4fb 167 TpmBase += fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RangesProp));\r
82662a3b
AB
168 }\r
169 }\r
2b16a4fb 170\r
82662a3b 171 break;\r
337d450e
AB
172 }\r
173 }\r
174 }\r
175\r
82662a3b
AB
176 if (FeaturePcdGet (PcdTpm2SupportEnabled)) {\r
177 if (TpmBase != 0) {\r
178 DEBUG ((DEBUG_INFO, "%a: TPM @ 0x%lx\n", __FUNCTION__, TpmBase));\r
179\r
180 Status = (EFI_STATUS)PcdSet64S (PcdTpmBaseAddress, TpmBase);\r
181 ASSERT_EFI_ERROR (Status);\r
182\r
183 Status = PeiServicesInstallPpi (&mTpm2DiscoveredPpi);\r
184 } else {\r
185 Status = PeiServicesInstallPpi (&mTpm2InitializationDonePpi);\r
186 }\r
2b16a4fb 187\r
82662a3b
AB
188 ASSERT_EFI_ERROR (Status);\r
189 }\r
190\r
bb5420bb 191 BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));\r
433b31dd
AB
192\r
193 return EFI_SUCCESS;\r
194}\r