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