VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c@ 107932

Last change on this file since 107932 was 101291, checked in by vboxsync, 20 months ago

EFI/FirmwareNew: Make edk2-stable202308 build on all supported platforms (using gcc at least, msvc not tested yet), bugref:4643

  • Property svn:eol-style set to native
File size: 4.6 KB
Line 
1/** @file
2 RISC-V instance of Timer Library.
3
4 Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8**/
9
10#include <Uefi.h>
11#include <Library/BaseLib.h>
12#include <Library/DebugLib.h>
13#include <Library/PcdLib.h>
14#include <Register/RiscV64/RiscVImpl.h>
15
16/**
17 Stalls the CPU for at least the given number of ticks.
18
19 Stalls the CPU for at least the given number of ticks. It's invoked by
20 MicroSecondDelay() and NanoSecondDelay().
21
22 @param Delay A period of time to delay in ticks.
23
24**/
25STATIC
26VOID
27InternalRiscVTimerDelay (
28 IN UINT64 Delay
29 )
30{
31 UINT64 Ticks;
32
33 Ticks = RiscVReadTimer () + Delay;
34
35 while (RiscVReadTimer () <= Ticks) {
36 CpuPause ();
37 }
38}
39
40/**
41 Stalls the CPU for at least the given number of microseconds.
42
43 Stalls the CPU for the number of microseconds specified by MicroSeconds.
44
45 @param MicroSeconds The minimum number of microseconds to delay.
46
47 @return MicroSeconds
48
49**/
50UINTN
51EFIAPI
52MicroSecondDelay (
53 IN UINTN MicroSeconds
54 )
55{
56 InternalRiscVTimerDelay (
57 DivU64x32 (
58 MultU64x32 (
59 MicroSeconds,
60 PcdGet64 (PcdCpuCoreCrystalClockFrequency)
61 ),
62 1000000u
63 )
64 );
65 return MicroSeconds;
66}
67
68/**
69 Stalls the CPU for at least the given number of nanoseconds.
70
71 Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
72
73 @param NanoSeconds The minimum number of nanoseconds to delay.
74
75 @return NanoSeconds
76
77**/
78UINTN
79EFIAPI
80NanoSecondDelay (
81 IN UINTN NanoSeconds
82 )
83{
84 InternalRiscVTimerDelay (
85 DivU64x32 (
86 MultU64x32 (
87 NanoSeconds,
88 PcdGet64 (PcdCpuCoreCrystalClockFrequency)
89 ),
90 1000000000u
91 )
92 );
93 return NanoSeconds;
94}
95
96/**
97 Retrieves the current value of a 64-bit free running performance counter.
98
99 Retrieves the current value of a 64-bit free running performance counter. The
100 counter can either count up by 1 or count down by 1. If the physical
101 performance counter counts by a larger increment, then the counter values
102 must be translated. The properties of the counter can be retrieved from
103 GetPerformanceCounterProperties().
104
105 @return The current value of the free running performance counter.
106
107**/
108UINT64
109EFIAPI
110GetPerformanceCounter (
111 VOID
112 )
113{
114 return (UINT64)RiscVReadTimer ();
115}
116
117/**return
118 Retrieves the 64-bit frequency in Hz and the range of performance counter
119 values.
120
121 If StartValue is not NULL, then the value that the performance counter starts
122 with immediately after is it rolls over is returned in StartValue. If
123 EndValue is not NULL, then the value that the performance counter end with
124 immediately before it rolls over is returned in EndValue. The 64-bit
125 frequency of the performance counter in Hz is always returned. If StartValue
126 is less than EndValue, then the performance counter counts up. If StartValue
127 is greater than EndValue, then the performance counter counts down. For
128 example, a 64-bit free running counter that counts up would have a StartValue
129 of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
130 that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
131
132 @param StartValue The value the performance counter starts with when it
133 rolls over.
134 @param EndValue The value that the performance counter ends with before
135 it rolls over.
136
137 @return The frequency in Hz.
138
139**/
140UINT64
141EFIAPI
142GetPerformanceCounterProperties (
143 OUT UINT64 *StartValue, OPTIONAL
144 OUT UINT64 *EndValue OPTIONAL
145 )
146{
147 if (StartValue != NULL) {
148 *StartValue = 0;
149 }
150
151 if (EndValue != NULL) {
152 *EndValue = 32 - 1;
153 }
154
155 return PcdGet64 (PcdCpuCoreCrystalClockFrequency);
156}
157
158/**
159 Converts elapsed ticks of performance counter to time in nanoseconds.
160
161 This function converts the elapsed ticks of running performance counter to
162 time value in unit of nanoseconds.
163
164 @param Ticks The number of elapsed ticks of running performance counter.
165
166 @return The elapsed time in nanoseconds.
167
168**/
169UINT64
170EFIAPI
171GetTimeInNanoSecond (
172 IN UINT64 Ticks
173 )
174{
175 UINT64 NanoSeconds;
176 UINT32 Remainder;
177
178 //
179 // Ticks
180 // Time = --------- x 1,000,000,000
181 // Frequency
182 //
183 NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, PcdGet64 (PcdCpuCoreCrystalClockFrequency), &Remainder), 1000000000u);
184
185 //
186 // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
187 // will not overflow 64-bit.
188 //
189 NanoSeconds += DivU64x32 (MultU64x32 ((UINT64)Remainder, 1000000000u), PcdGet64 (PcdCpuCoreCrystalClockFrequency));
190
191 return NanoSeconds;
192}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette