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

View File

@@ -61,17 +61,26 @@
volatile uint32_t Ttimer_val; volatile uint32_t Ttimer_val;
rtems_boolean Timer_driver_Find_average_overhead = TRUE; rtems_boolean Timer_driver_Find_average_overhead = TRUE;
volatile unsigned int fastLoop1ms, slowLoop1ms; 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 | External Prototypes
+--------------------------------------------------------------------------*/ +--------------------------------------------------------------------------*/
extern void timerisr(void); extern void timerisr(void);
/* timer (int 08h) Interrupt Service Routine (defined in 'timerisr.s') */ /* timer (int 08h) Interrupt Service Routine (defined in 'timerisr.s') */
extern int x86_capability;
/*
* forward declarations
*/
void Timer_exit();
/*-------------------------------------------------------------------------+ /*-------------------------------------------------------------------------+
| Pentium optimized timer handling. | Pentium optimized timer handling.
+--------------------------------------------------------------------------*/ +--------------------------------------------------------------------------*/
#if defined(pentium)
/*-------------------------------------------------------------------------+ /*-------------------------------------------------------------------------+
| Function: rdtsc | Function: rdtsc
@@ -98,9 +107,9 @@ rdtsc(void)
| Returns: Nothing. | Returns: Nothing.
+--------------------------------------------------------------------------*/ +--------------------------------------------------------------------------*/
void void
Timer_exit(void) tsc_timer_exit(void)
{ {
} /* Timer_exit */ } /* tsc_timer_exit */
/*-------------------------------------------------------------------------+ /*-------------------------------------------------------------------------+
| Function: Timer_initialize | Function: Timer_initialize
@@ -110,7 +119,7 @@ Timer_exit(void)
| Returns: Nothing. | Returns: Nothing.
+--------------------------------------------------------------------------*/ +--------------------------------------------------------------------------*/
void void
Timer_initialize(void) tsc_timer_initialize(void)
{ {
static rtems_boolean First = TRUE; static rtems_boolean First = TRUE;
@@ -121,7 +130,7 @@ Timer_initialize(void)
atexit(Timer_exit); /* Try not to hose the system at exit. */ atexit(Timer_exit); /* Try not to hose the system at exit. */
} }
Ttimer_val = rdtsc(); /* read starting time */ Ttimer_val = rdtsc(); /* read starting time */
} /* Timer_initialize */ } /* tsc_timer_initialize */
/*-------------------------------------------------------------------------+ /*-------------------------------------------------------------------------+
| Function: Read_timer | Function: Read_timer
@@ -131,7 +140,7 @@ Timer_initialize(void)
| Returns: Nothing. | Returns: Nothing.
+--------------------------------------------------------------------------*/ +--------------------------------------------------------------------------*/
uint32_t uint32_t
Read_timer(void) tsc_read_timer(void)
{ {
register uint32_t total; register uint32_t total;
@@ -143,9 +152,7 @@ Read_timer(void)
return 0; /* below timer resolution */ return 0; /* below timer resolution */
else else
return (total - AVG_OVERHEAD); return (total - AVG_OVERHEAD);
} /* Read_timer */ } /* tsc_read_timer */
#else /* pentium */
/*-------------------------------------------------------------------------+ /*-------------------------------------------------------------------------+
| Non-Pentium timer handling. | Non-Pentium timer handling.
@@ -209,7 +216,7 @@ static rtems_raw_irq_connect_data timer_raw_irq_data = {
| Returns: Nothing. | Returns: Nothing.
+--------------------------------------------------------------------------*/ +--------------------------------------------------------------------------*/
void void
Timer_exit(void) i386_timer_exit(void)
{ {
i386_delete_idt_entry (&timer_raw_irq_data); i386_delete_idt_entry (&timer_raw_irq_data);
} /* Timer_exit */ } /* Timer_exit */
@@ -222,7 +229,7 @@ Timer_exit(void)
| Returns: Nothing. | Returns: Nothing.
+--------------------------------------------------------------------------*/ +--------------------------------------------------------------------------*/
void void
Timer_initialize(void) i386_timer_initialize(void)
{ {
static rtems_boolean First = TRUE; static rtems_boolean First = TRUE;
@@ -251,7 +258,7 @@ Timer_initialize(void)
| Returns: Nothing. | Returns: Nothing.
+--------------------------------------------------------------------------*/ +--------------------------------------------------------------------------*/
uint32_t uint32_t
Read_timer(void) i386_read_timer(void)
{ {
register uint32_t total, clicks; register uint32_t total, clicks;
register uint8_t lsb, msb; register uint8_t lsb, msb;
@@ -270,7 +277,49 @@ Read_timer(void)
return (total - AVG_OVERHEAD); 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 | Function: Empty_function