1#include <acpi/hpet.h>
2#include <asm.h>
3#include <stdbool.h>
4#include <stdint.h>
5#include <time/spin_sleep.h>
6
7extern uint64_t *hpet_base;
8
9static void sleep_hpet_fs(uint64_t femtoseconds) {
10 uint32_t fs_per_tick = hpet_fs_per_tick;
11 uint64_t ticks_to_wait = femtoseconds / fs_per_tick;
12
13 uint64_t start = hpet_read64(HPET_MAIN_COUNTER_OFFSET);
14 while ((hpet_read64(HPET_MAIN_COUNTER_OFFSET) - start) < ticks_to_wait) {
15 cpu_relax();
16 }
17}
18
19void sleep_spin_ms(uint64_t ms) {
20 sleep_hpet_fs(femtoseconds: ms * 1000000000000ULL); // 1 ms = 1e12 femtoseconds
21}
22
23void sleep_spin_us(uint64_t us) {
24 sleep_hpet_fs(femtoseconds: us * 1000000000ULL); // 1 us = 1e9 femtoseconds
25}
26
27void sleep_spin(uint64_t seconds) {
28 sleep_hpet_fs(femtoseconds: seconds * 1000000000000000ULL); // 1 s = 1e15 femtoseconds
29}
30
31bool mmio_spin_wait(uint32_t *reg, uint32_t mask, uint64_t timeout) {
32 uint64_t timeout_us = timeout * 1000;
33 while ((mmio_read_32(address: reg) & mask) && timeout_us--) {
34 if (timeout_us == 0)
35 return false;
36 sleep_spin_us(us: 10);
37 }
38 return (mmio_read_32(address: reg) & mask) == 0;
39}
40