3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
14 #include "CommonHeader.h"
17 #include <Library/PciCf8Lib.h>
18 #include "PlatformBaseAddresses.h"
19 #include "PchAccess.h"
20 #include <Guid/PlatformInfo.h>
21 #include "PchCommonDefinitions.h"
22 #include <Ppi/MfgMemoryTest.h>
23 #include <Guid/SetupVariable.h>
24 #include <Guid/Vlv2Variable.h>
25 #include <Ppi/fTPMPolicy.h>
28 // Start::Alpine Valley platform
37 #define EC_BASE 0xE0000000
40 // DEVICE 0 (Memroy Controller Hub)
45 #define MC_DEV_FUN (MC_DEV << 3)
46 #define MC_BUS_DEV_FUN ((MC_BUS << 8) + MC_DEV_FUN)
49 // SysCtl SMBus address and block size
51 #define AV_SC_SMBUS_ADDRESS 0x60
52 #define AV_SC_BYTE_LEN 1
53 #define AV_SC_BLOCK_LEN 4
54 #define AV_SC_SMBUS_WRCMD 1
55 #define AV_SC_SMBUS_RDCMD 0
58 // SysCtl registers offset
60 #define AV_SC_REG_PLATFORM_ID 24 // 0x18
61 #define AV_SC_REG_BOARD_ID 28 // 0x1C
62 #define AV_SC_REG_FAB_ID 32 // 0x20
63 #define AV_SC_REG_ECO_ID 68 // 0x44
64 #define AV_SC_REG_DDR_DAUGHTER_CARD_ID 144 // 0x90
65 #define AV_SC_REG_SODIMM_CONFIG 36
70 #define AV_SC_PLATFORM_ID_TABLET 0
71 #define AV_SC_PLATFORM_ID_NETBOOK 2
72 #define AV_SC_PLATFORM_ID_INTERPOSER 3 // Configuration TBD
73 #define AV_SC_BOARD_ID_AV_SVP 1492
75 #define BUS_TRIES 3 // How many times to retry on Bus Errors
77 #define GTT_SIZE_1MB 1
78 #define GTT_SIZE_2MB 2
80 #define PciCfg16Read( PciExpressBase, Bus, Device, Function, Register ) \
81 MmioRead16(PciExpressBase + \
82 (UINTN)(Bus << 20) + \
83 (UINTN)(Device << 15) + \
84 (UINTN)(Function << 12) + \
86 #define PciCfg16Write( PciExpressBase, Bus, Device, Function, Register, Data ) \
87 MmioWrite16(PciExpressBase + \
88 (UINTN)(Bus << 20) + \
89 (UINTN)(Device << 15) + \
90 (UINTN)(Function << 12) + \
96 //Memory Test Manufacturing mode
98 UINT32 DataPatternForMemoryTest
[] = {
99 0x55555555, 0xAAAAAAAA, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF,
100 0x55555555, 0xAAAAAAAA, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55,
101 0x55555555, 0xAAAAAAAA, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555,
102 0x55555555, 0xAAAAAAAA, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555
104 #define DATA_PATTERN_ARRAY_SIZE (sizeof(DataPatternForMemoryTest) / sizeof(UINT32))
107 //Memory Test Manufacturing mode
110 // The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory
112 BOOLEAN ImageInMemory
= FALSE
;
117 IN CONST EFI_PEI_SERVICES
**PeiServices
,
118 IN CONST EFI_PEI_STALL_PPI
*This
,
119 IN UINTN Microseconds
125 IN CONST EFI_PEI_SERVICES
**PeiServices
,
126 IN PEI_MFG_MEMORY_TEST_PPI
*This
,
127 IN UINT32 BeginAddress
,
128 IN UINT32 MemoryLength
131 static EFI_PEI_STALL_PPI mStallPpi
= {
132 PEI_STALL_RESOLUTION
,
136 static PEI_MFG_MEMORY_TEST_PPI mPeiMfgMemoryTestPpi
= {
140 static EFI_PEI_PPI_DESCRIPTOR mInstallStallPpi
[] = {
142 EFI_PEI_PPI_DESCRIPTOR_PPI
,
143 &gEfiPeiStallPpiGuid
,
147 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
148 &gPeiMfgMemoryTestPpiGuid
,
149 &mPeiMfgMemoryTestPpi
153 EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList
[1] = {
155 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
156 &gEfiPeiMemoryDiscoveredPpiGuid
,
157 MemoryDiscoveredPpiNotifyCallback
163 InstallMonoStatusCode (
164 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
165 IN CONST EFI_PEI_SERVICES
**PeiServices
171 IN CONST EFI_PEI_SERVICES
**PeiServices
,
172 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
176 // Start::Alpine Valley platform
191 Detemine Turbot board
192 @return 0: Not Turbot board
197 DetermineTurbotBoard (
201 UINTN PciD31F0RegBase
= 0;
202 UINT32 GpioValue
= 0;
204 UINT32 MmioConf0
= 0;
205 UINT32 MmioPadval
= 0;
206 UINT32 PConf0Offset
= 0x200; //GPIO_S5_4 pad_conf0 register offset
207 UINT32 PValueOffset
= 0x208; //GPIO_S5_4 pad_value register offset
208 UINT32 SSUSOffset
= 0x2000;
211 DEBUG ((EFI_D_ERROR
, "DetermineTurbotBoard() Entry\n"));
212 PciD31F0RegBase
= MmPciAddress (0,
214 PCI_DEVICE_NUMBER_PCH_LPC
,
215 PCI_FUNCTION_NUMBER_PCH_LPC
,
218 IoBase
= MmioRead32 (PciD31F0RegBase
+ R_PCH_LPC_IO_BASE
) & B_PCH_LPC_IO_BASE_BAR
;
220 MmioConf0
= IoBase
+ SSUSOffset
+ PConf0Offset
;
221 MmioPadval
= IoBase
+ SSUSOffset
+ PValueOffset
;
222 //0xFED0E200/0xFED0E208 is pad_Conf/pad_val register address of GPIO_S5_4
223 DEBUG ((EFI_D_ERROR
, "MmioConf0[0x%x], MmioPadval[0x%x]\n", MmioConf0
, MmioPadval
));
225 MmioWrite32 (MmioConf0
, 0x2003CC00);
227 TmpVal
= MmioRead32 (MmioPadval
);
228 TmpVal
&= ~0x6; //Clear bit 1:2
229 TmpVal
|= 0x2; // Set the pin as GPI
230 MmioWrite32 (MmioPadval
, TmpVal
);
232 GpioValue
= MmioRead32 (MmioPadval
);
234 DEBUG ((EFI_D_ERROR
, "Gpio_S5_4 value is 0x%x\n", GpioValue
));
235 return (GpioValue
& 0x1);
242 IN CONST EFI_PEI_SERVICES
**PeiServices
,
243 IN SYSTEM_CONFIGURATION
*pSystemConfiguration
247 EFI_PEI_PPI_DESCRIPTOR
*mFtpmPolicyPpiDesc
;
248 SEC_FTPM_POLICY_PPI
*mFtpmPolicyPpi
;
251 DEBUG((EFI_D_INFO
, "FtpmPolicyInit Entry \n"));
253 if (NULL
== PeiServices
|| NULL
== pSystemConfiguration
) {
254 DEBUG((EFI_D_ERROR
, "Input error. \n"));
255 return EFI_INVALID_PARAMETER
;
258 Status
= (*PeiServices
)->AllocatePool(
260 sizeof (EFI_PEI_PPI_DESCRIPTOR
),
261 (void **)&mFtpmPolicyPpiDesc
263 ASSERT_EFI_ERROR (Status
);
265 Status
= (*PeiServices
)->AllocatePool(
267 sizeof (SEC_FTPM_POLICY_PPI
),
268 (void **)&mFtpmPolicyPpi
270 ASSERT_EFI_ERROR (Status
);
275 (*PeiServices
)->SetMem ((VOID
*)mFtpmPolicyPpi
, sizeof (SEC_FTPM_POLICY_PPI
), 0);
276 mFtpmPolicyPpiDesc
->Flags
= EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
;
277 mFtpmPolicyPpiDesc
->Guid
= &gSeCfTPMPolicyPpiGuid
;
278 mFtpmPolicyPpiDesc
->Ppi
= mFtpmPolicyPpi
;
281 DEBUG((EFI_D_INFO
, "pSystemConfiguration->fTPM = 0x%x \n", pSystemConfiguration
->fTPM
));
282 if(pSystemConfiguration
->fTPM
== 1) {
283 mFtpmPolicyPpi
->fTPMEnable
= TRUE
;
285 mFtpmPolicyPpi
->fTPMEnable
= FALSE
;
288 Status
= (*PeiServices
)->InstallPpi(
292 ASSERT_EFI_ERROR (Status
);
294 DEBUG((EFI_D_INFO
, "FtpmPolicyInit done \n"));
301 This routine attempts to acquire the SMBus
303 @retval FAILURE as failed
304 @retval SUCCESS as passed
315 StsReg
= (UINT8
)IoRead8(SmbusBase
+ R_PCH_SMBUS_HSTS
);
316 if (StsReg
& B_PCH_SMBUS_IUS
) {
317 return EFI_DEVICE_ERROR
;
318 } else if (StsReg
& B_PCH_SMBUS_HBSY
) {
320 // Clear Status Register and exit
322 // Wait for HSTS.HBSY to be clear
324 do { StsReg
= (UINT8
) IoRead8(SmbusBase
+R_PCH_SMBUS_HSTS
); } while ((StsReg
& B_PCH_SMBUS_HBSY
) != 0);
327 // Clear all status bits
329 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, 0xFE);
333 // Clear out any odd status information (Will Not Clear In Use)
335 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, StsReg
);
340 // End::Alpine Valley platform
344 This function checks the memory range in PEI.
346 @param PeiServices Pointer to PEI Services.
347 @param This Pei memory test PPI pointer.
348 @param BeginAddress Beginning of the memory address to be checked.
349 @param MemoryLength Bytes of memory range to be checked.
350 @param Operation Type of memory check operation to be performed.
351 @param ErrorAddress Return the address of the error memory address.
353 @retval EFI_SUCCESS The operation completed successfully.
354 @retval EFI_DEVICE_ERROR Memory test failed. It's not safe to use this range of memory.
360 IN CONST EFI_PEI_SERVICES
**PeiServices
,
361 IN PEI_MFG_MEMORY_TEST_PPI
*This
,
362 IN UINT32 BeginAddress
,
363 IN UINT32 MemoryLength
371 memAddr
= BeginAddress
;
374 //Output Message for MFG
376 DEBUG ((EFI_D_ERROR
, "MFGMODE SET\n"));
379 //Writting the pattern in defined location.
381 while (memAddr
< (BeginAddress
+MemoryLength
)) {
382 for (i
= 0; i
< DATA_PATTERN_ARRAY_SIZE
; i
++) {
383 if (memAddr
> (BeginAddress
+MemoryLength
-4)) {
384 memAddr
= memAddr
+ 4;
387 *((volatile UINT32
*) memAddr
) = DataPatternForMemoryTest
[i
];
388 memAddr
= memAddr
+ 4;
393 //Verify the pattern.
395 memAddr
= BeginAddress
;
396 while (memAddr
< (BeginAddress
+MemoryLength
)) {
397 for (i
= 0; i
< DATA_PATTERN_ARRAY_SIZE
; i
++) {
398 if (memAddr
> (BeginAddress
+MemoryLength
-4)) {
399 memAddr
= memAddr
+ 4;
402 readData
= *((volatile UINT32
*) memAddr
);
403 xorData
= readData
^ DataPatternForMemoryTest
[i
];
406 // If xorData is nonzero, this particular memAddr has a failure.
408 if (xorData
!= 0x00000000) {
409 DEBUG ((EFI_D_ERROR
, "Expected value....: %x\n", DataPatternForMemoryTest
[i
]));
410 DEBUG ((EFI_D_ERROR
, "ReadData value....: %x\n", readData
));
411 DEBUG ((EFI_D_ERROR
, "Pattern failure at....: %x\n", memAddr
));
414 memAddr
= memAddr
+ 4;
418 return EFI_DEVICE_ERROR
;
422 //Output Message for MFG
424 DEBUG ((EFI_D_ERROR
, "MFGMODE MEMORY TEST PASSED\n"));
430 IN CONST EFI_PEI_SERVICES
**PeiServices
434 EFI_PEI_STALL_PPI
*StallPpi
;
437 (**PeiServices
).LocatePpi (PeiServices
, &gEfiPeiStallPpiGuid
, 0, NULL
, (void **)&StallPpi
);
439 for (Count
= 0; Count
< 500; Count
++) { // Maximum waiting approximates to 1.5 seconds (= 3 msec * 500)
440 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERA
);
441 if ((IoRead8 (R_PCH_RTC_TARGET2
) & B_PCH_RTC_REGISTERA_UIP
) == 0) {
445 StallPpi
->Stall (PeiServices
, StallPpi
, 3000);
452 RtcPowerFailureHandler (
453 IN CONST EFI_PEI_SERVICES
**PeiServices
459 BOOLEAN RtcUipIsAlwaysSet
;
460 DataUint16
= MmioRead16 (PMC_BASE_ADDRESS
+ R_PCH_PMC_GEN_PMCON_1
);
461 RtcUipIsAlwaysSet
= IsRtcUipAlwaysSet (PeiServices
);
462 if ((DataUint16
& B_PCH_PMC_GEN_PMCON_RTC_PWR_STS
) || (RtcUipIsAlwaysSet
)) {
464 // Execute the sequence below. This will ensure that the RTC state machine has been initialized.
467 // BIOS clears this bit by writing a '0' to it.
469 if (DataUint16
& B_PCH_PMC_GEN_PMCON_RTC_PWR_STS
) {
471 // Set to invalid date in order to reset the time to
472 // BIOS build time later in the boot (SBRUN.c file).
474 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_YEAR
);
475 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
476 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_MONTH
);
477 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
478 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_DAYOFMONTH
);
479 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
480 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_DAYOFWEEK
);
481 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
483 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_SECONDSALARM
);
484 IoWrite8 (R_PCH_RTC_TARGET2
, 0x00);
485 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_MINUTESALARM
);
486 IoWrite8 (R_PCH_RTC_TARGET2
, 0x00);
487 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_HOURSALARM
);
488 IoWrite8 (R_PCH_RTC_TARGET2
, 0x00);
493 // Set RTC Register 0Ah[6:4] to '110' or '111'.
495 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERA
);
496 IoWrite8 (R_PCH_RTC_TARGET2
, (V_PCH_RTC_REGISTERA_DV_DIV_RST1
| V_PCH_RTC_REGISTERA_RS_976P5US
));
500 // Set RTC Register 0Bh[7].
502 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
503 DataUint8
= (IoRead8 (R_PCH_RTC_TARGET2
) | B_PCH_RTC_REGISTERB_SET
);
504 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
505 IoWrite8 (R_PCH_RTC_TARGET2
, DataUint8
);
509 // Set RTC Register 0Ah[6:4] to '010'.
511 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERA
);
512 IoWrite8 (R_PCH_RTC_TARGET2
, (V_PCH_RTC_REGISTERA_DV_NORM_OP
| V_PCH_RTC_REGISTERA_RS_976P5US
));
516 // Clear RTC Register 0Bh[7].
518 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
519 DataUint8
= (IoRead8 (R_PCH_RTC_TARGET2
) & (UINT8
)~B_PCH_RTC_REGISTERB_SET
);
520 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
521 IoWrite8 (R_PCH_RTC_TARGET2
, DataUint8
);
534 // Program ACPI Power Management I/O Space Base Address
538 DEFAULT_PCI_BUS_NUMBER_PCH
,
539 PCI_DEVICE_NUMBER_PCH_LPC
,
540 PCI_FUNCTION_NUMBER_PCH_LPC
,
543 (UINT16
)((ACPI_BASE_ADDRESS
& B_PCH_LPC_ACPI_BASE_BAR
) | B_PCH_LPC_ACPI_BASE_EN
)
547 // Program GPIO Base Address
551 DEFAULT_PCI_BUS_NUMBER_PCH
,
552 PCI_DEVICE_NUMBER_PCH_LPC
,
553 PCI_FUNCTION_NUMBER_PCH_LPC
,
556 (UINT16
)((GPIO_BASE_ADDRESS
& B_PCH_LPC_GPIO_BASE_BAR
) | B_PCH_LPC_GPIO_BASE_EN
)
560 // Set PMC Base Address
564 DEFAULT_PCI_BUS_NUMBER_PCH
,
565 PCI_DEVICE_NUMBER_PCH_LPC
,
566 PCI_FUNCTION_NUMBER_PCH_LPC
,
569 (UINT32
)((PMC_BASE_ADDRESS
& B_PCH_LPC_PMC_BASE_BAR
) | B_PCH_LPC_PMC_BASE_EN
)
573 // Set IO Base Address
577 DEFAULT_PCI_BUS_NUMBER_PCH
,
578 PCI_DEVICE_NUMBER_PCH_LPC
,
579 PCI_FUNCTION_NUMBER_PCH_LPC
,
582 (UINT32
)((IO_BASE_ADDRESS
& B_PCH_LPC_IO_BASE_BAR
) | B_PCH_LPC_IO_BASE_EN
)
586 // Set ILB Base Address
590 DEFAULT_PCI_BUS_NUMBER_PCH
,
591 PCI_DEVICE_NUMBER_PCH_LPC
,
592 PCI_FUNCTION_NUMBER_PCH_LPC
,
595 (UINT32
)((ILB_BASE_ADDRESS
& B_PCH_LPC_ILB_BASE_BAR
) | B_PCH_LPC_ILB_BASE_EN
)
599 // Set PUnit Base Address
603 DEFAULT_PCI_BUS_NUMBER_PCH
,
604 PCI_DEVICE_NUMBER_PCH_LPC
,
605 PCI_FUNCTION_NUMBER_PCH_LPC
,
608 (UINT32
)((PUNIT_BASE_ADDRESS
& B_PCH_LPC_PUNIT_BASE_BAR
) | B_PCH_LPC_PUNIT_BASE_EN
)
612 // Set SPI Base Address
616 DEFAULT_PCI_BUS_NUMBER_PCH
,
617 PCI_DEVICE_NUMBER_PCH_LPC
,
618 PCI_FUNCTION_NUMBER_PCH_LPC
,
621 (UINT32
)((SPI_BASE_ADDRESS
& B_PCH_LPC_SPI_BASE_BAR
) | B_PCH_LPC_SPI_BASE_EN
)
625 // Set Root Complex Base Address
629 DEFAULT_PCI_BUS_NUMBER_PCH
,
630 PCI_DEVICE_NUMBER_PCH_LPC
,
631 PCI_FUNCTION_NUMBER_PCH_LPC
,
634 (UINT32
)((RCBA_BASE_ADDRESS
& B_PCH_LPC_RCBA_BAR
) | B_PCH_LPC_RCBA_EN
)
638 // Set MPHY Base Address
642 DEFAULT_PCI_BUS_NUMBER_PCH
,
643 PCI_DEVICE_NUMBER_PCH_LPC
,
644 PCI_FUNCTION_NUMBER_PCH_LPC
,
647 (UINT32
)((MPHY_BASE_ADDRESS
& B_PCH_LPC_MPHY_BASE_BAR
) | B_PCH_LPC_MPHY_BASE_EN
)
651 DEFAULT_PCI_BUS_NUMBER_PCH
,
652 PCI_DEVICE_NUMBER_PCH_SMBUS
,
653 PCI_FUNCTION_NUMBER_PCH_SMBUS
,
656 (UINT16
)(SMBUS_BASE_ADDRESS
& B_PCH_SMBUS_BASE_BAR
)
661 DEFAULT_PCI_BUS_NUMBER_PCH
,
662 PCI_DEVICE_NUMBER_PCH_SMBUS
,
663 PCI_FUNCTION_NUMBER_PCH_SMBUS
,
666 B_PCH_SMBUS_PCICMD_IOSE
672 This is the entrypoint of PEIM
674 @param FileHandle Handle of the file being invoked.
675 @param PeiServices Describes the list of possible PEI Services.
677 @retval EFI_SUCCESS if it completed successfully.
682 IN EFI_PEI_FILE_HANDLE FileHandle
,
683 IN CONST EFI_PEI_SERVICES
**PeiServices
687 EFI_PLATFORM_INFO_HOB PlatformInfo
;
688 EFI_STATUS Status
= EFI_SUCCESS
;
689 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*Variable
= NULL
;
691 SYSTEM_CONFIGURATION SystemConfiguration
;
694 EFI_PEI_PPI_DESCRIPTOR
*mVlvMmioPolicyPpiDesc
;
695 VLV_MMIO_POLICY_PPI
*mVlvMmioPolicyPpi
;
697 ZeroMem (&PlatformInfo
, sizeof(PlatformInfo
));
699 Status
= InstallMonoStatusCode(FileHandle
, PeiServices
);
700 ASSERT_EFI_ERROR (Status
);
704 // Initialize Stall PPIs
706 Status
= (*PeiServices
)->InstallPpi (PeiServices
, &mInstallStallPpi
[0]);
707 ASSERT_EFI_ERROR (Status
);
709 Status
= (*PeiServices
)->NotifyPpi (PeiServices
, &mMemoryDiscoveredNotifyList
[0]);
710 ASSERT_EFI_ERROR (Status
);
711 SmbusRegBase
= PchPciDeviceMmBase (
712 DEFAULT_PCI_BUS_NUMBER_PCH
,
713 PCI_DEVICE_NUMBER_PCH_SMBUS
,
714 PCI_FUNCTION_NUMBER_PCH_SMBUS
717 // Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves
719 MmioAndThenOr32 (SmbusRegBase
+ R_PCH_SMBUS_BASE
, B_PCH_SMBUS_BASE_BAR
, SMBUS_BASE_ADDRESS
);
721 MmioOr8 (SmbusRegBase
+ R_PCH_SMBUS_PCICMD
, B_PCH_SMBUS_PCICMD_IOSE
);
726 //Todo: confirm if we need program 8254
729 // Program timer 1 as refresh timer
731 IoWrite8 (0x43, 0x54);
732 IoWrite8 (0x41, 0x12);
735 // RTC power failure handling
737 RtcPowerFailureHandler (PeiServices
);
740 PchMmPci32( 0, 0, 2, 0, 0x50) = 0x210;
742 VariableSize
= sizeof (SYSTEM_CONFIGURATION
);
743 ZeroMem (&SystemConfiguration
, VariableSize
);
746 // Obtain variable services
748 Status
= (*PeiServices
)->LocatePpi(
750 &gEfiPeiReadOnlyVariable2PpiGuid
,
755 ASSERT_EFI_ERROR(Status
);
756 Status
= Variable
->GetVariable (
759 &gEfiSetupVariableGuid
,
764 if (EFI_ERROR (Status
) || VariableSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
765 //The setup variable is corrupted
766 VariableSize
= sizeof(SYSTEM_CONFIGURATION
);
767 Status
= Variable
->GetVariable(
770 &gEfiSetupVariableGuid
,
775 ASSERT_EFI_ERROR (Status
);
778 if (EFI_ERROR (Status
)) {
779 GGC
= ((2 << 3) | 0x200);
780 PciCfg16Write(EC_BASE
, 0, 2, 0, 0x50, GGC
);
781 GGC
= PciCfg16Read(EC_BASE
, 0, 2, 0, 0x50);
782 DEBUG((EFI_D_INFO
, "GGC: 0x%08x GMSsize:0x%08x\n", GGC
, (GGC
& (BIT7
|BIT6
|BIT5
|BIT4
|BIT3
))>>3));
784 if (SystemConfiguration
.Igd
== 1 && SystemConfiguration
.PrimaryVideoAdaptor
!= 2) {
785 GGC
= (SystemConfiguration
.IgdDvmt50PreAlloc
<< 3) |
786 (SystemConfiguration
.GTTSize
== GTT_SIZE_1MB
? 0x100: 0x200);
787 PciCfg16Write(EC_BASE
, 0, 2, 0, 0x50, GGC
);
788 GGC
= PciCfg16Read(EC_BASE
, 0, 2, 0, 0x50);
789 DEBUG((EFI_D_INFO
, "GGC: 0x%08x GMSsize:0x%08x\n", GGC
, (GGC
& (BIT7
|BIT6
|BIT5
|BIT4
|BIT3
))>>3));
794 // Initialize PlatformInfo HOB
796 Status
= ReadPlatformIds(PeiServices
, &PlatformInfo
);
797 ASSERT_EFI_ERROR (Status
);
800 // 0 -> Disable , 1 -> Enable
802 if(SystemConfiguration
.CfioPnpSettings
== 1) {
803 DEBUG((EFI_D_INFO
, "CheckCfioPnpSettings: CFIO Pnp Settings Enabled\n"));
804 PlatformInfo
.CfioEnabled
= 1;
806 DEBUG((EFI_D_INFO
, "CheckCfioPnpSettings: CFIO Pnp Settings Disabled\n"));
807 PlatformInfo
.CfioEnabled
= 0;
811 // Build HOB for PlatformInfo
814 &gEfiPlatformInfoGuid
,
816 sizeof (EFI_PLATFORM_INFO_HOB
)
821 Status
= FtpmPolicyInit(PeiServices
, &SystemConfiguration
);
822 if (EFI_ERROR (Status
)) {
823 DEBUG((EFI_D_ERROR
, "fTPM init failed.\n"));
829 // Set the new boot mode for MRC
831 #ifdef NOCS_S3_SUPPORT
832 Status
= UpdateBootMode (PeiServices
);
833 ASSERT_EFI_ERROR (Status
);
836 DEBUG((EFI_D_INFO
, "Setup MMIO size ... \n\n"));
841 Status
= (*PeiServices
)->AllocatePool(
843 sizeof (EFI_PEI_PPI_DESCRIPTOR
),
844 (void **)&mVlvMmioPolicyPpiDesc
846 ASSERT_EFI_ERROR (Status
);
847 Status
= (*PeiServices
)->AllocatePool(
849 sizeof (VLV_MMIO_POLICY_PPI
),
850 (void **)&mVlvMmioPolicyPpi
852 ASSERT_EFI_ERROR (Status
);
853 (*PeiServices
)->SetMem (
854 (VOID
*)mVlvMmioPolicyPpi
,
855 sizeof (VLV_MMIO_POLICY_PPI
),
858 mVlvMmioPolicyPpiDesc
->Flags
= EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
;
859 mVlvMmioPolicyPpiDesc
->Guid
= &gVlvMmioPolicyPpiGuid
;
860 mVlvMmioPolicyPpiDesc
->Ppi
= mVlvMmioPolicyPpi
;
861 switch (SystemConfiguration
.MmioSize
) {
863 mVlvMmioPolicyPpi
->MmioSize
= 0x300;
866 mVlvMmioPolicyPpi
->MmioSize
= 0x400;
869 mVlvMmioPolicyPpi
->MmioSize
= 0x500;
872 mVlvMmioPolicyPpi
->MmioSize
= 0x600;
875 mVlvMmioPolicyPpi
->MmioSize
= 0x800;
878 mVlvMmioPolicyPpi
->MmioSize
= 0x800;
881 Status
= (*PeiServices
)->InstallPpi(
883 mVlvMmioPolicyPpiDesc
885 ASSERT_EFI_ERROR (Status
);
892 IN CONST EFI_PEI_SERVICES
**PeiServices
,
893 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
897 EFI_STATUS Status
= EFI_SUCCESS
;
900 EFI_PLATFORM_INFO_HOB TmpHob
;
901 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*PeiVar
;
902 UINT32 CompatibleBoard
= 0;
904 Status
= (**PeiServices
).LocatePpi (
906 &gEfiPeiReadOnlyVariable2PpiGuid
,
911 ASSERT_EFI_ERROR (Status
);
913 DataSize
= sizeof (EFI_PLATFORM_INFO_HOB
);
914 Status
= PeiVar
->GetVariable (
917 &gEfiVlv2VariableGuid
,
923 if (Status
== EFI_SUCCESS
) {
924 PlatformInfoHob
->BoardId
= TmpHob
.BoardId
;
925 PlatformInfoHob
->MemCfgID
= TmpHob
.MemCfgID
;
926 PlatformInfoHob
->BoardRev
= TmpHob
.BoardRev
;
927 PlatformInfoHob
->PlatformFlavor
= TmpHob
.PlatformFlavor
;
931 CompatibleBoard
= DetermineTurbotBoard();
932 if (1 == CompatibleBoard
) {
933 PlatformInfoHob
->BoardId
= BOARD_ID_MINNOW2_TURBOT
;
934 DEBUG ((EFI_D_INFO
, "I'm MinnowBoard Turbot!\n"));
936 PlatformInfoHob
->BoardId
= BOARD_ID_MINNOW2
;
937 DEBUG ((EFI_D_INFO
, "I'm MinnowBoard Max!\n"));
941 PlatformInfoHob
->MemCfgID
= 0;
942 PlatformInfoHob
->BoardRev
= FabId
+ 1; // FabId = 0 means FAB1 (BoardRev = 1), FabId = 1 means FAB2 (BoardRev = 2)...
943 PlatformInfoHob
->PlatformFlavor
= FlavorMobile
;
950 // Start::Alpine Valley platform
953 This routine reads SysCtl registers
955 @param SmbusBase SMBUS Base Address
956 @param SlvAddr Targeted Smbus Slave device address
957 @param Operation Which SMBus protocol will be used
958 @param Offset Offset of the register
959 @param Length Number of bytes
960 @param Buffer Buffer contains values read from registers
962 @retval SUCCESS as passed
963 @retval Others as failed
976 EFI_STATUS Status
=EFI_SUCCESS
;
978 UINT8 SmbusOperation
= 0;
982 UINT8 BlockCount
= 0;
983 BOOLEAN BufferTooSmall
;
986 UINT8 RetryCount
= BUS_TRIES
;
989 // MrcSmbusExec supports byte and block read.
990 // Only allow Byte or block access
992 if (!((*Length
== AV_SC_BYTE_LEN
) || (*Length
== AV_SC_BLOCK_LEN
))) {
993 return EFI_INVALID_PARAMETER
;
997 // See if its ok to use the bus based upon INUSE_STS bit.
999 Status
= AcquireBus (SmbusBase
);
1000 ASSERT_EFI_ERROR(Status
);
1002 CallBuffer
= Buffer
;
1005 //SmbStatus Bits of interest
1006 //[6] = IUS (In Use Status)
1008 //[3] = BERR (Bus Error = transaction collision)
1009 //[2] = DERR (Device Error = Illegal Command Field, Unclaimed Cycle, Host Device Timeout, CRC Error)
1010 //[1] = INTR (Successful completion of last command)
1014 // This is the main operation loop. If the operation results in a Smbus
1015 // collision with another master on the bus, it attempts the requested
1016 // transaction again at least BUS_TRIES attempts.
1018 while (RetryCount
--) {
1020 // Operation Specifics (pre-execution)
1022 Status
= EFI_SUCCESS
;
1023 SlvAddrReg
= SlvAddr
;
1024 HostCmdReg
= Offset
;
1027 switch (Operation
) {
1029 case SMBUS_WRITE_BYTE
:
1030 IoWrite8 (SmbusBase
+R_PCH_SMBUS_HD0
, CallBuffer
[0]);
1031 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BYTE_DATA
;
1034 case SMBUS_READ_BYTE
:
1035 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BYTE_DATA
;
1036 SlvAddrReg
|= B_PCH_SMBUS_RW_SEL_READ
;
1038 Status
= EFI_INVALID_PARAMETER
;
1043 case SMBUS_WRITE_BLOCK
:
1044 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BLOCK
;
1045 IoWrite8 (SmbusBase
+R_PCH_SMBUS_HD0
, *(UINT8
*) Length
);
1046 BlockCount
= (UINT8
) (*Length
);
1047 if ((*Length
< 1) || (*Length
> 32)) {
1048 Status
= EFI_INVALID_PARAMETER
;
1051 AuxcReg
|= B_PCH_SMBUS_E32B
;
1054 case SMBUS_READ_BLOCK
:
1055 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BLOCK
;
1056 SlvAddrReg
|= B_PCH_SMBUS_RW_SEL_READ
;
1057 if ((*Length
< 1) || (*Length
> 32)) {
1058 Status
= EFI_INVALID_PARAMETER
;
1061 AuxcReg
|= B_PCH_SMBUS_E32B
;
1065 Status
= EFI_INVALID_PARAMETER
;
1070 // Set Auxiliary Control register
1072 IoWrite8 (SmbusBase
+R_PCH_SMBUS_AUXC
, AuxcReg
);
1075 // Reset the pointer of the internal buffer
1077 IoRead8 (SmbusBase
+R_PCH_SMBUS_HCTL
);
1080 // Now that the 32 byte buffer is turned on, we can write th block data
1083 if (Operation
== SMBUS_WRITE_BLOCK
) {
1084 for (Index
= 0; Index
< BlockCount
; Index
++) {
1088 IoWrite8 (SmbusBase
+R_PCH_SMBUS_HBD
, CallBuffer
[Index
]);
1093 // Set SMBus slave address for the device to read
1095 IoWrite8(SmbusBase
+R_PCH_SMBUS_TSA
, SlvAddrReg
);
1099 // Set Command register for the offset to read
1101 IoWrite8(SmbusBase
+R_PCH_SMBUS_HCMD
, HostCmdReg
);
1104 // Set Control Register to Set "operation command" protocol and start bit
1106 IoWrite8(SmbusBase
+R_PCH_SMBUS_HCTL
, (UINT8
) (SmbusOperation
+ B_PCH_SMBUS_START
));
1109 // Wait for IO to complete
1111 do { StsReg
= (UINT8
) IoRead8(SmbusBase
+0); } while ((StsReg
& (BIT4
|BIT3
|BIT2
|BIT1
)) == 0);
1113 if (StsReg
& B_PCH_SMBUS_DERR
) {
1114 Status
= EFI_DEVICE_ERROR
;
1116 } else if (StsReg
& B_PCH_SMBUS_BERR
) {
1118 // Clear the Bus Error for another try
1120 Status
= EFI_DEVICE_ERROR
;
1121 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_BERR
);
1124 // Clear Status Registers
1126 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_HSTS_ALL
);
1127 IoWrite8(SmbusBase
+R_PCH_SMBUS_AUXS
, B_PCH_SMBUS_CRCE
);
1133 // successfull completion
1134 // Operation Specifics (post-execution)
1136 switch (Operation
) {
1138 case SMBUS_READ_BYTE
:
1139 CallBuffer
[0] = (UINT8
)(IoRead8 (SmbusBase
+R_PCH_SMBUS_HD0
));
1142 case SMBUS_WRITE_BLOCK
:
1143 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_BYTE_DONE_STS
);
1146 case SMBUS_READ_BLOCK
:
1147 BufferTooSmall
= FALSE
;
1150 // Find out how many bytes will be in the block
1152 BlockCount
= (UINT8
)(IoRead8 (SmbusBase
+R_PCH_SMBUS_HD0
));
1153 if (*Length
< BlockCount
) {
1154 BufferTooSmall
= TRUE
;
1156 for (Index
= 0; Index
< BlockCount
; Index
++) {
1160 CallBuffer
[Index
] = (UINT8
)IoRead8 (SmbusBase
+R_PCH_SMBUS_HBD
);
1164 *Length
= BlockCount
;
1165 if (BufferTooSmall
) {
1166 Status
= EFI_BUFFER_TOO_SMALL
;
1174 if ((StsReg
& B_PCH_SMBUS_BERR
) && (Status
== EFI_SUCCESS
)) {
1176 // Clear the Bus Error for another try
1178 Status
= EFI_DEVICE_ERROR
;
1179 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_BERR
);
1188 // Clear Status Registers and exit
1190 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_HSTS_ALL
);
1191 IoWrite8(SmbusBase
+R_PCH_SMBUS_AUXS
, B_PCH_SMBUS_CRCE
);
1192 IoWrite8(SmbusBase
+R_PCH_SMBUS_AUXC
, 0);
1196 // End::Alpine Valley platform