source: rtems/c/src/lib/libbsp/i386/go32/clock/ckinit.c @ 3a4ae6c

4.104.114.84.95
Last change on this file since 3a4ae6c was 3a4ae6c, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 11, 1995 at 7:35:39 PM

The word "RTEMS" almost completely removed from the core.

Configuration Table Template file added and all tests
modified to use this. All gvar.h and conftbl.h files
removed from test directories.

Configuration parameter maximum_devices added.

Core semaphore and mutex handlers added and RTEMS API Semaphore
Manager updated to reflect this.

Initialization sequence changed to invoke API specific initialization
routines. Initialization tasks table now owned by RTEMS Tasks Manager.

Added user extension for post-switch.

Utilized user extensions to implement API specific functionality
like signal dispatching.

Added extensions to the System Initialization Thread so that an
API can register a function to be invoked while the system
is being initialized. These are largely equivalent to the
pre-driver and post-driver hooks.

Added the Modules file oar-go32_p5, modified oar-go32, and modified
the file make/custom/go32.cfg to look at an environment varable which
determines what CPU model is being used.

All BSPs updated to reflect named devices and clock driver's IOCTL
used by the Shared Memory Driver. Also merged clock isr into
main file and removed ckisr.c where possible.

Updated spsize to reflect new and moved variables.

Makefiles for the executive source and include files updated to show
break down of files into Core, RTEMS API, and Neither.

