3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include "CommonHeader.h"
22 #include <Library/PciCf8Lib.h>
23 #include "PlatformBaseAddresses.h"
24 #include "PchAccess.h"
25 #include <Guid/PlatformInfo.h>
27 #include "PchCommonDefinitions.h"
28 #include <Ppi/MfgMemoryTest.h>
29 #include <Guid/SetupVariable.h>
30 #include <Guid/Vlv2Variable.h>
31 #include <Ppi/fTPMPolicy.h>
34 // Start::Alpine Valley platform
43 #define EC_BASE 0xE0000000
46 // DEVICE 0 (Memroy Controller Hub)
51 #define MC_DEV_FUN (MC_DEV << 3)
52 #define MC_BUS_DEV_FUN ((MC_BUS << 8) + MC_DEV_FUN)
55 // SysCtl SMBus address and block size
57 #define AV_SC_SMBUS_ADDRESS 0x60
58 #define AV_SC_BYTE_LEN 1
59 #define AV_SC_BLOCK_LEN 4
60 #define AV_SC_SMBUS_WRCMD 1
61 #define AV_SC_SMBUS_RDCMD 0
64 // SysCtl registers offset
66 #define AV_SC_REG_PLATFORM_ID 24 // 0x18
67 #define AV_SC_REG_BOARD_ID 28 // 0x1C
68 #define AV_SC_REG_FAB_ID 32 // 0x20
69 #define AV_SC_REG_ECO_ID 68 // 0x44
70 #define AV_SC_REG_DDR_DAUGHTER_CARD_ID 144 // 0x90
71 #define AV_SC_REG_SODIMM_CONFIG 36
76 #define AV_SC_PLATFORM_ID_TABLET 0
77 #define AV_SC_PLATFORM_ID_NETBOOK 2
78 #define AV_SC_PLATFORM_ID_INTERPOSER 3 // Configuration TBD
79 #define AV_SC_BOARD_ID_AV_SVP 1492
81 #define BUS_TRIES 3 // How many times to retry on Bus Errors
83 #define GTT_SIZE_1MB 1
84 #define GTT_SIZE_2MB 2
86 #define PciCfg16Read( PciExpressBase, Bus, Device, Function, Register ) \
87 MmioRead16(PciExpressBase + \
88 (UINTN)(Bus << 20) + \
89 (UINTN)(Device << 15) + \
90 (UINTN)(Function << 12) + \
92 #define PciCfg16Write( PciExpressBase, Bus, Device, Function, Register, Data ) \
93 MmioWrite16(PciExpressBase + \
94 (UINTN)(Bus << 20) + \
95 (UINTN)(Device << 15) + \
96 (UINTN)(Function << 12) + \
102 //Memory Test Manufacturing mode
104 UINT32 DataPatternForMemoryTest
[] = {
105 0x55555555, 0xAAAAAAAA, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF,
106 0x55555555, 0xAAAAAAAA, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55,
107 0x55555555, 0xAAAAAAAA, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555,
108 0x55555555, 0xAAAAAAAA, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555
110 #define DATA_PATTERN_ARRAY_SIZE (sizeof(DataPatternForMemoryTest) / sizeof(UINT32))
113 //Memory Test Manufacturing mode
116 // The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory
118 BOOLEAN ImageInMemory
= FALSE
;
123 IN CONST EFI_PEI_SERVICES
**PeiServices
,
124 IN CONST EFI_PEI_STALL_PPI
*This
,
125 IN UINTN Microseconds
131 IN CONST EFI_PEI_SERVICES
**PeiServices
,
132 IN PEI_MFG_MEMORY_TEST_PPI
*This
,
133 IN UINT32 BeginAddress
,
134 IN UINT32 MemoryLength
137 static EFI_PEI_STALL_PPI mStallPpi
= {
138 PEI_STALL_RESOLUTION
,
142 static PEI_MFG_MEMORY_TEST_PPI mPeiMfgMemoryTestPpi
= {
146 static EFI_PEI_PPI_DESCRIPTOR mInstallStallPpi
[] = {
148 EFI_PEI_PPI_DESCRIPTOR_PPI
,
149 &gEfiPeiStallPpiGuid
,
153 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
154 &gPeiMfgMemoryTestPpiGuid
,
155 &mPeiMfgMemoryTestPpi
159 EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList
[1] = {
161 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
162 &gEfiPeiMemoryDiscoveredPpiGuid
,
163 MemoryDiscoveredPpiNotifyCallback
169 InstallMonoStatusCode (
170 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
171 IN CONST EFI_PEI_SERVICES
**PeiServices
177 IN CONST EFI_PEI_SERVICES
**PeiServices
,
178 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
182 // Start::Alpine Valley platform
197 Detemine Turbot board
198 @return 0: Not Turbot board
203 DetermineTurbotBoard (
207 UINTN PciD31F0RegBase
= 0;
208 UINT32 GpioValue
= 0;
210 UINT32 MmioConf0
= 0;
211 UINT32 MmioPadval
= 0;
212 UINT32 PConf0Offset
= 0x200; //GPIO_S5_4 pad_conf0 register offset
213 UINT32 PValueOffset
= 0x208; //GPIO_S5_4 pad_value register offset
214 UINT32 SSUSOffset
= 0x2000;
217 DEBUG ((EFI_D_ERROR
, "DetermineTurbotBoard() Entry\n"));
218 PciD31F0RegBase
= MmPciAddress (0,
220 PCI_DEVICE_NUMBER_PCH_LPC
,
221 PCI_FUNCTION_NUMBER_PCH_LPC
,
224 IoBase
= MmioRead32 (PciD31F0RegBase
+ R_PCH_LPC_IO_BASE
) & B_PCH_LPC_IO_BASE_BAR
;
226 MmioConf0
= IoBase
+ SSUSOffset
+ PConf0Offset
;
227 MmioPadval
= IoBase
+ SSUSOffset
+ PValueOffset
;
228 //0xFED0E200/0xFED0E208 is pad_Conf/pad_val register address of GPIO_S5_4
229 DEBUG ((EFI_D_ERROR
, "MmioConf0[0x%x], MmioPadval[0x%x]\n", MmioConf0
, MmioPadval
));
231 MmioWrite32 (MmioConf0
, 0x2003CC00);
233 TmpVal
= MmioRead32 (MmioPadval
);
234 TmpVal
&= ~0x6; //Clear bit 1:2
235 TmpVal
|= 0x2; // Set the pin as GPI
236 MmioWrite32 (MmioPadval
, TmpVal
);
238 GpioValue
= MmioRead32 (MmioPadval
);
240 DEBUG ((EFI_D_ERROR
, "Gpio_S5_4 value is 0x%x\n", GpioValue
));
241 return (GpioValue
& 0x1);
248 IN CONST EFI_PEI_SERVICES
**PeiServices
,
249 IN SYSTEM_CONFIGURATION
*pSystemConfiguration
253 EFI_PEI_PPI_DESCRIPTOR
*mFtpmPolicyPpiDesc
;
254 SEC_FTPM_POLICY_PPI
*mFtpmPolicyPpi
;
257 DEBUG((EFI_D_INFO
, "FtpmPolicyInit Entry \n"));
259 if (NULL
== PeiServices
|| NULL
== pSystemConfiguration
) {
260 DEBUG((EFI_D_ERROR
, "Input error. \n"));
261 return EFI_INVALID_PARAMETER
;
264 Status
= (*PeiServices
)->AllocatePool(
266 sizeof (EFI_PEI_PPI_DESCRIPTOR
),
267 (void **)&mFtpmPolicyPpiDesc
269 ASSERT_EFI_ERROR (Status
);
271 Status
= (*PeiServices
)->AllocatePool(
273 sizeof (SEC_FTPM_POLICY_PPI
),
274 (void **)&mFtpmPolicyPpi
276 ASSERT_EFI_ERROR (Status
);
281 (*PeiServices
)->SetMem ((VOID
*)mFtpmPolicyPpi
, sizeof (SEC_FTPM_POLICY_PPI
), 0);
282 mFtpmPolicyPpiDesc
->Flags
= EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
;
283 mFtpmPolicyPpiDesc
->Guid
= &gSeCfTPMPolicyPpiGuid
;
284 mFtpmPolicyPpiDesc
->Ppi
= mFtpmPolicyPpi
;
287 DEBUG((EFI_D_INFO
, "pSystemConfiguration->fTPM = 0x%x \n", pSystemConfiguration
->fTPM
));
288 if(pSystemConfiguration
->fTPM
== 1) {
289 mFtpmPolicyPpi
->fTPMEnable
= TRUE
;
291 mFtpmPolicyPpi
->fTPMEnable
= FALSE
;
294 Status
= (*PeiServices
)->InstallPpi(
298 ASSERT_EFI_ERROR (Status
);
300 DEBUG((EFI_D_INFO
, "FtpmPolicyInit done \n"));
307 This routine attempts to acquire the SMBus
309 @retval FAILURE as failed
310 @retval SUCCESS as passed
321 StsReg
= (UINT8
)IoRead8(SmbusBase
+ R_PCH_SMBUS_HSTS
);
322 if (StsReg
& B_PCH_SMBUS_IUS
) {
323 return EFI_DEVICE_ERROR
;
324 } else if (StsReg
& B_PCH_SMBUS_HBSY
) {
326 // Clear Status Register and exit
328 // Wait for HSTS.HBSY to be clear
330 do { StsReg
= (UINT8
) IoRead8(SmbusBase
+R_PCH_SMBUS_HSTS
); } while ((StsReg
& B_PCH_SMBUS_HBSY
) != 0);
333 // Clear all status bits
335 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, 0xFE);
339 // Clear out any odd status information (Will Not Clear In Use)
341 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, StsReg
);
346 // End::Alpine Valley platform
350 This function checks the memory range in PEI.
352 @param PeiServices Pointer to PEI Services.
353 @param This Pei memory test PPI pointer.
354 @param BeginAddress Beginning of the memory address to be checked.
355 @param MemoryLength Bytes of memory range to be checked.
356 @param Operation Type of memory check operation to be performed.
357 @param ErrorAddress Return the address of the error memory address.
359 @retval EFI_SUCCESS The operation completed successfully.
360 @retval EFI_DEVICE_ERROR Memory test failed. It's not safe to use this range of memory.
366 IN CONST EFI_PEI_SERVICES
**PeiServices
,
367 IN PEI_MFG_MEMORY_TEST_PPI
*This
,
368 IN UINT32 BeginAddress
,
369 IN UINT32 MemoryLength
377 memAddr
= BeginAddress
;
380 //Output Message for MFG
382 DEBUG ((EFI_D_ERROR
, "MFGMODE SET\n"));
385 //Writting the pattern in defined location.
387 while (memAddr
< (BeginAddress
+MemoryLength
)) {
388 for (i
= 0; i
< DATA_PATTERN_ARRAY_SIZE
; i
++) {
389 if (memAddr
> (BeginAddress
+MemoryLength
-4)) {
390 memAddr
= memAddr
+ 4;
393 *((volatile UINT32
*) memAddr
) = DataPatternForMemoryTest
[i
];
394 memAddr
= memAddr
+ 4;
399 //Verify the pattern.
401 memAddr
= BeginAddress
;
402 while (memAddr
< (BeginAddress
+MemoryLength
)) {
403 for (i
= 0; i
< DATA_PATTERN_ARRAY_SIZE
; i
++) {
404 if (memAddr
> (BeginAddress
+MemoryLength
-4)) {
405 memAddr
= memAddr
+ 4;
408 readData
= *((volatile UINT32
*) memAddr
);
409 xorData
= readData
^ DataPatternForMemoryTest
[i
];
412 // If xorData is nonzero, this particular memAddr has a failure.
414 if (xorData
!= 0x00000000) {
415 DEBUG ((EFI_D_ERROR
, "Expected value....: %x\n", DataPatternForMemoryTest
[i
]));
416 DEBUG ((EFI_D_ERROR
, "ReadData value....: %x\n", readData
));
417 DEBUG ((EFI_D_ERROR
, "Pattern failure at....: %x\n", memAddr
));
420 memAddr
= memAddr
+ 4;
424 return EFI_DEVICE_ERROR
;
428 //Output Message for MFG
430 DEBUG ((EFI_D_ERROR
, "MFGMODE MEMORY TEST PASSED\n"));
436 IN CONST EFI_PEI_SERVICES
**PeiServices
440 EFI_PEI_STALL_PPI
*StallPpi
;
443 (**PeiServices
).LocatePpi (PeiServices
, &gEfiPeiStallPpiGuid
, 0, NULL
, (void **)&StallPpi
);
445 for (Count
= 0; Count
< 500; Count
++) { // Maximum waiting approximates to 1.5 seconds (= 3 msec * 500)
446 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERA
);
447 if ((IoRead8 (R_PCH_RTC_TARGET2
) & B_PCH_RTC_REGISTERA_UIP
) == 0) {
451 StallPpi
->Stall (PeiServices
, StallPpi
, 3000);
458 RtcPowerFailureHandler (
459 IN CONST EFI_PEI_SERVICES
**PeiServices
465 BOOLEAN RtcUipIsAlwaysSet
;
466 DataUint16
= MmioRead16 (PMC_BASE_ADDRESS
+ R_PCH_PMC_GEN_PMCON_1
);
467 RtcUipIsAlwaysSet
= IsRtcUipAlwaysSet (PeiServices
);
468 if ((DataUint16
& B_PCH_PMC_GEN_PMCON_RTC_PWR_STS
) || (RtcUipIsAlwaysSet
)) {
470 // Execute the sequence below. This will ensure that the RTC state machine has been initialized.
473 // BIOS clears this bit by writing a '0' to it.
475 if (DataUint16
& B_PCH_PMC_GEN_PMCON_RTC_PWR_STS
) {
477 // Set to invalid date in order to reset the time to
478 // BIOS build time later in the boot (SBRUN.c file).
480 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_YEAR
);
481 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
482 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_MONTH
);
483 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
484 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_DAYOFMONTH
);
485 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
486 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_DAYOFWEEK
);
487 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
489 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_SECONDSALARM
);
490 IoWrite8 (R_PCH_RTC_TARGET2
, 0x00);
491 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_MINUTESALARM
);
492 IoWrite8 (R_PCH_RTC_TARGET2
, 0x00);
493 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_HOURSALARM
);
494 IoWrite8 (R_PCH_RTC_TARGET2
, 0x00);
499 // Set RTC Register 0Ah[6:4] to '110' or '111'.
501 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERA
);
502 IoWrite8 (R_PCH_RTC_TARGET2
, (V_PCH_RTC_REGISTERA_DV_DIV_RST1
| V_PCH_RTC_REGISTERA_RS_976P5US
));
506 // Set RTC Register 0Bh[7].
508 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
509 DataUint8
= (IoRead8 (R_PCH_RTC_TARGET2
) | B_PCH_RTC_REGISTERB_SET
);
510 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
511 IoWrite8 (R_PCH_RTC_TARGET2
, DataUint8
);
515 // Set RTC Register 0Ah[6:4] to '010'.
517 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERA
);
518 IoWrite8 (R_PCH_RTC_TARGET2
, (V_PCH_RTC_REGISTERA_DV_NORM_OP
| V_PCH_RTC_REGISTERA_RS_976P5US
));
522 // Clear RTC Register 0Bh[7].
524 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
525 DataUint8
= (IoRead8 (R_PCH_RTC_TARGET2
) & (UINT8
)~B_PCH_RTC_REGISTERB_SET
);
526 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
527 IoWrite8 (R_PCH_RTC_TARGET2
, DataUint8
);
540 // Program ACPI Power Management I/O Space Base Address
544 DEFAULT_PCI_BUS_NUMBER_PCH
,
545 PCI_DEVICE_NUMBER_PCH_LPC
,
546 PCI_FUNCTION_NUMBER_PCH_LPC
,
549 (UINT16
)((ACPI_BASE_ADDRESS
& B_PCH_LPC_ACPI_BASE_BAR
) | B_PCH_LPC_ACPI_BASE_EN
)
553 // Program GPIO Base Address
557 DEFAULT_PCI_BUS_NUMBER_PCH
,
558 PCI_DEVICE_NUMBER_PCH_LPC
,
559 PCI_FUNCTION_NUMBER_PCH_LPC
,
562 (UINT16
)((GPIO_BASE_ADDRESS
& B_PCH_LPC_GPIO_BASE_BAR
) | B_PCH_LPC_GPIO_BASE_EN
)
566 // Set PMC Base Address
570 DEFAULT_PCI_BUS_NUMBER_PCH
,
571 PCI_DEVICE_NUMBER_PCH_LPC
,
572 PCI_FUNCTION_NUMBER_PCH_LPC
,
575 (UINT32
)((PMC_BASE_ADDRESS
& B_PCH_LPC_PMC_BASE_BAR
) | B_PCH_LPC_PMC_BASE_EN
)
579 // Set IO Base Address
583 DEFAULT_PCI_BUS_NUMBER_PCH
,
584 PCI_DEVICE_NUMBER_PCH_LPC
,
585 PCI_FUNCTION_NUMBER_PCH_LPC
,
588 (UINT32
)((IO_BASE_ADDRESS
& B_PCH_LPC_IO_BASE_BAR
) | B_PCH_LPC_IO_BASE_EN
)
592 // Set ILB Base Address
596 DEFAULT_PCI_BUS_NUMBER_PCH
,
597 PCI_DEVICE_NUMBER_PCH_LPC
,
598 PCI_FUNCTION_NUMBER_PCH_LPC
,
601 (UINT32
)((ILB_BASE_ADDRESS
& B_PCH_LPC_ILB_BASE_BAR
) | B_PCH_LPC_ILB_BASE_EN
)
605 // Set PUnit Base Address
609 DEFAULT_PCI_BUS_NUMBER_PCH
,
610 PCI_DEVICE_NUMBER_PCH_LPC
,
611 PCI_FUNCTION_NUMBER_PCH_LPC
,
614 (UINT32
)((PUNIT_BASE_ADDRESS
& B_PCH_LPC_PUNIT_BASE_BAR
) | B_PCH_LPC_PUNIT_BASE_EN
)
618 // Set SPI Base Address
622 DEFAULT_PCI_BUS_NUMBER_PCH
,
623 PCI_DEVICE_NUMBER_PCH_LPC
,
624 PCI_FUNCTION_NUMBER_PCH_LPC
,
627 (UINT32
)((SPI_BASE_ADDRESS
& B_PCH_LPC_SPI_BASE_BAR
) | B_PCH_LPC_SPI_BASE_EN
)
631 // Set Root Complex Base Address
635 DEFAULT_PCI_BUS_NUMBER_PCH
,
636 PCI_DEVICE_NUMBER_PCH_LPC
,
637 PCI_FUNCTION_NUMBER_PCH_LPC
,
640 (UINT32
)((RCBA_BASE_ADDRESS
& B_PCH_LPC_RCBA_BAR
) | B_PCH_LPC_RCBA_EN
)
644 // Set MPHY Base Address
648 DEFAULT_PCI_BUS_NUMBER_PCH
,
649 PCI_DEVICE_NUMBER_PCH_LPC
,
650 PCI_FUNCTION_NUMBER_PCH_LPC
,
653 (UINT32
)((MPHY_BASE_ADDRESS
& B_PCH_LPC_MPHY_BASE_BAR
) | B_PCH_LPC_MPHY_BASE_EN
)
657 DEFAULT_PCI_BUS_NUMBER_PCH
,
658 PCI_DEVICE_NUMBER_PCH_SMBUS
,
659 PCI_FUNCTION_NUMBER_PCH_SMBUS
,
662 (UINT16
)(SMBUS_BASE_ADDRESS
& B_PCH_SMBUS_BASE_BAR
)
667 DEFAULT_PCI_BUS_NUMBER_PCH
,
668 PCI_DEVICE_NUMBER_PCH_SMBUS
,
669 PCI_FUNCTION_NUMBER_PCH_SMBUS
,
672 B_PCH_SMBUS_PCICMD_IOSE
678 This is the entrypoint of PEIM
680 @param FileHandle Handle of the file being invoked.
681 @param PeiServices Describes the list of possible PEI Services.
683 @retval EFI_SUCCESS if it completed successfully.
688 IN EFI_PEI_FILE_HANDLE FileHandle
,
689 IN CONST EFI_PEI_SERVICES
**PeiServices
693 EFI_PLATFORM_INFO_HOB PlatformInfo
;
694 EFI_STATUS Status
= EFI_SUCCESS
;
695 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*Variable
= NULL
;
697 SYSTEM_CONFIGURATION SystemConfiguration
;
700 EFI_PEI_PPI_DESCRIPTOR
*mVlvMmioPolicyPpiDesc
;
701 VLV_MMIO_POLICY_PPI
*mVlvMmioPolicyPpi
;
703 ZeroMem (&PlatformInfo
, sizeof(PlatformInfo
));
705 Status
= InstallMonoStatusCode(FileHandle
, PeiServices
);
706 ASSERT_EFI_ERROR (Status
);
710 // Initialize Stall PPIs
712 Status
= (*PeiServices
)->InstallPpi (PeiServices
, &mInstallStallPpi
[0]);
713 ASSERT_EFI_ERROR (Status
);
715 Status
= (*PeiServices
)->NotifyPpi (PeiServices
, &mMemoryDiscoveredNotifyList
[0]);
716 ASSERT_EFI_ERROR (Status
);
717 SmbusRegBase
= PchPciDeviceMmBase (
718 DEFAULT_PCI_BUS_NUMBER_PCH
,
719 PCI_DEVICE_NUMBER_PCH_SMBUS
,
720 PCI_FUNCTION_NUMBER_PCH_SMBUS
723 // Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves
725 MmioAndThenOr32 (SmbusRegBase
+ R_PCH_SMBUS_BASE
, B_PCH_SMBUS_BASE_BAR
, SMBUS_BASE_ADDRESS
);
727 MmioOr8 (SmbusRegBase
+ R_PCH_SMBUS_PCICMD
, B_PCH_SMBUS_PCICMD_IOSE
);
732 //Todo: confirm if we need program 8254
735 // Program timer 1 as refresh timer
737 IoWrite8 (0x43, 0x54);
738 IoWrite8 (0x41, 0x12);
741 // RTC power failure handling
743 RtcPowerFailureHandler (PeiServices
);
746 PchMmPci32( 0, 0, 2, 0, 0x50) = 0x210;
748 VariableSize
= sizeof (SYSTEM_CONFIGURATION
);
749 ZeroMem (&SystemConfiguration
, VariableSize
);
752 // Obtain variable services
754 Status
= (*PeiServices
)->LocatePpi(
756 &gEfiPeiReadOnlyVariable2PpiGuid
,
761 ASSERT_EFI_ERROR(Status
);
762 Status
= Variable
->GetVariable (
765 &gEfiSetupVariableGuid
,
770 if (EFI_ERROR (Status
) || VariableSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
771 //The setup variable is corrupted
772 VariableSize
= sizeof(SYSTEM_CONFIGURATION
);
773 Status
= Variable
->GetVariable(
776 &gEfiSetupVariableGuid
,
781 ASSERT_EFI_ERROR (Status
);
784 if (EFI_ERROR (Status
)) {
785 GGC
= ((2 << 3) | 0x200);
786 PciCfg16Write(EC_BASE
, 0, 2, 0, 0x50, GGC
);
787 GGC
= PciCfg16Read(EC_BASE
, 0, 2, 0, 0x50);
788 DEBUG((EFI_D_INFO
, "GGC: 0x%08x GMSsize:0x%08x\n", GGC
, (GGC
& (BIT7
|BIT6
|BIT5
|BIT4
|BIT3
))>>3));
790 if (SystemConfiguration
.Igd
== 1 && SystemConfiguration
.PrimaryVideoAdaptor
!= 2) {
791 GGC
= (SystemConfiguration
.IgdDvmt50PreAlloc
<< 3) |
792 (SystemConfiguration
.GTTSize
== GTT_SIZE_1MB
? 0x100: 0x200);
793 PciCfg16Write(EC_BASE
, 0, 2, 0, 0x50, GGC
);
794 GGC
= PciCfg16Read(EC_BASE
, 0, 2, 0, 0x50);
795 DEBUG((EFI_D_INFO
, "GGC: 0x%08x GMSsize:0x%08x\n", GGC
, (GGC
& (BIT7
|BIT6
|BIT5
|BIT4
|BIT3
))>>3));
800 // Initialize PlatformInfo HOB
802 Status
= ReadPlatformIds(PeiServices
, &PlatformInfo
);
803 ASSERT_EFI_ERROR (Status
);
806 // 0 -> Disable , 1 -> Enable
808 if(SystemConfiguration
.CfioPnpSettings
== 1) {
809 DEBUG((EFI_D_INFO
, "CheckCfioPnpSettings: CFIO Pnp Settings Enabled\n"));
810 PlatformInfo
.CfioEnabled
= 1;
812 DEBUG((EFI_D_INFO
, "CheckCfioPnpSettings: CFIO Pnp Settings Disabled\n"));
813 PlatformInfo
.CfioEnabled
= 0;
817 // Build HOB for PlatformInfo
820 &gEfiPlatformInfoGuid
,
822 sizeof (EFI_PLATFORM_INFO_HOB
)
827 Status
= FtpmPolicyInit(PeiServices
, &SystemConfiguration
);
828 if (EFI_ERROR (Status
)) {
829 DEBUG((EFI_D_ERROR
, "fTPM init failed.\n"));
835 // Set the new boot mode for MRC
837 #ifdef NOCS_S3_SUPPORT
838 Status
= UpdateBootMode (PeiServices
);
839 ASSERT_EFI_ERROR (Status
);
842 DEBUG((EFI_D_INFO
, "Setup MMIO size ... \n\n"));
847 Status
= (*PeiServices
)->AllocatePool(
849 sizeof (EFI_PEI_PPI_DESCRIPTOR
),
850 (void **)&mVlvMmioPolicyPpiDesc
852 ASSERT_EFI_ERROR (Status
);
853 Status
= (*PeiServices
)->AllocatePool(
855 sizeof (VLV_MMIO_POLICY_PPI
),
856 (void **)&mVlvMmioPolicyPpi
858 ASSERT_EFI_ERROR (Status
);
859 (*PeiServices
)->SetMem (
860 (VOID
*)mVlvMmioPolicyPpi
,
861 sizeof (VLV_MMIO_POLICY_PPI
),
864 mVlvMmioPolicyPpiDesc
->Flags
= EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
;
865 mVlvMmioPolicyPpiDesc
->Guid
= &gVlvMmioPolicyPpiGuid
;
866 mVlvMmioPolicyPpiDesc
->Ppi
= mVlvMmioPolicyPpi
;
867 switch (SystemConfiguration
.MmioSize
) {
869 mVlvMmioPolicyPpi
->MmioSize
= 0x300;
872 mVlvMmioPolicyPpi
->MmioSize
= 0x400;
875 mVlvMmioPolicyPpi
->MmioSize
= 0x500;
878 mVlvMmioPolicyPpi
->MmioSize
= 0x600;
881 mVlvMmioPolicyPpi
->MmioSize
= 0x800;
884 mVlvMmioPolicyPpi
->MmioSize
= 0x800;
887 Status
= (*PeiServices
)->InstallPpi(
889 mVlvMmioPolicyPpiDesc
891 ASSERT_EFI_ERROR (Status
);
898 IN CONST EFI_PEI_SERVICES
**PeiServices
,
899 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
903 EFI_STATUS Status
= EFI_SUCCESS
;
906 EFI_PLATFORM_INFO_HOB TmpHob
;
907 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*PeiVar
;
908 UINT32 CompatibleBoard
= 0;
910 Status
= (**PeiServices
).LocatePpi (
912 &gEfiPeiReadOnlyVariable2PpiGuid
,
917 ASSERT_EFI_ERROR (Status
);
919 DataSize
= sizeof (EFI_PLATFORM_INFO_HOB
);
920 Status
= PeiVar
->GetVariable (
923 &gEfiVlv2VariableGuid
,
929 if (Status
== EFI_SUCCESS
) {
930 PlatformInfoHob
->BoardId
= TmpHob
.BoardId
;
931 PlatformInfoHob
->MemCfgID
= TmpHob
.MemCfgID
;
932 PlatformInfoHob
->BoardRev
= TmpHob
.BoardRev
;
933 PlatformInfoHob
->PlatformFlavor
= TmpHob
.PlatformFlavor
;
937 CompatibleBoard
= DetermineTurbotBoard();
938 if (1 == CompatibleBoard
) {
939 PlatformInfoHob
->BoardId
= BOARD_ID_MINNOW2_TURBOT
;
940 DEBUG ((EFI_D_INFO
, "I'm MinnowBoard Turbot!\n"));
942 PlatformInfoHob
->BoardId
= BOARD_ID_MINNOW2
;
943 DEBUG ((EFI_D_INFO
, "I'm MinnowBoard Max!\n"));
947 PlatformInfoHob
->MemCfgID
= 0;
948 PlatformInfoHob
->BoardRev
= FabId
+ 1; // FabId = 0 means FAB1 (BoardRev = 1), FabId = 1 means FAB2 (BoardRev = 2)...
949 PlatformInfoHob
->PlatformFlavor
= FlavorMobile
;
956 // Start::Alpine Valley platform
959 This routine reads SysCtl registers
961 @param SmbusBase SMBUS Base Address
962 @param SlvAddr Targeted Smbus Slave device address
963 @param Operation Which SMBus protocol will be used
964 @param Offset Offset of the register
965 @param Length Number of bytes
966 @param Buffer Buffer contains values read from registers
968 @retval SUCCESS as passed
969 @retval Others as failed
982 EFI_STATUS Status
=EFI_SUCCESS
;
984 UINT8 SmbusOperation
= 0;
988 UINT8 BlockCount
= 0;
989 BOOLEAN BufferTooSmall
;
992 UINT8 RetryCount
= BUS_TRIES
;
995 // MrcSmbusExec supports byte and block read.
996 // Only allow Byte or block access
998 if (!((*Length
== AV_SC_BYTE_LEN
) || (*Length
== AV_SC_BLOCK_LEN
))) {
999 return EFI_INVALID_PARAMETER
;
1003 // See if its ok to use the bus based upon INUSE_STS bit.
1005 Status
= AcquireBus (SmbusBase
);
1006 ASSERT_EFI_ERROR(Status
);
1008 CallBuffer
= Buffer
;
1011 //SmbStatus Bits of interest
1012 //[6] = IUS (In Use Status)
1014 //[3] = BERR (Bus Error = transaction collision)
1015 //[2] = DERR (Device Error = Illegal Command Field, Unclaimed Cycle, Host Device Timeout, CRC Error)
1016 //[1] = INTR (Successful completion of last command)
1020 // This is the main operation loop. If the operation results in a Smbus
1021 // collision with another master on the bus, it attempts the requested
1022 // transaction again at least BUS_TRIES attempts.
1024 while (RetryCount
--) {
1026 // Operation Specifics (pre-execution)
1028 Status
= EFI_SUCCESS
;
1029 SlvAddrReg
= SlvAddr
;
1030 HostCmdReg
= Offset
;
1033 switch (Operation
) {
1035 case SMBUS_WRITE_BYTE
:
1036 IoWrite8 (SmbusBase
+R_PCH_SMBUS_HD0
, CallBuffer
[0]);
1037 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BYTE_DATA
;
1040 case SMBUS_READ_BYTE
:
1041 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BYTE_DATA
;
1042 SlvAddrReg
|= B_PCH_SMBUS_RW_SEL_READ
;
1044 Status
= EFI_INVALID_PARAMETER
;
1049 case SMBUS_WRITE_BLOCK
:
1050 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BLOCK
;
1051 IoWrite8 (SmbusBase
+R_PCH_SMBUS_HD0
, *(UINT8
*) Length
);
1052 BlockCount
= (UINT8
) (*Length
);
1053 if ((*Length
< 1) || (*Length
> 32)) {
1054 Status
= EFI_INVALID_PARAMETER
;
1057 AuxcReg
|= B_PCH_SMBUS_E32B
;
1060 case SMBUS_READ_BLOCK
:
1061 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BLOCK
;
1062 SlvAddrReg
|= B_PCH_SMBUS_RW_SEL_READ
;
1063 if ((*Length
< 1) || (*Length
> 32)) {
1064 Status
= EFI_INVALID_PARAMETER
;
1067 AuxcReg
|= B_PCH_SMBUS_E32B
;
1071 Status
= EFI_INVALID_PARAMETER
;
1076 // Set Auxiliary Control register
1078 IoWrite8 (SmbusBase
+R_PCH_SMBUS_AUXC
, AuxcReg
);
1081 // Reset the pointer of the internal buffer
1083 IoRead8 (SmbusBase
+R_PCH_SMBUS_HCTL
);
1086 // Now that the 32 byte buffer is turned on, we can write th block data
1089 if (Operation
== SMBUS_WRITE_BLOCK
) {
1090 for (Index
= 0; Index
< BlockCount
; Index
++) {
1094 IoWrite8 (SmbusBase
+R_PCH_SMBUS_HBD
, CallBuffer
[Index
]);
1099 // Set SMBus slave address for the device to read
1101 IoWrite8(SmbusBase
+R_PCH_SMBUS_TSA
, SlvAddrReg
);
1105 // Set Command register for the offset to read
1107 IoWrite8(SmbusBase
+R_PCH_SMBUS_HCMD
, HostCmdReg
);
1110 // Set Control Register to Set "operation command" protocol and start bit
1112 IoWrite8(SmbusBase
+R_PCH_SMBUS_HCTL
, (UINT8
) (SmbusOperation
+ B_PCH_SMBUS_START
));
1115 // Wait for IO to complete
1117 do { StsReg
= (UINT8
) IoRead8(SmbusBase
+0); } while ((StsReg
& (BIT4
|BIT3
|BIT2
|BIT1
)) == 0);
1119 if (StsReg
& B_PCH_SMBUS_DERR
) {
1120 Status
= EFI_DEVICE_ERROR
;
1122 } else if (StsReg
& B_PCH_SMBUS_BERR
) {
1124 // Clear the Bus Error for another try
1126 Status
= EFI_DEVICE_ERROR
;
1127 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_BERR
);
1130 // Clear Status Registers
1132 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_HSTS_ALL
);
1133 IoWrite8(SmbusBase
+R_PCH_SMBUS_AUXS
, B_PCH_SMBUS_CRCE
);
1139 // successfull completion
1140 // Operation Specifics (post-execution)
1142 switch (Operation
) {
1144 case SMBUS_READ_BYTE
:
1145 CallBuffer
[0] = (UINT8
)(IoRead8 (SmbusBase
+R_PCH_SMBUS_HD0
));
1148 case SMBUS_WRITE_BLOCK
:
1149 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_BYTE_DONE_STS
);
1152 case SMBUS_READ_BLOCK
:
1153 BufferTooSmall
= FALSE
;
1156 // Find out how many bytes will be in the block
1158 BlockCount
= (UINT8
)(IoRead8 (SmbusBase
+R_PCH_SMBUS_HD0
));
1159 if (*Length
< BlockCount
) {
1160 BufferTooSmall
= TRUE
;
1162 for (Index
= 0; Index
< BlockCount
; Index
++) {
1166 CallBuffer
[Index
] = (UINT8
)IoRead8 (SmbusBase
+R_PCH_SMBUS_HBD
);
1170 *Length
= BlockCount
;
1171 if (BufferTooSmall
) {
1172 Status
= EFI_BUFFER_TOO_SMALL
;
1180 if ((StsReg
& B_PCH_SMBUS_BERR
) && (Status
== EFI_SUCCESS
)) {
1182 // Clear the Bus Error for another try
1184 Status
= EFI_DEVICE_ERROR
;
1185 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_BERR
);
1194 // Clear Status Registers and exit
1196 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_HSTS_ALL
);
1197 IoWrite8(SmbusBase
+R_PCH_SMBUS_AUXS
, B_PCH_SMBUS_CRCE
);
1198 IoWrite8(SmbusBase
+R_PCH_SMBUS_AUXC
, 0);
1202 // End::Alpine Valley platform