|
| 1 | +#pragma once |
| 2 | +#include <acpi.h> |
| 3 | +#include <common.h> |
| 4 | + |
| 5 | +/* Generic Timer Description Table */ |
| 6 | +#define ACPI_GTDT_SIGNATURE 'G', 'T', 'D', 'T' |
| 7 | +#define ACPI_GTDT_REVISION 2 |
| 8 | +// #define ACPI_GTDT_REVISION 3 |
| 9 | + |
| 10 | +#define ACPI_GTDT_TABLE_STRUCTURE_NAME GENERIC_TIMER_DESCRIPTION_TABLE |
| 11 | + |
| 12 | +/* Extra data in header */ |
| 13 | + |
| 14 | +typedef struct { |
| 15 | + UINT64 CntControlBasePhyAddress; |
| 16 | + UINT32 Reserved; |
| 17 | + UINT32 SecureEL1TimerGSI; |
| 18 | + UINT32 SecureEL1TimerFlags; |
| 19 | + UINT32 NSEL1TimerGSI; |
| 20 | + UINT32 NSEL1TimerFlags; |
| 21 | + UINT32 VirtualEL1TimerGSI; |
| 22 | + UINT32 VirtualEL1TimerFlags; |
| 23 | + UINT32 EL2TimerGSI; |
| 24 | + UINT32 EL2TimerFlags; |
| 25 | + UINT64 CntReadBasePhyAddress; |
| 26 | + UINT32 PlatformTimerCount; |
| 27 | + UINT32 PlatformTimerOffset; |
| 28 | +#if ACPI_GTDT_REVISION >= 3 |
| 29 | + UINT32 VirtualEL2TimerGSI; |
| 30 | + UINT32 VirtualEL2TimerFlags; |
| 31 | +#endif |
| 32 | + // Platform Timer Structures |
| 33 | +} __attribute__((packed)) GTDT_HEADER_EXTRA_DATA; |
| 34 | +#if (ACPI_GTDT_REVISION >= 3) |
| 35 | +_Static_assert(sizeof(GTDT_HEADER_EXTRA_DATA) == |
| 36 | + 104 - sizeof(ACPI_TABLE_HEADER), |
| 37 | + "GTDT_HEADER_EXTRA_DATA size incorrect"); |
| 38 | +#else |
| 39 | +_Static_assert(sizeof(GTDT_HEADER_EXTRA_DATA) == 96 - sizeof(ACPI_TABLE_HEADER), |
| 40 | + "GTDT_HEADER_EXTRA_DATA size incorrect"); |
| 41 | +#endif |
| 42 | + |
| 43 | +/* Body Structures */ |
| 44 | +#define GTDT_DEFINE_TIMER_BLOCK_STRUCTURE_TYPE(name, block_timer_cnt) \ |
| 45 | + typedef struct { \ |
| 46 | + UINT8 Type; \ |
| 47 | + UINT16 Length; \ |
| 48 | + UINT8 Reserved; \ |
| 49 | + UINT64 GTBlockPhysicalAddress; \ |
| 50 | + UINT32 GTBlockTimerCount; \ |
| 51 | + UINT32 GTBlockTimerOffset; \ |
| 52 | + GTDT_BLOCK_TIMER_STRUCTURE GTBlockTimerStructure[block_timer_cnt]; \ |
| 53 | + } __attribute__((packed)) GTDT_TIMER_BLOCK_STRUCTURE_##name; \ |
| 54 | + _Static_assert(sizeof(GTDT_TIMER_BLOCK_STRUCTURE_##name) == \ |
| 55 | + 20 + \ |
| 56 | + block_timer_cnt * sizeof(GTDT_BLOCK_TIMER_STRUCTURE), \ |
| 57 | + "GTDT_TIMER_BLOCK_STRUCTURE size incorrect"); |
| 58 | + |
| 59 | +typedef struct { |
| 60 | + UINT8 GTFrameNumber; |
| 61 | + UINT8 Reserved[3]; |
| 62 | + UINT64 CNTBaseX; |
| 63 | + UINT64 CNTEL0BaseX; |
| 64 | + UINT32 PhysicalTimerGSI; |
| 65 | + UINT32 PhysicalTimerFlags; |
| 66 | + UINT32 VirtualTimerGSI; |
| 67 | + UINT32 VirtualTimerFlags; |
| 68 | + UINT32 CommonFlags; |
| 69 | +} __attribute__((packed)) GTDT_BLOCK_TIMER_STRUCTURE; |
| 70 | +_Static_assert(sizeof(GTDT_BLOCK_TIMER_STRUCTURE) == 40, |
| 71 | + "GTDT_BLOCK_TIMER_STRUCTURE size incorrect"); |
| 72 | + |
| 73 | +#define GTDT_BLOCK_PVT_FLAG_TIMER_INTERRUPT_MODE BIT(0) |
| 74 | +enum GTDT_BLOCK_PVT_TIMER_INTERRUPT_MODE { |
| 75 | + GTDT_BLOCK_PVT_TIMER_INTERRUPT_MODE_LVL_TRIGGERED = 0, |
| 76 | + GTDT_BLOCK_PVT_TIMER_INTERRUPT_MODE_EDGE_TRIGGERED = 1, |
| 77 | +}; |
| 78 | +#define GTDT_BLOCK_PVT_FLAG_TIMER_INTERRUPT_POLARITY BIT(1) |
| 79 | +enum GTDT_BLOCK_PVT_TIMER_INTERRUPT_POLARITY { |
| 80 | + GTDT_BLOCK_PVT_TIMER_INTERRUPT_POLARITY_ACTIVE_HIGH = 0, |
| 81 | + GTDT_BLOCK_PVT_TIMER_INTERRUPT_POLARITY_ACTIVE_LOW = 1, |
| 82 | +}; |
| 83 | +#define GTDT_BLOCK_PVT_FLAG_TIMER_RESERVED GEN_MSK(31, 2) |
| 84 | + |
| 85 | +#define GTDT_BLOCK_COMMONT_FLAGS_TIMER_SECURE_TIMER BIT(0) |
| 86 | +#define GTDT_BLOCK_COMMONT_FLAGS_TIMER_ALWAYS_ON_CAP BIT(1) |
| 87 | +#define GTDT_BLOCK_COMMONR_FLAG_TIMER_RESERVED GEN_MSK(31, 2) |
| 88 | + |
| 89 | +typedef struct { |
| 90 | + UINT8 Type; // 0x1 => WDT |
| 91 | + UINT16 Length; // 28 |
| 92 | + UINT8 Reserved; |
| 93 | + UINT64 RefreshFramePhysicalAddress; |
| 94 | + UINT64 WatchdogControlFramePhysicalAddress; |
| 95 | + UINT32 WatchdogTimerGSI; |
| 96 | + UINT32 WatchdogTimerFlags; |
| 97 | +} __attribute__((packed)) ACPI_GTDT_GENERIC_WDT_STRUCTURE; |
| 98 | +_Static_assert(sizeof(ACPI_GTDT_GENERIC_WDT_STRUCTURE) == 28, |
| 99 | + "ACPI_GTDT_GENERIC_WDT_STRUCTURE size incorrect"); |
| 100 | + |
| 101 | +#define GTDT_WDT_FLAG_TIMER_TIMER_INTERRUPT_MODE BIT(0) |
| 102 | +#define GTDT_WDT_FLAG_TIMER_TIMER_INTERRUPT_POLARITY BIT(1) |
| 103 | +#define GTDT_WDT_FLAG_TIMER_SECURE_TIMER BIT(2) |
| 104 | +#define GTDT_WDT_FLAG_TIMER_RESERVED GEN_MSK(31, 3) |
| 105 | + |
| 106 | +/* Helper macros */ |
| 107 | +#define GTDT_DEFINE_TABLE(...) \ |
| 108 | + typedef struct { \ |
| 109 | + ACPI_TABLE_HEADER Header; \ |
| 110 | + GTDT_HEADER_EXTRA_DATA GTDTHeaderExtraData; \ |
| 111 | + __VA_OPT__(__VA_ARGS__) \ |
| 112 | + } __attribute__((packed)) ACPI_GTDT_TABLE_STRUCTURE_NAME; |
| 113 | + |
| 114 | +#define GTDT_GET_TIMER_BLOCK_STRUCTURE_NAME(name) \ |
| 115 | + GTDT_TIMER_BLOCK_STRUCTURE_##name |
| 116 | + |
| 117 | +#define GTDT_DEFINE_TIMER_BLOCK_IN_TABLE(name) \ |
| 118 | + GTDT_GET_TIMER_BLOCK_STRUCTURE_NAME(name) name; |
| 119 | + |
| 120 | +#define GTDT_DECLARE_HEADER \ |
| 121 | + ACPI_DECLARE_TABLE_HEADER( \ |
| 122 | + ACPI_GTDT_SIGNATURE, ACPI_GTDT_TABLE_STRUCTURE_NAME, ACPI_GTDT_REVISION) |
| 123 | + |
| 124 | +/* GTDT Table with Magic */ |
| 125 | +#define GTDT_DEFINE_WITH_MAGIC \ |
| 126 | + ACPI_TABLE_WITH_MAGIC(ACPI_GTDT_TABLE_STRUCTURE_NAME) |
| 127 | +#define GTDT_START ACPI_TABLE_START(ACPI_GTDT_TABLE_STRUCTURE_NAME) |
| 128 | +#define GTDT_END ACPI_TABLE_END(ACPI_GTDT_TABLE_STRUCTURE_NAME) |
0 commit comments