/** @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; }