diff --git a/src/kernel/cpu/timer.c b/src/kernel/cpu/timer.c index 5acb253..7f5fa31 100644 --- a/src/kernel/cpu/timer.c +++ b/src/kernel/cpu/timer.c @@ -14,7 +14,7 @@ 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 uint8_t spkr = inb(PC_SPKR); spkr &= ~0x1; @@ -24,7 +24,7 @@ static void pit_setup(uint8_t ms) { outb(PIT_CMD, 0x80 | 0x30); // 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 >> 8) & 0xFF); } @@ -41,29 +41,33 @@ static void pit_wait() { } 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_LVT(LVT_TIMER)) = 1<<16; // Mask + // Bit 16: Mask interrupt + APIC_REG(APIC_LVT(LVT_TIMER)) = 1<<16; APIC_REG(APIC_TIMER_INIT) = 0xFFFFFFFF; pit_wait(); 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) { + // Divide bus clock by 16 APIC_REG(APIC_TIMER_DIVIDER) = 0xB; 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; registers *apic_timer_handler(registers *r) { current_cpu->timer_ticks++; - reset_apic_timer(1000); irq_ack(); return r; }