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