Home | History | Annotate | Download | only in AcpiTables
      1 /** @file
      2 *  Multiple APIC Description Table (MADT)
      3 *
      4 *  Copyright (c) 2012 - 2016, ARM Limited. All rights reserved.
      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 "ArmPlatform.h"
     17 #include <Library/AcpiLib.h>
     18 #include <Library/ArmLib.h>
     19 #include <Library/PcdLib.h>
     20 #include <IndustryStandard/Acpi.h>
     21 
     22 //
     23 // Multiple APIC Description Table
     24 //
     25 #ifdef ARM_JUNO_ACPI_5_0
     26   #pragma pack (1)
     27 
     28   typedef struct {
     29     EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER   Header;
     30     EFI_ACPI_5_0_GIC_STRUCTURE                            GicInterfaces[FixedPcdGet32 (PcdCoreCount)];
     31     EFI_ACPI_5_0_GIC_DISTRIBUTOR_STRUCTURE                GicDistributor;
     32   } EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE;
     33 
     34   #pragma pack ()
     35 
     36   EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE Madt = {
     37     {
     38       ARM_ACPI_HEADER (
     39         EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
     40         EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE,
     41         EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION
     42       ),
     43       //
     44       // MADT specific fields
     45       //
     46       0, // LocalApicAddress
     47       0, // Flags
     48     },
     49     {
     50       // Format: EFI_ACPI_5_0_GIC_STRUCTURE_INIT(GicId, AcpiCpuId, Flags, PmuIrq, GicBase)
     51       // Note: The GIC Structure of the primary CPU must be the first entry (see note in 5.2.12.14 GIC Structure of
     52       //       ACPI v5.0).
     53       //       On Juno we can change the primary CPU changing the SCC register. It is not currently supported in the
     54       //       Trusted Firmware. When supported, we will need to code to dynamically change the ordering.
     55       //       For now we leave CPU2 (A53-0) at the first position.
     56       //       The cores from a same cluster are kept together. It is not an ACPI requirement but in case the OSPM uses
     57       //       the ACPI ARM Parking protocol, it might want to wake up the cores in the order of this table.
     58       EFI_ACPI_5_0_GIC_STRUCTURE_INIT(2, 0, EFI_ACPI_5_0_GIC_ENABLED, 50, FixedPcdGet64 (PcdGicInterruptInterfaceBase)), // A53-0
     59       EFI_ACPI_5_0_GIC_STRUCTURE_INIT(3, 1, EFI_ACPI_5_0_GIC_ENABLED, 54, FixedPcdGet64 (PcdGicInterruptInterfaceBase)), // A53-1
     60       EFI_ACPI_5_0_GIC_STRUCTURE_INIT(4, 2, EFI_ACPI_5_0_GIC_ENABLED, 58, FixedPcdGet64 (PcdGicInterruptInterfaceBase)), // A53-2
     61       EFI_ACPI_5_0_GIC_STRUCTURE_INIT(5, 3, EFI_ACPI_5_0_GIC_ENABLED, 62, FixedPcdGet64 (PcdGicInterruptInterfaceBase)), // A53-3
     62       EFI_ACPI_5_0_GIC_STRUCTURE_INIT(0, 4, EFI_ACPI_5_0_GIC_ENABLED, 34, FixedPcdGet64 (PcdGicInterruptInterfaceBase)), // A57-0
     63       EFI_ACPI_5_0_GIC_STRUCTURE_INIT(1, 5, EFI_ACPI_5_0_GIC_ENABLED, 38, FixedPcdGet64 (PcdGicInterruptInterfaceBase))  // A57-1
     64     },
     65     EFI_ACPI_5_0_GIC_DISTRIBUTOR_INIT(0, FixedPcdGet64 (PcdGicDistributorBase), 0)
     66   };
     67 #else
     68   #pragma pack (1)
     69 
     70   typedef struct {
     71     EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER   Header;
     72     EFI_ACPI_5_1_GIC_STRUCTURE                            GicInterfaces[FixedPcdGet32 (PcdCoreCount)];
     73     EFI_ACPI_5_1_GIC_DISTRIBUTOR_STRUCTURE                GicDistributor;
     74     EFI_ACPI_6_0_GIC_MSI_FRAME_STRUCTURE                  MsiFrame;
     75   } MULTIPLE_APIC_DESCRIPTION_TABLE;
     76 
     77   #pragma pack ()
     78 
     79   MULTIPLE_APIC_DESCRIPTION_TABLE Madt = {
     80     {
     81       ARM_ACPI_HEADER (
     82         EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
     83         MULTIPLE_APIC_DESCRIPTION_TABLE,
     84         EFI_ACPI_5_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION
     85       ),
     86       //
     87       // MADT specific fields
     88       //
     89       0, // LocalApicAddress
     90       0, // Flags
     91     },
     92     {
     93       // Format: EFI_ACPI_5_1_GICC_STRUCTURE_INIT(GicId, AcpiCpuUid, Flags, PmuIrq, GicBase, GicVBase, GicHBase,
     94       //                                          GsivId, GicRBase, Mpidr)
     95       // Note: The GIC Structure of the primary CPU must be the first entry (see note in 5.2.12.14 GICC Structure of
     96       //       ACPI v5.1).
     97       //       On Juno we can change the primary CPU changing the SCC register. It is not currently supported in the
     98       //       Trusted Firmware. When supported, we will need to code to dynamically change the ordering.
     99       //       For now we leave CPU2 (A53-0) at the first position.
    100       //       The cores from a same cluster are kept together. It is not an ACPI requirement but in case the OSPM uses
    101       //       the ACPI ARM Parking protocol, it might want to wake up the cores in the order of this table.
    102       EFI_ACPI_5_1_GICC_STRUCTURE_INIT( // A53-0
    103           2, 0, GET_MPID(1, 0), EFI_ACPI_5_0_GIC_ENABLED, 50, FixedPcdGet64 (PcdGicInterruptInterfaceBase),
    104           0x2C06F000, 0x2C04F000, 25, 0 /* GicRBase */),
    105       EFI_ACPI_5_1_GICC_STRUCTURE_INIT( // A53-1
    106           3, 1, GET_MPID(1, 1),  EFI_ACPI_5_0_GIC_ENABLED, 54, FixedPcdGet64 (PcdGicInterruptInterfaceBase),
    107           0x2C06F000, 0x2C04F000, 25, 0 /* GicRBase */),
    108       EFI_ACPI_5_1_GICC_STRUCTURE_INIT( // A53-2
    109           4, 2, GET_MPID(1, 2),  EFI_ACPI_5_0_GIC_ENABLED, 58, FixedPcdGet64 (PcdGicInterruptInterfaceBase),
    110           0x2C06F000, 0x2C04F000, 25, 0 /* GicRBase */),
    111       EFI_ACPI_5_1_GICC_STRUCTURE_INIT( // A53-3
    112           5, 3, GET_MPID(1, 3),  EFI_ACPI_5_0_GIC_ENABLED, 62, FixedPcdGet64 (PcdGicInterruptInterfaceBase),
    113           0x2C06F000, 0x2C04F000, 25, 0 /* GicRBase */),
    114       EFI_ACPI_5_1_GICC_STRUCTURE_INIT( // A57-0
    115           0, 4, GET_MPID(0, 0),  EFI_ACPI_5_0_GIC_ENABLED, 34, FixedPcdGet64 (PcdGicInterruptInterfaceBase),
    116           0x2C06F000, 0x2C04F000, 25, 0 /* GicRBase */),
    117       EFI_ACPI_5_1_GICC_STRUCTURE_INIT( // A57-1
    118           1, 5, GET_MPID(0, 1),  EFI_ACPI_5_0_GIC_ENABLED, 38, FixedPcdGet64 (PcdGicInterruptInterfaceBase),
    119           0x2C06F000, 0x2C04F000, 25, 0 /* GicRBase */),
    120     },
    121     EFI_ACPI_6_0_GIC_DISTRIBUTOR_INIT(0, FixedPcdGet64 (PcdGicDistributorBase), 0, 2),
    122     // Format: EFI_ACPI_6_0_GIC_MSI_FRAME_INIT(GicMsiFrameId, PhysicalBaseAddress, Flags, SPICount, SPIBase)
    123     EFI_ACPI_6_0_GIC_MSI_FRAME_INIT(0, ARM_JUNO_GIV2M_MSI_BASE, 0, ARM_JUNO_GIV2M_MSI_SPI_COUNT, ARM_JUNO_GIV2M_MSI_SPI_BASE)
    124   };
    125 #endif
    126 
    127 //
    128 // Reference the table being generated to prevent the optimizer from removing the
    129 // data structure from the executable
    130 //
    131 VOID* CONST ReferenceAcpiTable = &Madt;
    132