forked from Imagelibrary/rtems
updating go32 to make timer more accurate
This commit is contained in:
@@ -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 )
|
||||||
|
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user