diff --git a/kernel-src/arch/x86-64/apic.c b/kernel-src/arch/x86-64/apic.c index 96ccc918..8d1f2486 100644 --- a/kernel-src/arch/x86-64/apic.c +++ b/kernel-src/arch/x86-64/apic.c @@ -5,6 +5,7 @@ #include #include #include +#include #define IOAPIC_REG_ID 0 #define IOAPIC_REG_ENTRYCOUNT 1 @@ -190,6 +191,45 @@ void arch_apic_initap() { // TODO enable interrupts here } +void arch_apic_eoi() { + writelapic(APIC_REG_EOI, 0); +} + +void static timerisr(isr_t *isr, context_t *context) { + +} + +static void armtimer(time_t ticks) { + writelapic(APIC_TIMER_INITIALCOUNT, ticks); +} + +void arch_apic_timerinit() { + isr_t *isr = interrupt_allocate(timerisr, arch_apic_eoi, 0); // TODO when priorities are defined, change it here + __assert(isr); + int vec = isr->id & 0xff; + + writelapic(APIC_TIMER_DIVIDE, 3); // divide by 16 because us precision is desired and most amd64 machines will have the clock frequency at >1GHz anyways + + void (*uswait)(time_t) = NULL; + + if (arch_hpet_exists()) + uswait = arch_hpet_waitus; + + __assert(uswait); + + writelapic(APIC_TIMER_INITIALCOUNT, 0xffffffff); + + uswait(1000); + + time_t ticksperus = (0xffffffff - readlapic(APIC_TIMER_COUNT)) / 1000; + + writelapic(APIC_TIMER_INITIALCOUNT, 0); + + printf("cpu%lu: local apic timer calibrated at %lu ticks per us. ISR vector %lu\n", _cpu()->id, ticksperus, vec); + + writelapic(APIC_LVT_TIMER, vec); +} + void arch_apic_init() { madt = arch_acpi_findtable("APIC", 0); __assert(madt); diff --git a/kernel-src/arch/x86-64/main.c b/kernel-src/arch/x86-64/main.c index dac3d9c8..c6491f37 100644 --- a/kernel-src/arch/x86-64/main.c +++ b/kernel-src/arch/x86-64/main.c @@ -34,5 +34,6 @@ void kernel_entry() { // XXX fall back to another clock source time_t u = arch_hpet_init(); timekeeper_init(arch_hpet_ticks, u); + arch_apic_timerinit(); __assert(!"kernel entry end"); } diff --git a/kernel-src/include/x86-64/arch/apic.h b/kernel-src/include/x86-64/arch/apic.h index 9d2b6f53..8a505354 100644 --- a/kernel-src/include/x86-64/arch/apic.h +++ b/kernel-src/include/x86-64/arch/apic.h @@ -1,6 +1,7 @@ #ifndef _APIC_H #define _APIC_H +void arch_apic_timerinit(); void arch_apic_init(); void arch_apic_initap();