updating go32 to make timer more accurate

This commit is contained in:
Joel Sherrill
1995-07-20 19:20:31 +00:00
parent 3b170f53b3
commit 9e738b65b0
5 changed files with 56 additions and 51 deletions

View File

@@ -40,7 +40,7 @@ extern "C" {
* NOTE: Use a software interrupt for the i386. * NOTE: Use a software interrupt for the i386.
*/ */
#define MUST_WAIT_FOR_INTERRUTPT 0 #define MUST_WAIT_FOR_INTERRUPT 0
#define Install_tm27_vector( handler ) set_vector( (handler), 0x90, 1 ) #define Install_tm27_vector( handler ) set_vector( (handler), 0x90, 1 )

View File

@@ -38,15 +38,14 @@ extern "C" {
/* /*
* Define the interrupt mechanism for Time Test 27 * Define the interrupt mechanism for Time Test 27
* *
* NOTE: Use a software interrupt for the i386. * NOTE: Use a software interrupt for the i386 family.
*/ */
#define MUST_WAIT_FOR_INTERRUTPT 0 #define MUST_WAIT_FOR_INTERRUPT 0
#define Install_tm27_vector( handler ) set_vector( (handler), 0x90, 1 ) #define Install_tm27_vector( handler ) set_vector( (handler), 0x90, 1 )
#define Cause_tm27_intr() asm volatile( "int $0x90" : : ); #define Cause_tm27_intr() asm volatile( "int $0x90" : : );
#define Clear_tm27_intr() #define Clear_tm27_intr()
#define Lower_tm27_intr() #define Lower_tm27_intr()
/* /*
* Simple spin delay in microsecond units for device drivers. * Simple spin delay in microsecond units for device drivers.
* This is very dependent on the clock speed of the target. * This is very dependent on the clock speed of the target.
@@ -105,6 +104,11 @@ extern "C" {
#define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */ #define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */
#define TIMER_BCD 0x01 /* count in BCD */ #define TIMER_BCD 0x01 /* count in BCD */
#define CLOCK_DISABLE() \
({ char mask; inport_byte( 0x21, mask ); outport_byte( 0x21, mask | 1 ); })
#define CLOCK_ENABLE() \
({ char mask; inport_byte( 0x21, mask ); outport_byte( 0x21, mask & ~1); })
/* The internal tick rate in ticks per second */ /* The internal tick rate in ticks per second */
#define TIMER_TICK 1193182 #define TIMER_TICK 1193182
#define US_TO_TICK(us) (((us)*105+44)/88) #define US_TO_TICK(us) (((us)*105+44)/88)
@@ -154,3 +158,4 @@ i386_isr_entry set_vector(
#endif #endif
/* end of include file */ /* end of include file */

View File

@@ -37,30 +37,9 @@ i386_isr_entry set_vector( /* returns old vector */
i386_isr_entry previous_isr; i386_isr_entry previous_isr;
if ( type ) { if ( type ) {
rtems_interrupt_catch( handler, vector, rtems_interrupt_catch( handler, vector, (rtems_isr_entry *) &previous_isr);
(rtems_isr_entry *) &previous_isr );
} else { } else {
/* Interrupt goes straight to the supplied ISR. This code is */ _CPU_ISR_install_raw_handler( vector, handler, (proc_ptr *)&previous_isr);
/* slightly different than that in _CPU_ISR_install_vector */
/* (which is eventually called by the above) in that this code */
/* returns the raw entry point as the old handler, while the */
/* other version returns the old entry point pointed at by the */
/* rtems ISR table. */
_go32_dpmi_seginfo handler_info;
/* get the address of the old handler */
_go32_dpmi_get_protected_mode_interrupt_vector( vector, &handler_info);
/* Notice how we're failing to save the pm_segment portion of the */
/* structure here? That means we might crash the system if we */
/* try to restore the ISR. Can't fix this until i386_isr is */
/* redefined. XXX [BHC]. */
previous_isr = (i386_isr_entry) handler_info.pm_offset;
/* install the IDT entry */
handler_info.pm_offset = (u_long)handler;
handler_info.pm_selector = _go32_my_cs();
_go32_dpmi_set_protected_mode_interrupt_vector( vector, &handler_info);
} }
return previous_isr; return previous_isr;
} }

View File

@@ -20,7 +20,6 @@
* $Id$ * $Id$
*/ */
#include <rtems.h> #include <rtems.h>
#include <bsp.h> #include <bsp.h>
@@ -35,33 +34,54 @@ static inline unsigned long long rdtsc( void )
__asm __volatile( ".byte 0x0F, 0x31" : "=A" (result) ); __asm __volatile( ".byte 0x0F, 0x31" : "=A" (result) );
return result; return result;
} }
static void restore_timer( void )
{
CLOCK_ENABLE();
}
#else /* pentium */ #else /* pentium */
rtems_isr timerisr(); rtems_isr timerisr();
#endif /* pentium */ #endif /* pentium */
void Timer_initialize() void Timer_initialize()
{ {
static int First = 1;
#if defined(pentium) #if defined(pentium)
if ( First ) {
extern int atexit( void (*)(void) );
First = 0;
/* Disable the programmable timer. */
CLOCK_DISABLE();
/* Try not to hose the system on return to DOS. */
atexit( restore_timer );
}
Ttimer_val = rdtsc(); Ttimer_val = rdtsc();
#else /* pentium */ #else /* pentium */
static int First = 1;
#define WAIT() \
{ \
Ttimer_val = 0; \
while ( Ttimer_val == 0 ) \
continue; \
Ttimer_val = 0; \
}
if ( First ) { if ( First ) {
First = 0;
/* install ISR */ /* install ISR */
set_vector( timerisr, 0x8, 0 ); set_vector( timerisr, 0x8, 0 );
/* Wait for ISR to be called at least once */ /* Wait for ISR to be called at least once */
Ttimer_val = 0; WAIT();
while ( Ttimer_val == 0 )
continue;
/* load timer for 250 microsecond period */ /* load timer for 250 microsecond period */
outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN ); outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN );
outport_byte( TIMER_CNTR0, US_TO_TICK(250) >> 0 & 0xff); outport_byte( TIMER_CNTR0, US_TO_TICK(250) >> 0 & 0xff);
outport_byte( TIMER_CNTR0, US_TO_TICK(250) >> 8 & 0xff); outport_byte( TIMER_CNTR0, US_TO_TICK(250) >> 8 & 0xff);
First = 0;
} }
Ttimer_val = 0; /* clear timer ISR count */
/* Wait for ISR to be called at least once */
WAIT();
#endif /* PENTIUM */ #endif /* PENTIUM */
} }
@@ -81,7 +101,7 @@ int Read_timer()
inport_byte( TIMER_CNTR0, lsb ); inport_byte( TIMER_CNTR0, lsb );
inport_byte( TIMER_CNTR0, msb ); inport_byte( TIMER_CNTR0, msb );
clicks = msb << 8 | lsb; clicks = msb << 8 | lsb;
total = Ttimer_val + 250 - TICK_TO_US( clicks ); total = Ttimer_val + (250 - TICK_TO_US( clicks ));
#endif /* pentium */ #endif /* pentium */
if ( Timer_driver_Find_average_overhead == 1 ) if ( Timer_driver_Find_average_overhead == 1 )
@@ -104,3 +124,4 @@ void Set_find_average_overhead(
{ {
Timer_driver_Find_average_overhead = find_flag; Timer_driver_Find_average_overhead = find_flag;
} }

View File

@@ -26,16 +26,16 @@
PUBLIC(timerisr) PUBLIC(timerisr)
SYM (timerisr): SYM (timerisr):
addl $250,_Ttimer_val # another 250 microseconds addl $250,_Ttimer_val # another 250 microseconds
push edx push edx
push eax push eax
movw $0x20,dx movw $0x20,dx
mov edx,eax mov edx,eax
outb al,(dx) # touch interrupt controller outb al,(dx) # touch interrupt controller
pop eax pop eax
pop edx pop edx
iret iret
END_CODE END_CODE
END END