2024-09-17 17:48:26 +01:00
|
|
|
#include <arch/irq.h>
|
|
|
|
|
#include <arch/ports.h>
|
2026-02-19 18:54:48 +00:00
|
|
|
#include <kernel/clock.h>
|
|
|
|
|
#include <kernel/cpu.h>
|
|
|
|
|
#include <kernel/printk.h>
|
2023-04-28 20:51:51 +01:00
|
|
|
|
2024-09-17 17:48:26 +01:00
|
|
|
#define PIT_COUNTER0 0x40
|
|
|
|
|
#define PIT_CMD 0x43
|
2023-04-28 20:51:51 +01:00
|
|
|
|
2024-09-17 17:48:26 +01:00
|
|
|
#define CMD_BINARY 0x00 // Use Binary counter values
|
|
|
|
|
#define CMD_BCD 0x01 // Use Binary Coded Decimal counter values
|
2023-04-28 20:51:51 +01:00
|
|
|
|
2024-09-17 17:48:26 +01:00
|
|
|
#define CMD_MODE0 0x00 // Interrupt on Terminal Count
|
|
|
|
|
#define CMD_MODE1 0x02 // Hardware Retriggerable One-Shot
|
|
|
|
|
#define CMD_MODE2 0x04 // Rate Generator
|
|
|
|
|
#define CMD_MODE3 0x06 // Square Wave
|
|
|
|
|
#define CMD_MODE4 0x08 // Software Trigerred Strobe
|
|
|
|
|
#define CMD_MODE5 0x0a // Hardware Trigerred Strobe
|
2023-04-28 20:51:51 +01:00
|
|
|
|
2024-09-17 17:48:26 +01:00
|
|
|
#define CMD_LATCH 0x00
|
|
|
|
|
#define CMD_RW_LOW 0x10 // Least Significant Byte
|
|
|
|
|
#define CMD_RW_HI 0x20 // Most Significant Byte
|
|
|
|
|
#define CMD_RW_BOTH 0x30 // Least followed by Most Significant Byte
|
2023-04-28 20:51:51 +01:00
|
|
|
|
2024-09-17 17:48:26 +01:00
|
|
|
#define CMD_COUNTER0 0x00
|
|
|
|
|
#define CMD_COUNTER1 0x40
|
|
|
|
|
#define CMD_COUNTER2 0x80
|
|
|
|
|
#define CMD_READBACK 0xc0
|
2023-04-28 20:51:51 +01:00
|
|
|
|
2024-09-17 17:48:26 +01:00
|
|
|
#define PIT_FREQUENCY 1193182
|
2023-04-28 20:51:51 +01:00
|
|
|
|
|
|
|
|
static volatile unsigned long long ticks = 0;
|
2023-03-20 20:21:44 +00:00
|
|
|
|
2023-03-19 20:36:36 +00:00
|
|
|
static int pit_callback(void)
|
|
|
|
|
{
|
2023-04-28 20:51:51 +01:00
|
|
|
clock_advance(1);
|
|
|
|
|
ticks++;
|
|
|
|
|
|
2023-03-19 20:36:36 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-17 17:48:26 +01:00
|
|
|
static struct irq_hook pit_irq_hook = {.irq_callback = pit_callback};
|
2023-03-19 20:36:36 +00:00
|
|
|
|
2023-03-20 20:21:44 +00:00
|
|
|
void pit_start(unsigned int hz)
|
2023-03-19 20:36:36 +00:00
|
|
|
{
|
|
|
|
|
hook_irq(IRQ0, &pit_irq_hook);
|
2023-04-28 20:51:51 +01:00
|
|
|
|
|
|
|
|
unsigned int divisor = PIT_FREQUENCY / hz;
|
|
|
|
|
outportb(PIT_CMD, CMD_BINARY | CMD_MODE2 | CMD_RW_BOTH | CMD_COUNTER0);
|
|
|
|
|
outportb(PIT_COUNTER0, divisor);
|
|
|
|
|
outportb(PIT_COUNTER0, divisor >> 8);
|
2023-03-20 20:21:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pit_stop(void)
|
|
|
|
|
{
|
2023-04-28 20:51:51 +01:00
|
|
|
unsigned int divisor = PIT_FREQUENCY / 20;
|
|
|
|
|
outportb(PIT_CMD, CMD_BINARY | CMD_MODE4 | CMD_RW_BOTH | CMD_COUNTER0);
|
|
|
|
|
outportb(PIT_COUNTER0, divisor);
|
|
|
|
|
outportb(PIT_COUNTER0, divisor >> 8);
|
2023-03-20 20:21:44 +00:00
|
|
|
|
|
|
|
|
unhook_irq(IRQ0, &pit_irq_hook);
|
|
|
|
|
}
|