]> git.proxmox.com Git - mirror_edk2.git/blame - ArmEbPkg/Library/TimerLib/TimerLib.c
Report correct MediaPresentSupported value from Nt32 SNP mode data.
[mirror_edk2.git] / ArmEbPkg / Library / TimerLib / TimerLib.c
CommitLineData
b76848cb 1/** @file\r
ebeffc42 2 TimerLib for ARM EB. Hardcoded to 100ns period\r
3\r
4 This library assume the following initialization, usually done in SEC. \r
5\r
6 // configure SP810 to use 1MHz clock and disable\r
7 MmioAndThenOr32 (EB_SP810_CTRL_BASE + SP810_SYS_CTRL_REG, ~SP810_SYS_CTRL_TIMER2_EN, SP810_SYS_CTRL_TIMER2_TIMCLK);\r
8 // Enable\r
9 MmioOr32 (EB_SP810_CTRL_BASE + SP810_SYS_CTRL_REG, SP810_SYS_CTRL_TIMER2_EN);\r
10\r
11 // configure timer 2 for one shot operation, 32 bits, no prescaler, and interrupt disabled\r
12 MmioOr32 (EB_SP804_TIMER2_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ONESHOT | SP804_TIMER_CTRL_32BIT | SP804_PRESCALE_DIV_1);\r
13\r
14 // preload the timer count register\r
15 MmioWrite32 (EB_SP804_TIMER2_BASE + SP804_TIMER_LOAD_REG, 1);\r
16\r
17 // enable the timer\r
18 MmioOr32 (EB_SP804_TIMER2_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE);\r
19\r
b76848cb 20\r
21 Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
22 \r
23 This program and the accompanying materials\r
24 are licensed and made available under the terms and conditions of the BSD License\r
25 which accompanies this distribution. The full text of the license may be found at\r
26 http://opensource.org/licenses/bsd-license.php\r
27\r
28 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
29 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
30\r
31**/\r
32\r
33#include <Base.h>\r
34\r
35#include <Library/BaseLib.h>\r
36#include <Library/TimerLib.h>\r
37#include <Library/DebugLib.h>\r
38#include <Library/PcdLib.h>\r
39#include <Library/IoLib.h>\r
40\r
ebeffc42 41#include <ArmEb/ArmEb.h>\r
42\r
43\r
44/**\r
45 Stalls the CPU for at least the given number of microseconds.\r
b76848cb 46\r
ebeffc42 47 Stalls the CPU for the number of microseconds specified by MicroSeconds.\r
48\r
49 @param MicroSeconds The minimum number of microseconds to delay.\r
50\r
51 @return The value of MicroSeconds inputted.\r
52\r
53**/\r
b76848cb 54UINTN\r
55EFIAPI\r
56MicroSecondDelay (\r
57 IN UINTN MicroSeconds\r
58 )\r
59{\r
60 UINT64 NanoSeconds;\r
61 \r
62 NanoSeconds = MultU64x32 (MicroSeconds, 1000);\r
63\r
64 while (NanoSeconds > (UINTN)-1) { \r
65 NanoSecondDelay((UINTN)-1);\r
66 NanoSeconds -= (UINTN)-1;\r
67 }\r
68\r
69 NanoSecondDelay (NanoSeconds);\r
70\r
71 return MicroSeconds;\r
72}\r
73\r
ebeffc42 74/**\r
75 Stalls the CPU for at least the given number of nanoseconds.\r
76\r
77 Stalls the CPU for the number of nanoseconds specified by NanoSeconds.\r
78\r
79 @param NanoSeconds The minimum number of nanoseconds to delay.\r
80\r
81 @return The value of NanoSeconds inputted.\r
82\r
83**/\r
b76848cb 84UINTN\r
85EFIAPI\r
86NanoSecondDelay (\r
87 IN UINTN NanoSeconds\r
88 )\r
89{\r
ebeffc42 90 UINT32 TickNumber;\r
b76848cb 91\r
ebeffc42 92 if (NanoSeconds == 0) {\r
93 return NanoSeconds;\r
94 }\r
b76848cb 95\r
ebeffc42 96 // Round up to 100ns Tick Number\r
97 TickNumber = (UINT32)NanoSeconds / 100;\r
98 TickNumber += ((UINT32)NanoSeconds % 100) == 0 ? 0 : 1;\r
b76848cb 99\r
ebeffc42 100 // load the timer count register\r
101 MmioWrite32 (EB_SP804_TIMER2_BASE + SP804_TIMER_LOAD_REG, TickNumber);\r
b76848cb 102\r
ebeffc42 103 while (MmioRead32 (EB_SP804_TIMER2_BASE + SP804_TIMER_CURRENT_REG) > 0) {\r
104 ;\r
105 } \r
106 \r
b76848cb 107 return NanoSeconds;\r
108}\r
109\r
ebeffc42 110/**\r
111 Retrieves the current value of a 64-bit free running performance counter.\r
112\r
113 The counter can either count up by 1 or count down by 1. If the physical\r
114 performance counter counts by a larger increment, then the counter values\r
115 must be translated. The properties of the counter can be retrieved from\r
116 GetPerformanceCounterProperties().\r
117\r
118 @return The current value of the free running performance counter.\r
119\r
120**/\r
b76848cb 121UINT64\r
122EFIAPI\r
123GetPerformanceCounter (\r
124 VOID\r
125 )\r
126{ \r
ebeffc42 127 // Free running 64-bit/32-bit counter is needed here.\r
128 // Don't think we need this to boot, just to do performance profile\r
129 ASSERT (FALSE);\r
b76848cb 130 return (UINT64)0ULL;\r
131}\r
132\r
ebeffc42 133\r
134/**\r
135 Retrieves the 64-bit frequency in Hz and the range of performance counter\r
136 values.\r
137\r
138 If StartValue is not NULL, then the value that the performance counter starts\r
139 with immediately after is it rolls over is returned in StartValue. If\r
140 EndValue is not NULL, then the value that the performance counter end with\r
141 immediately before it rolls over is returned in EndValue. The 64-bit\r
142 frequency of the performance counter in Hz is always returned. If StartValue\r
143 is less than EndValue, then the performance counter counts up. If StartValue\r
144 is greater than EndValue, then the performance counter counts down. For\r
145 example, a 64-bit free running counter that counts up would have a StartValue\r
146 of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter\r
147 that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.\r
148\r
149 @param StartValue The value the performance counter starts with when it\r
150 rolls over.\r
151 @param EndValue The value that the performance counter ends with before\r
152 it rolls over.\r
153\r
154 @return The frequency in Hz.\r
155\r
156**/\r
b76848cb 157UINT64\r
158EFIAPI\r
159GetPerformanceCounterProperties (\r
160 OUT UINT64 *StartValue, OPTIONAL\r
161 OUT UINT64 *EndValue OPTIONAL\r
162 )\r
163{\r
164 if (StartValue != NULL) {\r
165 // Timer starts with the reload value\r
166 *StartValue = (UINT64)0ULL;\r
167 }\r
168 \r
169 if (EndValue != NULL) {\r
170 // Timer counts up to 0xFFFFFFFF\r
171 *EndValue = 0xFFFFFFFF;\r
172 }\r
173 \r
ebeffc42 174 return 100;\r
b76848cb 175}\r
ebeffc42 176\r
177\r