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