]>
git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/Dxe/Misc/Stall.c
6ecc708ac368e7a330a846c8fc61642d71bc4f10
2 UEFI Miscellaneous boot Services Stall service implementation
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
16 Internal worker function to call the Metronome Architectural Protocol for
17 the number of ticks specified by the UINT64 Counter value. WaitForTick()
18 service of the Metronome Architectural Protocol uses a UINT32 for the number
19 of ticks to wait, so this function loops when Counter is larger than 0xffffffff.
21 @param Counter Number of ticks to wait.
25 CoreInternalWaitForTick (
29 while (RShiftU64 (Counter
, 32) > 0) {
30 gMetronome
->WaitForTick (gMetronome
, 0xffffffff);
31 Counter
-= 0xffffffff;
33 gMetronome
->WaitForTick (gMetronome
, (UINT32
)Counter
);
37 Introduces a fine-grained stall.
39 @param Microseconds The number of microseconds to stall execution.
41 @retval EFI_SUCCESS Execution was stalled for at least the requested
42 amount of microseconds.
43 @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet
56 if (gMetronome
== NULL
) {
57 return EFI_NOT_AVAILABLE_YET
;
61 // Counter = Microseconds * 10 / gMetronome->TickPeriod
62 // 0x1999999999999999 = (2^64 - 1) / 10
64 if ((UINT64
) Microseconds
> 0x1999999999999999ULL
) {
66 // Microseconds is too large to multiple by 10 first. Perform the divide
67 // operation first and loop 10 times to avoid 64-bit math overflow.
69 Counter
= DivU64x32Remainder (
71 gMetronome
->TickPeriod
,
74 for (Index
= 0; Index
< 10; Index
++) {
75 CoreInternalWaitForTick (Counter
);
80 // If Remainder was not zero, then normally, Counter would be rounded
81 // up by 1 tick. In this case, since a loop for 10 counts was used
82 // to emulate the multiply by 10 operation, Counter needs to be rounded
85 CoreInternalWaitForTick (10);
89 // Calculate the number of ticks by dividing the number of microseconds by
90 // the TickPeriod. Calculation is based on 100ns unit.
92 Counter
= DivU64x32Remainder (
93 MultU64x32 (Microseconds
, 10),
94 gMetronome
->TickPeriod
,
99 // If Remainder is not zero, then round Counter up by one tick.
103 CoreInternalWaitForTick (Counter
);