TianoCore EDK2 master
Loading...
Searching...
No Matches
PlatformPeiLib.c
Go to the documentation of this file.
1
10#include <PiPei.h>
11
14#include <Library/DebugLib.h>
15#include <Library/FdtLib.h>
16#include <Library/HobLib.h>
17#include <Library/PcdLib.h>
20
22#include <Guid/FdtHob.h>
23
24STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpm2DiscoveredPpi = {
25 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
26 &gOvmfTpmDiscoveredPpiGuid,
27 NULL
28};
29
30STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpm2InitializationDonePpi = {
31 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
32 &gPeiTpmInitializationDonePpiGuid,
33 NULL
34};
35
37EFIAPI
39 VOID
40 )
41{
42 VOID *Base;
43 VOID *NewBase;
44 UINTN FdtSize;
45 UINTN FdtPages;
46 UINT64 *FdtHobData;
47 EARLY_PL011_BASE_ADDRESS *UartHobData;
48 FDT_SERIAL_PORTS Ports;
49 INT32 Node, Prev;
50 INT32 Parent, Depth;
51 CONST CHAR8 *Compatible;
52 CONST CHAR8 *CompItem;
53 INT32 Len;
54 INT32 RangesLen;
55 CONST UINT64 *RegProp;
56 CONST UINT32 *RangesProp;
57 UINT64 TpmBase;
58 EFI_STATUS Status;
59
60 Base = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
61 ASSERT (Base != NULL);
62 ASSERT (FdtCheckHeader (Base) == 0);
63
64 FdtSize = FdtTotalSize (Base) + PcdGet32 (PcdDeviceTreeAllocationPadding);
65 FdtPages = EFI_SIZE_TO_PAGES (FdtSize);
66 NewBase = AllocatePages (FdtPages);
67 ASSERT (NewBase != NULL);
68 FdtOpenInto (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));
69
70 FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);
71 ASSERT (FdtHobData != NULL);
72 *FdtHobData = (UINTN)NewBase;
73
74 UartHobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *UartHobData);
75 ASSERT (UartHobData != NULL);
76 SetMem (UartHobData, sizeof *UartHobData, 0);
77
78 Status = FdtSerialGetPorts (Base, "arm,pl011", &Ports);
79 if (!EFI_ERROR (Status)) {
80 if (Ports.NumberOfPorts == 1) {
81 //
82 // Just one UART; direct both SerialPortLib+console and DebugLib to it.
83 //
84 UartHobData->ConsoleAddress = Ports.BaseAddress[0];
85 UartHobData->DebugAddress = Ports.BaseAddress[0];
86 } else {
87 UINT64 ConsoleAddress;
88
89 Status = FdtSerialGetConsolePort (Base, &ConsoleAddress);
90 if (EFI_ERROR (Status)) {
91 //
92 // At least two UARTs; but failed to get the console preference. Use the
93 // first UART for SerialPortLib+console, and the second one for
94 // DebugLib.
95 //
96 UartHobData->ConsoleAddress = Ports.BaseAddress[0];
97 UartHobData->DebugAddress = Ports.BaseAddress[1];
98 } else {
99 //
100 // At least two UARTs; and console preference available. Use the
101 // preferred UART for SerialPortLib+console, and *another* UART for
102 // DebugLib.
103 //
104 UartHobData->ConsoleAddress = ConsoleAddress;
105 if (ConsoleAddress == Ports.BaseAddress[0]) {
106 UartHobData->DebugAddress = Ports.BaseAddress[1];
107 } else {
108 UartHobData->DebugAddress = Ports.BaseAddress[0];
109 }
110 }
111 }
112
113 DEBUG ((
114 DEBUG_INFO,
115 "%a: PL011 UART (console) @ 0x%lx\n",
116 __func__,
117 UartHobData->ConsoleAddress
118 ));
119 DEBUG ((
120 DEBUG_INFO,
121 "%a: PL011 UART (debug) @ 0x%lx\n",
122 __func__,
123 UartHobData->DebugAddress
124 ));
125 }
126
127 TpmBase = 0;
128
129 //
130 // Set Parent to suppress incorrect compiler/analyzer warnings.
131 //
132 Parent = 0;
133
134 for (Prev = Depth = 0; ; Prev = Node) {
135 Node = FdtNextNode (Base, Prev, &Depth);
136 if (Node < 0) {
137 break;
138 }
139
140 if (Depth == 1) {
141 Parent = Node;
142 }
143
144 Compatible = FdtGetProp (Base, Node, "compatible", &Len);
145
146 //
147 // Iterate over the NULL-separated items in the compatible string
148 //
149 for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;
150 CompItem += 1 + AsciiStrLen (CompItem))
151 {
152 if (FeaturePcdGet (PcdTpm2SupportEnabled) &&
153 (AsciiStrCmp (CompItem, "tcg,tpm-tis-mmio") == 0))
154 {
155 RegProp = FdtGetProp (Base, Node, "reg", &Len);
156 ASSERT (Len == 8 || Len == 16);
157 if (Len == 8) {
158 TpmBase = Fdt32ToCpu (RegProp[0]);
159 } else if (Len == 16) {
160 TpmBase = Fdt64ToCpu (ReadUnaligned64 ((UINT64 *)RegProp));
161 }
162
163 if (Depth > 1) {
164 //
165 // QEMU/mach-virt may put the TPM on the platform bus, in which case
166 // we have to take its 'ranges' property into account to translate the
167 // MMIO address. This consists of a <child base, parent base, size>
168 // tuple, where the child base and the size use the same number of
169 // cells as the 'reg' property above, and the parent base uses 2 cells
170 //
171 RangesProp = FdtGetProp (Base, Parent, "ranges", &RangesLen);
172 ASSERT (RangesProp != NULL);
173
174 //
175 // a plain 'ranges' attribute without a value implies a 1:1 mapping
176 //
177 if (RangesLen != 0) {
178 //
179 // assume a single translated range with 2 cells for the parent base
180 //
181 if (RangesLen != Len + 2 * sizeof (UINT32)) {
182 DEBUG ((
183 DEBUG_WARN,
184 "%a: 'ranges' property has unexpected size %d\n",
185 __func__,
186 RangesLen
187 ));
188 break;
189 }
190
191 if (Len == 8) {
192 TpmBase -= Fdt32ToCpu (RangesProp[0]);
193 } else {
194 TpmBase -= Fdt64ToCpu (ReadUnaligned64 ((UINT64 *)RangesProp));
195 }
196
197 //
198 // advance RangesProp to the parent bus address
199 //
200 RangesProp = (UINT32 *)((UINT8 *)RangesProp + Len / 2);
201 TpmBase += Fdt64ToCpu (ReadUnaligned64 ((UINT64 *)RangesProp));
202 }
203 }
204
205 break;
206 }
207 }
208 }
209
210 if (FeaturePcdGet (PcdTpm2SupportEnabled)) {
211 if (TpmBase != 0) {
212 DEBUG ((DEBUG_INFO, "%a: TPM @ 0x%lx\n", __func__, TpmBase));
213
214 Status = (EFI_STATUS)PcdSet64S (PcdTpmBaseAddress, TpmBase);
215 ASSERT_EFI_ERROR (Status);
216
217 Status = PeiServicesInstallPpi (&mTpm2DiscoveredPpi);
218 } else {
219 Status = PeiServicesInstallPpi (&mTpm2InitializationDonePpi);
220 }
221
222 ASSERT_EFI_ERROR (Status);
223 }
224
225 BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));
226
227 return EFI_SUCCESS;
228}
UINT64 UINTN
EFI_STATUS EFIAPI PlatformPeim(VOID)
VOID EFIAPI BuildFvHob(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
Definition: HobLib.c:404
VOID *EFIAPI BuildGuidHob(IN CONST EFI_GUID *Guid, IN UINTN DataLength)
Definition: HobLib.c:336
UINT64 EFIAPI ReadUnaligned64(IN CONST VOID *Buffer)
Definition: Unaligned.c:191
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
Definition: String.c:716
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
Definition: SetMemWrapper.c:38
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
UINT64 EFIAPI Fdt64ToCpu(IN UINT64 Value)
Definition: FdtLib.c:91
INT32 EFIAPI FdtOpenInto(IN CONST VOID *Fdt, OUT VOID *Buffer, IN INT32 BufferSize)
Definition: FdtLib.c:163
INT32 EFIAPI FdtNextNode(IN CONST VOID *Fdt, IN INT32 Offset, IN INT32 *Depth)
Definition: FdtLib.c:220
INT32 EFIAPI FdtCheckHeader(IN CONST VOID *Fdt)
Definition: FdtLib.c:125
UINT32 EFIAPI Fdt32ToCpu(IN UINT32 Value)
Definition: FdtLib.c:57
CONST VOID *EFIAPI FdtGetProp(IN CONST VOID *Fdt, IN INT32 NodeOffset, IN CONST CHAR8 *Name, IN INT32 *Length)
Definition: FdtLib.c:495
RETURN_STATUS EFIAPI FdtSerialGetConsolePort(IN CONST VOID *DeviceTree, OUT UINT64 *BaseAddress)
RETURN_STATUS EFIAPI FdtSerialGetPorts(IN CONST VOID *DeviceTree, IN CONST CHAR8 *Compatible, OUT FDT_SERIAL_PORTS *Ports)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define VOID
Definition: Base.h:269
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:463
#define DEBUG(Expression)
Definition: DebugLib.h:435
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdSet64S(TokenName, Value)
Definition: PcdLib.h:511
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
VOID *EFIAPI AllocatePages(IN UINTN Pages)
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112