/** @file * Multiple APIC Description Table (MADT) * * Copyright (c) 2018, ARM Limited. All rights reserved. * * 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 #include #include #include #include "N1SdpAcpiHeader.h" #include "N1SdpPlatform.h" #define CORES (FixedPcdGet32 (PcdClusterCount) * \ FixedPcdGet32 (PcdCoreCount)) // EFI_ACPI_6_1_GIC_STRUCTURE #define EFI_ACPI_6_1_GICC_STRUCTURE_INIT(GicId, AcpiCpuUid, Mpidr, Flags, \ PmuIrq, GicBase, GicVBase, GicHBase, GsivId, GicRBase, Efficiency) \ { \ EFI_ACPI_6_1_GIC, /* Type */ \ sizeof (EFI_ACPI_6_1_GIC_STRUCTURE), /* Length */ \ EFI_ACPI_RESERVED_WORD, /* Reserved */ \ GicId, /* CPUInterfaceNumber */ \ AcpiCpuUid, /* AcpiProcessorUid */ \ Flags, /* Flags */ \ 0, /* ParkingProtocolVersion */ \ PmuIrq, /* PerformanceInterruptGsiv */ \ 0, /* ParkedAddress */ \ GicBase, /* PhysicalBaseAddress */ \ GicVBase, /* GICV */ \ GicHBase, /* GICH */ \ GsivId, /* VGICMaintenanceInterrupt */ \ GicRBase, /* GICRBaseAddress */ \ Mpidr, /* MPIDR */ \ Efficiency, /* ProcessorPowerEfficiencyClass */ \ { \ EFI_ACPI_RESERVED_BYTE, /* Reserved2[0] */ \ EFI_ACPI_RESERVED_BYTE, /* Reserved2[1] */ \ EFI_ACPI_RESERVED_BYTE /* Reserved2[2] */ \ } \ } // EFI_ACPI_6_1_GIC_DISTRIBUTOR_STRUCTURE #define EFI_ACPI_6_1_GIC_DISTRIBUTOR_INIT(GicDistHwId, GicDistBase, \ GicDistVector, GicVersion) \ { \ EFI_ACPI_6_1_GICD, /* Type */ \ sizeof (EFI_ACPI_6_1_GIC_DISTRIBUTOR_STRUCTURE), \ EFI_ACPI_RESERVED_WORD, /* Reserved1 */ \ GicDistHwId, /* GicId */ \ GicDistBase, /* PhysicalBaseAddress */ \ GicDistVector, /* SystemVectorBase */ \ GicVersion, /* GicVersion */ \ { \ EFI_ACPI_RESERVED_BYTE, /* Reserved2[0] */ \ EFI_ACPI_RESERVED_BYTE, /* Reserved2[1] */ \ EFI_ACPI_RESERVED_BYTE, /* Reserved2[2] */ \ } \ } // EFI_ACPI_6_1_GICR_STRUCTURE #define EFI_ACPI_6_1_GIC_REDISTRIBUTOR_INIT(RedisRegionAddr, RedisDiscLength) \ { \ EFI_ACPI_6_1_GICR, /* Type */ \ sizeof (EFI_ACPI_6_1_GICR_STRUCTURE), /* Length */ \ EFI_ACPI_RESERVED_WORD, /* Reserved */ \ RedisRegionAddr, /* DiscoveryRangeBaseAddress */ \ RedisDiscLength /* DiscoveryRangeLength */ \ } // EFI_ACPI_6_1_GIC_ITS_STRUCTURE #define EFI_ACPI_6_1_GIC_ITS_INIT(GicItsId, GicItsBase) \ { \ EFI_ACPI_6_1_GIC_ITS, /* Type */ \ sizeof (EFI_ACPI_6_1_GIC_ITS_STRUCTURE), \ EFI_ACPI_RESERVED_WORD, /* Reserved */ \ GicItsId, /* GicItsId */ \ GicItsBase, /* PhysicalBaseAddress */ \ EFI_ACPI_RESERVED_DWORD, /* DiscoveryRangeLength */ \ } // // Multiple APIC Description Table // #pragma pack (1) typedef struct { EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER Header; EFI_ACPI_6_1_GIC_STRUCTURE GicInterfaces[CORES]; EFI_ACPI_6_1_GIC_DISTRIBUTOR_STRUCTURE GicDistributor; EFI_ACPI_6_1_GICR_STRUCTURE GicRedistributor; EFI_ACPI_6_1_GIC_ITS_STRUCTURE GicIts; } EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE; #pragma pack () STATIC EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE Madt = { { ARM_ACPI_HEADER ( EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE, EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION ), // MADT specific fields 0, // LocalApicAddress 0, // Flags }, { // Format: EFI_ACPI_6_1_GICC_STRUCTURE_INIT(GicId, AcpiCpuUid, Mpidr, Flags, // PmuIrq, GicBase, GicVBase, // GicHBase, GsivId, GicRBase, // Efficiency) // Note: The GIC Structure of the primary CPU must be the first entry // (see note in 5.2.12.14 GICC Structure of ACPI v6.1). EFI_ACPI_6_1_GICC_STRUCTURE_INIT( // Ares-0 0, 0, GET_MPID(0x0, 0x0), EFI_ACPI_6_1_GIC_ENABLED, 23, FixedPcdGet32 (PcdGicDistributorBase), 0x2c020000, 0x2c010000, 25, 0 /* GicRBase */, 0 /* Efficiency */), EFI_ACPI_6_1_GICC_STRUCTURE_INIT( // Ares-1 0, 1, GET_MPID(0x0, 0x100), EFI_ACPI_6_1_GIC_ENABLED, 23, FixedPcdGet32 (PcdGicDistributorBase), 0x2c020000, 0x2c010000, 25, 0 /* GicRBase */, 0 /* Efficiency */), EFI_ACPI_6_1_GICC_STRUCTURE_INIT( // Ares-2 0, 2, GET_MPID(0x100, 0x0), EFI_ACPI_6_1_GIC_ENABLED, 23, FixedPcdGet32 (PcdGicDistributorBase), 0x2c020000, 0x2c010000, 25, 0 /* GicRBase */, 0 /* Efficiency */), EFI_ACPI_6_1_GICC_STRUCTURE_INIT( // Ares-3 0, 3, GET_MPID(0x100, 0x100), EFI_ACPI_6_1_GIC_ENABLED, 23, FixedPcdGet32 (PcdGicDistributorBase), 0x2c020000, 0x2c010000, 25, 0 /* GicRBase */, 0 /* Efficiency */), }, // GIC Distributor Entry EFI_ACPI_6_1_GIC_DISTRIBUTOR_INIT(0, FixedPcdGet32 (PcdGicDistributorBase), 0, 3), // GIC Redistributor EFI_ACPI_6_1_GIC_REDISTRIBUTOR_INIT(FixedPcdGet32 (PcdGicRedistributorsBase), SIZE_1MB), // GIC ITS EFI_ACPI_6_1_GIC_ITS_INIT(0, 0x300A0000), }; // // Reference the table being generated to prevent the optimizer from removing // the data structure from the executable // VOID* CONST ReferenceAcpiTable = &Madt;