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