On Wed, 17 Nov 1999, Christophe Kumsta wrote: : : Hi all, : : I got a compiler error : : [...] : gcc-2.95 is buggy ??? No, gcc-2.95 is ok, the only thing is that new gcc is more strict about asm constraints. The attached patch is against rtai-0.7, features : - it allow compiling with gcc-2.95 - CPU speed autodetection and 8254 calibration integrated in modules, so you don't need recompiling them if another machine occured - only upscheduler tested - native cpu calibration routine give me strange values - don't know why : : Rus
diff -ur rtai-0.7/cpu_freq_calibration/rt_cal.c rtai-0.7.1/cpu_freq_calibration/rt_cal.c --- rtai-0.7/cpu_freq_calibration/rt_cal.c Mon Sep 13 12:57:46 1999 +++ rtai-0.7.1/cpu_freq_calibration/rt_cal.c Sun Nov 7 20:01:21 1999 @@ -29,12 +29,12 @@ gcount++; if (++count == RESET_COUNT) { tsc.time -= tbase; - __asm__ __volatile__("movl %%cr0,%%eax": "=a" (linux_cr0): : "ax"); + __asm__ __volatile__("movl %%cr0,%%eax": "=a" (linux_cr0)); __asm__ __volatile__("clts; fnsave %0": "=m" (fpu_reg)); freq = (double)tsc.time_lh[1]*(double)0x100000000LL + (double)tsc.time_lh[0]; count = (freq*CLOCK_TICK_RATE)/(((double)gcount)*LATCH) + 0.4999999999999; __asm__ __volatile__("frstor %0" : "=m" (fpu_reg)); - __asm__ __volatile__("movl %%eax,%%cr0": :"a" (linux_cr0): "ax"); + __asm__ __volatile__("movl %%eax,%%cr0": :"a" (linux_cr0)); printk("\n->>> MEASURED CPU_FREQ: %d (Hz) (%d s) <<<-\n", count, gcount/100 + 1); count = 0; } diff -ur rtai-0.7/examples/sound/rt_process.c rtai-0.7.1/examples/sound/rt_process.c --- rtai-0.7/examples/sound/rt_process.c Mon Sep 13 12:57:46 1999 +++ rtai-0.7.1/examples/sound/rt_process.c Sun Nov 7 19:41:26 1999 @@ -17,7 +17,7 @@ #include <rtai_fifos.h> #include <rtai_sched.h> -#define ONESHOT +//#define ONESHOT #define TIMER_TO_CPU 3 // < 0 || > 1 to maintain a symmetric processed timer. diff -ur rtai-0.7/include/rtai.h rtai-0.7.1/include/rtai.h --- rtai-0.7/include/rtai.h Fri Sep 24 20:46:42 1999 +++ rtai-0.7.1/include/rtai.h Mon Nov 8 02:05:52 1999 @@ -16,13 +16,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#ifndef _RTAI_H_ +#define _RTAI_H_ #include <asm/ptrace.h> #include <asm/spinlock.h> #define FREQ_8254 1193180 #define LATENCY_8254 11000 -#define SETUP_TIME_8254 2000 #define BUS_FREQ 100225700 #define APIC_DIVISOR 16 @@ -31,9 +32,7 @@ #define LATENCY_APIC 3000 #define SETUP_TIME_APIC 500 -//#define CPU_FREQ FREQ_8254 -//#define CPU_FREQ 233863280 -#define CPU_FREQ 350799293 +//#define RT_FOR_486 #define IFLAG 9 @@ -323,7 +322,7 @@ extern void rt_setup_8254_tsc(void); #undef rdtsc -#if CPU_FREQ == FREQ_8254 +#ifdef RT_FOR_486 #define rdtsc() rd_8254_ts() #else #define rdtsc() rd_CPU_ts() @@ -334,35 +333,36 @@ { union {unsigned long long time; unsigned long time_lh[2]; } tsc; __asm__ __volatile__( "rdtsc" - : "=a" (tsc.time_lh[0]), "=d" (tsc.time_lh[1]) - : - :"ax", "dx"); + : "=a" (tsc.time_lh[0]), "=d" (tsc.time_lh[1])); return tsc.time; } // returns (int)i = (int)i*(int)(mult)/(int)div. static inline int imuldiv(int i, int mult, int div) { + int dummy, dummy1; + __asm__("imull %%edx ; idiv %%ecx; sal $1,%%edx \n\t" "cmpl %%edx,%%ecx; jge 1f; incl %%eax; 1:" - : "=a" (i) - : "a" (i), "d" (mult), "c" (div) - : "%eax", "%ecx", "%edx"); + : "=a" (i), "=c" (dummy), "=d" (dummy1) + : "a" (i), "d" (mult), "c" (div)); return i; } // returns (long long)ll = (int)ll*(int)(mult)/(int)div. static inline long long llimd(long long ll, int mult, int div) { + int dummy, dummy1; + __asm__( "movl %%edx,%%ecx; mull %%esi; movl %%eax,%%ebx; \n\t" "movl %%ecx,%%eax; movl %%edx,%%ecx; mull %%esi; \n\t" "addl %%ecx,%%eax; adcl $0,%%edx; divl %%edi; \n\t" "movl %%eax,%%ecx; movl %%ebx,%%eax; divl %%edi; \n\t" "sal $1,%%edx; cmpl %%edx,%%edi; movl %%ecx,%%edx; \n\t" "jge 1f; addl $1,%%eax; adcl $0,%%edx; 1:" - : "=A" (ll) + : "=A" (ll), "=S" (dummy), "=D" (dummy1) : "A" (ll), "S" (mult), "D" (div) - : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi" ); + : "%ebx", "%ecx"); return ll; } @@ -378,7 +378,7 @@ #define SAVE_IRQ_REG __asm__ __volatile__ (" \ pushl pushl %es; pushl %ds; pushl %eax;\n\t \ pushl %ebp; pushl %ecx; pushl %edx;\n\t \ - movl $" STR(__KERNEL_DS) ",%edx; movl %dx,%ds; movl %dx,%es") + movl $" STR(__KERNEL_DS) ",%edx; movl %edx,%ds; movl %edx,%es") #define RSTR_IRQ_REG __asm__ __volatile__ (" \ popl %edx; popl %ecx; popl %ebp; popl %eax;\n\t \ @@ -388,7 +388,7 @@ cld; pushl %es; pushl %ds; pushl %eax;\n\t \ pushl %ebp; pushl %edi; pushl %esi;\n\t \ pushl %edx; pushl %ecx; pushl %ebx;\n\t \ - movl $" STR(__KERNEL_DS) ",%edx; movl %dx,%ds; movl %dx,%es") + movl $" STR(__KERNEL_DS) ",%edx; movl %edx,%ds; movl %edx,%es") #define RSTR_FULL_IRQ_REG __asm__ __volatile__ (" \ popl %ebx; popl %ecx; popl %edx; popl %esi; popl %edi;\n\t \ @@ -398,8 +398,10 @@ cld; pushl %es; pushl %ds; pushl %ebp;\n\t \ pushl %edi; pushl %esi; pushl %ecx;\n\t \ pushl %ebx; pushl %edx; pushl %eax;\n\t \ - movl $" STR(__KERNEL_DS) ",%ebx; movl %bx,%ds; movl %bx,%es") + movl $" STR(__KERNEL_DS) ",%ebx; movl %ebx,%ds; movl %ebx,%es") #define RSTR_SRQ_REG __asm__ __volatile__ (" \ popl %eax; popl %edx; popl %ebx; popl %ecx; popl %esi;\n\t \ popl %edi; popl %ebp; popl %ds; popl %es; iret") + +#endif diff -ur rtai-0.7/include/rtai_sched.h rtai-0.7.1/include/rtai_sched.h --- rtai-0.7/include/rtai_sched.h Fri Oct 1 20:03:27 1999 +++ rtai-0.7.1/include/rtai_sched.h Sun Nov 7 20:34:31 1999 @@ -16,6 +16,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#ifndef _RTAI_SCHED_H_ +#define _RTAI_SCHED_H_ #ifdef INTERFACE_TO_LINUX #define RT_LINUX_PRIORITY 0x7fffFfff @@ -222,5 +224,7 @@ extern int rt_mbx_receive_until(MBX *mbx, void *msg, int msg_size, RTIME time); extern int rt_mbx_receive_timed(MBX *mbx, void *msg, int msg_size, RTIME delay); + +#endif #endif diff -ur rtai-0.7/linux-2.2.12/copyto rtai-0.7.1/linux-2.2.12/copyto --- rtai-0.7/linux-2.2.12/copyto Mon Sep 13 12:57:47 1999 +++ rtai-0.7.1/linux-2.2.12/copyto Sun Nov 7 18:40:04 1999 @@ -1,5 +1,5 @@ #!/bin/bash -LINUXDIR=/usr/src/linux-2.2.12 +LINUXDIR=/usr/src/linux cp $LINUXDIR/arch/i386/kernel/irq.c $LINUXDIR/arch/i386/kernel/irq.c.old cp $LINUXDIR/arch/i386/kernel/time.c $LINUXDIR/arch/i386/kernel/time.c.old diff -ur rtai-0.7/rtai.c rtai-0.7.1/rtai.c --- rtai-0.7/rtai.c Tue Oct 5 19:55:39 1999 +++ rtai-0.7.1/rtai.c Mon Nov 8 18:06:30 1999 @@ -36,6 +36,7 @@ #include <asm/bitops.h> #include <asm/atomic.h> #include <asm/desc.h> +//#include <asm/msr.h> #include "include/rtai.h" #include "include/rtai_srq.h" @@ -59,7 +60,7 @@ #define SAVE_REG(irq) __asm__ __volatile__ (" \ pushl $"#irq"; pushl %es; pushl %ds; pushl %eax;\n\t \ pushl %ebp; pushl %ecx; pushl %edx;\n\t \ - movl $" STR(__KERNEL_DS) ",%edx; movl %dx,%ds; movl %dx,%es") + movl $" STR(__KERNEL_DS) ",%edx; movl %edx,%ds; movl %edx,%es") #define RSTR_REG __asm__ __volatile__ (" \ popl %edx; popl %ecx; testl %eax,%eax; jnz 1f;\n\t \ @@ -87,13 +88,15 @@ RSTR_REG; \ } +unsigned long cpu_freq; + static void srqisr(void) { __asm__ __volatile__ (" \ cld; pushl %es; pushl %ds; pushl %ebp;\n\t \ pushl %edi; pushl %esi; pushl %ecx;\n\t \ pushl %ebx; pushl %edx; pushl %eax;\n\t \ - movl $" STR(__KERNEL_DS) ",%ebx; movl %bx,%ds; movl %bx,%es"); + movl $" STR(__KERNEL_DS) ",%ebx; movl %ebx,%ds; movl %ebx,%es"); __asm__ __volatile__ ("call "SYMBOL_NAME_STR(dispatch_srq)); @@ -1179,10 +1182,10 @@ cpu_own_irq[HARD_LOCK_IPI].handler = hard_lock_all_handler; hard_sti(); } - printk("\n***** RTAI NEWLY MOUNTED (MOUNT COUNT %d) ******\n\n", rtai_mounted); - } else { - printk("\n***** RTAI ALREADY MOUNTED (MOUNT COUNT %d) ******\n\n", rtai_mounted); - } +// printk("\n***** RTAI NEWLY MOUNTED (MOUNT COUNT %d) ******\n\n", +rtai_mounted); + } //else { +// printk("\n***** RTAI ALREADY MOUNTED (MOUNT COUNT %d) ******\n\n", +rtai_mounted); +// } rt_spin_unlock(&rtai_mount_lock); } @@ -1210,13 +1213,30 @@ cpu_own_irq[HARD_LOCK_IPI].handler = 0; cpu_own_irq[INVALIDATE_IPI].handler = 0; hard_unlock_all(flags); - printk("\n***** RTAI UNMOUNTED (MOUNT COUNT %d) ******\n\n", rtai_mounted); - } else { - printk("\n***** RTAI CANNOT BE UMOUNTED (MOUNT COUNT %d) ******\n\n", rtai_mounted); - } +// printk("\n***** RTAI UNMOUNTED (MOUNT COUNT %d) ******\n\n", +rtai_mounted); + }// else { +// printk("\n***** RTAI CANNOT BE UMOUNTED (MOUNT COUNT %d) ******\n\n", +rtai_mounted); +// } rt_spin_unlock(&rtai_mount_lock); } +void calibrate_cpu_freq(void); + +void calibrate_cpu_freq() +{ + unsigned int t1, t2, t3; + unsigned long flags; + printk("\n***** Calibrating CPU frequency ... "); + save_flags(flags); + cli(); + rdtscl(t1); + __udelay(1000); + rdtscl(t2); + rdtscl(t3); + restore_flags(flags); + cpu_freq = (t2-t1) - (t3-t2); + printk("%ld Hz *****\n", cpu_freq); +} /* module init-cleanup */ @@ -1287,6 +1307,7 @@ // Uncomment the line below if you want to check that Linux works well when it // is intercepted. // rt_mount_rtai(); + calibrate_cpu_freq(); return 0; } @@ -1516,6 +1537,7 @@ hard_unlock_all(flags); } + int calibrate_8254(void) { unsigned long flags, i; @@ -1529,6 +1551,6 @@ } i = rdtsc() - t; hard_unlock_all(flags); - return imuldiv(i, 100000, CPU_FREQ); + return imuldiv(i, 100000, cpu_freq); } /********** END OF SOME TIMER FUNCTIONS TO BE LIKELY PUT ELSWHERE ***********/ diff -ur rtai-0.7/shmem/rtai_shm.c rtai-0.7.1/shmem/rtai_shm.c --- rtai-0.7/shmem/rtai_shm.c Mon Sep 13 12:57:47 1999 +++ rtai-0.7.1/shmem/rtai_shm.c Sun Nov 7 19:55:19 1999 @@ -49,7 +49,7 @@ cld; pushl %es; pushl %ds; pushl %ebp;\n\t \ pushl %edi; pushl %esi; pushl %ecx;\n\t \ pushl %ebx; pushl %edx; pushl %eax;\n\t \ - movl $" STR(__KERNEL_DS) ",%ebx; movl %bx,%ds; movl %bx,%es"); + movl $" STR(__KERNEL_DS) ",%ebx; movl %ebx,%ds; movl %ebx,%es"); __asm__ __volatile__ ("call "SYMBOL_NAME_STR(shm_handler)); diff -ur rtai-0.7/smpscheduler/rtai_sched.c rtai-0.7.1/smpscheduler/rtai_sched.c --- rtai-0.7/smpscheduler/rtai_sched.c Mon Sep 27 18:37:25 1999 +++ rtai-0.7.1/smpscheduler/rtai_sched.c Mon Nov 8 01:59:51 1999 @@ -78,7 +78,7 @@ #define TIMER_CHIP "8254" #define TIMER_FREQ FREQ_8254 #define TIMER_LATENCY LATENCY_8254 -#define TIMER_SETUP_TIME SETUP_TIME_8254 +//#define TIMER_SETUP_TIME SETUP_TIME_8254 #define set_timer_cpu(cpu_map) #define is_timer_cpu() #define set_timer_chip(delay) \ @@ -690,14 +690,16 @@ const int LinuxFpu = LINUX_FPU; MODULE_PARM(LinuxFpu, "i"); -const int CpuFreq = CPU_FREQ; -MODULE_PARM(CpuFreq, "i"); - const int Latency = TIMER_LATENCY; MODULE_PARM(Latency, "i"); +#ifdef __USE_APIC__ const int SetupTimeTIMER = TIMER_SETUP_TIME; MODULE_PARM(SetupTimeTIMER, "i"); +#else +extern int calibrate_8254(void); +int SetupTimeTIMER; +#endif int init_module(void) { @@ -717,9 +719,12 @@ fpu_smp_task[cpuid] = &rt_linux_task; } set_timer_cpu(cpu_present_map); - tuned.cpu_freq = CpuFreq; - tuned.latency = imuldiv(Latency, CpuFreq, 1E9); - tuned.setup_time_TIMER_CPUNIT = imuldiv(SetupTimeTIMER, CpuFreq, 1E9); + tuned.cpu_freq = cpu_freq; + tuned.latency = imuldiv(Latency, cpu_freq, 1E9); +#ifndef __USE_APIC__ + SetupTimeTIMER = calibrate_8254(); +#endif + tuned.setup_time_TIMER_CPUNIT = imuldiv(SetupTimeTIMER, cpu_freq, 1E9); tuned.setup_time_TIMER_UNIT = imuldiv(SetupTimeTIMER, TIMER_FREQ, 1E9); oneshot_timer = OneShot != 0 ? 1 : 0; preempt_always = 0; diff -ur rtai-0.7/upscheduler/rtai_sched.c rtai-0.7.1/upscheduler/rtai_sched.c --- rtai-0.7/upscheduler/rtai_sched.c Mon Sep 27 19:25:05 1999 +++ rtai-0.7.1/upscheduler/rtai_sched.c Mon Nov 8 15:59:37 1999 @@ -18,7 +18,7 @@ #define LINUX_FPU 0 -#define ONE_SHOT 0 +#define ONE_SHOT 1 /* if PRIORDs below are not defined msg and sem queues are FIFOs otherwise */ /* insertion is in priority order and receiving tasks have their priority */ @@ -86,8 +86,7 @@ popl %%ebp\n\t \ popl %%eax\n\t" \ : /* no output */ \ - : "c" (tsk) \ - :"cx"); + : "c" (tsk)); static RT_TASK *rt_current; @@ -416,7 +415,7 @@ hard_save_flags_and_cli(flags); if (oneshot_timer) { -#if CPU_FREQ == FREQ_8254 +#ifdef RT_FOR_486 rt_setup_8254_tsc(); #endif rt_request_timer(rt_timer_handler, 0, 0); @@ -490,14 +489,13 @@ const int LinuxFpu = LINUX_FPU; MODULE_PARM(LinuxFpu, "i"); -const int CpuFreq = CPU_FREQ; -MODULE_PARM(CpuFreq, "i"); - const int Latency = LATENCY_8254; MODULE_PARM(Latency, "i"); -const int SetupTimeTIMER = SETUP_TIME_8254; -MODULE_PARM(SetupTimeTIMER, "i"); +int SetupTimeTIMER; + +extern unsigned long cpu_freq; +extern int calibrate_8254(void); int init_module(void) { @@ -510,9 +508,10 @@ rt_linux_task.next = 0; rt_current = &rt_linux_task; fpu_task = &rt_linux_task; - tuned.cpu_freq = CpuFreq; - tuned.latency = imuldiv(Latency, CpuFreq, 1E9); - tuned.setup_time_TIMER_CPUNIT = imuldiv(SetupTimeTIMER, CpuFreq, 1E9); + tuned.cpu_freq = cpu_freq; + tuned.latency = imuldiv(Latency, cpu_freq, 1E9); + SetupTimeTIMER = calibrate_8254(); + tuned.setup_time_TIMER_CPUNIT = imuldiv(SetupTimeTIMER, cpu_freq, 1E9); tuned.setup_time_TIMER_UNIT = imuldiv(SetupTimeTIMER, TIMER_FREQ, 1E9); oneshot_timer = OneShot != 0 ? 1 : 0; preempt_always = 0;