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