SMP - Single shot local timer
- APIC timer always reprogrammed if expired - timer tick never happens when in kernel => never immediate return from userspace to kernel because of a buffered interrupt - renamed argument to lapic_set_timer_one_shot() - removed arch_ prefix from timer functions
This commit is contained in:
parent
e87d29171f
commit
e2701da5a9
8 changed files with 26 additions and 27 deletions
|
@ -499,7 +499,7 @@ PRIVATE void apic_calibrate_clocks(unsigned cpu)
|
|||
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;
|
||||
|
@ -508,7 +508,6 @@ PUBLIC void lapic_set_timer_one_shot(const u32_t value)
|
|||
|
||||
ticks_per_us = lapic_bus_freq[cpu] / 1000000;
|
||||
|
||||
/* calculate divisor and count from value */
|
||||
lvtt = APIC_TDCR_1;
|
||||
lapic_write(LAPIC_TIMER_DCR, lvtt);
|
||||
|
||||
|
@ -516,7 +515,7 @@ PUBLIC void lapic_set_timer_one_shot(const u32_t value)
|
|||
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)
|
||||
|
@ -543,13 +542,16 @@ PUBLIC void lapic_stop_timer(void)
|
|||
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)
|
||||
|
|
|
@ -117,7 +117,7 @@ PRIVATE void estimate_cpu_freq(void)
|
|||
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 */
|
||||
|
@ -140,7 +140,7 @@ PUBLIC int arch_init_local_timer(unsigned freq)
|
|||
return 0;
|
||||
}
|
||||
|
||||
PUBLIC void arch_stop_local_timer(void)
|
||||
PUBLIC void stop_local_timer(void)
|
||||
{
|
||||
#ifdef CONFIG_APIC
|
||||
if (lapic_addr) {
|
||||
|
@ -153,19 +153,16 @@ PUBLIC void arch_stop_local_timer(void)
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -269,7 +266,7 @@ PUBLIC void context_stop_idle(void)
|
|||
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)
|
||||
|
|
|
@ -238,7 +238,6 @@ PRIVATE void ap_finish_booting(void)
|
|||
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);
|
||||
|
|
|
@ -224,10 +224,10 @@ PRIVATE void load_update(void)
|
|||
|
||||
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;
|
||||
|
||||
|
@ -236,6 +236,6 @@ PUBLIC int boot_cpu_init_timer(unsigned freq)
|
|||
|
||||
PUBLIC int app_cpu_init_timer(unsigned freq)
|
||||
{
|
||||
if (arch_init_local_timer(freq))
|
||||
if (init_local_timer(freq))
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -9,12 +9,12 @@ _PROTOTYPE(int app_cpu_init_timer, (unsigned freq));
|
|||
|
||||
_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));
|
||||
|
||||
|
|
|
@ -376,8 +376,8 @@ PUBLIC void minix_shutdown(timer_t *tp)
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -191,7 +191,7 @@ PRIVATE void idle(void)
|
|||
#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
|
||||
|
||||
|
@ -338,10 +338,11 @@ check_misc_flags:
|
|||
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 */
|
||||
|
|
|
@ -30,7 +30,7 @@ PUBLIC void ap_boot_finished(unsigned cpu)
|
|||
PUBLIC void smp_ipi_halt_handler(void)
|
||||
{
|
||||
ipi_ack();
|
||||
arch_stop_local_timer();
|
||||
stop_local_timer();
|
||||
arch_smp_halt_cpu();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue