This commit is contained in:
Thomas Lovén 2022-01-20 23:50:37 +01:00
parent 9ef3c195d0
commit fb87e52a94

View File

@ -14,7 +14,7 @@
volatile uint32_t apic_ticks_per_us = 1; volatile uint32_t apic_ticks_per_us = 1;
static void pit_setup(uint8_t ms) { static void pit_setup(uint64_t us) {
// Disable the pc speaker output // Disable the pc speaker output
uint8_t spkr = inb(PC_SPKR); uint8_t spkr = inb(PC_SPKR);
spkr &= ~0x1; spkr &= ~0x1;
@ -24,7 +24,7 @@ static void pit_setup(uint8_t ms) {
outb(PIT_CMD, 0x80 | 0x30); outb(PIT_CMD, 0x80 | 0x30);
// Set up CH2 for counting down from a number of ms // Set up CH2 for counting down from a number of ms
uint64_t count = PIT_FREQ * ms/1000; uint64_t count = PIT_FREQ * us/1000000;
outb(PIT_CH2, count & 0xFF); outb(PIT_CH2, count & 0xFF);
outb(PIT_CH2, (count >> 8) & 0xFF); outb(PIT_CH2, (count >> 8) & 0xFF);
} }
@ -41,29 +41,33 @@ static void pit_wait() {
} }
static uint64_t calibrate_apic_timer() { static uint64_t calibrate_apic_timer() {
pit_setup(10); uint64_t wait_time = 10000;
pit_setup(wait_time);
// Divide bus clock by 16
APIC_REG(APIC_TIMER_DIVIDER) = 0xB; APIC_REG(APIC_TIMER_DIVIDER) = 0xB;
APIC_REG(APIC_LVT(LVT_TIMER)) = 1<<16; // Mask // Bit 16: Mask interrupt
APIC_REG(APIC_LVT(LVT_TIMER)) = 1<<16;
APIC_REG(APIC_TIMER_INIT) = 0xFFFFFFFF; APIC_REG(APIC_TIMER_INIT) = 0xFFFFFFFF;
pit_wait(); pit_wait();
uint32_t ticks = APIC_REG(APIC_TIMER_CURRENT); uint32_t ticks = APIC_REG(APIC_TIMER_CURRENT);
return (0xFFFFFFFF-ticks)/10/1000; return (0xFFFFFFFF-ticks)/wait_time;
} }
void reset_apic_timer(uint64_t us) { void reset_apic_timer(uint64_t us) {
// Divide bus clock by 16
APIC_REG(APIC_TIMER_DIVIDER) = 0xB; APIC_REG(APIC_TIMER_DIVIDER) = 0xB;
APIC_REG(APIC_TIMER_INIT) = us*current_cpu->timer_freq; APIC_REG(APIC_TIMER_INIT) = us*current_cpu->timer_freq;
APIC_REG(APIC_LVT(LVT_TIMER)) = 0x0 | IRQ_INTERRUPT(IRQ_TIMER); // Bit 17: Periodic timer mode
APIC_REG(APIC_LVT(LVT_TIMER)) = 1<<17 | IRQ_INTERRUPT(IRQ_TIMER);
} }
volatile int ctr = 0; volatile int ctr = 0;
registers *apic_timer_handler(registers *r) { registers *apic_timer_handler(registers *r) {
current_cpu->timer_ticks++; current_cpu->timer_ticks++;
reset_apic_timer(1000);
irq_ack(); irq_ack();
return r; return r;
} }