/** @file
|
* Generic Timer Description Table (GTDT)
|
*
|
* Copyrignt (c) 2020, Linaro Limited. All rights reserved.
|
*
|
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
**/
|
|
#include <Library/AcpiLib.h>
|
#include <Library/PcdLib.h>
|
#include <IndustryStandard/Acpi.h>
|
#include <IndustryStandard/SbsaQemuAcpi.h>
|
|
#define GTDT_GLOBAL_FLAGS_MAPPED EFI_ACPI_5_0_GTDT_GLOBAL_FLAG_MEMORY_MAPPED_BLOCK_PRESENT
|
#define GTDT_GLOBAL_FLAGS_NOT_MAPPED 0
|
#define GTDT_GLOBAL_FLAGS_EDGE EFI_ACPI_5_0_GTDT_GLOBAL_FLAG_INTERRUPT_MODE
|
#define GTDT_GLOBAL_FLAGS_LEVEL 0
|
|
// Note: We could have a build flag that switches between memory mapped/non-memory mapped timer
|
#ifdef SYSTEM_TIMER_BASE_ADDRESS
|
#define GTDT_GLOBAL_FLAGS (GTDT_GLOBAL_FLAGS_MAPPED | GTDT_GLOBAL_FLAGS_LEVEL)
|
#else
|
#define GTDT_GLOBAL_FLAGS (GTDT_GLOBAL_FLAGS_NOT_MAPPED | GTDT_GLOBAL_FLAGS_LEVEL)
|
#define SYSTEM_TIMER_BASE_ADDRESS 0xFFFFFFFFFFFFFFFF
|
#endif
|
|
#define GTDT_TIMER_EDGE_TRIGGERED EFI_ACPI_6_3_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE
|
#define GTDT_TIMER_LEVEL_TRIGGERED 0
|
#define GTDT_TIMER_ACTIVE_LOW EFI_ACPI_6_3_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY
|
#define GTDT_TIMER_ACTIVE_HIGH 0
|
|
#define GTDT_GTIMER_FLAGS (GTDT_TIMER_ACTIVE_LOW | GTDT_TIMER_LEVEL_TRIGGERED)
|
|
#define SBSA_PLATFORM_WATCHDOG_COUNT 1
|
#define SBSA_PLATFORM_TIMER_COUNT (SBSA_PLATFORM_WATCHDOG_COUNT)
|
|
#define SBSAQEMU_WDT_REFRESH_FRAME_BASE 0x50010000
|
#define SBSAQEMU_WDT_CONTROL_FRAME_BASE 0x50011000
|
#define SBSAQEMU_WDT_IRQ 48
|
|
#define GTDT_WDTIMER_EDGE_TRIGGERED EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE
|
#define GTDT_WDTIMER_LEVEL_TRIGGERED 0
|
#define GTDT_WDTIMER_ACTIVE_LOW EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY
|
#define GTDT_WDTIMER_ACTIVE_HIGH 0
|
|
#define GTDT_WDTIMER_FLAGS (GTDT_WDTIMER_ACTIVE_HIGH | GTDT_WDTIMER_LEVEL_TRIGGERED)
|
|
#define EFI_ACPI_6_3_SBSA_GENERIC_WATCHDOG_STRUCTURE_INIT( \
|
RefreshFramePhysicalAddress, ControlFramePhysicalAddress, \
|
WatchdogTimerGSIV, WatchdogTimerFlags) \
|
{ \
|
EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG, \
|
sizeof(EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE), \
|
EFI_ACPI_RESERVED_WORD, \
|
RefreshFramePhysicalAddress, \
|
ControlFramePhysicalAddress, \
|
WatchdogTimerGSIV, \
|
WatchdogTimerFlags \
|
}
|
|
#pragma pack (1)
|
|
typedef struct {
|
EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE Gtdt;
|
EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE Gwdt;
|
} GENERIC_TIMER_DESCRIPTION_TABLES;
|
|
#pragma pack ()
|
|
GENERIC_TIMER_DESCRIPTION_TABLES Gtdt = {
|
{
|
SBSAQEMU_ACPI_HEADER(
|
EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
|
GENERIC_TIMER_DESCRIPTION_TABLES,
|
EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION
|
),
|
SYSTEM_TIMER_BASE_ADDRESS, // UINT64 PhysicalAddress
|
0, // UINT32 Reserved
|
FixedPcdGet32 (PcdArmArchTimerSecIntrNum), // UINT32 SecurePL1TimerGSIV
|
GTDT_GTIMER_FLAGS, // UINT32 SecurePL1TimerFlags
|
FixedPcdGet32 (PcdArmArchTimerIntrNum), // UINT32 NonSecurePL1TimerGSIV
|
GTDT_GTIMER_FLAGS, // UINT32 NonSecurePL1TimerFlags
|
FixedPcdGet32 (PcdArmArchTimerVirtIntrNum), // UINT32 VirtualTimerGSIV
|
GTDT_GTIMER_FLAGS, // UINT32 VirtualTimerFlags
|
FixedPcdGet32 (PcdArmArchTimerHypIntrNum), // UINT32 NonSecurePL2TimerGSIV
|
GTDT_GTIMER_FLAGS, // UINT32 NonSecurePL2TimerFlags
|
0xFFFFFFFFFFFFFFFF, // UINT64 CntReadBasePhysicalAddress
|
SBSA_PLATFORM_TIMER_COUNT, // UINT32 PlatformTimerCount
|
sizeof(EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE),
|
// UINT32 PlatformTimerOffset
|
0, // UINT32 VirtualPL2TimerGSIV
|
0 // UINT32 VirtualPL2TimerFlags
|
},
|
EFI_ACPI_6_3_SBSA_GENERIC_WATCHDOG_STRUCTURE_INIT(
|
SBSAQEMU_WDT_REFRESH_FRAME_BASE,
|
SBSAQEMU_WDT_CONTROL_FRAME_BASE,
|
SBSAQEMU_WDT_IRQ,
|
GTDT_WDTIMER_FLAGS
|
)
|
};
|
|
// Reference the table being generated to prevent the optimizer from removing the
|
// data structure from the executable
|
VOID* CONST ReferenceAcpiTable = &Gtdt;
|