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