[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