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 SPDX-License-Identifier: BSD-2-Clause-Patent
16 #include "CommonHeader.h"
17 #include "PlatformEarlyInit.h"
18 #include "PeiFvSecurity.h"
22 EndOfPeiSignalPpiNotifyCallback (
23 IN EFI_PEI_SERVICES
**PeiServices
,
24 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
29 // Function prototypes to routines implemented in other source modules
30 // within this component.
35 PlatformErratasPostMrc (
40 // The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory
42 BOOLEAN ImageInMemory
= FALSE
;
44 BOARD_LEGACY_GPIO_CONFIG mBoardLegacyGpioConfigTable
[] = { PLATFORM_LEGACY_GPIO_TABLE_DEFINITION
};
45 UINTN mBoardLegacyGpioConfigTableLen
= (sizeof(mBoardLegacyGpioConfigTable
) / sizeof(BOARD_LEGACY_GPIO_CONFIG
));
46 BOARD_GPIO_CONTROLLER_CONFIG mBoardGpioControllerConfigTable
[] = { PLATFORM_GPIO_CONTROLLER_CONFIG_DEFINITION
};
47 UINTN mBoardGpioControllerConfigTableLen
= (sizeof(mBoardGpioControllerConfigTable
) / sizeof(BOARD_GPIO_CONTROLLER_CONFIG
));
48 UINT8 ChipsetDefaultMac
[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
50 EFI_PEI_PPI_DESCRIPTOR mPpiBootMode
[1] = {
52 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
53 &gEfiPeiMasterBootModePpiGuid
,
58 EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList
[1] = {
60 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
61 &gEfiPeiMemoryDiscoveredPpiGuid
,
62 MemoryDiscoveredPpiNotifyCallback
66 EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiSignalPpiNotifyList
[1] = {
68 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
69 &gEfiEndOfPeiSignalPpiGuid
,
70 EndOfPeiSignalPpiNotifyCallback
74 EFI_PEI_STALL_PPI mStallPpi
= {
79 EFI_PEI_PPI_DESCRIPTOR mPpiStall
[1] = {
81 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
88 Set Mac address on chipset ethernet device.
90 @param Bus PCI Bus number of chipset ethernet device.
91 @param Device Device number of chipset ethernet device.
92 @param Func PCI Function number of chipset ethernet device.
93 @param MacAddr MAC Address to set.
98 SetLanControllerMacAddr (
100 IN CONST UINT8 Device
,
102 IN CONST UINT8
*MacAddr
,
111 volatile UINT8
*Wrote
;
116 DevPcieAddr
= PCI_LIB_ADDRESS (
124 // Do nothing if not a supported device.
126 PciVid
= PciRead16 (DevPcieAddr
+ PCI_VENDOR_ID_OFFSET
);
127 PciDid
= PciRead16 (DevPcieAddr
+ PCI_DEVICE_ID_OFFSET
);
128 if((PciVid
!= V_IOH_MAC_VENDOR_ID
) || (PciDid
!= V_IOH_MAC_DEVICE_ID
)) {
133 // Save current settings for PCI CMD/BAR registers
135 SaveCmdReg
= PciRead16 (DevPcieAddr
+ PCI_COMMAND_OFFSET
);
136 SaveBarReg
= PciRead32 (DevPcieAddr
+ R_IOH_MAC_MEMBAR
);
139 // Use predefined temporary memory resource
141 PciWrite32 ( DevPcieAddr
+ R_IOH_MAC_MEMBAR
, Bar0
);
142 PciWrite8 ( DevPcieAddr
+ PCI_COMMAND_OFFSET
, EFI_PCI_COMMAND_MEMORY_SPACE
);
144 Addr
= Bar0
+ R_IOH_MAC_GMAC_REG_8
;
145 MacVer
= *((volatile UINT32
*) (UINTN
)(Addr
));
147 DEBUG ((EFI_D_INFO
, "Ioh MAC [B:%d, D:%d, F:%d] VER:%04x ADDR:",
155 // Set MAC Address0 Low Register (GMAC_REG_17) ADDRLO bits.
157 Addr
= Bar0
+ R_IOH_MAC_GMAC_REG_17
;
158 Data32
= *((UINT32
*) (UINTN
)(&MacAddr
[0]));
159 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
160 Wrote
= (volatile UINT8
*) (UINTN
)(Addr
);
161 DEBUG ((EFI_D_INFO
, "%02x-%02x-%02x-%02x-",
169 // Set MAC Address0 High Register (GMAC_REG_16) ADDRHI bits
170 // and Address Enable (AE) bit.
172 Addr
= Bar0
+ R_IOH_MAC_GMAC_REG_16
;
174 ((UINT32
) MacAddr
[4]) |
175 (((UINT32
)MacAddr
[5]) << 8) |
177 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
178 Wrote
= (volatile UINT8
*) (UINTN
)(Addr
);
180 DEBUG ((EFI_D_INFO
, "%02x-%02x\n", (UINTN
) Wrote
[0], (UINTN
) Wrote
[1]));
183 // Restore settings for PCI CMD/BAR registers
185 PciWrite32 ((DevPcieAddr
+ R_IOH_MAC_MEMBAR
), SaveBarReg
);
186 PciWrite16 (DevPcieAddr
+ PCI_COMMAND_OFFSET
, SaveCmdReg
);
190 Initialize state of I2C GPIO expanders.
192 @param PlatformType Platform type for GPIO expander init.
196 EarlyPlatformConfigGpioExpanders (
197 IN CONST EFI_PLATFORM_TYPE PlatformType
,
198 EFI_BOOT_MODE BootMode
202 EFI_I2C_DEVICE_ADDRESS I2CSlaveAddress
;
208 // Configure GPIO expanders for Galileo Gen 2
209 // Route I2C pins to Arduino header
210 // Set all GPIO expander pins connected to the Reset Button as inputs
212 if (PlatformType
== GalileoGen2
) {
214 // Configure AMUX1_IN (EXP2.P1_4) as an output
216 PlatformPcal9555GpioSetDir (
217 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR
, // IO Expander 2.
219 FALSE
// Configure as output
223 // Set AMUX1_IN(EXP2.P1_4) low to route I2C to Arduino Shield connector
225 PlatformPcal9555GpioSetLevel (
226 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR
, // IO Expander 2.
232 // Configure Reset Button(EXP1.P1_7) as an input
234 PlatformPcal9555GpioSetDir (
235 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR
, // IO Expander 1.
241 // Disable pullup on Reset Button(EXP1.P1_7)
243 PlatformPcal9555GpioDisablePull (
244 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR
, // IO Expander 1.
249 // Configure Reset Button(EXP2.P1_7) as an input
251 PlatformPcal9555GpioSetDir (
252 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR
, // IO Expander 2.
258 // Disable pullup on Reset Button(EXP2.P1_7)
260 PlatformPcal9555GpioDisablePull (
261 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR
, // IO Expander 2.
265 if (BootMode
!= BOOT_IN_RECOVERY_MODE
) {
267 // Read state of Reset Button - EXP2.P1_7
268 // This GPIO is pulled high when the button is not pressed
269 // This GPIO reads low when button is pressed
271 if (!PlatformPcal9555GpioGetState (
272 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR
, // IO Expander 2
275 DEBUG ((EFI_D_INFO
, " Force Recovery mode and reset\n"));
278 // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset
281 QUARK_SCSS_SOC_UNIT_SB_PORT_ID
,
282 QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW
,
283 QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID
, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW
) | B_CFG_STICKY_RW_FORCE_RECOVERY
291 // Configure GPIO expanders for Galileo Gen 2
292 // Set all GPIO expander pins connected to the Reset Button as inputs
293 // Route I2C pins to Arduino header
295 if (PlatformType
== Galileo
) {
297 // Detect the I2C Slave Address of the GPIO Expander
299 if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL
, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO
)) {
300 I2CSlaveAddress
.I2CDeviceAddress
= GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR
;
302 I2CSlaveAddress
.I2CDeviceAddress
= GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR
;
304 DEBUG ((EFI_D_INFO
, "Galileo GPIO Expender Slave Address = %02x\n", I2CSlaveAddress
.I2CDeviceAddress
));
307 // Set I2C_MUX (GPORT1_BIT5) low to route I2C to Arduino Shield connector
311 // Select GPIO Expander GPORT1
314 Buffer
[0] = 0x18; //sub-address
315 Buffer
[1] = 0x01; //data
316 Status
= I2cWriteMultipleByte (
318 EfiI2CSevenBitAddrMode
,
322 ASSERT_EFI_ERROR (Status
);
325 // Read "Pin Direction" of GPIO Expander GPORT1
330 Status
= I2cReadMultipleByte (
332 EfiI2CSevenBitAddrMode
,
337 ASSERT_EFI_ERROR (Status
);
340 // Configure GPIO Expander GPORT1_BIT5 as an output
343 Buffer
[0] = 0x1C; //sub-address
344 Buffer
[1] = (UINT8
)(Buffer
[1] & (~BIT5
)); //data
346 Status
= I2cWriteMultipleByte (
348 EfiI2CSevenBitAddrMode
,
352 ASSERT_EFI_ERROR (Status
);
355 // Set GPIO Expander GPORT1_BIT5 low
358 Buffer
[0] = 0x09; //sub-address
359 Buffer
[1] = (UINT8
)(~BIT5
); //data
361 Status
= I2cWriteMultipleByte (
363 EfiI2CSevenBitAddrMode
,
367 ASSERT_EFI_ERROR (Status
);
370 // Configure RESET_N_SHLD (GPORT5_BIT0) and SW_RESET_N_SHLD (GPORT5_BIT1) as inputs
374 // Select GPIO Expander GPORT5
379 Status
= I2cWriteMultipleByte (
381 EfiI2CSevenBitAddrMode
,
385 ASSERT_EFI_ERROR (Status
);
388 // Read "Pin Direction" of GPIO Expander GPORT5
393 Status
= I2cReadMultipleByte (
395 EfiI2CSevenBitAddrMode
,
400 ASSERT_EFI_ERROR (Status
);
403 // Configure GPIO Expander GPORT5_BIT0 and GPORT5_BIT1 as inputs
407 Buffer
[1] = Buffer
[1] | BIT0
| BIT1
;
408 Status
= I2cWriteMultipleByte (
410 EfiI2CSevenBitAddrMode
,
414 ASSERT_EFI_ERROR (Status
);
416 if (BootMode
!= BOOT_IN_RECOVERY_MODE
) {
418 // Read state of RESET_N_SHLD (GPORT5_BIT0)
423 Status
= I2cReadMultipleByte (
425 EfiI2CSevenBitAddrMode
,
430 ASSERT_EFI_ERROR (Status
);
433 // Return the state of GPORT5_BIT0
435 if ((Buffer
[1] & BIT0
) == 0) {
436 DEBUG ((EFI_D_INFO
, " Force Recovery mode and reset\n"));
439 // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset
442 QUARK_SCSS_SOC_UNIT_SB_PORT_ID
,
443 QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW
,
444 QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID
, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW
) | B_CFG_STICKY_RW_FORCE_RECOVERY
455 This is the entrypoint of PEIM
457 @param FileHandle Handle of the file being invoked.
458 @param PeiServices Describes the list of possible PEI Services.
460 @retval EFI_SUCCESS if it completed successfully.
465 IN EFI_PEI_FILE_HANDLE FileHandle
,
466 IN CONST EFI_PEI_SERVICES
**PeiServices
470 EFI_BOOT_MODE BootMode
;
471 EFI_PEI_STALL_PPI
*StallPpi
;
472 EFI_PEI_PPI_DESCRIPTOR
*StallPeiPpiDescriptor
;
473 EFI_FV_FILE_INFO FileInfo
;
474 EFI_PLATFORM_TYPE PlatformType
;
476 PlatformType
= (EFI_PLATFORM_TYPE
)PcdGet16 (PcdPlatformType
);
479 // Initialize Firmware Volume security.
480 // This must be done before any firmware volume accesses (excl. BFV)
482 Status
= PeiInitializeFvSecurity();
483 ASSERT_EFI_ERROR (Status
);
486 // Do any early platform specific initialization.
488 EarlyPlatformInit ();
491 // This is a second path on entry, in recovery boot path the Stall PPI need to be memory-based
492 // to improve recovery performance.
494 Status
= PeiServicesFfsGetFileInfo (FileHandle
, &FileInfo
);
495 ASSERT_EFI_ERROR (Status
);
497 // The follow conditional check only works for memory-mapped FFS,
498 // so we ASSERT that the file is really a MM FFS.
500 ASSERT (FileInfo
.Buffer
!= NULL
);
501 if (!(((UINTN
) FileInfo
.Buffer
<= (UINTN
) PeiInitPlatform
) &&
502 ((UINTN
) PeiInitPlatform
<= (UINTN
) FileInfo
.Buffer
+ FileInfo
.BufferSize
))) {
504 // Now that module in memory, update the
505 // PPI that describes the Stall to other modules
507 Status
= PeiServicesLocatePpi (
508 &gEfiPeiStallPpiGuid
,
510 &StallPeiPpiDescriptor
,
514 if (!EFI_ERROR (Status
)) {
516 Status
= PeiServicesReInstallPpi (
517 StallPeiPpiDescriptor
,
522 Status
= PeiServicesInstallPpi (&mPpiStall
[0]);
528 // Initialize System Phys
535 // Do platform specific logic to create a boot mode
537 Status
= UpdateBootMode ((EFI_PEI_SERVICES
**)PeiServices
, &BootMode
);
538 ASSERT_EFI_ERROR (Status
);
541 // Signal possible dependent modules that there has been a
542 // final boot mode determination
544 if (!EFI_ERROR(Status
)) {
545 Status
= PeiServicesInstallPpi (&mPpiBootMode
[0]);
546 ASSERT_EFI_ERROR (Status
);
549 if (BootMode
!= BOOT_ON_S3_RESUME
) {
550 QNCClearSmiAndWake ();
553 DEBUG ((EFI_D_INFO
, "MRC Entry\n"));
554 MemoryInit ((EFI_PEI_SERVICES
**)PeiServices
);
557 // Do Early PCIe init.
559 DEBUG ((EFI_D_INFO
, "Early PCIe controller initialization\n"));
560 PlatformPciExpressEarlyInit (PlatformType
);
563 DEBUG ((EFI_D_INFO
, "Platform Erratas After MRC\n"));
564 PlatformErratasPostMrc ();
569 DEBUG ((EFI_D_INFO
, "EarlyPlatformConfigGpioExpanders ()\n"));
570 EarlyPlatformConfigGpioExpanders (PlatformType
, BootMode
);
573 // Now that all of the pre-permanent memory activities have
574 // been taken care of, post a call-back for the permanent-memory
575 // resident services, such as HOB construction.
576 // PEI Core will switch stack after this PEIM exit. After that the MTRR
579 Status
= PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList
[0]);
580 ASSERT_EFI_ERROR (Status
);
583 if (BootMode != BOOT_ON_S3_RESUME) {
584 Status = PeiServicesNotifyPpi (mEndOfPeiSignalPpiNotifyList);
585 ASSERT_EFI_ERROR (Status);
588 if (BootMode
== BOOT_IN_RECOVERY_MODE
) {
589 PeiServicesRegisterForShadow (FileHandle
);
597 EndOfPeiSignalPpiNotifyCallback (
598 IN EFI_PEI_SERVICES
**PeiServices
,
599 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
605 DEBUG ((EFI_D_INFO
, "End of PEI Signal Callback\n"));
608 // Restore the flash region to be UC
609 // for both normal boot as we build a Resource Hob to
610 // describe this region as UC to DXE core.
612 WriteBackInvalidateDataCacheRange (
613 (VOID
*) (UINTN
) PcdGet32 (PcdFlashAreaBaseAddress
),
614 PcdGet32 (PcdFlashAreaSize
)
617 Status
= MtrrSetMemoryAttribute (PcdGet32 (PcdFlashAreaBaseAddress
), PcdGet32 (PcdFlashAreaSize
), CacheUncacheable
);
618 ASSERT_EFI_ERROR (Status
);
624 This function will initialize USB Phy registers associated with QuarkSouthCluster.
626 @param VOID No Argument
628 @retval EFI_SUCCESS All registers have been initialized
638 /** In order to configure the PHY to use clk120 (ickusbcoreclk) as PLL reference clock
639 * and Port2 as a USB device port, the following sequence must be followed
643 // Sideband register write to USB AFE (Phy)
644 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_GLOBAL_PORT
);
645 RegData32
&= ~(BIT1
);
647 // Sighting #4930631 PDNRESCFG [8:7] of USB2_GLOBAL_PORT = 11b.
648 // For port 0 & 1 as host and port 2 as device.
650 RegData32
|= (BIT8
| BIT7
);
651 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_GLOBAL_PORT
, RegData32
);
654 // Sighting #4930653 Required BIOS change on Disconnect vref to change to 600mV.
656 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_COMPBG
);
657 RegData32
&= ~(BIT10
| BIT9
| BIT8
| BIT7
);
658 RegData32
|= (BIT10
| BIT7
);
659 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_COMPBG
, RegData32
);
661 // Sideband register write to USB AFE (Phy)
662 // (pllbypass) to bypass/Disable PLL before switch
663 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
);
665 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
, RegData32
);
667 // Sideband register write to USB AFE (Phy)
668 // (coreclksel) to select 120MHz (ickusbcoreclk) clk source.
669 // (Default 0 to select 96MHz (ickusbclk96_npad/ppad))
670 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL1
);
672 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL1
, RegData32
);
674 // Sideband register write to USB AFE (Phy)
675 // (divide by 8) to achieve internal 480MHz clock
676 // for 120MHz input refclk. (Default: 4'b1000 (divide by 10) for 96MHz)
677 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL1
);
678 RegData32
&= ~(BIT5
| BIT4
| BIT3
);
680 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL1
, RegData32
);
682 // Sideband register write to USB AFE (Phy)
684 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
);
686 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
, RegData32
);
688 // Sideband register write to USB AFE (Phy)
689 // Set (startlock) to force the PLL FSM to restart the lock
690 // sequence due to input clock/freq switch.
691 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
);
693 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
, RegData32
);
695 // At this point the PLL FSM and COMP FSM will complete
700 This function provides early platform Thermal sensor initialisation.
704 EarlyPlatformThermalSensorInit (
708 DEBUG ((EFI_D_INFO
, "Early Platform Thermal Sensor Init\n"));
711 // Set Thermal sensor mode.
713 QNCThermalSensorSetRatiometricMode ();
716 // Enable RMU Thermal sensor with a Catastrophic Trip point.
718 QNCThermalSensorEnableWithCatastrophicTrip (PLATFORM_CATASTROPHIC_TRIP_CELSIUS
);
721 // Lock all RMU Thermal sensor control & trip point registers.
723 QNCThermalSensorLockAllRegisters ();
727 Print early platform info messages includeing the Stage1 module that's
728 running, MFH item list and platform data item list.
732 EarlyPlatformInfoMessages (
737 QUARK_EDKII_STAGE1_HEADER
*Edk2ImageHeader
;
740 // Find which 'Stage1' image we are running and print the details
742 Edk2ImageHeader
= (QUARK_EDKII_STAGE1_HEADER
*) PcdGet32 (PcdEsramStage1Base
);
743 DEBUG ((EFI_D_INFO
, "\n************************************************************\n"));
745 switch ((UINT8
)Edk2ImageHeader
->ImageIndex
& QUARK_STAGE1_IMAGE_TYPE_MASK
) {
746 case QUARK_STAGE1_BOOT_IMAGE_TYPE
:
747 DEBUG ((EFI_D_INFO
, "**** Quark EDKII Stage 1 Boot Image %d ****\n", ((UINT8
)Edk2ImageHeader
->ImageIndex
& ~(QUARK_STAGE1_IMAGE_TYPE_MASK
))));
750 case QUARK_STAGE1_RECOVERY_IMAGE_TYPE
:
751 DEBUG ((EFI_D_INFO
, "**** Quark EDKII Stage 1 Recovery Image %d ****\n", ((UINT8
)Edk2ImageHeader
->ImageIndex
& ~(QUARK_STAGE1_IMAGE_TYPE_MASK
))));
755 DEBUG ((EFI_D_INFO
, "**** Quark EDKII Unknown Stage 1 Image !!!! ****\n"));
760 "**** Quark EDKII Stage 2 Image 0x%08X:0x%08X ****\n" ,
761 (UINTN
) PcdGet32 (PcdFlashFvMainBase
),
762 (UINTN
) PcdGet32 (PcdFlashFvMainSize
)
767 "**** Quark EDKII Payload Image 0x%08X:0x%08X ****\n" ,
768 (UINTN
) PcdGet32 (PcdFlashFvPayloadBase
),
769 (UINTN
) PcdGet32 (PcdFlashFvPayloadSize
)
772 DEBUG ((EFI_D_INFO
, "************************************************************\n\n"));
778 Check if system reset due to error condition.
780 @param ClearErrorBits If TRUE clear error flags and value bits.
782 @retval TRUE if system reset due to error condition.
783 @retval FALSE if NO reset error conditions.
786 CheckForResetDueToErrors (
787 IN BOOLEAN ClearErrorBits
791 BOOLEAN ResetDueToError
;
793 ResetDueToError
= FALSE
;
796 // Check if RMU reset system due to access violations.
797 // RMU updates a SOC Unit register before resetting the system.
799 RegValue
= QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID
, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW
);
800 if ((RegValue
& B_CFG_STICKY_RW_VIOLATION
) != 0) {
801 ResetDueToError
= TRUE
;
805 "\nReset due to access violation: %s %s %s %s\n",
806 ((RegValue
& B_CFG_STICKY_RW_IMR_VIOLATION
) != 0) ? L
"'IMR'" : L
".",
807 ((RegValue
& B_CFG_STICKY_RW_DECC_VIOLATION
) != 0) ? L
"'DECC'" : L
".",
808 ((RegValue
& B_CFG_STICKY_RW_SMM_VIOLATION
) != 0) ? L
"'SMM'" : L
".",
809 ((RegValue
& B_CFG_STICKY_RW_HMB_VIOLATION
) != 0) ? L
"'HMB'" : L
"."
815 if (ClearErrorBits
) {
816 RegValue
&= ~(B_CFG_STICKY_RW_VIOLATION
);
817 QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID
, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW
, RegValue
);
821 return ResetDueToError
;
825 This function provides early platform initialization.
827 @param PlatformInfo Pointer to platform Info structure.
836 EFI_PLATFORM_TYPE PlatformType
;
838 PlatformType
= (EFI_PLATFORM_TYPE
) PcdGet16 (PcdPlatformType
);
840 DEBUG ((EFI_D_INFO
, "EarlyPlatformInit for PlatType=0x%02x\n", (UINTN
) PlatformType
));
843 // Check if system reset due to error condition.
845 if (CheckForResetDueToErrors (TRUE
)) {
846 if(FeaturePcdGet (WaitIfResetDueToError
)) {
847 DEBUG ((EFI_D_ERROR
, "Wait 10 seconds.\n"));
848 MicroSecondDelay(10000000);
853 // Display platform info messages.
855 EarlyPlatformInfoMessages ();
858 // Early Legacy Gpio Init.
860 EarlyPlatformLegacyGpioInit (PlatformType
);
863 // Early platform Legacy GPIO manipulation depending on GPIOs
864 // setup by EarlyPlatformLegacyGpioInit.
866 EarlyPlatformLegacyGpioManipulation (PlatformType
);
869 // Early platform specific GPIO Controller init & manipulation.
870 // Combined for sharing of temp. memory bar.
872 EarlyPlatformGpioCtrlerInitAndManipulation (PlatformType
);
875 // Early Thermal Sensor Init.
877 EarlyPlatformThermalSensorInit ();
880 // Early Lan Ethernet Mac Init.
882 EarlyPlatformMacInit (
883 PcdGetPtr (PcdIohEthernetMac0
),
884 PcdGetPtr (PcdIohEthernetMac1
)
889 This function provides early platform Legacy GPIO initialisation.
891 @param PlatformType Platform type for GPIO init.
896 EarlyPlatformLegacyGpioInit (
897 IN CONST EFI_PLATFORM_TYPE PlatformType
900 BOARD_LEGACY_GPIO_CONFIG
*LegacyGpioConfig
;
902 UINT32 GpioBaseAddress
;
905 // Assert if platform type outside table range.
907 ASSERT ((UINTN
) PlatformType
< mBoardLegacyGpioConfigTableLen
);
908 LegacyGpioConfig
= &mBoardLegacyGpioConfigTable
[(UINTN
) PlatformType
];
910 GpioBaseAddress
= (UINT32
)PcdGet16 (PcdGbaIoBaseAddress
);
914 // Program QNC GPIO Registers.
916 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGEN_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellEnable
;
917 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGEN_CORE_WELL
, NewValue
);
918 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGIO_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellIoSelect
;
919 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGIO_CORE_WELL
, NewValue
);
920 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGLVL_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellLvlForInputOrOutput
;
921 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGLVL_CORE_WELL
, NewValue
);
922 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGTPE_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellTriggerPositiveEdge
;
923 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGTPE_CORE_WELL
, NewValue
);
924 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGTNE_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellTriggerNegativeEdge
;
925 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGTNE_CORE_WELL
, NewValue
);
926 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGGPE_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellGPEEnable
;
927 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGGPE_CORE_WELL
, NewValue
);
928 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGSMI_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellSMIEnable
;
929 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGSMI_CORE_WELL
, NewValue
);
930 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGTS_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellTriggerStatus
;
931 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGTS_CORE_WELL
, NewValue
);
932 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CNMIEN_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellNMIEnable
;
933 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CNMIEN_CORE_WELL
, NewValue
);
935 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGEN_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellEnable
;
936 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGEN_RESUME_WELL
, NewValue
);
937 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGIO_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellIoSelect
;
938 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGIO_RESUME_WELL
, NewValue
) ;
939 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGLVL_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellLvlForInputOrOutput
;
940 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGLVL_RESUME_WELL
, NewValue
);
941 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGTPE_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellTriggerPositiveEdge
;
942 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGTPE_RESUME_WELL
, NewValue
);
943 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGTNE_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellTriggerNegativeEdge
;
944 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGTNE_RESUME_WELL
, NewValue
) ;
945 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGGPE_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellGPEEnable
;
946 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGGPE_RESUME_WELL
, NewValue
);
947 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGSMI_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellSMIEnable
;
948 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGSMI_RESUME_WELL
, NewValue
);
949 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGTS_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellTriggerStatus
;
950 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGTS_RESUME_WELL
, NewValue
) ;
951 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RNMIEN_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellNMIEnable
;
952 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RNMIEN_RESUME_WELL
, NewValue
);
956 Performs any early platform specific Legacy GPIO manipulation.
958 @param PlatformType Platform type GPIO manipulation.
963 EarlyPlatformLegacyGpioManipulation (
964 IN CONST EFI_PLATFORM_TYPE PlatformType
967 if (PlatformType
== CrossHill
) {
970 // Pull TPM reset low for 80us (equivalent to cold reset, Table 39
971 // Infineon SLB9645 Databook), then pull TPM reset high and wait for
972 // 150ms to give time for TPM to stabilise (Section 4.7.1 Infineon
973 // SLB9645 Databook states TPM is ready to receive command after 30ms
974 // but section 4.7 states some TPM commands may take longer to execute
975 // upto 150ms after test).
978 PlatformLegacyGpioSetLevel (
979 R_QNC_GPIO_RGLVL_RESUME_WELL
,
980 PLATFORM_RESUMEWELL_TPM_RST_GPIO
,
983 MicroSecondDelay (80);
985 PlatformLegacyGpioSetLevel (
986 R_QNC_GPIO_RGLVL_RESUME_WELL
,
987 PLATFORM_RESUMEWELL_TPM_RST_GPIO
,
990 MicroSecondDelay (150000);
996 Performs any early platform specific GPIO Controller init & manipulation.
998 @param PlatformType Platform type for GPIO init & manipulation.
1003 EarlyPlatformGpioCtrlerInitAndManipulation (
1004 IN CONST EFI_PLATFORM_TYPE PlatformType
1010 BOARD_GPIO_CONTROLLER_CONFIG
*GpioConfig
;
1017 ASSERT ((UINTN
) PlatformType
< mBoardGpioControllerConfigTableLen
);
1018 GpioConfig
= &mBoardGpioControllerConfigTable
[(UINTN
) PlatformType
];
1020 IohGpioBase
= (UINT32
) PcdGet64 (PcdIohGpioMmioBase
);
1022 DevPcieAddr
= PCI_LIB_ADDRESS (
1023 PcdGet8 (PcdIohGpioBusNumber
),
1024 PcdGet8 (PcdIohGpioDevNumber
),
1025 PcdGet8 (PcdIohGpioFunctionNumber
),
1030 // Do nothing if not a supported device.
1032 PciVid
= PciRead16 (DevPcieAddr
+ PCI_VENDOR_ID_OFFSET
);
1033 PciDid
= PciRead16 (DevPcieAddr
+ PCI_DEVICE_ID_OFFSET
);
1034 if((PciVid
!= V_IOH_I2C_GPIO_VENDOR_ID
) || (PciDid
!= V_IOH_I2C_GPIO_DEVICE_ID
)) {
1039 // Save current settings for PCI CMD/BAR registers.
1041 SaveCmdReg
= PciRead16 (DevPcieAddr
+ PCI_COMMAND_OFFSET
);
1042 SaveBarReg
= PciRead32 (DevPcieAddr
+ PcdGet8 (PcdIohGpioBarRegister
));
1045 // Use predefined temporary memory resource.
1047 PciWrite32 ( DevPcieAddr
+ PcdGet8 (PcdIohGpioBarRegister
), IohGpioBase
);
1048 PciWrite8 ( DevPcieAddr
+ PCI_COMMAND_OFFSET
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1051 // Gpio Controller Init Tasks.
1055 // IEN- Interrupt Enable Register
1057 Addr
= IohGpioBase
+ GPIO_INTEN
;
1058 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1059 Data32
|= (GpioConfig
->IntEn
& 0x000FFFFF);
1060 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1063 // ISTATUS- Interrupt Status Register
1065 Addr
= IohGpioBase
+ GPIO_INTSTATUS
;
1066 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1067 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1070 // GPIO SWPORTA Direction Register - GPIO_SWPORTA_DR
1072 Addr
= IohGpioBase
+ GPIO_SWPORTA_DR
;
1073 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1074 Data32
|= (GpioConfig
->PortADR
& 0x000FFFFF);
1075 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1078 // GPIO SWPORTA Data Direction Register - GPIO_SWPORTA_DDR - default input
1080 Addr
= IohGpioBase
+ GPIO_SWPORTA_DDR
;
1081 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1082 Data32
|= (GpioConfig
->PortADir
& 0x000FFFFF);
1083 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1086 // Interrupt Mask Register - GPIO_INTMASK - default interrupts unmasked
1088 Addr
= IohGpioBase
+ GPIO_INTMASK
;
1089 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1090 Data32
|= (GpioConfig
->IntMask
& 0x000FFFFF);
1091 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1094 // Interrupt Level Type Register - GPIO_INTTYPE_LEVEL - default is level sensitive
1096 Addr
= IohGpioBase
+ GPIO_INTTYPE_LEVEL
;
1097 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1098 Data32
|= (GpioConfig
->IntType
& 0x000FFFFF);
1099 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1102 // Interrupt Polarity Type Register - GPIO_INT_POLARITY - default is active low
1104 Addr
= IohGpioBase
+ GPIO_INT_POLARITY
;
1105 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1106 Data32
|= (GpioConfig
->IntPolarity
& 0x000FFFFF);
1107 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1110 // Interrupt Debounce Type Register - GPIO_DEBOUNCE - default no debounce
1112 Addr
= IohGpioBase
+ GPIO_DEBOUNCE
;
1113 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1114 Data32
|= (GpioConfig
->Debounce
& 0x000FFFFF);
1115 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1118 // Interrupt Clock Synchronisation Register - GPIO_LS_SYNC - default no sync with pclk_intr(APB bus clk)
1120 Addr
= IohGpioBase
+ GPIO_LS_SYNC
;
1121 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1122 Data32
|= (GpioConfig
->LsSync
& 0x000FFFFF);
1123 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1126 // Gpio Controller Manipulation Tasks.
1129 if (PlatformType
== (EFI_PLATFORM_TYPE
) Galileo
) {
1131 // Reset Cypress Expander on Galileo Platform
1133 Addr
= IohGpioBase
+ GPIO_SWPORTA_DR
;
1134 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
));
1135 Data32
|= BIT4
; // Cypress Reset line controlled by GPIO<4>
1136 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1138 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
));
1139 Data32
&= ~BIT4
; // Cypress Reset line controlled by GPIO<4>
1140 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1145 // Restore settings for PCI CMD/BAR registers
1147 PciWrite32 ((DevPcieAddr
+ PcdGet8 (PcdIohGpioBarRegister
)), SaveBarReg
);
1148 PciWrite16 (DevPcieAddr
+ PCI_COMMAND_OFFSET
, SaveCmdReg
);
1152 Performs any early platform init of SoC Ethernet Mac devices.
1154 @param IohMac0Address Mac address to program into Mac0 device.
1155 @param IohMac1Address Mac address to program into Mac1 device.
1160 EarlyPlatformMacInit (
1161 IN CONST UINT8
*IohMac0Address
,
1162 IN CONST UINT8
*IohMac1Address
1168 // Set chipset MAC0 address if configured.
1171 (CompareMem (ChipsetDefaultMac
, IohMac0Address
, sizeof (ChipsetDefaultMac
))) != 0;
1173 if ((*(IohMac0Address
) & BIT0
) != 0) {
1174 DEBUG ((EFI_D_ERROR
, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n",
1175 (UINTN
) IOH_MAC0_BUS_NUMBER
,
1176 (UINTN
) IOH_MAC0_DEVICE_NUMBER
,
1177 (UINTN
) IOH_MAC0_FUNCTION_NUMBER
1181 SetLanControllerMacAddr (
1182 IOH_MAC0_BUS_NUMBER
,
1183 IOH_MAC0_DEVICE_NUMBER
,
1184 IOH_MAC0_FUNCTION_NUMBER
,
1186 (UINT32
) PcdGet64(PcdIohMac0MmioBase
)
1190 DEBUG ((EFI_D_WARN
, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n",
1191 (UINTN
) IOH_MAC0_BUS_NUMBER
,
1192 (UINTN
) IOH_MAC0_DEVICE_NUMBER
,
1193 (UINTN
) IOH_MAC0_FUNCTION_NUMBER
1198 // Set chipset MAC1 address if configured.
1201 (CompareMem (ChipsetDefaultMac
, IohMac1Address
, sizeof (ChipsetDefaultMac
))) != 0;
1203 if ((*(IohMac1Address
) & BIT0
) != 0) {
1204 DEBUG ((EFI_D_ERROR
, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n",
1205 (UINTN
) IOH_MAC1_BUS_NUMBER
,
1206 (UINTN
) IOH_MAC1_DEVICE_NUMBER
,
1207 (UINTN
) IOH_MAC1_FUNCTION_NUMBER
1211 SetLanControllerMacAddr (
1212 IOH_MAC1_BUS_NUMBER
,
1213 IOH_MAC1_DEVICE_NUMBER
,
1214 IOH_MAC1_FUNCTION_NUMBER
,
1216 (UINT32
) PcdGet64(PcdIohMac1MmioBase
)
1220 DEBUG ((EFI_D_WARN
, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n",
1221 (UINTN
) IOH_MAC1_BUS_NUMBER
,
1222 (UINTN
) IOH_MAC1_DEVICE_NUMBER
,
1223 (UINTN
) IOH_MAC1_FUNCTION_NUMBER