2 This PEIM initialize platform for MRC, following action is performed,
5 3. Detect video adapter to determine whether we need pre allocated memory
6 4. Calls MRC to initialize memory and install a PPI notify to do post memory initialization.
7 This file contains the main entrypoint of the PEIM.
9 Copyright (c) 2013 - 2016 Intel Corporation.
11 This program and the accompanying materials
12 are licensed and made available under the terms and conditions of the BSD License
13 which accompanies this distribution. The full text of the license may be found at
14 http://opensource.org/licenses/bsd-license.php
16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 #include "CommonHeader.h"
23 #include "PlatformEarlyInit.h"
24 #include "PeiFvSecurity.h"
28 EndOfPeiSignalPpiNotifyCallback (
29 IN EFI_PEI_SERVICES
**PeiServices
,
30 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
35 // Function prototypes to routines implemented in other source modules
36 // within this component.
41 PlatformErratasPostMrc (
46 // The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory
48 BOOLEAN ImageInMemory
= FALSE
;
50 BOARD_LEGACY_GPIO_CONFIG mBoardLegacyGpioConfigTable
[] = { PLATFORM_LEGACY_GPIO_TABLE_DEFINITION
};
51 UINTN mBoardLegacyGpioConfigTableLen
= (sizeof(mBoardLegacyGpioConfigTable
) / sizeof(BOARD_LEGACY_GPIO_CONFIG
));
52 BOARD_GPIO_CONTROLLER_CONFIG mBoardGpioControllerConfigTable
[] = { PLATFORM_GPIO_CONTROLLER_CONFIG_DEFINITION
};
53 UINTN mBoardGpioControllerConfigTableLen
= (sizeof(mBoardGpioControllerConfigTable
) / sizeof(BOARD_GPIO_CONTROLLER_CONFIG
));
54 UINT8 ChipsetDefaultMac
[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
56 EFI_PEI_PPI_DESCRIPTOR mPpiBootMode
[1] = {
58 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
59 &gEfiPeiMasterBootModePpiGuid
,
64 EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList
[1] = {
66 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
67 &gEfiPeiMemoryDiscoveredPpiGuid
,
68 MemoryDiscoveredPpiNotifyCallback
72 EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiSignalPpiNotifyList
[1] = {
74 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
75 &gEfiEndOfPeiSignalPpiGuid
,
76 EndOfPeiSignalPpiNotifyCallback
80 EFI_PEI_STALL_PPI mStallPpi
= {
85 EFI_PEI_PPI_DESCRIPTOR mPpiStall
[1] = {
87 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
94 Set Mac address on chipset ethernet device.
96 @param Bus PCI Bus number of chipset ethernet device.
97 @param Device Device number of chipset ethernet device.
98 @param Func PCI Function number of chipset ethernet device.
99 @param MacAddr MAC Address to set.
104 SetLanControllerMacAddr (
106 IN CONST UINT8 Device
,
108 IN CONST UINT8
*MacAddr
,
117 volatile UINT8
*Wrote
;
122 DevPcieAddr
= PCI_LIB_ADDRESS (
130 // Do nothing if not a supported device.
132 PciVid
= PciRead16 (DevPcieAddr
+ PCI_VENDOR_ID_OFFSET
);
133 PciDid
= PciRead16 (DevPcieAddr
+ PCI_DEVICE_ID_OFFSET
);
134 if((PciVid
!= V_IOH_MAC_VENDOR_ID
) || (PciDid
!= V_IOH_MAC_DEVICE_ID
)) {
139 // Save current settings for PCI CMD/BAR registers
141 SaveCmdReg
= PciRead16 (DevPcieAddr
+ PCI_COMMAND_OFFSET
);
142 SaveBarReg
= PciRead32 (DevPcieAddr
+ R_IOH_MAC_MEMBAR
);
145 // Use predefined tempory memory resource
147 PciWrite32 ( DevPcieAddr
+ R_IOH_MAC_MEMBAR
, Bar0
);
148 PciWrite8 ( DevPcieAddr
+ PCI_COMMAND_OFFSET
, EFI_PCI_COMMAND_MEMORY_SPACE
);
150 Addr
= Bar0
+ R_IOH_MAC_GMAC_REG_8
;
151 MacVer
= *((volatile UINT32
*) (UINTN
)(Addr
));
153 DEBUG ((EFI_D_INFO
, "Ioh MAC [B:%d, D:%d, F:%d] VER:%04x ADDR:",
161 // Set MAC Address0 Low Register (GMAC_REG_17) ADDRLO bits.
163 Addr
= Bar0
+ R_IOH_MAC_GMAC_REG_17
;
164 Data32
= *((UINT32
*) (UINTN
)(&MacAddr
[0]));
165 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
166 Wrote
= (volatile UINT8
*) (UINTN
)(Addr
);
167 DEBUG ((EFI_D_INFO
, "%02x-%02x-%02x-%02x-",
175 // Set MAC Address0 High Register (GMAC_REG_16) ADDRHI bits
176 // and Address Enable (AE) bit.
178 Addr
= Bar0
+ R_IOH_MAC_GMAC_REG_16
;
180 ((UINT32
) MacAddr
[4]) |
181 (((UINT32
)MacAddr
[5]) << 8) |
183 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
184 Wrote
= (volatile UINT8
*) (UINTN
)(Addr
);
186 DEBUG ((EFI_D_INFO
, "%02x-%02x\n", (UINTN
) Wrote
[0], (UINTN
) Wrote
[1]));
189 // Restore settings for PCI CMD/BAR registers
191 PciWrite32 ((DevPcieAddr
+ R_IOH_MAC_MEMBAR
), SaveBarReg
);
192 PciWrite16 (DevPcieAddr
+ PCI_COMMAND_OFFSET
, SaveCmdReg
);
196 Initialize state of I2C GPIO expanders.
198 @param PlatformType Platform type for GPIO expander init.
202 EarlyPlatformConfigGpioExpanders (
203 IN CONST EFI_PLATFORM_TYPE PlatformType
207 EFI_I2C_DEVICE_ADDRESS I2CSlaveAddress
;
213 // Configure GPIO expanders for Galileo Gen 2
214 // Route I2C pins to Arduino header
215 // Set all GPIO expander pins connected to the Reset Button as inputs
217 if (PlatformType
== GalileoGen2
) {
219 // Configure AMUX1_IN (EXP2.P1_4) as an output
221 PlatformPcal9555GpioSetDir (
222 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR
, // IO Expander 2.
224 FALSE
// Configure as output
228 // Set AMUX1_IN(EXP2.P1_4) low to route I2C to Arduino Shield connector
230 PlatformPcal9555GpioSetLevel (
231 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR
, // IO Expander 2.
237 // Configure Reset Button(EXP1.P1_7) as an input
239 PlatformPcal9555GpioSetDir (
240 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR
, // IO Expander 1.
246 // Disable pullup on Reset Button(EXP1.P1_7)
248 PlatformPcal9555GpioDisablePull (
249 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR
, // IO Expander 1.
254 // Configure Reset Button(EXP2.P1_7) as an input
256 PlatformPcal9555GpioSetDir (
257 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR
, // IO Expander 2.
263 // Disable pullup on Reset Button(EXP2.P1_7)
265 PlatformPcal9555GpioDisablePull (
266 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR
, // IO Expander 2.
272 // Configure GPIO expanders for Galileo Gen 2
273 // Set all GPIO expander pins connected to the Reset Button as inputs
274 // Route I2C pins to Arduino header
276 if (PlatformType
== Galileo
) {
278 // Detect the I2C Slave Address of the GPIO Expander
280 if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL
, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO
)) {
281 I2CSlaveAddress
.I2CDeviceAddress
= GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR
;
283 I2CSlaveAddress
.I2CDeviceAddress
= GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR
;
285 DEBUG ((EFI_D_INFO
, "Galileo GPIO Expender Slave Address = %02x\n", I2CSlaveAddress
.I2CDeviceAddress
));
288 // Set I2C_MUX (GPORT1_BIT5) low to route I2C to Arduino Shield connector
292 // Select GPIO Expander GPORT1
295 Buffer
[0] = 0x18; //sub-address
296 Buffer
[1] = 0x01; //data
297 Status
= I2cWriteMultipleByte (
299 EfiI2CSevenBitAddrMode
,
303 ASSERT_EFI_ERROR (Status
);
306 // Read "Pin Direction" of GPIO Expander GPORT1
311 Status
= I2cReadMultipleByte (
313 EfiI2CSevenBitAddrMode
,
318 ASSERT_EFI_ERROR (Status
);
321 // Configure GPIO Expander GPORT1_BIT5 as an output
324 Buffer
[0] = 0x1C; //sub-address
325 Buffer
[1] = (UINT8
)(Buffer
[1] & (~BIT5
)); //data
327 Status
= I2cWriteMultipleByte (
329 EfiI2CSevenBitAddrMode
,
333 ASSERT_EFI_ERROR (Status
);
336 // Set GPIO Expander GPORT1_BIT5 low
339 Buffer
[0] = 0x09; //sub-address
340 Buffer
[1] = (UINT8
)(~BIT5
); //data
342 Status
= I2cWriteMultipleByte (
344 EfiI2CSevenBitAddrMode
,
348 ASSERT_EFI_ERROR (Status
);
351 // Configure RESET_N_SHLD (GPORT5_BIT0) and SW_RESET_N_SHLD (GPORT5_BIT1) as inputs
355 // Select GPIO Expander GPORT5
360 Status
= I2cWriteMultipleByte (
362 EfiI2CSevenBitAddrMode
,
366 ASSERT_EFI_ERROR (Status
);
369 // Read "Pin Direction" of GPIO Expander GPORT5
374 Status
= I2cReadMultipleByte (
376 EfiI2CSevenBitAddrMode
,
381 ASSERT_EFI_ERROR (Status
);
384 // Configure GPIO Expander GPORT5_BIT0 and GPORT5_BIT1 as inputs
388 Buffer
[1] = Buffer
[1] | BIT0
| BIT1
;
389 Status
= I2cWriteMultipleByte (
391 EfiI2CSevenBitAddrMode
,
395 ASSERT_EFI_ERROR (Status
);
402 This is the entrypoint of PEIM
404 @param FileHandle Handle of the file being invoked.
405 @param PeiServices Describes the list of possible PEI Services.
407 @retval EFI_SUCCESS if it completed successfully.
412 IN EFI_PEI_FILE_HANDLE FileHandle
,
413 IN CONST EFI_PEI_SERVICES
**PeiServices
417 EFI_BOOT_MODE BootMode
;
418 EFI_PEI_STALL_PPI
*StallPpi
;
419 EFI_PEI_PPI_DESCRIPTOR
*StallPeiPpiDescriptor
;
420 EFI_FV_FILE_INFO FileInfo
;
421 EFI_PLATFORM_TYPE PlatformType
;
423 PlatformType
= (EFI_PLATFORM_TYPE
)PcdGet16 (PcdPlatformType
);
426 // Initialize Firmware Volume security.
427 // This must be done before any firmware volume accesses (excl. BFV)
429 Status
= PeiInitializeFvSecurity();
430 ASSERT_EFI_ERROR (Status
);
433 // Do any early platform specific initialization.
435 EarlyPlatformInit ();
438 // This is a second path on entry, in recovery boot path the Stall PPI need to be memory-based
439 // to improve recovery performance.
441 Status
= PeiServicesFfsGetFileInfo (FileHandle
, &FileInfo
);
442 ASSERT_EFI_ERROR (Status
);
444 // The follow conditional check only works for memory-mapped FFS,
445 // so we ASSERT that the file is really a MM FFS.
447 ASSERT (FileInfo
.Buffer
!= NULL
);
448 if (!(((UINTN
) FileInfo
.Buffer
<= (UINTN
) PeiInitPlatform
) &&
449 ((UINTN
) PeiInitPlatform
<= (UINTN
) FileInfo
.Buffer
+ FileInfo
.BufferSize
))) {
451 // Now that module in memory, update the
452 // PPI that describes the Stall to other modules
454 Status
= PeiServicesLocatePpi (
455 &gEfiPeiStallPpiGuid
,
457 &StallPeiPpiDescriptor
,
461 if (!EFI_ERROR (Status
)) {
463 Status
= PeiServicesReInstallPpi (
464 StallPeiPpiDescriptor
,
469 Status
= PeiServicesInstallPpi (&mPpiStall
[0]);
475 // Initialize System Phys
482 // Do platform specific logic to create a boot mode
484 Status
= UpdateBootMode ((EFI_PEI_SERVICES
**)PeiServices
, &BootMode
);
485 ASSERT_EFI_ERROR (Status
);
488 // Signal possible dependent modules that there has been a
489 // final boot mode determination
491 if (!EFI_ERROR(Status
)) {
492 Status
= PeiServicesInstallPpi (&mPpiBootMode
[0]);
493 ASSERT_EFI_ERROR (Status
);
496 if (BootMode
!= BOOT_ON_S3_RESUME
) {
497 QNCClearSmiAndWake ();
500 DEBUG ((EFI_D_INFO
, "MRC Entry\n"));
501 MemoryInit ((EFI_PEI_SERVICES
**)PeiServices
);
504 // Do Early PCIe init.
506 DEBUG ((EFI_D_INFO
, "Early PCIe controller initialization\n"));
507 PlatformPciExpressEarlyInit (PlatformType
);
510 DEBUG ((EFI_D_INFO
, "Platform Erratas After MRC\n"));
511 PlatformErratasPostMrc ();
516 DEBUG ((EFI_D_INFO
, "EarlyPlatformConfigGpioExpanders ()\n"));
517 EarlyPlatformConfigGpioExpanders (PlatformType
);
520 // Now that all of the pre-permanent memory activities have
521 // been taken care of, post a call-back for the permanent-memory
522 // resident services, such as HOB construction.
523 // PEI Core will switch stack after this PEIM exit. After that the MTRR
526 Status
= PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList
[0]);
527 ASSERT_EFI_ERROR (Status
);
530 if (BootMode != BOOT_ON_S3_RESUME) {
531 Status = PeiServicesNotifyPpi (mEndOfPeiSignalPpiNotifyList);
532 ASSERT_EFI_ERROR (Status);
535 if (BootMode
== BOOT_IN_RECOVERY_MODE
) {
536 PeiServicesRegisterForShadow (FileHandle
);
544 EndOfPeiSignalPpiNotifyCallback (
545 IN EFI_PEI_SERVICES
**PeiServices
,
546 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
552 DEBUG ((EFI_D_INFO
, "End of PEI Signal Callback\n"));
555 // Restore the flash region to be UC
556 // for both normal boot as we build a Resource Hob to
557 // describe this region as UC to DXE core.
559 WriteBackInvalidateDataCacheRange (
560 (VOID
*) (UINTN
) PcdGet32 (PcdFlashAreaBaseAddress
),
561 PcdGet32 (PcdFlashAreaSize
)
564 Status
= MtrrSetMemoryAttribute (PcdGet32 (PcdFlashAreaBaseAddress
), PcdGet32 (PcdFlashAreaSize
), CacheUncacheable
);
565 ASSERT_EFI_ERROR (Status
);
571 This function will initialize USB Phy registers associated with QuarkSouthCluster.
573 @param VOID No Argument
575 @retval EFI_SUCCESS All registers have been initialized
585 /** In order to configure the PHY to use clk120 (ickusbcoreclk) as PLL reference clock
586 * and Port2 as a USB device port, the following sequence must be followed
590 // Sideband register write to USB AFE (Phy)
591 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_GLOBAL_PORT
);
592 RegData32
&= ~(BIT1
);
594 // Sighting #4930631 PDNRESCFG [8:7] of USB2_GLOBAL_PORT = 11b.
595 // For port 0 & 1 as host and port 2 as device.
597 RegData32
|= (BIT8
| BIT7
);
598 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_GLOBAL_PORT
, RegData32
);
601 // Sighting #4930653 Required BIOS change on Disconnect vref to change to 600mV.
603 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_COMPBG
);
604 RegData32
&= ~(BIT10
| BIT9
| BIT8
| BIT7
);
605 RegData32
|= (BIT10
| BIT7
);
606 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_COMPBG
, RegData32
);
608 // Sideband register write to USB AFE (Phy)
609 // (pllbypass) to bypass/Disable PLL before switch
610 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
);
612 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
, RegData32
);
614 // Sideband register write to USB AFE (Phy)
615 // (coreclksel) to select 120MHz (ickusbcoreclk) clk source.
616 // (Default 0 to select 96MHz (ickusbclk96_npad/ppad))
617 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL1
);
619 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL1
, RegData32
);
621 // Sideband register write to USB AFE (Phy)
622 // (divide by 8) to achieve internal 480MHz clock
623 // for 120MHz input refclk. (Default: 4'b1000 (divide by 10) for 96MHz)
624 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL1
);
625 RegData32
&= ~(BIT5
| BIT4
| BIT3
);
627 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL1
, RegData32
);
629 // Sideband register write to USB AFE (Phy)
631 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
);
633 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
, RegData32
);
635 // Sideband register write to USB AFE (Phy)
636 // Set (startlock) to force the PLL FSM to restart the lock
637 // sequence due to input clock/freq switch.
638 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
);
640 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
, RegData32
);
642 // At this point the PLL FSM and COMP FSM will complete
647 This function provides early platform Thermal sensor initialisation.
651 EarlyPlatformThermalSensorInit (
655 DEBUG ((EFI_D_INFO
, "Early Platform Thermal Sensor Init\n"));
658 // Set Thermal sensor mode.
660 QNCThermalSensorSetRatiometricMode ();
663 // Enable RMU Thermal sensor with a Catastrophic Trip point.
665 QNCThermalSensorEnableWithCatastrophicTrip (PLATFORM_CATASTROPHIC_TRIP_CELSIUS
);
668 // Lock all RMU Thermal sensor control & trip point registers.
670 QNCThermalSensorLockAllRegisters ();
674 Print early platform info messages includeing the Stage1 module that's
675 running, MFH item list and platform data item list.
679 EarlyPlatformInfoMessages (
684 QUARK_EDKII_STAGE1_HEADER
*Edk2ImageHeader
;
687 // Find which 'Stage1' image we are running and print the details
689 Edk2ImageHeader
= (QUARK_EDKII_STAGE1_HEADER
*) PcdGet32 (PcdEsramStage1Base
);
690 DEBUG ((EFI_D_INFO
, "\n************************************************************\n"));
692 switch ((UINT8
)Edk2ImageHeader
->ImageIndex
& QUARK_STAGE1_IMAGE_TYPE_MASK
) {
693 case QUARK_STAGE1_BOOT_IMAGE_TYPE
:
694 DEBUG ((EFI_D_INFO
, "**** Quark EDKII Stage 1 Boot Image %d ****\n", ((UINT8
)Edk2ImageHeader
->ImageIndex
& ~(QUARK_STAGE1_IMAGE_TYPE_MASK
))));
697 case QUARK_STAGE1_RECOVERY_IMAGE_TYPE
:
698 DEBUG ((EFI_D_INFO
, "**** Quark EDKII Stage 1 Recovery Image %d ****\n", ((UINT8
)Edk2ImageHeader
->ImageIndex
& ~(QUARK_STAGE1_IMAGE_TYPE_MASK
))));
702 DEBUG ((EFI_D_INFO
, "**** Quark EDKII Unknown Stage 1 Image !!!! ****\n"));
707 "**** Quark EDKII Stage 2 Image 0x%08X:0x%08X ****\n" ,
708 (UINTN
) PcdGet32 (PcdFlashFvMainBase
),
709 (UINTN
) PcdGet32 (PcdFlashFvMainSize
)
714 "**** Quark EDKII Payload Image 0x%08X:0x%08X ****\n" ,
715 (UINTN
) PcdGet32 (PcdFlashFvPayloadBase
),
716 (UINTN
) PcdGet32 (PcdFlashFvPayloadSize
)
719 DEBUG ((EFI_D_INFO
, "************************************************************\n\n"));
725 Check if system reset due to error condition.
727 @param ClearErrorBits If TRUE clear error flags and value bits.
729 @retval TRUE if system reset due to error condition.
730 @retval FALSE if NO reset error conditions.
733 CheckForResetDueToErrors (
734 IN BOOLEAN ClearErrorBits
738 BOOLEAN ResetDueToError
;
740 ResetDueToError
= FALSE
;
743 // Check if RMU reset system due to access violations.
744 // RMU updates a SOC Unit register before reseting the system.
746 RegValue
= QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID
, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW
);
747 if ((RegValue
& B_CFG_STICKY_RW_VIOLATION
) != 0) {
748 ResetDueToError
= TRUE
;
752 "\nReset due to access violation: %s %s %s %s\n",
753 ((RegValue
& B_CFG_STICKY_RW_IMR_VIOLATION
) != 0) ? L
"'IMR'" : L
".",
754 ((RegValue
& B_CFG_STICKY_RW_DECC_VIOLATION
) != 0) ? L
"'DECC'" : L
".",
755 ((RegValue
& B_CFG_STICKY_RW_SMM_VIOLATION
) != 0) ? L
"'SMM'" : L
".",
756 ((RegValue
& B_CFG_STICKY_RW_HMB_VIOLATION
) != 0) ? L
"'HMB'" : L
"."
762 if (ClearErrorBits
) {
763 RegValue
&= ~(B_CFG_STICKY_RW_VIOLATION
);
764 QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID
, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW
, RegValue
);
768 return ResetDueToError
;
772 This function provides early platform initialization.
774 @param PlatformInfo Pointer to platform Info structure.
783 EFI_PLATFORM_TYPE PlatformType
;
785 PlatformType
= (EFI_PLATFORM_TYPE
) PcdGet16 (PcdPlatformType
);
787 DEBUG ((EFI_D_INFO
, "EarlyPlatformInit for PlatType=0x%02x\n", (UINTN
) PlatformType
));
790 // Check if system reset due to error condition.
792 if (CheckForResetDueToErrors (TRUE
)) {
793 if(FeaturePcdGet (WaitIfResetDueToError
)) {
794 DEBUG ((EFI_D_ERROR
, "Press any key to continue.\n"));
795 PlatformDebugPortGetChar8 ();
800 // Display platform info messages.
802 EarlyPlatformInfoMessages ();
805 // Early Legacy Gpio Init.
807 EarlyPlatformLegacyGpioInit (PlatformType
);
810 // Early platform Legacy GPIO manipulation depending on GPIOs
811 // setup by EarlyPlatformLegacyGpioInit.
813 EarlyPlatformLegacyGpioManipulation (PlatformType
);
816 // Early platform specific GPIO Controller init & manipulation.
817 // Combined for sharing of temp. memory bar.
819 EarlyPlatformGpioCtrlerInitAndManipulation (PlatformType
);
822 // Early Thermal Sensor Init.
824 EarlyPlatformThermalSensorInit ();
827 // Early Lan Ethernet Mac Init.
829 EarlyPlatformMacInit (
830 PcdGetPtr (PcdIohEthernetMac0
),
831 PcdGetPtr (PcdIohEthernetMac1
)
836 This function provides early platform Legacy GPIO initialisation.
838 @param PlatformType Platform type for GPIO init.
843 EarlyPlatformLegacyGpioInit (
844 IN CONST EFI_PLATFORM_TYPE PlatformType
847 BOARD_LEGACY_GPIO_CONFIG
*LegacyGpioConfig
;
849 UINT32 GpioBaseAddress
;
852 // Assert if platform type outside table range.
854 ASSERT ((UINTN
) PlatformType
< mBoardLegacyGpioConfigTableLen
);
855 LegacyGpioConfig
= &mBoardLegacyGpioConfigTable
[(UINTN
) PlatformType
];
857 GpioBaseAddress
= (UINT32
)PcdGet16 (PcdGbaIoBaseAddress
);
861 // Program QNC GPIO Registers.
863 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGEN_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellEnable
;
864 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGEN_CORE_WELL
, NewValue
);
865 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGIO_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellIoSelect
;
866 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGIO_CORE_WELL
, NewValue
);
867 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGLVL_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellLvlForInputOrOutput
;
868 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGLVL_CORE_WELL
, NewValue
);
869 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGTPE_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellTriggerPositiveEdge
;
870 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGTPE_CORE_WELL
, NewValue
);
871 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGTNE_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellTriggerNegativeEdge
;
872 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGTNE_CORE_WELL
, NewValue
);
873 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGGPE_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellGPEEnable
;
874 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGGPE_CORE_WELL
, NewValue
);
875 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGSMI_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellSMIEnable
;
876 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGSMI_CORE_WELL
, NewValue
);
877 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGTS_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellTriggerStatus
;
878 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGTS_CORE_WELL
, NewValue
);
879 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CNMIEN_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellNMIEnable
;
880 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CNMIEN_CORE_WELL
, NewValue
);
882 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGEN_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellEnable
;
883 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGEN_RESUME_WELL
, NewValue
);
884 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGIO_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellIoSelect
;
885 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGIO_RESUME_WELL
, NewValue
) ;
886 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGLVL_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellLvlForInputOrOutput
;
887 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGLVL_RESUME_WELL
, NewValue
);
888 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGTPE_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellTriggerPositiveEdge
;
889 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGTPE_RESUME_WELL
, NewValue
);
890 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGTNE_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellTriggerNegativeEdge
;
891 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGTNE_RESUME_WELL
, NewValue
) ;
892 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGGPE_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellGPEEnable
;
893 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGGPE_RESUME_WELL
, NewValue
);
894 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGSMI_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellSMIEnable
;
895 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGSMI_RESUME_WELL
, NewValue
);
896 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGTS_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellTriggerStatus
;
897 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGTS_RESUME_WELL
, NewValue
) ;
898 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RNMIEN_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellNMIEnable
;
899 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RNMIEN_RESUME_WELL
, NewValue
);
903 Performs any early platform specific Legacy GPIO manipulation.
905 @param PlatformType Platform type GPIO manipulation.
910 EarlyPlatformLegacyGpioManipulation (
911 IN CONST EFI_PLATFORM_TYPE PlatformType
914 if (PlatformType
== CrossHill
) {
917 // Pull TPM reset low for 80us (equivalent to cold reset, Table 39
918 // Infineon SLB9645 Databook), then pull TPM reset high and wait for
919 // 150ms to give time for TPM to stabilise (Section 4.7.1 Infineon
920 // SLB9645 Databook states TPM is ready to receive command after 30ms
921 // but section 4.7 states some TPM commands may take longer to execute
922 // upto 150ms after test).
925 PlatformLegacyGpioSetLevel (
926 R_QNC_GPIO_RGLVL_RESUME_WELL
,
927 PLATFORM_RESUMEWELL_TPM_RST_GPIO
,
930 MicroSecondDelay (80);
932 PlatformLegacyGpioSetLevel (
933 R_QNC_GPIO_RGLVL_RESUME_WELL
,
934 PLATFORM_RESUMEWELL_TPM_RST_GPIO
,
937 MicroSecondDelay (150000);
943 Performs any early platform specific GPIO Controller init & manipulation.
945 @param PlatformType Platform type for GPIO init & manipulation.
950 EarlyPlatformGpioCtrlerInitAndManipulation (
951 IN CONST EFI_PLATFORM_TYPE PlatformType
957 BOARD_GPIO_CONTROLLER_CONFIG
*GpioConfig
;
964 ASSERT ((UINTN
) PlatformType
< mBoardGpioControllerConfigTableLen
);
965 GpioConfig
= &mBoardGpioControllerConfigTable
[(UINTN
) PlatformType
];
967 IohGpioBase
= (UINT32
) PcdGet64 (PcdIohGpioMmioBase
);
969 DevPcieAddr
= PCI_LIB_ADDRESS (
970 PcdGet8 (PcdIohGpioBusNumber
),
971 PcdGet8 (PcdIohGpioDevNumber
),
972 PcdGet8 (PcdIohGpioFunctionNumber
),
977 // Do nothing if not a supported device.
979 PciVid
= PciRead16 (DevPcieAddr
+ PCI_VENDOR_ID_OFFSET
);
980 PciDid
= PciRead16 (DevPcieAddr
+ PCI_DEVICE_ID_OFFSET
);
981 if((PciVid
!= V_IOH_I2C_GPIO_VENDOR_ID
) || (PciDid
!= V_IOH_I2C_GPIO_DEVICE_ID
)) {
986 // Save current settings for PCI CMD/BAR registers.
988 SaveCmdReg
= PciRead16 (DevPcieAddr
+ PCI_COMMAND_OFFSET
);
989 SaveBarReg
= PciRead32 (DevPcieAddr
+ PcdGet8 (PcdIohGpioBarRegister
));
992 // Use predefined tempory memory resource.
994 PciWrite32 ( DevPcieAddr
+ PcdGet8 (PcdIohGpioBarRegister
), IohGpioBase
);
995 PciWrite8 ( DevPcieAddr
+ PCI_COMMAND_OFFSET
, EFI_PCI_COMMAND_MEMORY_SPACE
);
998 // Gpio Controller Init Tasks.
1002 // IEN- Interrupt Enable Register
1004 Addr
= IohGpioBase
+ GPIO_INTEN
;
1005 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1006 Data32
|= (GpioConfig
->IntEn
& 0x000FFFFF);
1007 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1010 // ISTATUS- Interrupt Status Register
1012 Addr
= IohGpioBase
+ GPIO_INTSTATUS
;
1013 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1014 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1017 // GPIO SWPORTA Direction Register - GPIO_SWPORTA_DR
1019 Addr
= IohGpioBase
+ GPIO_SWPORTA_DR
;
1020 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1021 Data32
|= (GpioConfig
->PortADR
& 0x000FFFFF);
1022 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1025 // GPIO SWPORTA Data Direction Register - GPIO_SWPORTA_DDR - default input
1027 Addr
= IohGpioBase
+ GPIO_SWPORTA_DDR
;
1028 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1029 Data32
|= (GpioConfig
->PortADir
& 0x000FFFFF);
1030 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1033 // Interrupt Mask Register - GPIO_INTMASK - default interrupts unmasked
1035 Addr
= IohGpioBase
+ GPIO_INTMASK
;
1036 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1037 Data32
|= (GpioConfig
->IntMask
& 0x000FFFFF);
1038 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1041 // Interrupt Level Type Register - GPIO_INTTYPE_LEVEL - default is level sensitive
1043 Addr
= IohGpioBase
+ GPIO_INTTYPE_LEVEL
;
1044 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1045 Data32
|= (GpioConfig
->IntType
& 0x000FFFFF);
1046 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1049 // Interrupt Polarity Type Register - GPIO_INT_POLARITY - default is active low
1051 Addr
= IohGpioBase
+ GPIO_INT_POLARITY
;
1052 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1053 Data32
|= (GpioConfig
->IntPolarity
& 0x000FFFFF);
1054 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1057 // Interrupt Debounce Type Register - GPIO_DEBOUNCE - default no debounce
1059 Addr
= IohGpioBase
+ GPIO_DEBOUNCE
;
1060 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1061 Data32
|= (GpioConfig
->Debounce
& 0x000FFFFF);
1062 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1065 // Interrupt Clock Synchronisation Register - GPIO_LS_SYNC - default no sync with pclk_intr(APB bus clk)
1067 Addr
= IohGpioBase
+ GPIO_LS_SYNC
;
1068 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1069 Data32
|= (GpioConfig
->LsSync
& 0x000FFFFF);
1070 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1073 // Gpio Controller Manipulation Tasks.
1076 if (PlatformType
== (EFI_PLATFORM_TYPE
) Galileo
) {
1078 // Reset Cypress Expander on Galileo Platform
1080 Addr
= IohGpioBase
+ GPIO_SWPORTA_DR
;
1081 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
));
1082 Data32
|= BIT4
; // Cypress Reset line controlled by GPIO<4>
1083 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1085 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
));
1086 Data32
&= ~BIT4
; // Cypress Reset line controlled by GPIO<4>
1087 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1092 // Restore settings for PCI CMD/BAR registers
1094 PciWrite32 ((DevPcieAddr
+ PcdGet8 (PcdIohGpioBarRegister
)), SaveBarReg
);
1095 PciWrite16 (DevPcieAddr
+ PCI_COMMAND_OFFSET
, SaveCmdReg
);
1099 Performs any early platform init of SoC Ethernet Mac devices.
1101 @param IohMac0Address Mac address to program into Mac0 device.
1102 @param IohMac1Address Mac address to program into Mac1 device.
1107 EarlyPlatformMacInit (
1108 IN CONST UINT8
*IohMac0Address
,
1109 IN CONST UINT8
*IohMac1Address
1115 // Set chipset MAC0 address if configured.
1118 (CompareMem (ChipsetDefaultMac
, IohMac0Address
, sizeof (ChipsetDefaultMac
))) != 0;
1120 if ((*(IohMac0Address
) & BIT0
) != 0) {
1121 DEBUG ((EFI_D_ERROR
, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n",
1122 (UINTN
) IOH_MAC0_BUS_NUMBER
,
1123 (UINTN
) IOH_MAC0_DEVICE_NUMBER
,
1124 (UINTN
) IOH_MAC0_FUNCTION_NUMBER
1128 SetLanControllerMacAddr (
1129 IOH_MAC0_BUS_NUMBER
,
1130 IOH_MAC0_DEVICE_NUMBER
,
1131 IOH_MAC0_FUNCTION_NUMBER
,
1133 (UINT32
) PcdGet64(PcdIohMac0MmioBase
)
1137 DEBUG ((EFI_D_WARN
, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n",
1138 (UINTN
) IOH_MAC0_BUS_NUMBER
,
1139 (UINTN
) IOH_MAC0_DEVICE_NUMBER
,
1140 (UINTN
) IOH_MAC0_FUNCTION_NUMBER
1145 // Set chipset MAC1 address if configured.
1148 (CompareMem (ChipsetDefaultMac
, IohMac1Address
, sizeof (ChipsetDefaultMac
))) != 0;
1150 if ((*(IohMac1Address
) & BIT0
) != 0) {
1151 DEBUG ((EFI_D_ERROR
, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n",
1152 (UINTN
) IOH_MAC1_BUS_NUMBER
,
1153 (UINTN
) IOH_MAC1_DEVICE_NUMBER
,
1154 (UINTN
) IOH_MAC1_FUNCTION_NUMBER
1158 SetLanControllerMacAddr (
1159 IOH_MAC1_BUS_NUMBER
,
1160 IOH_MAC1_DEVICE_NUMBER
,
1161 IOH_MAC1_FUNCTION_NUMBER
,
1163 (UINT32
) PcdGet64(PcdIohMac1MmioBase
)
1167 DEBUG ((EFI_D_WARN
, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n",
1168 (UINTN
) IOH_MAC1_BUS_NUMBER
,
1169 (UINTN
) IOH_MAC1_DEVICE_NUMBER
,
1170 (UINTN
) IOH_MAC1_FUNCTION_NUMBER