• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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//
131VOID* CONST ReferenceAcpiTable = &Madt;
132