[PATCH] pc386 BSP: automatic timer functions selection [was: Re: [pc386 BSP] tm[01|02].exe doesn't run on K6-2 (raw handler connexion failed issue)]

Karel Gardas kgardas at objectsecurity.com
Tue Aug 23 19:35:10 UTC 2005


On Tue, 26 Jul 2005, Joel Sherrill <joel at OARcorp.com> wrote:

> Karel Gardas wrote:
>> 
>> Hello,
>> 
>> testing today's sources of RTEMS 4.7, I've found that I'm not able to run 
>> time meassuring tests on my K6-2/128MB box. All tests so far starts well, 
>> but then print "raw handler connexion failed" message.
>> 
>> Any idea how to get this working?
>
> The timer driver comes in two style on the pc386 BSP.  If the
> CPU has the RDTSC instruction, then the CPU cycle counter is
> used.  Otherwise, a counter/timer is used.
>
> If the K6 has the rdtsc instruction, then the conditional
> in pc386/timer/timer.c just needs to be changed to reflect
> that it is a supported instruction.  A quick google shows
> that RDTSC is supposed to work on the K6 so the macro is
> too tight.
>
> Patch welcomed.

Attached. Tested on machines with TSC.

Cheers,
Karel
--
Karel Gardas                  kgardas at objectsecurity.com
ObjectSecurity Ltd.           http://www.objectsecurity.com
-------------- next part --------------
Index: c/src/lib/libbsp/i386/pc386/ChangeLog
===================================================================
RCS file: /usr1/CVS/rtems/c/src/lib/libbsp/i386/pc386/ChangeLog,v
retrieving revision 1.127
diff -u -r1.127 ChangeLog
--- c/src/lib/libbsp/i386/pc386/ChangeLog	22 Aug 2005 13:26:42 -0000	1.127
+++ c/src/lib/libbsp/i386/pc386/ChangeLog	23 Aug 2005 19:17:54 -0000
@@ -1,3 +1,14 @@
+2005-08-23  Karel Gardas  <kgardas at objectsecurity.com>>
+
+	* timer/timer.c: Enhance to use either interupt-based timer
+	functions on older CPUs or to use TSC-based timer functions on
+	more recent (Pentium and above) CPUs. The decision is made in
+	Timer_initialize function when it is called for the first time
+	based on a result obtained from cpuid instruction during the BSP
+	initialization phase. During the first call, there are also late
+	bindings to the implementation functions initialized to
+	appropriate values.
+
 2005-08-18  Karel Gardas  <kgardas at objectsecurity.com>
 
 	* startup/bspstart.c: Initialize PCI bus in bsp_start function.
Index: c/src/lib/libbsp/i386/pc386/timer/timer.c
===================================================================
RCS file: /usr1/CVS/rtems/c/src/lib/libbsp/i386/pc386/timer/timer.c,v
retrieving revision 1.19
diff -u -r1.19 timer.c
--- c/src/lib/libbsp/i386/pc386/timer/timer.c	6 May 2005 19:53:03 -0000	1.19
+++ c/src/lib/libbsp/i386/pc386/timer/timer.c	23 Aug 2005 19:17:56 -0000
@@ -61,17 +61,26 @@
 volatile uint32_t         Ttimer_val;
 rtems_boolean    	  Timer_driver_Find_average_overhead = TRUE;
 volatile unsigned int     fastLoop1ms, slowLoop1ms;
+void (*Timer_initialize_function)(void) = 0;
+uint32_t (*Read_timer_function)(void) = 0;
+void (*Timer_exit_function)(void) = 0;
 
 /*-------------------------------------------------------------------------+
 | External Prototypes
 +--------------------------------------------------------------------------*/
 extern void timerisr(void);
        /* timer (int 08h) Interrupt Service Routine (defined in 'timerisr.s') */
+extern int x86_capability;
+
+/*
+ * forward declarations
+ */
+
+void Timer_exit();
 
 /*-------------------------------------------------------------------------+
 | Pentium optimized timer handling.
 +--------------------------------------------------------------------------*/
-#if defined(pentium)
 
 /*-------------------------------------------------------------------------+
 |         Function: rdtsc
@@ -98,9 +107,9 @@
 |          Returns: Nothing.
 +--------------------------------------------------------------------------*/
 void
-Timer_exit(void)
+tsc_timer_exit(void)
 {
-} /* Timer_exit */
+} /* tsc_timer_exit */
 
 /*-------------------------------------------------------------------------+
 |         Function: Timer_initialize
@@ -110,7 +119,7 @@
 |          Returns: Nothing.
 +--------------------------------------------------------------------------*/
 void
