microsoft/mu_feature_ffa

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
update_rust

Branches

Tags

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

Clone

HTTPS

Download ZIP

FfaFeaturePkg/Library/ArmArchTimerLibEx/ArmArchTimerLibEx.c

223lines · 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
59// Calculate counter ticks that represent requested delay:
60// = MicroSeconds x TICKS_PER_MICRO_SEC
61// = MicroSeconds x Frequency.10^-6
62TimerTicks64 = DivU64x32 (
184656c8kuqin121 years ago63MultU64x64 (
89ca181erdiaz1 years ago64MicroSeconds,
65GetPlatformTimerFreq ()
66),
671000000U
68);
69
70// Wait until delay count expires.
71SystemCounterVal = 0;
72while (SystemCounterVal < TimerTicks64) {
73SystemCounterVal++;
74}
75
76return MicroSeconds;
77}
78
79/**
80Stalls the CPU for at least the given number of nanoseconds.
81
82Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
83
84When the timer frequency is 1MHz, each tick corresponds to 1 microsecond.
85Therefore, the nanosecond delay will be rounded up to the nearest 1 microsecond.
86
87@param NanoSeconds The minimum number of nanoseconds to delay.
88
89@return The value of NanoSeconds inputted.
90
91**/
92UINTN
93EFIAPI
94NanoSecondDelay (
95IN UINTN NanoSeconds
96)
97{
98UINTN MicroSeconds;
99
100// Round up to 1us Tick Number
101MicroSeconds = NanoSeconds / 1000;
102MicroSeconds += ((NanoSeconds % 1000) == 0) ? 0 : 1;
103
104MicroSecondDelay (MicroSeconds);
105
106return NanoSeconds;
107}
108
109/**
110Retrieves the current value of a 64-bit free running performance counter.
111
112The counter can either count up by 1 or count down by 1. If the physical
113performance counter counts by a larger increment, then the counter values
114must be translated. The properties of the counter can be retrieved from
115GetPerformanceCounterProperties().
116
117@return The current value of the free running performance counter.
118
119**/
120UINT64
121EFIAPI
122GetPerformanceCounter (
123VOID
124)
125{
126// Just return the value of system count
127return ArmGenericTimerGetSystemCount ();
128}
129
130/**
131Retrieves the 64-bit frequency in Hz and the range of performance counter
132values.
133
134If StartValue is not NULL, then the value that the performance counter starts
135with immediately after is it rolls over is returned in StartValue. If
136EndValue is not NULL, then the value that the performance counter end with
137immediately before it rolls over is returned in EndValue. The 64-bit
138frequency of the performance counter in Hz is always returned. If StartValue
139is less than EndValue, then the performance counter counts up. If StartValue
140is greater than EndValue, then the performance counter counts down. For
141example, a 64-bit free running counter that counts up would have a StartValue
142of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
143that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
144
145@param StartValue The value the performance counter starts with when it
146rolls over.
147@param EndValue The value that the performance counter ends with before
148it rolls over.
149
150@return The frequency in Hz.
151
152**/
153UINT64
154EFIAPI
155GetPerformanceCounterProperties (
156OUT UINT64 *StartValue OPTIONAL,
157OUT UINT64 *EndValue OPTIONAL
158)
159{
160if (StartValue != NULL) {
161// Timer starts at 0
162*StartValue = (UINT64)0ULL;
163}
164
165if (EndValue != NULL) {
166// Timer counts up.
167*EndValue = 0xFFFFFFFFFFFFFFFFUL;
168}
169
170return (UINT64)ArmGenericTimerGetTimerFreq ();
171}
172
173/**
174Converts elapsed ticks of performance counter to time in nanoseconds.
175
176This function converts the elapsed ticks of running performance counter to
177time value in unit of nanoseconds.
178
179@param Ticks The number of elapsed ticks of running performance counter.
180
181@return The elapsed time in nanoseconds.
182
183**/
184UINT64
185EFIAPI
186GetTimeInNanoSecond (
187IN UINT64 Ticks
188)
189{
190UINT64 NanoSeconds;
184656c8kuqin121 years ago191UINT64 Remainder;
192UINT64 TimerFreq;
89ca181erdiaz1 years ago193
194TimerFreq = (UINT32)GetPlatformTimerFreq (); // MU_CHANGE - ARM64 VS change
195//
196// Ticks
197// Time = --------- x 1,000,000,000
198// Frequency
199//
184656c8kuqin121 years ago200NanoSeconds = MultU64x64 (
201DivU64x64Remainder (
89ca181erdiaz1 years ago202Ticks,
203TimerFreq,
204&Remainder
205),
2061000000000U
207);
208
209//
210// Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
211// will not overflow 64-bit.
212//
184656c8kuqin121 years ago213NanoSeconds += DivU64x64Remainder (
214MultU64x64 (
215Remainder,
89ca181erdiaz1 years ago2161000000000U
217),
184656c8kuqin121 years ago218TimerFreq,
219NULL
89ca181erdiaz1 years ago220);
221
222return NanoSeconds;
223}