|
PatchworkOS
28a9544
A non-POSIX operating system.
|
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_t * | hpet |
| 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. | |
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.
| #define HPET_ADDRESS_SPACE_IO 1 |
If hpet_t::addressSpaceId is equal to this, the address is in system I/O space.
| #define HPET_ADDRESS_SPACE_MEMORY 0 |
If hpet_t::addressSpaceId is equal to this, the address is in system memory space.
| #define HPET_CAP_COUNTER_CLK_PERIOD_SHIFT 32 |
| #define HPET_CONF_ENABLE_CNF_BIT (1 << 0) |
| #define HPET_CONF_LEG_RT_CNF_BIT (1 << 1) |
| #define HPET_FEMTOSECONDS_PER_SECOND 1000000000000000ULL |
| enum hpet_register_t |
|
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().
|
static |
Initialize the HPET.
0. On failure, ERR. Definition at line 196 of file hpet.c.
References acpi_tables_lookup(), hpet_t::address, address, hpet_t::addressSpaceId, CLOCKS_PER_SEC, hpet_t::comparatorCount, hpet_t::counterIs64Bit, cpu_get_unsafe(), ERR, hpet, HPET_ADDRESS_SPACE_MEMORY, HPET_CAP_COUNTER_CLK_PERIOD_SHIFT, HPET_FEMTOSECONDS_PER_SECOND, hpet_ns_per_tick(), hpet_read(), HPET_REG_GENERAL_CAPABILITIES_ID, hpet_reset_counter(), hpet_timer_handler(), LOG_ERR, LOG_INFO, NULL, PAGE_SIZE, period, PML_GLOBAL, PML_LOWER_TO_HIGHER, PML_PRESENT, PML_WRITE, sys_time_source_t::precision, source, sys_time_register_source(), and vmm_map().
Referenced by _module_procedure().
|
inlinestatic |
Get 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().
|
inlinestatic |
Read from an HPET register.
| reg | The register to read from. |
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().
|
static |
Safely read the HPET counter value 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().
|
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().
|
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.
| frame | The interrupt frame. |
| self | The 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().
|
inlinestatic |
Write to an HPET register.
| reg | The register to write to. |
| value | The value to write. |
Definition at line 105 of file hpet.c.
References address, and WRITE_64.
Referenced by hpet_deinit(), and hpet_reset_counter().
|
static |
Mapped virtual address of the HPET registers.
Definition at line 93 of file hpet.c.
Referenced by _syscall_mmap(), _syscall_mprotect(), _syscall_munmap(), aml_ensure_mem_is_mapped(), aml_generic_field_read_at(), aml_generic_field_write_at(), aml_opregion_read(), aml_opregion_write(), aml_pci_config_read(), aml_pci_config_write(), aml_system_io_read(), aml_system_io_write(), aml_system_mem_read(), aml_system_mem_write(), hpet_init(), hpet_read(), hpet_write(), local_listen_find(), local_listen_new(), local_socket_bind(), local_socket_connect(), mmap(), mprotect(), munmap(), page_table_page_buffer_push(), pci_config_get_address(), pmm_alloc(), pmm_alloc_bitmap(), pmm_alloc_pages(), pmm_bitmap_free(), pmm_free(), pmm_free_pages_unlocked(), pmm_free_region(), pmm_free_unlocked(), pmm_stack_alloc(), pmm_stack_free(), shmem_mmap(), shmem_object_allocate_pages(), space_pin_depth_dec(), space_pin_depth_inc(), space_pin_terminated(), space_unpin(), SYSCALL_DEFINE(), SYSCALL_DEFINE(), SYSCALL_DEFINE(), and vfs_mmap().
|
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().
|
static |
Seqlock for the accumulated counter.
Definition at line 97 of file hpet.c.
Referenced by hpet_read_ns_counter(), and hpet_timer_handler().
|
static |
|
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().
|
static |
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().