BOOT_VERBOSE(cpu_print_freq(cpuid));
}
-PUBLIC void lapic_set_timer_one_shot(const u32_t value)
+PUBLIC void lapic_set_timer_one_shot(const u32_t usec)
{
/* sleep in micro seconds */
u32_t lvtt;
ticks_per_us = lapic_bus_freq[cpu] / 1000000;
- /* calculate divisor and count from value */
lvtt = APIC_TDCR_1;
lapic_write(LAPIC_TIMER_DCR, lvtt);
lvtt = APIC_TIMER_INT_VECTOR;
lapic_write(LAPIC_LVTTR, lvtt);
- lapic_write(LAPIC_TIMER_ICR, value * ticks_per_us);
+ lapic_write(LAPIC_TIMER_ICR, usec * ticks_per_us);
}
PUBLIC void lapic_set_timer_periodic(const unsigned freq)
u32_t lvtt;
lvtt = lapic_read(LAPIC_LVTTR);
lapic_write(LAPIC_LVTTR, lvtt | APIC_LVTT_MASK);
+ /* zero the current counter so it can be restarted again */
+ lapic_write(LAPIC_TIMER_ICR, 0);
+ lapic_write(LAPIC_TIMER_CCR, 0);
}
PUBLIC void lapic_restart_timer(void)
{
- u32_t lvtt;
- lvtt = lapic_read(LAPIC_LVTTR);
- lapic_write(LAPIC_LVTTR, lvtt & ~APIC_LVTT_MASK);
+ /* restart the timer only if the counter reached zero, i.e. expired */
+ if (lapic_read(LAPIC_TIMER_CCR) == 0)
+ lapic_set_timer_one_shot(1000000/system_hz);
}
PUBLIC void lapic_microsec_sleep(unsigned count)
BOOT_VERBOSE(cpu_print_freq(cpuid));
}
-PUBLIC int arch_init_local_timer(unsigned freq)
+PUBLIC int init_local_timer(unsigned freq)
{
#ifdef CONFIG_APIC
/* if we know the address, lapic is enabled and we should use it */
return 0;
}
-PUBLIC void arch_stop_local_timer(void)
+PUBLIC void stop_local_timer(void)
{
#ifdef CONFIG_APIC
if (lapic_addr) {
}
}
-PUBLIC void arch_restart_local_timer(void)
+PUBLIC void restart_local_timer(void)
{
#ifdef CONFIG_APIC
if (lapic_addr) {
lapic_restart_timer();
- } else
-#endif
- {
- init_8253A_timer(system_hz);
}
+#endif
}
-PUBLIC int arch_register_local_timer_handler(const irq_handler_t handler)
+PUBLIC int register_local_timer_handler(const irq_handler_t handler)
{
#ifdef CONFIG_APIC
if (lapic_addr) {
context_stop(get_cpulocal_var_ptr(idle_proc));
if (is_idle)
- arch_restart_local_timer();
+ restart_local_timer();
}
PUBLIC u64_t ms_2_cpu_time(unsigned ms)
panic("FATAL : failed to initialize timer interrupts CPU %d, "
"cannot continue without any clock source!", cpu);
}
- printf("CPU %d local APIC timer is ticking\n", cpu);
/* FIXME assign CPU local idle structure */
get_cpulocal_var(proc_ptr) = get_cpulocal_var_ptr(idle_proc);
PUBLIC int boot_cpu_init_timer(unsigned freq)
{
- if (arch_init_local_timer(freq))
+ if (init_local_timer(freq))
return -1;
- if (arch_register_local_timer_handler(
+ if (register_local_timer_handler(
(irq_handler_t) timer_int_handler))
return -1;
PUBLIC int app_cpu_init_timer(unsigned freq)
{
- if (arch_init_local_timer(freq))
+ if (init_local_timer(freq))
return -1;
}
_PROTOTYPE(int timer_int_handler, (void));
-_PROTOTYPE(int arch_init_local_timer, (unsigned freq));
+_PROTOTYPE(int init_local_timer, (unsigned freq));
/* sto p the local timer ticking */
-_PROTOTYPE(void arch_stop_local_timer, (void));
+_PROTOTYPE(void stop_local_timer, (void));
/* let the time tick again with the original settings after it was stopped */
-_PROTOTYPE(void arch_restart_local_timer, (void));
-_PROTOTYPE(int arch_register_local_timer_handler, (irq_handler_t handler));
+_PROTOTYPE(void restart_local_timer, (void));
+_PROTOTYPE(int register_local_timer_handler, (irq_handler_t handler));
_PROTOTYPE( u64_t ms_2_cpu_time, (unsigned ms));
if (ncpus > 1)
smp_shutdown_aps();
#endif
- arch_stop_local_timer();
hw_intr_disable_all();
+ stop_local_timer();
intr_init(INTS_ORIG, 0);
arch_shutdown(tp ? tmr_arg(tp)->ta_int : RBT_PANIC);
}
#ifdef CONFIG_SMP
/* we don't need to keep time on APs as it is handled on the BSP */
if (cpuid != bsp_cpu_id)
- arch_stop_local_timer();
+ stop_local_timer();
get_cpulocal_var(cpu_is_idle) = 1;
#endif
p->p_schedules++;
#endif
-
p = arch_finish_switch_to_user();
assert(!is_zero64(p->p_cpu_time_left));
+ restart_local_timer();
+
context_stop(proc_addr(KERNEL));
/* If the process isn't the owner of FPU, enable the FPU exception */
PUBLIC void smp_ipi_halt_handler(void)
{
ipi_ack();
- arch_stop_local_timer();
+ stop_local_timer();
arch_smp_halt_cpu();
}