microsoft/mu_feature_ffa

Public

mirrored from https://github.com/microsoft/mu_feature_ffaAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
main

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

FfaFeaturePkg/Library/ArmArchTimerLibEx/ArmArchTimerLibEx.c

242lines · modeblame

89ca181erdiaz1 years ago1/** @file
2Generic ARM implementation of TimerLib.h
3
4Copyright (c) 2011 - 2021, Arm Limited. All rights reserved.<BR>
5
6SPDX-License-Identifier: BSD-2-Clause-Patent
7
8**/
9
10#include <Base.h>
11#include <Library/ArmLib.h>
12#include <Library/BaseLib.h>
13#include <Library/TimerLib.h>
14#include <Library/DebugLib.h>
15#include <Library/PcdLib.h>
16#include <Library/ArmGenericTimerCounterLib.h>
17
184656c8kuqin121 years ago18#define TICKS_PER_MICRO_SEC (ArmGenericTimerGetTimerFreq ()/1000000U)
89ca181erdiaz1 years ago19
20/**
21A local utility function that returns the PCD value, if specified.
22Otherwise it defaults to ArmGenericTimerGetTimerFreq.
23
24@return The timer frequency.
25
26**/
27STATIC
28UINTN
29EFIAPI
30GetPlatformTimerFreq (
31)
32{
33UINTN TimerFreq;
34
184656c8kuqin121 years ago35TimerFreq = ArmGenericTimerGetTimerFreq ();
36
37ASSERT (TimerFreq != 0);
89ca181erdiaz1 years ago38
39return TimerFreq;
40}
41
42/**
43Stalls the CPU for the number of microseconds specified by MicroSeconds.
44
45@param MicroSeconds The minimum number of microseconds to delay.
46
47@return The value of MicroSeconds input.
48
49**/
50UINTN
51EFIAPI
52MicroSecondDelay (
53IN UINTN MicroSeconds
54)
55{
56UINT64 TimerTicks64;
57UINT64 SystemCounterVal;
58
2eee9be7Aaron5 months ago59// MU_CHANGE - Start - Cannot depend on GenericTimer Calls
60// UINT64 PreviousSystemCounterVal;
61// UINT64 DeltaCounterVal;
62// MU_CHANGE - End - Cannot depend on GenericTimer Calls
63
89ca181erdiaz1 years ago64// Calculate counter ticks that represent requested delay:
65// = MicroSeconds x TICKS_PER_MICRO_SEC
66// = MicroSeconds x Frequency.10^-6
67TimerTicks64 = DivU64x32 (
184656c8kuqin121 years ago68MultU64x64 (
89ca181erdiaz1 years ago69MicroSeconds,
70GetPlatformTimerFreq ()
71),
721000000U
73);
74
2eee9be7Aaron5 months ago75// MU_CHANGE - Start - Cannot depend on GenericTimer Calls
76// // Read System Counter value
77// PreviousSystemCounterVal = ArmGenericTimerGetSystemCount ();
78//
79// // Wait until delay count expires.
80// while (TimerTicks64 > 0) {
81// SystemCounterVal = ArmGenericTimerGetSystemCount ();
82// // Get how much we advanced this tick. Wrap around still has delta correct
83// DeltaCounterVal = (SystemCounterVal - PreviousSystemCounterVal)
84// & (MAX_UINT64 >> 8); // Account for a lesser (minimum) size
85// // Never wrap back around below zero by choosing the min and thus stop at 0
86// TimerTicks64 -= MIN (TimerTicks64, DeltaCounterVal);
87// PreviousSystemCounterVal = SystemCounterVal;
89ca181erdiaz1 years ago88// Wait until delay count expires.
89SystemCounterVal = 0;
90while (SystemCounterVal < TimerTicks64) {
91SystemCounterVal++;
2eee9be7Aaron5 months ago92// MU_CHANGE - End - Cannot depend on GenericTimer Calls
89ca181erdiaz1 years ago93}
94
95return MicroSeconds;
96}
97
98/**
99Stalls the CPU for at least the given number of nanoseconds.
100
101Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
102
103When the timer frequency is 1MHz, each tick corresponds to 1 microsecond.
104Therefore, the nanosecond delay will be rounded up to the nearest 1 microsecond.
105
106@param NanoSeconds The minimum number of nanoseconds to delay.
107
108@return The value of NanoSeconds inputted.
109
110**/
111UINTN
112EFIAPI
113NanoSecondDelay (
114IN UINTN NanoSeconds
115)
116{
117UINTN MicroSeconds;
118
119// Round up to 1us Tick Number
120MicroSeconds = NanoSeconds / 1000;
121MicroSeconds += ((NanoSeconds % 1000) == 0) ? 0 : 1;
122
123MicroSecondDelay (MicroSeconds);
124
125return NanoSeconds;
126}
127
128/**
129Retrieves the current value of a 64-bit free running performance counter.
130
131The counter can either count up by 1 or count down by 1. If the physical
132performance counter counts by a larger increment, then the counter values
133must be translated. The properties of the counter can be retrieved from
134GetPerformanceCounterProperties().
135
136@return The current value of the free running performance counter.
137
138**/
139UINT64
140EFIAPI
141GetPerformanceCounter (
142VOID
143)
144{
145// Just return the value of system count
146return ArmGenericTimerGetSystemCount ();
147}
148
149/**
150Retrieves the 64-bit frequency in Hz and the range of performance counter
151values.
152
153If StartValue is not NULL, then the value that the performance counter starts
154with immediately after is it rolls over is returned in StartValue. If
155EndValue is not NULL, then the value that the performance counter end with
156immediately before it rolls over is returned in EndValue. The 64-bit
157frequency of the performance counter in Hz is always returned. If StartValue
158is less than EndValue, then the performance counter counts up. If StartValue
159is greater than EndValue, then the performance counter counts down. For
160example, a 64-bit free running counter that counts up would have a StartValue
161of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
162that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
163
164@param StartValue The value the performance counter starts with when it
165rolls over.
166@param EndValue The value that the performance counter ends with before
167it rolls over.
168
169@return The frequency in Hz.
170
171**/
172UINT64
173EFIAPI
174GetPerformanceCounterProperties (
175OUT UINT64 *StartValue OPTIONAL,
176OUT UINT64 *EndValue OPTIONAL
177)
178{
179if (StartValue != NULL) {
180// Timer starts at 0
181*StartValue = (UINT64)0ULL;
182}
183
184if (EndValue != NULL) {
185// Timer counts up.
186*EndValue = 0xFFFFFFFFFFFFFFFFUL;
187}
188
189return (UINT64)ArmGenericTimerGetTimerFreq ();
190}
191
192/**
193Converts elapsed ticks of performance counter to time in nanoseconds.
194
195This function converts the elapsed ticks of running performance counter to
196time value in unit of nanoseconds.
197
198@param Ticks The number of elapsed ticks of running performance counter.
199
200@return The elapsed time in nanoseconds.
201
202**/
203UINT64
204EFIAPI
205GetTimeInNanoSecond (
206IN UINT64 Ticks
207)
208{
209UINT64 NanoSeconds;
184656c8kuqin121 years ago210UINT64 Remainder;
211UINT64 TimerFreq;
89ca181erdiaz1 years ago212
2eee9be7Aaron5 months ago213TimerFreq = GetPlatformTimerFreq ();
89ca181erdiaz1 years ago214//
215// Ticks
216// Time = --------- x 1,000,000,000
217// Frequency
218//
184656c8kuqin121 years ago219NanoSeconds = MultU64x64 (
220DivU64x64Remainder (
89ca181erdiaz1 years ago221Ticks,
222TimerFreq,
223&Remainder
224),
2251000000000U
226);
227
228//
229// Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
230// will not overflow 64-bit.
231//
184656c8kuqin121 years ago232NanoSeconds += DivU64x64Remainder (
233MultU64x64 (
234Remainder,
89ca181erdiaz1 years ago2351000000000U
236),
184656c8kuqin121 years ago237TimerFreq,
238NULL
89ca181erdiaz1 years ago239);
240
241return NanoSeconds;
242}