/** @file
Sample ACPI Platform Driver
Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.
Copyright (c) 2014 - 2016, AMD Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
/**
Derived from:
MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatform.c
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "AcpiPlatform.h"
STATIC EFI_ACPI_TABLE_PROTOCOL *mAcpiTableProtocol;
STATIC AMD_MP_CORE_INFO_PROTOCOL *mAmdMpCoreInfoProtocol;
STATIC CONST UINT8 mDefaultMacPackageA[] = {
0x12, 0xe, 0x6, 0xa, 0x2, 0xa, 0xa1, 0xa, 0xa2, 0xa, 0xa3, 0xa, 0xa4, 0xa, 0xa5
};
STATIC CONST UINT8 mDefaultMacPackageB[] = {
0x12, 0xe, 0x6, 0xa, 0x2, 0xa, 0xb1, 0xa, 0xb2, 0xa, 0xb3, 0xa, 0xb4, 0xa, 0xb5
};
#define PACKAGE_MAC_OFFSET 4
#define PACKAGE_MAC_INCR 2
STATIC
VOID
SetPackageAddress (
UINT8 *Package,
UINT8 *MacAddress,
UINTN Size
)
{
UINTN Index;
for (Index = PACKAGE_MAC_OFFSET; Index < Size; Index += PACKAGE_MAC_INCR) {
Package[Index] = *MacAddress++;
}
}
STATIC
VOID
PatchAmlPackage (
CONST UINT8 *Pattern,
CONST UINT8 *Replacement,
UINTN PatternLength,
UINT8 *SsdtTable,
UINTN TableSize
)
{
UINTN Offset;
for (Offset = 0; Offset < (TableSize - PatternLength); Offset++) {
if (CompareMem (SsdtTable + Offset, Pattern, PatternLength) == 0) {
CopyMem (SsdtTable + Offset, Replacement, PatternLength);
break;
}
}
}
STATIC
VOID
EnableAvailableCores (
EFI_ACPI_5_1_GIC_STRUCTURE *GicC
)
{
ARM_CORE_INFO *ArmCoreInfoTable;
UINTN CoreCount;
UINTN Index;
CoreCount = 0;
ArmCoreInfoTable = mAmdMpCoreInfoProtocol->GetArmCoreInfoTable (&CoreCount);
ASSERT (ArmCoreInfoTable != NULL);
while (CoreCount--) {
for (Index = 0; Index < MAX_CORES; Index++) {
if (GicC[Index].MPIDR == GET_MPID (ArmCoreInfoTable->ClusterId,
ArmCoreInfoTable->CoreId)) {
GicC[Index].Flags |= EFI_ACPI_5_1_GIC_ENABLED;
break;
}
}
ArmCoreInfoTable++;
}
}
STATIC
VOID
InstallSystemDescriptionTables (
VOID
)
{
EFI_ACPI_DESCRIPTION_HEADER *Table;
EFI_STATUS Status;
UINT32 CpuId;
UINTN Index;
UINTN TableSize;
UINTN TableHandle;
EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE *Gtdt;
EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt;
EFI_ACPI_5_1_GIC_STRUCTURE *GicC;
UINT8 MacPackage[sizeof(mDefaultMacPackageA)];
CpuId = PcdGet32 (PcdSocCpuId);
Status = EFI_SUCCESS;
for (Index = 0; !EFI_ERROR (Status); Index++) {
Status = GetSectionFromFv (&gEfiCallerIdGuid, EFI_SECTION_RAW, Index,
(VOID **) &Table, &TableSize);
if (EFI_ERROR (Status)) {
break;
}
switch (Table->OemTableId) {
case SIGNATURE_64 ('S', 't', 'y', 'x', 'B', '1', ' ', ' '):
if ((CpuId & STYX_SOC_VERSION_MASK) < STYX_SOC_VERSION_B1) {
continue;
}
break;
case SIGNATURE_64 ('S', 't', 'y', 'x', 'X', 'g', 'b', 'e'):
if (!FixedPcdGetBool (PcdXgbeEnable)) {
continue;
}
//
// Patch the SSDT binary with the correct MAC addresses
//
CopyMem (MacPackage, mDefaultMacPackageA, sizeof (MacPackage));
SetPackageAddress (MacPackage, PcdGetPtr (PcdEthMacA), sizeof (MacPackage));
PatchAmlPackage (mDefaultMacPackageA, MacPackage, sizeof (MacPackage),
(UINT8 *)Table, TableSize);
SetPackageAddress (MacPackage, PcdGetPtr (PcdEthMacB), sizeof (MacPackage));
PatchAmlPackage (mDefaultMacPackageB, MacPackage, sizeof (MacPackage),
(UINT8 *)Table, TableSize);
break;
case SIGNATURE_64 ('S', 't', 'y', 'x', 'K', 'c', 's', ' '):
if (!FixedPcdGetBool (PcdEnableKcs) ||
(CpuId & STYX_SOC_VERSION_MASK) < STYX_SOC_VERSION_B1) {
continue;
}
default:
switch (Table->Signature) {
case EFI_ACPI_6_0_IO_REMAPPING_TABLE_SIGNATURE:
if (!PcdGetBool (PcdEnableSmmus)) {
continue;
}
break;
case EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE:
if ((CpuId & STYX_SOC_VERSION_MASK) < STYX_SOC_VERSION_B1) {
Gtdt = (EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE *)Table;
Gtdt->Header.Length = sizeof (*Gtdt);
Gtdt->PlatformTimerCount = 0;
Gtdt->PlatformTimerOffset = 0;
}
break;
case EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
Madt = (EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)Table;
GicC = (EFI_ACPI_5_1_GIC_STRUCTURE *)(Madt + 1);
EnableAvailableCores (GicC);
break;
}
}
Status = mAcpiTableProtocol->InstallAcpiTable (mAcpiTableProtocol, Table,
Table->Length, &TableHandle);
DEBUG ((DEBUG_WARN,
"Installing %c%c%c%c Table (Revision %d, Length %d) ... %r\n",
((UINT8 *)&Table->Signature)[0], ((UINT8 *)&Table->Signature)[1],
((UINT8 *)&Table->Signature)[2], ((UINT8 *)&Table->Signature)[3],
Table->Revision, Table->Length, Status));
FreePool (Table);
}
}
/**
Entrypoint of Acpi Platform driver.
@param ImageHandle
@param SystemTable
@return EFI_SUCCESS
@return EFI_LOAD_ERROR
@return EFI_OUT_OF_RESOURCES
**/
EFI_STATUS
EFIAPI
AcpiPlatformEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
//
// Find the AcpiTable protocol
//
Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL,
(VOID**)&mAcpiTableProtocol);
ASSERT_EFI_ERROR (Status);
Status = gBS->LocateProtocol (&gAmdMpCoreInfoProtocolGuid, NULL,
(VOID**)&mAmdMpCoreInfoProtocol);
ASSERT_EFI_ERROR (Status);
InstallSystemDescriptionTables ();
return EFI_REQUEST_UNLOAD_IMAGE;
}