Import upstream u-boot 1.1.4
[u-boot.git] / board / MAI / bios_emulator / scitech / src / pm / rttarget / ztimer.c
1 /****************************************************************************
2 *
3 *                         Ultra Long Period Timer
4 *
5 *  ========================================================================
6 *
7 *    The contents of this file are subject to the SciTech MGL Public
8 *    License Version 1.0 (the "License"); you may not use this file
9 *    except in compliance with the License. You may obtain a copy of
10 *    the License at http://www.scitechsoft.com/mgl-license.txt
11 *
12 *    Software distributed under the License is distributed on an
13 *    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 *    implied. See the License for the specific language governing
15 *    rights and limitations under the License.
16 *
17 *    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
18 *
19 *    The Initial Developer of the Original Code is SciTech Software, Inc.
20 *    All Rights Reserved.
21 *
22 *  ========================================================================
23 *
24 * Language:     ANSI C
25 * Environment:  RTTarget-32
26 *
27 * Description:  OS specific implementation for the Zen Timer functions.
28 *
29 ****************************************************************************/
30
31 /*---------------------------- Global variables ---------------------------*/
32
33 static CPU_largeInteger countFreq;
34 static ibool            havePerformanceCounter;
35 static ulong            start,finish;
36
37 /*----------------------------- Implementation ----------------------------*/
38
39 /****************************************************************************
40 REMARKS:
41 Initialise the Zen Timer module internals.
42 ****************************************************************************/
43 void __ZTimerInit(void)
44 {
45 #ifdef  NO_ASSEMBLER
46     havePerformanceCounter = false;
47 #else
48     havePerformanceCounter = QueryPerformanceFrequency((LARGE_INTEGER*)&countFreq);
49 #endif
50 }
51
52 /****************************************************************************
53 REMARKS:
54 Start the Zen Timer counting.
55 ****************************************************************************/
56 static void __LZTimerOn(
57     LZTimerObject *tm)
58 {
59     if (havePerformanceCounter)
60         QueryPerformanceCounter((LARGE_INTEGER*)&tm->start);
61     else
62         tm->start.low = timeGetTime();
63 }
64
65 /****************************************************************************
66 REMARKS:
67 Compute the lap time since the timer was started.
68 ****************************************************************************/
69 static ulong __LZTimerLap(
70     LZTimerObject *tm)
71 {
72     CPU_largeInteger    tmLap,tmCount;
73
74     if (havePerformanceCounter) {
75         QueryPerformanceCounter((LARGE_INTEGER*)&tmLap);
76         _CPU_diffTime64(&tm->start,&tmLap,&tmCount);
77         return _CPU_calcMicroSec(&tmCount,countFreq.low);
78         }
79     else {
80         tmLap.low = timeGetTime();
81         return (tmLap.low - tm->start.low) * 1000L;
82         }
83 }
84
85 /****************************************************************************
86 REMARKS:
87 Stop the Zen Timer counting.
88 ****************************************************************************/
89 static void __LZTimerOff(
90     LZTimerObject *tm)
91 {
92     if (havePerformanceCounter)
93         QueryPerformanceCounter((LARGE_INTEGER*)&tm->end);
94     else
95         tm->end.low = timeGetTime();
96 }
97
98 /****************************************************************************
99 REMARKS:
100 Compute the elapsed time in microseconds between start and end timings.
101 ****************************************************************************/
102 static ulong __LZTimerCount(
103     LZTimerObject *tm)
104 {
105     CPU_largeInteger    tmCount;
106
107     if (havePerformanceCounter) {
108         _CPU_diffTime64(&tm->start,&tm->end,&tmCount);
109         return _CPU_calcMicroSec(&tmCount,countFreq.low);
110         }
111     else
112         return (tm->end.low - tm->start.low) * 1000L;
113 }
114
115 /****************************************************************************
116 REMARKS:
117 Define the resolution of the long period timer as microseconds per timer tick.
118 ****************************************************************************/
119 #define ULZTIMER_RESOLUTION     1000
120
121 /****************************************************************************
122 REMARKS:
123 Read the Long Period timer from the OS
124 ****************************************************************************/
125 static ulong __ULZReadTime(void)
126 { return timeGetTime(); }
127
128 /****************************************************************************
129 REMARKS:
130 Compute the elapsed time from the BIOS timer tick. Note that we check to see
131 whether a midnight boundary has passed, and if so adjust the finish time to
132 account for this. We cannot detect if more that one midnight boundary has
133 passed, so if this happens we will be generating erronous results.
134 ****************************************************************************/
135 ulong __ULZElapsedTime(ulong start,ulong finish)
136 { return finish - start; }