source: rtems/c/src/lib/libbsp/i386/go32/timer/timer.c @ 9e738b65

4.104.114.84.95
Last change on this file since 9e738b65 was 9e738b65, checked in by Joel Sherrill <joel.sherrill@…>, on 07/20/95 at 19:20:31

updating go32 to make timer more accurate

  • Property mode set to 100644
File size: 3.1 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}
37static void restore_timer( void )
38{
39    CLOCK_ENABLE();
40}
41#else /* pentium */
42rtems_isr timerisr();
43#endif /* pentium */
44
45void Timer_initialize()
46{
47    static int First = 1;
48#if defined(pentium)
49    if ( First )  {
50        extern int atexit( void (*)(void) );
51        First = 0;
52        /* Disable the programmable timer. */
53        CLOCK_DISABLE();
54        /* Try not to hose the system on return to DOS. */
55        atexit( restore_timer );
56    }
57    Ttimer_val = rdtsc();
58#else /* pentium */
59
60#define WAIT() \
61  { \
62    Ttimer_val = 0; \
63    while ( Ttimer_val == 0 ) \
64      continue; \
65    Ttimer_val = 0; \
66  }
67
68    if ( First )  {
69        First = 0;
70
71        /* install ISR */
72        set_vector( timerisr, 0x8, 0 );
73
74       /* Wait for ISR to be called at least once */
75       WAIT();
76
77       /* load timer for 250 microsecond period */
78       outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN );
79       outport_byte( TIMER_CNTR0, US_TO_TICK(250) >> 0 & 0xff);
80       outport_byte( TIMER_CNTR0, US_TO_TICK(250) >> 8 & 0xff);
81    }
82
83    /* Wait for ISR to be called at least once */
84    WAIT();
85#endif /* PENTIUM */
86}
87
88#define AVG_OVERHEAD       0  /* 0.1 microseconds to start/stop timer. */
89#define LEAST_VALID        1  /* Don't trust a value lower than this */
90
91
92int Read_timer()
93{
94    register rtems_unsigned32 total;
95#if defined(pentium)
96    total = rdtsc() - Ttimer_val;
97#else /* pentium */
98    register rtems_unsigned8 lsb, msb;
99    register rtems_unsigned32 clicks;
100    outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_LATCH );
101    inport_byte( TIMER_CNTR0, lsb );
102    inport_byte( TIMER_CNTR0, msb );
103    clicks = msb << 8 | lsb;
104    total = Ttimer_val + (250 - TICK_TO_US( clicks ));
105#endif /* pentium */
106
107    if ( Timer_driver_Find_average_overhead == 1 )
108        return total;
109    else if ( total < LEAST_VALID )
110        return 0;               /* below timer resolution */
111    else
112        return total - AVG_OVERHEAD;
113}
114
115rtems_status_code Empty_function( void )
116{
117    return RTEMS_SUCCESSFUL;
118}
119
120
121void Set_find_average_overhead(
122  rtems_boolean find_flag
123)
124{
125  Timer_driver_Find_average_overhead = find_flag;
126}
127
Note: See TracBrowser for help on using the repository browser.