source: rtems/c/src/lib/libbsp/i386/go32/timer/timer.c @ 254b4450

4.104.114.84.95
Last change on this file since 254b4450 was c35e9622, checked in by Joel Sherrill <joel.sherrill@…>, on 07/24/95 at 15:43:17

times reported reasonably correctly

  • 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
38#define US_PER_ISR  250
39extern rtems_isr timerisr();
40static rtems_isr_entry Old_Ticker;
41#endif
42
43static void Timer_exit( void )
44{
45#if defined(pentium)
46    CLOCK_ENABLE();
47#else /* pentium */
48    extern void rtc_set_dos_date( void );
49
50    /* reset to DOS value: */
51    outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN );
52    outport_byte( TIMER_CNTR0, 0 );
53    outport_byte( TIMER_CNTR0, 0 );
54
55    /* reset time-of-day */
56    rtc_set_dos_date();
57       
58    /* re-enable old handler: assume it was one of ours */
59    set_vector( (rtems_isr_entry)Old_Ticker, 0x8, 0 );
60#endif /* pentium */
61}
62
63void Timer_initialize()
64{
65    extern int atexit( void (*)(void) );
66
67    static int First = 1;
68
69    if ( First )  {
70        First = 0;
71
72        /* Try not to hose the system on return to DOS. */
73        atexit( Timer_exit );
74
75#if defined(pentium)
76        /* Disable the programmable timer so ticks don't interfere. */
77        CLOCK_DISABLE();
78#else /* pentium */
79        /* install a timer ISR */
80        Old_Ticker = (rtems_isr_entry) set_vector( timerisr, 0x8, 0 );
81
82        /* Wait for ISR to be called at least once */
83        Ttimer_val = 0;
84        while ( Ttimer_val == 0 )
85            continue;
86
87        /* load timer for US_PER_ISR microsecond period */
88        outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN );
89        outport_byte( TIMER_CNTR0, US_TO_TICK(US_PER_ISR) >> 0 & 0xff );
90        outport_byte( TIMER_CNTR0, US_TO_TICK(US_PER_ISR) >> 8 & 0xff );
91#endif /* PENTIUM */
92    }
93#if defined(pentium)
94    Ttimer_val = rdtsc();       /* read starting time */
95#else
96    /* Wait for ISR to be called at least once */
97    asm( "sti" );
98    Ttimer_val = 0;
99    while ( Ttimer_val == 0 )
100        continue;
101    Ttimer_val = 0;
102#endif
103}
104
105#define AVG_OVERHEAD       0  /* 0.1 microseconds to start/stop timer. */
106#define LEAST_VALID        1  /* Don't trust a value lower than this */
107
108
109int Read_timer()
110{
111    register rtems_unsigned32 total;
112#if defined(pentium)
113    total = rdtsc() - Ttimer_val;
114#else /* pentium */
115    register rtems_unsigned8 lsb, msb;
116    register rtems_unsigned32 clicks;
117    outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_LATCH );
118    inport_byte( TIMER_CNTR0, lsb );
119    inport_byte( TIMER_CNTR0, msb );
120    clicks = msb << 8 | lsb;
121    total = (Ttimer_val * US_PER_ISR) + (US_PER_ISR - TICK_TO_US( clicks ));
122#endif /* pentium */
123
124    if ( Timer_driver_Find_average_overhead == 1 )
125        return total;
126    else if ( total < LEAST_VALID )
127        return 0;               /* below timer resolution */
128    else
129        return total - AVG_OVERHEAD;
130}
131
132rtems_status_code Empty_function( void )
133{
134    return RTEMS_SUCCESSFUL;
135}
136
137
138void Set_find_average_overhead(
139  rtems_boolean find_flag
140)
141{
142  Timer_driver_Find_average_overhead = find_flag;
143}
144
Note: See TracBrowser for help on using the repository browser.