source: rtems/c/src/lib/libbsp/i386/go32/timer/timer.c @ 1690c6b

4.104.114.84.95
Last change on this file since 1690c6b was 1690c6b, checked in by Joel Sherrill <joel.sherrill@…>, on 07/21/95 at 20:10:49

after testing go32 and cvme961

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