PatchworkOS  621ae6b
A non-POSIX operating system.
Loading...
Searching...
No Matches

High Precision Event Timer. More...

Collaboration diagram for HPET:

Detailed Description

High Precision Event Timer.

Note
Since the HPET might be 32bit it could overflow rather quickly, so we implement a system for checking roughly when it will overflow and accumulate the counter into a 64 bit nanosecond counter.
See also
OSDev HPET

Data Structures

struct  hpet_t
 High Precision Event Timer structure. More...
 

Macros

#define HPET_CAP_COUNTER_CLK_PERIOD_SHIFT   32
 The bit offset of the clock period in the capabilities register.
 
#define HPET_CONF_ENABLE_CNF_BIT   (1 << 0)
 The bit to set to enable the HPET in the configuration register.
 
#define HPET_CONF_LEG_RT_CNF_BIT   (1 << 1)
 The bit to set to enable legacy replacement mode in the configuration register.
 
#define HPET_ADDRESS_SPACE_MEMORY   0
 If hpet_t::addressSpaceId is equal to this, the address is in system memory space.
 
#define HPET_ADDRESS_SPACE_IO   1
 If hpet_t::addressSpaceId is equal to this, the address is in system I/O space.
 
#define HPET_FEMTOSECONDS_PER_SECOND   1000000000000000ULL
 The number of femtoseconds in one second.
 

Enumerations

enum  hpet_register_t {
  HPET_REG_GENERAL_CAPABILITIES_ID = 0x000 , HPET_REG_GENERAL_CONFIG = 0x010 , HPET_REG_GENERAL_INTERRUPT = 0x020 , HPET_REG_MAIN_COUNTER_VALUE = 0x0F0 ,
  HPET_REG_TIMER0_CONFIG_CAP = 0x100 , HPET_REG_TIMER0_COMPARATOR = 0x108
}
 HPET register offsets. More...
 

Functions

static void hpet_write (hpet_register_t reg, uint64_t value)
 Write to an HPET register.
 
static uint64_t hpet_read (hpet_register_t reg)
 Read from an HPET register.
 
static clock_t hpet_ns_per_tick (void)
 Get the HPET clock period in nanoseconds.
 
static clock_t hpet_read_ns_counter (void)
 Safely read the HPET counter value in nanoseconds.
 
static void hpet_reset_counter (void)
 Reset the HPET main counter to zero and enable the HPET.
 
static void hpet_overflow_thread (void *arg)
 Thread function that periodically accumulates the HPET counter to prevent overflow.
 
static uint64_t hpet_init (void)
 Initialize the HPET.
 
static void hpet_deinit (void)
 Deinitialize the HPET.
 

Variables

static hpet_thpet
 Pointer to the HPET ACPI table.
 
static uintptr_t address
 Mapped virtual address of the HPET registers.
 
static uint64_t period
 Main counter tick period in femtoseconds (10^-15 s).
 
static atomic_uint64_t counter = ATOMIC_VAR_INIT(0)
 Accumulated nanosecond counter, used to avoid overflows.
 
static seqlock_t counterLock = SEQLOCK_CREATE()
 Seqlock for the accumulated counter.
 
static tid_t overflowThreadTid = 0
 Thread ID of the overflow thread.
 
static wait_queue_t overflowQueue = WAIT_QUEUE_CREATE(overflowQueue)
 Wait queue for the overflow thread.
 
static atomic_bool overflowShouldStop = ATOMIC_VAR_INIT(false)
 Flag to signal the overflow thread to stop.
 
static clock_source_t source
 Structure to describe the HPET to the sys time subsystem.
 

Macro Definition Documentation

◆ HPET_CAP_COUNTER_CLK_PERIOD_SHIFT

#define HPET_CAP_COUNTER_CLK_PERIOD_SHIFT   32

The bit offset of the clock period in the capabilities register.

Definition at line 44 of file hpet.c.

◆ HPET_CONF_ENABLE_CNF_BIT

#define HPET_CONF_ENABLE_CNF_BIT   (1 << 0)

The bit to set to enable the HPET in the configuration register.

Definition at line 49 of file hpet.c.

◆ HPET_CONF_LEG_RT_CNF_BIT

#define HPET_CONF_LEG_RT_CNF_BIT   (1 << 1)

The bit to set to enable legacy replacement mode in the configuration register.

Definition at line 54 of file hpet.c.

◆ HPET_ADDRESS_SPACE_MEMORY

#define HPET_ADDRESS_SPACE_MEMORY   0

If hpet_t::addressSpaceId is equal to this, the address is in system memory space.

