Changes for V4 ============== 1) Move delete of QuarkSocPkg\QuarkNorthCluster\Binary\QuarkMicrocode from QuarkPlatformPkg commit to QuarkSocPkg commit 2) Fix incorrect license header in PlatformSecLibModStrs.uni Changes for V3 ============== 1) Set PcdResetOnMemoryTypeInformationChange FALSE in QuarkMin.dsc This is required because QuarkMin.dsc uses the emulated variable driver that does not preserve any non-volatile UEFI variables across reset. If the condition is met where the memory type information variable needs to be updated, then the system will reset every time the UEFI Shell is run. By setting this PCD to FALSE, then reset action is disabled. 2) Move one binary file to QuarkSocBinPkg 3) Change RMU.bin FILE statements to INF statement in DSC FD region to be compatible with PACKAGES_PATH search for QuarkSocBinPkg Changes for V2 ============== 1) Use new generic PCI serial driver PciSioSerialDxe in MdeModulePkg 2) Configure PcdPciSerialParameters for PCI serial driver for Quark 3) Use new MtrrLib API to reduce time to set MTRRs for all DRAM 4) Convert all UNI files to utf-8 5) Replace tabs with spaces and remove trailing spaces 6) Add License.txt Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Michael Kinney <michael.d.kinney@intel.com> Acked-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19287 6f19259b-4bc3-4df7-8a09-765794883524
816 lines
26 KiB
C
816 lines
26 KiB
C
/** @file
|
|
ACPI Platform Driver
|
|
|
|
Copyright (c) 2013-2015 Intel Corporation.
|
|
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
#include <Protocol/AcpiTable.h>
|
|
#include <IndustryStandard/Pci22.h>
|
|
#include "AcpiPlatform.h"
|
|
|
|
//
|
|
// Global Variable
|
|
//
|
|
EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea;
|
|
EFI_ACPI_SDT_PROTOCOL *mAcpiSdt;
|
|
|
|
EFI_ACPI_HANDLE mDsdtHandle = NULL;
|
|
|
|
|
|
EFI_STATUS
|
|
LocateSupportProtocol (
|
|
IN EFI_GUID *Protocol,
|
|
OUT VOID **Instance,
|
|
IN UINT32 Type
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Locate the first instance of a protocol. If the protocol requested is an
|
|
FV protocol, then it will return the first FV that contains the ACPI table
|
|
storage file.
|
|
|
|
Arguments:
|
|
|
|
Protocol The protocol to find.
|
|
Instance Return pointer to the first instance of the protocol
|
|
|
|
Returns:
|
|
|
|
EFI_SUCCESS The function completed successfully.
|
|
EFI_NOT_FOUND The protocol could not be located.
|
|
EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE *HandleBuffer;
|
|
UINTN NumberOfHandles;
|
|
EFI_FV_FILETYPE FileType;
|
|
UINT32 FvStatus;
|
|
EFI_FV_FILE_ATTRIBUTES Attributes;
|
|
UINTN Size;
|
|
UINTN i;
|
|
|
|
FvStatus = 0;
|
|
|
|
//
|
|
// Locate protocol.
|
|
//
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
Protocol,
|
|
NULL,
|
|
&NumberOfHandles,
|
|
&HandleBuffer
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
//
|
|
// Defined errors at this time are not found and out of resources.
|
|
//
|
|
return Status;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Looking for FV with ACPI storage file
|
|
//
|
|
|
|
for (i = 0; i < NumberOfHandles; i++) {
|
|
//
|
|
// Get the protocol on this handle
|
|
// This should not fail because of LocateHandleBuffer
|
|
//
|
|
Status = gBS->HandleProtocol (
|
|
HandleBuffer[i],
|
|
Protocol,
|
|
Instance
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
if (!Type) {
|
|
//
|
|
// Not looking for the FV protocol, so find the first instance of the
|
|
// protocol. There should not be any errors because our handle buffer
|
|
// should always contain at least one or LocateHandleBuffer would have
|
|
// returned not found.
|
|
//
|
|
break;
|
|
}
|
|
|
|
//
|
|
// See if it has the ACPI storage file
|
|
//
|
|
|
|
Status = ((EFI_FIRMWARE_VOLUME2_PROTOCOL*) (*Instance))->ReadFile (*Instance,
|
|
(EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
|
|
NULL,
|
|
&Size,
|
|
&FileType,
|
|
&Attributes,
|
|
&FvStatus
|
|
);
|
|
|
|
//
|
|
// If we found it, then we are done
|
|
//
|
|
if (Status == EFI_SUCCESS) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Our exit status is determined by the success of the previous operations
|
|
// If the protocol was found, Instance already points to it.
|
|
//
|
|
|
|
//
|
|
// Free any allocated buffers
|
|
//
|
|
gBS->FreePool (HandleBuffer);
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
VOID
|
|
DsdtTableUpdate (
|
|
IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader,
|
|
IN OUT EFI_ACPI_TABLE_VERSION *Version
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Update the DSDT table
|
|
|
|
Arguments:
|
|
|
|
Table - The table to be set
|
|
Version - Version to publish
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
|
|
UINT8 *CurrPtr;
|
|
UINT8 *DsdtPointer;
|
|
UINT32 *Signature;
|
|
UINT8 *Operation;
|
|
UINT32 *Address;
|
|
UINT16 *Size;
|
|
//
|
|
// Loop through the ASL looking for values that we must fix up.
|
|
//
|
|
CurrPtr = (UINT8 *) TableHeader;
|
|
for (DsdtPointer = CurrPtr;
|
|
DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length);
|
|
DsdtPointer++
|
|
)
|
|
{
|
|
Signature = (UINT32 *) DsdtPointer;
|
|
switch (*Signature) {
|
|
//
|
|
// MNVS operation region
|
|
//
|
|
case (SIGNATURE_32 ('M', 'N', 'V', 'S')):
|
|
//
|
|
// Conditional match. For Region Objects, the Operator will always be the
|
|
// byte immediately before the specific name. Therefore, subtract 1 to check
|
|
// the Operator.
|
|
//
|
|
Operation = DsdtPointer - 1;
|
|
if (*Operation == AML_OPREGION_OP) {
|
|
Address = (UINT32 *) (DsdtPointer + 6);
|
|
*Address = (UINT32) (UINTN) mGlobalNvsArea.Area;
|
|
Size = (UINT16 *) (DsdtPointer + 11);
|
|
*Size = sizeof (EFI_GLOBAL_NVS_AREA);
|
|
}
|
|
break;
|
|
|
|
//
|
|
// Update processor PBLK register I/O base address
|
|
//
|
|
case (SIGNATURE_32 ('P', 'R', 'I', 'O')):
|
|
//
|
|
// Conditional match. Update the following ASL code:
|
|
// Processor (CPU0, 0x01, 0x4F495250, 0x06) {}
|
|
// The 3rd parameter will be updated to the actual PBLK I/O base address.
|
|
// the Operator.
|
|
//
|
|
Operation = DsdtPointer - 8;
|
|
if ((*Operation == AML_EXT_OP) && (*(Operation + 1) == AML_EXT_PROCESSOR_OP)) {
|
|
*(UINT32 *)DsdtPointer = PcdGet16(PcdPmbaIoBaseAddress);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
ApicTableUpdate (
|
|
IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader,
|
|
IN OUT EFI_ACPI_TABLE_VERSION *Version
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Update the processors information in the APIC table
|
|
|
|
Arguments:
|
|
|
|
Table - The table to be set
|
|
Version - Version to publish
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_MP_SERVICES_PROTOCOL *MpService;
|
|
UINT8 *CurrPtr;
|
|
UINT8 *EndPtr;
|
|
UINT8 CurrIoApic;
|
|
UINT8 CurrProcessor;
|
|
UINTN NumberOfCPUs;
|
|
UINTN NumberOfEnabledCPUs;
|
|
UINTN BufferSize;
|
|
EFI_PROCESSOR_INFORMATION MpContext;
|
|
ACPI_APIC_STRUCTURE_PTR *ApicPtr;
|
|
|
|
CurrIoApic = 0;
|
|
CurrProcessor = 0;
|
|
//
|
|
// Find the MP Protocol. This is an MP platform, so MP protocol must be
|
|
// there.
|
|
//
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiMpServiceProtocolGuid,
|
|
NULL,
|
|
(VOID**)&MpService
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
//
|
|
// Failed to get MP information, doesn't publish the invalid table
|
|
//
|
|
*Version = EFI_ACPI_TABLE_VERSION_NONE;
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Determine the number of processors
|
|
//
|
|
MpService->GetNumberOfProcessors (
|
|
MpService,
|
|
&NumberOfCPUs,
|
|
&NumberOfEnabledCPUs
|
|
);
|
|
|
|
CurrPtr = (UINT8*) &(TableHeader[1]);
|
|
CurrPtr = CurrPtr + 8; // Size of Local APIC Address & Flag
|
|
EndPtr = (UINT8*) TableHeader;
|
|
EndPtr = EndPtr + TableHeader->Length;
|
|
|
|
while (CurrPtr < EndPtr) {
|
|
|
|
ApicPtr = (ACPI_APIC_STRUCTURE_PTR*) CurrPtr;
|
|
switch (ApicPtr->AcpiApicCommon.Type) {
|
|
|
|
case EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC:
|
|
BufferSize = sizeof (EFI_PROCESSOR_INFORMATION);
|
|
ApicPtr->AcpiLocalApic.Flags = 0;
|
|
ApicPtr->AcpiLocalApic.ApicId = 0;
|
|
Status = MpService->GetProcessorInfo (
|
|
MpService,
|
|
CurrProcessor,
|
|
&MpContext
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
if (MpContext.StatusFlag & PROCESSOR_ENABLED_BIT) {
|
|
ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_3_0_LOCAL_APIC_ENABLED;
|
|
}
|
|
ApicPtr->AcpiLocalApic.ApicId = (UINT8)MpContext.ProcessorId;
|
|
}
|
|
CurrProcessor++;
|
|
break;
|
|
|
|
case EFI_ACPI_1_0_IO_APIC:
|
|
//
|
|
// IO APIC entries can be patched here
|
|
//
|
|
if (CurrIoApic == 0) {
|
|
//
|
|
// Update SOC internel IOAPIC base
|
|
//
|
|
ApicPtr->AcpiIoApic.IoApicId = PcdGet8 (PcdIoApicSettingIoApicId);
|
|
ApicPtr->AcpiIoApic.IoApicAddress = (UINT32)PcdGet64(PcdIoApicBaseAddress);
|
|
ApicPtr->AcpiIoApic.GlobalSystemInterruptBase = 0;
|
|
} else {
|
|
//
|
|
// Porting is required to update other IOAPIC entries if available
|
|
//
|
|
ASSERT (0);
|
|
}
|
|
CurrIoApic++;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
};
|
|
CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
AcpiUpdateTable (
|
|
IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader,
|
|
IN OUT EFI_ACPI_TABLE_VERSION *Version
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Set the correct table revision upon the setup value
|
|
|
|
Arguments:
|
|
|
|
Table - The table to be set
|
|
Version - Version to publish
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader1;
|
|
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader2;
|
|
EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader3;
|
|
EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *AllocationStructurePtr;
|
|
|
|
if (TableHeader != NULL && Version != NULL) {
|
|
|
|
*Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
|
|
//
|
|
// Here we use all 3.0 signature because all version use same signature if they supported
|
|
//
|
|
switch (TableHeader->Signature) {
|
|
//
|
|
// "APIC" Multiple APIC Description Table
|
|
//
|
|
case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
|
|
ApicTableUpdate (TableHeader, Version);
|
|
break;
|
|
//
|
|
// "DSDT" Differentiated System Description Table
|
|
//
|
|
case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
|
|
DsdtTableUpdate (TableHeader, Version);
|
|
break;
|
|
|
|
//
|
|
// "FACP" Fixed ACPI Description Table (FADT)
|
|
//
|
|
case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
|
|
*Version = EFI_ACPI_TABLE_VERSION_NONE;
|
|
if (TableHeader->Revision == EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
|
|
*Version = EFI_ACPI_TABLE_VERSION_1_0B;
|
|
FadtHeader1 = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader;
|
|
FadtHeader1->SmiCmd = PcdGet16(PcdSmmActivationPort);
|
|
FadtHeader1->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress);
|
|
FadtHeader1->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C;
|
|
FadtHeader1->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T;
|
|
FadtHeader1->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress);
|
|
} else if (TableHeader->Revision == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
|
|
*Version = EFI_ACPI_TABLE_VERSION_2_0;
|
|
FadtHeader2 = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader;
|
|
FadtHeader2->SmiCmd = PcdGet16(PcdSmmActivationPort);
|
|
FadtHeader2->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress);
|
|
FadtHeader2->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C;
|
|
FadtHeader2->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T;
|
|
FadtHeader2->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress);
|
|
FadtHeader2->XPm1aEvtBlk.Address = FadtHeader2->Pm1aEvtBlk;
|
|
FadtHeader2->XPm1aCntBlk.Address = FadtHeader2->Pm1aCntBlk;
|
|
FadtHeader2->XPmTmrBlk.Address = FadtHeader2->PmTmrBlk;
|
|
FadtHeader2->XGpe0Blk.Address = FadtHeader2->Gpe0Blk;
|
|
} else if (TableHeader->Revision == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
|
|
*Version = EFI_ACPI_TABLE_VERSION_3_0;
|
|
FadtHeader3 = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader;
|
|
FadtHeader3->SmiCmd = PcdGet16(PcdSmmActivationPort);
|
|
FadtHeader3->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress);
|
|
FadtHeader3->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C;
|
|
FadtHeader3->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T;
|
|
FadtHeader3->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress);
|
|
FadtHeader3->XPm1aEvtBlk.Address = FadtHeader3->Pm1aEvtBlk;
|
|
FadtHeader3->XPm1aCntBlk.Address = FadtHeader3->Pm1aCntBlk;
|
|
FadtHeader3->XPmTmrBlk.Address = FadtHeader3->PmTmrBlk;
|
|
FadtHeader3->XGpe0Blk.Address = FadtHeader3->Gpe0Blk;
|
|
}
|
|
break;
|
|
//
|
|
// "FACS" Firmware ACPI Control Structure
|
|
//
|
|
case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:
|
|
break;
|
|
//
|
|
// "SSDT" Secondary System Description Table
|
|
//
|
|
case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
|
|
break;
|
|
//
|
|
// "HPET" IA-PC High Precision Event Timer Table
|
|
//
|
|
case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
|
|
//
|
|
// If HPET is disabled in setup, don't publish the table.
|
|
//
|
|
if (mGlobalNvsArea.Area->HpetEnable == 0) {
|
|
*Version = EFI_ACPI_TABLE_VERSION_NONE;
|
|
}
|
|
((EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) TableHeader)->BaseAddressLower32Bit.Address
|
|
= PcdGet64 (PcdHpetBaseAddress);
|
|
break;
|
|
//
|
|
// "SPCR" Serial Port Concole Redirection Table
|
|
//
|
|
case EFI_ACPI_3_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE:
|
|
break;
|
|
//
|
|
// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table
|
|
//
|
|
case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
|
|
AllocationStructurePtr = (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *)
|
|
((UINT8 *)TableHeader + sizeof(EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER));
|
|
AllocationStructurePtr->BaseAddress = PcdGet64(PcdPciExpressBaseAddress);
|
|
break;
|
|
// Lakeport platform doesn't support the following table
|
|
/*
|
|
//
|
|
// "ECDT" Embedded Controller Boot Resources Table
|
|
//
|
|
case EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE:
|
|
break;
|
|
//
|
|
// "PSDT" Persistent System Description Table
|
|
//
|
|
case EFI_ACPI_3_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
|
|
break;
|
|
//
|
|
// "SBST" Smart Battery Specification Table
|
|
//
|
|
case EFI_ACPI_3_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE:
|
|
break;
|
|
//
|
|
// "SLIT" System Locality Information Table
|
|
//
|
|
case EFI_ACPI_3_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE:
|
|
break;
|
|
//
|
|
// "SRAT" Static Resource Affinity Table
|
|
//
|
|
case EFI_ACPI_3_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE:
|
|
break;
|
|
//
|
|
// "XSDT" Extended System Description Table
|
|
//
|
|
case EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
|
|
break;
|
|
//
|
|
// "BOOT" MS Simple Boot Spec
|
|
//
|
|
case EFI_ACPI_3_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE:
|
|
break;
|
|
//
|
|
// "CPEP" Corrected Platform Error Polling Table
|
|
//
|
|
case EFI_ACPI_3_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE:
|
|
break;
|
|
//
|
|
// "DBGP" MS Debug Port Spec
|
|
//
|
|
case EFI_ACPI_3_0_DEBUG_PORT_TABLE_SIGNATURE:
|
|
break;
|
|
//
|
|
// "ETDT" Event Timer Description Table
|
|
//
|
|
case EFI_ACPI_3_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE:
|
|
break;
|
|
//
|
|
// "SPMI" Server Platform Management Interface Table
|
|
//
|
|
case EFI_ACPI_3_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE:
|
|
break;
|
|
//
|
|
// "TCPA" Trusted Computing Platform Alliance Capabilities Table
|
|
//
|
|
case EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE:
|
|
break;
|
|
*/
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Description:
|
|
// Entrypoint of Acpi Platform driver
|
|
// In:
|
|
// ImageHandle
|
|
// SystemTable
|
|
// Out:
|
|
// EFI_SUCCESS
|
|
// EFI_LOAD_ERROR
|
|
// EFI_OUT_OF_RESOURCES
|
|
//
|
|
|
|
EFI_STATUS
|
|
AcpiPlatformEntryPoint (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
|
|
EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
|
|
INTN Instance;
|
|
EFI_ACPI_COMMON_HEADER *CurrentTable;
|
|
UINTN TableHandle;
|
|
UINT32 FvStatus;
|
|
UINTN Size;
|
|
EFI_ACPI_TABLE_VERSION Version;
|
|
QNC_DEVICE_ENABLES QNCDeviceEnables;
|
|
EFI_HANDLE Handle;
|
|
UINTN Index;
|
|
PCI_DEVICE_INFO *PciDeviceInfo;
|
|
EFI_ACPI_HANDLE PciRootHandle;
|
|
BOOLEAN UpdatePRT;
|
|
BOOLEAN UpdatePRW;
|
|
PCI_DEVICE_SETTING *mConfigData;
|
|
|
|
DEBUG((DEBUG_INFO, "ACPI Platform start...\n"));
|
|
|
|
Instance = 0;
|
|
TableHandle = 0;
|
|
CurrentTable = NULL;
|
|
mConfigData = NULL;
|
|
QNCDeviceEnables.Uint32 = PcdGet32 (PcdDeviceEnables);
|
|
|
|
//
|
|
// Initialize the EFI Driver Library
|
|
//
|
|
|
|
ASSERT (sizeof (EFI_GLOBAL_NVS_AREA) == 512);
|
|
|
|
Status = gBS->AllocatePool (
|
|
EfiACPIMemoryNVS,
|
|
sizeof (EFI_GLOBAL_NVS_AREA),
|
|
(VOID**)&mGlobalNvsArea.Area
|
|
);
|
|
|
|
Handle = NULL;
|
|
Status = gBS->InstallProtocolInterface (
|
|
&Handle,
|
|
&gEfiGlobalNvsAreaProtocolGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
&mGlobalNvsArea
|
|
);
|
|
|
|
ASSERT_EFI_ERROR (Status);
|
|
if (!EFI_ERROR (Status)) {
|
|
SetMem (
|
|
mGlobalNvsArea.Area,
|
|
sizeof (EFI_GLOBAL_NVS_AREA),
|
|
0
|
|
);
|
|
}
|
|
|
|
//
|
|
// Initialize the data. Eventually, this will be controlled by setup options.
|
|
//
|
|
mGlobalNvsArea.Area->HpetEnable = PcdGetBool (PcdHpetEnable);
|
|
mGlobalNvsArea.Area->Pm1blkIoBaseAddress = PcdGet16(PcdPm1blkIoBaseAddress);
|
|
mGlobalNvsArea.Area->PmbaIoBaseAddress = PcdGet16(PcdPmbaIoBaseAddress);
|
|
mGlobalNvsArea.Area->Gpe0blkIoBaseAddress = PcdGet16(PcdGpe0blkIoBaseAddress);
|
|
mGlobalNvsArea.Area->GbaIoBaseAddress = PcdGet16(PcdGbaIoBaseAddress);
|
|
mGlobalNvsArea.Area->SmbaIoBaseAddress = PcdGet16(PcdSmbaIoBaseAddress);
|
|
mGlobalNvsArea.Area->WdtbaIoBaseAddress = PcdGet16(PcdWdtbaIoBaseAddress);
|
|
mGlobalNvsArea.Area->HpetBaseAddress = (UINT32)PcdGet64(PcdHpetBaseAddress);
|
|
mGlobalNvsArea.Area->HpetSize = (UINT32)PcdGet64(PcdHpetSize);
|
|
mGlobalNvsArea.Area->PciExpressBaseAddress= (UINT32)PcdGet64(PcdPciExpressBaseAddress);
|
|
mGlobalNvsArea.Area->PciExpressSize = (UINT32)PcdGet64(PcdPciExpressSize);
|
|
mGlobalNvsArea.Area->RcbaMmioBaseAddress = (UINT32)PcdGet64(PcdRcbaMmioBaseAddress);
|
|
mGlobalNvsArea.Area->RcbaMmioSize = (UINT32)PcdGet64(PcdRcbaMmioSize);
|
|
mGlobalNvsArea.Area->IoApicBaseAddress = (UINT32)PcdGet64(PcdIoApicBaseAddress);
|
|
mGlobalNvsArea.Area->IoApicSize = (UINT32)PcdGet64(PcdIoApicSize);
|
|
mGlobalNvsArea.Area->TpmPresent = (UINT32)(FALSE);
|
|
mGlobalNvsArea.Area->DBG2Present = (UINT32)(FALSE);
|
|
mGlobalNvsArea.Area->PlatformType = (UINT32)PcdGet16 (PcdPlatformType);
|
|
|
|
//
|
|
// Configure platform IO expander I2C Slave Address.
|
|
//
|
|
if (mGlobalNvsArea.Area->PlatformType == Galileo) {
|
|
if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
|
|
mGlobalNvsArea.Area->AlternateSla = FALSE;
|
|
} else {
|
|
mGlobalNvsArea.Area->AlternateSla = TRUE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Find the AcpiTable protocol
|
|
//
|
|
Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_ABORTED;
|
|
}
|
|
|
|
//
|
|
// Initialize MADT table
|
|
//
|
|
Status = MadtTableInitialize (&CurrentTable, &Size);
|
|
ASSERT_EFI_ERROR (Status);
|
|
//
|
|
// Perform any table specific updates.
|
|
//
|
|
AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version);
|
|
|
|
//
|
|
// Update the check sum
|
|
// It needs to be zeroed before the checksum calculation
|
|
//
|
|
((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;
|
|
((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum =
|
|
CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);
|
|
|
|
//
|
|
// Add the table
|
|
//
|
|
TableHandle = 0;
|
|
Status = AcpiTable->InstallAcpiTable (
|
|
AcpiTable,
|
|
CurrentTable,
|
|
CurrentTable->Length,
|
|
&TableHandle
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
CurrentTable = NULL;
|
|
|
|
//
|
|
// Init Pci Device PRT PRW information structure from PCD
|
|
//
|
|
mConfigData = (PCI_DEVICE_SETTING *)AllocateZeroPool (sizeof (PCI_DEVICE_SETTING));
|
|
ASSERT_EFI_ERROR (mConfigData);
|
|
InitPciDeviceInfoStructure (mConfigData);
|
|
//
|
|
// Get the Acpi SDT protocol for manipulation on acpi table
|
|
//
|
|
Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&mAcpiSdt);
|
|
ASSERT_EFI_ERROR (Status);
|
|
//
|
|
// Locate the firmware volume protocol
|
|
//
|
|
Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol, 1);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_ABORTED;
|
|
}
|
|
//
|
|
// Read tables from the storage file.
|
|
//
|
|
|
|
while (Status == EFI_SUCCESS) {
|
|
|
|
Status = FwVol->ReadSection (
|
|
FwVol,
|
|
(EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
|
|
EFI_SECTION_RAW,
|
|
Instance,
|
|
(VOID**)&CurrentTable,
|
|
&Size,
|
|
&FvStatus
|
|
);
|
|
|
|
if (!EFI_ERROR(Status)) {
|
|
//
|
|
// Perform any table specific updates.
|
|
//
|
|
AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version);
|
|
|
|
//
|
|
// Update the check sum
|
|
// It needs to be zeroed before the checksum calculation
|
|
//
|
|
((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;
|
|
((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum =
|
|
CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);
|
|
|
|
//
|
|
// Add the table
|
|
//
|
|
TableHandle = 0;
|
|
Status = AcpiTable->InstallAcpiTable (
|
|
AcpiTable,
|
|
CurrentTable,
|
|
((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length,
|
|
&TableHandle
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
return EFI_ABORTED;
|
|
}
|
|
//
|
|
// If this table is the DSDT table, then update the _PRT and _PRW based on
|
|
// the settings from pcds
|
|
//
|
|
if (CurrentTable->Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
|
|
//
|
|
// Create the root handle for DSDT table
|
|
//
|
|
Status = mAcpiSdt->OpenSdt (TableHandle, &mDsdtHandle);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
PciRootHandle = NULL;
|
|
PciRootHandle = SdtGetRootBridgeHandle (mAcpiSdt, mDsdtHandle);
|
|
ASSERT (PciRootHandle != NULL);
|
|
|
|
PciDeviceInfo = NULL;
|
|
for (Index = 0; Index < mConfigData->PciDeviceInfoNumber; Index++) {
|
|
PciDeviceInfo = &(mConfigData->PciDeviceInfo[Index]);
|
|
|
|
//
|
|
// Check whether this is a valid item
|
|
//
|
|
if ((PciDeviceInfo->BridgeAddress != 0xFFFFFFFF) && (PciDeviceInfo->DeviceAddress != 0xFFFFFFFF)) {
|
|
|
|
//DEBUG ((EFI_D_ERROR, "Valid pci info structure: bridge address:0x%x, device address:0x%x\n", PciDeviceInfo->BridgeAddress, PciDeviceInfo->DeviceAddress));
|
|
|
|
UpdatePRT = FALSE;
|
|
UpdatePRW = FALSE;
|
|
|
|
SdtCheckPciDeviceInfoChanged (PciDeviceInfo, &UpdatePRT, &UpdatePRW);
|
|
//
|
|
// Check whether there is any valid pci routing item
|
|
//
|
|
if (UpdatePRT) {
|
|
//
|
|
// Update the pci routing information
|
|
//
|
|
//DEBUG ((EFI_D_ERROR, "Update _PRT\n"));
|
|
SdtUpdatePciRouting (mAcpiSdt, PciRootHandle, PciDeviceInfo);
|
|
}
|
|
//
|
|
// Check whether there is any valid pci routing item
|
|
//
|
|
if (UpdatePRW) {
|
|
//
|
|
// Update the pci wakeup information
|
|
//
|
|
//DEBUG ((EFI_D_ERROR, "Update _PRW\n"));
|
|
SdtUpdatePowerWake (mAcpiSdt, PciRootHandle, PciDeviceInfo);
|
|
}
|
|
}
|
|
}
|
|
Status = mAcpiSdt->Close (PciRootHandle);
|
|
ASSERT_EFI_ERROR (Status);
|
|
//
|
|
// Mark the root handle as modified , let SDT protocol recaculate the checksum
|
|
//
|
|
((EFI_AML_HANDLE *)mDsdtHandle)->Modified = TRUE;
|
|
Status = mAcpiSdt->Close (mDsdtHandle);
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
//
|
|
// Increment the instance
|
|
//
|
|
Instance++;
|
|
CurrentTable = NULL;
|
|
}
|
|
}
|
|
|
|
gBS->FreePool (mConfigData);
|
|
return EFI_SUCCESS;
|
|
}
|