]> git.proxmox.com Git - mirror_edk2.git/blob - CorebootModulePkg/CbSupportPei/CbSupportPei.c
CorebootModulePkg: Replace BSD License with BSD+Patent License
[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 - 2016, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9 #include "CbSupportPei.h"
10
11 #define LEGACY_8259_MASK_REGISTER_MASTER 0x21
12 #define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1
13
14 EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
15 { EfiACPIReclaimMemory, FixedPcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory) },
16 { EfiACPIMemoryNVS, FixedPcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS) },
17 { EfiReservedMemoryType, FixedPcdGet32 (PcdMemoryTypeEfiReservedMemoryType) },
18 { EfiRuntimeServicesData, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesData) },
19 { EfiRuntimeServicesCode, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode) },
20 { EfiMaxMemoryType, 0 }
21 };
22
23 EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {
24 {
25 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
26 &gEfiPeiMasterBootModePpiGuid,
27 NULL
28 }
29 };
30
31 /**
32 Create memory mapped io resource hob.
33
34 @param MmioBase Base address of the memory mapped io range
35 @param MmioSize Length of the memory mapped io range
36
37 **/
38 VOID
39 BuildMemoryMappedIoRangeHob (
40 EFI_PHYSICAL_ADDRESS MmioBase,
41 UINT64 MmioSize
42 )
43 {
44 BuildResourceDescriptorHob (
45 EFI_RESOURCE_MEMORY_MAPPED_IO,
46 (EFI_RESOURCE_ATTRIBUTE_PRESENT |
47 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
48 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
49 EFI_RESOURCE_ATTRIBUTE_TESTED),
50 MmioBase,
51 MmioSize
52 );
53
54 BuildMemoryAllocationHob (
55 MmioBase,
56 MmioSize,
57 EfiMemoryMappedIO
58 );
59 }
60
61 /**
62 Check the integrity of firmware volume header
63
64 @param[in] FwVolHeader A pointer to a firmware volume header
65
66 @retval TRUE The firmware volume is consistent
67 @retval FALSE The firmware volume has corrupted.
68
69 **/
70 STATIC
71 BOOLEAN
72 IsFvHeaderValid (
73 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
74 )
75 {
76 UINT16 Checksum;
77
78 // Skip nv storage fv
79 if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) {
80 return FALSE;
81 }
82
83 if ( (FwVolHeader->Revision != EFI_FVH_REVISION) ||
84 (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
85 (FwVolHeader->FvLength == ((UINTN) -1)) ||
86 ((FwVolHeader->HeaderLength & 0x01 ) !=0) ) {
87 return FALSE;
88 }
89
90 Checksum = CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength);
91 if (Checksum != 0) {
92 DEBUG (( DEBUG_ERROR,
93 "ERROR - Invalid Firmware Volume Header Checksum, change 0x%04x to 0x%04x\r\n",
94 FwVolHeader->Checksum,
95 (UINT16)( Checksum + FwVolHeader->Checksum )));
96 return FALSE;
97 }
98
99 return TRUE;
100 }
101
102 /**
103 Install FvInfo PPI and create fv hobs for remained fvs
104
105 **/
106 VOID
107 CbPeiReportRemainedFvs (
108 VOID
109 )
110 {
111 UINT8* TempPtr;
112 UINT8* EndPtr;
113
114 TempPtr = (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase);
115 EndPtr = (UINT8* )(UINTN) (PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize));
116
117 for (;TempPtr < EndPtr;) {
118 if (IsFvHeaderValid ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)) {
119 if (TempPtr != (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase)) {
120 // Skip the PEI FV
121 DEBUG((EFI_D_ERROR, "Found one valid fv : 0x%lx.\n", TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength));
122
123 PeiServicesInstallFvInfoPpi (
124 NULL,
125 (VOID *) (UINTN) TempPtr,
126 (UINT32) (UINTN) ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength,
127 NULL,
128 NULL
129 );
130 BuildFvHob ((EFI_PHYSICAL_ADDRESS)(UINTN) TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength);
131 }
132 }
133 TempPtr += ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength;
134 }
135 }
136
137 /**
138 Based on memory base, size and type, build resource descripter HOB.
139
140 @param Base Memory base address.
141 @param Size Memory size.
142 @param Type Memory type.
143 @param Param A pointer to CB_MEM_INFO.
144
145 @retval EFI_SUCCESS if it completed successfully.
146 **/
147 EFI_STATUS
148 CbMemInfoCallback (
149 UINT64 Base,
150 UINT64 Size,
151 UINT32 Type,
152 VOID *Param
153 )
154 {
155 CB_MEM_INFO *MemInfo;
156 UINTN Attribue;
157
158 Attribue = EFI_RESOURCE_ATTRIBUTE_PRESENT |
159 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
160 EFI_RESOURCE_ATTRIBUTE_TESTED |
161 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
162 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
163 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
164 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE;
165
166 if ((Base < 0x100000) && ((Base + Size) > 0x100000)) {
167 Size -= (0x100000 - Base);
168 Base = 0x100000;
169 }
170
171 MemInfo = (CB_MEM_INFO *)Param;
172 if (Base >= 0x100000) {
173 if (Type == CB_MEM_RAM) {
174 if (Base < 0x100000000ULL) {
175 MemInfo->UsableLowMemTop = (UINT32)(Base + Size);
176 } else {
177 Attribue &= ~EFI_RESOURCE_ATTRIBUTE_TESTED;
178 }
179 BuildResourceDescriptorHob (
180 EFI_RESOURCE_SYSTEM_MEMORY,
181 Attribue,
182 (EFI_PHYSICAL_ADDRESS)Base,
183 Size
184 );
185 } else if (Type == CB_MEM_TABLE) {
186 BuildResourceDescriptorHob (
187 EFI_RESOURCE_MEMORY_RESERVED,
188 Attribue,
189 (EFI_PHYSICAL_ADDRESS)Base,
190 Size
191 );
192 MemInfo->SystemLowMemTop = ((UINT32)(Base + Size) + 0x0FFFFFFF) & 0xF0000000;
193 } else if (Type == CB_MEM_RESERVED) {
194 if ((MemInfo->SystemLowMemTop == 0) || (Base < MemInfo->SystemLowMemTop)) {
195 BuildResourceDescriptorHob (
196 EFI_RESOURCE_MEMORY_RESERVED,
197 Attribue,
198 (EFI_PHYSICAL_ADDRESS)Base,
199 Size
200 );
201 }
202 }
203 }
204
205 return EFI_SUCCESS;
206 }
207
208 /**
209 This is the entrypoint of PEIM
210
211 @param FileHandle Handle of the file being invoked.
212 @param PeiServices Describes the list of possible PEI Services.
213
214 @retval EFI_SUCCESS if it completed successfully.
215 **/
216 EFI_STATUS
217 EFIAPI
218 CbPeiEntryPoint (
219 IN EFI_PEI_FILE_HANDLE FileHandle,
220 IN CONST EFI_PEI_SERVICES **PeiServices
221 )
222 {
223 EFI_STATUS Status;
224 UINT64 LowMemorySize;
225 UINT64 PeiMemSize = SIZE_64MB; // 64 MB
226 EFI_PHYSICAL_ADDRESS PeiMemBase = 0;
227 UINT32 RegEax;
228 UINT8 PhysicalAddressBits;
229 VOID* pCbHeader;
230 VOID* pAcpiTable;
231 UINT32 AcpiTableSize;
232 VOID* pSmbiosTable;
233 UINT32 SmbiosTableSize;
234 SYSTEM_TABLE_INFO* pSystemTableInfo;
235 FRAME_BUFFER_INFO FbInfo;
236 FRAME_BUFFER_INFO* pFbInfo;
237 ACPI_BOARD_INFO* pAcpiBoardInfo;
238 UINTN PmCtrlRegBase, PmTimerRegBase, ResetRegAddress, ResetValue;
239 UINTN PmEvtBase;
240 UINTN PmGpeEnBase;
241 CB_MEM_INFO CbMemInfo;
242
243 //
244 // Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED
245 // is intentionally omitted to prevent erasing of the coreboot header
246 // record before it is processed by CbParseMemoryInfo.
247 //
248 BuildResourceDescriptorHob (
249 EFI_RESOURCE_SYSTEM_MEMORY,
250 (
251 EFI_RESOURCE_ATTRIBUTE_PRESENT |
252 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
253 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
254 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
255 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
256 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
257 ),
258 (EFI_PHYSICAL_ADDRESS)(0),
259 (UINT64)(0xA0000)
260 );
261
262
263 BuildResourceDescriptorHob (
264 EFI_RESOURCE_MEMORY_RESERVED,
265 (
266 EFI_RESOURCE_ATTRIBUTE_PRESENT |
267 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
268 EFI_RESOURCE_ATTRIBUTE_TESTED |
269 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
270 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
271 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
272 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
273 ),
274 (EFI_PHYSICAL_ADDRESS)(0xA0000),
275 (UINT64)(0x60000)
276 );
277
278 ZeroMem (&CbMemInfo, sizeof(CbMemInfo));
279 Status = CbParseMemoryInfo (CbMemInfoCallback, (VOID *)&CbMemInfo);
280 if (EFI_ERROR(Status)) {
281 return Status;
282 }
283
284 LowMemorySize = CbMemInfo.UsableLowMemTop;
285 DEBUG ((EFI_D_INFO, "Low memory 0x%lx\n", LowMemorySize));
286 DEBUG ((EFI_D_INFO, "SystemLowMemTop 0x%x\n", CbMemInfo.SystemLowMemTop));
287
288 //
289 // Should be 64k aligned
290 //
291 PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));
292
293 DEBUG((EFI_D_ERROR, "PeiMemBase: 0x%lx.\n", PeiMemBase));
294 DEBUG((EFI_D_ERROR, "PeiMemSize: 0x%lx.\n", PeiMemSize));
295
296 Status = PeiServicesInstallPeiMemory (
297 PeiMemBase,
298 PeiMemSize
299 );
300 ASSERT_EFI_ERROR (Status);
301
302 //
303 // Set cache on the physical memory
304 //
305 MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack);
306 MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);
307
308 //
309 // Create Memory Type Information HOB
310 //
311 BuildGuidDataHob (
312 &gEfiMemoryTypeInformationGuid,
313 mDefaultMemoryTypeInformation,
314 sizeof(mDefaultMemoryTypeInformation)
315 );
316
317 //
318 // Create Fv hob
319 //
320 CbPeiReportRemainedFvs ();
321
322 BuildMemoryAllocationHob (
323 PcdGet32 (PcdPayloadFdMemBase),
324 PcdGet32 (PcdPayloadFdMemSize),
325 EfiBootServicesData
326 );
327
328 //
329 // Build CPU memory space and IO space hob
330 //
331 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
332 if (RegEax >= 0x80000008) {
333 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
334 PhysicalAddressBits = (UINT8) RegEax;
335 } else {
336 PhysicalAddressBits = 36;
337 }
338 //
339 // Create a CPU hand-off information
340 //
341 BuildCpuHob (PhysicalAddressBits, 16);
342
343 //
344 // Report Local APIC range
345 //
346 BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);
347
348 //
349 // Boot mode
350 //
351 Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);
352 ASSERT_EFI_ERROR (Status);
353
354 Status = PeiServicesInstallPpi (mPpiBootMode);
355 ASSERT_EFI_ERROR (Status);
356
357 //
358 // Set pcd to save the upper coreboot header in case the dxecore will
359 // erase 0~4k memory
360 //
361 pCbHeader = NULL;
362 if ((CbParseGetCbHeader (1, &pCbHeader) == RETURN_SUCCESS)
363 && ((UINTN)pCbHeader > BASE_4KB)) {
364 DEBUG((EFI_D_ERROR, "Actual Coreboot header: %p.\n", pCbHeader));
365 Status = PcdSet32S (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader);
366 ASSERT_EFI_ERROR (Status);
367 }
368
369 //
370 // Create guid hob for system tables like acpi table and smbios table
371 //
372 pAcpiTable = NULL;
373 AcpiTableSize = 0;
374 pSmbiosTable = NULL;
375 SmbiosTableSize = 0;
376 Status = CbParseAcpiTable (&pAcpiTable, &AcpiTableSize);
377 if (EFI_ERROR (Status)) {
378 // ACPI table is oblidgible
379 DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n"));
380 ASSERT (FALSE);
381 }
382 CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize);
383
384 pSystemTableInfo = NULL;
385 pSystemTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO));
386 ASSERT (pSystemTableInfo != NULL);
387 pSystemTableInfo->AcpiTableBase = (UINT64) (UINTN)pAcpiTable;
388 pSystemTableInfo->AcpiTableSize = AcpiTableSize;
389 pSystemTableInfo->SmbiosTableBase = (UINT64) (UINTN)pSmbiosTable;
390 pSystemTableInfo->SmbiosTableSize = SmbiosTableSize;
391 DEBUG ((EFI_D_ERROR, "Detected Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize));
392 DEBUG ((EFI_D_ERROR, "Detected Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize));
393 DEBUG ((EFI_D_ERROR, "Create system table info guid hob\n"));
394
395 //
396 // Create guid hob for acpi board information
397 //
398 Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue, &PmEvtBase, &PmGpeEnBase);
399 ASSERT_EFI_ERROR (Status);
400 pAcpiBoardInfo = NULL;
401 pAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO));
402 ASSERT (pAcpiBoardInfo != NULL);
403 pAcpiBoardInfo->PmCtrlRegBase = (UINT64)PmCtrlRegBase;
404 pAcpiBoardInfo->PmTimerRegBase = (UINT64)PmTimerRegBase;
405 pAcpiBoardInfo->ResetRegAddress = (UINT64)ResetRegAddress;
406 pAcpiBoardInfo->ResetValue = (UINT8)ResetValue;
407 pAcpiBoardInfo->PmEvtBase = (UINT64)PmEvtBase;
408 pAcpiBoardInfo->PmGpeEnBase = (UINT64)PmGpeEnBase;
409 DEBUG ((EFI_D_ERROR, "Create acpi board info guid hob\n"));
410
411 //
412 // Create guid hob for frame buffer information
413 //
414 ZeroMem (&FbInfo, sizeof (FRAME_BUFFER_INFO));
415 Status = CbParseFbInfo (&FbInfo);
416 if (!EFI_ERROR (Status)) {
417 pFbInfo = BuildGuidHob (&gUefiFrameBufferInfoGuid, sizeof (FRAME_BUFFER_INFO));
418 ASSERT (pSystemTableInfo != NULL);
419 CopyMem (pFbInfo, &FbInfo, sizeof (FRAME_BUFFER_INFO));
420 DEBUG ((EFI_D_ERROR, "Create frame buffer info guid hob\n"));
421 }
422
423 //
424 // Parse platform specific information from coreboot.
425 //
426 Status = CbParsePlatformInfo ();
427 if (EFI_ERROR (Status)) {
428 DEBUG ((EFI_D_ERROR, "Error when parsing platform info, Status = %r\n", Status));
429 return Status;
430 }
431
432 //
433 // Mask off all legacy 8259 interrupt sources
434 //
435 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
436 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF);
437
438 return EFI_SUCCESS;
439 }
440