Header and inline files installed into subdirectory based on whether
logically in the Core or a part of the RTEMS API.

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*  Clock_initialize
2 *
3 *  This routine initializes the 8254 timer under GO32.
4 *  The tick frequency is 1 millisecond.
5 *
6 *  Input parameters:  NONE
7 *
8 *  Output parameters:  NONE
9 *
10 *  $Id$
11 */
12
13#include <bsp.h>
14#include <rtems/libio.h>
15
16#include <stdlib.h>
17
18volatile rtems_unsigned32 Clock_driver_ticks;
19rtems_unsigned32 Clock_isrs_per_tick;  /* ISRs per tick */
20rtems_unsigned32 Clock_isrs;   /* ISRs until next tick */
21rtems_isr_entry  Old_ticker;
22
23#define CLOCK_VECTOR 0x8
24
25void Clock_exit( void );
26
27/*
28 * These are set by clock driver during its init
29 */
30 
31rtems_device_major_number rtems_clock_major = ~0;
32rtems_device_minor_number rtems_clock_minor;
33
34rtems_isr Clock_isr(
35  rtems_vector_number vector
36)
37{
38    /* touch interrupt controller for irq0 (0x20+0) */
39    outport_byte( 0x20, 0x20 );
40
41    Clock_driver_ticks += 1;
42
43#if 0 && defined(pentium)
44    {
45      extern long long Last_RDTSC;
46      __asm __volatile( ".byte 0x0F, 0x31" : "=A" (Last_RDTSC) );
47    }
48#endif
49
50    if ( Clock_isrs == 1 ) {
51      rtems_clock_tick();
52      Clock_isrs = Clock_isrs_per_tick;
53    } else {
54      Clock_isrs -= 1;
55    }
56}
57
58void Install_clock(
59  rtems_isr_entry clock_isr
60)
61{
62    unsigned int microseconds_per_isr;
63
64#if 0
65    /* Initialize clock from on-board real time clock.  This breaks the */
66    /* test code which assumes which assumes the application will do it. */
67    {
68       rtems_time_of_day Now;
69       extern void init_rtc( void );
70       extern long rtc_read( rtems_time_of_day * tod );
71       init_rtc();
72       if ( rtc_read( &Now ) >= 0 )
73         clock_set( &Now );
74       }
75#endif
76
77    /* Start by assuming hardware counter is large enough, then */
78    /* scale it until it actually fits.    */
79    Clock_driver_ticks = 0;
80    Clock_isrs_per_tick = 1;
81
82    if ( BSP_Configuration.microseconds_per_tick == 0 )
83       microseconds_per_isr = 10000; /* default 10 ms */
84    else
85       microseconds_per_isr = BSP_Configuration.microseconds_per_tick;
86    while ( US_TO_TICK(microseconds_per_isr) > 65535 )  {
87      Clock_isrs_per_tick  *= 10;
88      microseconds_per_isr /= 10;
89    }
90
91    /* Initialize count in ckisr.c */
92    Clock_isrs = Clock_isrs_per_tick;
93
94#if 0
95    /* This was dropped in the last revision.  Its a nice thing to know. */
96    TICKS_PER_SECOND = 1000000 / (Clock_isrs_per_tick * microseconds_per_isr);
97#endif
98
99    if ( BSP_Configuration.ticks_per_timeslice )  {
100      /* 105/88 approximates TIMER_TICK*1e-6 */
101      unsigned int count = US_TO_TICK( microseconds_per_isr );
102
103      Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 );
104      outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN );
105      outport_byte( TIMER_CNTR0, count >> 0 & 0xff );
106      outport_byte( TIMER_CNTR0, count >> 8 & 0xff );
107    } 
108    atexit( Clock_exit );
109}
110
111void ReInstall_clock(
112  rtems_isr_entry clock_isr
113)
114{
115  rtems_unsigned32 isrlevel = 0;
116
117  rtems_interrupt_disable( isrlevel );
118   (void) set_vector( clock_isr, CLOCK_VECTOR, 1 );
119  rtems_interrupt_enable( isrlevel );
120}
121
122void Clock_exit( void )
123{
124  if ( BSP_Configuration.ticks_per_timeslice ) {
125 extern void rtc_set_dos_date( void );
126
127 /* reset to DOS value: */
128 outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN );
129 outport_byte( TIMER_CNTR0, 0 );
130 outport_byte( TIMER_CNTR0, 0 );
131
132 /* reset time-of-day */
133 rtc_set_dos_date();
134 
135 /* re-enable old handler: assume it was one of ours */
136 set_vector( (rtems_isr_entry)Old_ticker, CLOCK_VECTOR, 1 );
137  }
138}
139
140rtems_device_driver Clock_initialize(
141  rtems_device_major_number major,
142  rtems_device_minor_number minor,
143  void *pargp
144)
145{
146  Install_clock( Clock_isr );
147 
148  /*
149   * make major/minor avail to others such as shared memory driver
150   */
151 
152  rtems_clock_major = major;
153  rtems_clock_minor = minor;
154 
155  return RTEMS_SUCCESSFUL;
156}
157 
158rtems_device_driver Clock_control(
159  rtems_device_major_number major,
160  rtems_device_minor_number minor,
161  void *pargp
162)
163{
164    rtems_libio_ioctl_args_t *args = pargp;
165 
166    if (args == 0)
167        goto done;
168 
169    /*
170     * This is hokey, but until we get a defined interface
171     * to do this, it will just be this simple...
172     */
173 
174    if (args->command == rtems_build_name('I', 'S', 'R', ' '))
175    {
176        Clock_isr(CLOCK_VECTOR);
177    }
178    else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
179    {
180        ReInstall_clock(args->buffer);
181    }
182 
183done:
184    return RTEMS_SUCCESSFUL;
185}
186
187#if 0 && defined(pentium)
188/* This can be used to get extremely accurate timing on a pentium. */
189/* It isn't supported. [bryce]      */
190#define HZ 90.0
191volatile long long Last_RDTSC;
192#define RDTSC()\
193  ({ long long _now; __asm __volatile (".byte 0x0F,0x31":"=A"(_now)); _now; })
194
195long long Kernel_Time_ns( void )
196{
197    extern rtems_unsigned32 _TOD_Ticks_per_second;
198    unsigned isrs_per_second = Clock_isrs_per_tick * _TOD_Ticks_per_second;
199    long long now;
200    int flags;
201    disable_intr( flags );
202    now = 1e9 * Clock_driver_ticks / isrs_per_second
203       + (RDTSC() - Last_RDTSC) * (1000.0/HZ);
204    enable_intr( flags );
205    return now;
206}
207#endif
Note: See TracBrowser for help on using the repository browser.