]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkPlatformPkg/Acpi/Dxe/AcpiPlatform/AcpiPlatform.c
QuarkPlatformPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / QuarkPlatformPkg / Acpi / Dxe / AcpiPlatform / AcpiPlatform.c
CommitLineData
b303605e
MK
1/** @file\r
2ACPI Platform Driver\r
3\r
fb308fdb 4Copyright (c) 2013-2016 Intel Corporation.\r
b303605e 5\r
0eb3de2e 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
b303605e
MK
7\r
8**/\r
9\r
10#include <Protocol/AcpiTable.h>\r
11#include <IndustryStandard/Pci22.h>\r
12#include "AcpiPlatform.h"\r
13\r
14//\r
15// Global Variable\r
16//\r
17EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea;\r
18EFI_ACPI_SDT_PROTOCOL *mAcpiSdt;\r
19\r
20EFI_ACPI_HANDLE mDsdtHandle = NULL;\r
21\r
22\r
23EFI_STATUS\r
24LocateSupportProtocol (\r
25 IN EFI_GUID *Protocol,\r
26 OUT VOID **Instance,\r
27 IN UINT32 Type\r
28 )\r
29/*++\r
30\r
31Routine Description:\r
32\r
33 Locate the first instance of a protocol. If the protocol requested is an\r
34 FV protocol, then it will return the first FV that contains the ACPI table\r
35 storage file.\r
36\r
37Arguments:\r
38\r
39 Protocol The protocol to find.\r
40 Instance Return pointer to the first instance of the protocol\r
41\r
42Returns:\r
43\r
44 EFI_SUCCESS The function completed successfully.\r
45 EFI_NOT_FOUND The protocol could not be located.\r
46 EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.\r
47\r
48--*/\r
49{\r
50 EFI_STATUS Status;\r
51 EFI_HANDLE *HandleBuffer;\r
52 UINTN NumberOfHandles;\r
53 EFI_FV_FILETYPE FileType;\r
54 UINT32 FvStatus;\r
55 EFI_FV_FILE_ATTRIBUTES Attributes;\r
56 UINTN Size;\r
57 UINTN i;\r
58\r
59 FvStatus = 0;\r
60\r
61 //\r
62 // Locate protocol.\r
63 //\r
64 Status = gBS->LocateHandleBuffer (\r
65 ByProtocol,\r
66 Protocol,\r
67 NULL,\r
68 &NumberOfHandles,\r
69 &HandleBuffer\r
70 );\r
71 if (EFI_ERROR (Status)) {\r
72\r
73 //\r
74 // Defined errors at this time are not found and out of resources.\r
75 //\r
76 return Status;\r
77 }\r
78\r
79\r
80\r
81 //\r
82 // Looking for FV with ACPI storage file\r
83 //\r
84\r
85 for (i = 0; i < NumberOfHandles; i++) {\r
86 //\r
87 // Get the protocol on this handle\r
88 // This should not fail because of LocateHandleBuffer\r
89 //\r
90 Status = gBS->HandleProtocol (\r
91 HandleBuffer[i],\r
92 Protocol,\r
93 Instance\r
94 );\r
95 ASSERT_EFI_ERROR (Status);\r
96\r
97 if (!Type) {\r
98 //\r
99 // Not looking for the FV protocol, so find the first instance of the\r
100 // protocol. There should not be any errors because our handle buffer\r
101 // should always contain at least one or LocateHandleBuffer would have\r
102 // returned not found.\r
103 //\r
104 break;\r
105 }\r
106\r
107 //\r
108 // See if it has the ACPI storage file\r
109 //\r
110\r
111 Status = ((EFI_FIRMWARE_VOLUME2_PROTOCOL*) (*Instance))->ReadFile (*Instance,\r
112 (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),\r
113 NULL,\r
114 &Size,\r
115 &FileType,\r
116 &Attributes,\r
117 &FvStatus\r
118 );\r
119\r
120 //\r
121 // If we found it, then we are done\r
122 //\r
123 if (Status == EFI_SUCCESS) {\r
124 break;\r
125 }\r
126 }\r
127\r
128 //\r
129 // Our exit status is determined by the success of the previous operations\r
130 // If the protocol was found, Instance already points to it.\r
131 //\r
132\r
133 //\r
134 // Free any allocated buffers\r
135 //\r
136 gBS->FreePool (HandleBuffer);\r
137\r
138 return Status;\r
139}\r
140\r
141\r
142VOID\r
143DsdtTableUpdate (\r
144 IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader,\r
145 IN OUT EFI_ACPI_TABLE_VERSION *Version\r
146 )\r
147/*++\r
148\r
149 Routine Description:\r
150\r
151 Update the DSDT table\r
152\r
153 Arguments:\r
154\r
155 Table - The table to be set\r
156 Version - Version to publish\r
157\r
158 Returns:\r
159\r
160 None\r
161\r
162--*/\r
163{\r
164\r
165 UINT8 *CurrPtr;\r
166 UINT8 *DsdtPointer;\r
167 UINT32 *Signature;\r
168 UINT8 *Operation;\r
169 UINT32 *Address;\r
170 UINT16 *Size;\r
171 //\r
172 // Loop through the ASL looking for values that we must fix up.\r
173 //\r
174 CurrPtr = (UINT8 *) TableHeader;\r
175 for (DsdtPointer = CurrPtr;\r
176 DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length);\r
177 DsdtPointer++\r
178 )\r
179 {\r
180 Signature = (UINT32 *) DsdtPointer;\r
181 switch (*Signature) {\r
182 //\r
183 // MNVS operation region\r
184 //\r
185 case (SIGNATURE_32 ('M', 'N', 'V', 'S')):\r
186 //\r
187 // Conditional match. For Region Objects, the Operator will always be the\r
188 // byte immediately before the specific name. Therefore, subtract 1 to check\r
189 // the Operator.\r
190 //\r
191 Operation = DsdtPointer - 1;\r
192 if (*Operation == AML_OPREGION_OP) {\r
193 Address = (UINT32 *) (DsdtPointer + 6);\r
194 *Address = (UINT32) (UINTN) mGlobalNvsArea.Area;\r
195 Size = (UINT16 *) (DsdtPointer + 11);\r
196 *Size = sizeof (EFI_GLOBAL_NVS_AREA);\r
197 }\r
198 break;\r
199\r
200 //\r
201 // Update processor PBLK register I/O base address\r
202 //\r
203 case (SIGNATURE_32 ('P', 'R', 'I', 'O')):\r
204 //\r
205 // Conditional match. Update the following ASL code:\r
206 // Processor (CPU0, 0x01, 0x4F495250, 0x06) {}\r
207 // The 3rd parameter will be updated to the actual PBLK I/O base address.\r
208 // the Operator.\r
209 //\r
210 Operation = DsdtPointer - 8;\r
211 if ((*Operation == AML_EXT_OP) && (*(Operation + 1) == AML_EXT_PROCESSOR_OP)) {\r
212 *(UINT32 *)DsdtPointer = PcdGet16(PcdPmbaIoBaseAddress);\r
213 }\r
214 break;\r
215 default:\r
216 break;\r
217 }\r
218 }\r
219}\r
220\r
221\r
222VOID\r
223ApicTableUpdate (\r
224 IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader,\r
225 IN OUT EFI_ACPI_TABLE_VERSION *Version\r
226 )\r
227/*++\r
228\r
229 Routine Description:\r
230\r
231 Update the processors information in the APIC table\r
232\r
233 Arguments:\r
234\r
235 Table - The table to be set\r
236 Version - Version to publish\r
237\r
238 Returns:\r
239\r
240 None\r
241\r
242--*/\r
243{\r
244 EFI_STATUS Status;\r
245 EFI_MP_SERVICES_PROTOCOL *MpService;\r
246 UINT8 *CurrPtr;\r
247 UINT8 *EndPtr;\r
248 UINT8 CurrIoApic;\r
249 UINT8 CurrProcessor;\r
250 UINTN NumberOfCPUs;\r
251 UINTN NumberOfEnabledCPUs;\r
b303605e
MK
252 EFI_PROCESSOR_INFORMATION MpContext;\r
253 ACPI_APIC_STRUCTURE_PTR *ApicPtr;\r
254\r
255 CurrIoApic = 0;\r
256 CurrProcessor = 0;\r
257 //\r
258 // Find the MP Protocol. This is an MP platform, so MP protocol must be\r
259 // there.\r
260 //\r
261 Status = gBS->LocateProtocol (\r
262 &gEfiMpServiceProtocolGuid,\r
263 NULL,\r
264 (VOID**)&MpService\r
265 );\r
266 if (EFI_ERROR (Status)) {\r
267 //\r
268 // Failed to get MP information, doesn't publish the invalid table\r
269 //\r
270 *Version = EFI_ACPI_TABLE_VERSION_NONE;\r
271 return;\r
272 }\r
273\r
274 //\r
275 // Determine the number of processors\r
276 //\r
277 MpService->GetNumberOfProcessors (\r
278 MpService,\r
279 &NumberOfCPUs,\r
280 &NumberOfEnabledCPUs\r
281 );\r
282\r
283 CurrPtr = (UINT8*) &(TableHeader[1]);\r
284 CurrPtr = CurrPtr + 8; // Size of Local APIC Address & Flag\r
285 EndPtr = (UINT8*) TableHeader;\r
286 EndPtr = EndPtr + TableHeader->Length;\r
287\r
288 while (CurrPtr < EndPtr) {\r
289\r
290 ApicPtr = (ACPI_APIC_STRUCTURE_PTR*) CurrPtr;\r
291 switch (ApicPtr->AcpiApicCommon.Type) {\r
292\r
293 case EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC:\r
b303605e
MK
294 ApicPtr->AcpiLocalApic.Flags = 0;\r
295 ApicPtr->AcpiLocalApic.ApicId = 0;\r
296 Status = MpService->GetProcessorInfo (\r
297 MpService,\r
298 CurrProcessor,\r
299 &MpContext\r
300 );\r
301\r
302 if (!EFI_ERROR (Status)) {\r
303 if (MpContext.StatusFlag & PROCESSOR_ENABLED_BIT) {\r
304 ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_3_0_LOCAL_APIC_ENABLED;\r
305 }\r
306 ApicPtr->AcpiLocalApic.ApicId = (UINT8)MpContext.ProcessorId;\r
307 }\r
308 CurrProcessor++;\r
309 break;\r
310\r
311 case EFI_ACPI_1_0_IO_APIC:\r
312 //\r
313 // IO APIC entries can be patched here\r
314 //\r
315 if (CurrIoApic == 0) {\r
316 //\r
317 // Update SOC internel IOAPIC base\r
318 //\r
319 ApicPtr->AcpiIoApic.IoApicId = PcdGet8 (PcdIoApicSettingIoApicId);\r
320 ApicPtr->AcpiIoApic.IoApicAddress = (UINT32)PcdGet64(PcdIoApicBaseAddress);\r
321 ApicPtr->AcpiIoApic.GlobalSystemInterruptBase = 0;\r
322 } else {\r
323 //\r
324 // Porting is required to update other IOAPIC entries if available\r
325 //\r
326 ASSERT (0);\r
327 }\r
328 CurrIoApic++;\r
329 break;\r
330\r
331 default:\r
332 break;\r
333 };\r
334 CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length;\r
335 }\r
336}\r
337\r
338VOID\r
339AcpiUpdateTable (\r
340 IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader,\r
341 IN OUT EFI_ACPI_TABLE_VERSION *Version\r
342 )\r
343/*++\r
344\r
345 Routine Description:\r
346\r
347 Set the correct table revision upon the setup value\r
348\r
349 Arguments:\r
350\r
351 Table - The table to be set\r
352 Version - Version to publish\r
353\r
354 Returns:\r
355\r
356 None\r
357\r
358--*/\r
359\r
360{\r
361 EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader1;\r
362 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader2;\r
363 EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader3;\r
364 EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *AllocationStructurePtr;\r
365\r
366 if (TableHeader != NULL && Version != NULL) {\r
367\r
368 *Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;\r
369 //\r
370 // Here we use all 3.0 signature because all version use same signature if they supported\r
371 //\r
372 switch (TableHeader->Signature) {\r
373 //\r
374 // "APIC" Multiple APIC Description Table\r
375 //\r
376 case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:\r
377 ApicTableUpdate (TableHeader, Version);\r
378 break;\r
379 //\r
380 // "DSDT" Differentiated System Description Table\r
381 //\r
382 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
383 DsdtTableUpdate (TableHeader, Version);\r
384 break;\r
385\r
386 //\r
387 // "FACP" Fixed ACPI Description Table (FADT)\r
388 //\r
389 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:\r
390 *Version = EFI_ACPI_TABLE_VERSION_NONE;\r
391 if (TableHeader->Revision == EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {\r
392 *Version = EFI_ACPI_TABLE_VERSION_1_0B;\r
393 FadtHeader1 = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader;\r
394 FadtHeader1->SmiCmd = PcdGet16(PcdSmmActivationPort);\r
395 FadtHeader1->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress);\r
396 FadtHeader1->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C;\r
397 FadtHeader1->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T;\r
398 FadtHeader1->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress);\r
399 } else if (TableHeader->Revision == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {\r
400 *Version = EFI_ACPI_TABLE_VERSION_2_0;\r
401 FadtHeader2 = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader;\r
402 FadtHeader2->SmiCmd = PcdGet16(PcdSmmActivationPort);\r
403 FadtHeader2->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress);\r
404 FadtHeader2->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C;\r
405 FadtHeader2->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T;\r
406 FadtHeader2->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress);\r
407 FadtHeader2->XPm1aEvtBlk.Address = FadtHeader2->Pm1aEvtBlk;\r
408 FadtHeader2->XPm1aCntBlk.Address = FadtHeader2->Pm1aCntBlk;\r
409 FadtHeader2->XPmTmrBlk.Address = FadtHeader2->PmTmrBlk;\r
410 FadtHeader2->XGpe0Blk.Address = FadtHeader2->Gpe0Blk;\r
411 } else if (TableHeader->Revision == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {\r
412 *Version = EFI_ACPI_TABLE_VERSION_3_0;\r
413 FadtHeader3 = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader;\r
414 FadtHeader3->SmiCmd = PcdGet16(PcdSmmActivationPort);\r
415 FadtHeader3->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress);\r
416 FadtHeader3->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C;\r
417 FadtHeader3->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T;\r
418 FadtHeader3->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress);\r
419 FadtHeader3->XPm1aEvtBlk.Address = FadtHeader3->Pm1aEvtBlk;\r
420 FadtHeader3->XPm1aCntBlk.Address = FadtHeader3->Pm1aCntBlk;\r
421 FadtHeader3->XPmTmrBlk.Address = FadtHeader3->PmTmrBlk;\r
422 FadtHeader3->XGpe0Blk.Address = FadtHeader3->Gpe0Blk;\r
423 }\r
424 break;\r
425 //\r
426 // "FACS" Firmware ACPI Control Structure\r
427 //\r
428 case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:\r
429 break;\r
430 //\r
431 // "SSDT" Secondary System Description Table\r
432 //\r
433 case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
434 break;\r
435 //\r
436 // "HPET" IA-PC High Precision Event Timer Table\r
437 //\r
438 case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:\r
439 //\r
440 // If HPET is disabled in setup, don't publish the table.\r
441 //\r
442 if (mGlobalNvsArea.Area->HpetEnable == 0) {\r
443 *Version = EFI_ACPI_TABLE_VERSION_NONE;\r
444 }\r
445 ((EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) TableHeader)->BaseAddressLower32Bit.Address\r
446 = PcdGet64 (PcdHpetBaseAddress);\r
447 break;\r
448 //\r
449 // "SPCR" Serial Port Concole Redirection Table\r
450 //\r
451 case EFI_ACPI_3_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE:\r
452 break;\r
453 //\r
454 // "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table\r
455 //\r
456 case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:\r
457 AllocationStructurePtr = (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *)\r
458 ((UINT8 *)TableHeader + sizeof(EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER));\r
459 AllocationStructurePtr->BaseAddress = PcdGet64(PcdPciExpressBaseAddress);\r
460 break;\r
461 // Lakeport platform doesn't support the following table\r
462 /*\r
463 //\r
464 // "ECDT" Embedded Controller Boot Resources Table\r
465 //\r
466 case EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE:\r
467 break;\r
468 //\r
469 // "PSDT" Persistent System Description Table\r
470 //\r
471 case EFI_ACPI_3_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
472 break;\r
473 //\r
474 // "SBST" Smart Battery Specification Table\r
475 //\r
476 case EFI_ACPI_3_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE:\r
477 break;\r
478 //\r
479 // "SLIT" System Locality Information Table\r
480 //\r
481 case EFI_ACPI_3_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE:\r
482 break;\r
483 //\r
484 // "SRAT" Static Resource Affinity Table\r
485 //\r
486 case EFI_ACPI_3_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE:\r
487 break;\r
488 //\r
489 // "XSDT" Extended System Description Table\r
490 //\r
491 case EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
492 break;\r
493 //\r
494 // "BOOT" MS Simple Boot Spec\r
495 //\r
496 case EFI_ACPI_3_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE:\r
497 break;\r
498 //\r
499 // "CPEP" Corrected Platform Error Polling Table\r
500 //\r
501 case EFI_ACPI_3_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE:\r
502 break;\r
503 //\r
504 // "DBGP" MS Debug Port Spec\r
505 //\r
506 case EFI_ACPI_3_0_DEBUG_PORT_TABLE_SIGNATURE:\r
507 break;\r
508 //\r
509 // "ETDT" Event Timer Description Table\r
510 //\r
511 case EFI_ACPI_3_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE:\r
512 break;\r
513 //\r
514 // "SPMI" Server Platform Management Interface Table\r
515 //\r
516 case EFI_ACPI_3_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE:\r
517 break;\r
518 //\r
519 // "TCPA" Trusted Computing Platform Alliance Capabilities Table\r
520 //\r
521 case EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE:\r
522 break;\r
523 */\r
524 default:\r
525 break;\r
526 }\r
527 }\r
528}\r
529\r
530//\r
531// Description:\r
532// Entrypoint of Acpi Platform driver\r
533// In:\r
534// ImageHandle\r
535// SystemTable\r
536// Out:\r
537// EFI_SUCCESS\r
538// EFI_LOAD_ERROR\r
539// EFI_OUT_OF_RESOURCES\r
540//\r
541\r
542EFI_STATUS\r
543AcpiPlatformEntryPoint (\r
544 IN EFI_HANDLE ImageHandle,\r
545 IN EFI_SYSTEM_TABLE *SystemTable\r
546 )\r
547{\r
548 EFI_STATUS Status;\r
549 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;\r
550 EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;\r
551 INTN Instance;\r
552 EFI_ACPI_COMMON_HEADER *CurrentTable;\r
553 UINTN TableHandle;\r
554 UINT32 FvStatus;\r
555 UINTN Size;\r
556 EFI_ACPI_TABLE_VERSION Version;\r
b303605e
MK
557 EFI_HANDLE Handle;\r
558 UINTN Index;\r
559 PCI_DEVICE_INFO *PciDeviceInfo;\r
560 EFI_ACPI_HANDLE PciRootHandle;\r
561 BOOLEAN UpdatePRT;\r
562 BOOLEAN UpdatePRW;\r
563 PCI_DEVICE_SETTING *mConfigData;\r
564\r
565 DEBUG((DEBUG_INFO, "ACPI Platform start...\n"));\r
566\r
567 Instance = 0;\r
568 TableHandle = 0;\r
569 CurrentTable = NULL;\r
570 mConfigData = NULL;\r
b303605e
MK
571\r
572 //\r
573 // Initialize the EFI Driver Library\r
574 //\r
575\r
576 ASSERT (sizeof (EFI_GLOBAL_NVS_AREA) == 512);\r
577\r
578 Status = gBS->AllocatePool (\r
579 EfiACPIMemoryNVS,\r
580 sizeof (EFI_GLOBAL_NVS_AREA),\r
581 (VOID**)&mGlobalNvsArea.Area\r
582 );\r
583\r
584 Handle = NULL;\r
585 Status = gBS->InstallProtocolInterface (\r
586 &Handle,\r
587 &gEfiGlobalNvsAreaProtocolGuid,\r
588 EFI_NATIVE_INTERFACE,\r
589 &mGlobalNvsArea\r
590 );\r
591\r
592 ASSERT_EFI_ERROR (Status);\r
593 if (!EFI_ERROR (Status)) {\r
594 SetMem (\r
595 mGlobalNvsArea.Area,\r
596 sizeof (EFI_GLOBAL_NVS_AREA),\r
597 0\r
598 );\r
599 }\r
600\r
601 //\r
602 // Initialize the data. Eventually, this will be controlled by setup options.\r
603 //\r
604 mGlobalNvsArea.Area->HpetEnable = PcdGetBool (PcdHpetEnable);\r
605 mGlobalNvsArea.Area->Pm1blkIoBaseAddress = PcdGet16(PcdPm1blkIoBaseAddress);\r
606 mGlobalNvsArea.Area->PmbaIoBaseAddress = PcdGet16(PcdPmbaIoBaseAddress);\r
607 mGlobalNvsArea.Area->Gpe0blkIoBaseAddress = PcdGet16(PcdGpe0blkIoBaseAddress);\r
608 mGlobalNvsArea.Area->GbaIoBaseAddress = PcdGet16(PcdGbaIoBaseAddress);\r
609 mGlobalNvsArea.Area->SmbaIoBaseAddress = PcdGet16(PcdSmbaIoBaseAddress);\r
610 mGlobalNvsArea.Area->WdtbaIoBaseAddress = PcdGet16(PcdWdtbaIoBaseAddress);\r
611 mGlobalNvsArea.Area->HpetBaseAddress = (UINT32)PcdGet64(PcdHpetBaseAddress);\r
612 mGlobalNvsArea.Area->HpetSize = (UINT32)PcdGet64(PcdHpetSize);\r
613 mGlobalNvsArea.Area->PciExpressBaseAddress= (UINT32)PcdGet64(PcdPciExpressBaseAddress);\r
614 mGlobalNvsArea.Area->PciExpressSize = (UINT32)PcdGet64(PcdPciExpressSize);\r
615 mGlobalNvsArea.Area->RcbaMmioBaseAddress = (UINT32)PcdGet64(PcdRcbaMmioBaseAddress);\r
616 mGlobalNvsArea.Area->RcbaMmioSize = (UINT32)PcdGet64(PcdRcbaMmioSize);\r
617 mGlobalNvsArea.Area->IoApicBaseAddress = (UINT32)PcdGet64(PcdIoApicBaseAddress);\r
618 mGlobalNvsArea.Area->IoApicSize = (UINT32)PcdGet64(PcdIoApicSize);\r
619 mGlobalNvsArea.Area->TpmPresent = (UINT32)(FALSE);\r
620 mGlobalNvsArea.Area->DBG2Present = (UINT32)(FALSE);\r
621 mGlobalNvsArea.Area->PlatformType = (UINT32)PcdGet16 (PcdPlatformType);\r
622\r
623 //\r
624 // Configure platform IO expander I2C Slave Address.\r
625 //\r
626 if (mGlobalNvsArea.Area->PlatformType == Galileo) {\r
627 if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {\r
628 mGlobalNvsArea.Area->AlternateSla = FALSE;\r
629 } else {\r
630 mGlobalNvsArea.Area->AlternateSla = TRUE;\r
631 }\r
632 }\r
633\r
634 //\r
635 // Find the AcpiTable protocol\r
636 //\r
637 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);\r
638 if (EFI_ERROR (Status)) {\r
639 return EFI_ABORTED;\r
640 }\r
641\r
642 //\r
643 // Initialize MADT table\r
644 //\r
645 Status = MadtTableInitialize (&CurrentTable, &Size);\r
646 ASSERT_EFI_ERROR (Status);\r
647 //\r
648 // Perform any table specific updates.\r
649 //\r
650 AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version);\r
651\r
652 //\r
653 // Update the check sum\r
654 // It needs to be zeroed before the checksum calculation\r
655 //\r
656 ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;\r
657 ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum =\r
658 CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);\r
659\r
660 //\r
661 // Add the table\r
662 //\r
663 TableHandle = 0;\r
664 Status = AcpiTable->InstallAcpiTable (\r
665 AcpiTable,\r
666 CurrentTable,\r
667 CurrentTable->Length,\r
668 &TableHandle\r
669 );\r
670 ASSERT_EFI_ERROR (Status);\r
671 CurrentTable = NULL;\r
672\r
673 //\r
674 // Init Pci Device PRT PRW information structure from PCD\r
675 //\r
676 mConfigData = (PCI_DEVICE_SETTING *)AllocateZeroPool (sizeof (PCI_DEVICE_SETTING));\r
74e00be5 677 ASSERT (mConfigData != NULL);\r
b303605e
MK
678 InitPciDeviceInfoStructure (mConfigData);\r
679 //\r
680 // Get the Acpi SDT protocol for manipulation on acpi table\r
681 //\r
682 Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&mAcpiSdt);\r
683 ASSERT_EFI_ERROR (Status);\r
684 //\r
685 // Locate the firmware volume protocol\r
686 //\r
687 Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol, 1);\r
688 if (EFI_ERROR (Status)) {\r
689 return EFI_ABORTED;\r
690 }\r
691 //\r
692 // Read tables from the storage file.\r
693 //\r
694\r
695 while (Status == EFI_SUCCESS) {\r
696\r
697 Status = FwVol->ReadSection (\r
698 FwVol,\r
699 (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),\r
700 EFI_SECTION_RAW,\r
701 Instance,\r
702 (VOID**)&CurrentTable,\r
703 &Size,\r
704 &FvStatus\r
705 );\r
706\r
707 if (!EFI_ERROR(Status)) {\r
708 //\r
709 // Perform any table specific updates.\r
710 //\r
711 AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version);\r
712\r
713 //\r
714 // Update the check sum\r
715 // It needs to be zeroed before the checksum calculation\r
716 //\r
717 ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;\r
718 ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum =\r
719 CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);\r
720\r
721 //\r
722 // Add the table\r
723 //\r
724 TableHandle = 0;\r
725 Status = AcpiTable->InstallAcpiTable (\r
726 AcpiTable,\r
727 CurrentTable,\r
728 ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length,\r
729 &TableHandle\r
730 );\r
731 if (EFI_ERROR(Status)) {\r
732 return EFI_ABORTED;\r
733 }\r
734 //\r
735 // If this table is the DSDT table, then update the _PRT and _PRW based on\r
736 // the settings from pcds\r
737 //\r
738 if (CurrentTable->Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {\r
739 //\r
740 // Create the root handle for DSDT table\r
741 //\r
742 Status = mAcpiSdt->OpenSdt (TableHandle, &mDsdtHandle);\r
743 ASSERT_EFI_ERROR (Status);\r
744\r
745 PciRootHandle = NULL;\r
746 PciRootHandle = SdtGetRootBridgeHandle (mAcpiSdt, mDsdtHandle);\r
747 ASSERT (PciRootHandle != NULL);\r
748\r
749 PciDeviceInfo = NULL;\r
750 for (Index = 0; Index < mConfigData->PciDeviceInfoNumber; Index++) {\r
751 PciDeviceInfo = &(mConfigData->PciDeviceInfo[Index]);\r
752\r
753 //\r
754 // Check whether this is a valid item\r
755 //\r
756 if ((PciDeviceInfo->BridgeAddress != 0xFFFFFFFF) && (PciDeviceInfo->DeviceAddress != 0xFFFFFFFF)) {\r
757\r
758 //DEBUG ((EFI_D_ERROR, "Valid pci info structure: bridge address:0x%x, device address:0x%x\n", PciDeviceInfo->BridgeAddress, PciDeviceInfo->DeviceAddress));\r
759\r
760 UpdatePRT = FALSE;\r
761 UpdatePRW = FALSE;\r
762\r
763 SdtCheckPciDeviceInfoChanged (PciDeviceInfo, &UpdatePRT, &UpdatePRW);\r
764 //\r
765 // Check whether there is any valid pci routing item\r
766 //\r
767 if (UpdatePRT) {\r
768 //\r
769 // Update the pci routing information\r
770 //\r
771 //DEBUG ((EFI_D_ERROR, "Update _PRT\n"));\r
772 SdtUpdatePciRouting (mAcpiSdt, PciRootHandle, PciDeviceInfo);\r
773 }\r
774 //\r
775 // Check whether there is any valid pci routing item\r
776 //\r
777 if (UpdatePRW) {\r
778 //\r
779 // Update the pci wakeup information\r
780 //\r
781 //DEBUG ((EFI_D_ERROR, "Update _PRW\n"));\r
782 SdtUpdatePowerWake (mAcpiSdt, PciRootHandle, PciDeviceInfo);\r
783 }\r
784 }\r
785 }\r
786 Status = mAcpiSdt->Close (PciRootHandle);\r
787 ASSERT_EFI_ERROR (Status);\r
788 //\r
789 // Mark the root handle as modified , let SDT protocol recaculate the checksum\r
790 //\r
791 ((EFI_AML_HANDLE *)mDsdtHandle)->Modified = TRUE;\r
792 Status = mAcpiSdt->Close (mDsdtHandle);\r
793 ASSERT_EFI_ERROR (Status);\r
794 }\r
795 //\r
796 // Increment the instance\r
797 //\r
798 Instance++;\r
799 CurrentTable = NULL;\r
800 }\r
801 }\r
802\r
803 gBS->FreePool (mConfigData);\r
804 return EFI_SUCCESS;\r
805}\r