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