]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/PlatformDxe/IchTcoReset.c
Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to
[mirror_edk2.git] / Vlv2TbltDevicePkg / PlatformDxe / IchTcoReset.c
1 /** @file
2
3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
4
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.
9
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.
12
13
14 Module Name:
15
16
17 IchTcoReset.c
18
19 Abstract:
20 Implements the programming of events in TCO Reset
21
22
23 --*/
24
25 #include "PlatformDxe.h"
26 #include <Protocol/TcoReset.h>
27 #include <Protocol/HwWatchdogTimer.h>
28
29
30 EFI_STATUS
31 EFIAPI
32 EnableTcoReset (
33 IN UINT32 *RcrbGcsSaveValue
34 );
35
36 EFI_STATUS
37 EFIAPI
38 DisableTcoReset (
39 OUT UINT32 RcrbGcsRestoreValue
40 );
41
42 EFI_TCO_RESET_PROTOCOL mTcoResetProtocol = {
43 EnableTcoReset,
44 DisableTcoReset
45 };
46
47 /**
48
49 Enables the TCO timer to reset the system in case of a system hang. This is
50 used when writing the clock registers.
51
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.
55
56 @retval EFI_STATUS
57
58 **/
59 EFI_STATUS
60 EFIAPI
61 EnableTcoReset (
62 IN UINT32 *RcrbGcsSaveValue
63 )
64 {
65 UINT16 TmpWord;
66 UINT16 AcpiBase;
67 EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL *WatchdogTimerProtocol;
68 EFI_STATUS Status;
69 UINTN PbtnDisableInterval = 4; //Default value
70
71 //
72 // Get Watchdog Timer protocol.
73 //
74 Status = gBS->LocateProtocol (
75 &gEfiWatchdogTimerDriverProtocolGuid,
76 NULL,
77 (VOID **)&WatchdogTimerProtocol
78 );
79
80 //
81 // If the protocol is present, shut off the Timer as we enter BDS
82 //
83 if (!EFI_ERROR(Status)) {
84 WatchdogTimerProtocol->RestartWatchdogTimer();
85 WatchdogTimerProtocol->AllowKnownReset(TRUE);
86 }
87
88 if (*RcrbGcsSaveValue == 0) {
89 PbtnDisableInterval = PcdGet32(PcdPBTNDisableInterval);
90 } else {
91 PbtnDisableInterval = *RcrbGcsSaveValue * 10 / 6;
92 }
93
94 //
95 // Read ACPI Base Address
96 //
97 AcpiBase = PchLpcPciCfg16(R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
98
99 //
100 // Stop TCO if not already stopped
101 //
102 TmpWord = IoRead16(AcpiBase + R_PCH_TCO_CNT);
103 TmpWord |= B_PCH_TCO_CNT_TMR_HLT;
104 IoWrite16(AcpiBase + R_PCH_TCO_CNT, TmpWord);
105
106 //
107 // Clear second TCO status
108 //
109 IoWrite32(AcpiBase + R_PCH_TCO_STS, B_PCH_TCO_STS_SECOND_TO);
110
111 //
112 // Enable reboot on TCO timeout
113 //
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);
116
117 //
118 // Set TCO reload value (interval *.6s)
119 //
120 IoWrite32(AcpiBase + R_PCH_TCO_TMR, (UINT32)(PbtnDisableInterval<<16));
121
122 //
123 // Force TCO to load new value
124 //
125 IoWrite8(AcpiBase + R_PCH_TCO_RLD, 4);
126
127 //
128 // Clear second TCO status
129 //
130 IoWrite32(AcpiBase + R_PCH_TCO_STS, B_PCH_TCO_STS_SECOND_TO);
131
132 //
133 // Start TCO timer running
134 //
135 TmpWord = IoRead16(AcpiBase + R_PCH_TCO_CNT);
136 TmpWord &= ~(B_PCH_TCO_CNT_TMR_HLT);
137 IoWrite16(AcpiBase + R_PCH_TCO_CNT, TmpWord);
138
139 return EFI_SUCCESS;
140 }
141
142 /**
143 Disables the TCO timer. This is used after writing the clock registers.
144
145 @param RcrbGcsRestoreValue Value saved in PpiEnableTcoReset so that it can
146 restored.
147
148 @retval EFI_STATUS
149
150 **/
151 EFI_STATUS
152 EFIAPI
153 DisableTcoReset (
154 OUT UINT32 RcrbGcsRestoreValue
155 )
156 {
157 UINT16 TmpWord;
158 UINT16 AcpiBase;
159 EFI_WATCHDOG_TIMER_DRIVER_PROTOCOL *WatchdogTimerProtocol;
160 EFI_STATUS Status;
161
162 //
163 // Read ACPI Base Address
164 //
165 AcpiBase = PchLpcPciCfg16(R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
166
167 //
168 // Stop the TCO timer
169 //
170 TmpWord = IoRead16(AcpiBase + R_PCH_TCO_CNT);
171 TmpWord |= B_PCH_TCO_CNT_TMR_HLT;
172 IoWrite16(AcpiBase + R_PCH_TCO_CNT, TmpWord);
173
174 //
175 // Get Watchdog Timer protocol.
176 //
177 Status = gBS->LocateProtocol (
178 &gEfiWatchdogTimerDriverProtocolGuid,
179 NULL,
180 (VOID **)&WatchdogTimerProtocol
181 );
182
183 //
184 // If the protocol is present, shut off the Timer as we enter BDS
185 //
186 if (!EFI_ERROR(Status)) {
187 WatchdogTimerProtocol->AllowKnownReset(FALSE);
188 }
189
190 return EFI_SUCCESS;
191 }
192
193 /**
194
195 Updates the feature policies according to the setup variable.
196
197 @retval Returns VOID
198
199 **/
200 VOID
201 InitTcoReset (
202 )
203 {
204 EFI_HANDLE Handle;
205 EFI_STATUS Status;
206
207 Handle = NULL;
208 Status = gBS->InstallProtocolInterface (
209 &Handle,
210 &gEfiTcoResetProtocolGuid,
211 EFI_NATIVE_INTERFACE,
212 &mTcoResetProtocol
213 );
214 ASSERT_EFI_ERROR(Status);
215
216 }