]> git.proxmox.com Git - mirror_edk2.git/blame - Vlv2TbltDevicePkg/PlatformInitPei/PchInitPeim.c
EmulatorPkg: Change the cpu frequency to a non-zero value
[mirror_edk2.git] / Vlv2TbltDevicePkg / PlatformInitPei / PchInitPeim.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
9\r
10Module Name:\r
11\r
12 PchInitPeim.c\r
13\r
14Abstract:\r
15\r
16 Do Early PCH platform initialization.\r
17\r
18\r
19--*/\r
20\r
21#include "PlatformEarlyInit.h"\r
22#include "Ppi/PchPlatformPolicy.h"\r
23#include "PchRegs.h"\r
24#include <Ppi/PchUsbPolicy.h>\r
25#include "Ppi/PchInit.h"\r
26#include <Library/PcdLib.h>\r
27\r
28EFI_GUID gPchPlatformPolicyPpiGuid = PCH_PLATFORM_POLICY_PPI_GUID;\r
29\r
30#define MC_PMSTS_OFFSET 0xC\r
31\r
32#define DEFAULT_BUS_INFO 0x2020\r
33\r
34\r
35#define PCI_LPC_BASE (0x8000F800)\r
36#define PCI_LPC_REG(x) (PCI_LPC_BASE + (x))\r
37#define PCIEX_BASE_ADDRESS 0xE0000000\r
38#define PciD31F0RegBase PCIEX_BASE_ADDRESS + (UINT32) (31 << 15)\r
39\r
40VOID\r
41PchPolicySetupInit (\r
42 IN CONST EFI_PEI_SERVICES **PeiServices,\r
43 IN SYSTEM_CONFIGURATION *SystemConfiguration\r
44 );\r
45\r
46VOID\r
47PchInitInterrupt (\r
48 IN SYSTEM_CONFIGURATION *SystemConfiguration\r
49 );\r
50\r
a27bdc05
JY
51EFI_STATUS\r
52InstallPeiPchUsbPolicy (\r
53 IN CONST EFI_PEI_SERVICES **PeiServices\r
54 );\r
55\r
3cbfba02
DW
56#ifndef __GNUC__\r
57#pragma warning (push)\r
58#pragma warning (disable : 4245)\r
59#pragma warning (pop)\r
60#endif\r
61\r
62UINT8\r
63ReadCmosBank1Byte (\r
64 IN UINT8 Address\r
65 )\r
66{\r
67 UINT8 Data;\r
68\r
69 IoWrite8(R_PCH_RTC_EXT_INDEX, Address);\r
70 Data = IoRead8 (R_PCH_RTC_EXT_TARGET);\r
71 return Data;\r
72}\r
73\r
74VOID\r
75WriteCmosBank1Byte (\r
76 IN UINT8 Address,\r
77 IN UINT8 Data\r
78 )\r
79{\r
80 IoWrite8(R_PCH_RTC_EXT_INDEX, Address);\r
81 IoWrite8(R_PCH_RTC_EXT_TARGET, Data);\r
82}\r
83\r
84/**\r
85 Turn off system if needed.\r
86\r
87 @param PeiServices Pointer to PEI Services\r
88 @param CpuIo Pointer to CPU I/O Protocol\r
89\r
90 @retval None.\r
91\r
92**/\r
93VOID\r
94CheckPowerOffNow (\r
95 VOID\r
96 )\r
97{\r
98 UINT16 Pm1Sts;\r
99\r
100 //\r
101 // Read and check the ACPI registers\r
102 //\r
103 Pm1Sts = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);\r
104 if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) == B_PCH_ACPI_PM1_STS_PWRBTN) {\r
105 IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_PWRBTN);\r
106 IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, V_PCH_ACPI_PM1_CNT_S5);\r
107 IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, V_PCH_ACPI_PM1_CNT_S5 + B_PCH_ACPI_PM1_CNT_SLP_EN);\r
108\r
109 //\r
110 // Should not return\r
111 //\r
112 CpuDeadLoop();\r
113 }\r
114}\r
115\r
116VOID\r
117ClearPowerState (\r
118 IN SYSTEM_CONFIGURATION *SystemConfiguration\r
119 )\r
120{\r
121 UINT8 Data8;\r
122 UINT16 Data16;\r
123 UINT32 Data32;\r
124\r
125 //\r
126 // Check for PowerState option for AC power loss and program the chipset\r
127 //\r
128\r
129 //\r
130 // Clear PWROK (Set to Clear)\r
131 //\r
132 MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, B_PCH_PMC_GEN_PMCON_PWROK_FLR);\r
133\r
134 //\r
135 // Clear Power Failure Bit (Set to Clear)\r
136 //\r
137 // TODO: Check if it is OK to clear here\r
138 //\r
139\r
140 MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR);\r
141\r
142 //\r
143 // Clear the GPE and PM enable\r
144 //\r
145 IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_EN, (UINT16) 0x00);\r
146 IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_EN, (UINT32) 0x00);\r
147\r
148 //\r
149 // Halt the TCO timer\r
150 //\r
151 Data16 = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_TCO_CNT);\r
152 Data16 |= B_PCH_TCO_CNT_TMR_HLT;\r
153 IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_TCO_CNT, Data16);\r
154\r
155 //\r
156 // if NMI_NOW_STS is set\r
157 // NMI NOW bit is "Write '1' to clear"\r
158 //\r
159 Data8 = MmioRead8(ILB_BASE_ADDRESS + R_PCH_ILB_GNMI);\r
160 if ((Data8 & B_PCH_ILB_GNMI_NMINS) == B_PCH_ILB_GNMI_NMINS) {\r
161 MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_GNMI, B_PCH_ILB_GNMI_NMIN);\r
162 }\r
163\r
164 //\r
165 // Before we clear the TO status bit here we need to save the results in a CMOS bit for later use.\r
166 //\r
167 Data32 = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_TCO_STS);\r
168 if ((Data32 & B_PCH_TCO_STS_SECOND_TO) == B_PCH_TCO_STS_SECOND_TO)\r
169 {\r
170#if (defined(HW_WATCHDOG_TIMER_SUPPORT) && (HW_WATCHDOG_TIMER_SUPPORT != 0))\r
171 WriteCmosBank1Byte (\r
172 EFI_CMOS_PERFORMANCE_FLAGS,\r
173 ReadCmosBank1Byte (EFI_CMOS_PERFORMANCE_FLAGS) | B_CMOS_TCO_WDT_RESET\r
174 );\r
175#endif\r
176 }\r
177}\r
178\r
179/*++\r
180\r
181 Clear any SMI status or wake status left over from boot.\r
182\r
183**/\r
184VOID\r
185ClearSmiAndWake (\r
186 VOID\r
187 )\r
188{\r
189 UINT16 Pm1Sts;\r
190 UINT32 Gpe0Sts;\r
191 UINT32 SmiSts;\r
192\r
193 //\r
194 // Read the ACPI registers\r
195 //\r
196 Pm1Sts = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS);\r
197 Gpe0Sts = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS);\r
198 SmiSts = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_SMI_STS);\r
199\r
200 //\r
201 // Register Wake up reason for S4. This information is used to notify\r
202 // WinXp of wake up reason because S4 wake up path doesn't keep SCI.\r
203 // This is important for Viiv(Quick resume) platform.\r
204 //\r
205\r
206 //\r
207 // First Clear CMOS S4 Wake up flag.\r
208 //\r
209 WriteCmosBank1Byte(CMOS_S4_WAKEUP_FLAG_ADDRESS, 0);\r
210\r
211 //\r
212 // Check wake up reason and set CMOS accordingly. Currently checks\r
213 // Power button, USB, PS/2.\r
214 // Note : PS/2 wake up is using GPI13 (IO_PME). This must be changed depending\r
215 // on board design.\r
216 //\r
217 if ((Pm1Sts & B_PCH_ACPI_PM1_STS_PWRBTN) || (Gpe0Sts & (B_PCH_ACPI_GPE0a_STS_CORE_GPIO | B_PCH_ACPI_GPE0a_STS_SUS_GPIO))) {\r
218 WriteCmosBank1Byte(CMOS_S4_WAKEUP_FLAG_ADDRESS, 1);\r
219 }\r
220\r
221 //\r
222 // Clear any SMI or wake state from the boot\r
223 //\r
224 Pm1Sts = (B_PCH_ACPI_PM1_STS_PRBTNOR | B_PCH_ACPI_PM1_STS_PWRBTN);\r
225\r
226 Gpe0Sts |=\r
227 (\r
228 B_PCH_ACPI_GPE0a_STS_CORE_GPIO |\r
229 B_PCH_ACPI_GPE0a_STS_SUS_GPIO |\r
230 B_PCH_ACPI_GPE0a_STS_PME_B0 |\r
231 B_PCH_ACPI_GPE0a_STS_BATLOW |\r
232 B_PCH_ACPI_GPE0a_STS_PCI_EXP |\r
233 B_PCH_ACPI_GPE0a_STS_GUNIT_SCI |\r
234 B_PCH_ACPI_GPE0a_STS_PUNIT_SCI |\r
235 B_PCH_ACPI_GPE0a_STS_SWGPE |\r
236 B_PCH_ACPI_GPE0a_STS_HOT_PLUG\r
237 );\r
238\r
239 SmiSts |=\r
240 (\r
241 B_PCH_SMI_STS_SMBUS |\r
242 B_PCH_SMI_STS_PERIODIC |\r
243 B_PCH_SMI_STS_TCO |\r
244 B_PCH_SMI_STS_SWSMI_TMR |\r
245 B_PCH_SMI_STS_APM |\r
246 B_PCH_SMI_STS_ON_SLP_EN |\r
247 B_PCH_SMI_STS_BIOS\r
248 );\r
249\r
250 //\r
251 // Write them back\r
252 //\r
253 IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_STS, Pm1Sts);\r
254 IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_GPE0a_STS, Gpe0Sts);\r
255 IoWrite32 (ACPI_BASE_ADDRESS + R_PCH_SMI_STS, SmiSts);\r
256}\r
257\r
258/**\r
259 Issue PCI-E Secondary Bus Reset\r
260\r
261 @param Bus Bus number of the bridge\r
262 @param Dev Devices number of the bridge\r
263 @param Fun Function number of the bridge\r
264\r
265 @retval EFI_SUCCESS\r
266\r
267**/\r
268EFI_STATUS\r
269PcieSecondaryBusReset (\r
270 IN CONST EFI_PEI_SERVICES **PeiServices,\r
271 IN UINT8 Bus,\r
272 IN UINT8 Dev,\r
273 IN UINT8 Fun\r
274 )\r
275{\r
276 EFI_PEI_STALL_PPI *PeiStall;\r
277 EFI_STATUS Status;\r
278\r
279 Status = (**PeiServices).LocatePpi (\r
280 PeiServices,\r
281 &gEfiPeiStallPpiGuid,\r
282 0,\r
283 NULL,\r
284 (void **)&PeiStall\r
285 );\r
286 ASSERT_EFI_ERROR (Status);\r
287\r
288 //\r
289 // Issue secondary bus reset\r
290 //\r
291 MmPci16Or(0, Bus, Dev, Fun, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS);\r
292\r
293 //\r
294 // Wait 1ms\r
295 //\r
296 PeiStall->Stall (PeiServices, PeiStall, 1000);\r
297\r
298\r
299 //\r
300 // Clear the reset bit\r
301 // Note: The PCIe spec suggests 100ms delay between clearing this bit and accessing\r
302 // the device's config space. Since we will not access the config space until we enter DXE\r
303 // we don't put delay expressly here.\r
304 //\r
305 MmPci16And(0, Bus, Dev, Fun, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, ~(EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS));\r
306\r
307 return EFI_SUCCESS;\r
308}\r
309\r
310/**\r
311 Provide hard reset PPI service.\r
312 To generate full hard reset, write 0x0E to ICH RESET_GENERATOR_PORT (0xCF9).\r
313\r
314 @param PeiServices General purpose services available to every PEIM.\r
315\r
316 @retval Not return System reset occured.\r
317 @retval EFI_DEVICE_ERROR Device error, could not reset the system.\r
318\r
319**/\r
320EFI_STATUS\r
321EFIAPI\r
322IchReset (\r
323 IN CONST EFI_PEI_SERVICES **PeiServices\r
324 )\r
325{\r
326 IoWrite8 (\r
327 R_PCH_RST_CNT,\r
328 V_PCH_RST_CNT_HARDSTARTSTATE\r
329 );\r
330\r
331 IoWrite8 (\r
332 R_PCH_RST_CNT,\r
333 V_PCH_RST_CNT_HARDRESET\r
334 );\r
335\r
336 //\r
337 // System reset occured, should never reach at this line.\r
338 //\r
339 ASSERT_EFI_ERROR (EFI_DEVICE_ERROR);\r
340 CpuDeadLoop();\r
341\r
342 return EFI_DEVICE_ERROR;\r
343}\r
344\r
345VOID\r
346PchPlatformLpcInit (\r
347 IN CONST EFI_PEI_SERVICES **PeiServices,\r
348 IN SYSTEM_CONFIGURATION *SystemConfiguration\r
349 )\r
350{\r
351 EFI_BOOT_MODE BootMode;\r
352 UINT8 Data8;\r
353 UINT16 Data16;\r
354\r
355 (*PeiServices)->GetBootMode(PeiServices, &BootMode);\r
356\r
357 if ((BootMode != BOOT_ON_S3_RESUME)) {\r
358\r
359 //\r
360 // Clear all pending SMI. On S3 clear power button enable so it wll not generate an SMI\r
361 //\r
362 ClearSmiAndWake ();\r
363 }\r
364\r
365 ClearPowerState (SystemConfiguration);\r
366\r
367 //\r
368 // Need to set and clear SET bit (RTC_REGB Bit 7) as requested by the ICH EDS\r
369 // early in POST after each power up directly after coin-cell battery insertion.\r
370 // This is to avoid the UIP bit (RTC_REGA Bit 7) from stuck at "1".\r
371 // The UIP bit status may be polled by software (i.e ME FW) during POST.\r
372 //\r
373 if (MmioRead8 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1) & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) {\r
374 //\r
375 // Set and clear SET bit in RTC_REGB\r
376 //\r
377 IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERB);\r
378 Data8 = IoRead8(R_PCH_RTC_TARGET);\r
379 Data8 |= B_PCH_RTC_REGISTERB_SET;\r
380 IoWrite8(R_PCH_RTC_TARGET, Data8);\r
381\r
382 IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERB);\r
383 Data8 &= (~B_PCH_RTC_REGISTERB_SET);\r
384 IoWrite8(R_PCH_RTC_TARGET, Data8);\r
385\r
386 //\r
387 // Clear the UIP bit in RTC_REGA\r
388 //\r
389 IoWrite8(R_PCH_RTC_INDEX, R_PCH_RTC_REGISTERA);\r
390 IoWrite8(R_PCH_RTC_TARGET, 0x00);\r
391 }\r
392\r
393 //\r
394 // Disable SERR NMI and IOCHK# NMI in port 61\r
395 //\r
396 Data8 = IoRead8 (R_PCH_NMI_SC);\r
397 IoWrite8(R_PCH_NMI_SC, (UINT8) (Data8 | B_PCH_NMI_SC_PCI_SERR_EN | B_PCH_NMI_SC_IOCHK_NMI_EN));\r
398\r
399 //\r
400 // Enable Bus Master, I/O, Mem, and SERR on LPC bridge\r
401 //\r
402 Data16 = PchLpcPciCfg16 (R_PCH_LPC_COMMAND);\r
403 MmioWrite16 (\r
404 MmPciAddress (0,\r
405 DEFAULT_PCI_BUS_NUMBER_PCH,\r
406 PCI_DEVICE_NUMBER_PCH_LPC,\r
407 PCI_FUNCTION_NUMBER_PCH_LPC,\r
408 R_PCH_LPC_COMMAND\r
409 ),\r
410 (Data16 |\r
411 B_PCH_LPC_COMMAND_IOSE |\r
412 B_PCH_LPC_COMMAND_MSE |\r
413 B_PCH_LPC_COMMAND_BME |\r
414 B_PCH_LPC_COMMAND_SERR_EN)\r
415 );\r
416\r
417 //\r
418 // Set Stretch S4 to 1-2s per marketing request.\r
419 // Note: This register is powered by RTC well.\r
420 //\r
421 MmioAndThenOr8 (\r
422 PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1 ,\r
423 (UINT8) (~B_PCH_PMC_GEN_PMCON_SLP_S4_MAW),\r
424 (UINT8) (B_PCH_PMC_GEN_PMCON_SLP_S4_ASE | V_PCH_PMC_GEN_PMCON_SLP_S4_MAW_4S)\r
425 );\r
426\r
427}\r
428\r
429#define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3 BIT3 // UART IRQ3 Enable\r
430\r
431VOID\r
432UARTInit (\r
433 IN SYSTEM_CONFIGURATION *SystemConfiguration\r
434 )\r
435{\r
436 if (0) { // for fix cr4 issue\r
437 //\r
438 // Program and enable PMC Base.\r
439 //\r
440 IoWrite32 (0xCF8, PCI_LPC_REG(R_PCH_LPC_PMC_BASE));\r
441 IoWrite32 (0xCFC, (PMC_BASE_ADDRESS | B_PCH_LPC_PMC_BASE_EN));\r
442\r
443 if( (SystemConfiguration->PcuUart1 == 1) &&\r
444 (SystemConfiguration->LpssHsuart0Enabled == 0)){\r
445 //\r
446 // Enable COM1 for debug message output.\r
447 //\r
448 MmioOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, BIT24);\r
449\r
450 //\r
451 //Enable internal UART3 port(COM1)\r
452 //\r
453 MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);\r
454 MmioOr32 (IO_BASE_ADDRESS + 0x0520, 0x01); // UART3_RXD-L\r
455 MmioOr32 (IO_BASE_ADDRESS + 0x0530, 0x01); // UART3_TXD-0\r
456 MmioOr8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) B_PCH_LPC_UART_CTRL_COM1_EN);\r
457 } else {\r
458 //\r
459 //Disable UART3(COM1)\r
460 //\r
461 MmioAnd8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) ~V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);\r
462 MmioAnd32 (IO_BASE_ADDRESS + 0x0520, ~(UINT32)0x07);\r
463 MmioAnd32 (IO_BASE_ADDRESS + 0x0530, ~(UINT32)0x07);\r
464 MmioAnd8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) ~B_PCH_LPC_UART_CTRL_COM1_EN);\r
465\r
466\r
467 if (SystemConfiguration->LpssHsuart0Enabled == 1){\r
468 //\r
469 //Valleyview BIOS Specification Vol2,17.2\r
470