]> git.proxmox.com Git - mirror_edk2.git/blob - CorebootModulePkg/CbSupportPei/CbSupportPei.c
EmbeddedPkg/GdbDebugAgent: fix VOID* cast of incorrect size
[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 MemInfo = (CB_MEM_INFO *)Param;
173 if (Base >= 0x100000) {
174 if (Type == CB_MEM_RAM) {
175 if (Base < 0x100000000ULL) {
176 MemInfo->UsableLowMemTop = (UINT32)(Base + Size);
177 } else {
178 Attribue &= ~EFI_RESOURCE_ATTRIBUTE_TESTED;
179 }
180 BuildResourceDescriptorHob (
181 EFI_RESOURCE_SYSTEM_MEMORY,
182 Attribue,
183 (EFI_PHYSICAL_ADDRESS)Base,
184 Size
185 );
186 } else if (Type == CB_MEM_TABLE) {
187 BuildResourceDescriptorHob (
188 EFI_RESOURCE_MEMORY_RESERVED,
189 Attribue,
190 (EFI_PHYSICAL_ADDRESS)Base,
191 Size
192 );
193 MemInfo->SystemLowMemTop = ((UINT32)(Base + Size) + 0x0FFFFFFF) & 0xF0000000;
194 } else if (Type == CB_MEM_RESERVED) {
195 if ((MemInfo->SystemLowMemTop == 0) || (Base < MemInfo->SystemLowMemTop)) {
196 BuildResourceDescriptorHob (
197 EFI_RESOURCE_MEMORY_RESERVED,
198 Attribue,
199 (EFI_PHYSICAL_ADDRESS)Base,
200 Size
201 );
202 }
203 }
204 }
205
206 return EFI_SUCCESS;
207 }
208
209 /**
210 This is the entrypoint of PEIM
211
212 @param FileHandle Handle of the file being invoked.
213 @param PeiServices Describes the list of possible PEI Services.
214
215 @retval EFI_SUCCESS if it completed successfully.
216 **/
217 EFI_STATUS
218 EFIAPI
219 CbPeiEntryPoint (
220 IN EFI_PEI_FILE_HANDLE FileHandle,
221 IN CONST EFI_PEI_SERVICES **PeiServices
222 )
223 {
224 EFI_STATUS Status;
225 UINT64 LowMemorySize;
226 UINT64 PeiMemSize = SIZE_64MB; // 64 MB
227 EFI_PHYSICAL_ADDRESS PeiMemBase = 0;
228 UINT32 RegEax;
229 UINT8 PhysicalAddressBits;
230 VOID* pCbHeader;
231 VOID* pAcpiTable;
232 UINT32 AcpiTableSize;
233 VOID* pSmbiosTable;
234 UINT32 SmbiosTableSize;
235 SYSTEM_TABLE_INFO* pSystemTableInfo;
236 FRAME_BUFFER_INFO FbInfo;
237 FRAME_BUFFER_INFO* pFbInfo;
238 ACPI_BOARD_INFO* pAcpiBoardInfo;
239 UINTN PmCtrlRegBase, PmTimerRegBase, ResetRegAddress, ResetValue;
240 UINTN PmEvtBase;
241 UINTN PmGpeEnBase;
242 CB_MEM_INFO CbMemInfo;
243
244 //
245 // Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED
246 // is intentionally omitted to prevent erasing of the coreboot header
247 // record before it is processed by CbParseMemoryInfo.
248 //
249 BuildResourceDescriptorHob (
250 EFI_RESOURCE_SYSTEM_MEMORY,
251 (
252 EFI_RESOURCE_ATTRIBUTE_PRESENT |
253 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
254 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
255 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
256 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
257 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
258 ),
259 (EFI_PHYSICAL_ADDRESS)(0),
260 (UINT64)(0xA0000)
261 );
262
263
264 BuildResourceDescriptorHob (
265 EFI_RESOURCE_MEMORY_RESERVED,
266 (
267 EFI_RESOURCE_ATTRIBUTE_PRESENT |
268 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
269 EFI_RESOURCE_ATTRIBUTE_TESTED |
270 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
271 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
272 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
273 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
274 ),
275 (EFI_PHYSICAL_ADDRESS)(0xA0000),
276 (UINT64)(0x60000)
277 );
278
279 ZeroMem (&CbMemInfo, sizeof(CbMemInfo));
280 Status = CbParseMemoryInfo (CbMemInfoCallback, (VOID *)&CbMemInfo);
281 if (EFI_ERROR(Status)) {
282 return Status;
283 }
284
285 LowMemorySize = CbMemInfo.UsableLowMemTop;
286 DEBUG ((EFI_D_INFO, "Low memory 0x%lx\n", LowMemorySize));
287 DEBUG ((EFI_D_INFO, "SystemLowMemTop 0x%x\n", CbMemInfo.SystemLowMemTop));
288
289 //
290 // Should be 64k aligned
291 //
292 PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));
293
294 DEBUG((EFI_D_ERROR, "PeiMemBase: 0x%lx.\n", PeiMemBase));
295 DEBUG((EFI_D_ERROR, "PeiMemSize: 0x%lx.\n", PeiMemSize));
296
297 Status = PeiServicesInstallPeiMemory (
298 PeiMemBase,
299 PeiMemSize
300 );
301 ASSERT_EFI_ERROR (Status);
302
303 //
304 // Set cache on the physical memory
305 //
306 MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack);
307 MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);
308
309 //
310 // Create Memory Type Information HOB
311 //
312 BuildGuidDataHob (
313 &gEfiMemoryTypeInformationGuid,
314 mDefaultMemoryTypeInformation,
315 sizeof(mDefaultMemoryTypeInformation)
316 );
317
318 //
319 // Create Fv hob
320 //
321 CbPeiReportRemainedFvs ();
322
323 BuildMemoryAllocationHob (
324 PcdGet32 (PcdPayloadFdMemBase),
325 PcdGet32 (PcdPayloadFdMemSize),
326 EfiBootServicesData
327 );
328
329 //
330 // Build CPU memory space and IO space hob
331 //
332 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
333 if (RegEax >= 0x80000008) {
334 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
335 PhysicalAddressBits = (UINT8) RegEax;
336 } else {
337 PhysicalAddressBits = 36;
338 }
339 //
340 // Create a CPU hand-off information
341 //
342 BuildCpuHob (PhysicalAddressBits, 16);
343
344 //
345 // Report Local APIC range
346 //
347 BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);
348
349 //
350 // Boot mode
351 //
352 Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);
353 ASSERT_EFI_ERROR (Status);
354
355 Status = PeiServicesInstallPpi (mPpiBootMode);
356 ASSERT_EFI_ERROR (Status);
357
358 //
359 // Set pcd to save the upper coreboot header in case the dxecore will
360 // erase 0~4k memory
361 //
362 pCbHeader = NULL;
363 if ((CbParseGetCbHeader (1, &pCbHeader) == RETURN_SUCCESS)
364 && ((UINTN)pCbHeader > BASE_4KB)) {
365 DEBUG((EFI_D_ERROR, "Actual Coreboot header: %p.\n", pCbHeader));
366 Status = PcdSet32S (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader);
367 ASSERT_EFI_ERROR (Status);
368 }
369
370 //
371 // Create guid hob for system tables like acpi table and smbios table
372 //
373 pAcpiTable = NULL;
374 AcpiTableSize = 0;
375 pSmbiosTable = NULL;
376 SmbiosTableSize = 0;
377 Status = CbParseAcpiTable (&pAcpiTable, &AcpiTableSize);
378 if (EFI_ERROR (Status)) {
379 // ACPI table is oblidgible
380 DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n"));
381 ASSERT (FALSE);
382 }
383 CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize);
384
385 pSystemTableInfo = NULL;
386 pSystemTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO));
387 ASSERT (pSystemTableInfo != NULL);
388 pSystemTableInfo->AcpiTableBase = (UINT64) (UINTN)pAcpiTable;
389 pSystemTableInfo->AcpiTableSize = AcpiTableSize;
390 pSystemTableInfo->SmbiosTableBase = (UINT64) (UINTN)pSmbiosTable;
391 pSystemTableInfo->SmbiosTableSize = SmbiosTableSize;
392 DEBUG ((EFI_D_ERROR, "Detected Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize));
393 DEBUG ((EFI_D_ERROR, "Detected Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize));
394 DEBUG ((EFI_D_ERROR, "Create system table info guid hob\n"));
395
396 //
397 // Create guid hob for acpi board information
398 //
399 Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue, &PmEvtBase, &PmGpeEnBase);
400 ASSERT_EFI_ERROR (Status);
401 pAcpiBoardInfo = NULL;
402 pAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO));
403 ASSERT (pAcpiBoardInfo != NULL);
404 pAcpiBoardInfo->PmCtrlRegBase = (UINT64)PmCtrlRegBase;
405 pAcpiBoardInfo->PmTimerRegBase = (UINT64)PmTimerRegBase;
406 pAcpiBoardInfo->ResetRegAddress = (UINT64)ResetRegAddress;
407 pAcpiBoardInfo->ResetValue = (UINT8)ResetValue;
408 pAcpiBoardInfo->PmEvtBase = (UINT64)PmEvtBase;
409 pAcpiBoardInfo->PmGpeEnBase = (UINT64)PmGpeEnBase;
410 DEBUG ((EFI_D_ERROR, "Create acpi board info guid hob\n"));
411
412 //
413 // Create guid hob for frame buffer information
414 //
415 ZeroMem (&FbInfo, sizeof (FRAME_BUFFER_INFO));
416 Status = CbParseFbInfo (&FbInfo);
417 if (!EFI_ERROR (Status)) {
418 pFbInfo = BuildGuidHob (&gUefiFrameBufferInfoGuid, sizeof (FRAME_BUFFER_INFO));
419 ASSERT (pSystemTableInfo != NULL);
420 CopyMem (pFbInfo, &FbInfo, sizeof (FRAME_BUFFER_INFO));
421 DEBUG ((EFI_D_ERROR, "Create frame buffer info guid hob\n"));
422 }
423
424 //
425 // Parse platform specific information from coreboot.
426 //
427 Status = CbParsePlatformInfo ();
428 if (EFI_ERROR (Status)) {
429 DEBUG ((EFI_D_ERROR, "Error when parsing platform info, Status = %r\n", Status));
430 return Status;
431 }
432
433 //
434 // Mask off all legacy 8259 interrupt sources
435 //
436 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
437 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF);
438
439 return EFI_SUCCESS;
440 }
441