source: rtems/c/src/lib/libbsp/i386/pc386/clock/ckinit.c @ 6fda59f

4.104.114.84.9
Last change on this file since 6fda59f was 6fda59f, checked in by Ralf Corsepius <ralf.corsepius@…>, on Mar 31, 2004 at 5:08:13 AM

2004-03-31 Ralf Corsepius <ralf_corsepius@…>

  • clock/ckinit.c, clock/rtc.c, console/inch.c, ide/ide.c, include/bsp.h, startup/bspstart.c, timer/timer.c: Convert to using c99 fixed size types.
  • Property mode set to 100644
File size: 9.2 KB
Line 
1/*-------------------------------------------------------------------------+
2| ckinit.c v1.1 - PC386 BSP - 1997/08/07
3+--------------------------------------------------------------------------+
4| This file contains the PC386 clock package.
5+--------------------------------------------------------------------------+
6| (C) Copyright 1997 -
7| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
8|
9| http://pandora.ist.utl.pt
10|
11| Instituto Superior Tecnico * Lisboa * PORTUGAL
12+--------------------------------------------------------------------------+
13| Disclaimer:
14|
15| This file is provided "AS IS" without warranty of any kind, either
16| expressed or implied.
17+--------------------------------------------------------------------------+
18| This code is based on:
19|   ckinit.c,v 1.4 1995/12/19 20:07:13 joel Exp - go32 BSP
20| With the following copyright notice:
21| **************************************************************************
22| *  COPYRIGHT (c) 1989-1999.
23| *  On-Line Applications Research Corporation (OAR).
24| *
25| *  The license and distribution terms for this file may be
26| *  found in found in the file LICENSE in this distribution or at
27| *  http://www.rtems.com/license/LICENSE.
28| **************************************************************************
29|
30|  $Id$
31+--------------------------------------------------------------------------*/
32
33
34#include <stdlib.h>
35
36#include <bsp.h>
37#include <irq.h>
38#include <rtems/libio.h>
39
40/*-------------------------------------------------------------------------+
41| Macros
42+--------------------------------------------------------------------------*/
43#if 0
44/* This was dropped in the last revision.  Its a nice thing to know. */
45#define TICKS_PER_SECOND() \
46          (1000000 / (Clock_isrs_per_tick * microseconds_per_isr))
47#endif /* 0 */
48
49/*-------------------------------------------------------------------------+
50| Global Variables
51+--------------------------------------------------------------------------*/
52
53volatile uint32_t         Clock_driver_ticks;   /* Tick (interrupt) counter. */
54         uint32_t         Clock_isrs_per_tick;  /* ISRs per tick.            */
55         uint32_t         Clock_isrs;           /* ISRs until next tick.     */
56
57/* The following variables are set by the clock driver during its init */
58
59rtems_device_major_number rtems_clock_major = ~0;
60rtems_device_minor_number rtems_clock_minor;
61
62/*-------------------------------------------------------------------------+
63|         Function: clockIsr
64|      Description: Interrupt Service Routine for clock (0h) interruption.
65| Global Variables: Clock_driver_ticks, Clock_isrs.
66|        Arguments: vector - standard RTEMS argument - see documentation.
67|          Returns: standard return value - see documentation.
68+--------------------------------------------------------------------------*/
69static void clockIsr()
70{
71  /*-------------------------------------------------------------------------+
72  | PLEASE NOTE: The following is directly transcribed from the go32 BSP for
73  |              those who wish to use it with PENTIUM based machine. It needs
74  |              to be correctly integrated with the rest of the code!!!
75  +--------------------------------------------------------------------------*/
76
77#if 0 && defined(pentium) /* more accurate clock for PENTIUMs (not supported) */
78  {
79    extern long long Last_RDTSC;
80    __asm __volatile(".byte 0x0F, 0x31" : "=A" (Last_RDTSC));
81  }
82#endif /* 0 && pentium */
83
84  Clock_driver_ticks++;
85
86  if ( Clock_isrs == 1 )
87  {
88    rtems_clock_tick();
89    Clock_isrs = Clock_isrs_per_tick;
90  }
91  else
92    Clock_isrs--;
93
94} /* clockIsr */
95
96/*-------------------------------------------------------------------------+
97|         Function: Clock_exit
98|      Description: Clock cleanup routine at RTEMS exit. NOTE: This routine is
99|                   not really necessary, since there will be a reset at exit.
100| Global Variables: None.
101|        Arguments: None.
102|          Returns: Nothing.
103+--------------------------------------------------------------------------*/
104void clockOff(const rtems_irq_connect_data* unused)
105{
106  /* reset timer mode to standard (BIOS) value */
107  outport_byte(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN);
108  outport_byte(TIMER_CNTR0, 0);
109  outport_byte(TIMER_CNTR0, 0);
110} /* Clock_exit */
111
112
113/*-------------------------------------------------------------------------+
114|         Function: Install_clock
115|      Description: Initialize and install clock interrupt handler.
116| Global Variables: None.
117|        Arguments: None.
118|          Returns: Nothing.
119+--------------------------------------------------------------------------*/
120static void clockOn(const rtems_irq_connect_data* unused)
121{
122  uint32_t          microseconds_per_isr;
123
124#if 0
125  /* Initialize clock from on-board real time clock.  This breaks the  */
126  /* test code which assumes which assumes the application will do it. */
127  {
128    rtems_time_of_day now;
129
130    /* External Prototypes */
131    extern void init_rtc(void);                /* defined in 'rtc.c' */
132    extern long rtc_read(rtems_time_of_day *); /* defined in 'rtc.c' */
133
134    init_rtc();
135    if (rtc_read(&now) >= 0)
136      clock_set(&now);
137  }
138#endif /* 0 */
139
140  /* Start by assuming hardware counter is large enough, then  scale it until
141     it actually fits. */
142
143  Clock_driver_ticks  = 0;
144  Clock_isrs_per_tick = 1;
145
146  if (BSP_Configuration.microseconds_per_tick == 0)
147    microseconds_per_isr = 10000; /* default 10 ms */
148  else
149    microseconds_per_isr = BSP_Configuration.microseconds_per_tick;
150  while (US_TO_TICK(microseconds_per_isr) > 65535)
151  {
152    Clock_isrs_per_tick  *= 10;
153    microseconds_per_isr /= 10;
154  }
155
156  Clock_isrs = Clock_isrs_per_tick; /* Initialize Clock_isrs */
157
158  {
159    /* 105/88 approximates TIMER_TICK * 1e-6 */
160    uint32_t         count = US_TO_TICK(microseconds_per_isr);
161
162    outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);
163    outport_byte(TIMER_CNTR0, count >> 0 & 0xff);
164    outport_byte(TIMER_CNTR0, count >> 8 & 0xff);
165  } 
166
167} 
168
169int clockIsOn(const rtems_irq_connect_data* unused)
170{
171  return ((i8259s_cache & 0x1) == 0);
172}
173
174static rtems_irq_connect_data clockIrqData = {BSP_PERIODIC_TIMER,
175                                              clockIsr,
176                                              clockOn,
177                                              clockOff,
178                                              clockIsOn};
179                                             
180                                             
181
182/*-------------------------------------------------------------------------+
183| Clock device driver INITIALIZE entry point.
184+--------------------------------------------------------------------------+
185| Initilizes the clock driver.
186+--------------------------------------------------------------------------*/
187rtems_device_driver
188Clock_initialize(rtems_device_major_number major,
189                 rtems_device_minor_number minor,
190                 void                      *pargp)
191{
192
193  if (!BSP_install_rtems_irq_handler (&clockIrqData)) {
194    printk("Unable to initialize system clock\n");
195    rtems_fatal_error_occurred(1);
196  }
197  /* make major/minor avail to others such as shared memory driver */
198 
199  rtems_clock_major = major;
200  rtems_clock_minor = minor;
201 
202  return RTEMS_SUCCESSFUL;
203} /* Clock_initialize */
204
205                                             
206/*-------------------------------------------------------------------------+
207| Console device driver CONTROL entry point
208+--------------------------------------------------------------------------*/
209rtems_device_driver
210Clock_control(rtems_device_major_number major,
211              rtems_device_minor_number minor,
212              void                      *pargp)
213{
214  if (pargp != NULL)
215  {
216    rtems_libio_ioctl_args_t *args = pargp;
217       
218    /*-------------------------------------------------------------------------+
219    | This is hokey, but until we get a defined interface to do this, it will
220    | just be this simple...
221    +-------------------------------------------------------------------------*/
222 
223    if      (args->command == rtems_build_name('I', 'S', 'R', ' '))
224      clockIsr();
225    else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
226    {
227      if (!BSP_install_rtems_irq_handler (&clockIrqData)) {
228        printk("Error installing clock interrupt handler!\n");
229        rtems_fatal_error_occurred(1);
230      }
231    }
232  }
233
234  return RTEMS_SUCCESSFUL;
235} /* Clock_control */
236
237void Clock_exit()
238{
239  BSP_remove_rtems_irq_handler (&clockIrqData);
240}
241
242/*-------------------------------------------------------------------------+
243| PLEASE NOTE: The following is directly transcribed from the go32 BSP for
244|              those who wish to use it with PENTIUM based machine. It needs
245|              to be correctly integrated with the rest of the code!!!
246+--------------------------------------------------------------------------*/
247
248
249#if 0 && defined(pentium)
250
251/* This can be used to get extremely accurate timing on a pentium. */
252/* It isn't supported. [bryce]                                     */
253
254#define HZ 90.0
255
256volatile long long Last_RDTSC;
257
258#define RDTSC()\
259  ({ long long _now; __asm __volatile (".byte 0x0F,0x31":"=A"(_now)); _now; })
260
261long long Kernel_Time_ns( void )
262{
263  extern uint32_t         _TOD_Ticks_per_second;
264
265  unsigned  isrs_per_second = Clock_isrs_per_tick * _TOD_Ticks_per_second;
266  long long now;
267  int       flags;
268
269  disable_intr(flags);
270  now = 1e9 * Clock_driver_ticks / isrs_per_second +
271        (RDTSC() - Last_RDTSC) * (1000.0/HZ);
272  enable_intr(flags);
273  return now;
274} /* Kernel_Time_ns */
275
276#endif /* 0 && pentium */
Note: See TracBrowser for help on using the repository browser.