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