diff --git a/base/arch/x86/hal/hal.c b/base/arch/x86/hal/hal.c index 17463ad5..1795c04b 100644 --- a/base/arch/x86/hal/hal.c +++ b/base/arch/x86/hal/hal.c @@ -159,12 +159,7 @@ static void sync_tsc(unsigned long master, unsigned int slave) long long delta, rt = 0, master_time_stamp = 0; go[MASTER] = 1; - if (smp_call_function(sync_master, (void *)master, -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) - 1, -#endif - 0) < 0) { -// printk(KERN_ERR "sync_tsc: slave CPU %u failed to get attention from master CPU %u!\n", slave, master); + if (smp_call_function(sync_master, (void *)master, 0) < 0) { return; } while (go[MASTER]) { @@ -222,72 +217,3 @@ void cleanup_tsc_sync(void) } #endif /* defined(CONFIG_SMP) && defined(CONFIG_RTAI_DIAG_TSC_SYNC) */ - -#define CAL_LOOPS 200 -int rtai_calibrate_hard_timer(void) -{ - unsigned long flags; - RTIME t; - int i, dt; - - flags = rtai_critical_enter(NULL); -#ifdef CONFIG_X86_LOCAL_APIC - t = rtai_rdtsc(); - for (i = 0; i < CAL_LOOPS; i++) { - apic_write_around(APIC_TMICT, 8000); - } -#else - outb(0x34, 0x43); - t = rtai_rdtsc(); - for (i = 0; i < CAL_LOOPS; i++) { - outb(LATCH & 0xff,0x40); - outb(LATCH >> 8,0x40); - } -#endif - dt = (int)(rtai_rdtsc() - t); - rtai_critical_exit(flags); - return rtai_imuldiv((dt + CAL_LOOPS/2)/CAL_LOOPS, 1000000000, rtai_tunables.cpu_freq); -} -EXPORT_SYMBOL(rtai_calibrate_hard_timer); - -#ifdef CONFIG_SMP - -extern int rtai_sched_affinity; // in Linux "kernel/sched/core.c" -// should we hold a lock for p->cpus_allowed, risky ? -void free_isolcpus_from_linux(void *IsolCpusMask) -{ - struct task_struct *p; - struct cpumask mask; - - rtai_sched_affinity = 1; - for_each_process(p) { - if (p->rtai_tskext(TSKEXT0)) { - continue; - } - cpumask_andnot(&mask, &p->cpus_allowed, (struct cpumask *)IsolCpusMask); - if (!cpumask_weight(&mask)) { - cpumask_complement(&mask, (struct cpumask *)IsolCpusMask); - } -#if 0 // diagnostic - { - char buf[4*sizeof(struct cpumask)]; - cpumask_scnprintf(buf, sizeof(buf), &p->cpus_allowed); - printk("PID: %d, ORIG: %s ", p->pid, buf); - cpulist_scnprintf(buf, sizeof(buf), &p->cpus_allowed); - printk("(%s), ", buf); - cpumask_scnprintf(buf, sizeof(buf), &mask); - printk("NEW: %s ", buf); - cpulist_scnprintf(buf, sizeof(buf), &mask); - printk("(%s).\n", buf); - } -#endif - set_cpus_allowed_ptr(p, &mask); - } -} - -#else - -void free_isolcpus_from_linux(void *IsolCpusMask) { return; } - -#endif - diff --git a/base/arch/x86/hal/hal_64.c b/base/arch/x86/hal/hal_64.c index 0ee8a8dd..b00a8fa8 100644 --- a/base/arch/x86/hal/hal_64.c +++ b/base/arch/x86/hal/hal_64.c @@ -96,7 +96,7 @@ static void rtai_release_tickdev(void); static inline void rtai_setup_periodic_apic (unsigned count, unsigned vector) { apic_read(APIC_LVTT); - apic_write(APIC_LVTT, APIC_LVT_TIMER_PERIODIC | vector); + apic_write(APIC_LVTT, APIC_INTEGRATED(GET_APIC_VERSION(apic_read(APIC_LVR))) ? SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | APIC_LVT_TIMER_PERIODIC | vector : APIC_LVT_TIMER_PERIODIC | vector); apic_read(APIC_TMICT); apic_write(APIC_TMICT, count); } @@ -104,7 +104,7 @@ static inline void rtai_setup_periodic_apic (unsigned count, unsigned vector) static inline void rtai_setup_oneshot_apic (unsigned count, unsigned vector) { apic_read(APIC_LVTT); - apic_write(APIC_LVTT, vector); + apic_write(APIC_LVTT, APIC_INTEGRATED(GET_APIC_VERSION(apic_read(APIC_LVR))) ? SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | vector : vector); apic_read(APIC_TMICT); apic_write(APIC_TMICT, count); } @@ -222,8 +222,34 @@ int rt_release_irq (unsigned irq) return 0; } +#ifdef CONFIG_X86_IO_APIC +int ack_8259A_irq(unsigned int irq) +{ + return 0; +} +#else +int ack_8259A_irq(unsigned int irq) +{ + extern spinlock_t i8259A_lock; + spin_lock(&i8259A_lock); + if (irq & 8) { + outb(0x62,0x20); + outb(0x20,0xA0); + } else { + outb(0x20,0x20); + } + spin_unlock(&i8259A_lock); + return 0; +} +#endif + int rt_set_irq_ack(unsigned irq, int (*irq_ack)(unsigned int, void *)) { +#ifdef CONFIG_X86_IO_APIC + if (irq_ack == (void *)ack_8259A_irq) { + return -ENODEV; + } +#endif if (irq >= RTAI_NR_IRQS) { return -EINVAL; } @@ -561,6 +587,12 @@ void rt_end_irq (unsigned irq) void rt_eoi_irq (unsigned irq) { + if ( + #ifdef CONFIG_X86_IO_APIC + !IO_APIC_IRQ(irq) || + #endif /* CONFIG_X86_IO_APIC */ + !(rtai_irq_desc(irq).status_use_accessors & (IRQD_IRQ_DISABLED | IRQD_IRQ_INPROGRESS))) { + } rtai_irq_desc_chip(irq)->rtai_irq_endis_fun(eoi, irq); } @@ -924,8 +956,8 @@ void rt_request_apic_timers (void (*handler)(void), struct apic_timer_setup_data } } - rtai_critical_exit(flags); rtai_request_tickdev(handler); + rtai_critical_exit(flags); } /** @@ -942,8 +974,8 @@ void rt_free_apic_timers(void) rtai_release_tickdev(); rtai_sync_level = 3; rtai_setup_periodic_apic(RTAI_APIC_ICOUNT,LOCAL_TIMER_VECTOR); - rtai_critical_exit(flags); rt_release_irq(RTAI_APIC_TIMER_IPI); + rtai_critical_exit(flags); } /** @@ -966,8 +998,8 @@ void rt_free_apic_timers(void) */ unsigned long rt_assign_irq_to_cpu (int irq, unsigned long cpumask) { - if (irq >= IPIPE_NR_XIRQS || &rtai_irq_desc(irq) == NULL || rtai_irq_desc_chip(irq) == NULL || rtai_irq_desc_chip(irq)->irq_set_affinity == NULL) { - return 0; + if (irq >= IPIPE_NR_XIRQS) { + return -EINVAL; } else { unsigned long oldmask, flags; @@ -1251,14 +1283,7 @@ static int rtai_hirq_dispatcher (int irq) return 0; } -//#define HINT_DIAG_ECHO -//#define HINT_DIAG_TRAPS - -#ifdef HINT_DIAG_ECHO -#define HINT_DIAG_MSG(x) x -#else #define HINT_DIAG_MSG(x) -#endif static int PrintFpuTrap = 0; RTAI_MODULE_PARM(PrintFpuTrap, int); @@ -1394,7 +1419,7 @@ static unsigned long hal_request_apic_freq(void); static void rtai_install_archdep (void) { - ipipe_select_timers(cpu_active_mask); + ipipe_select_timers(cpu_present_mask); hal_catch_event(hal_root_domain, HAL_SYSCALL_PROLOGUE, (void *)intercept_syscall_prologue); if (rtai_cpufreq_arg == 0) { @@ -1595,6 +1620,7 @@ int __rtai_hal_init (void) { int trapnr, halinv = 0; struct hal_attr_struct attr; + struct hal_sysinfo_struct sysinfo; ipipe_catch_event(hal_root_domain, 0, 0); for (halinv = trapnr = 0; trapnr < HAL_NR_EVENTS; trapnr++) { @@ -1635,6 +1661,18 @@ int __rtai_hal_init (void) rtai_install_archdep(); + /* test if timers are available */ + hal_get_sysinfo(&sysinfo); + if (!sysinfo.sys_hrtimer_freq || !sysinfo.sys_hrclock_freq || !sysinfo.sys_cpu_freq) { + printk(KERN_ERR "RTAI[hal]: NO CLOCK AVAILABLE.\n"); + /* undo what is partially done, in order found in __rtai_hal_exit */ + hal_irq_handler = NULL; + hal_virtualize_irq(hal_root_domain, rtai_sysreq_virq, NULL, NULL, 0); + hal_free_irq(rtai_sysreq_virq); + rtai_uninstall_archdep(); + return -1; + } + #ifdef CONFIG_PROC_FS rtai_proc_register(); #endif @@ -1655,7 +1693,6 @@ int __rtai_hal_init (void) for (trapnr = 0; trapnr < IPIPE_NR_XIRQS; trapnr++) { rtai_orig_irq_affinity[trapnr] = rt_assign_irq_to_cpu(trapnr, ~IsolCpusMask); } - free_isolcpus_from_linux(&IsolCpusMask); } #else IsolCpusMask = 0; diff --git a/base/sched/sched.c b/base/sched/sched.c index 8078671e..53bd1a5a 100644 --- a/base/sched/sched.c +++ b/base/sched/sched.c @@ -2586,19 +2586,12 @@ static int __rtai_lxrt_init(void) rt_linux_task.resq.task = NULL; } tuned.latency = imuldiv(Latency, tuned.cpu_freq, 1000000000); - tuned.kern_latency_busy_align_ret_delay = imuldiv(RTAI_KERN_BUSY_ALIGN_RET_DELAY, tuned.cpu_freq, 1000000000); - tuned.user_latency_busy_align_ret_delay = imuldiv(RTAI_USER_BUSY_ALIGN_RET_DELAY, tuned.cpu_freq, 1000000000); - SetupTimeTIMER = rtai_calibrate_hard_timer(); - tuned.setup_time_TIMER_UNIT = imuldiv(SetupTimeTIMER, TIMER_FREQ, 1000000000); - if (tuned.setup_time_TIMER_UNIT < 1) { - tuned.setup_time_TIMER_UNIT = 1; - tuned.setup_time_TIMER_CPUNIT = (tuned.cpu_freq + TIMER_FREQ/2)/TIMER_FREQ; - } else { - tuned.setup_time_TIMER_CPUNIT = imuldiv(SetupTimeTIMER, tuned.cpu_freq, 1000000000); - } - if (tuned.latency < tuned.setup_time_TIMER_CPUNIT) { - tuned.latency = tuned.setup_time_TIMER_CPUNIT; - } + tuned.setup_time_TIMER_CPUNIT = imuldiv( SetupTimeTIMER, + tuned.cpu_freq, + 1000000000); + tuned.setup_time_TIMER_UNIT = imuldiv( SetupTimeTIMER, + TIMER_FREQ, + 1000000000); tuned.timers_tol[0] = 0; oneshot_span = ONESHOT_SPAN; satdlay = oneshot_span - tuned.latency;