}
intr_disable();
+ BKL_LOCK();
/* remove the probe */
rm_irq_handler(&calib_clk);
ia32_msr_read(IA32_APIC_BASE, &msr.hi, &msr.lo);
+#if 0
+ /*FIXME this is a problem on AP */
/*
* FIXME if the location is different (unlikely) then the one we expect,
* update it
}
lapic_addr = phys2vir(msr.lo & ~((1 << 12) - 1));
}
+#endif
msr.lo |= (1 << IA32_APIC_BASE_ENABLE_BIT);
ia32_msr_write(IA32_APIC_BASE, msr.hi, msr.lo);
/* Set up idt tables for smp mode.
*/
- vir_bytes local_timer_intr_handler;
int is_bsp = is_boot_apic(apicid());
if (reset) {
/* configure the timer interupt handler */
if (is_bsp) {
- local_timer_intr_handler = (vir_bytes) lapic_bsp_timer_int_handler;
- BOOT_VERBOSE(printf("Initiating BSP timer handler\n"));
- } else {
- local_timer_intr_handler = (vir_bytes) lapic_ap_timer_int_handler;
- BOOT_VERBOSE(printf("Initiating AP timer handler\n"));
+ BOOT_VERBOSE(printf("Initiating APIC timer handler\n"));
+ /* register the timer interrupt handler for this CPU */
+ int_gate(APIC_TIMER_INT_VECTOR, (vir_bytes) lapic_timer_int_handler,
+ PRESENT | INT_GATE_TYPE | (INTR_PRIVILEGE << DPL_SHIFT));
}
- /* register the timer interrupt handler for this CPU */
- int_gate(APIC_TIMER_INT_VECTOR, (vir_bytes) local_timer_intr_handler,
- PRESENT | INT_GATE_TYPE | (INTR_PRIVILEGE << DPL_SHIFT));
}
PRIVATE int acpi_get_ioapics(struct io_apic * ioa, unsigned * nioa, unsigned max)
#include <assert.h>
#include "clock.h"
-#include "debug.h"
#ifdef CONFIG_WATCHDOG
#include "watchdog.h"
* The boot processos timer interrupt handler. In addition to non-boot cpus it
* keeps real time and notifies the clock task if need be
*/
-extern unsigned ooq_msg;
-PUBLIC int bsp_timer_int_handler(void)
+PUBLIC int timer_int_handler(void)
{
- unsigned ticks;
+ /* Update user and system accounting times. Charge the current process
+ * for user time. If the current process is not billable, that is, if a
+ * non-user process is running, charge the billable process for system
+ * time as well. Thus the unbillable process' user time is the billable
+ * user's system time.
+ */
+
+ struct proc * p, * billp;
+
+ /* FIXME watchdog for slave cpus! */
+#ifdef CONFIG_WATCHDOG
+ /*
+ * we need to know whether local timer ticks are happening or whether
+ * the kernel is locked up. We don't care about overflows as we only
+ * need to know that it's still ticking or not
+ */
+ watchdog_local_timer_ticks++;
+#endif
+
+ if (cpu_is_bsp(cpuid))
+ realtime++;
+
+ /* Update user and system accounting times. Charge the current process
+ * for user time. If the current process is not billable, that is, if a
+ * non-user process is running, charge the billable process for system
+ * time as well. Thus the unbillable process' user time is the billable
+ * user's system time.
+ */
- if(minix_panicing)
- return 0;
+ p = get_cpulocal_var(proc_ptr);
+ billp = get_cpulocal_var(bill_ptr);
- /* Get number of ticks and update realtime. */
- ticks = lost_ticks + 1;
- lost_ticks = 0;
- realtime += ticks;
+ p->p_user_time++;
- ap_timer_int_handler();
+ if (! (priv(p)->s_flags & BILLABLE)) {
+ billp->p_sys_time++;
+ }
- /* if a timer expired, notify the clock task */
- if ((next_timeout <= realtime)) {
- tmrs_exptimers(&clock_timers, realtime, NULL);
- next_timeout = (clock_timers == NULL) ?
- TMR_NEVER : clock_timers->tmr_exp_time;
+ /* Decrement virtual timers, if applicable. We decrement both the
+ * virtual and the profile timer of the current process, and if the
+ * current process is not billable, the timer of the billed process as
+ * well. If any of the timers expire, do_clocktick() will send out
+ * signals.
+ */
+ if ((p->p_misc_flags & MF_VIRT_TIMER)){
+ p->p_virt_left--;
+ }
+ if ((p->p_misc_flags & MF_PROF_TIMER)){
+ p->p_prof_left--;
+ }
+ if (! (priv(p)->s_flags & BILLABLE) &&
+ (billp->p_misc_flags & MF_PROF_TIMER)){
+ billp->p_prof_left--;
}
- if (do_serial_debug)
- do_ser_debug();
+ /*
+ * Check if a process-virtual timer expired. Check current process, but
+ * also bill_ptr - one process's user time is another's system time, and
+ * the profile timer decreases for both!
+ */
+ vtimer_check(p);
+
+ if (p != billp)
+ vtimer_check(billp);
+
+ /* Update load average. */
+ load_update();
+
+ if (cpu_is_bsp(cpuid)) {
+ /* if a timer expired, notify the clock task */
+ if ((next_timeout <= realtime)) {
+ tmrs_exptimers(&clock_timers, realtime, NULL);
+ next_timeout = (clock_timers == NULL) ?
+ TMR_NEVER : clock_timers->tmr_exp_time;
+ }
+
+ if (do_serial_debug)
+ do_ser_debug();
+ }
return(1); /* reenable interrupts */
}
}
/* Cumulation. How many processes are ready now? */
- for(q = 0; q < NR_SCHED_QUEUES; q++)
- for(p = rdy_head[q]; p; p = p->p_nextready)
+ for(q = 0; q < NR_SCHED_QUEUES; q++) {
+ for(p = rdy_head[q]; p != NULL; p = p->p_nextready) {
enqueued++;
+ }
+ }
kloadinfo.proc_load_history[slot] += enqueued;
kloadinfo.last_clock = realtime;
}
-/*
- * Timer interupt handler. This is the only thing executed on non boot
- * processors. It is called by bsp_timer_int_handler() on the boot processor
- */
-PUBLIC int ap_timer_int_handler(void)
-{
-
- /* Update user and system accounting times. Charge the current process
- * for user time. If the current process is not billable, that is, if a
- * non-user process is running, charge the billable process for system
- * time as well. Thus the unbillable process' user time is the billable
- * user's system time.
- */
-
- const unsigned ticks = 1;
- struct proc * p, * billp;
-
-#ifdef CONFIG_WATCHDOG
- /*
- * we need to know whether local timer ticks are happening or whether
- * the kernel is locked up. We don't care about overflows as we only
- * need to know that it's still ticking or not
- */
- watchdog_local_timer_ticks++;
-#endif
-
- /* Update user and system accounting times. Charge the current process
- * for user time. If the current process is not billable, that is, if a
- * non-user process is running, charge the billable process for system
- * time as well. Thus the unbillable process' user time is the billable
- * user's system time.
- */
-
- p = get_cpulocal_var(proc_ptr);
- billp = get_cpulocal_var(bill_ptr);
-
- p->p_user_time += ticks;
-
- /* FIXME make this ms too */
- if (! (priv(p)->s_flags & BILLABLE)) {
- billp->p_sys_time += ticks;
- }
-
- /* Decrement virtual timers, if applicable. We decrement both the
- * virtual and the profile timer of the current process, and if the
- * current process is not billable, the timer of the billed process as
- * well. If any of the timers expire, do_clocktick() will send out
- * signals.
- */
- if ((p->p_misc_flags & MF_VIRT_TIMER)){
- p->p_virt_left -= ticks;
- }
- if ((p->p_misc_flags & MF_PROF_TIMER)){
- p->p_prof_left -= ticks;
- }
- if (! (priv(p)->s_flags & BILLABLE) &&
- (billp->p_misc_flags & MF_PROF_TIMER)){
- billp->p_prof_left -= ticks;
- }
-
- /*
- * Check if a process-virtual timer expired. Check current process, but
- * also bill_ptr - one process's user time is another's system time, and
- * the profile timer decreases for both!
- */
- vtimer_check(p);
-
- if (p != billp)
- vtimer_check(billp);
-
- /* Update load average. */
- load_update();
-
- return 1;
-}
-
PUBLIC int boot_cpu_init_timer(unsigned freq)
{
if (arch_init_local_timer(freq))
return -1;
if (arch_register_local_timer_handler(
- (irq_handler_t) bsp_timer_int_handler))
+ (irq_handler_t) timer_int_handler))
return -1;
return 0;
}
+
+PUBLIC int app_cpu_init_timer(unsigned freq)
+{
+ if (arch_init_local_timer(freq))
+ return -1;
+}