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 IN CONST EFI_PEI_SERVICES
**PeiServices
,
198 IN SYSTEM_CONFIGURATION
*pSystemConfiguration
202 EFI_PEI_PPI_DESCRIPTOR
*mFtpmPolicyPpiDesc
;
203 SEC_FTPM_POLICY_PPI
*mFtpmPolicyPpi
;
206 DEBUG((EFI_D_INFO
, "FtpmPolicyInit Entry \n"));
208 if (NULL
== PeiServices
|| NULL
== pSystemConfiguration
) {
209 DEBUG((EFI_D_ERROR
, "Input error. \n"));
210 return EFI_INVALID_PARAMETER
;
213 Status
= (*PeiServices
)->AllocatePool(
215 sizeof (EFI_PEI_PPI_DESCRIPTOR
),
216 (void **)&mFtpmPolicyPpiDesc
218 ASSERT_EFI_ERROR (Status
);
220 Status
= (*PeiServices
)->AllocatePool(
222 sizeof (SEC_FTPM_POLICY_PPI
),
223 (void **)&mFtpmPolicyPpi
225 ASSERT_EFI_ERROR (Status
);
230 (*PeiServices
)->SetMem ((VOID
*)mFtpmPolicyPpi
, sizeof (SEC_FTPM_POLICY_PPI
), 0);
231 mFtpmPolicyPpiDesc
->Flags
= EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
;
232 mFtpmPolicyPpiDesc
->Guid
= &gSeCfTPMPolicyPpiGuid
;
233 mFtpmPolicyPpiDesc
->Ppi
= mFtpmPolicyPpi
;
236 DEBUG((EFI_D_INFO
, "pSystemConfiguration->fTPM = 0x%x \n", pSystemConfiguration
->fTPM
));
237 if(pSystemConfiguration
->fTPM
== 1) {
238 mFtpmPolicyPpi
->fTPMEnable
= TRUE
;
240 mFtpmPolicyPpi
->fTPMEnable
= FALSE
;
243 Status
= (*PeiServices
)->InstallPpi(
247 ASSERT_EFI_ERROR (Status
);
249 DEBUG((EFI_D_INFO
, "FtpmPolicyInit done \n"));
256 This routine attempts to acquire the SMBus
258 @retval FAILURE as failed
259 @retval SUCCESS as passed
270 StsReg
= (UINT8
)IoRead8(SmbusBase
+ R_PCH_SMBUS_HSTS
);
271 if (StsReg
& B_PCH_SMBUS_IUS
) {
272 return EFI_DEVICE_ERROR
;
273 } else if (StsReg
& B_PCH_SMBUS_HBSY
) {
275 // Clear Status Register and exit
277 // Wait for HSTS.HBSY to be clear
279 do { StsReg
= (UINT8
) IoRead8(SmbusBase
+R_PCH_SMBUS_HSTS
); } while ((StsReg
& B_PCH_SMBUS_HBSY
) != 0);
282 // Clear all status bits
284 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, 0xFE);
288 // Clear out any odd status information (Will Not Clear In Use)
290 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, StsReg
);
295 // End::Alpine Valley platform
299 This function checks the memory range in PEI.
301 @param PeiServices Pointer to PEI Services.
302 @param This Pei memory test PPI pointer.
303 @param BeginAddress Beginning of the memory address to be checked.
304 @param MemoryLength Bytes of memory range to be checked.
305 @param Operation Type of memory check operation to be performed.
306 @param ErrorAddress Return the address of the error memory address.
308 @retval EFI_SUCCESS The operation completed successfully.
309 @retval EFI_DEVICE_ERROR Memory test failed. It's not safe to use this range of memory.
315 IN CONST EFI_PEI_SERVICES
**PeiServices
,
316 IN PEI_MFG_MEMORY_TEST_PPI
*This
,
317 IN UINT32 BeginAddress
,
318 IN UINT32 MemoryLength
326 memAddr
= BeginAddress
;
329 //Output Message for MFG
331 DEBUG ((EFI_D_ERROR
, "MFGMODE SET\n"));
334 //Writting the pattern in defined location.
336 while (memAddr
< (BeginAddress
+MemoryLength
)) {
337 for (i
= 0; i
< DATA_PATTERN_ARRAY_SIZE
; i
++) {
338 if (memAddr
> (BeginAddress
+MemoryLength
-4)) {
339 memAddr
= memAddr
+ 4;
342 *((volatile UINT32
*) memAddr
) = DataPatternForMemoryTest
[i
];
343 memAddr
= memAddr
+ 4;
348 //Verify the pattern.
350 memAddr
= BeginAddress
;
351 while (memAddr
< (BeginAddress
+MemoryLength
)) {
352 for (i
= 0; i
< DATA_PATTERN_ARRAY_SIZE
; i
++) {
353 if (memAddr
> (BeginAddress
+MemoryLength
-4)) {
354 memAddr
= memAddr
+ 4;
357 readData
= *((volatile UINT32
*) memAddr
);
358 xorData
= readData
^ DataPatternForMemoryTest
[i
];
361 // If xorData is nonzero, this particular memAddr has a failure.
363 if (xorData
!= 0x00000000) {
364 DEBUG ((EFI_D_ERROR
, "Expected value....: %x\n", DataPatternForMemoryTest
[i
]));
365 DEBUG ((EFI_D_ERROR
, "ReadData value....: %x\n", readData
));
366 DEBUG ((EFI_D_ERROR
, "Pattern failure at....: %x\n", memAddr
));
369 memAddr
= memAddr
+ 4;
373 return EFI_DEVICE_ERROR
;
377 //Output Message for MFG
379 DEBUG ((EFI_D_ERROR
, "MFGMODE MEMORY TEST PASSED\n"));
385 IN CONST EFI_PEI_SERVICES
**PeiServices
389 EFI_PEI_STALL_PPI
*StallPpi
;
392 (**PeiServices
).LocatePpi (PeiServices
, &gEfiPeiStallPpiGuid
, 0, NULL
, (void **)&StallPpi
);
394 for (Count
= 0; Count
< 500; Count
++) { // Maximum waiting approximates to 1.5 seconds (= 3 msec * 500)
395 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERA
);
396 if ((IoRead8 (R_PCH_RTC_TARGET2
) & B_PCH_RTC_REGISTERA_UIP
) == 0) {
400 StallPpi
->Stall (PeiServices
, StallPpi
, 3000);
407 RtcPowerFailureHandler (
408 IN CONST EFI_PEI_SERVICES
**PeiServices
414 BOOLEAN RtcUipIsAlwaysSet
;
415 DataUint16
= MmioRead16 (PMC_BASE_ADDRESS
+ R_PCH_PMC_GEN_PMCON_1
);
416 RtcUipIsAlwaysSet
= IsRtcUipAlwaysSet (PeiServices
);
417 if ((DataUint16
& B_PCH_PMC_GEN_PMCON_RTC_PWR_STS
) || (RtcUipIsAlwaysSet
)) {
419 // Execute the sequence below. This will ensure that the RTC state machine has been initialized.
422 // BIOS clears this bit by writing a '0' to it.
424 if (DataUint16
& B_PCH_PMC_GEN_PMCON_RTC_PWR_STS
) {
426 // Set to invalid date in order to reset the time to
427 // BIOS build time later in the boot (SBRUN.c file).
429 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_YEAR
);
430 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
431 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_MONTH
);
432 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
433 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_DAYOFMONTH
);
434 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
435 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_DAYOFWEEK
);
436 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
438 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_SECONDSALARM
);
439 IoWrite8 (R_PCH_RTC_TARGET2
, 0x00);
440 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_MINUTESALARM
);
441 IoWrite8 (R_PCH_RTC_TARGET2
, 0x00);
442 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_HOURSALARM
);
443 IoWrite8 (R_PCH_RTC_TARGET2
, 0x00);
448 // Set RTC Register 0Ah[6:4] to '110' or '111'.
450 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERA
);
451 IoWrite8 (R_PCH_RTC_TARGET2
, (V_PCH_RTC_REGISTERA_DV_DIV_RST1
| V_PCH_RTC_REGISTERA_RS_976P5US
));
455 // Set RTC Register 0Bh[7].
457 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
458 DataUint8
= (IoRead8 (R_PCH_RTC_TARGET2
) | B_PCH_RTC_REGISTERB_SET
);
459 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
460 IoWrite8 (R_PCH_RTC_TARGET2
, DataUint8
);
464 // Set RTC Register 0Ah[6:4] to '010'.
466 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERA
);
467 IoWrite8 (R_PCH_RTC_TARGET2
, (V_PCH_RTC_REGISTERA_DV_NORM_OP
| V_PCH_RTC_REGISTERA_RS_976P5US
));
471 // Clear RTC Register 0Bh[7].
473 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
474 DataUint8
= (IoRead8 (R_PCH_RTC_TARGET2
) & (UINT8
)~B_PCH_RTC_REGISTERB_SET
);
475 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
476 IoWrite8 (R_PCH_RTC_TARGET2
, DataUint8
);
489 // Program ACPI Power Management I/O Space Base Address
493 DEFAULT_PCI_BUS_NUMBER_PCH
,
494 PCI_DEVICE_NUMBER_PCH_LPC
,
495 PCI_FUNCTION_NUMBER_PCH_LPC
,
498 (UINT16
)((ACPI_BASE_ADDRESS
& B_PCH_LPC_ACPI_BASE_BAR
) | B_PCH_LPC_ACPI_BASE_EN
)
502 // Program GPIO Base Address
506 DEFAULT_PCI_BUS_NUMBER_PCH
,
507 PCI_DEVICE_NUMBER_PCH_LPC
,
508 PCI_FUNCTION_NUMBER_PCH_LPC
,
511 (UINT16
)((GPIO_BASE_ADDRESS
& B_PCH_LPC_GPIO_BASE_BAR
) | B_PCH_LPC_GPIO_BASE_EN
)
515 // Set PMC Base Address
519 DEFAULT_PCI_BUS_NUMBER_PCH
,
520 PCI_DEVICE_NUMBER_PCH_LPC
,
521 PCI_FUNCTION_NUMBER_PCH_LPC
,
524 (UINT32
)((PMC_BASE_ADDRESS
& B_PCH_LPC_PMC_BASE_BAR
) | B_PCH_LPC_PMC_BASE_EN
)
528 // Set IO Base Address
532 DEFAULT_PCI_BUS_NUMBER_PCH
,
533 PCI_DEVICE_NUMBER_PCH_LPC
,
534 PCI_FUNCTION_NUMBER_PCH_LPC
,
537 (UINT32
)((IO_BASE_ADDRESS
& B_PCH_LPC_IO_BASE_BAR
) | B_PCH_LPC_IO_BASE_EN
)
541 // Set ILB Base Address
545 DEFAULT_PCI_BUS_NUMBER_PCH
,
546 PCI_DEVICE_NUMBER_PCH_LPC
,
547 PCI_FUNCTION_NUMBER_PCH_LPC
,
550 (UINT32
)((ILB_BASE_ADDRESS
& B_PCH_LPC_ILB_BASE_BAR
) | B_PCH_LPC_ILB_BASE_EN
)
554 // Set PUnit Base Address
558 DEFAULT_PCI_BUS_NUMBER_PCH
,
559 PCI_DEVICE_NUMBER_PCH_LPC
,
560 PCI_FUNCTION_NUMBER_PCH_LPC
,
563 (UINT32
)((PUNIT_BASE_ADDRESS
& B_PCH_LPC_PUNIT_BASE_BAR
) | B_PCH_LPC_PUNIT_BASE_EN
)
567 // Set SPI Base Address
571 DEFAULT_PCI_BUS_NUMBER_PCH
,
572 PCI_DEVICE_NUMBER_PCH_LPC
,
573 PCI_FUNCTION_NUMBER_PCH_LPC
,
576 (UINT32
)((SPI_BASE_ADDRESS
& B_PCH_LPC_SPI_BASE_BAR
) | B_PCH_LPC_SPI_BASE_EN
)
580 // Set Root Complex Base Address
584 DEFAULT_PCI_BUS_NUMBER_PCH
,
585 PCI_DEVICE_NUMBER_PCH_LPC
,
586 PCI_FUNCTION_NUMBER_PCH_LPC
,
589 (UINT32
)((RCBA_BASE_ADDRESS
& B_PCH_LPC_RCBA_BAR
) | B_PCH_LPC_RCBA_EN
)
593 // Set MPHY Base Address
597 DEFAULT_PCI_BUS_NUMBER_PCH
,
598 PCI_DEVICE_NUMBER_PCH_LPC
,
599 PCI_FUNCTION_NUMBER_PCH_LPC
,
602 (UINT32
)((MPHY_BASE_ADDRESS
& B_PCH_LPC_MPHY_BASE_BAR
) | B_PCH_LPC_MPHY_BASE_EN
)
606 DEFAULT_PCI_BUS_NUMBER_PCH
,
607 PCI_DEVICE_NUMBER_PCH_SMBUS
,
608 PCI_FUNCTION_NUMBER_PCH_SMBUS
,
611 (UINT16
)(SMBUS_BASE_ADDRESS
& B_PCH_SMBUS_BASE_BAR
)
616 DEFAULT_PCI_BUS_NUMBER_PCH
,
617 PCI_DEVICE_NUMBER_PCH_SMBUS
,
618 PCI_FUNCTION_NUMBER_PCH_SMBUS
,
621 B_PCH_SMBUS_PCICMD_IOSE
627 This is the entrypoint of PEIM
629 @param FileHandle Handle of the file being invoked.
630 @param PeiServices Describes the list of possible PEI Services.
632 @retval EFI_SUCCESS if it completed successfully.
637 IN EFI_PEI_FILE_HANDLE FileHandle
,
638 IN CONST EFI_PEI_SERVICES
**PeiServices
642 EFI_PLATFORM_INFO_HOB PlatformInfo
;
643 EFI_STATUS Status
= EFI_SUCCESS
;
644 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*Variable
= NULL
;
646 SYSTEM_CONFIGURATION SystemConfiguration
;
649 EFI_PEI_PPI_DESCRIPTOR
*mVlvMmioPolicyPpiDesc
;
650 VLV_MMIO_POLICY_PPI
*mVlvMmioPolicyPpi
;
652 ZeroMem (&PlatformInfo
, sizeof(PlatformInfo
));
654 Status
= InstallMonoStatusCode(FileHandle
, PeiServices
);
655 ASSERT_EFI_ERROR (Status
);
659 // Initialize Stall PPIs
661 Status
= (*PeiServices
)->InstallPpi (PeiServices
, &mInstallStallPpi
[0]);
662 ASSERT_EFI_ERROR (Status
);
664 Status
= (*PeiServices
)->NotifyPpi (PeiServices
, &mMemoryDiscoveredNotifyList
[0]);
665 ASSERT_EFI_ERROR (Status
);
666 SmbusRegBase
= PchPciDeviceMmBase (
667 DEFAULT_PCI_BUS_NUMBER_PCH
,
668 PCI_DEVICE_NUMBER_PCH_SMBUS
,
669 PCI_FUNCTION_NUMBER_PCH_SMBUS
672 // Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves
674 MmioAndThenOr32 (SmbusRegBase
+ R_PCH_SMBUS_BASE
, B_PCH_SMBUS_BASE_BAR
, SMBUS_BASE_ADDRESS
);
676 MmioOr8 (SmbusRegBase
+ R_PCH_SMBUS_PCICMD
, B_PCH_SMBUS_PCICMD_IOSE
);
681 //Todo: confirm if we need program 8254
684 // Program timer 1 as refresh timer
686 IoWrite8 (0x43, 0x54);
687 IoWrite8 (0x41, 0x12);
690 // RTC power failure handling
692 RtcPowerFailureHandler (PeiServices
);
695 PchMmPci32( 0, 0, 2, 0, 0x50) = 0x210;
697 VariableSize
= sizeof (SYSTEM_CONFIGURATION
);
698 ZeroMem (&SystemConfiguration
, VariableSize
);
701 // Obtain variable services
703 Status
= (*PeiServices
)->LocatePpi(
705 &gEfiPeiReadOnlyVariable2PpiGuid
,
710 ASSERT_EFI_ERROR(Status
);
711 Status
= Variable
->GetVariable (
714 &gEfiSetupVariableGuid
,
719 if (EFI_ERROR (Status
) || VariableSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
720 //The setup variable is corrupted
721 VariableSize
= sizeof(SYSTEM_CONFIGURATION
);
722 Status
= Variable
->GetVariable(
725 &gEfiSetupVariableGuid
,
730 ASSERT_EFI_ERROR (Status
);
733 if (EFI_ERROR (Status
)) {
734 GGC
= ((2 << 3) | 0x200);
735 PciCfg16Write(EC_BASE
, 0, 2, 0, 0x50, GGC
);
736 GGC
= PciCfg16Read(EC_BASE
, 0, 2, 0, 0x50);
737 DEBUG((EFI_D_INFO
, "GGC: 0x%08x GMSsize:0x%08x\n", GGC
, (GGC
& (BIT7
|BIT6
|BIT5
|BIT4
|BIT3
))>>3));
739 if (SystemConfiguration
.Igd
== 1 && SystemConfiguration
.PrimaryVideoAdaptor
!= 2) {
740 GGC
= (SystemConfiguration
.IgdDvmt50PreAlloc
<< 3) |
741 (SystemConfiguration
.GTTSize
== GTT_SIZE_1MB
? 0x100: 0x200);
742 PciCfg16Write(EC_BASE
, 0, 2, 0, 0x50, GGC
);
743 GGC
= PciCfg16Read(EC_BASE
, 0, 2, 0, 0x50);
744 DEBUG((EFI_D_INFO
, "GGC: 0x%08x GMSsize:0x%08x\n", GGC
, (GGC
& (BIT7
|BIT6
|BIT5
|BIT4
|BIT3
))>>3));
749 // Initialize PlatformInfo HOB
751 Status
= ReadPlatformIds(PeiServices
, &PlatformInfo
);
752 ASSERT_EFI_ERROR (Status
);
755 // 0 -> Disable , 1 -> Enable
757 if(SystemConfiguration
.CfioPnpSettings
== 1) {
758 DEBUG((EFI_D_INFO
, "CheckCfioPnpSettings: CFIO Pnp Settings Enabled\n"));
759 PlatformInfo
.CfioEnabled
= 1;
761 DEBUG((EFI_D_INFO
, "CheckCfioPnpSettings: CFIO Pnp Settings Disabled\n"));
762 PlatformInfo
.CfioEnabled
= 0;
766 // Build HOB for PlatformInfo
769 &gEfiPlatformInfoGuid
,
771 sizeof (EFI_PLATFORM_INFO_HOB
)
776 Status
= FtpmPolicyInit(PeiServices
, &SystemConfiguration
);
777 if (EFI_ERROR (Status
)) {
778 DEBUG((EFI_D_ERROR
, "fTPM init failed.\n"));
784 // Set the new boot mode for MRC
786 #ifdef NOCS_S3_SUPPORT
787 Status
= UpdateBootMode (PeiServices
);
788 ASSERT_EFI_ERROR (Status
);
791 DEBUG((EFI_D_INFO
, "Setup MMIO size ... \n\n"));
796 Status
= (*PeiServices
)->AllocatePool(
798 sizeof (EFI_PEI_PPI_DESCRIPTOR
),
799 (void **)&mVlvMmioPolicyPpiDesc
801 ASSERT_EFI_ERROR (Status
);
802 Status
= (*PeiServices
)->AllocatePool(
804 sizeof (VLV_MMIO_POLICY_PPI
),
805 (void **)&mVlvMmioPolicyPpi
807 ASSERT_EFI_ERROR (Status
);
808 (*PeiServices
)->SetMem (
809 (VOID
*)mVlvMmioPolicyPpi
,
810 sizeof (VLV_MMIO_POLICY_PPI
),
813 mVlvMmioPolicyPpiDesc
->Flags
= EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
;
814 mVlvMmioPolicyPpiDesc
->Guid
= &gVlvMmioPolicyPpiGuid
;
815 mVlvMmioPolicyPpiDesc
->Ppi
= mVlvMmioPolicyPpi
;
816 switch (SystemConfiguration
.MmioSize
) {
818 mVlvMmioPolicyPpi
->MmioSize
= 0x300;
821 mVlvMmioPolicyPpi
->MmioSize
= 0x400;
824 mVlvMmioPolicyPpi
->MmioSize
= 0x500;
827 mVlvMmioPolicyPpi
->MmioSize
= 0x600;
830 mVlvMmioPolicyPpi
->MmioSize
= 0x800;
833 mVlvMmioPolicyPpi
->MmioSize
= 0x800;
836 Status
= (*PeiServices
)->InstallPpi(
838 mVlvMmioPolicyPpiDesc
840 ASSERT_EFI_ERROR (Status
);
847 IN CONST EFI_PEI_SERVICES
**PeiServices
,
848 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
852 EFI_STATUS Status
= EFI_SUCCESS
;
855 EFI_PLATFORM_INFO_HOB TmpHob
;
856 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*PeiVar
;
858 Status
= (**PeiServices
).LocatePpi (
860 &gEfiPeiReadOnlyVariable2PpiGuid
,
865 ASSERT_EFI_ERROR (Status
);
867 DataSize
= sizeof (EFI_PLATFORM_INFO_HOB
);
868 Status
= PeiVar
->GetVariable (
871 &gEfiVlv2VariableGuid
,
877 if (Status
== EFI_SUCCESS
) {
878 PlatformInfoHob
->BoardId
= TmpHob
.BoardId
;
879 PlatformInfoHob
->MemCfgID
= TmpHob
.MemCfgID
;
880 PlatformInfoHob
->BoardRev
= TmpHob
.BoardRev
;
881 PlatformInfoHob
->PlatformFlavor
= TmpHob
.PlatformFlavor
;
886 PlatformInfoHob
->BoardId
= BOARD_ID_MINNOW2
;
887 DEBUG ((EFI_D_INFO
, "I'm Minnow2!\n"));
889 PlatformInfoHob
->MemCfgID
= 0;
890 PlatformInfoHob
->BoardRev
= FabId
+ 1; // FabId = 0 means FAB1 (BoardRev = 1), FabId = 1 means FAB2 (BoardRev = 2)...
891 PlatformInfoHob
->PlatformFlavor
= FlavorMobile
;
898 // Start::Alpine Valley platform
901 This routine reads SysCtl registers
903 @param SmbusBase SMBUS Base Address
904 @param SlvAddr Targeted Smbus Slave device address
905 @param Operation Which SMBus protocol will be used
906 @param Offset Offset of the register
907 @param Length Number of bytes
908 @param Buffer Buffer contains values read from registers
910 @retval SUCCESS as passed
911 @retval Others as failed
924 EFI_STATUS Status
=EFI_SUCCESS
;
926 UINT8 SmbusOperation
= 0;
930 UINT8 BlockCount
= 0;
931 BOOLEAN BufferTooSmall
;
934 UINT8 RetryCount
= BUS_TRIES
;
937 // MrcSmbusExec supports byte and block read.
938 // Only allow Byte or block access
940 if (!((*Length
== AV_SC_BYTE_LEN
) || (*Length
== AV_SC_BLOCK_LEN
))) {
941 return EFI_INVALID_PARAMETER
;
945 // See if its ok to use the bus based upon INUSE_STS bit.
947 Status
= AcquireBus (SmbusBase
);
948 ASSERT_EFI_ERROR(Status
);
953 //SmbStatus Bits of interest
954 //[6] = IUS (In Use Status)
956 //[3] = BERR (Bus Error = transaction collision)
957 //[2] = DERR (Device Error = Illegal Command Field, Unclaimed Cycle, Host Device Timeout, CRC Error)
958 //[1] = INTR (Successful completion of last command)
962 // This is the main operation loop. If the operation results in a Smbus
963 // collision with another master on the bus, it attempts the requested
964 // transaction again at least BUS_TRIES attempts.
966 while (RetryCount
--) {
968 // Operation Specifics (pre-execution)
970 Status
= EFI_SUCCESS
;
971 SlvAddrReg
= SlvAddr
;
977 case SMBUS_WRITE_BYTE
:
978 IoWrite8 (SmbusBase
+R_PCH_SMBUS_HD0
, CallBuffer
[0]);
979 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BYTE_DATA
;
982 case SMBUS_READ_BYTE
:
983 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BYTE_DATA
;
984 SlvAddrReg
|= B_PCH_SMBUS_RW_SEL_READ
;
986 Status
= EFI_INVALID_PARAMETER
;
991 case SMBUS_WRITE_BLOCK
:
992 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BLOCK
;
993 IoWrite8 (SmbusBase
+R_PCH_SMBUS_HD0
, *(UINT8
*) Length
);
994 BlockCount
= (UINT8
) (*Length
);
995 if ((*Length
< 1) || (*Length
> 32)) {
996 Status
= EFI_INVALID_PARAMETER
;
999 AuxcReg
|= B_PCH_SMBUS_E32B
;
1002 case SMBUS_READ_BLOCK
:
1003 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BLOCK
;
1004 SlvAddrReg
|= B_PCH_SMBUS_RW_SEL_READ
;
1005 if ((*Length
< 1) || (*Length
> 32)) {
1006 Status
= EFI_INVALID_PARAMETER
;
1009 AuxcReg
|= B_PCH_SMBUS_E32B
;
1013 Status
= EFI_INVALID_PARAMETER
;
1018 // Set Auxiliary Control register
1020 IoWrite8 (SmbusBase
+R_PCH_SMBUS_AUXC
, AuxcReg
);
1023 // Reset the pointer of the internal buffer
1025 IoRead8 (SmbusBase
+R_PCH_SMBUS_HCTL
);
1028 // Now that the 32 byte buffer is turned on, we can write th block data
1031 if (Operation
== SMBUS_WRITE_BLOCK
) {
1032 for (Index
= 0; Index
< BlockCount
; Index
++) {
1036 IoWrite8 (SmbusBase
+R_PCH_SMBUS_HBD
, CallBuffer
[Index
]);
1041 // Set SMBus slave address for the device to read
1043 IoWrite8(SmbusBase
+R_PCH_SMBUS_TSA
, SlvAddrReg
);
1047 // Set Command register for the offset to read
1049 IoWrite8(SmbusBase
+R_PCH_SMBUS_HCMD
, HostCmdReg
);
1052 // Set Control Register to Set "operation command" protocol and start bit
1054 IoWrite8(SmbusBase
+R_PCH_SMBUS_HCTL
, (UINT8
) (SmbusOperation
+ B_PCH_SMBUS_START
));
1057 // Wait for IO to complete
1059 do { StsReg
= (UINT8
) IoRead8(SmbusBase
+0); } while ((StsReg
& (BIT4
|BIT3
|BIT2
|BIT1
)) == 0);
1061 if (StsReg
& B_PCH_SMBUS_DERR
) {
1062 Status
= EFI_DEVICE_ERROR
;
1064 } else if (StsReg
& B_PCH_SMBUS_BERR
) {
1066 // Clear the Bus Error for another try
1068 Status
= EFI_DEVICE_ERROR
;
1069 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_BERR
);
1072 // Clear Status Registers
1074 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_HSTS_ALL
);
1075 IoWrite8(SmbusBase
+R_PCH_SMBUS_AUXS
, B_PCH_SMBUS_CRCE
);
1081 // successfull completion
1082 // Operation Specifics (post-execution)
1084 switch (Operation
) {
1086 case SMBUS_READ_BYTE
:
1087 CallBuffer
[0] = (UINT8
)(IoRead8 (SmbusBase
+R_PCH_SMBUS_HD0
));
1090 case SMBUS_WRITE_BLOCK
:
1091 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_BYTE_DONE_STS
);
1094 case SMBUS_READ_BLOCK
:
1095 BufferTooSmall
= FALSE
;
1098 // Find out how many bytes will be in the block
1100 BlockCount
= (UINT8
)(IoRead8 (SmbusBase
+R_PCH_SMBUS_HD0
));
1101 if (*Length
< BlockCount
) {
1102 BufferTooSmall
= TRUE
;
1104 for (Index
= 0; Index
< BlockCount
; Index
++) {
1108 CallBuffer
[Index
] = (UINT8
)IoRead8 (SmbusBase
+R_PCH_SMBUS_HBD
);
1112 *Length
= BlockCount
;
1113 if (BufferTooSmall
) {
1114 Status
= EFI_BUFFER_TOO_SMALL
;
1122 if ((StsReg
& B_PCH_SMBUS_BERR
) && (Status
== EFI_SUCCESS
)) {
1124 // Clear the Bus Error for another try
1126 Status
= EFI_DEVICE_ERROR
;
1127 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_BERR
);
1136 // Clear Status Registers and exit
1138 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_HSTS_ALL
);
1139 IoWrite8(SmbusBase
+R_PCH_SMBUS_AUXS
, B_PCH_SMBUS_CRCE
);
1140 IoWrite8(SmbusBase
+R_PCH_SMBUS_AUXC
, 0);
1144 // End::Alpine Valley platform