2005-08-23 Karel Gardas <kgardas@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.
This commit is contained in:
Joel Sherrill
2005-08-31 18:51:30 +00:00
parent 54791b8266
commit 1131dfe304
2 changed files with 73 additions and 13 deletions

View File

@@ -1,3 +1,14 @@
2005-08-23 Karel Gardas <kgardas@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@objectsecurity.com>
* startup/bspstart.c: Initialize PCI bus in bsp_start function.

View File

@@ -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 @@ rdtsc(void)
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
Timer_exit(void)
tsc_timer_exit(void)
{
} /* Timer_exit */
} /* tsc_timer_exit */
/*-------------------------------------------------------------------------+
| Function: Timer_initialize
@@ -110,7 +119,7 @@ Timer_exit(void)
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
Timer_initialize(void)
tsc_timer_initialize(void)
{
static rtems_boolean First = TRUE;
@@ -121,7 +130,7 @@ Timer_initialize(void)
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 @@ Timer_initialize(void)
| Returns: Nothing.
+--------------------------------------------------------------------------*/
uint32_t
Read_timer(void)
tsc_read_timer(void)
{
register uint32_t total;
@@ -143,9 +152,7 @@ Read_timer(void)
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 @@ static rtems_raw_irq_connect_data timer_raw_irq_data = {
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
Timer_exit(void)
i386_timer_exit(void)
{
i386_delete_idt_entry (&timer_raw_irq_data);
} /* Timer_exit */
@@ -222,7 +229,7 @@ Timer_exit(void)
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
Timer_initialize(void)
i386_timer_initialize(void)
{
static rtems_boolean First = TRUE;
@@ -251,7 +258,7 @@ Timer_initialize(void)
| 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 @@ Read_timer(void)
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