summaryrefslogtreecommitdiff
path: root/Silicon/AMD/Styx/AcpiTables/Gtdt.c
blob: 139c9ae0baad2dae924ae62b788626399e02b826 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/** @file

  Generic Timer Description Table (GTDT)

  Copyright (c) 2012 - 2014, ARM Ltd. All rights reserved.<BR>
  Copyright (c) 2014 - 2016, AMD Inc. All rights reserved.<BR>

  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.

**/
/**

  Derived from:
   ArmPlatformPkg/ArmJunoPkg/AcpiTables/Gtdt.aslc

**/

#include <AmdStyxAcpiLib.h>

#pragma pack(push, 1)

#define CNT_CONTROL_BASE_ADDRESS      FixedPcdGet64(PcdCntControlBase)
#define CNT_READ_BASE_ADDRESS         FixedPcdGet64(PcdCntReadBase)
#define CNT_CTL_BASE_ADDRESS          FixedPcdGet64(PcdCntCTLBase)
#define CNT_BASE0_ADDRESS             FixedPcdGet64(PcdCntBase0)
#define CNT_EL0_BASE0_ADDRESS         FixedPcdGet64(PcdCntEL0Base0)
#define SBSA_WATCHDOG_REFRESH_BASE    FixedPcdGet64(PcdSbsaWatchDogRefreshBase)
#define SBSA_WATCHDOG_CONTROL_BASE    FixedPcdGet64(PcdSbsaWatchDogControlBase)
#define SBSA_WAKEUP_GSIV              FixedPcdGet64(PcdSbsaWakeUpGSIV)
#define SBSA_WATCHDOG_GSIV            FixedPcdGet64(PcdSbsaWatchDogGSIV)


/*
 * Section 8.2.3 of Cortex-A15 r2p1 TRM
 */
#define CP15_TIMER_SEC_INTR    29
#define CP15_TIMER_NS_INTR     30
#define CP15_TIMER_VIRT_INTR   27
#define CP15_TIMER_NSHYP_INTR  26

/* SBSA Timers */
  #define PLATFORM_TIMER_COUNT          2
  #define PLATFORM_TIMER_OFFSET         sizeof (EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE)

/*
// GTDT Table timer flags.

Bit 0: Timer interrupt Mode
  This bit indicates the mode of the timer interrupt
    1: Interrupt is Edge triggered
    0: Interrupt is Level triggered
Timer Interrupt polarity
  This bit indicates the polarity of the timer interrupt
    1: Interrupt is Active low
    0: Interrupt is Active high
Reserved 2 30 Reserved, must be zero.

From A15 TRM:
   9.2 Generic Timer functional description
    ...
    Each timer provides an active-LOW interrupt output that is an external pin to the SoC and is
    sent to the GIC as a Private Peripheral Interrupt (PPI). See Interrupt sources on page 8-4 for
    the ID and PPI allocation of the Timer interrupts.
      PPI6 Virtual Maintenance Interrupt.
      PPI5 Hypervisor timer event.
      PPI4 Virtual timer event.
      PPI3 nIRQ.
      PPI2 Non-secure physical timer event.
      PPI1 Secure physical timer event.
      PPI0-5 Active-LOW level-sensitive.
      PPI6 Active-HIGH level-sensitive.*/

#define GTDT_TIMER_EDGE_TRIGGERED   EFI_ACPI_5_1_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE
#define GTDT_TIMER_LEVEL_TRIGGERED  0
#define GTDT_TIMER_ACTIVE_LOW       EFI_ACPI_5_1_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY
#define GTDT_TIMER_ACTIVE_HIGH      0
#define GTDT_TIMER_SECURE           EFI_ACPI_5_1_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY
#define GTDT_TIMER_NON_SECURE       0
#define GTDT_GTIMER_FLAGS           (GTDT_TIMER_NON_SECURE | GTDT_TIMER_ACTIVE_HIGH | GTDT_TIMER_LEVEL_TRIGGERED)

#define GTX_TIMER_EDGE_TRIGGERED    EFI_ACPI_5_1_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE
#define GTX_TIMER_LEVEL_TRIGGERED   0
#define GTX_TIMER_ACTIVE_LOW        EFI_ACPI_5_1_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY
#define GTX_TIMER_ACTIVE_HIGH       0
#define GTX_TIMER_FLAGS             (GTX_TIMER_ACTIVE_HIGH | GTX_TIMER_LEVEL_TRIGGERED)

#define GTX_TIMER_SECURE            EFI_ACPI_5_1_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER
#define GTX_TIMER_NON_SECURE        0
#define GTX_TIMER_SAVE_CONTEXT      EFI_ACPI_5_1_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY
#define GTX_TIMER_LOSE_CONTEXT      0
#define GTX_COMMON_FLAGS            (GTX_TIMER_SAVE_CONTEXT | GTX_TIMER_NON_SECURE)

#define SBSA_WATCHDOG_EDGE_TRIGGERED   EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE
#define SBSA_WATCHDOG_LEVEL_TRIGGERED  0
#define SBSA_WATCHDOG_ACTIVE_LOW       EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY
#define SBSA_WATCHDOG_ACTIVE_HIGH      0
#define SBSA_WATCHDOG_SECURE           EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_SECURE_TIMER
#define SBSA_WATCHDOG_NON_SECURE       0
#define SBSA_WATCHDOG_FLAGS            (SBSA_WATCHDOG_NON_SECURE | SBSA_WATCHDOG_ACTIVE_HIGH | SBSA_WATCHDOG_LEVEL_TRIGGERED)


