OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [i386/] [pc386/] [clock/] [ckinit.c] - Blame information for rev 173

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*-------------------------------------------------------------------------+
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.OARcorp.com/rtems/license.html.
28
| **************************************************************************
29
|
30
|  $Id: ckinit.c,v 1.2 2001-09-27 11:59:47 chris Exp $
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
 
53
volatile rtems_unsigned32 Clock_driver_ticks;   /* Tick (interrupt) counter. */
54
         rtems_unsigned32 Clock_isrs_per_tick;  /* ISRs per tick.            */
55
         rtems_unsigned32 Clock_isrs;           /* ISRs until next tick.     */
56
 
57
/* The following variables are set by the clock driver during its init */
58
 
59
rtems_device_major_number rtems_clock_major = ~0;
60
rtems_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
+--------------------------------------------------------------------------*/
69
static 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
+--------------------------------------------------------------------------*/
104
void 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
+--------------------------------------------------------------------------*/
120
static void clockOn(const rtems_irq_connect_data* unused)
121
{
122
  rtems_unsigned32  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
    rtems_unsigned32 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
 
169
int clockIsOn(const rtems_irq_connect_data* unused)
170
{
171
  return ((i8259s_cache & 0x1) == 0);
172
}
173
 
174
static 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
+--------------------------------------------------------------------------*/
187
rtems_device_driver
188
Clock_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
+--------------------------------------------------------------------------*/
209
rtems_device_driver
210
Clock_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
 
237
void 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
 
256
volatile long long Last_RDTSC;
257
 
258
#define RDTSC()\
259
  ({ long long _now; __asm __volatile (".byte 0x0F,0x31":"=A"(_now)); _now; })
260
 
261
long long Kernel_Time_ns( void )
262
{
263
  extern rtems_unsigned32 _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 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.