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