#include #include #include #include static unsigned long long tick_counter = 0; static int pit_callback(void) { tick_counter++; return 0; } static struct irq_hook pit_irq_hook = { .irq_callback = pit_callback }; void pit_start(unsigned int hz) { tick_counter = 0; unsigned int divisor = 1193180 / hz; outportb(0x43, 0x36); uint8_t lo = (uint8_t)(divisor & 0xFF); uint8_t hi = (uint8_t)((divisor >> 8) & 0xFF); outportb(0x40, lo); outportb(0x40, hi); hook_irq(IRQ0, &pit_irq_hook); } void pit_stop(void) { /* lowest possible frequency */ unsigned int divisor = 1193180; outportb(0x43, 0x36); uint8_t lo = (uint8_t)(divisor & 0xFF); uint8_t hi = (uint8_t)((divisor >> 8) & 0xFF); outportb(0x40, lo); outportb(0x40, hi); unhook_irq(IRQ0, &pit_irq_hook); } void pit_wait(unsigned int ticks) { unsigned long long end = tick_counter + ticks; while (READ_ONCE(tick_counter) < end) { } }