Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • GT Block,

  • Server Base System Architecture (SBSA) Generic Watchdog.

GTDT table structure

...

SW Status

...

ACPI table defined in UEFI:

Code Block
typedef struct {
  UINT32  Signature;
  UINT32  Length;
  UINT8   Revision;
  UINT8   Checksum;
  UINT8   OemId[6];
  UINT64  OemTableId;
  UINT32  OemRevision;
  UINT32  CreatorId;
  UINT32  CreatorRevision;
} EFI_ACPI_DESCRIPTION_HEADER;

///
/// Generic Timer Description Table definition.
///
typedef struct {
  EFI_ACPI_DESCRIPTION_HEADER    Header;
  UINT64                         PhysicalAddress;
  UINT32                         GlobalFlags;
  UINT32                         SecurePL1TimerGSIV;
  UINT32                         SecurePL1TimerFlags;
  UINT32                         NonSecurePL1TimerGSIV;
  UINT32                         NonSecurePL1TimerFlags;
  UINT32                         VirtualTimerGSIV;
  UINT32                         VirtualTimerFlags;
  UINT32                         NonSecurePL2TimerGSIV;
  UINT32                         NonSecurePL2TimerFlags;
} EFI_ACPI_5_0_GENERIC_TIMER_DESCRIPTION_TABLE;

SW Status

Generic timer work well on i.MX8MP.

Code for ACPI

GTDT table for i.MX8MP:

Code Block
# ARM Architectural Timer Interrupt(GIC PPI) numbers
  gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|29|UINT32|0x00000035
  gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036
  gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|26|UINT32|0x00000040
  gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|27|UINT32|0x00000041
  

#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_5_0_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE
#define GTDT_TIMER_LEVEL_TRIGGERED  0
#define GTDT_TIMER_ACTIVE_LOW       EFI_ACPI_5_0_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY
#define GTDT_TIMER_ACTIVE_HIGH      0

#define GTDT_GTIMER_FLAGS           (GTDT_TIMER_ACTIVE_LOW | GTDT_TIMER_LEVEL_TRIGGERED)

  EFI_ACPI_5_0_GENERIC_TIMER_DESCRIPTION_TABLE Gtdt = {
    ARM_ACPI_HEADER(
      EFI_ACPI_5_0_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
      EFI_ACPI_5_0_GENERIC_TIMER_DESCRIPTION_TABLE,
      EFI_ACPI_5_0_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION
    ),
    SYSTEM_TIMER_BASE_ADDRESS,                            // UINT64  PhysicalAddress
    GTDT_GLOBAL_FLAGS,                                            // UINT32  GlobalFlags
    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
  };

External timer

For external timer (also called as SoC timer), different SoC vendor may design their SoC timer, there have many difference in register layout and timer logic. So we see there have many platform timer driver in the kernel “drivers/clocksource/“.

How to support one new SoC timer ? Currently, it can use Device scope and DSD can match the platform driver requirement.