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 temporary 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
,
204 EFI_BOOT_MODE BootMode
208 EFI_I2C_DEVICE_ADDRESS I2CSlaveAddress
;
214 // Configure GPIO expanders for Galileo Gen 2
215 // Route I2C pins to Arduino header
216 // Set all GPIO expander pins connected to the Reset Button as inputs
218 if (PlatformType
== GalileoGen2
) {
220 // Configure AMUX1_IN (EXP2.P1_4) as an output
222 PlatformPcal9555GpioSetDir (
223 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR
, // IO Expander 2.
225 FALSE
// Configure as output
229 // Set AMUX1_IN(EXP2.P1_4) low to route I2C to Arduino Shield connector
231 PlatformPcal9555GpioSetLevel (
232 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR
, // IO Expander 2.
238 // Configure Reset Button(EXP1.P1_7) as an input
240 PlatformPcal9555GpioSetDir (
241 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR
, // IO Expander 1.
247 // Disable pullup on Reset Button(EXP1.P1_7)
249 PlatformPcal9555GpioDisablePull (
250 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR
, // IO Expander 1.
255 // Configure Reset Button(EXP2.P1_7) as an input
257 PlatformPcal9555GpioSetDir (
258 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR
, // IO Expander 2.
264 // Disable pullup on Reset Button(EXP2.P1_7)
266 PlatformPcal9555GpioDisablePull (
267 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR
, // IO Expander 2.
271 if (BootMode
!= BOOT_IN_RECOVERY_MODE
) {
273 // Read state of Reset Button - EXP2.P1_7
274 // This GPIO is pulled high when the button is not pressed
275 // This GPIO reads low when button is pressed
277 if (!PlatformPcal9555GpioGetState (
278 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR
, // IO Expander 2
281 DEBUG ((EFI_D_INFO
, " Force Recovery mode and reset\n"));
284 // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset
287 QUARK_SCSS_SOC_UNIT_SB_PORT_ID
,
288 QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW
,
289 QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID
, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW
) | B_CFG_STICKY_RW_FORCE_RECOVERY
297 // Configure GPIO expanders for Galileo Gen 2
298 // Set all GPIO expander pins connected to the Reset Button as inputs
299 // Route I2C pins to Arduino header
301 if (PlatformType
== Galileo
) {
303 // Detect the I2C Slave Address of the GPIO Expander
305 if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL
, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO
)) {
306 I2CSlaveAddress
.I2CDeviceAddress
= GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR
;
308 I2CSlaveAddress
.I2CDeviceAddress
= GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR
;
310 DEBUG ((EFI_D_INFO
, "Galileo GPIO Expender Slave Address = %02x\n", I2CSlaveAddress
.I2CDeviceAddress
));
313 // Set I2C_MUX (GPORT1_BIT5) low to route I2C to Arduino Shield connector
317 // Select GPIO Expander GPORT1
320 Buffer
[0] = 0x18; //sub-address
321 Buffer
[1] = 0x01; //data
322 Status
= I2cWriteMultipleByte (
324 EfiI2CSevenBitAddrMode
,
328 ASSERT_EFI_ERROR (Status
);
331 // Read "Pin Direction" of GPIO Expander GPORT1
336 Status
= I2cReadMultipleByte (
338 EfiI2CSevenBitAddrMode
,
343 ASSERT_EFI_ERROR (Status
);
346 // Configure GPIO Expander GPORT1_BIT5 as an output
349 Buffer
[0] = 0x1C; //sub-address
350 Buffer
[1] = (UINT8
)(Buffer
[1] & (~BIT5
)); //data
352 Status
= I2cWriteMultipleByte (
354 EfiI2CSevenBitAddrMode
,
358 ASSERT_EFI_ERROR (Status
);
361 // Set GPIO Expander GPORT1_BIT5 low
364 Buffer
[0] = 0x09; //sub-address
365 Buffer
[1] = (UINT8
)(~BIT5
); //data
367 Status
= I2cWriteMultipleByte (
369 EfiI2CSevenBitAddrMode
,
373 ASSERT_EFI_ERROR (Status
);
376 // Configure RESET_N_SHLD (GPORT5_BIT0) and SW_RESET_N_SHLD (GPORT5_BIT1) as inputs
380 // Select GPIO Expander GPORT5
385 Status
= I2cWriteMultipleByte (
387 EfiI2CSevenBitAddrMode
,
391 ASSERT_EFI_ERROR (Status
);
394 // Read "Pin Direction" of GPIO Expander GPORT5
399 Status
= I2cReadMultipleByte (
401 EfiI2CSevenBitAddrMode
,
406 ASSERT_EFI_ERROR (Status
);
409 // Configure GPIO Expander GPORT5_BIT0 and GPORT5_BIT1 as inputs
413 Buffer
[1] = Buffer
[1] | BIT0
| BIT1
;
414 Status
= I2cWriteMultipleByte (
416 EfiI2CSevenBitAddrMode
,
420 ASSERT_EFI_ERROR (Status
);
422 if (BootMode
!= BOOT_IN_RECOVERY_MODE
) {
424 // Read state of RESET_N_SHLD (GPORT5_BIT0)
429 Status
= I2cReadMultipleByte (
431 EfiI2CSevenBitAddrMode
,
436 ASSERT_EFI_ERROR (Status
);
439 // Return the state of GPORT5_BIT0
441 if ((Buffer
[1] & BIT0
) == 0) {
442 DEBUG ((EFI_D_INFO
, " Force Recovery mode and reset\n"));
445 // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset
448 QUARK_SCSS_SOC_UNIT_SB_PORT_ID
,
449 QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW
,
450 QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID
, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW
) | B_CFG_STICKY_RW_FORCE_RECOVERY
461 This is the entrypoint of PEIM
463 @param FileHandle Handle of the file being invoked.
464 @param PeiServices Describes the list of possible PEI Services.
466 @retval EFI_SUCCESS if it completed successfully.
471 IN EFI_PEI_FILE_HANDLE FileHandle
,
472 IN CONST EFI_PEI_SERVICES
**PeiServices
476 EFI_BOOT_MODE BootMode
;
477 EFI_PEI_STALL_PPI
*StallPpi
;
478 EFI_PEI_PPI_DESCRIPTOR
*StallPeiPpiDescriptor
;
479 EFI_FV_FILE_INFO FileInfo
;
480 EFI_PLATFORM_TYPE PlatformType
;
482 PlatformType
= (EFI_PLATFORM_TYPE
)PcdGet16 (PcdPlatformType
);
485 // Initialize Firmware Volume security.
486 // This must be done before any firmware volume accesses (excl. BFV)
488 Status
= PeiInitializeFvSecurity();
489 ASSERT_EFI_ERROR (Status
);
492 // Do any early platform specific initialization.
494 EarlyPlatformInit ();
497 // This is a second path on entry, in recovery boot path the Stall PPI need to be memory-based
498 // to improve recovery performance.
500 Status
= PeiServicesFfsGetFileInfo (FileHandle
, &FileInfo
);
501 ASSERT_EFI_ERROR (Status
);
503 // The follow conditional check only works for memory-mapped FFS,
504 // so we ASSERT that the file is really a MM FFS.
506 ASSERT (FileInfo
.Buffer
!= NULL
);
507 if (!(((UINTN
) FileInfo
.Buffer
<= (UINTN
) PeiInitPlatform
) &&
508 ((UINTN
) PeiInitPlatform
<= (UINTN
) FileInfo
.Buffer
+ FileInfo
.BufferSize
))) {
510 // Now that module in memory, update the
511 // PPI that describes the Stall to other modules
513 Status
= PeiServicesLocatePpi (
514 &gEfiPeiStallPpiGuid
,
516 &StallPeiPpiDescriptor
,
520 if (!EFI_ERROR (Status
)) {
522 Status
= PeiServicesReInstallPpi (
523 StallPeiPpiDescriptor
,
528 Status
= PeiServicesInstallPpi (&mPpiStall
[0]);
534 // Initialize System Phys
541 // Do platform specific logic to create a boot mode
543 Status
= UpdateBootMode ((EFI_PEI_SERVICES
**)PeiServices
, &BootMode
);
544 ASSERT_EFI_ERROR (Status
);
547 // Signal possible dependent modules that there has been a
548 // final boot mode determination
550 if (!EFI_ERROR(Status
)) {
551 Status
= PeiServicesInstallPpi (&mPpiBootMode
[0]);
552 ASSERT_EFI_ERROR (Status
);
555 if (BootMode
!= BOOT_ON_S3_RESUME
) {
556 QNCClearSmiAndWake ();
559 DEBUG ((EFI_D_INFO
, "MRC Entry\n"));
560 MemoryInit ((EFI_PEI_SERVICES
**)PeiServices
);
563 // Do Early PCIe init.
565 DEBUG ((EFI_D_INFO
, "Early PCIe controller initialization\n"));
566 PlatformPciExpressEarlyInit (PlatformType
);
569 DEBUG ((EFI_D_INFO
, "Platform Erratas After MRC\n"));
570 PlatformErratasPostMrc ();
575 DEBUG ((EFI_D_INFO
, "EarlyPlatformConfigGpioExpanders ()\n"));
576 EarlyPlatformConfigGpioExpanders (PlatformType
, BootMode
);
579 // Now that all of the pre-permanent memory activities have
580 // been taken care of, post a call-back for the permanent-memory
581 // resident services, such as HOB construction.
582 // PEI Core will switch stack after this PEIM exit. After that the MTRR
585 Status
= PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList
[0]);
586 ASSERT_EFI_ERROR (Status
);
589 if (BootMode != BOOT_ON_S3_RESUME) {
590 Status = PeiServicesNotifyPpi (mEndOfPeiSignalPpiNotifyList);
591 ASSERT_EFI_ERROR (Status);
594 if (BootMode
== BOOT_IN_RECOVERY_MODE
) {
595 PeiServicesRegisterForShadow (FileHandle
);
603 EndOfPeiSignalPpiNotifyCallback (
604 IN EFI_PEI_SERVICES
**PeiServices
,
605 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
611 DEBUG ((EFI_D_INFO
, "End of PEI Signal Callback\n"));
614 // Restore the flash region to be UC
615 // for both normal boot as we build a Resource Hob to
616 // describe this region as UC to DXE core.
618 WriteBackInvalidateDataCacheRange (
619 (VOID
*) (UINTN
) PcdGet32 (PcdFlashAreaBaseAddress
),
620 PcdGet32 (PcdFlashAreaSize
)
623 Status
= MtrrSetMemoryAttribute (PcdGet32 (PcdFlashAreaBaseAddress
), PcdGet32 (PcdFlashAreaSize
), CacheUncacheable
);
624 ASSERT_EFI_ERROR (Status
);
630 This function will initialize USB Phy registers associated with QuarkSouthCluster.
632 @param VOID No Argument
634 @retval EFI_SUCCESS All registers have been initialized
644 /** In order to configure the PHY to use clk120 (ickusbcoreclk) as PLL reference clock
645 * and Port2 as a USB device port, the following sequence must be followed
649 // Sideband register write to USB AFE (Phy)
650 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_GLOBAL_PORT
);
651 RegData32
&= ~(BIT1
);
653 // Sighting #4930631 PDNRESCFG [8:7] of USB2_GLOBAL_PORT = 11b.
654 // For port 0 & 1 as host and port 2 as device.
656 RegData32
|= (BIT8
| BIT7
);
657 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_GLOBAL_PORT
, RegData32
);
660 // Sighting #4930653 Required BIOS change on Disconnect vref to change to 600mV.
662 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_COMPBG
);
663 RegData32
&= ~(BIT10
| BIT9
| BIT8
| BIT7
);
664 RegData32
|= (BIT10
| BIT7
);
665 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_COMPBG
, RegData32
);
667 // Sideband register write to USB AFE (Phy)
668 // (pllbypass) to bypass/Disable PLL before switch
669 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
);
671 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
, RegData32
);
673 // Sideband register write to USB AFE (Phy)
674 // (coreclksel) to select 120MHz (ickusbcoreclk) clk source.
675 // (Default 0 to select 96MHz (ickusbclk96_npad/ppad))
676 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL1
);
678 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL1
, RegData32
);
680 // Sideband register write to USB AFE (Phy)
681 // (divide by 8) to achieve internal 480MHz clock
682 // for 120MHz input refclk. (Default: 4'b1000 (divide by 10) for 96MHz)
683 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL1
);
684 RegData32
&= ~(BIT5
| BIT4
| BIT3
);
686 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL1
, RegData32
);
688 // Sideband register write to USB AFE (Phy)
690 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
);
692 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
, RegData32
);
694 // Sideband register write to USB AFE (Phy)
695 // Set (startlock) to force the PLL FSM to restart the lock
696 // sequence due to input clock/freq switch.
697 RegData32
= QNCAltPortRead (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
);
699 QNCAltPortWrite (QUARK_SC_USB_AFE_SB_PORT_ID
, USB2_PLL2
, RegData32
);
701 // At this point the PLL FSM and COMP FSM will complete
706 This function provides early platform Thermal sensor initialisation.
710 EarlyPlatformThermalSensorInit (
714 DEBUG ((EFI_D_INFO
, "Early Platform Thermal Sensor Init\n"));
717 // Set Thermal sensor mode.
719 QNCThermalSensorSetRatiometricMode ();
722 // Enable RMU Thermal sensor with a Catastrophic Trip point.
724 QNCThermalSensorEnableWithCatastrophicTrip (PLATFORM_CATASTROPHIC_TRIP_CELSIUS
);
727 // Lock all RMU Thermal sensor control & trip point registers.
729 QNCThermalSensorLockAllRegisters ();
733 Print early platform info messages includeing the Stage1 module that's
734 running, MFH item list and platform data item list.
738 EarlyPlatformInfoMessages (
743 QUARK_EDKII_STAGE1_HEADER
*Edk2ImageHeader
;
746 // Find which 'Stage1' image we are running and print the details
748 Edk2ImageHeader
= (QUARK_EDKII_STAGE1_HEADER
*) PcdGet32 (PcdEsramStage1Base
);
749 DEBUG ((EFI_D_INFO
, "\n************************************************************\n"));
751 switch ((UINT8
)Edk2ImageHeader
->ImageIndex
& QUARK_STAGE1_IMAGE_TYPE_MASK
) {
752 case QUARK_STAGE1_BOOT_IMAGE_TYPE
:
753 DEBUG ((EFI_D_INFO
, "**** Quark EDKII Stage 1 Boot Image %d ****\n", ((UINT8
)Edk2ImageHeader
->ImageIndex
& ~(QUARK_STAGE1_IMAGE_TYPE_MASK
))));
756 case QUARK_STAGE1_RECOVERY_IMAGE_TYPE
:
757 DEBUG ((EFI_D_INFO
, "**** Quark EDKII Stage 1 Recovery Image %d ****\n", ((UINT8
)Edk2ImageHeader
->ImageIndex
& ~(QUARK_STAGE1_IMAGE_TYPE_MASK
))));
761 DEBUG ((EFI_D_INFO
, "**** Quark EDKII Unknown Stage 1 Image !!!! ****\n"));
766 "**** Quark EDKII Stage 2 Image 0x%08X:0x%08X ****\n" ,
767 (UINTN
) PcdGet32 (PcdFlashFvMainBase
),
768 (UINTN
) PcdGet32 (PcdFlashFvMainSize
)
773 "**** Quark EDKII Payload Image 0x%08X:0x%08X ****\n" ,
774 (UINTN
) PcdGet32 (PcdFlashFvPayloadBase
),
775 (UINTN
) PcdGet32 (PcdFlashFvPayloadSize
)
778 DEBUG ((EFI_D_INFO
, "************************************************************\n\n"));
784 Check if system reset due to error condition.
786 @param ClearErrorBits If TRUE clear error flags and value bits.
788 @retval TRUE if system reset due to error condition.
789 @retval FALSE if NO reset error conditions.
792 CheckForResetDueToErrors (
793 IN BOOLEAN ClearErrorBits
797 BOOLEAN ResetDueToError
;
799 ResetDueToError
= FALSE
;
802 // Check if RMU reset system due to access violations.
803 // RMU updates a SOC Unit register before resetting the system.
805 RegValue
= QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID
, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW
);
806 if ((RegValue
& B_CFG_STICKY_RW_VIOLATION
) != 0) {
807 ResetDueToError
= TRUE
;
811 "\nReset due to access violation: %s %s %s %s\n",
812 ((RegValue
& B_CFG_STICKY_RW_IMR_VIOLATION
) != 0) ? L
"'IMR'" : L
".",
813 ((RegValue
& B_CFG_STICKY_RW_DECC_VIOLATION
) != 0) ? L
"'DECC'" : L
".",
814 ((RegValue
& B_CFG_STICKY_RW_SMM_VIOLATION
) != 0) ? L
"'SMM'" : L
".",
815 ((RegValue
& B_CFG_STICKY_RW_HMB_VIOLATION
) != 0) ? L
"'HMB'" : L
"."
821 if (ClearErrorBits
) {
822 RegValue
&= ~(B_CFG_STICKY_RW_VIOLATION
);
823 QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID
, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW
, RegValue
);
827 return ResetDueToError
;
831 This function provides early platform initialization.
833 @param PlatformInfo Pointer to platform Info structure.
842 EFI_PLATFORM_TYPE PlatformType
;
844 PlatformType
= (EFI_PLATFORM_TYPE
) PcdGet16 (PcdPlatformType
);
846 DEBUG ((EFI_D_INFO
, "EarlyPlatformInit for PlatType=0x%02x\n", (UINTN
) PlatformType
));
849 // Check if system reset due to error condition.
851 if (CheckForResetDueToErrors (TRUE
)) {
852 if(FeaturePcdGet (WaitIfResetDueToError
)) {
853 DEBUG ((EFI_D_ERROR
, "Wait 10 seconds.\n"));
854 MicroSecondDelay(10000000);
859 // Display platform info messages.
861 EarlyPlatformInfoMessages ();
864 // Early Legacy Gpio Init.
866 EarlyPlatformLegacyGpioInit (PlatformType
);
869 // Early platform Legacy GPIO manipulation depending on GPIOs
870 // setup by EarlyPlatformLegacyGpioInit.
872 EarlyPlatformLegacyGpioManipulation (PlatformType
);
875 // Early platform specific GPIO Controller init & manipulation.
876 // Combined for sharing of temp. memory bar.
878 EarlyPlatformGpioCtrlerInitAndManipulation (PlatformType
);
881 // Early Thermal Sensor Init.
883 EarlyPlatformThermalSensorInit ();
886 // Early Lan Ethernet Mac Init.
888 EarlyPlatformMacInit (
889 PcdGetPtr (PcdIohEthernetMac0
),
890 PcdGetPtr (PcdIohEthernetMac1
)
895 This function provides early platform Legacy GPIO initialisation.
897 @param PlatformType Platform type for GPIO init.
902 EarlyPlatformLegacyGpioInit (
903 IN CONST EFI_PLATFORM_TYPE PlatformType
906 BOARD_LEGACY_GPIO_CONFIG
*LegacyGpioConfig
;
908 UINT32 GpioBaseAddress
;
911 // Assert if platform type outside table range.
913 ASSERT ((UINTN
) PlatformType
< mBoardLegacyGpioConfigTableLen
);
914 LegacyGpioConfig
= &mBoardLegacyGpioConfigTable
[(UINTN
) PlatformType
];
916 GpioBaseAddress
= (UINT32
)PcdGet16 (PcdGbaIoBaseAddress
);
920 // Program QNC GPIO Registers.
922 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGEN_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellEnable
;
923 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGEN_CORE_WELL
, NewValue
);
924 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGIO_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellIoSelect
;
925 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGIO_CORE_WELL
, NewValue
);
926 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGLVL_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellLvlForInputOrOutput
;
927 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGLVL_CORE_WELL
, NewValue
);
928 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGTPE_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellTriggerPositiveEdge
;
929 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGTPE_CORE_WELL
, NewValue
);
930 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGTNE_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellTriggerNegativeEdge
;
931 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGTNE_CORE_WELL
, NewValue
);
932 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGGPE_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellGPEEnable
;
933 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGGPE_CORE_WELL
, NewValue
);
934 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGSMI_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellSMIEnable
;
935 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGSMI_CORE_WELL
, NewValue
);
936 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CGTS_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellTriggerStatus
;
937 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CGTS_CORE_WELL
, NewValue
);
938 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_CNMIEN_CORE_WELL
) & 0xFFFFFFFC) | LegacyGpioConfig
->CoreWellNMIEnable
;
939 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_CNMIEN_CORE_WELL
, NewValue
);
941 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGEN_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellEnable
;
942 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGEN_RESUME_WELL
, NewValue
);
943 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGIO_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellIoSelect
;
944 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGIO_RESUME_WELL
, NewValue
) ;
945 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGLVL_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellLvlForInputOrOutput
;
946 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGLVL_RESUME_WELL
, NewValue
);
947 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGTPE_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellTriggerPositiveEdge
;
948 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGTPE_RESUME_WELL
, NewValue
);
949 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGTNE_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellTriggerNegativeEdge
;
950 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGTNE_RESUME_WELL
, NewValue
) ;
951 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGGPE_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellGPEEnable
;
952 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGGPE_RESUME_WELL
, NewValue
);
953 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGSMI_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellSMIEnable
;
954 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGSMI_RESUME_WELL
, NewValue
);
955 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RGTS_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellTriggerStatus
;
956 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RGTS_RESUME_WELL
, NewValue
) ;
957 NewValue
= (IoRead32 (GpioBaseAddress
+ R_QNC_GPIO_RNMIEN_RESUME_WELL
) & 0xFFFFFFC0) | LegacyGpioConfig
->ResumeWellNMIEnable
;
958 IoWrite32 (GpioBaseAddress
+ R_QNC_GPIO_RNMIEN_RESUME_WELL
, NewValue
);
962 Performs any early platform specific Legacy GPIO manipulation.
964 @param PlatformType Platform type GPIO manipulation.
969 EarlyPlatformLegacyGpioManipulation (
970 IN CONST EFI_PLATFORM_TYPE PlatformType
973 if (PlatformType
== CrossHill
) {
976 // Pull TPM reset low for 80us (equivalent to cold reset, Table 39
977 // Infineon SLB9645 Databook), then pull TPM reset high and wait for
978 // 150ms to give time for TPM to stabilise (Section 4.7.1 Infineon
979 // SLB9645 Databook states TPM is ready to receive command after 30ms
980 // but section 4.7 states some TPM commands may take longer to execute
981 // upto 150ms after test).
984 PlatformLegacyGpioSetLevel (
985 R_QNC_GPIO_RGLVL_RESUME_WELL
,
986 PLATFORM_RESUMEWELL_TPM_RST_GPIO
,
989 MicroSecondDelay (80);
991 PlatformLegacyGpioSetLevel (
992 R_QNC_GPIO_RGLVL_RESUME_WELL
,
993 PLATFORM_RESUMEWELL_TPM_RST_GPIO
,
996 MicroSecondDelay (150000);
1002 Performs any early platform specific GPIO Controller init & manipulation.
1004 @param PlatformType Platform type for GPIO init & manipulation.
1009 EarlyPlatformGpioCtrlerInitAndManipulation (
1010 IN CONST EFI_PLATFORM_TYPE PlatformType
1016 BOARD_GPIO_CONTROLLER_CONFIG
*GpioConfig
;
1023 ASSERT ((UINTN
) PlatformType
< mBoardGpioControllerConfigTableLen
);
1024 GpioConfig
= &mBoardGpioControllerConfigTable
[(UINTN
) PlatformType
];
1026 IohGpioBase
= (UINT32
) PcdGet64 (PcdIohGpioMmioBase
);
1028 DevPcieAddr
= PCI_LIB_ADDRESS (
1029 PcdGet8 (PcdIohGpioBusNumber
),
1030 PcdGet8 (PcdIohGpioDevNumber
),
1031 PcdGet8 (PcdIohGpioFunctionNumber
),
1036 // Do nothing if not a supported device.
1038 PciVid
= PciRead16 (DevPcieAddr
+ PCI_VENDOR_ID_OFFSET
);
1039 PciDid
= PciRead16 (DevPcieAddr
+ PCI_DEVICE_ID_OFFSET
);
1040 if((PciVid
!= V_IOH_I2C_GPIO_VENDOR_ID
) || (PciDid
!= V_IOH_I2C_GPIO_DEVICE_ID
)) {
1045 // Save current settings for PCI CMD/BAR registers.
1047 SaveCmdReg
= PciRead16 (DevPcieAddr
+ PCI_COMMAND_OFFSET
);
1048 SaveBarReg
= PciRead32 (DevPcieAddr
+ PcdGet8 (PcdIohGpioBarRegister
));
1051 // Use predefined temporary memory resource.
1053 PciWrite32 ( DevPcieAddr
+ PcdGet8 (PcdIohGpioBarRegister
), IohGpioBase
);
1054 PciWrite8 ( DevPcieAddr
+ PCI_COMMAND_OFFSET
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1057 // Gpio Controller Init Tasks.
1061 // IEN- Interrupt Enable Register
1063 Addr
= IohGpioBase
+ GPIO_INTEN
;
1064 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1065 Data32
|= (GpioConfig
->IntEn
& 0x000FFFFF);
1066 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1069 // ISTATUS- Interrupt Status Register
1071 Addr
= IohGpioBase
+ GPIO_INTSTATUS
;
1072 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1073 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1076 // GPIO SWPORTA Direction Register - GPIO_SWPORTA_DR
1078 Addr
= IohGpioBase
+ GPIO_SWPORTA_DR
;
1079 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1080 Data32
|= (GpioConfig
->PortADR
& 0x000FFFFF);
1081 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1084 // GPIO SWPORTA Data Direction Register - GPIO_SWPORTA_DDR - default input
1086 Addr
= IohGpioBase
+ GPIO_SWPORTA_DDR
;
1087 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1088 Data32
|= (GpioConfig
->PortADir
& 0x000FFFFF);
1089 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1092 // Interrupt Mask Register - GPIO_INTMASK - default interrupts unmasked
1094 Addr
= IohGpioBase
+ GPIO_INTMASK
;
1095 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1096 Data32
|= (GpioConfig
->IntMask
& 0x000FFFFF);
1097 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1100 // Interrupt Level Type Register - GPIO_INTTYPE_LEVEL - default is level sensitive
1102 Addr
= IohGpioBase
+ GPIO_INTTYPE_LEVEL
;
1103 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1104 Data32
|= (GpioConfig
->IntType
& 0x000FFFFF);
1105 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1108 // Interrupt Polarity Type Register - GPIO_INT_POLARITY - default is active low
1110 Addr
= IohGpioBase
+ GPIO_INT_POLARITY
;
1111 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1112 Data32
|= (GpioConfig
->IntPolarity
& 0x000FFFFF);
1113 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1116 // Interrupt Debounce Type Register - GPIO_DEBOUNCE - default no debounce
1118 Addr
= IohGpioBase
+ GPIO_DEBOUNCE
;
1119 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1120 Data32
|= (GpioConfig
->Debounce
& 0x000FFFFF);
1121 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1124 // Interrupt Clock Synchronisation Register - GPIO_LS_SYNC - default no sync with pclk_intr(APB bus clk)
1126 Addr
= IohGpioBase
+ GPIO_LS_SYNC
;
1127 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
)) & 0xFFFFFF00; // Keep reserved bits [31:8]
1128 Data32
|= (GpioConfig
->LsSync
& 0x000FFFFF);
1129 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1132 // Gpio Controller Manipulation Tasks.
1135 if (PlatformType
== (EFI_PLATFORM_TYPE
) Galileo
) {
1137 // Reset Cypress Expander on Galileo Platform
1139 Addr
= IohGpioBase
+ GPIO_SWPORTA_DR
;
1140 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
));
1141 Data32
|= BIT4
; // Cypress Reset line controlled by GPIO<4>
1142 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1144 Data32
= *((volatile UINT32
*) (UINTN
)(Addr
));
1145 Data32
&= ~BIT4
; // Cypress Reset line controlled by GPIO<4>
1146 *((volatile UINT32
*) (UINTN
)(Addr
)) = Data32
;
1151 // Restore settings for PCI CMD/BAR registers
1153 PciWrite32 ((DevPcieAddr
+ PcdGet8 (PcdIohGpioBarRegister
)), SaveBarReg
);
1154 PciWrite16 (DevPcieAddr
+ PCI_COMMAND_OFFSET
, SaveCmdReg
);
1158 Performs any early platform init of SoC Ethernet Mac devices.
1160 @param IohMac0Address Mac address to program into Mac0 device.
1161 @param IohMac1Address Mac address to program into Mac1 device.
1166 EarlyPlatformMacInit (
1167 IN CONST UINT8
*IohMac0Address
,
1168 IN CONST UINT8
*IohMac1Address
1174 // Set chipset MAC0 address if configured.
1177 (CompareMem (ChipsetDefaultMac
, IohMac0Address
, sizeof (ChipsetDefaultMac
))) != 0;
1179 if ((*(IohMac0Address
) & BIT0
) != 0) {
1180 DEBUG ((EFI_D_ERROR
, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n",
1181 (UINTN
) IOH_MAC0_BUS_NUMBER
,
1182 (UINTN
) IOH_MAC0_DEVICE_NUMBER
,
1183 (UINTN
) IOH_MAC0_FUNCTION_NUMBER
1187 SetLanControllerMacAddr (
1188 IOH_MAC0_BUS_NUMBER
,
1189 IOH_MAC0_DEVICE_NUMBER
,
1190 IOH_MAC0_FUNCTION_NUMBER
,
1192 (UINT32
) PcdGet64(PcdIohMac0MmioBase
)
1196 DEBUG ((EFI_D_WARN
, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n",
1197 (UINTN
) IOH_MAC0_BUS_NUMBER
,
1198 (UINTN
) IOH_MAC0_DEVICE_NUMBER
,
1199 (UINTN
) IOH_MAC0_FUNCTION_NUMBER
1204 // Set chipset MAC1 address if configured.
1207 (CompareMem (ChipsetDefaultMac
, IohMac1Address
, sizeof (ChipsetDefaultMac
))) != 0;
1209 if ((*(IohMac1Address
) & BIT0
) != 0) {
1210 DEBUG ((EFI_D_ERROR
, "HALT: Multicast Mac Address configured for Ioh MAC [B:%d, D:%d, F:%d]\n",
1211 (UINTN
) IOH_MAC1_BUS_NUMBER
,
1212 (UINTN
) IOH_MAC1_DEVICE_NUMBER
,
1213 (UINTN
) IOH_MAC1_FUNCTION_NUMBER
1217 SetLanControllerMacAddr (
1218 IOH_MAC1_BUS_NUMBER
,
1219 IOH_MAC1_DEVICE_NUMBER
,
1220 IOH_MAC1_FUNCTION_NUMBER
,
1222 (UINT32
) PcdGet64(PcdIohMac1MmioBase
)
1226 DEBUG ((EFI_D_WARN
, "WARNING: Ioh MAC [B:%d, D:%d, F:%d] NO HW ADDR CONFIGURED!!!\n",
1227 (UINTN
) IOH_MAC1_BUS_NUMBER
,
1228 (UINTN
) IOH_MAC1_DEVICE_NUMBER
,
1229 (UINTN
) IOH_MAC1_FUNCTION_NUMBER