3 Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 SMM I/O access utility implementation file, for Ia32
28 #include "Library/StallSmmLib.h"
29 #include "Pi/PiSmmCis.h"
31 #include <Library/IoLib.h>
32 #include <Library/PcdLib.h>
33 #include "PchAccess.h"
36 Delay for at least the request number of microseconds.
37 Timer used is ACPI time counter, which has 1us granularity.
39 @param Microseconds Number of microseconds to delay.
56 if (Microseconds
== 0) {
60 AcpiBaseAddr
= PchLpcPciCfg16 (R_PCH_LPC_ACPI_BASE
) & B_PCH_LPC_ACPI_BASE_BAR
;
62 OriginalTick
= IoRead32 (AcpiBaseAddr
+ R_PCH_ACPI_PM1_TMR
);
63 CurrentTick
= OriginalTick
;
66 // The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
68 Ticks
= Microseconds
* 358 / 100 + OriginalTick
+ 1;
71 // The loops needed by timer overflow
73 Counts
= Ticks
/ V_PCH_ACPI_PM1_TMR_MAX_VAL
;
76 // Remaining clocks within one loop
78 RemainingTick
= Ticks
% V_PCH_ACPI_PM1_TMR_MAX_VAL
;
81 // not intend to use TMROF_STS bit of register PM1_STS, because this adds extra
82 // one I/O operation, and maybe generate SMI
84 while ((Counts
!= 0) || (RemainingTick
> CurrentTick
)) {
85 CurrentTick
= IoRead32 (AcpiBaseAddr
+ R_PCH_ACPI_PM1_TMR
);
87 // Check if timer overflow
89 if (CurrentTick
< OriginalTick
) {
92 OriginalTick
= CurrentTick
;