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