PatchworkOS  28a9544
A non-POSIX operating system.
Loading...
Searching...
No Matches

High Precision Event Timer. More...

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_timer_handler (interrupt_frame_t *frame, cpu_t *self)
 Timer interrupt handler to avoid HPET counter overflows on 32-bit HPETs.
 
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 sys_time_source_t source
 Structure to describe the HPET to the sys time subsystem.
 

Detailed Description

High Precision Event Timer.

Note that 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

Macro Definition Documentation

◆ 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 62 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 57 of file hpet.c.

◆ 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 42 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 47 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 52 of file hpet.c.

◆ HPET_FEMTOSECONDS_PER_SECOND

#define HPET_FEMTOSECONDS_PER_SECOND   1000000000000000ULL

The number of femtoseconds in one second.

Definition at line 67 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 29 of file hpet.c.

Function Documentation

◆ hpet_deinit()

static void hpet_deinit ( void  )
static

Deinitialize the HPET.

Definition at line 248 of file hpet.c.

References HPET_REG_GENERAL_CONFIG, hpet_write(), source, and sys_time_unregister_source().

Referenced by _module_procedure().

◆ hpet_init()

◆ 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 126 of file hpet.c.

References CLOCKS_PER_SEC, HPET_FEMTOSECONDS_PER_SECOND, and period.

Referenced by hpet_init(), hpet_read_ns_counter(), and hpet_timer_handler().

◆ 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 116 of file hpet.c.

References address, and READ_64.

Referenced by hpet_init(), hpet_read_ns_counter(), and hpet_timer_handler().

◆ 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 136 of file hpet.c.

References atomic_load, counter, counterLock, hpet_ns_per_tick(), hpet_read(), HPET_REG_MAIN_COUNTER_VALUE, seqlock_read_begin(), seqlock_read_retry(), and time().

◆ hpet_reset_counter()

static void hpet_reset_counter ( void  )
inlinestatic

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

Definition at line 151 of file hpet.c.

References HPET_CONF_ENABLE_CNF_BIT, HPET_REG_GENERAL_CONFIG, HPET_REG_MAIN_COUNTER_VALUE, and hpet_write().

Referenced by hpet_init(), and hpet_timer_handler().

◆ hpet_timer_handler()

static void hpet_timer_handler ( interrupt_frame_t frame,
cpu_t self 
)
static

Timer interrupt handler to avoid HPET counter overflows on 32-bit HPETs.

Is also used for 64-bit HPETs but it will in practice never fire.

Parameters
frameThe interrupt frame.
selfThe current CPU.

Definition at line 166 of file hpet.c.

References atomic_fetch_add, counter, counterLock, hpet_ns_per_tick(), hpet_read(), HPET_REG_MAIN_COUNTER_VALUE, hpet_reset_counter(), LOG_INFO, seqlock_write_acquire(), seqlock_write_release(), sys_time_uptime(), timer_one_shot(), and UINT32_MAX.

Referenced by hpet_init().

◆ 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 105 of file hpet.c.

References address, and WRITE_64.

Referenced by hpet_deinit(), and hpet_reset_counter().

Variable Documentation

◆ address

◆ counter

atomic_uint64_t counter = ATOMIC_VAR_INIT(0)
static

Accumulated nanosecond counter, used to avoid overflows.

Definition at line 96 of file hpet.c.

Referenced by hpet_read_ns_counter(), and hpet_timer_handler().

◆ counterLock

seqlock_t counterLock = SEQLOCK_CREATE
static

Seqlock for the accumulated counter.

Definition at line 97 of file hpet.c.

Referenced by hpet_read_ns_counter(), and hpet_timer_handler().

◆ hpet

hpet_t* hpet
static

Pointer to the HPET ACPI table.

Definition at line 92 of file hpet.c.

Referenced by hpet_init().

◆ period

uint64_t period
static

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

Definition at line 94 of file hpet.c.

Referenced by hpet_init(), and hpet_ns_per_tick().

◆ source

sys_time_source_t source
static
Initial value:
= {
.name = "HPET",
.precision = 0,
}
static clock_t hpet_read_ns_counter(void)
Safely read the HPET counter value in nanoseconds.
Definition hpet.c:136

Structure to describe the HPET to the sys time subsystem.

Definition at line 185 of file hpet.c.

Referenced by _syscall_bind(), aml_concat_resolve_to_buffer(), aml_concat_resolve_to_integer(), aml_concat_resolve_to_string(), aml_def_alias_read(), aml_def_cond_ref_of_read(), aml_def_copy_object_read(), aml_def_decrement_read(), aml_def_increment_read(), aml_def_store_read(), aml_def_to_string_read(), bind(), hpet_deinit(), hpet_init(), namespace_bind(), sys_time_register_source(), sys_time_unregister_source(), and SYSCALL_DEFINE().