49488438a2b8e3db1dda4db9010ec9ad1f0a93d7
[mirror_edk2.git] / CorebootModulePkg / CbSupportPei / CbSupportPei.c
1 /** @file
2 This PEIM will parse coreboot table in memory and report resource information into pei core.
3 This file contains the main entrypoint of the PEIM.
4
5 Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15 #include "CbSupportPei.h"
16
17 EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
18 { EfiACPIReclaimMemory, 0x008 },
19 { EfiACPIMemoryNVS, 0x004 },
20 { EfiReservedMemoryType, 0x004 },
21 { EfiRuntimeServicesData, 0x080 },
22 { EfiRuntimeServicesCode, 0x080 },
23 { EfiMaxMemoryType, 0 }
24 };
25
26 EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {
27 {
28 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
29 &gEfiPeiMasterBootModePpiGuid,
30 NULL
31 }
32 };
33
34 /**
35 Create memory mapped io resource hob.
36
37 @param MmioBase Base address of the memory mapped io range
38 @param MmioSize Length of the memory mapped io range
39
40 **/
41 VOID
42 BuildMemoryMappedIoRangeHob (
43 EFI_PHYSICAL_ADDRESS MmioBase,
44 UINT64 MmioSize
45 )
46 {
47 BuildResourceDescriptorHob (
48 EFI_RESOURCE_MEMORY_MAPPED_IO,
49 (EFI_RESOURCE_ATTRIBUTE_PRESENT |
50 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
51 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
52 EFI_RESOURCE_ATTRIBUTE_TESTED),
53 MmioBase,
54 MmioSize
55 );
56
57 BuildMemoryAllocationHob (
58 MmioBase,
59 MmioSize,
60 EfiMemoryMappedIO
61 );
62 }
63
64 /**
65 Check the integrity of firmware volume header
66
67 @param[in] FwVolHeader A pointer to a firmware volume header
68
69 @retval TRUE The firmware volume is consistent
70 @retval FALSE The firmware volume has corrupted.
71
72 **/
73 STATIC
74 BOOLEAN
75 IsFvHeaderValid (
76 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
77 )
78 {
79 UINT16 Checksum;
80
81 // Skip nv storage fv
82 if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) {
83 return FALSE;
84 }
85
86 if ( (FwVolHeader->Revision != EFI_FVH_REVISION) ||
87 (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
88 (FwVolHeader->FvLength == ((UINTN) -1)) ||
89 ((FwVolHeader->HeaderLength & 0x01 ) !=0) ) {
90 return FALSE;
91 }
92
93 Checksum = CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength);
94 if (Checksum != 0) {
95 DEBUG (( DEBUG_ERROR,
96 "ERROR - Invalid Firmware Volume Header Checksum, change 0x%04x to 0x%04x\r\n",
97 FwVolHeader->Checksum,
98 (UINT16)( Checksum + FwVolHeader->Checksum )));
99 return FALSE;
100 }
101
102 return TRUE;
103 }
104
105 /**
106 Install FvInfo PPI and create fv hobs for remained fvs
107
108 **/
109 VOID
110 CbPeiReportRemainedFvs (
111 VOID
112 )
113 {
114 UINT8* TempPtr;
115 UINT8* EndPtr;
116
117 TempPtr = (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase);
118 EndPtr = (UINT8* )(UINTN) (PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize));
119
120 for (;TempPtr < EndPtr;) {
121 if (IsFvHeaderValid ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)) {
122 if (TempPtr != (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase)) {
123 // Skip the PEI FV
124 DEBUG((EFI_D_ERROR, "Found one valid fv : 0x%x.\n", TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength));
125
126 PeiServicesInstallFvInfoPpi (
127 NULL,
128 (VOID *) (UINTN) TempPtr,
129 (UINT32) (UINTN) ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength,
130 NULL,
131 NULL
132 );
133 BuildFvHob ((EFI_PHYSICAL_ADDRESS)(UINTN) TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength);
134 }
135 }
136 TempPtr += ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength;
137 }
138 }
139
140 /**
141 This is the entrypoint of PEIM
142
143 @param FileHandle Handle of the file being invoked.
144 @param PeiServices Describes the list of possible PEI Services.
145
146 @retval EFI_SUCCESS if it completed successfully.
147 **/
148 EFI_STATUS
149 EFIAPI
150 CbPeiEntryPoint (
151 IN EFI_PEI_FILE_HANDLE FileHandle,
152 IN CONST EFI_PEI_SERVICES **PeiServices
153 )
154 {
155 EFI_STATUS Status;
156 UINT64 LowMemorySize, HighMemorySize;
157 UINT64 PeiMemSize = SIZE_64MB; // 64 MB
158 EFI_PHYSICAL_ADDRESS PeiMemBase = 0;
159 UINT32 RegEax;
160 UINT8 PhysicalAddressBits;
161 VOID* pCbHeader;
162 VOID* pAcpiTable;
163 UINT32 AcpiTableSize;
164 VOID* pSmbiosTable;
165 UINT32 SmbiosTableSize;
166 SYSTEM_TABLE_INFO* pSystemTableInfo;
167 FRAME_BUFFER_INFO FbInfo;
168 FRAME_BUFFER_INFO* pFbInfo;
169 ACPI_BOARD_INFO* pAcpiBoardInfo;
170 UINTN PmCtrlRegBase, PmTimerRegBase, ResetRegAddress, ResetValue;
171
172 LowMemorySize = 0;
173 HighMemorySize = 0;
174
175 Status = CbParseMemoryInfo (&LowMemorySize, &HighMemorySize);
176 if (EFI_ERROR(Status))
177 return Status;
178
179 DEBUG((EFI_D_ERROR, "LowMemorySize: 0x%x.\n", LowMemorySize));
180 DEBUG((EFI_D_ERROR, "HighMemorySize: 0x%x.\n", HighMemorySize));
181
182 ASSERT (LowMemorySize > 0);
183
184 BuildResourceDescriptorHob (
185 EFI_RESOURCE_SYSTEM_MEMORY,
186 (
187 EFI_RESOURCE_ATTRIBUTE_PRESENT |
188 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
189 EFI_RESOURCE_ATTRIBUTE_TESTED |
190 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
191 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
192 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
193 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
194 ),
195 (EFI_PHYSICAL_ADDRESS)(0),
196 (UINT64)(0xA0000)
197 );
198
199
200 BuildResourceDescriptorHob (
201 EFI_RESOURCE_MEMORY_RESERVED,
202 (
203 EFI_RESOURCE_ATTRIBUTE_PRESENT |
204 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
205 EFI_RESOURCE_ATTRIBUTE_TESTED |
206 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
207 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
208 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
209 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
210 ),
211 (EFI_PHYSICAL_ADDRESS)(0xA0000),
212 (UINT64)(0x60000)
213 );
214
215 BuildResourceDescriptorHob (
216 EFI_RESOURCE_SYSTEM_MEMORY,
217 (
218 EFI_RESOURCE_ATTRIBUTE_PRESENT |
219 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
220 EFI_RESOURCE_ATTRIBUTE_TESTED |
221 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
222 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
223 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
224 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
225 ),
226 (EFI_PHYSICAL_ADDRESS)(0x100000),
227 (UINT64) (LowMemorySize - 0x100000)
228 );
229
230 if (HighMemorySize > 0) {
231 BuildResourceDescriptorHob (
232 EFI_RESOURCE_SYSTEM_MEMORY,
233 (
234 EFI_RESOURCE_ATTRIBUTE_PRESENT |
235 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
236 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
237 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
238 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
239 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
240 ),
241 (EFI_PHYSICAL_ADDRESS)(0x100000000ULL),
242 HighMemorySize
243 );
244 }
245
246 //
247 // Should be 64k aligned
248 //
249 PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));
250
251 DEBUG((EFI_D_ERROR, "PeiMemBase: 0x%x.\n", PeiMemBase));
252 DEBUG((EFI_D_ERROR, "PeiMemSize: 0x%x.\n", PeiMemSize));
253
254 Status = PeiServicesInstallPeiMemory (
255 PeiMemBase,
256 PeiMemSize
257 );
258 ASSERT_EFI_ERROR (Status);
259
260 //
261 // Set cache on the physical memory
262 //
263 MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack);
264 MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);
265
266 //
267 // Create Memory Type Information HOB
268 //
269 BuildGuidDataHob (
270 &gEfiMemoryTypeInformationGuid,
271 mDefaultMemoryTypeInformation,
272 sizeof(mDefaultMemoryTypeInformation)
273 );
274
275 //
276 // Create Fv hob
277 //
278 CbPeiReportRemainedFvs ();
279
280 BuildMemoryAllocationHob (
281 PcdGet32 (PcdPayloadFdMemBase),
282 PcdGet32 (PcdPayloadFdMemSize),
283 EfiBootServicesData
284 );
285
286 //
287 // Build CPU memory space and IO space hob
288 //
289 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
290 if (RegEax >= 0x80000008) {
291 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
292 PhysicalAddressBits = (UINT8) RegEax;
293 } else {
294 PhysicalAddressBits = 36;
295 }
296 //
297 // Create a CPU hand-off information
298 //
299 BuildCpuHob (PhysicalAddressBits, 16);
300
301 //
302 // Report Local APIC range
303 //
304 BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);
305
306 //
307 // Boot mode
308 //
309 Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);
310 ASSERT_EFI_ERROR (Status);
311
312 Status = PeiServicesInstallPpi (mPpiBootMode);
313 ASSERT_EFI_ERROR (Status);
314
315 //
316 // Set pcd to save the upper coreboot header in case the dxecore will
317 // erase 0~4k memory
318 //
319 pCbHeader = NULL;
320 if ((CbParseGetCbHeader (1, &pCbHeader) == RETURN_SUCCESS)
321 && ((UINTN)pCbHeader > BASE_4KB)) {
322 DEBUG((EFI_D_ERROR, "Actual Coreboot header: 0x%x.\n", (UINTN)pCbHeader));
323 PcdSet32 (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader);
324 }
325
326 //
327 // Create guid hob for system tables like acpi table and smbios table
328 //
329 pAcpiTable = NULL;
330 AcpiTableSize = 0;
331 pSmbiosTable = NULL;
332 SmbiosTableSize = 0;
333 Status = CbParseAcpiTable (&pAcpiTable, &AcpiTableSize);
334 if (EFI_ERROR (Status)) {
335 // ACPI table is oblidgible
336 DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n"));
337 ASSERT (FALSE);
338 }
339 CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize);
340
341 pSystemTableInfo = NULL;
342 pSystemTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO));
343 ASSERT (pSystemTableInfo != NULL);
344 pSystemTableInfo->AcpiTableBase = (UINT64) (UINTN)pAcpiTable;
345 pSystemTableInfo->AcpiTableSize = AcpiTableSize;
346 pSystemTableInfo->SmbiosTableBase = (UINT64) (UINTN)pSmbiosTable;
347 pSystemTableInfo->SmbiosTableSize = SmbiosTableSize;
348 DEBUG ((EFI_D_ERROR, "Detected Acpi Table at 0x%x, length 0x%x\n", (UINTN)pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize));
349 DEBUG ((EFI_D_ERROR, "Detected Smbios Table at 0x%x, length 0x%x\n", (UINTN)pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize));
350 DEBUG ((EFI_D_ERROR, "Create system table info guid hob\n"));
351
352 //
353 // Create guid hob for acpi board information
354 //
355 Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue);
356 ASSERT_EFI_ERROR (Status);
357 pAcpiBoardInfo = NULL;
358 pAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO));
359 ASSERT (pAcpiBoardInfo != NULL);
360 pAcpiBoardInfo->PmCtrlRegBase = (UINT64)PmCtrlRegBase;
361 pAcpiBoardInfo->PmTimerRegBase = (UINT64)PmTimerRegBase;
362 pAcpiBoardInfo->ResetRegAddress = (UINT64)ResetRegAddress;
363 pAcpiBoardInfo->ResetValue = (UINT8)ResetValue;
364 DEBUG ((EFI_D_ERROR, "Create acpi board info guid hob\n"));
365
366 //
367 // Create guid hob for frame buffer information
368 //
369 ZeroMem (&FbInfo, sizeof (FRAME_BUFFER_INFO));
370 Status = CbParseFbInfo (&FbInfo);
371 if (!EFI_ERROR (Status)) {
372 pFbInfo = BuildGuidHob (&gUefiFrameBufferInfoGuid, sizeof (FRAME_BUFFER_INFO));
373 ASSERT (pSystemTableInfo != NULL);
374 CopyMem (pFbInfo, &FbInfo, sizeof (FRAME_BUFFER_INFO));
375 DEBUG ((EFI_D_ERROR, "Create frame buffer info guid hob\n"));
376 }
377
378 return EFI_SUCCESS;
379 }
380