]> git.proxmox.com Git - mirror_edk2.git/blame - Vlv2TbltDevicePkg/PlatformPei/Platform.c
Add ACPI6.0 header file.
[mirror_edk2.git] / Vlv2TbltDevicePkg / PlatformPei / Platform.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
14\r
15Module Name:\r
16\r
17**/\r
18\r
19#include "CommonHeader.h"\r
20\r
21#include "Platform.h"\r
22#include <Library/PciCf8Lib.h>\r
23#include "PlatformBaseAddresses.h"\r
24#include "PchAccess.h"\r
25#include <Guid/PlatformInfo.h>\r
26#include "Platform.h"\r
27#include "PchCommonDefinitions.h"\r
28#include <Ppi/MfgMemoryTest.h>\r
29#include <Guid/SetupVariable.h>\r
30#include <Guid/Vlv2Variable.h>\r
31\r
32//\r
33// Start::Alpine Valley platform\r
34//\r
35enum {\r
36 SMBUS_READ_BYTE,\r
37 SMBUS_WRITE_BYTE,\r
38 SMBUS_READ_BLOCK,\r
39 SMBUS_WRITE_BLOCK\r
40};\r
41\r
42#define EC_BASE 0xE0000000\r
43\r
44//\r
45// DEVICE 0 (Memroy Controller Hub)\r
46//\r
47#define MC_BUS 0x00\r
48#define MC_DEV 0x00\r
49#define MC_FUN 0x00\r
50#define MC_DEV_FUN (MC_DEV << 3)\r
51#define MC_BUS_DEV_FUN ((MC_BUS << 8) + MC_DEV_FUN)\r
52\r
53//\r
54// SysCtl SMBus address and block size\r
55//\r
56#define AV_SC_SMBUS_ADDRESS 0x60\r
57#define AV_SC_BYTE_LEN 1\r
58#define AV_SC_BLOCK_LEN 4\r
59#define AV_SC_SMBUS_WRCMD 1\r
60#define AV_SC_SMBUS_RDCMD 0\r
61\r
62//\r
63// SysCtl registers offset\r
64//\r
65#define AV_SC_REG_PLATFORM_ID 24 // 0x18\r
66#define AV_SC_REG_BOARD_ID 28 // 0x1C\r
67#define AV_SC_REG_FAB_ID 32 // 0x20\r
68#define AV_SC_REG_ECO_ID 68 // 0x44\r
69#define AV_SC_REG_DDR_DAUGHTER_CARD_ID 144 // 0x90\r
70#define AV_SC_REG_SODIMM_CONFIG 36\r
71\r
72//\r
73// ID values\r
74//\r
75#define AV_SC_PLATFORM_ID_TABLET 0\r
76#define AV_SC_PLATFORM_ID_NETBOOK 2\r
77#define AV_SC_PLATFORM_ID_INTERPOSER 3 // Configuration TBD\r
78#define AV_SC_BOARD_ID_AV_SVP 1492\r
79\r
80#define BUS_TRIES 3 // How many times to retry on Bus Errors\r
81\r
82#define GTT_SIZE_1MB 1\r
83#define GTT_SIZE_2MB 2\r
84\r
85#define PciCfg16Read( PciExpressBase, Bus, Device, Function, Register ) \\r
86 MmioRead16(PciExpressBase + \\r
87 (UINTN)(Bus << 20) + \\r
88 (UINTN)(Device << 15) + \\r
89 (UINTN)(Function << 12) + \\r
90 (UINTN)(Register))\r
91#define PciCfg16Write( PciExpressBase, Bus, Device, Function, Register, Data ) \\r
92 MmioWrite16(PciExpressBase + \\r
93 (UINTN)(Bus << 20) + \\r
94 (UINTN)(Device << 15) + \\r
95 (UINTN)(Function << 12) + \\r
96 (UINTN)(Register), \\r
97 (UINT16)Data)\r
98\r
99\r
100//\r
101//Memory Test Manufacturing mode\r
102//\r
103UINT32 DataPatternForMemoryTest[] = {\r
104 0x55555555, 0xAAAAAAAA, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF,\r
105 0x55555555, 0xAAAAAAAA, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55,\r
106 0x55555555, 0xAAAAAAAA, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555,\r
107 0x55555555, 0xAAAAAAAA, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555\r
108};\r
109#define DATA_PATTERN_ARRAY_SIZE (sizeof(DataPatternForMemoryTest) / sizeof(UINT32))\r
110\r
111//\r
112//Memory Test Manufacturing mode\r
113//\r
114//\r
115// The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory\r
116//\r
117BOOLEAN ImageInMemory = FALSE;\r
118\r
119EFI_STATUS\r
120EFIAPI\r
121Stall (\r
122 IN CONST EFI_PEI_SERVICES **PeiServices,\r
123 IN CONST EFI_PEI_STALL_PPI *This,\r
124 IN UINTN Microseconds\r
125 );\r
126\r
127EFI_STATUS\r
128EFIAPI\r
129MfgMemoryTest (\r
130 IN CONST EFI_PEI_SERVICES **PeiServices,\r
131 IN PEI_MFG_MEMORY_TEST_PPI *This,\r
132 IN UINT32 BeginAddress,\r
133 IN UINT32 MemoryLength\r
134 );\r
135\r
136static EFI_PEI_STALL_PPI mStallPpi = {\r
137 PEI_STALL_RESOLUTION,\r
138 Stall\r
139};\r
140\r
141static PEI_MFG_MEMORY_TEST_PPI mPeiMfgMemoryTestPpi = {\r
142 MfgMemoryTest\r
143};\r
144\r
145static EFI_PEI_PPI_DESCRIPTOR mInstallStallPpi[] = {\r
146 {\r
147 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
148 &gEfiPeiStallPpiGuid,\r
149 &mStallPpi\r
150 },\r
151 {\r
152 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
153 &gPeiMfgMemoryTestPpiGuid,\r
154 &mPeiMfgMemoryTestPpi\r
155 }\r
156 };\r
157\r
158EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = {\r
159 {\r
160 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
161 &gEfiPeiMemoryDiscoveredPpiGuid,\r
162 MemoryDiscoveredPpiNotifyCallback\r
163 }\r
164};\r
165\r
166EFI_STATUS\r
167EFIAPI\r
168InstallMonoStatusCode (\r
169 IN EFI_FFS_FILE_HEADER *FfsHeader,\r
170 IN CONST EFI_PEI_SERVICES **PeiServices\r
171 );\r
172\r
173\r
174EFI_STATUS\r
175ReadPlatformIds (\r
176 IN CONST EFI_PEI_SERVICES **PeiServices,\r
177 IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob\r
178 );\r
179\r
180//\r
181// Start::Alpine Valley platform\r
182//\r
183EFI_STATUS\r
184PeiSmbusExec (\r
185 UINT16 SmbusBase,\r
186 UINT8 SlvAddr,\r
187 UINT8 Operation,\r
188 UINT8 Offset,\r
189 UINT8 *Length,\r
190 UINT8 *Buffer\r
191 );\r
192\r
193/**\r
194 This routine attempts to acquire the SMBus\r
195\r
196 @retval FAILURE as failed\r
197 @retval SUCCESS as passed\r
198\r
199**/\r
200EFI_STATUS\r
201AcquireBus (\r
202 UINT16 SmbusBase\r
203 )\r
204{\r
205 UINT8 StsReg;\r
206\r
207 StsReg = 0;\r
208 StsReg = (UINT8)IoRead8(SmbusBase + R_PCH_SMBUS_HSTS);\r
209 if (StsReg & B_PCH_SMBUS_IUS) {\r
210 return EFI_DEVICE_ERROR;\r
211 } else if (StsReg & B_PCH_SMBUS_HBSY) {\r
212 //\r
213 // Clear Status Register and exit\r
214 //\r
215 // Wait for HSTS.HBSY to be clear\r
216 //\r
217 do { StsReg = (UINT8) IoRead8(SmbusBase+R_PCH_SMBUS_HSTS); } while ((StsReg & B_PCH_SMBUS_HBSY) != 0);\r
218\r
219 //\r
220 // Clear all status bits\r
221 //\r
222 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, 0xFE);\r
223 return EFI_SUCCESS;\r
224 } else {\r
225 //\r
226 // Clear out any odd status information (Will Not Clear In Use)\r
227 //\r
228 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, StsReg);\r
229 return EFI_SUCCESS;\r
230 }\r
231}\r
232//\r
233// End::Alpine Valley platform\r
234//\r
235\r
236/**\r
237 This function checks the memory range in PEI.\r
238\r
239 @param PeiServices Pointer to PEI Services.\r
240 @param This Pei memory test PPI pointer.\r
241 @param BeginAddress Beginning of the memory address to be checked.\r
242 @param MemoryLength Bytes of memory range to be checked.\r
243 @param Operation Type of memory check operation to be performed.\r
244 @param ErrorAddress Return the address of the error memory address.\r
245\r
246 @retval EFI_SUCCESS The operation completed successfully.\r
247 @retval EFI_DEVICE_ERROR Memory test failed. It's not safe to use this range of memory.\r
248\r
249**/\r
250EFI_STATUS\r
251EFIAPI\r
252MfgMemoryTest (\r
253 IN CONST EFI_PEI_SERVICES **PeiServices,\r
254 IN PEI_MFG_MEMORY_TEST_PPI *This,\r
255 IN UINT32 BeginAddress,\r
256 IN UINT32 MemoryLength\r
257 )\r
258{\r
259 UINT32 i;\r
260 UINT32 memAddr;\r
261 UINT32 readData;\r
262 UINT32 xorData;\r
263 UINT32 TestFlag = 0;\r
264 memAddr = BeginAddress;\r
265\r
266 //\r
267 //Output Message for MFG\r
268 //\r
269 DEBUG ((EFI_D_ERROR, "MFGMODE SET\n"));\r
270\r
271 //\r
272 //Writting the pattern in defined location.\r
273 //\r
274 while (memAddr < (BeginAddress+MemoryLength)) {\r
275 for (i = 0; i < DATA_PATTERN_ARRAY_SIZE; i++) {\r
276 if (memAddr > (BeginAddress+MemoryLength -4)) {\r
277 memAddr = memAddr + 4;\r
278 break;\r
279 }\r
280 *((volatile UINT32*) memAddr) = DataPatternForMemoryTest[i];\r
281 memAddr = memAddr + 4;\r
282 }\r
283 }\r
284\r
285 //\r
286 //Verify the pattern.\r
287 //\r
288 memAddr = BeginAddress;\r
289 while (memAddr < (BeginAddress+MemoryLength)) {\r
290 for (i = 0; i < DATA_PATTERN_ARRAY_SIZE; i++) {\r
291 if (memAddr > (BeginAddress+MemoryLength -4)) {\r
292 memAddr = memAddr + 4;\r
293 break;\r
294 }\r
295 readData = *((volatile UINT32*) memAddr);\r
296 xorData = readData ^ DataPatternForMemoryTest[i];\r
297\r
298 //\r
299 // If xorData is nonzero, this particular memAddr has a failure.\r
300 //\r
301 if (xorData != 0x00000000) {\r
302 DEBUG ((EFI_D_ERROR, "Expected value....: %x\n", DataPatternForMemoryTest[i]));\r
303 DEBUG ((EFI_D_ERROR, "ReadData value....: %x\n", readData));\r
304 DEBUG ((EFI_D_ERROR, "Pattern failure at....: %x\n", memAddr));\r
305 TestFlag = 1;\r
306 }\r
307 memAddr = memAddr + 4;\r
308 }\r
309 }\r
310 if (TestFlag) {\r
311 return EFI_DEVICE_ERROR;\r
312 }\r
313\r
314 //\r
315 //Output Message for MFG\r
316 //\r
317 DEBUG ((EFI_D_ERROR, "MFGMODE MEMORY TEST PASSED\n"));\r
318 return EFI_SUCCESS;\r
319}\r
320\r
321BOOLEAN\r
322IsRtcUipAlwaysSet (\r
323 IN CONST EFI_PEI_SERVICES **PeiServices\r
324 )\r
325{\r
326\r
327 EFI_PEI_STALL_PPI *StallPpi;\r
328 UINTN Count;\r
329\r
330 (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0, NULL, (void **)&StallPpi);\r
331\r
332 for (Count = 0; Count < 500; Count++) { // Maximum waiting approximates to 1.5 seconds (= 3 msec * 500)\r
333 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);\r
334 if ((IoRead8 (R_PCH_RTC_TARGET2) & B_PCH_RTC_REGISTERA_UIP) == 0) {\r
335 return FALSE;\r
336 }\r
337\r
338 StallPpi->Stall (PeiServices, StallPpi, 3000);\r
339 }\r
340\r
341 return TRUE;\r
342}\r
343\r
344EFI_STATUS\r
345RtcPowerFailureHandler (\r
346 IN CONST EFI_PEI_SERVICES **PeiServices\r
347 )\r
348{\r
349\r
350 UINT16 DataUint16;\r
351 UINT8 DataUint8;\r
352 BOOLEAN RtcUipIsAlwaysSet;\r
353 DataUint16 = MmioRead16 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1);\r
354 RtcUipIsAlwaysSet = IsRtcUipAlwaysSet (PeiServices);\r
355 if ((DataUint16 & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) || (RtcUipIsAlwaysSet)) {\r
356 //\r
357 // Execute the sequence below. This will ensure that the RTC state machine has been initialized.\r
358 //\r
359 // Step 1.\r
360 // BIOS clears this bit by writing a '0' to it.\r
361 //\r
362 if (DataUint16 & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) {\r
363 //\r
364 // Set to invalid date in order to reset the time to\r
365 // BIOS build time later in the boot (SBRUN.c file).\r
366 //\r
367 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_YEAR);\r
368 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);\r
369 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MONTH);\r
370 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);\r
371 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFMONTH);\r
372 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);\r
373 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFWEEK);\r
374 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);\r
375\r
376 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_SECONDSALARM);\r
377 IoWrite8 (R_PCH_RTC_TARGET2, 0x00);\r
378 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MINUTESALARM);\r
379 IoWrite8 (R_PCH_RTC_TARGET2, 0x00);\r
380 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_HOURSALARM);\r
381 IoWrite8 (R_PCH_RTC_TARGET2, 0x00);\r
382 }\r
383\r
384 //\r
385 // Step 2.\r
386 // Set RTC Register 0Ah[6:4] to '110' or '111'.\r
387 //\r
388 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);\r
389 IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_DIV_RST1 | V_PCH_RTC_REGISTERA_RS_976P5US));\r
390\r
391 //\r
392 // Step 3.\r
393 // Set RTC Register 0Bh[7].\r
394 //\r
395 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);\r
396 DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) | B_PCH_RTC_REGISTERB_SET);\r
397 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);\r
398 IoWrite8 (R_PCH_RTC_TARGET2, DataUint8);\r
399\r
400 //\r
401 // Step 4.\r
402 // Set RTC Register 0Ah[6:4] to '010'.\r
403 //\r
404 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);\r
405 IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_NORM_OP | V_PCH_RTC_REGISTERA_RS_976P5US));\r
406\r
407 //\r
408 // Step 5.\r
409 // Clear RTC Register 0Bh[7].\r
410 //\r
411 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);\r
412 DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) & (UINT8)~B_PCH_RTC_REGISTERB_SET);\r
413 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);\r
414 IoWrite8 (R_PCH_RTC_TARGET2, DataUint8);\r
415 }\r
416\r
417 return EFI_SUCCESS;\r
418}\r
419\r
420\r
421VOID\r
422PchBaseInit (\r
423 VOID\r
424 )\r
425{\r
426 //\r
427 // Program ACPI Power Management I/O Space Base Address\r
428 //\r
429 MmioWrite16 (\r
430 MmPciAddress (0,\r
431 DEFAULT_PCI_BUS_NUMBER_PCH,\r
432 PCI_DEVICE_NUMBER_PCH_LPC,\r
433 PCI_FUNCTION_NUMBER_PCH_LPC,\r
434 R_PCH_LPC_ACPI_BASE\r
435 ),\r
436 (UINT16)((ACPI_BASE_ADDRESS & B_PCH_LPC_ACPI_BASE_BAR) | B_PCH_LPC_ACPI_BASE_EN)\r
437 );\r
438\r
439 //\r
440 // Program GPIO Base Address\r
441 //\r
442 MmioWrite16 (\r
443 MmPciAddress (0,\r
444 DEFAULT_PCI_BUS_NUMBER_PCH,\r
445 PCI_DEVICE_NUMBER_PCH_LPC,\r
446 PCI_FUNCTION_NUMBER_PCH_LPC,\r
447 R_PCH_LPC_GPIO_BASE\r
448 ),\r
449 (UINT16)((GPIO_BASE_ADDRESS & B_PCH_LPC_GPIO_BASE_BAR) | B_PCH_LPC_GPIO_BASE_EN)\r
450 );\r
451\r
452 //\r
453 // Set PMC Base Address\r
454 //\r
455 MmioWrite32 (\r
456 MmPciAddress (0,\r
457 DEFAULT_PCI_BUS_NUMBER_PCH,\r
458 PCI_DEVICE_NUMBER_PCH_LPC,\r
459 PCI_FUNCTION_NUMBER_PCH_LPC,\r
460 R_PCH_LPC_PMC_BASE\r
461 ),\r
462 (UINT32)((PMC_BASE_ADDRESS & B_PCH_LPC_PMC_BASE_BAR) | B_PCH_LPC_PMC_BASE_EN)\r
463 );\r
464\r
465 //\r
466 // Set IO Base Address\r
467 //\r
468 MmioWrite32 (\r
469 MmPciAddress (0,\r
470 DEFAULT_PCI_BUS_NUMBER_PCH,\r
471 PCI_DEVICE_NUMBER_PCH_LPC,\r
472 PCI_FUNCTION_NUMBER_PCH_LPC,\r
473 R_PCH_LPC_IO_BASE\r
474 ),\r
475 (UINT32)((IO_BASE_ADDRESS & B_PCH_LPC_IO_BASE_BAR) | B_PCH_LPC_IO_BASE_EN)\r
476 );\r
477\r
478 //\r
479 // Set ILB Base Address\r
480 //\r
481 MmioWrite32 (\r
482 MmPciAddress (0,\r
483 DEFAULT_PCI_BUS_NUMBER_PCH,\r
484 PCI_DEVICE_NUMBER_PCH_LPC,\r
485 PCI_FUNCTION_NUMBER_PCH_LPC,\r
486 R_PCH_LPC_ILB_BASE\r
487 ),\r
488 (UINT32)((ILB_BASE_ADDRESS & B_PCH_LPC_ILB_BASE_BAR) | B_PCH_LPC_ILB_BASE_EN)\r
489 );\r
490\r
491 //\r
492 // Set PUnit Base Address\r
493 //\r
494 MmioWrite32 (\r
495 MmPciAddress (0,\r
496 DEFAULT_PCI_BUS_NUMBER_PCH,\r
497 PCI_DEVICE_NUMBER_PCH_LPC,\r
498 PCI_FUNCTION_NUMBER_PCH_LPC,\r
499 R_PCH_LPC_PUNIT_BASE\r
500 ),\r
501 (UINT32)((PUNIT_BASE_ADDRESS & B_PCH_LPC_PUNIT_BASE_BAR) | B_PCH_LPC_PUNIT_BASE_EN)\r
502 );\r
503\r
504 //\r
505 // Set SPI Base Address\r
506 //\r
507 MmioWrite32 (\r
508 MmPciAddress (0,\r
509 DEFAULT_PCI_BUS_NUMBER_PCH,\r
510 PCI_DEVICE_NUMBER_PCH_LPC,\r
511 PCI_FUNCTION_NUMBER_PCH_LPC,\r
512 R_PCH_LPC_SPI_BASE\r
513 ),\r
514 (UINT32)((SPI_BASE_ADDRESS & B_PCH_LPC_SPI_BASE_BAR) | B_PCH_LPC_SPI_BASE_EN)\r
515 );\r
516\r
517 //\r
518 // Set Root Complex Base Address\r
519 //\r
520 MmioWrite32 (\r
521 MmPciAddress (0,\r
522 DEFAULT_PCI_BUS_NUMBER_PCH,\r
523 PCI_DEVICE_NUMBER_PCH_LPC,\r
524 PCI_FUNCTION_NUMBER_PCH_LPC,\r
525 R_PCH_LPC_RCBA\r
526 ),\r
527 (UINT32)((RCBA_BASE_ADDRESS & B_PCH_LPC_RCBA_BAR) | B_PCH_LPC_RCBA_EN)\r
528 );\r
529\r
530 //\r
531 // Set MPHY Base Address\r
532 //\r
533 MmioWrite32 (\r
534 MmPciAddress (0,\r
535 DEFAULT_PCI_BUS_NUMBER_PCH,\r
536 PCI_DEVICE_NUMBER_PCH_LPC,\r
537 PCI_FUNCTION_NUMBER_PCH_LPC,\r
538 R_PCH_LPC_MPHY_BASE\r
539 ),\r
540 (UINT32)((MPHY_BASE_ADDRESS & B_PCH_LPC_MPHY_BASE_BAR) | B_PCH_LPC_MPHY_BASE_EN)\r
541 );\r
542 MmioWrite16 (\r
543 MmPciAddress (0,\r
544 DEFAULT_PCI_BUS_NUMBER_PCH,\r
545 PCI_DEVICE_NUMBER_PCH_SMBUS,\r
546 PCI_FUNCTION_NUMBER_PCH_SMBUS,\r
547 R_PCH_SMBUS_BASE\r
548 ),\r
549 (UINT16)(SMBUS_BASE_ADDRESS & B_PCH_SMBUS_BASE_BAR)\r
550 );\r
551\r
552 MmioOr8 (\r
553 MmPciAddress (0,\r
554 DEFAULT_PCI_BUS_NUMBER_PCH,\r
555 PCI_DEVICE_NUMBER_PCH_SMBUS,\r
556 PCI_FUNCTION_NUMBER_PCH_SMBUS,\r
557 R_PCH_SMBUS_PCICMD\r
558 ),\r
559 B_PCH_SMBUS_PCICMD_IOSE\r
560 );\r
561\r
562}\r
563\r
564/**\r
565 This is the entrypoint of PEIM\r
566\r
567 @param FileHandle Handle of the file being invoked.\r
568 @param PeiServices Describes the list of possible PEI Services.\r
569\r
570 @retval EFI_SUCCESS if it completed successfully.\r
571**/\r
572EFI_STATUS\r
573EFIAPI\r
574PeiInitPlatform (\r
575 IN EFI_PEI_FILE_HANDLE FileHandle,\r
576 IN CONST EFI_PEI_SERVICES **PeiServices\r
577 )\r
578{\r
579 UINTN SmbusRegBase;\r
580 EFI_PLATFORM_INFO_HOB PlatformInfo;\r
581 EFI_STATUS Status= EFI_SUCCESS;\r
582 EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable = NULL;\r
583 UINTN VariableSize;\r
584 SYSTEM_CONFIGURATION SystemConfiguration;\r
585 UINT32 GGC = 0;\r
586\r
587 EFI_PEI_PPI_DESCRIPTOR *mVlvMmioPolicyPpiDesc;\r
588 VLV_MMIO_POLICY_PPI *mVlvMmioPolicyPpi;\r
589\r
590 ZeroMem (&PlatformInfo, sizeof(PlatformInfo));\r
591\r
592 Status = InstallMonoStatusCode(FileHandle, PeiServices);\r
593 ASSERT_EFI_ERROR (Status);\r
594\r
595\r
596 //\r
597 // Initialize Stall PPIs\r
598 //\r
599 Status = (*PeiServices)->InstallPpi (PeiServices, &mInstallStallPpi[0]);\r
600 ASSERT_EFI_ERROR (Status);\r
601\r
602 Status = (*PeiServices)->NotifyPpi (PeiServices, &mMemoryDiscoveredNotifyList[0]);\r
603 ASSERT_EFI_ERROR (Status);\r
604 SmbusRegBase = PchPciDeviceMmBase (\r
605 DEFAULT_PCI_BUS_NUMBER_PCH,\r
606 PCI_DEVICE_NUMBER_PCH_SMBUS,\r
607 PCI_FUNCTION_NUMBER_PCH_SMBUS\r
608 );\r
609 //\r
610 // Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves\r
611 //\r
612 MmioAndThenOr32 (SmbusRegBase + R_PCH_SMBUS_BASE, B_PCH_SMBUS_BASE_BAR, SMBUS_BASE_ADDRESS);\r
613\r
614 MmioOr8 (SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE);\r
615\r
616 PchBaseInit();\r
617\r
618 //\r
619 //Todo: confirm if we need program 8254\r
620 //\r
621 // Setting 8254\r
622 // Program timer 1 as refresh timer\r
623 //\r
624 IoWrite8 (0x43, 0x54);\r
625 IoWrite8 (0x41, 0x12);\r
626\r
627 //\r
628 // RTC power failure handling\r
629 //\r
630 RtcPowerFailureHandler (PeiServices);\r
631\r
632\r
633 PchMmPci32( 0, 0, 2, 0, 0x50) = 0x210;\r
634\r
635 VariableSize = sizeof (SYSTEM_CONFIGURATION);\r
636 ZeroMem (&SystemConfiguration, VariableSize);\r
637\r
638 //\r
639 // Obtain variable services\r
640 //\r
641 Status = (*PeiServices)->LocatePpi(\r
642 PeiServices,\r
643 &gEfiPeiReadOnlyVariable2PpiGuid,\r
644 0,\r
645 NULL,\r
646 (void **)&Variable\r
647 );\r
648 ASSERT_EFI_ERROR(Status);\r
649 Status = Variable->GetVariable (\r
650 Variable,\r
651 L"Setup",\r
652 &gEfiSetupVariableGuid,\r
653 NULL,\r
654 &VariableSize,\r
655 &SystemConfiguration\r
656 );\r
657 ASSERT_EFI_ERROR(Status);\r
658 if (EFI_ERROR (Status)) {\r
659 GGC = ((2 << 3) | 0x200);\r
660 PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC);\r
661 GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50);\r
662 DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC & (BIT7|BIT6|BIT5|BIT4|BIT3))>>3));\r
663 } else {\r
664 if (SystemConfiguration.Igd == 1 && SystemConfiguration.PrimaryVideoAdaptor != 2) {\r
665 GGC = (SystemConfiguration.IgdDvmt50PreAlloc << 3) |\r
666 (SystemConfiguration.GTTSize == GTT_SIZE_1MB ? 0x100: 0x200);\r
667 PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC);\r
668 GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50);\r
669 DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC & (BIT7|BIT6|BIT5|BIT4|BIT3))>>3));\r
670 }\r
671 }\r
672\r
673 //\r
674 // Initialize PlatformInfo HOB\r
675 //\r
676 Status = ReadPlatformIds(PeiServices, &PlatformInfo);\r
677 ASSERT_EFI_ERROR (Status);\r
678\r
679 //\r
680 // 0 -> Disable , 1 -> Enable\r
681 //\r
682 if(SystemConfiguration.CfioPnpSettings == 1) {\r
683 DEBUG((EFI_D_INFO, "CheckCfioPnpSettings: CFIO Pnp Settings Enabled\n"));\r
684 PlatformInfo.CfioEnabled = 1;\r
685 } else {\r
686 DEBUG((EFI_D_INFO, "CheckCfioPnpSettings: CFIO Pnp Settings Disabled\n"));\r
687 PlatformInfo.CfioEnabled = 0;\r
688 }\r
689\r
690 //\r
691 // Build HOB for PlatformInfo\r
692 //\r
693 BuildGuidDataHob (\r
694 &gEfiPlatformInfoGuid,\r
695 &PlatformInfo,\r
696 sizeof (EFI_PLATFORM_INFO_HOB)\r
697 );\r
698\r
699\r
700 //\r
701 // Set the new boot mode for MRC\r
702 //\r
703#ifdef NOCS_S3_SUPPORT\r
704 Status = UpdateBootMode (PeiServices);\r
705 ASSERT_EFI_ERROR (Status);\r
706#endif\r
707\r
708 DEBUG((EFI_D_INFO, "Setup MMIO size ... \n\n"));\r
709\r
710 //\r
711 // Setup MMIO size\r
712 //\r
713 Status = (*PeiServices)->AllocatePool(\r
714 PeiServices,\r
715 sizeof (EFI_PEI_PPI_DESCRIPTOR),\r
716 (void **)&mVlvMmioPolicyPpiDesc\r
717 );\r
718 ASSERT_EFI_ERROR (Status);\r
719 Status = (*PeiServices)->AllocatePool(\r
720 PeiServices,\r
721 sizeof (VLV_MMIO_POLICY_PPI),\r
722 (void **)&mVlvMmioPolicyPpi\r
723 );\r
724 ASSERT_EFI_ERROR (Status);\r
725 (*PeiServices)->SetMem (\r
726 (VOID *)mVlvMmioPolicyPpi,\r
727 sizeof (VLV_MMIO_POLICY_PPI),\r
728 0\r
729 );\r
730 mVlvMmioPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;\r
731 mVlvMmioPolicyPpiDesc->Guid = &gVlvMmioPolicyPpiGuid;\r
732 mVlvMmioPolicyPpiDesc->Ppi = mVlvMmioPolicyPpi;\r
733 switch (SystemConfiguration.MmioSize) {\r
734 case 0: // 768MB\r
735 mVlvMmioPolicyPpi->MmioSize = 0x300;\r
736 break;\r
737 case 1: // 1GB\r
738 mVlvMmioPolicyPpi->MmioSize = 0x400;\r
739 break;\r
740 case 2: // 1.25GB\r
741 mVlvMmioPolicyPpi->MmioSize = 0x500;\r
742 break;\r
743 case 3: // 1.5GB\r
744 mVlvMmioPolicyPpi->MmioSize = 0x600;\r
745 break;\r
746 case 4: // 2GB\r
747 mVlvMmioPolicyPpi->MmioSize = 0x800;\r
748 break;\r
749 default:\r
750 mVlvMmioPolicyPpi->MmioSize = 0x800;\r
751 break;\r
752 }\r
753 Status = (*PeiServices)->InstallPpi(\r
754 PeiServices,\r
755 mVlvMmioPolicyPpiDesc\r
756 );\r
757 ASSERT_EFI_ERROR (Status);\r
758\r
759 return Status;\r
760}\r
761\r
762EFI_STATUS\r
763ReadPlatformIds (\r
764 IN CONST EFI_PEI_SERVICES **PeiServices,\r
765 IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob\r
766 )\r
767{\r
768 {\r
769 EFI_STATUS Status = EFI_SUCCESS;\r
770 UINT8 FabId = 0;\r
771 UINTN DataSize;\r
772 EFI_PLATFORM_INFO_HOB TmpHob;\r
773 EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiVar;\r
774\r
775 Status = (**PeiServices).LocatePpi (\r
776 PeiServices,\r
777 &gEfiPeiReadOnlyVariable2PpiGuid,\r
778 0,\r
779 NULL,\r
780 (void **)&PeiVar\r
781 );\r
782 ASSERT_EFI_ERROR (Status);\r
783\r
784 DataSize = sizeof (EFI_PLATFORM_INFO_HOB);\r
785 Status = PeiVar->GetVariable (\r
786 PeiVar,\r
787 L"PlatformInfo",\r
788 &gEfiVlv2VariableGuid,\r
789 NULL,\r
790 &DataSize,\r
791 &TmpHob\r
792 );\r
793\r
794 if (Status == EFI_SUCCESS) {\r
795 PlatformInfoHob->BoardId = TmpHob.BoardId;\r
796 PlatformInfoHob->MemCfgID = TmpHob.MemCfgID;\r
797 PlatformInfoHob->BoardRev = TmpHob.BoardRev;\r
798 PlatformInfoHob->PlatformFlavor = TmpHob.PlatformFlavor;\r
799 return Status;\r
800 }\r
801\r
802\r
803 PlatformInfoHob->BoardId = BOARD_ID_MINNOW2;\r
804 DEBUG ((EFI_D_INFO, "I'm Minnow2!\n"));\r
805\r
806 PlatformInfoHob->MemCfgID = 0;\r
807 PlatformInfoHob->BoardRev = FabId + 1; // FabId = 0 means FAB1 (BoardRev = 1), FabId = 1 means FAB2 (BoardRev = 2)...\r
808 PlatformInfoHob->PlatformFlavor = FlavorMobile;\r
809 }\r
810\r
811 return EFI_SUCCESS;\r
812}\r
813\r
814//\r
815// Start::Alpine Valley platform\r
816//\r
817/**\r
818 This routine reads SysCtl registers\r
819\r
820 @param SmbusBase SMBUS Base Address\r
821 @param SlvAddr Targeted Smbus Slave device address\r
822 @param Operation Which SMBus protocol will be used\r
823 @param Offset Offset of the register\r
824 @param Length Number of bytes\r
825 @param Buffer Buffer contains values read from registers\r
826\r
827 @retval SUCCESS as passed\r
828 @retval Others as failed\r
829\r
830**/\r
831EFI_STATUS\r
832PeiSmbusExec (\r
833 UINT16 SmbusBase,\r
834 UINT8 SlvAddr,\r
835 UINT8 Operation,\r
836 UINT8 Offset,\r
837 UINT8 *Length,\r
838 UINT8 *Buffer\r
839 )\r
840{\r
841 EFI_STATUS Status=EFI_SUCCESS;\r
842 UINT8 AuxcReg;\r
843 UINT8 SmbusOperation = 0;\r
844 UINT8 StsReg;\r
845 UINT8 SlvAddrReg;\r
846 UINT8 HostCmdReg;\r
847 UINT8 BlockCount = 0;\r
848 BOOLEAN BufferTooSmall;\r
849 UINT8 Index;\r
850 UINT8 *CallBuffer;\r
851 UINT8 RetryCount = BUS_TRIES;\r
852\r
853 //\r
854 // MrcSmbusExec supports byte and block read.\r
855 // Only allow Byte or block access\r
856 //\r
857 if (!((*Length == AV_SC_BYTE_LEN) || (*Length == AV_SC_BLOCK_LEN))) {\r
858 return EFI_INVALID_PARAMETER;\r
859 }\r
860\r
861 //\r
862 // See if its ok to use the bus based upon INUSE_STS bit.\r
863 //\r
864 Status = AcquireBus (SmbusBase);\r
865 ASSERT_EFI_ERROR(Status);\r
866\r
867 CallBuffer = Buffer;\r
868\r
869 //\r
870 //SmbStatus Bits of interest\r
871 //[6] = IUS (In Use Status)\r
872 //[4] = FAIL\r
873 //[3] = BERR (Bus Error = transaction collision)\r
874 //[2] = DERR (Device Error = Illegal Command Field, Unclaimed Cycle, Host Device Timeout, CRC Error)\r
875 //[1] = INTR (Successful completion of last command)\r
876 //[0] = HOST BUSY\r
877 //\r
878 //\r
879 // This is the main operation loop. If the operation results in a Smbus\r
880 // collision with another master on the bus, it attempts the requested\r
881 // transaction again at least BUS_TRIES attempts.\r
882 //\r
883 while (RetryCount--) {\r
884 //\r
885 // Operation Specifics (pre-execution)\r
886 //\r
887 Status = EFI_SUCCESS;\r
888 SlvAddrReg = SlvAddr;\r
889 HostCmdReg = Offset;\r
890 AuxcReg = 0;\r
891\r
892 switch (Operation) {\r
893\r
894 case SMBUS_WRITE_BYTE:\r
895 IoWrite8 (SmbusBase+R_PCH_SMBUS_HD0, CallBuffer[0]);\r
896 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA;\r
897 break;\r
898\r
899 case SMBUS_READ_BYTE:\r
900 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA;\r
901 SlvAddrReg |= B_PCH_SMBUS_RW_SEL_READ;\r
902 if (*Length < 1) {\r
903 Status = EFI_INVALID_PARAMETER;\r
904 }\r
905 *Length = 1;\r
906 break;\r
907\r
908 case SMBUS_WRITE_BLOCK:\r
909 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK;\r
910 IoWrite8 (SmbusBase+R_PCH_SMBUS_HD0, *(UINT8 *) Length);\r
911 BlockCount = (UINT8) (*Length);\r
912 if ((*Length < 1) || (*Length > 32)) {\r
913 Status = EFI_INVALID_PARAMETER;\r
914 break;\r
915 }\r
916 AuxcReg |= B_PCH_SMBUS_E32B;\r
917 break;\r
918\r
919 case SMBUS_READ_BLOCK:\r
920 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK;\r
921 SlvAddrReg |= B_PCH_SMBUS_RW_SEL_READ;\r
922 if ((*Length < 1) || (*Length > 32)) {\r
923 Status = EFI_INVALID_PARAMETER;\r
924 break;\r
925 }\r
926 AuxcReg |= B_PCH_SMBUS_E32B;\r
927 break;\r
928\r
929 default:\r
930 Status = EFI_INVALID_PARAMETER;\r
931 break;\r
932 }\r
933\r
934 //\r
935 // Set Auxiliary Control register\r
936 //\r
937 IoWrite8 (SmbusBase+R_PCH_SMBUS_AUXC, AuxcReg);\r
938\r
939 //\r
940 // Reset the pointer of the internal buffer\r
941 //\r
942 IoRead8 (SmbusBase+R_PCH_SMBUS_HCTL);\r
943\r
944 //\r
945 // Now that the 32 byte buffer is turned on, we can write th block data\r
946 // into it\r
947 //\r
948 if (Operation == SMBUS_WRITE_BLOCK) {\r
949 for (Index = 0; Index < BlockCount; Index++) {\r
950 //\r
951 // Write next byte\r
952 //\r
953 IoWrite8 (SmbusBase+R_PCH_SMBUS_HBD, CallBuffer[Index]);\r
954 }\r
955 }\r
956\r
957 //\r
958 // Set SMBus slave address for the device to read\r
959 //\r
960 IoWrite8(SmbusBase+R_PCH_SMBUS_TSA, SlvAddrReg);\r
961\r
962 //\r
963 //\r
964 // Set Command register for the offset to read\r
965 //\r
966 IoWrite8(SmbusBase+R_PCH_SMBUS_HCMD, HostCmdReg );\r
967\r
968 //\r
969 // Set Control Register to Set "operation command" protocol and start bit\r
970 //\r
971 IoWrite8(SmbusBase+R_PCH_SMBUS_HCTL, (UINT8) (SmbusOperation + B_PCH_SMBUS_START));\r
972\r
973 //\r
974 // Wait for IO to complete\r
975 //\r
976 do { StsReg = (UINT8) IoRead8(SmbusBase+0); } while ((StsReg & (BIT4|BIT3|BIT2|BIT1)) == 0);\r
977\r
978 if (StsReg & B_PCH_SMBUS_DERR) {\r
979 Status = EFI_DEVICE_ERROR;\r
980 break;\r
981 } else if (StsReg & B_PCH_SMBUS_BERR) {\r
982 //\r
983 // Clear the Bus Error for another try\r
984 //\r
985 Status = EFI_DEVICE_ERROR;\r
986 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);\r
987\r
988 //\r
989 // Clear Status Registers\r
990 //\r
991 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);\r
992 IoWrite8(SmbusBase+R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);\r
993\r
994 continue;\r
995 }\r
996\r
997 //\r
998 // successfull completion\r
999 // Operation Specifics (post-execution)\r
1000 //\r
1001 switch (Operation) {\r
1002\r
1003 case SMBUS_READ_BYTE:\r
1004 CallBuffer[0] = (UINT8)(IoRead8 (SmbusBase+R_PCH_SMBUS_HD0));\r
1005 break;\r
1006\r
1007 case SMBUS_WRITE_BLOCK:\r
1008 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BYTE_DONE_STS);\r
1009 break;\r
1010\r
1011 case SMBUS_READ_BLOCK:\r
1012 BufferTooSmall = FALSE;\r
1013\r
1014 //\r
1015 // Find out how many bytes will be in the block\r
1016 //\r
1017 BlockCount = (UINT8)(IoRead8 (SmbusBase+R_PCH_SMBUS_HD0));\r
1018 if (*Length < BlockCount) {\r
1019 BufferTooSmall = TRUE;\r
1020 } else {\r
1021 for (Index = 0; Index < BlockCount; Index++) {\r
1022 //\r
1023 // Read the byte\r
1024 //\r
1025 CallBuffer[Index] = (UINT8)IoRead8 (SmbusBase+R_PCH_SMBUS_HBD);\r
1026 }\r
1027 }\r
1028\r
1029 *Length = BlockCount;\r
1030 if (BufferTooSmall) {\r
1031 Status = EFI_BUFFER_TOO_SMALL;\r
1032 }\r
1033 break;\r
1034\r
1035 default:\r
1036 break;\r
1037 };\r
1038\r
1039 if ((StsReg & B_PCH_SMBUS_BERR) && (Status == EFI_SUCCESS)) {\r
1040 //\r
1041 // Clear the Bus Error for another try\r
1042 //\r
1043 Status = EFI_DEVICE_ERROR;\r
1044 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);\r
1045\r
1046 continue;\r
1047 } else {\r
1048 break;\r
1049 }\r
1050 }\r
1051\r
1052 //\r
1053 // Clear Status Registers and exit\r
1054 //\r
1055 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);\r
1056 IoWrite8(SmbusBase+R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);\r
1057 IoWrite8(SmbusBase+R_PCH_SMBUS_AUXC, 0);\r
1058 return Status;\r
1059}\r
1060//\r
1061// End::Alpine Valley platform\r
1062//\r
1063\r