1 /** @file 2 ACPI Platform Driver 3 4 Copyright (c) 2013-2015 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 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 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 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 UINTN BufferSize; 259 EFI_PROCESSOR_INFORMATION MpContext; 260 ACPI_APIC_STRUCTURE_PTR *ApicPtr; 261 262 CurrIoApic = 0; 263 CurrProcessor = 0; 264 // 265 // Find the MP Protocol. This is an MP platform, so MP protocol must be 266 // there. 267 // 268 Status = gBS->LocateProtocol ( 269 &gEfiMpServiceProtocolGuid, 270 NULL, 271 (VOID**)&MpService 272 ); 273 if (EFI_ERROR (Status)) { 274 // 275 // Failed to get MP information, doesn't publish the invalid table 276 // 277 *Version = EFI_ACPI_TABLE_VERSION_NONE; 278 return; 279 } 280 281 // 282 // Determine the number of processors 283 // 284 MpService->GetNumberOfProcessors ( 285 MpService, 286 &NumberOfCPUs, 287 &NumberOfEnabledCPUs 288 ); 289 290 CurrPtr = (UINT8*) &(TableHeader[1]); 291 CurrPtr = CurrPtr + 8; // Size of Local APIC Address & Flag 292 EndPtr = (UINT8*) TableHeader; 293 EndPtr = EndPtr + TableHeader->Length; 294 295 while (CurrPtr < EndPtr) { 296 297 ApicPtr = (ACPI_APIC_STRUCTURE_PTR*) CurrPtr; 298 switch (ApicPtr->AcpiApicCommon.Type) { 299 300 case EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC: 301 BufferSize = sizeof (EFI_PROCESSOR_INFORMATION); 302 ApicPtr->AcpiLocalApic.Flags = 0; 303 ApicPtr->AcpiLocalApic.ApicId = 0; 304 Status = MpService->GetProcessorInfo ( 305 MpService, 306 CurrProcessor, 307 &MpContext 308 ); 309 310 if (!EFI_ERROR (Status)) { 311 if (MpContext.StatusFlag & PROCESSOR_ENABLED_BIT) { 312 ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_3_0_LOCAL_APIC_ENABLED; 313 } 314 ApicPtr->AcpiLocalApic.ApicId = (UINT8)MpContext.ProcessorId; 315 } 316 CurrProcessor++; 317 break; 318 319 case EFI_ACPI_1_0_IO_APIC: 320 // 321 // IO APIC entries can be patched here 322 // 323 if (CurrIoApic == 0) { 324 // 325 // Update SOC internel IOAPIC base 326 // 327 ApicPtr->AcpiIoApic.IoApicId = PcdGet8 (PcdIoApicSettingIoApicId); 328 ApicPtr->AcpiIoApic.IoApicAddress = (UINT32)PcdGet64(PcdIoApicBaseAddress); 329 ApicPtr->AcpiIoApic.GlobalSystemInterruptBase = 0; 330 } else { 331 // 332 // Porting is required to update other IOAPIC entries if available 333 // 334 ASSERT (0); 335 } 336 CurrIoApic++; 337 break; 338 339 default: 340 break; 341 }; 342 CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length; 343 } 344 } 345 346 VOID 347 AcpiUpdateTable ( 348 IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader, 349 IN OUT EFI_ACPI_TABLE_VERSION *Version 350 ) 351 /*++ 352 353 Routine Description: 354 355 Set the correct table revision upon the setup value 356 357 Arguments: 358 359 Table - The table to be set 360 Version - Version to publish 361 362 Returns: 363 364 None 365 366 --*/ 367 368 { 369 EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader1; 370 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader2; 371 EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader3; 372 EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *AllocationStructurePtr; 373 374 if (TableHeader != NULL && Version != NULL) { 375 376 *Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0; 377 // 378 // Here we use all 3.0 signature because all version use same signature if they supported 379 // 380 switch (TableHeader->Signature) { 381 // 382 // "APIC" Multiple APIC Description Table 383 // 384 case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE: 385 ApicTableUpdate (TableHeader, Version); 386 break; 387 // 388 // "DSDT" Differentiated System Description Table 389 // 390 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: 391 DsdtTableUpdate (TableHeader, Version); 392 break; 393 394 // 395 // "FACP" Fixed ACPI Description Table (FADT) 396 // 397 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE: 398 *Version = EFI_ACPI_TABLE_VERSION_NONE; 399 if (TableHeader->Revision == EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) { 400 *Version = EFI_ACPI_TABLE_VERSION_1_0B; 401 FadtHeader1 = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader; 402 FadtHeader1->SmiCmd = PcdGet16(PcdSmmActivationPort); 403 FadtHeader1->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress); 404 FadtHeader1->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C; 405 FadtHeader1->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T; 406 FadtHeader1->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress); 407 } else if (TableHeader->Revision == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) { 408 *Version = EFI_ACPI_TABLE_VERSION_2_0; 409 FadtHeader2 = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader; 410 FadtHeader2->SmiCmd = PcdGet16(PcdSmmActivationPort); 411 FadtHeader2->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress); 412 FadtHeader2->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C; 413 FadtHeader2->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T; 414 FadtHeader2->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress); 415 FadtHeader2->XPm1aEvtBlk.Address = FadtHeader2->Pm1aEvtBlk; 416 FadtHeader2->XPm1aCntBlk.Address = FadtHeader2->Pm1aCntBlk; 417 FadtHeader2->XPmTmrBlk.Address = FadtHeader2->PmTmrBlk; 418 FadtHeader2->XGpe0Blk.Address = FadtHeader2->Gpe0Blk; 419 } else if (TableHeader->Revision == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) { 420 *Version = EFI_ACPI_TABLE_VERSION_3_0; 421 FadtHeader3 = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader; 422 FadtHeader3->SmiCmd = PcdGet16(PcdSmmActivationPort); 423 FadtHeader3->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress); 424 FadtHeader3->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C; 425 FadtHeader3->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T; 426 FadtHeader3->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress); 427 FadtHeader3->XPm1aEvtBlk.Address = FadtHeader3->Pm1aEvtBlk; 428 FadtHeader3->XPm1aCntBlk.Address = FadtHeader3->Pm1aCntBlk; 429 FadtHeader3->XPmTmrBlk.Address = FadtHeader3->PmTmrBlk; 430 FadtHeader3->XGpe0Blk.Address = FadtHeader3->Gpe0Blk; 431 } 432 break; 433 // 434 // "FACS" Firmware ACPI Control Structure 435 // 436 case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE: 437 break; 438 // 439 // "SSDT" Secondary System Description Table 440 // 441 case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: 442 break; 443 // 444 // "HPET" IA-PC High Precision Event Timer Table 445 // 446 case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE: 447 // 448 // If HPET is disabled in setup, don't publish the table. 449 // 450 if (mGlobalNvsArea.Area->HpetEnable == 0) { 451 *Version = EFI_ACPI_TABLE_VERSION_NONE; 452 } 453 ((EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) TableHeader)->BaseAddressLower32Bit.Address 454 = PcdGet64 (PcdHpetBaseAddress); 455 break; 456 // 457 // "SPCR" Serial Port Concole Redirection Table 458 // 459 case EFI_ACPI_3_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE: 460 break; 461 // 462 // "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table 463 // 464 case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE: 465 AllocationStructurePtr = (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *) 466 ((UINT8 *)TableHeader + sizeof(EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER)); 467 AllocationStructurePtr->BaseAddress = PcdGet64(PcdPciExpressBaseAddress); 468 break; 469 // Lakeport platform doesn't support the following table 470 /* 471 // 472 // "ECDT" Embedded Controller Boot Resources Table 473 // 474 case EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE: 475 break; 476 // 477 // "PSDT" Persistent System Description Table 478 // 479 case EFI_ACPI_3_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: 480 break; 481 // 482 // "SBST" Smart Battery Specification Table 483 // 484 case EFI_ACPI_3_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE: 485 break; 486 // 487 // "SLIT" System Locality Information Table 488 // 489 case EFI_ACPI_3_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE: 490 break; 491 // 492 // "SRAT" Static Resource Affinity Table 493 // 494 case EFI_ACPI_3_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE: 495 break; 496 // 497 // "XSDT" Extended System Description Table 498 // 499 case EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: 500 break; 501 // 502 // "BOOT" MS Simple Boot Spec 503 // 504 case EFI_ACPI_3_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE: 505 break; 506 // 507 // "CPEP" Corrected Platform Error Polling Table 508 // 509 case EFI_ACPI_3_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE: 510 break; 511 // 512 // "DBGP" MS Debug Port Spec 513 // 514 case EFI_ACPI_3_0_DEBUG_PORT_TABLE_SIGNATURE: 515 break; 516 // 517 // "ETDT" Event Timer Description Table 518 // 519 case EFI_ACPI_3_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE: 520 break; 521 // 522 // "SPMI" Server Platform Management Interface Table 523 // 524 case EFI_ACPI_3_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE: 525 break; 526 // 527 // "TCPA" Trusted Computing Platform Alliance Capabilities Table 528 // 529 case EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE: 530 break; 531 */ 532 default: 533 break; 534 } 535 } 536 } 537 538 // 539 // Description: 540 // Entrypoint of Acpi Platform driver 541 // In: 542 // ImageHandle 543 // SystemTable 544 // Out: 545 // EFI_SUCCESS 546 // EFI_LOAD_ERROR 547 // EFI_OUT_OF_RESOURCES 548 // 549 550 EFI_STATUS 551 AcpiPlatformEntryPoint ( 552 IN EFI_HANDLE ImageHandle, 553 IN EFI_SYSTEM_TABLE *SystemTable 554 ) 555 { 556 EFI_STATUS Status; 557 EFI_ACPI_TABLE_PROTOCOL *AcpiTable; 558 EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; 559 INTN Instance; 560 EFI_ACPI_COMMON_HEADER *CurrentTable; 561 UINTN TableHandle; 562 UINT32 FvStatus; 563 UINTN Size; 564 EFI_ACPI_TABLE_VERSION Version; 565 QNC_DEVICE_ENABLES QNCDeviceEnables; 566 EFI_HANDLE Handle; 567 UINTN Index; 568 PCI_DEVICE_INFO *PciDeviceInfo; 569 EFI_ACPI_HANDLE PciRootHandle; 570 BOOLEAN UpdatePRT; 571 BOOLEAN UpdatePRW; 572 PCI_DEVICE_SETTING *mConfigData; 573 574 DEBUG((DEBUG_INFO, "ACPI Platform start...\n")); 575 576 Instance = 0; 577 TableHandle = 0; 578 CurrentTable = NULL; 579 mConfigData = NULL; 580 QNCDeviceEnables.Uint32 = PcdGet32 (PcdDeviceEnables); 581 582 // 583 // Initialize the EFI Driver Library 584 // 585 586 ASSERT (sizeof (EFI_GLOBAL_NVS_AREA) == 512); 587 588 Status = gBS->AllocatePool ( 589 EfiACPIMemoryNVS, 590 sizeof (EFI_GLOBAL_NVS_AREA), 591 (VOID**)&mGlobalNvsArea.Area 592 ); 593 594 Handle = NULL; 595 Status = gBS->InstallProtocolInterface ( 596 &Handle, 597 &gEfiGlobalNvsAreaProtocolGuid, 598 EFI_NATIVE_INTERFACE, 599 &mGlobalNvsArea 600 ); 601 602 ASSERT_EFI_ERROR (Status); 603 if (!EFI_ERROR (Status)) { 604 SetMem ( 605 mGlobalNvsArea.Area, 606 sizeof (EFI_GLOBAL_NVS_AREA), 607 0 608 ); 609 } 610 611 // 612 // Initialize the data. Eventually, this will be controlled by setup options. 613 // 614 mGlobalNvsArea.Area->HpetEnable = PcdGetBool (PcdHpetEnable); 615 mGlobalNvsArea.Area->Pm1blkIoBaseAddress = PcdGet16(PcdPm1blkIoBaseAddress); 616 mGlobalNvsArea.Area->PmbaIoBaseAddress = PcdGet16(PcdPmbaIoBaseAddress); 617 mGlobalNvsArea.Area->Gpe0blkIoBaseAddress = PcdGet16(PcdGpe0blkIoBaseAddress); 618 mGlobalNvsArea.Area->GbaIoBaseAddress = PcdGet16(PcdGbaIoBaseAddress); 619 mGlobalNvsArea.Area->SmbaIoBaseAddress = PcdGet16(PcdSmbaIoBaseAddress); 620 mGlobalNvsArea.Area->WdtbaIoBaseAddress = PcdGet16(PcdWdtbaIoBaseAddress); 621 mGlobalNvsArea.Area->HpetBaseAddress = (UINT32)PcdGet64(PcdHpetBaseAddress); 622 mGlobalNvsArea.Area->HpetSize = (UINT32)PcdGet64(PcdHpetSize); 623 mGlobalNvsArea.Area->PciExpressBaseAddress= (UINT32)PcdGet64(PcdPciExpressBaseAddress); 624 mGlobalNvsArea.Area->PciExpressSize = (UINT32)PcdGet64(PcdPciExpressSize); 625 mGlobalNvsArea.Area->RcbaMmioBaseAddress = (UINT32)PcdGet64(PcdRcbaMmioBaseAddress); 626 mGlobalNvsArea.Area->RcbaMmioSize = (UINT32)PcdGet64(PcdRcbaMmioSize); 627 mGlobalNvsArea.Area->IoApicBaseAddress = (UINT32)PcdGet64(PcdIoApicBaseAddress); 628 mGlobalNvsArea.Area->IoApicSize = (UINT32)PcdGet64(PcdIoApicSize); 629 mGlobalNvsArea.Area->TpmPresent = (UINT32)(FALSE); 630 mGlobalNvsArea.Area->DBG2Present = (UINT32)(FALSE); 631 mGlobalNvsArea.Area->PlatformType = (UINT32)PcdGet16 (PcdPlatformType); 632 633 // 634 // Configure platform IO expander I2C Slave Address. 635 // 636 if (mGlobalNvsArea.Area->PlatformType == Galileo) { 637 if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) { 638 mGlobalNvsArea.Area->AlternateSla = FALSE; 639 } else { 640 mGlobalNvsArea.Area->AlternateSla = TRUE; 641 } 642 } 643 644 // 645 // Find the AcpiTable protocol 646 // 647 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); 648 if (EFI_ERROR (Status)) { 649 return EFI_ABORTED; 650 } 651 652 // 653 // Initialize MADT table 654 // 655 Status = MadtTableInitialize (&CurrentTable, &Size); 656 ASSERT_EFI_ERROR (Status); 657 // 658 // Perform any table specific updates. 659 // 660 AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version); 661 662 // 663 // Update the check sum 664 // It needs to be zeroed before the checksum calculation 665 // 666 ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0; 667 ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 668 CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length); 669 670 // 671 // Add the table 672 // 673 TableHandle = 0; 674 Status = AcpiTable->InstallAcpiTable ( 675 AcpiTable, 676 CurrentTable, 677 CurrentTable->Length, 678 &TableHandle 679 ); 680 ASSERT_EFI_ERROR (Status); 681 CurrentTable = NULL; 682 683 // 684 // Init Pci Device PRT PRW information structure from PCD 685 // 686 mConfigData = (PCI_DEVICE_SETTING *)AllocateZeroPool (sizeof (PCI_DEVICE_SETTING)); 687 ASSERT_EFI_ERROR (mConfigData); 688 InitPciDeviceInfoStructure (mConfigData); 689 // 690 // Get the Acpi SDT protocol for manipulation on acpi table 691 // 692 Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&mAcpiSdt); 693 ASSERT_EFI_ERROR (Status); 694 // 695 // Locate the firmware volume protocol 696 // 697 Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol, 1); 698 if (EFI_ERROR (Status)) { 699 return EFI_ABORTED; 700 } 701 // 702 // Read tables from the storage file. 703 // 704 705 while (Status == EFI_SUCCESS) { 706 707 Status = FwVol->ReadSection ( 708 FwVol, 709 (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile), 710 EFI_SECTION_RAW, 711 Instance, 712 (VOID**)&CurrentTable, 713 &Size, 714 &FvStatus 715 ); 716 717 if (!EFI_ERROR(Status)) { 718 // 719 // Perform any table specific updates. 720 // 721 AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version); 722 723 // 724 // Update the check sum 725 // It needs to be zeroed before the checksum calculation 726 // 727 ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0; 728 ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 729 CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length); 730 731 // 732 // Add the table 733 // 734 TableHandle = 0; 735 Status = AcpiTable->InstallAcpiTable ( 736 AcpiTable, 737 CurrentTable, 738 ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length, 739 &TableHandle 740 ); 741 if (EFI_ERROR(Status)) { 742 return EFI_ABORTED; 743 } 744 // 745 // If this table is the DSDT table, then update the _PRT and _PRW based on 746 // the settings from pcds 747 // 748 if (CurrentTable->Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) { 749 // 750 // Create the root handle for DSDT table 751 // 752 Status = mAcpiSdt->OpenSdt (TableHandle, &mDsdtHandle); 753 ASSERT_EFI_ERROR (Status); 754 755 PciRootHandle = NULL; 756 PciRootHandle = SdtGetRootBridgeHandle (mAcpiSdt, mDsdtHandle); 757 ASSERT (PciRootHandle != NULL); 758 759 PciDeviceInfo = NULL; 760 for (Index = 0; Index < mConfigData->PciDeviceInfoNumber; Index++) { 761 PciDeviceInfo = &(mConfigData->PciDeviceInfo[Index]); 762 763 // 764 // Check whether this is a valid item 765 // 766 if ((PciDeviceInfo->BridgeAddress != 0xFFFFFFFF) && (PciDeviceInfo->DeviceAddress != 0xFFFFFFFF)) { 767 768 //DEBUG ((EFI_D_ERROR, "Valid pci info structure: bridge address:0x%x, device address:0x%x\n", PciDeviceInfo->BridgeAddress, PciDeviceInfo->DeviceAddress)); 769 770 UpdatePRT = FALSE; 771 UpdatePRW = FALSE; 772 773 SdtCheckPciDeviceInfoChanged (PciDeviceInfo, &UpdatePRT, &UpdatePRW); 774 // 775 // Check whether there is any valid pci routing item 776 // 777 if (UpdatePRT) { 778 // 779 // Update the pci routing information 780 // 781 //DEBUG ((EFI_D_ERROR, "Update _PRT\n")); 782 SdtUpdatePciRouting (mAcpiSdt, PciRootHandle, PciDeviceInfo); 783 } 784 // 785 // Check whether there is any valid pci routing item 786 // 787 if (UpdatePRW) { 788 // 789 // Update the pci wakeup information 790 // 791 //DEBUG ((EFI_D_ERROR, "Update _PRW\n")); 792 SdtUpdatePowerWake (mAcpiSdt, PciRootHandle, PciDeviceInfo); 793 } 794 } 795 } 796 Status = mAcpiSdt->Close (PciRootHandle); 797 ASSERT_EFI_ERROR (Status); 798 // 799 // Mark the root handle as modified , let SDT protocol recaculate the checksum 800 // 801 ((EFI_AML_HANDLE *)mDsdtHandle)->Modified = TRUE; 802 Status = mAcpiSdt->Close (mDsdtHandle); 803 ASSERT_EFI_ERROR (Status); 804 } 805 // 806 // Increment the instance 807 // 808 Instance++; 809 CurrentTable = NULL; 810 } 811 } 812 813 gBS->FreePool (mConfigData); 814 return EFI_SUCCESS; 815 } 816