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