3 Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved
5 SPDX-License-Identifier: BSD-2-Clause-Patent
16 SMM I/O access utility implementation file, for Ia32
23 #include "Library/StallSmmLib.h"
24 #include "Pi/PiSmmCis.h"
26 #include <Library/IoLib.h>
27 #include <Library/PcdLib.h>
28 #include "PchAccess.h"
31 Delay for at least the request number of microseconds.
32 Timer used is ACPI time counter, which has 1us granularity.
34 @param Microseconds Number of microseconds to delay.
51 if (Microseconds
== 0) {
55 AcpiBaseAddr
= PchLpcPciCfg16 (R_PCH_LPC_ACPI_BASE
) & B_PCH_LPC_ACPI_BASE_BAR
;
57 OriginalTick
= IoRead32 (AcpiBaseAddr
+ R_PCH_ACPI_PM1_TMR
);
58 CurrentTick
= OriginalTick
;
61 // The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
63 Ticks
= Microseconds
* 358 / 100 + OriginalTick
+ 1;
66 // The loops needed by timer overflow
68 Counts
= Ticks
/ V_PCH_ACPI_PM1_TMR_MAX_VAL
;
71 // Remaining clocks within one loop
73 RemainingTick
= Ticks
% V_PCH_ACPI_PM1_TMR_MAX_VAL
;
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
79 while ((Counts
!= 0) || (RemainingTick
> CurrentTick
)) {
80 CurrentTick
= IoRead32 (AcpiBaseAddr
+ R_PCH_ACPI_PM1_TMR
);
82 // Check if timer overflow
84 if (CurrentTick
< OriginalTick
) {
87 OriginalTick
= CurrentTick
;