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