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>
33 // Start::Alpine Valley platform
42 #define EC_BASE 0xE0000000
45 // DEVICE 0 (Memroy Controller Hub)
50 #define MC_DEV_FUN (MC_DEV << 3)
51 #define MC_BUS_DEV_FUN ((MC_BUS << 8) + MC_DEV_FUN)
54 // SysCtl SMBus address and block size
56 #define AV_SC_SMBUS_ADDRESS 0x60
57 #define AV_SC_BYTE_LEN 1
58 #define AV_SC_BLOCK_LEN 4
59 #define AV_SC_SMBUS_WRCMD 1
60 #define AV_SC_SMBUS_RDCMD 0
63 // SysCtl registers offset
65 #define AV_SC_REG_PLATFORM_ID 24 // 0x18
66 #define AV_SC_REG_BOARD_ID 28 // 0x1C
67 #define AV_SC_REG_FAB_ID 32 // 0x20
68 #define AV_SC_REG_ECO_ID 68 // 0x44
69 #define AV_SC_REG_DDR_DAUGHTER_CARD_ID 144 // 0x90
70 #define AV_SC_REG_SODIMM_CONFIG 36
75 #define AV_SC_PLATFORM_ID_TABLET 0
76 #define AV_SC_PLATFORM_ID_NETBOOK 2
77 #define AV_SC_PLATFORM_ID_INTERPOSER 3 // Configuration TBD
78 #define AV_SC_BOARD_ID_AV_SVP 1492
80 #define BUS_TRIES 3 // How many times to retry on Bus Errors
82 #define GTT_SIZE_1MB 1
83 #define GTT_SIZE_2MB 2
85 #define PciCfg16Read( PciExpressBase, Bus, Device, Function, Register ) \
86 MmioRead16(PciExpressBase + \
87 (UINTN)(Bus << 20) + \
88 (UINTN)(Device << 15) + \
89 (UINTN)(Function << 12) + \
91 #define PciCfg16Write( PciExpressBase, Bus, Device, Function, Register, Data ) \
92 MmioWrite16(PciExpressBase + \
93 (UINTN)(Bus << 20) + \
94 (UINTN)(Device << 15) + \
95 (UINTN)(Function << 12) + \
101 //Memory Test Manufacturing mode
103 UINT32 DataPatternForMemoryTest
[] = {
104 0x55555555, 0xAAAAAAAA, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF,
105 0x55555555, 0xAAAAAAAA, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55,
106 0x55555555, 0xAAAAAAAA, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555,
107 0x55555555, 0xAAAAAAAA, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555
109 #define DATA_PATTERN_ARRAY_SIZE (sizeof(DataPatternForMemoryTest) / sizeof(UINT32))
112 //Memory Test Manufacturing mode
115 // The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory
117 BOOLEAN ImageInMemory
= FALSE
;
122 IN CONST EFI_PEI_SERVICES
**PeiServices
,
123 IN CONST EFI_PEI_STALL_PPI
*This
,
124 IN UINTN Microseconds
130 IN CONST EFI_PEI_SERVICES
**PeiServices
,
131 IN PEI_MFG_MEMORY_TEST_PPI
*This
,
132 IN UINT32 BeginAddress
,
133 IN UINT32 MemoryLength
136 static EFI_PEI_STALL_PPI mStallPpi
= {
137 PEI_STALL_RESOLUTION
,
141 static PEI_MFG_MEMORY_TEST_PPI mPeiMfgMemoryTestPpi
= {
145 static EFI_PEI_PPI_DESCRIPTOR mInstallStallPpi
[] = {
147 EFI_PEI_PPI_DESCRIPTOR_PPI
,
148 &gEfiPeiStallPpiGuid
,
152 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
153 &gPeiMfgMemoryTestPpiGuid
,
154 &mPeiMfgMemoryTestPpi
158 EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList
[1] = {
160 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
161 &gEfiPeiMemoryDiscoveredPpiGuid
,
162 MemoryDiscoveredPpiNotifyCallback
168 InstallMonoStatusCode (
169 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
170 IN CONST EFI_PEI_SERVICES
**PeiServices
176 IN CONST EFI_PEI_SERVICES
**PeiServices
,
177 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
181 // Start::Alpine Valley platform
194 This routine attempts to acquire the SMBus
196 @retval FAILURE as failed
197 @retval SUCCESS as passed
208 StsReg
= (UINT8
)IoRead8(SmbusBase
+ R_PCH_SMBUS_HSTS
);
209 if (StsReg
& B_PCH_SMBUS_IUS
) {
210 return EFI_DEVICE_ERROR
;
211 } else if (StsReg
& B_PCH_SMBUS_HBSY
) {
213 // Clear Status Register and exit
215 // Wait for HSTS.HBSY to be clear
217 do { StsReg
= (UINT8
) IoRead8(SmbusBase
+R_PCH_SMBUS_HSTS
); } while ((StsReg
& B_PCH_SMBUS_HBSY
) != 0);
220 // Clear all status bits
222 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, 0xFE);
226 // Clear out any odd status information (Will Not Clear In Use)
228 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, StsReg
);
233 // End::Alpine Valley platform
237 This function checks the memory range in PEI.
239 @param PeiServices Pointer to PEI Services.
240 @param This Pei memory test PPI pointer.
241 @param BeginAddress Beginning of the memory address to be checked.
242 @param MemoryLength Bytes of memory range to be checked.
243 @param Operation Type of memory check operation to be performed.
244 @param ErrorAddress Return the address of the error memory address.
246 @retval EFI_SUCCESS The operation completed successfully.
247 @retval EFI_DEVICE_ERROR Memory test failed. It's not safe to use this range of memory.
253 IN CONST EFI_PEI_SERVICES
**PeiServices
,
254 IN PEI_MFG_MEMORY_TEST_PPI
*This
,
255 IN UINT32 BeginAddress
,
256 IN UINT32 MemoryLength
264 memAddr
= BeginAddress
;
267 //Output Message for MFG
269 DEBUG ((EFI_D_ERROR
, "MFGMODE SET\n"));
272 //Writting the pattern in defined location.
274 while (memAddr
< (BeginAddress
+MemoryLength
)) {
275 for (i
= 0; i
< DATA_PATTERN_ARRAY_SIZE
; i
++) {
276 if (memAddr
> (BeginAddress
+MemoryLength
-4)) {
277 memAddr
= memAddr
+ 4;
280 *((volatile UINT32
*) memAddr
) = DataPatternForMemoryTest
[i
];
281 memAddr
= memAddr
+ 4;
286 //Verify the pattern.
288 memAddr
= BeginAddress
;
289 while (memAddr
< (BeginAddress
+MemoryLength
)) {
290 for (i
= 0; i
< DATA_PATTERN_ARRAY_SIZE
; i
++) {
291 if (memAddr
> (BeginAddress
+MemoryLength
-4)) {
292 memAddr
= memAddr
+ 4;
295 readData
= *((volatile UINT32
*) memAddr
);
296 xorData
= readData
^ DataPatternForMemoryTest
[i
];
299 // If xorData is nonzero, this particular memAddr has a failure.
301 if (xorData
!= 0x00000000) {
302 DEBUG ((EFI_D_ERROR
, "Expected value....: %x\n", DataPatternForMemoryTest
[i
]));
303 DEBUG ((EFI_D_ERROR
, "ReadData value....: %x\n", readData
));
304 DEBUG ((EFI_D_ERROR
, "Pattern failure at....: %x\n", memAddr
));
307 memAddr
= memAddr
+ 4;
311 return EFI_DEVICE_ERROR
;
315 //Output Message for MFG
317 DEBUG ((EFI_D_ERROR
, "MFGMODE MEMORY TEST PASSED\n"));
323 IN CONST EFI_PEI_SERVICES
**PeiServices
327 EFI_PEI_STALL_PPI
*StallPpi
;
330 (**PeiServices
).LocatePpi (PeiServices
, &gEfiPeiStallPpiGuid
, 0, NULL
, (void **)&StallPpi
);
332 for (Count
= 0; Count
< 500; Count
++) { // Maximum waiting approximates to 1.5 seconds (= 3 msec * 500)
333 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERA
);
334 if ((IoRead8 (R_PCH_RTC_TARGET2
) & B_PCH_RTC_REGISTERA_UIP
) == 0) {
338 StallPpi
->Stall (PeiServices
, StallPpi
, 3000);
345 RtcPowerFailureHandler (
346 IN CONST EFI_PEI_SERVICES
**PeiServices
352 BOOLEAN RtcUipIsAlwaysSet
;
353 DataUint16
= MmioRead16 (PMC_BASE_ADDRESS
+ R_PCH_PMC_GEN_PMCON_1
);
354 RtcUipIsAlwaysSet
= IsRtcUipAlwaysSet (PeiServices
);
355 if ((DataUint16
& B_PCH_PMC_GEN_PMCON_RTC_PWR_STS
) || (RtcUipIsAlwaysSet
)) {
357 // Execute the sequence below. This will ensure that the RTC state machine has been initialized.
360 // BIOS clears this bit by writing a '0' to it.
362 if (DataUint16
& B_PCH_PMC_GEN_PMCON_RTC_PWR_STS
) {
364 // Set to invalid date in order to reset the time to
365 // BIOS build time later in the boot (SBRUN.c file).
367 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_YEAR
);
368 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
369 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_MONTH
);
370 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
371 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_DAYOFMONTH
);
372 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
373 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_DAYOFWEEK
);
374 IoWrite8 (R_PCH_RTC_TARGET2
, 0x0FF);
376 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_SECONDSALARM
);
377 IoWrite8 (R_PCH_RTC_TARGET2
, 0x00);
378 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_MINUTESALARM
);
379 IoWrite8 (R_PCH_RTC_TARGET2
, 0x00);
380 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_HOURSALARM
);
381 IoWrite8 (R_PCH_RTC_TARGET2
, 0x00);
386 // Set RTC Register 0Ah[6:4] to '110' or '111'.
388 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERA
);
389 IoWrite8 (R_PCH_RTC_TARGET2
, (V_PCH_RTC_REGISTERA_DV_DIV_RST1
| V_PCH_RTC_REGISTERA_RS_976P5US
));
393 // Set RTC Register 0Bh[7].
395 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
396 DataUint8
= (IoRead8 (R_PCH_RTC_TARGET2
) | B_PCH_RTC_REGISTERB_SET
);
397 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
398 IoWrite8 (R_PCH_RTC_TARGET2
, DataUint8
);
402 // Set RTC Register 0Ah[6:4] to '010'.
404 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERA
);
405 IoWrite8 (R_PCH_RTC_TARGET2
, (V_PCH_RTC_REGISTERA_DV_NORM_OP
| V_PCH_RTC_REGISTERA_RS_976P5US
));
409 // Clear RTC Register 0Bh[7].
411 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
412 DataUint8
= (IoRead8 (R_PCH_RTC_TARGET2
) & (UINT8
)~B_PCH_RTC_REGISTERB_SET
);
413 IoWrite8 (R_PCH_RTC_INDEX2
, R_PCH_RTC_REGISTERB
);
414 IoWrite8 (R_PCH_RTC_TARGET2
, DataUint8
);
427 // Program ACPI Power Management I/O Space Base Address
431 DEFAULT_PCI_BUS_NUMBER_PCH
,
432 PCI_DEVICE_NUMBER_PCH_LPC
,
433 PCI_FUNCTION_NUMBER_PCH_LPC
,
436 (UINT16
)((ACPI_BASE_ADDRESS
& B_PCH_LPC_ACPI_BASE_BAR
) | B_PCH_LPC_ACPI_BASE_EN
)
440 // Program GPIO Base Address
444 DEFAULT_PCI_BUS_NUMBER_PCH
,
445 PCI_DEVICE_NUMBER_PCH_LPC
,
446 PCI_FUNCTION_NUMBER_PCH_LPC
,
449 (UINT16
)((GPIO_BASE_ADDRESS
& B_PCH_LPC_GPIO_BASE_BAR
) | B_PCH_LPC_GPIO_BASE_EN
)
453 // Set PMC Base Address
457 DEFAULT_PCI_BUS_NUMBER_PCH
,
458 PCI_DEVICE_NUMBER_PCH_LPC
,
459 PCI_FUNCTION_NUMBER_PCH_LPC
,
462 (UINT32
)((PMC_BASE_ADDRESS
& B_PCH_LPC_PMC_BASE_BAR
) | B_PCH_LPC_PMC_BASE_EN
)
466 // Set IO Base Address
470 DEFAULT_PCI_BUS_NUMBER_PCH
,
471 PCI_DEVICE_NUMBER_PCH_LPC
,
472 PCI_FUNCTION_NUMBER_PCH_LPC
,
475 (UINT32
)((IO_BASE_ADDRESS
& B_PCH_LPC_IO_BASE_BAR
) | B_PCH_LPC_IO_BASE_EN
)
479 // Set ILB Base Address
483 DEFAULT_PCI_BUS_NUMBER_PCH
,
484 PCI_DEVICE_NUMBER_PCH_LPC
,
485 PCI_FUNCTION_NUMBER_PCH_LPC
,
488 (UINT32
)((ILB_BASE_ADDRESS
& B_PCH_LPC_ILB_BASE_BAR
) | B_PCH_LPC_ILB_BASE_EN
)
492 // Set PUnit Base Address
496 DEFAULT_PCI_BUS_NUMBER_PCH
,
497 PCI_DEVICE_NUMBER_PCH_LPC
,
498 PCI_FUNCTION_NUMBER_PCH_LPC
,
501 (UINT32
)((PUNIT_BASE_ADDRESS
& B_PCH_LPC_PUNIT_BASE_BAR
) | B_PCH_LPC_PUNIT_BASE_EN
)
505 // Set SPI Base Address
509 DEFAULT_PCI_BUS_NUMBER_PCH
,
510 PCI_DEVICE_NUMBER_PCH_LPC
,
511 PCI_FUNCTION_NUMBER_PCH_LPC
,
514 (UINT32
)((SPI_BASE_ADDRESS
& B_PCH_LPC_SPI_BASE_BAR
) | B_PCH_LPC_SPI_BASE_EN
)
518 // Set Root Complex Base Address
522 DEFAULT_PCI_BUS_NUMBER_PCH
,
523 PCI_DEVICE_NUMBER_PCH_LPC
,
524 PCI_FUNCTION_NUMBER_PCH_LPC
,
527 (UINT32
)((RCBA_BASE_ADDRESS
& B_PCH_LPC_RCBA_BAR
) | B_PCH_LPC_RCBA_EN
)
531 // Set MPHY Base Address
535 DEFAULT_PCI_BUS_NUMBER_PCH
,
536 PCI_DEVICE_NUMBER_PCH_LPC
,
537 PCI_FUNCTION_NUMBER_PCH_LPC
,
540 (UINT32
)((MPHY_BASE_ADDRESS
& B_PCH_LPC_MPHY_BASE_BAR
) | B_PCH_LPC_MPHY_BASE_EN
)
544 DEFAULT_PCI_BUS_NUMBER_PCH
,
545 PCI_DEVICE_NUMBER_PCH_SMBUS
,
546 PCI_FUNCTION_NUMBER_PCH_SMBUS
,
549 (UINT16
)(SMBUS_BASE_ADDRESS
& B_PCH_SMBUS_BASE_BAR
)
554 DEFAULT_PCI_BUS_NUMBER_PCH
,
555 PCI_DEVICE_NUMBER_PCH_SMBUS
,
556 PCI_FUNCTION_NUMBER_PCH_SMBUS
,
559 B_PCH_SMBUS_PCICMD_IOSE
565 This is the entrypoint of PEIM
567 @param FileHandle Handle of the file being invoked.
568 @param PeiServices Describes the list of possible PEI Services.
570 @retval EFI_SUCCESS if it completed successfully.
575 IN EFI_PEI_FILE_HANDLE FileHandle
,
576 IN CONST EFI_PEI_SERVICES
**PeiServices
580 EFI_PLATFORM_INFO_HOB PlatformInfo
;
581 EFI_STATUS Status
= EFI_SUCCESS
;
582 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*Variable
= NULL
;
584 SYSTEM_CONFIGURATION SystemConfiguration
;
587 EFI_PEI_PPI_DESCRIPTOR
*mVlvMmioPolicyPpiDesc
;
588 VLV_MMIO_POLICY_PPI
*mVlvMmioPolicyPpi
;
590 ZeroMem (&PlatformInfo
, sizeof(PlatformInfo
));
592 Status
= InstallMonoStatusCode(FileHandle
, PeiServices
);
593 ASSERT_EFI_ERROR (Status
);
597 // Initialize Stall PPIs
599 Status
= (*PeiServices
)->InstallPpi (PeiServices
, &mInstallStallPpi
[0]);
600 ASSERT_EFI_ERROR (Status
);
602 Status
= (*PeiServices
)->NotifyPpi (PeiServices
, &mMemoryDiscoveredNotifyList
[0]);
603 ASSERT_EFI_ERROR (Status
);
604 SmbusRegBase
= PchPciDeviceMmBase (
605 DEFAULT_PCI_BUS_NUMBER_PCH
,
606 PCI_DEVICE_NUMBER_PCH_SMBUS
,
607 PCI_FUNCTION_NUMBER_PCH_SMBUS
610 // Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves
612 MmioAndThenOr32 (SmbusRegBase
+ R_PCH_SMBUS_BASE
, B_PCH_SMBUS_BASE_BAR
, SMBUS_BASE_ADDRESS
);
614 MmioOr8 (SmbusRegBase
+ R_PCH_SMBUS_PCICMD
, B_PCH_SMBUS_PCICMD_IOSE
);
619 //Todo: confirm if we need program 8254
622 // Program timer 1 as refresh timer
624 IoWrite8 (0x43, 0x54);
625 IoWrite8 (0x41, 0x12);
628 // RTC power failure handling
630 RtcPowerFailureHandler (PeiServices
);
633 PchMmPci32( 0, 0, 2, 0, 0x50) = 0x210;
635 VariableSize
= sizeof (SYSTEM_CONFIGURATION
);
636 ZeroMem (&SystemConfiguration
, VariableSize
);
639 // Obtain variable services
641 Status
= (*PeiServices
)->LocatePpi(
643 &gEfiPeiReadOnlyVariable2PpiGuid
,
648 ASSERT_EFI_ERROR(Status
);
649 Status
= Variable
->GetVariable (
652 &gEfiSetupVariableGuid
,
657 ASSERT_EFI_ERROR(Status
);
658 if (EFI_ERROR (Status
)) {
659 GGC
= ((2 << 3) | 0x200);
660 PciCfg16Write(EC_BASE
, 0, 2, 0, 0x50, GGC
);
661 GGC
= PciCfg16Read(EC_BASE
, 0, 2, 0, 0x50);
662 DEBUG((EFI_D_INFO
, "GGC: 0x%08x GMSsize:0x%08x\n", GGC
, (GGC
& (BIT7
|BIT6
|BIT5
|BIT4
|BIT3
))>>3));
664 if (SystemConfiguration
.Igd
== 1 && SystemConfiguration
.PrimaryVideoAdaptor
!= 2) {
665 GGC
= (SystemConfiguration
.IgdDvmt50PreAlloc
<< 3) |
666 (SystemConfiguration
.GTTSize
== GTT_SIZE_1MB
? 0x100: 0x200);
667 PciCfg16Write(EC_BASE
, 0, 2, 0, 0x50, GGC
);
668 GGC
= PciCfg16Read(EC_BASE
, 0, 2, 0, 0x50);
669 DEBUG((EFI_D_INFO
, "GGC: 0x%08x GMSsize:0x%08x\n", GGC
, (GGC
& (BIT7
|BIT6
|BIT5
|BIT4
|BIT3
))>>3));
674 // Initialize PlatformInfo HOB
676 Status
= ReadPlatformIds(PeiServices
, &PlatformInfo
);
677 ASSERT_EFI_ERROR (Status
);
680 // 0 -> Disable , 1 -> Enable
682 if(SystemConfiguration
.CfioPnpSettings
== 1) {
683 DEBUG((EFI_D_INFO
, "CheckCfioPnpSettings: CFIO Pnp Settings Enabled\n"));
684 PlatformInfo
.CfioEnabled
= 1;
686 DEBUG((EFI_D_INFO
, "CheckCfioPnpSettings: CFIO Pnp Settings Disabled\n"));
687 PlatformInfo
.CfioEnabled
= 0;
691 // Build HOB for PlatformInfo
694 &gEfiPlatformInfoGuid
,
696 sizeof (EFI_PLATFORM_INFO_HOB
)
701 // Set the new boot mode for MRC
703 #ifdef NOCS_S3_SUPPORT
704 Status
= UpdateBootMode (PeiServices
);
705 ASSERT_EFI_ERROR (Status
);
708 DEBUG((EFI_D_INFO
, "Setup MMIO size ... \n\n"));
713 Status
= (*PeiServices
)->AllocatePool(
715 sizeof (EFI_PEI_PPI_DESCRIPTOR
),
716 (void **)&mVlvMmioPolicyPpiDesc
718 ASSERT_EFI_ERROR (Status
);
719 Status
= (*PeiServices
)->AllocatePool(
721 sizeof (VLV_MMIO_POLICY_PPI
),
722 (void **)&mVlvMmioPolicyPpi
724 ASSERT_EFI_ERROR (Status
);
725 (*PeiServices
)->SetMem (
726 (VOID
*)mVlvMmioPolicyPpi
,
727 sizeof (VLV_MMIO_POLICY_PPI
),
730 mVlvMmioPolicyPpiDesc
->Flags
= EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
;
731 mVlvMmioPolicyPpiDesc
->Guid
= &gVlvMmioPolicyPpiGuid
;
732 mVlvMmioPolicyPpiDesc
->Ppi
= mVlvMmioPolicyPpi
;
733 switch (SystemConfiguration
.MmioSize
) {
735 mVlvMmioPolicyPpi
->MmioSize
= 0x300;
738 mVlvMmioPolicyPpi
->MmioSize
= 0x400;
741 mVlvMmioPolicyPpi
->MmioSize
= 0x500;
744 mVlvMmioPolicyPpi
->MmioSize
= 0x600;
747 mVlvMmioPolicyPpi
->MmioSize
= 0x800;
750 mVlvMmioPolicyPpi
->MmioSize
= 0x800;
753 Status
= (*PeiServices
)->InstallPpi(
755 mVlvMmioPolicyPpiDesc
757 ASSERT_EFI_ERROR (Status
);
764 IN CONST EFI_PEI_SERVICES
**PeiServices
,
765 IN OUT EFI_PLATFORM_INFO_HOB
*PlatformInfoHob
769 EFI_STATUS Status
= EFI_SUCCESS
;
772 EFI_PLATFORM_INFO_HOB TmpHob
;
773 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*PeiVar
;
775 Status
= (**PeiServices
).LocatePpi (
777 &gEfiPeiReadOnlyVariable2PpiGuid
,
782 ASSERT_EFI_ERROR (Status
);
784 DataSize
= sizeof (EFI_PLATFORM_INFO_HOB
);
785 Status
= PeiVar
->GetVariable (
788 &gEfiVlv2VariableGuid
,
794 if (Status
== EFI_SUCCESS
) {
795 PlatformInfoHob
->BoardId
= TmpHob
.BoardId
;
796 PlatformInfoHob
->MemCfgID
= TmpHob
.MemCfgID
;
797 PlatformInfoHob
->BoardRev
= TmpHob
.BoardRev
;
798 PlatformInfoHob
->PlatformFlavor
= TmpHob
.PlatformFlavor
;
803 PlatformInfoHob
->BoardId
= BOARD_ID_MINNOW2
;
804 DEBUG ((EFI_D_INFO
, "I'm Minnow2!\n"));
806 PlatformInfoHob
->MemCfgID
= 0;
807 PlatformInfoHob
->BoardRev
= FabId
+ 1; // FabId = 0 means FAB1 (BoardRev = 1), FabId = 1 means FAB2 (BoardRev = 2)...
808 PlatformInfoHob
->PlatformFlavor
= FlavorMobile
;
815 // Start::Alpine Valley platform
818 This routine reads SysCtl registers
820 @param SmbusBase SMBUS Base Address
821 @param SlvAddr Targeted Smbus Slave device address
822 @param Operation Which SMBus protocol will be used
823 @param Offset Offset of the register
824 @param Length Number of bytes
825 @param Buffer Buffer contains values read from registers
827 @retval SUCCESS as passed
828 @retval Others as failed
841 EFI_STATUS Status
=EFI_SUCCESS
;
843 UINT8 SmbusOperation
= 0;
847 UINT8 BlockCount
= 0;
848 BOOLEAN BufferTooSmall
;
851 UINT8 RetryCount
= BUS_TRIES
;
854 // MrcSmbusExec supports byte and block read.
855 // Only allow Byte or block access
857 if (!((*Length
== AV_SC_BYTE_LEN
) || (*Length
== AV_SC_BLOCK_LEN
))) {
858 return EFI_INVALID_PARAMETER
;
862 // See if its ok to use the bus based upon INUSE_STS bit.
864 Status
= AcquireBus (SmbusBase
);
865 ASSERT_EFI_ERROR(Status
);
870 //SmbStatus Bits of interest
871 //[6] = IUS (In Use Status)
873 //[3] = BERR (Bus Error = transaction collision)
874 //[2] = DERR (Device Error = Illegal Command Field, Unclaimed Cycle, Host Device Timeout, CRC Error)
875 //[1] = INTR (Successful completion of last command)
879 // This is the main operation loop. If the operation results in a Smbus
880 // collision with another master on the bus, it attempts the requested
881 // transaction again at least BUS_TRIES attempts.
883 while (RetryCount
--) {
885 // Operation Specifics (pre-execution)
887 Status
= EFI_SUCCESS
;
888 SlvAddrReg
= SlvAddr
;
894 case SMBUS_WRITE_BYTE
:
895 IoWrite8 (SmbusBase
+R_PCH_SMBUS_HD0
, CallBuffer
[0]);
896 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BYTE_DATA
;
899 case SMBUS_READ_BYTE
:
900 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BYTE_DATA
;
901 SlvAddrReg
|= B_PCH_SMBUS_RW_SEL_READ
;
903 Status
= EFI_INVALID_PARAMETER
;
908 case SMBUS_WRITE_BLOCK
:
909 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BLOCK
;
910 IoWrite8 (SmbusBase
+R_PCH_SMBUS_HD0
, *(UINT8
*) Length
);
911 BlockCount
= (UINT8
) (*Length
);
912 if ((*Length
< 1) || (*Length
> 32)) {
913 Status
= EFI_INVALID_PARAMETER
;
916 AuxcReg
|= B_PCH_SMBUS_E32B
;
919 case SMBUS_READ_BLOCK
:
920 SmbusOperation
= V_PCH_SMBUS_SMB_CMD_BLOCK
;
921 SlvAddrReg
|= B_PCH_SMBUS_RW_SEL_READ
;
922 if ((*Length
< 1) || (*Length
> 32)) {
923 Status
= EFI_INVALID_PARAMETER
;
926 AuxcReg
|= B_PCH_SMBUS_E32B
;
930 Status
= EFI_INVALID_PARAMETER
;
935 // Set Auxiliary Control register
937 IoWrite8 (SmbusBase
+R_PCH_SMBUS_AUXC
, AuxcReg
);
940 // Reset the pointer of the internal buffer
942 IoRead8 (SmbusBase
+R_PCH_SMBUS_HCTL
);
945 // Now that the 32 byte buffer is turned on, we can write th block data
948 if (Operation
== SMBUS_WRITE_BLOCK
) {
949 for (Index
= 0; Index
< BlockCount
; Index
++) {
953 IoWrite8 (SmbusBase
+R_PCH_SMBUS_HBD
, CallBuffer
[Index
]);
958 // Set SMBus slave address for the device to read
960 IoWrite8(SmbusBase
+R_PCH_SMBUS_TSA
, SlvAddrReg
);
964 // Set Command register for the offset to read
966 IoWrite8(SmbusBase
+R_PCH_SMBUS_HCMD
, HostCmdReg
);
969 // Set Control Register to Set "operation command" protocol and start bit
971 IoWrite8(SmbusBase
+R_PCH_SMBUS_HCTL
, (UINT8
) (SmbusOperation
+ B_PCH_SMBUS_START
));
974 // Wait for IO to complete
976 do { StsReg
= (UINT8
) IoRead8(SmbusBase
+0); } while ((StsReg
& (BIT4
|BIT3
|BIT2
|BIT1
)) == 0);
978 if (StsReg
& B_PCH_SMBUS_DERR
) {
979 Status
= EFI_DEVICE_ERROR
;
981 } else if (StsReg
& B_PCH_SMBUS_BERR
) {
983 // Clear the Bus Error for another try
985 Status
= EFI_DEVICE_ERROR
;
986 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_BERR
);
989 // Clear Status Registers
991 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_HSTS_ALL
);
992 IoWrite8(SmbusBase
+R_PCH_SMBUS_AUXS
, B_PCH_SMBUS_CRCE
);
998 // successfull completion
999 // Operation Specifics (post-execution)
1001 switch (Operation
) {
1003 case SMBUS_READ_BYTE
:
1004 CallBuffer
[0] = (UINT8
)(IoRead8 (SmbusBase
+R_PCH_SMBUS_HD0
));
1007 case SMBUS_WRITE_BLOCK
:
1008 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_BYTE_DONE_STS
);
1011 case SMBUS_READ_BLOCK
:
1012 BufferTooSmall
= FALSE
;
1015 // Find out how many bytes will be in the block
1017 BlockCount
= (UINT8
)(IoRead8 (SmbusBase
+R_PCH_SMBUS_HD0
));
1018 if (*Length
< BlockCount
) {
1019 BufferTooSmall
= TRUE
;
1021 for (Index
= 0; Index
< BlockCount
; Index
++) {
1025 CallBuffer
[Index
] = (UINT8
)IoRead8 (SmbusBase
+R_PCH_SMBUS_HBD
);
1029 *Length
= BlockCount
;
1030 if (BufferTooSmall
) {
1031 Status
= EFI_BUFFER_TOO_SMALL
;
1039 if ((StsReg
& B_PCH_SMBUS_BERR
) && (Status
== EFI_SUCCESS
)) {
1041 // Clear the Bus Error for another try
1043 Status
= EFI_DEVICE_ERROR
;
1044 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_BERR
);
1053 // Clear Status Registers and exit
1055 IoWrite8(SmbusBase
+R_PCH_SMBUS_HSTS
, B_PCH_SMBUS_HSTS_ALL
);
1056 IoWrite8(SmbusBase
+R_PCH_SMBUS_AUXS
, B_PCH_SMBUS_CRCE
);
1057 IoWrite8(SmbusBase
+R_PCH_SMBUS_AUXC
, 0);
1061 // End::Alpine Valley platform