Definition at line 59 of file hpet.c.

◆ HPET_ADDRESS_SPACE_IO

#define HPET_ADDRESS_SPACE_IO   1

If hpet_t::addressSpaceId is equal to this, the address is in system I/O space.

Definition at line 64 of file hpet.c.

◆ HPET_FEMTOSECONDS_PER_SECOND

#define HPET_FEMTOSECONDS_PER_SECOND   1000000000000000ULL

The number of femtoseconds in one second.

Definition at line 69 of file hpet.c.

Enumeration Type Documentation

◆ hpet_register_t

HPET register offsets.

Enumerator
HPET_REG_GENERAL_CAPABILITIES_ID 
HPET_REG_GENERAL_CONFIG 
HPET_REG_GENERAL_INTERRUPT 
HPET_REG_MAIN_COUNTER_VALUE 
HPET_REG_TIMER0_CONFIG_CAP 
HPET_REG_TIMER0_COMPARATOR 

Definition at line 31 of file hpet.c.

Function Documentation

◆ hpet_write()

static void hpet_write ( hpet_register_t  reg,
uint64_t  value 
)
inlinestatic

Write to an HPET register.

Parameters
regThe register to write to.
valueThe value to write.

Definition at line 111 of file hpet.c.

Here is the caller graph for this function:

◆ hpet_read()

static uint64_t hpet_read ( hpet_register_t  reg)
inlinestatic

Read from an HPET register.

Parameters
regThe register to read from.
Returns
The value read from the register.

Definition at line 122 of file hpet.c.

Here is the caller graph for this function:

◆ hpet_ns_per_tick()

static clock_t hpet_ns_per_tick ( void  )
inlinestatic

Get the HPET clock period in nanoseconds.

Returns
The HPET clock period in nanoseconds.

Definition at line 132 of file hpet.c.

Here is the caller graph for this function:

◆ hpet_read_ns_counter()

static clock_t hpet_read_ns_counter ( void  )
static

Safely read the HPET counter value in nanoseconds.

Returns
The current value of the HPET counter in nanoseconds.

Definition at line 142 of file hpet.c.

Here is the call graph for this function:

◆ hpet_reset_counter()

static void hpet_reset_counter ( void  )
inlinestatic

Reset the HPET main counter to zero and enable the HPET.

Definition at line 157 of file hpet.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ hpet_overflow_thread()

static void hpet_overflow_thread ( void arg)
static

Thread function that periodically accumulates the HPET counter to prevent overflow.

Parameters
argUnused.

Definition at line 169 of file hpet.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ hpet_init()

static uint64_t hpet_init ( void  )
static

Initialize the HPET.

Returns
On success, 0. On failure, ERR.

Definition at line 204 of file hpet.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ hpet_deinit()

static void hpet_deinit ( void  )
static

Deinitialize the HPET.

Definition at line 263 of file hpet.c.

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ hpet

hpet_t* hpet
static

Pointer to the HPET ACPI table.

Definition at line 94 of file hpet.c.

◆ address

uintptr_t address
static

Mapped virtual address of the HPET registers.

Definition at line 95 of file hpet.c.

◆ period

uint64_t period
static

Main counter tick period in femtoseconds (10^-15 s).

Definition at line 96 of file hpet.c.

◆ counter

atomic_uint64_t counter = ATOMIC_VAR_INIT(0)
static

Accumulated nanosecond counter, used to avoid overflows.

Definition at line 98 of file hpet.c.

◆ counterLock

seqlock_t counterLock = SEQLOCK_CREATE()
static

Seqlock for the accumulated counter.

Definition at line 99 of file hpet.c.

◆ overflowThreadTid

tid_t overflowThreadTid = 0
static

Thread ID of the overflow thread.

Definition at line 101 of file hpet.c.

◆ overflowQueue

wait_queue_t overflowQueue = WAIT_QUEUE_CREATE(overflowQueue)
static

Wait queue for the overflow thread.

Definition at line 102 of file hpet.c.

◆ overflowShouldStop

atomic_bool overflowShouldStop = ATOMIC_VAR_INIT(false)
static

Flag to signal the overflow thread to stop.

Definition at line 103 of file hpet.c.

◆ source

clock_source_t source
static
Initial value:
= {
.name = "HPET",
.precision = 0,
.read_epoch = NULL,
}
#define NULL
Pointer error value.
Definition NULL.h:23
static clock_t hpet_read_ns_counter(void)
Safely read the HPET counter value in nanoseconds.
Definition hpet.c:142

Structure to describe the HPET to the sys time subsystem.

Definition at line 192 of file hpet.c.