3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
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.
20 Implements the programming of events in TCO Reset
25 #include "PlatformDxe.h"
26 #include <Protocol/TcoReset.h>
27 #include <Protocol/HwWatchdogTimer.h>
33 IN UINT32
*RcrbGcsSaveValue
39 OUT UINT32 RcrbGcsRestoreValue
42 EFI_TCO_RESET_PROTOCOL mTcoResetProtocol
= {
49 Enables the TCO timer to reset the system in case of a system hang. This is
50 used when writing the clock registers.
52 @param RcrbGcsSaveValue This is the value of the RCRB GCS register before it is
53 changed by this procedure. This will be used to restore
54 the settings of this register in PpiDisableTcoReset.
62 IN UINT32
*RcrbGcsSaveValue
67 EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL
*WatchdogTimerProtocol
;
69 UINTN PbtnDisableInterval
= 4; //Default value
72 // Get Watchdog Timer protocol.
74 Status
= gBS
->LocateProtocol (
75 &gEfiWatchdogTimerDriverProtocolGuid
,
77 (VOID
**)&WatchdogTimerProtocol
81 // If the protocol is present, shut off the Timer as we enter BDS
83 if (!EFI_ERROR(Status
)) {
84 WatchdogTimerProtocol
->RestartWatchdogTimer();
85 WatchdogTimerProtocol
->AllowKnownReset(TRUE
);
88 if (*RcrbGcsSaveValue
== 0) {
89 PbtnDisableInterval
= PcdGet32(PcdPBTNDisableInterval
);
91 PbtnDisableInterval
= *RcrbGcsSaveValue
* 10 / 6;
95 // Read ACPI Base Address
97 AcpiBase
= PchLpcPciCfg16(R_PCH_LPC_ACPI_BASE
) & B_PCH_LPC_ACPI_BASE_BAR
;
100 // Stop TCO if not already stopped
102 TmpWord
= IoRead16(AcpiBase
+ R_PCH_TCO_CNT
);
103 TmpWord
|= B_PCH_TCO_CNT_TMR_HLT
;
104 IoWrite16(AcpiBase
+ R_PCH_TCO_CNT
, TmpWord
);
107 // Clear second TCO status
109 IoWrite32(AcpiBase
+ R_PCH_TCO_STS
, B_PCH_TCO_STS_SECOND_TO
);
112 // Enable reboot on TCO timeout
114 *RcrbGcsSaveValue
= MmioRead32 (PMC_BASE_ADDRESS
+ R_PCH_PMC_PM_CFG
);
115 MmioAnd8 (PMC_BASE_ADDRESS
+ R_PCH_PMC_PM_CFG
, (UINT8
) ~B_PCH_PMC_PM_CFG_NO_REBOOT
);
118 // Set TCO reload value (interval *.6s)
120 IoWrite32(AcpiBase
+ R_PCH_TCO_TMR
, (UINT32
)(PbtnDisableInterval
<<16));
123 // Force TCO to load new value
125 IoWrite8(AcpiBase
+ R_PCH_TCO_RLD
, 4);
128 // Clear second TCO status
130 IoWrite32(AcpiBase
+ R_PCH_TCO_STS
, B_PCH_TCO_STS_SECOND_TO
);
133 // Start TCO timer running
135 TmpWord
= IoRead16(AcpiBase
+ R_PCH_TCO_CNT
);
136 TmpWord
&= ~(B_PCH_TCO_CNT_TMR_HLT
);
137 IoWrite16(AcpiBase
+ R_PCH_TCO_CNT
, TmpWord
);
143 Disables the TCO timer. This is used after writing the clock registers.
145 @param RcrbGcsRestoreValue Value saved in PpiEnableTcoReset so that it can
154 OUT UINT32 RcrbGcsRestoreValue
159 EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL
*WatchdogTimerProtocol
;
163 // Read ACPI Base Address
165 AcpiBase
= PchLpcPciCfg16(R_PCH_LPC_ACPI_BASE
) & B_PCH_LPC_ACPI_BASE_BAR
;
168 // Stop the TCO timer
170 TmpWord
= IoRead16(AcpiBase
+ R_PCH_TCO_CNT
);
171 TmpWord
|= B_PCH_TCO_CNT_TMR_HLT
;
172 IoWrite16(AcpiBase
+ R_PCH_TCO_CNT
, TmpWord
);
175 // Get Watchdog Timer protocol.
177 Status
= gBS
->LocateProtocol (
178 &gEfiWatchdogTimerDriverProtocolGuid
,
180 (VOID
**)&WatchdogTimerProtocol
184 // If the protocol is present, shut off the Timer as we enter BDS
186 if (!EFI_ERROR(Status
)) {
187 WatchdogTimerProtocol
->AllowKnownReset(FALSE
);
195 Updates the feature policies according to the setup variable.
208 Status
= gBS
->InstallProtocolInterface (
210 &gEfiTcoResetProtocolGuid
,
211 EFI_NATIVE_INTERFACE
,
214 ASSERT_EFI_ERROR(Status
);