static void rt_timer_tick(void) { cpu_used[NR_RT_CPUS]++; if (passed++ < 5) { t0 = rdtsc(); } else { t = rdtsc(); if ((jit = t - t0 - imuldiv(rt_times.periodic_tick, CPU_FREQ, FREQ_8254)) < 0) { jit = -jit; } if (jit > maxj) { maxj = jit; } t0 = t; } rt_times.tick_time = rt_times.intr_time; rt_times.intr_time = rt_times.tick_time + rt_times.periodic_tick; rt_set_timer_delay(0); if (rt_times.tick_time >= rt_times.linux_time) { rt_times.linux_time += rt_times.linux_tick; rt_pend_linux_irq(TIMER_8254_IRQ); } if (Mode) { rt_sem_signal(&sem); } else { rt_task_resume(&thread); } }
static int rt_timer_tick_ext(int irq, unsigned long data) { RTIME t; int jit; if (loops++ < INILOOPS) { t0 = rdtsc(); } else { t = rdtsc(); if (use_parport) { outb(bit = 1 - bit, PARPORT); } if ((jit = abs((int)(t - t0) - bus_period)) > maxj) { maxj = jit; if (maxj > bus_threshold) { int msg; msg = imuldiv(maxj, 1000000000, CPU_FREQ); rtf_put(0, &msg, sizeof(msg)); } } t0 = t; } rt_times.tick_time = rt_times.intr_time; rt_times.intr_time = rt_times.tick_time + rt_times.periodic_tick; rt_set_timer_delay(0); if (rt_times.tick_time >= rt_times.linux_time) { rt_times.linux_time += rt_times.linux_tick; hard_sti(); rt_pend_linux_irq(TIMER_8254_IRQ); return 0; } hard_sti(); return 1; }
static int rt_timer_tick_ext(int irq, unsigned long data) { int ret = 1; cpu_used[NR_RT_CPUS]++; if (passed++ < 5) { t0 = rdtsc(); } else { t = rdtsc(); if ((jit = t - t0 - imuldiv(rt_times.periodic_tick, CPU_FREQ, FREQ_8254)) < 0) { jit = -jit; } if (jit > maxj) { maxj = jit; } t0 = t; } rt_times.tick_time = rt_times.intr_time; rt_times.intr_time = rt_times.tick_time + rt_times.periodic_tick; rt_set_timer_delay(0); if (rt_times.tick_time >= rt_times.linux_time) { rt_times.linux_time += rt_times.linux_tick; rt_pend_linux_irq(TIMER_8254_IRQ); ret = 0; } rt_sched_lock(); if (Mode) { rt_sem_signal(&sem); } else { rt_task_resume(&thread); } rt_sched_unlock(); return ret; }
static void timer_tick(void) { rt_times.tick_time = rt_times.intr_time; rt_times.intr_time = rt_times.tick_time + rt_times.periodic_tick; rt_set_timer_delay(0); if (rt_times.tick_time >= rt_times.linux_time) { rt_times.linux_time += rt_times.linux_tick; rt_pend_linux_irq(TIMER_8254_IRQ); } if (run) { if (rt_waiting_return(tasknode, taskport)) { overuns++; } switch(run) { case 1: RT_sem_signal(tasknode, -taskport, rmt_sem); rt_printk("SEM SIGNAL %d\n", ++cnt); break; case 2: RT_task_resume(tasknode, -taskport, rmt_task); rt_printk("TASK RESUME %d\n", ++cnt); break; case 3: RT_send_if(tasknode, -taskport, rmt_task, run); rt_printk("TASK SEND %d\n", ++cnt); break; } } }
int rtai_calibrate_TC (void) { unsigned long flags; RTIME t, dt; int i; flags = rtai_critical_enter(NULL); rt_set_timer_delay(LATCH); t = rtai_rdtsc(); for (i = 0; i < 10000; i++) { rt_set_timer_delay(LATCH); } dt = rtai_rdtsc() - t; rtai_critical_exit(flags); return rtai_imuldiv(dt, 100000, RTAI_CPU_FREQ); }
void rt_free_timer (void) { unsigned long flags; rt_periodic = 0; __ipipe_mach_timerstolen = 0; // ipipe can reprogram timer for Linux now at91_tc_write(AT91_TC_CMR, AT91_TC_TIMER_CLOCK3); // back to oneshot mode rt_set_timer_delay(__ipipe_mach_ticks_per_jiffy); // regular timer delay rt_release_irq(RTAI_TIMER_IRQ); // free this irq rtai_save_flags_and_cli(flags); // critical section extern_timer_isr = NULL; // let ipipe run as normally rtai_restore_flags(flags); // end of critical section }
static void rt_timer_tick(void) { char wakeup; rtf_put(CMDF, &wakeup, sizeof(wakeup)); rt_times.tick_time = rt_times.intr_time; rt_times.intr_time = rt_times.tick_time + rt_times.periodic_tick; rt_set_timer_delay(0); if (rt_times.tick_time >= rt_times.linux_time) { if (rt_times.linux_tick > 0) { rt_times.linux_time += rt_times.linux_tick; } rt_pend_linux_irq(TIMER_8254_IRQ); } }
int rt_request_timer (void (*handler)(void), unsigned tick, int use_apic) { unsigned long flags; flags = rtai_critical_enter(NULL); __ipipe_mach_timerstolen = 1; // no need to reprogram timer on timer_tick() call rt_times.tick_time = rtai_rdtsc(); rt_times.linux_tick = __ipipe_mach_ticks_per_jiffy; if (tick > 0) { rt_periodic = 1; /* Periodic setup -- Use the built-in Adeos service directly. */ if (tick > __ipipe_mach_ticks_per_jiffy) { tick = __ipipe_mach_ticks_per_jiffy; } rt_times.intr_time = rt_times.tick_time + tick; rt_times.linux_time = rt_times.tick_time + rt_times.linux_tick; rt_times.periodic_tick = tick; /* Prepare TCx to reload automaticly on RC compare */ at91_tc_write(AT91_TC_CCR, AT91_TC_CLKDIS); at91_tc_write(AT91_TC_CMR, AT91_TC_TIMER_CLOCK3 | AT91_TC_WAVESEL_UP_AUTO | AT91_TC_WAVE); at91_tc_write(AT91_TC_RC, rt_times.periodic_tick); at91_tc_write(AT91_TC_CCR, AT91_TC_CLKEN | AT91_TC_SWTRG); } else { rt_periodic = 0; /* Oneshot setup. */ rt_times.intr_time = rt_times.tick_time + rt_times.linux_tick; rt_times.linux_time = rt_times.tick_time + rt_times.linux_tick; rt_times.periodic_tick = rt_times.linux_tick; /* Prepare TCx behaviour as oneshot timer */ at91_tc_write(AT91_TC_CMR, AT91_TC_TIMER_CLOCK3); rt_set_timer_delay(rt_times.periodic_tick); } rt_release_irq(RTAI_TIMER_IRQ); rt_request_irq(RTAI_TIMER_IRQ, (rt_irq_handler_t)handler, NULL, 0); extern_timer_isr = rtai_timer_handler; // shunt for ipipe.c __ipipe_grab_irq rtai_critical_exit(flags); return 0; }
int rt_request_timer (void (*handler)(void), unsigned tick, int use_apic) { unsigned long flags; rtai_save_flags_and_cli(flags); // read tick values: current time base register and linux tick rt_times.tick_time = rtai_rdtsc(); rt_times.linux_tick = tb_ticks_per_jiffy; if (tick > 0) { // periodic Mode // if tick is greater than tb_ticks_per_jiffy schedule a linux timer first if (tick > tb_ticks_per_jiffy) { tick = tb_ticks_per_jiffy; } rt_times.intr_time = rt_times.tick_time + tick; rt_times.linux_time = rt_times.tick_time + rt_times.linux_tick; rt_times.periodic_tick = tick; #ifdef CONFIG_40x /* Set the PIT auto-reload mode */ mtspr(SPRN_TCR, mfspr(SPRN_TCR) | TCR_ARE); /* Set the PIT reload value and just let it run. */ mtspr(SPRN_PIT, tick); #endif /* CONFIG_40x */ } else { //one-shot Mode // in this mode we set all to decade at linux_tick rt_times.intr_time = rt_times.tick_time + rt_times.linux_tick; rt_times.linux_time = rt_times.tick_time + rt_times.linux_tick; rt_times.periodic_tick = rt_times.linux_tick; #ifdef CONFIG_40x /* Disable the PIT auto-reload mode */ mtspr(SPRN_TCR, mfspr(SPRN_TCR) & ~TCR_ARE); #endif /* CONFIG_40x */ } // request an IRQ and register it rt_release_irq(RTAI_TIMER_DECR_IRQ); decr_timer_handler = handler; // pass throught ipipe: register immediate timer_trap handler // on i386 for a periodic mode is rt_set_timer_delay(tick); -> is set rate generator at tick; in one shot set LATCH all for the 8254 timer. Here is the same. rtai_disarm_decr(rtai_cpuid(), 1); rt_set_timer_delay(rt_times.periodic_tick); rtai_set_gate_vector(DECR_VECTOR, rtai_decr_timer_handler, 0); rtai_request_tickdev(); rtai_restore_flags(flags); return 0; }
static void rt_timer_tick(void) { struct rt_tasklet_struct *tasklet; rt_times.tick_time = rt_times.intr_time; rt_times.intr_time = rt_times.tick_time + rt_times.periodic_tick; rt_set_timer_delay(0); if (rt_times.tick_time >= rt_times.linux_time) { if (rt_times.linux_tick > 0) { rt_times.linux_time += rt_times.linux_tick; } rt_pend_linux_irq(TIMER_8254_IRQ); } if ((tasklet = rt_find_tasklet_by_id(nam2num("TSKLET")))) { rt_exec_tasklet(tasklet); } }
static void timer_tick(void) { rt_times.tick_time = rt_times.intr_time; rt_times.intr_time = rt_times.tick_time + rt_times.periodic_tick; rt_set_timer_delay(0); if (rt_times.tick_time >= rt_times.linux_time) { if (rt_times.linux_tick) { rt_times.linux_time += rt_times.linux_tick; } rt_pend_linux_irq(TIMER_8254_IRQ); } if (run) { if (rt_waiting_return(tasknode, taskport)) { overuns++; } rt_task_resume(&sup_task); } }
int rt_request_timers(void *rtai_time_handler) { int cpuid; if (!rt_linux_hrt_next_shot) { rt_linux_hrt_next_shot = _rt_linux_hrt_next_shot; } for (cpuid = 0; cpuid < num_active_cpus(); cpuid++) { struct rt_times *rtimes; int ret; ret = ipipe_timer_start(rtai_time_handler, rt_linux_hrt_set_mode, rt_linux_hrt_next_shot, cpuid); if (ret < 0 || ret == CLOCK_EVT_MODE_SHUTDOWN) { printk("THE TIMERS REQUEST FAILED RETURNING %d FOR CPUID %d, FREEING ALL TIMERS.\n", ret, cpuid); do { ipipe_timer_stop(cpuid); } while (--cpuid >= 0); return -1; } rtimes = &rt_smp_times[cpuid]; if (ret == CLOCK_EVT_MODE_ONESHOT || ret == CLOCK_EVT_MODE_UNUSED) { rtimes->linux_tick = 0; } else { rt_smp_times[0].linux_tick = rtai_llimd((1000000000 + HZ/2)/HZ, rtai_tunables.clock_freq, 1000000000); } rtimes->tick_time = rtai_rdtsc(); rtimes->intr_time = rtimes->tick_time + rtimes->linux_tick; rtimes->linux_time = rtimes->tick_time + rtimes->linux_tick; rtimes->periodic_tick = rtimes->linux_tick; } #if 0 // #ifndef CONFIG_X86_LOCAL_APIC, for calibrating 8254 with our set delay rtai_cli(); outb(0x30, 0x43); rt_set_timer_delay(rtai_tunables.clock_freq/50000); rtai_sti(); #endif return 0; }