GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / main / cfe_timer.c
blob19b96e926b6731092896e0c371ccba4c1504bf98
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * Timer routines File: cfe_timer.c
5 *
6 * This module contains routines to keep track of the system time,.
7 * Since we don't have any interrupts in the firmware, even the
8 * timer is polled. The timer must be called often enough
9 * to prevent missing the overflow of the CP0 COUNT
10 * register, approximately 2 billion cycles (half the count)
12 * Be sure to use the POLL() macro each time you enter a loop
13 * where you are waiting for some I/O event to occur or
14 * are waiting for time to elapse.
16 * It is *not* a time-of-year clock. The timer is only used
17 * for timing I/O events.
19 * Internally, time is maintained in units of "CLOCKSPERTICK",
20 * which should be about tenths of seconds.
22 * Author: Mitch Lichtenberg (mpl@broadcom.com)
24 *********************************************************************
26 * Copyright 2000,2001,2002,2003
27 * Broadcom Corporation. All rights reserved.
29 * This software is furnished under license and may be used and
30 * copied only in accordance with the following terms and
31 * conditions. Subject to these conditions, you may download,
32 * copy, install, use, modify and distribute modified or unmodified
33 * copies of this software in source and/or binary form. No title
34 * or ownership is transferred hereby.
36 * 1) Any source code used, modified or distributed must reproduce
37 * and retain this copyright notice and list of conditions
38 * as they appear in the source file.
40 * 2) No right is granted to use any trade name, trademark, or
41 * logo of Broadcom Corporation. The "Broadcom Corporation"
42 * name may not be used to endorse or promote products derived
43 * from this software without the prior written permission of
44 * Broadcom Corporation.
46 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
47 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
48 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
49 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
50 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
51 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
52 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
54 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
55 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
56 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
57 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
58 * THE POSSIBILITY OF SUCH DAMAGE.
59 ********************************************************************* */
62 #include "lib_types.h"
63 #include "lib_printf.h"
65 #include "cfe_timer.h"
67 #include "cfe.h"
69 #include "bsp_config.h"
70 #include "cpu_config.h"
72 #ifndef CFG_CPU_SPEED
73 #define CFG_CPU_SPEED 500000 /* CPU speed in Hz */
74 #endif
76 #ifndef CPUCFG_CYCLESPERCPUTICK
77 #define CPUCFG_CYCLESPERCPUTICK 1 /* CPU clock ticks per CP0 COUNT */
78 #endif
80 /* *********************************************************************
81 * Externs
82 ********************************************************************* */
84 extern int32_t _getticks(void); /* return value of CP0 COUNT */
86 /* *********************************************************************
87 * Data
88 ********************************************************************* */
90 volatile int64_t cfe_ticks; /* current system time */
92 int cfe_cpu_speed; /* CPU speed in clocks/second */
94 /* With current technology, we would like to accomodate
95 sub-microsecond delays, but clocks per nanosecond may be a small
96 number. For more precision, we convert in terms of Kns, where
97 one Kns = 1024 nsec, and scale by shifting. */
99 /* We assume that cfe_cpu_speed gets updated before cfe_timer_init is
100 called. Currently, it's done in console_init. It would be better
101 as an argument of cfe_timer_init, but that's a lot of editing. */
102 static unsigned int cfe_clocks_per_Kns;
103 static unsigned int cfe_clocks_per_usec;
104 static unsigned int cfe_clocks_per_tick;
106 static int32_t cfe_oldcount; /* For keeping track of ticks */
107 static int32_t cfe_remticks;
108 static int cfe_timer_initflg = 0;
111 * C0_COUNT clocks per microsecond and per tick. Some CPUs tick CP0
112 * every 'n' cycles, that's what CPUCFG_CYCLESPERCPUTICK is for. */
113 #define CFE_CLOCKSPERUSEC (cfe_cpu_speed/1000000/(CPUCFG_CYCLESPERCPUTICK))
114 #define CFE_CLOCKSPERKNS (cfe_cpu_speed/976563/(CPUCFG_CYCLESPERCPUTICK))
115 #define CFE_CLOCKSPERTICK (cfe_cpu_speed/(CFE_HZ)/(CPUCFG_CYCLESPERCPUTICK))
118 /* *********************************************************************
119 * cfe_timer_task()
121 * This routine is called as part of normal device polling to
122 * update the system time. We read the CP0 COUNT register,
123 * add the delta into our current time, convert to ticks,
124 * and keep track of the COUNT register overflow
126 * Input parameters:
127 * nothing
129 * Return value:
130 * nothing
131 ********************************************************************* */
134 static void cfe_timer_task(void *arg)
136 int32_t count;
137 int32_t deltaticks;
138 int32_t clockspertick;
140 clockspertick = CFE_CLOCKSPERTICK;
142 count = _getticks();
144 if (count >= cfe_oldcount) {
145 deltaticks = (count - cfe_oldcount) / clockspertick;
146 cfe_remticks += (count - cfe_oldcount) % clockspertick;
148 else {
149 deltaticks = (cfe_oldcount - count) / clockspertick;
150 cfe_remticks += (cfe_oldcount - count) % clockspertick;
153 cfe_ticks += deltaticks + (cfe_remticks / clockspertick);
154 cfe_remticks %= clockspertick;
155 cfe_oldcount = count;
159 /* *********************************************************************
160 * cfe_timer_init()
162 * Initialize the timer module.
164 * Input parameters:
165 * nothing
167 * Return value:
168 * nothing
169 ********************************************************************* */
171 void cfe_timer_init(void)
173 cfe_clocks_per_tick = CFE_CLOCKSPERTICK;
174 cfe_clocks_per_Kns = CFE_CLOCKSPERKNS;
175 if (cfe_clocks_per_Kns == 0)
176 cfe_clocks_per_Kns = 1; /* for the simulator */
177 cfe_clocks_per_usec = CFE_CLOCKSPERUSEC;
178 if (cfe_clocks_per_usec == 0)
179 cfe_clocks_per_usec = 1; /* for the simulator */
181 cfe_oldcount = _getticks(); /* get current COUNT register */
182 cfe_ticks = 0;
184 if (!cfe_timer_initflg) {
185 cfe_bg_add(cfe_timer_task,NULL); /* add task for background polling */
186 cfe_timer_initflg = 1;
191 /* *********************************************************************
192 * cfe_sleep(ticks)
194 * Sleep for 'ticks' ticks. Background tasks are processed while
195 * we wait.
197 * Input parameters:
198 * ticks - number of ticks to sleep (note: *not* clocks!)
200 * Return value:
201 * nothing
202 ********************************************************************* */
204 void cfe_sleep(int ticks)
206 int64_t timer;
208 TIMER_SET(timer,ticks);
209 while (!TIMER_EXPIRED(timer)) {
210 POLL();
216 /* *********************************************************************
217 * cfe_usleep(usec)
219 * Sleep for approximately the specified number of microseconds.
221 * Input parameters:
222 * usec - number of microseconds to wait
224 * Return value:
225 * nothing
226 ********************************************************************* */
228 void cfe_usleep(int usec)
230 uint32_t newcount;
231 uint32_t now;
234 now = _getticks();
235 newcount = now + usec*cfe_clocks_per_usec;
237 if (newcount < now) /* wait for wraparound */
238 while (_getticks() > now)
242 while (_getticks() < newcount)
247 /* *********************************************************************
248 * cfe_nsleep(nsec)
250 * Sleep for approximately the specified number of nanoseconds.
252 * Input parameters:
253 * nsec - number of nanoseconds to wait
255 * Return value:
256 * nothing
257 ********************************************************************* */
259 void cfe_nsleep(int nsec)
261 uint32_t newcount;
262 uint32_t now;
265 now = _getticks();
266 newcount = now + ((nsec*cfe_clocks_per_Kns + 512) >> 10);
268 if (newcount < now) /* wait for wraparound */
269 while (_getticks() > now)
272 while (_getticks() < newcount)