]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmm.c
062994f088c253b83da4c17589d2d2af39e69c1b
[mirror_edk2.git] / Vlv2TbltDevicePkg / Library / StallSmmLib / StallSmm.c
1 /*++
2
3 Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved
4
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7
8
9
10 Module Name:
11
12 SmmIo.c
13
14 Abstract:
15
16 SMM I/O access utility implementation file, for Ia32
17
18 --*/
19
20 //
21 // Include files
22 //
23 #include "Library/StallSmmLib.h"
24 #include "Pi/PiSmmCis.h"
25 #include "PiDxe.h"
26 #include <Library/IoLib.h>
27 #include <Library/PcdLib.h>
28 #include "PchAccess.h"
29
30 /**
31 Delay for at least the request number of microseconds.
32 Timer used is ACPI time counter, which has 1us granularity.
33
34 @param Microseconds Number of microseconds to delay.
35
36 @retval None
37
38 **/
39 VOID
40 SmmStall (
41 IN UINTN Microseconds
42 )
43 {
44 UINTN Ticks;
45 UINTN Counts;
46 UINTN CurrentTick;
47 UINTN OriginalTick;
48 UINTN RemainingTick;
49 UINT16 AcpiBaseAddr;
50
51 if (Microseconds == 0) {
52 return;
53 }
54
55 AcpiBaseAddr = PchLpcPciCfg16 (R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
56
57 OriginalTick = IoRead32 (AcpiBaseAddr + R_PCH_ACPI_PM1_TMR);
58 CurrentTick = OriginalTick;
59
60 //
61 // The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
62 //
63 Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
64
65 //
66 // The loops needed by timer overflow
67 //
68 Counts = Ticks / V_PCH_ACPI_PM1_TMR_MAX_VAL;
69
70 //
71 // Remaining clocks within one loop
72 //
73 RemainingTick = Ticks % V_PCH_ACPI_PM1_TMR_MAX_VAL;
74
75 //
76 // not intend to use TMROF_STS bit of register PM1_STS, because this adds extra
77 // one I/O operation, and maybe generate SMI
78 //
79 while ((Counts != 0) || (RemainingTick > CurrentTick)) {
80 CurrentTick = IoRead32 (AcpiBaseAddr + R_PCH_ACPI_PM1_TMR);
81 //
82 // Check if timer overflow
83 //
84 if (CurrentTick < OriginalTick) {
85 Counts--;
86 }
87 OriginalTick = CurrentTick;
88 }
89 }