source: rtems/c/src/lib/libbsp/i386/go32/timer/timer.c @ 2f2a597

4.104.114.84.95
Last change on this file since 2f2a597 was 2f2a597, checked in by Joel Sherrill <joel.sherrill@…>, on 07/24/95 at 14:00:27

hopefully works with regular timer and tm27

  • Property mode set to 100644
File size: 3.7 KB
Line 
1/*  Timer_init()
2 *
3 *  This routine initializes the timer on the IBM 386.
4 *
5 *  Input parameters:  NONE
6 *
7 *  Output parameters:  NONE
8 *
9 *  NOTE: It is important that the timer start/stop overhead be
10 *        determined when porting or modifying this code.
11 *
12 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
13 *  On-Line Applications Research Corporation (OAR).
14 *  All rights assigned to U.S. Government, 1994.
15 *
16 *  This material may be reproduced by or for the U.S. Government pursuant
17 *  to the copyright license under the clause at DFARS 252.227-7013.  This
18 *  notice must appear in all copies of this file and its derivatives.
19 *
20 *  $Id$
21 */
22
23#include <rtems.h>
24#include <bsp.h>
25
26volatile rtems_unsigned32 Ttimer_val;
27rtems_boolean Timer_driver_Find_average_overhead;
28
29#if defined(pentium)
30static inline unsigned long long rdtsc( void )
31{
32    /* Return the value of the on-chip cycle counter. */
33    unsigned long long result;
34    __asm __volatile( ".byte 0x0F, 0x31" : "=A" (result) );
35    return result;
36}
37#else
38extern rtems_isr timerisr();
39static rtems_isr_entry Old_Ticker;
40#endif
41
42static void Timer_exit( void )
43{
44#if defined(pentium)
45    CLOCK_ENABLE();
46#else /* pentium */
47    extern void rtc_set_dos_date( void );
48
49    /* reset to DOS value: */
50    outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN );
51    outport_byte( TIMER_CNTR0, 0 );
52    outport_byte( TIMER_CNTR0, 0 );
53
54    /* reset time-of-day */
55    rtc_set_dos_date();
56       
57    /* re-enable old handler: assume it was one of ours */
58    set_vector( (rtems_isr_entry)Old_Ticker, 0x8, 0 );
59#endif /* pentium */
60}
61
62void Timer_initialize()
63{
64    extern int atexit( void (*)(void) );
65
66    static int First = 1;
67
68    if ( First )  {
69        First = 0;
70
71        /* Try not to hose the system on return to DOS. */
72        atexit( Timer_exit );
73
74#if defined(pentium)
75        /* Disable the programmable timer so ticks don't interfere. */
76        CLOCK_DISABLE();
77#else /* pentium */
78        /* install a timer ISR */
79        Old_Ticker = (rtems_isr_entry) set_vector( timerisr, 0x8, 0 );
80
81        /* Wait for ISR to be called at least once */
82        Ttimer_val = 0;
83        while ( Ttimer_val == 0 )
84            continue;
85
86        /* load timer for 250 microsecond period */
87        outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN );
88        outport_byte( TIMER_CNTR0, US_TO_TICK(250) >> 0 & 0xff );
89        outport_byte( TIMER_CNTR0, US_TO_TICK(250) >> 8 & 0xff );
90#endif /* PENTIUM */
91    }
92#if defined(pentium)
93    Ttimer_val = rdtsc();       /* read starting time */
94#else
95    /* Wait for ISR to be called at least once */
96    asm( "sti" );
97    Ttimer_val = 0;
98    while ( Ttimer_val == 0 )
99        continue;
100    Ttimer_val = 0;
101#endif
102}
103
104#define AVG_OVERHEAD       0  /* 0.1 microseconds to start/stop timer. */
105#define LEAST_VALID        1  /* Don't trust a value lower than this */
106
107
108int Read_timer()
109{
110    register rtems_unsigned32 total;
111#if defined(pentium)
112    total = rdtsc() - Ttimer_val;
113#else /* pentium */
114    register rtems_unsigned8 lsb, msb;
115    register rtems_unsigned32 clicks;
116    outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_LATCH );
117    inport_byte( TIMER_CNTR0, lsb );
118    inport_byte( TIMER_CNTR0, msb );
119    clicks = msb << 8 | lsb;
120    total = Ttimer_val + 250 - TICK_TO_US( clicks );
121#endif /* pentium */
122
123    if ( Timer_driver_Find_average_overhead == 1 )
124        return total;
125    else if ( total < LEAST_VALID )
126        return 0;               /* below timer resolution */
127    else
128        return total - AVG_OVERHEAD;
129}
130
131rtems_status_code Empty_function( void )
132{
133    return RTEMS_SUCCESSFUL;
134}
135
136
137void Set_find_average_overhead(
138  rtems_boolean find_flag
139)
140{
141  Timer_driver_Find_average_overhead = find_flag;
142}
143
Note: See TracBrowser for help on using the repository browser.