#define AMD_SBSA_GTX {                                                                     \
   EFI_ACPI_5_1_GTDT_GT_BLOCK,                           /* UINT8  Type */                 \
   sizeof (EFI_ACPI_5_1_GTDT_GT_BLOCK_STRUCTURE) +                                         \
   sizeof (EFI_ACPI_5_1_GTDT_GT_BLOCK_TIMER_STRUCTURE),  /* UINT16 Length */               \
   EFI_ACPI_RESERVED_BYTE,                               /* UINT8  Reserved */             \
   CNT_CTL_BASE_ADDRESS,                                 /* UINT64 CntCtlBase */           \
   1,                                                    /* UINT32 GTBlockTimerCount */    \
   sizeof (EFI_ACPI_5_1_GTDT_GT_BLOCK_STRUCTURE)         /* UINT32 GTBlockTimerOffset */   \
  }

#define AMD_SBSA_GTX_TIMER {                                                                  \
   0,                                                    /* UINT8  GTFrameNumber */           \
   {0, 0, 0},                                            /* UINT8  Reserved[3] */             \
   CNT_BASE0_ADDRESS,                                    /* UINT64 CntBaseX */                \
   CNT_EL0_BASE0_ADDRESS,                                /* UINT64 CntEL0BaseX */             \
   SBSA_WAKEUP_GSIV,                                     /* UINT32 GTxPhysicalTimerGSIV */    \
   GTX_TIMER_FLAGS,                                      /* UINT32 GTxPhysicalTimerFlags */   \
   0,                                                    /* UINT32 GTxVirtualTimerGSIV */     \
   GTX_TIMER_FLAGS,                                      /* UINT32 GTxVirtualTimerFlags */    \
   GTX_COMMON_FLAGS                                      /* UINT32 GTxCommonFlags */          \
  }

#define AMD_SBSA_WATCHDOG {                                                                                        \
   EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG,                     /* UINT8  Type */                                  \
   sizeof (EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE),  /* UINT16 Length */                                \
   EFI_ACPI_RESERVED_BYTE,                                      /* UINT8  Reserved */                              \
   SBSA_WATCHDOG_REFRESH_BASE,                                  /* UINT64 RefreshFramePhysicalAddress */           \
   SBSA_WATCHDOG_CONTROL_BASE,                                  /* UINT64 WatchdogControlFramePhysicalAddress */   \
   SBSA_WATCHDOG_GSIV,                                          /* UINT32 WatchdogTimerGSIV */                     \
   SBSA_WATCHDOG_FLAGS                                          /* UINT32 WatchdogTimerFlags */                    \
  }

typedef struct {
  EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE      Gtdt;
  EFI_ACPI_5_1_GTDT_GT_BLOCK_STRUCTURE              GTxBlock;
  EFI_ACPI_5_1_GTDT_GT_BLOCK_TIMER_STRUCTURE        GTxTimer;
  EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE WatchDog;
} AMD_ACPI_5_1_ARM_GTDT_STRUCTURE;

STATIC AMD_ACPI_5_1_ARM_GTDT_STRUCTURE AcpiGtdt = {
  {
    AMD_ACPI_HEADER(EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
                    AMD_ACPI_5_1_ARM_GTDT_STRUCTURE,
                    EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION),
    CNT_CONTROL_BASE_ADDRESS,     // UINT64  PhysicalAddress
    0,                            // UINT32  Reserved
    CP15_TIMER_SEC_INTR,          // UINT32  SecureEL1TimerGSIV
    GTDT_GTIMER_FLAGS,            // UINT32  SecureEL1TimerFlags
    CP15_TIMER_NS_INTR,           // UINT32  NonSecureEL1TimerGSIV
    GTDT_GTIMER_FLAGS,            // UINT32  NonSecureEL1TimerFlags
    CP15_TIMER_VIRT_INTR,         // UINT32  VirtualTimerGSIV
    GTDT_GTIMER_FLAGS,            // UINT32  VirtualTimerFlags
    CP15_TIMER_NSHYP_INTR,        // UINT32  NonSecureEL2TimerGSIV
    GTDT_GTIMER_FLAGS,            // UINT32  NonSecureEL2TimerFlags
    CNT_READ_BASE_ADDRESS,        // UINT64  CntReadBaseAddress
    PLATFORM_TIMER_COUNT,         // UINT32  PlatformTimerCount
    PLATFORM_TIMER_OFFSET         // UINT32  PlatformTimerOffset
  },
  AMD_SBSA_GTX,
  AMD_SBSA_GTX_TIMER,
  AMD_SBSA_WATCHDOG,
};

#pragma pack(pop)


EFI_ACPI_DESCRIPTION_HEADER *
GtdtHeader (
  VOID
  )
{
  UINT32 CpuId = PcdGet32 (PcdSocCpuId);

  // Check BaseModel and Stepping: Styx-B0 or prior?
  if (((CpuId & 0xFF0) == 0) || ((CpuId & 0x00F) == 0)) {
    AcpiGtdt.Gtdt.Header.Length = sizeof (EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE);
    AcpiGtdt.Gtdt.PlatformTimerCount = 0;
    AcpiGtdt.Gtdt.PlatformTimerOffset = 0;
  }

  return (EFI_ACPI_DESCRIPTION_HEADER *) &AcpiGtdt.Gtdt.Header;
}