1 /** @file 2 3 Generic Timer Description Table (GTDT) 4 5 Copyright (c) 2012 - 2014, ARM Ltd. All rights reserved.<BR> 6 Copyright (c) 2014 - 2016, AMD Inc. All rights reserved.<BR> 7 8 This program and the accompanying materials 9 are licensed and made available under the terms and conditions of the BSD License 10 which accompanies this distribution. The full text of the license may be found at 11 http://opensource.org/licenses/bsd-license.php 12 13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 15 16 **/ 17 /** 18 19 Derived from: 20 ArmPlatformPkg/ArmJunoPkg/AcpiTables/Gtdt.aslc 21 22 **/ 23 24 #include <AmdStyxAcpiLib.h> 25 26 #pragma pack(push, 1) 27 28 #define CNT_CONTROL_BASE_ADDRESS FixedPcdGet64(PcdCntControlBase) 29 #define CNT_READ_BASE_ADDRESS FixedPcdGet64(PcdCntReadBase) 30 #define CNT_CTL_BASE_ADDRESS FixedPcdGet64(PcdCntCTLBase) 31 #define CNT_BASE0_ADDRESS FixedPcdGet64(PcdCntBase0) 32 #define CNT_EL0_BASE0_ADDRESS FixedPcdGet64(PcdCntEL0Base0) 33 #define SBSA_WATCHDOG_REFRESH_BASE FixedPcdGet64(PcdSbsaWatchDogRefreshBase) 34 #define SBSA_WATCHDOG_CONTROL_BASE FixedPcdGet64(PcdSbsaWatchDogControlBase) 35 #define SBSA_WAKEUP_GSIV FixedPcdGet64(PcdSbsaWakeUpGSIV) 36 #define SBSA_WATCHDOG_GSIV FixedPcdGet64(PcdSbsaWatchDogGSIV) 37 38 39 /* 40 * Section 8.2.3 of Cortex-A15 r2p1 TRM 41 */ 42 #define CP15_TIMER_SEC_INTR 29 43 #define CP15_TIMER_NS_INTR 30 44 #define CP15_TIMER_VIRT_INTR 27 45 #define CP15_TIMER_NSHYP_INTR 26 46 47 /* SBSA Timers */ 48 #define PLATFORM_TIMER_COUNT 2 49 #define PLATFORM_TIMER_OFFSET sizeof (EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE) 50 51 /* 52 // GTDT Table timer flags. 53 54 Bit 0: Timer interrupt Mode 55 This bit indicates the mode of the timer interrupt 56 1: Interrupt is Edge triggered 57 0: Interrupt is Level triggered 58 Timer Interrupt polarity 59 This bit indicates the polarity of the timer interrupt 60 1: Interrupt is Active low 61 0: Interrupt is Active high 62 Reserved 2 30 Reserved, must be zero. 63 64 From A15 TRM: 65 9.2 Generic Timer functional description 66 ... 67 Each timer provides an active-LOW interrupt output that is an external pin to the SoC and is 68 sent to the GIC as a Private Peripheral Interrupt (PPI). See Interrupt sources on page 8-4 for 69 the ID and PPI allocation of the Timer interrupts. 70 PPI6 Virtual Maintenance Interrupt. 71 PPI5 Hypervisor timer event. 72 PPI4 Virtual timer event. 73 PPI3 nIRQ. 74 PPI2 Non-secure physical timer event. 75 PPI1 Secure physical timer event. 76 PPI0-5 Active-LOW level-sensitive. 77 PPI6 Active-HIGH level-sensitive.*/ 78 79 #define GTDT_TIMER_EDGE_TRIGGERED EFI_ACPI_5_1_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE 80 #define GTDT_TIMER_LEVEL_TRIGGERED 0 81 #define GTDT_TIMER_ACTIVE_LOW EFI_ACPI_5_1_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY 82 #define GTDT_TIMER_ACTIVE_HIGH 0 83 #define GTDT_TIMER_SECURE EFI_ACPI_5_1_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY 84 #define GTDT_TIMER_NON_SECURE 0 85 #define GTDT_GTIMER_FLAGS (GTDT_TIMER_NON_SECURE | GTDT_TIMER_ACTIVE_HIGH | GTDT_TIMER_LEVEL_TRIGGERED) 86 87 #define GTX_TIMER_EDGE_TRIGGERED EFI_ACPI_5_1_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE 88 #define GTX_TIMER_LEVEL_TRIGGERED 0 89 #define GTX_TIMER_ACTIVE_LOW EFI_ACPI_5_1_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY 90 #define GTX_TIMER_ACTIVE_HIGH 0 91 #define GTX_TIMER_FLAGS (GTX_TIMER_ACTIVE_HIGH | GTX_TIMER_LEVEL_TRIGGERED) 92 93 #define GTX_TIMER_SECURE EFI_ACPI_5_1_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER 94 #define GTX_TIMER_NON_SECURE 0 95 #define GTX_TIMER_SAVE_CONTEXT EFI_ACPI_5_1_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY 96 #define GTX_TIMER_LOSE_CONTEXT 0 97 #define GTX_COMMON_FLAGS (GTX_TIMER_SAVE_CONTEXT | GTX_TIMER_NON_SECURE) 98 99 #define SBSA_WATCHDOG_EDGE_TRIGGERED EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE 100 #define SBSA_WATCHDOG_LEVEL_TRIGGERED 0 101 #define SBSA_WATCHDOG_ACTIVE_LOW EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY 102 #define SBSA_WATCHDOG_ACTIVE_HIGH 0 103 #define SBSA_WATCHDOG_SECURE EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_SECURE_TIMER 104 #define SBSA_WATCHDOG_NON_SECURE 0 105 #define SBSA_WATCHDOG_FLAGS (SBSA_WATCHDOG_NON_SECURE | SBSA_WATCHDOG_ACTIVE_HIGH | SBSA_WATCHDOG_LEVEL_TRIGGERED) 106 107 108 #define AMD_SBSA_GTX { \ 109 EFI_ACPI_5_1_GTDT_GT_BLOCK, /* UINT8 Type */ \ 110 sizeof (EFI_ACPI_5_1_GTDT_GT_BLOCK_STRUCTURE) + \ 111 sizeof (EFI_ACPI_5_1_GTDT_GT_BLOCK_TIMER_STRUCTURE), /* UINT16 Length */ \ 112 EFI_ACPI_RESERVED_BYTE, /* UINT8 Reserved */ \ 113 CNT_CTL_BASE_ADDRESS, /* UINT64 CntCtlBase */ \ 114 1, /* UINT32 GTBlockTimerCount */ \ 115 sizeof (EFI_ACPI_5_1_GTDT_GT_BLOCK_STRUCTURE) /* UINT32 GTBlockTimerOffset */ \ 116 } 117 118 #define AMD_SBSA_GTX_TIMER { \ 119 0, /* UINT8 GTFrameNumber */ \ 120 {0, 0, 0}, /* UINT8 Reserved[3] */ \ 121 CNT_BASE0_ADDRESS, /* UINT64 CntBaseX */ \ 122 CNT_EL0_BASE0_ADDRESS, /* UINT64 CntEL0BaseX */ \ 123 SBSA_WAKEUP_GSIV, /* UINT32 GTxPhysicalTimerGSIV */ \ 124 GTX_TIMER_FLAGS, /* UINT32 GTxPhysicalTimerFlags */ \ 125 0, /* UINT32 GTxVirtualTimerGSIV */ \ 126 GTX_TIMER_FLAGS, /* UINT32 GTxVirtualTimerFlags */ \ 127 GTX_COMMON_FLAGS /* UINT32 GTxCommonFlags */ \ 128 } 129 130 #define AMD_SBSA_WATCHDOG { \ 131 EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG, /* UINT8 Type */ \ 132 sizeof (EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE), /* UINT16 Length */ \ 133 EFI_ACPI_RESERVED_BYTE, /* UINT8 Reserved */ \ 134 SBSA_WATCHDOG_REFRESH_BASE, /* UINT64 RefreshFramePhysicalAddress */ \ 135 SBSA_WATCHDOG_CONTROL_BASE, /* UINT64 WatchdogControlFramePhysicalAddress */ \ 136 SBSA_WATCHDOG_GSIV, /* UINT32 WatchdogTimerGSIV */ \ 137 SBSA_WATCHDOG_FLAGS /* UINT32 WatchdogTimerFlags */ \ 138 } 139 140 typedef struct { 141 EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE Gtdt; 142 EFI_ACPI_5_1_GTDT_GT_BLOCK_STRUCTURE GTxBlock; 143 EFI_ACPI_5_1_GTDT_GT_BLOCK_TIMER_STRUCTURE GTxTimer; 144 EFI_ACPI_5_1_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE WatchDog; 145 } AMD_ACPI_5_1_ARM_GTDT_STRUCTURE; 146 147 STATIC AMD_ACPI_5_1_ARM_GTDT_STRUCTURE AcpiGtdt = { 148 { 149 AMD_ACPI_HEADER(EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, 150 AMD_ACPI_5_1_ARM_GTDT_STRUCTURE, 151 EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION), 152 CNT_CONTROL_BASE_ADDRESS, // UINT64 PhysicalAddress 153 0, // UINT32 Reserved 154 CP15_TIMER_SEC_INTR, // UINT32 SecureEL1TimerGSIV 155 GTDT_GTIMER_FLAGS, // UINT32 SecureEL1TimerFlags 156 CP15_TIMER_NS_INTR, // UINT32 NonSecureEL1TimerGSIV 157 GTDT_GTIMER_FLAGS, // UINT32 NonSecureEL1TimerFlags 158 CP15_TIMER_VIRT_INTR, // UINT32 VirtualTimerGSIV 159 GTDT_GTIMER_FLAGS, // UINT32 VirtualTimerFlags 160 CP15_TIMER_NSHYP_INTR, // UINT32 NonSecureEL2TimerGSIV 161 GTDT_GTIMER_FLAGS, // UINT32 NonSecureEL2TimerFlags 162 CNT_READ_BASE_ADDRESS, // UINT64 CntReadBaseAddress 163 PLATFORM_TIMER_COUNT, // UINT32 PlatformTimerCount 164 PLATFORM_TIMER_OFFSET // UINT32 PlatformTimerOffset 165 }, 166 AMD_SBSA_GTX, 167 AMD_SBSA_GTX_TIMER, 168 AMD_SBSA_WATCHDOG, 169 }; 170 171 #pragma pack(pop) 172 173 174 EFI_ACPI_DESCRIPTION_HEADER * 175 GtdtHeader ( 176 VOID 177 ) 178 { 179 UINT32 CpuId = PcdGet32 (PcdSocCpuId); 180 181 // Check BaseModel and Stepping: Styx-B0 or prior? 182 if (((CpuId & 0xFF0) == 0) || ((CpuId & 0x00F) == 0)) { 183 AcpiGtdt.Gtdt.Header.Length = sizeof (EFI_ACPI_5_1_GENERIC_TIMER_DESCRIPTION_TABLE); 184 AcpiGtdt.Gtdt.PlatformTimerCount = 0; 185 AcpiGtdt.Gtdt.PlatformTimerOffset = 0; 186 } 187 188 return (EFI_ACPI_DESCRIPTION_HEADER *) &AcpiGtdt.Gtdt.Header; 189 } 190