-Timer_initialize(void)
+tsc_timer_initialize(void)
 {
   static rtems_boolean First = TRUE;
 
@@ -121,7 +130,7 @@
     atexit(Timer_exit); /* Try not to hose the system at exit. */
   }
   Ttimer_val = rdtsc(); /* read starting time */
-} /* Timer_initialize */
+} /* tsc_timer_initialize */
 
 /*-------------------------------------------------------------------------+
 |         Function: Read_timer
@@ -131,7 +140,7 @@
 |          Returns: Nothing.
 +--------------------------------------------------------------------------*/
 uint32_t
-Read_timer(void)
+tsc_read_timer(void)
 {
   register uint32_t         total;
 
@@ -143,9 +152,7 @@
     return 0; /* below timer resolution */
   else
     return (total - AVG_OVERHEAD);
-} /* Read_timer */
-
-#else /* pentium */
+} /* tsc_read_timer */
 
 /*-------------------------------------------------------------------------+
 | Non-Pentium timer handling.
@@ -209,7 +216,7 @@
 |          Returns: Nothing.
 +--------------------------------------------------------------------------*/
 void
-Timer_exit(void)
+i386_timer_exit(void)
 {
   i386_delete_idt_entry (&timer_raw_irq_data);
 } /* Timer_exit */
@@ -222,7 +229,7 @@
 |          Returns: Nothing.
 +--------------------------------------------------------------------------*/
 void
-Timer_initialize(void)
+i386_timer_initialize(void)
 {
   static rtems_boolean First = TRUE;
 
@@ -251,7 +258,7 @@
 |          Returns: Nothing.
 +--------------------------------------------------------------------------*/
 uint32_t
-Read_timer(void)
+i386_read_timer(void)
 {
   register uint32_t         total, clicks;
   register uint8_t          lsb, msb;
@@ -270,7 +277,49 @@
     return (total - AVG_OVERHEAD);
 }
 
-#endif /* pentium */
+/*
+ * General timer functions using either TSC-based implementation
+ * or interrupt-based implementation
+ */
+
+void
+Timer_initialize(void)
+{
+    static rtems_boolean First = TRUE;
+
+    if (First) {
+        if (x86_capability & (1 << 4) ) {
+#if defined(DEBUG)
+            printk("TSC: timer initialization\n");
+#endif // DEBUG
+            Timer_initialize_function = &tsc_timer_initialize;
+            Read_timer_function = &tsc_read_timer;
+            Timer_exit_function = &tsc_timer_exit;
+        }
+        else {
+#if defined(DEBUG)
+            printk("ISR: timer initialization\n");
+#endif // DEBUG
+            Timer_initialize_function = &i386_timer_initialize;
+            Read_timer_function = &i386_read_timer;
+            Timer_exit_function = &i386_timer_exit;
+        }
+        First = FALSE;
+    }
+    (*Timer_initialize_function)();
+}
+
+uint32_t
+Read_timer()
+{
+    return (*Read_timer_function)();
+}
+
+void
+Timer_exit()
+{
+    return (*Timer_exit_function)();
+}
 
 /*-------------------------------------------------------------------------+
 |         Function: Empty_function


More information about the users mailing list