Files
Sylva/kernel/interrupt/pit.cpp
T
2026-06-06 10:31:20 +08:00

50 lines
1.1 KiB
C++

#include <pit.h>
#include <common.h>
#include <string_utils.h>
#include <pic.h>
#include <serial.h>
static inline void outb(UINT16 port, UINT8 val) {
ASM("outb %0, %1" : : "a"(val), "Nd"(port));
}
static volatile UINT64 g_ticks = 0;
static timer_callback_t g_tick_handler = NULL;
extern "C" void pit_irq_handler(void) {
g_ticks++;
if (g_tick_handler) {
g_tick_handler();
}
}
void pit_init(void) {
serial_write("PIT: initializing channel 0 at ");
serial_write_hex(PIT_TICK_HZ);
serial_write(" Hz\n");
UINT32 divisor = PIT_BASE_FREQ / PIT_TICK_HZ;
// 命令字节:通道 0,低/高字节,速率生成器,二进制
outb(PIT_COMMAND_PORT, 0x36);
// 发送除数(先低字节后高字节)
outb(PIT_CHANNEL0_DATA, (UINT8)(divisor & 0xFF));
outb(PIT_CHANNEL0_DATA, (UINT8)((divisor >> 8) & 0xFF));
// 取消屏蔽 IRQ 0(定时器)
pic_unmask_irq(0);
serial_write("PIT: divisor = ");
serial_write_hex(divisor);
serial_write("\n");
}
void pit_set_tick_handler(timer_callback_t handler) {
g_tick_handler = handler;
}
UINT64 pit_get_ticks(void) {
return g_ticks;
}