diff --git a/kernel/arch/x86_64/cmos.c b/kernel/arch/x86_64/cmos.c index b39f9c20..1593e49a 100644 --- a/kernel/arch/x86_64/cmos.c +++ b/kernel/arch/x86_64/cmos.c @@ -256,19 +256,27 @@ void arch_tick_others(void); static uint64_t time_slice_basis = 0; -int cmos_time_stuff(struct regs *r) { +static spin_lock_t clock_lock = { 0 }; +void arch_update_clock(void) { uint64_t clock_ticks = read_tsc() / tsc_mhz; uint64_t timer_ticks, timer_subticks; + spin_lock(clock_lock); update_ticks(clock_ticks, &timer_ticks, &timer_subticks); - wakeup_sleepers(timer_ticks, timer_subticks); - irq_ack(0); - if (time_slice_basis + SUBSECONDS_PER_SECOND/4 <= clock_ticks) { update_process_usage(clock_ticks - time_slice_basis, tsc_mhz); time_slice_basis = clock_ticks; } + spin_unlock(clock_lock); + + wakeup_sleepers(timer_ticks, timer_subticks); + +} + +int cmos_time_stuff(struct regs *r) { + arch_update_clock(); + + irq_ack(0); - arch_tick_others(); switch_task(1); asm volatile ( ".global _ret_from_preempt_source\n" diff --git a/kernel/arch/x86_64/idt.c b/kernel/arch/x86_64/idt.c index e122ba4c..dce3cf1d 100644 --- a/kernel/arch/x86_64/idt.c +++ b/kernel/arch/x86_64/idt.c @@ -339,6 +339,8 @@ struct regs * isr_handler(struct regs * r) { return r; } case 123: { + extern void arch_update_clock(void); + arch_update_clock(); switch_task(1); return r; } diff --git a/kernel/arch/x86_64/smp.c b/kernel/arch/x86_64/smp.c index 50019634..0294162b 100644 --- a/kernel/arch/x86_64/smp.c +++ b/kernel/arch/x86_64/smp.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -123,6 +124,20 @@ void ap_main(void) { /* Enable our spurious vector register */ *((volatile uint32_t*)(lapic_final + 0x0F0)) = 0x127; + *((volatile uint32_t*)(lapic_final + 0x320)) = 0x7b; + *((volatile uint32_t*)(lapic_final + 0x3e0)) = 1; + + uint64_t before = arch_perf_timer(); + *((volatile uint32_t*)(lapic_final + 0x380)) = 1000000; + while (*((volatile uint32_t*)(lapic_final + 0x390))); + uint64_t after = arch_perf_timer(); + + uint64_t ms = (after-before)/arch_cpu_mhz(); + uint64_t target = 10000000000UL / ms; + + *((volatile uint32_t*)(lapic_final + 0x3e0)) = 1; + *((volatile uint32_t*)(lapic_final + 0x320)) = 0x7b | 0x20000; + *((volatile uint32_t*)(lapic_final + 0x380)) = target; /* Set our pml pointers */ this_core->current_pml = &init_page_region[0];