return EFI_SUCCESS;\r
}\r
\r
-/**\r
-\r
- Check whether go to recovery path\r
- @retval TRUE Go to recovery path\r
- @retval FALSE Go to normal path\r
-\r
-**/\r
-BOOLEAN\r
-OemRecoveryBootMode ()\r
-{\r
- return PlatformIsBootWithRecoveryStage1 ();\r
-}\r
-\r
/**\r
Peform the boot mode determination logic\r
If the box is closed, then\r
EFI_STATUS Status;\r
EFI_BOOT_MODE NewBootMode;\r
PEI_CAPSULE_PPI *Capsule;\r
- CHAR8 UserSelection;\r
- UINT32 Straps32;\r
+ UINT32 RegValue;\r
+\r
+ NewBootMode = *BootMode;\r
\r
//\r
- // Read Straps. Used later if recovery boot.\r
+ // Read Sticky R/W Bits\r
//\r
- Straps32 = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_STPDDRCFG);\r
+ RegValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW);\r
+ DEBUG ((EFI_D_ERROR, "RegValue = %08x\n", RegValue));\r
\r
//\r
// Check if we need to boot in recovery mode\r
//\r
- if ((ValidateFvHeader (BootMode) != EFI_SUCCESS)) {\r
- DEBUG ((EFI_D_INFO, "Force Boot mode recovery\n"));\r
+ if ((RegValue & B_CFG_STICKY_RW_FORCE_RECOVERY) != 0) {\r
NewBootMode = BOOT_IN_RECOVERY_MODE;\r
- Status = PeiServicesInstallPpi (&mPpiListRecoveryBootMode);\r
- ASSERT_EFI_ERROR (Status);\r
- if (OemRecoveryBootMode () == FALSE) {\r
- DEBUG ((EFI_D_INFO, "Recovery stage1 not Active, reboot to activate recovery stage1 image\n"));\r
- OemInitiateRecoveryAndWait ();\r
- }\r
- } else if (OemRecoveryBootMode ()) {\r
- DEBUG ((EFI_D_INFO, "Boot mode recovery\n"));\r
+ DEBUG ((EFI_D_ERROR, "RECOVERY from sticky bit\n"));;\r
+\r
+ //\r
+ // Clear force recovery sticky bit\r
+ //\r
+ QNCAltPortWrite (\r
+ QUARK_SCSS_SOC_UNIT_SB_PORT_ID,\r
+ QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW,\r
+ RegValue &(~B_CFG_STICKY_RW_FORCE_RECOVERY)\r
+ );\r
+\r
+ } else if (ValidateFvHeader (BootMode) != EFI_SUCCESS) {\r
NewBootMode = BOOT_IN_RECOVERY_MODE;\r
- Status = PeiServicesInstallPpi (&mPpiListRecoveryBootMode);\r
- ASSERT_EFI_ERROR (Status);\r
+ DEBUG ((EFI_D_ERROR, "RECOVERY from corrupt FV\n"));;\r
} else if (QNCCheckS3AndClearState ()) {\r
//\r
// Determine if we're in capsule update mode\r
NewBootMode = BOOT_WITH_FULL_CONFIGURATION;\r
}\r
}\r
- *BootMode = NewBootMode;\r
- Status = PeiServicesSetBootMode (NewBootMode);\r
- ASSERT_EFI_ERROR (Status);\r
\r
- //\r
- // If Recovery Boot then prompt the user to insert a USB key with recovery nodule and\r
- // continue with the recovery. Also give the user a chance to retry a normal boot.\r
- //\r
if (NewBootMode == BOOT_IN_RECOVERY_MODE) {\r
- if ((Straps32 & B_STPDDRCFG_FORCE_RECOVERY) == 0) {\r
- DEBUG ((EFI_D_ERROR, "*****************************************************************\n"));\r
- DEBUG ((EFI_D_ERROR, "***** Force Recovery Jumper Detected. *****\n"));\r
- DEBUG ((EFI_D_ERROR, "***** Attempting auto recovery of system flash. *****\n"));\r
- DEBUG ((EFI_D_ERROR, "***** Expecting USB key with recovery module connected. *****\n"));\r
- DEBUG ((EFI_D_ERROR, "***** PLEASE REMOVE FORCE RECOVERY JUMPER. *****\n"));\r
- DEBUG ((EFI_D_ERROR, "*****************************************************************\n"));\r
- } else {\r
- DEBUG ((EFI_D_ERROR, "*****************************************************************\n"));\r
- DEBUG ((EFI_D_ERROR, "***** ERROR: System boot failure!!!!!!! *****\n"));\r
- DEBUG ((EFI_D_ERROR, "***** - Press 'R' if you wish to force system recovery *****\n"));\r
- DEBUG ((EFI_D_ERROR, "***** (connect USB key with recovery module first) *****\n"));\r
- DEBUG ((EFI_D_ERROR, "***** - Press any other key to attempt another boot *****\n"));\r
- DEBUG ((EFI_D_ERROR, "*****************************************************************\n"));\r
-\r
- UserSelection = PlatformDebugPortGetChar8 ();\r
- if ((UserSelection != 'R') && (UserSelection != 'r')) {\r
- DEBUG ((EFI_D_ERROR, "New boot attempt selected........\n"));\r
- //\r
- // Initialte the cold reset\r
- //\r
- ResetCold ();\r
- }\r
- DEBUG ((EFI_D_ERROR, "Recovery boot selected..........\n"));\r
- }\r
+ DEBUG ((EFI_D_INFO, "Boot mode recovery\n"));\r
+ Status = PeiServicesInstallPpi (&mPpiListRecoveryBootMode);\r
+ ASSERT_EFI_ERROR (Status);\r
}\r
\r
+ Status = PeiServicesSetBootMode (NewBootMode);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ *BootMode = NewBootMode;\r
+\r
return EFI_SUCCESS;\r
}\r
#include <Library/IntelQNCLib.h>\r
#include <Library/PcdLib.h>\r
#include <Library/SmbusLib.h>\r
-#include <Library/RecoveryOemHookLib.h>\r
#include <Library/TimerLib.h>\r
#include <Library/PrintLib.h>\r
#include <Library/ResetSystemLib.h>\r
\r
#include <Register/Cpuid.h>\r
\r
+#include <Pcal9555.h>\r
+#include <QNCAccess.h>\r
+\r
#endif\r
UINT64 PeiMemoryLength;\r
UINTN BufferSize;\r
UINTN PeiMemoryIndex;\r
- UINTN RequiredMemSize;\r
EFI_RESOURCE_ATTRIBUTE_TYPE Attribute;\r
EFI_PHYSICAL_ADDRESS BadMemoryAddress;\r
EFI_SMRAM_DESCRIPTOR DescriptorAcpiVariable;\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
- //\r
- // Get required memory size for ACPI use. This helps to put ACPI memory on the topest\r
- //\r
- RequiredMemSize = 0;\r
- RetriveRequiredMemorySize (PeiServices, &RequiredMemSize);\r
-\r
//\r
// Detect MOR request by the OS.\r
//\r
//\r
Status = SetPlatformImrPolicy (\r
PeiMemoryBaseAddress,\r
- PeiMemoryLength,\r
- RequiredMemSize\r
+ PeiMemoryLength\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
// Carve out the top memory reserved for ACPI\r
//\r
- Status = PeiServicesInstallPeiMemory (PeiMemoryBaseAddress, (PeiMemoryLength - RequiredMemSize));\r
+ Status = PeiServicesInstallPeiMemory (PeiMemoryBaseAddress, PeiMemoryLength);\r
ASSERT_EFI_ERROR (Status);\r
\r
BuildResourceDescriptorHob (\r
return EFI_SUCCESS;\r
}\r
\r
-/**\r
-\r
- This function returns the size, in bytes, required for the DXE phase.\r
-\r
- @param PeiServices PEI Services table.\r
- @param Size Pointer to the size, in bytes, required for the DXE phase.\r
-\r
- @return None\r
-\r
-**/\r
-VOID\r
-RetriveRequiredMemorySize (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- OUT UINTN *Size\r
- )\r
-{\r
- EFI_PEI_HOB_POINTERS Hob;\r
- EFI_MEMORY_TYPE_INFORMATION *MemoryData;\r
- UINT8 Index;\r
- UINTN TempPageNum;\r
-\r
- MemoryData = NULL;\r
- TempPageNum = 0;\r
- Index = 0;\r
-\r
- PeiServicesGetHobList ((VOID **)&Hob.Raw);\r
- while (!END_OF_HOB_LIST (Hob)) {\r
- if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION &&\r
- CompareGuid (&Hob.Guid->Name, &gEfiMemoryTypeInformationGuid)\r
- ) {\r
- MemoryData = (EFI_MEMORY_TYPE_INFORMATION *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID));\r
- break;\r
- }\r
-\r
- Hob.Raw = GET_NEXT_HOB (Hob);\r
- }\r
- //\r
- // Platform PEIM should supply such a information. Generic PEIM doesn't assume any default value\r
- //\r
- if (!MemoryData) {\r
- return ;\r
- }\r
-\r
- while (MemoryData[Index].Type != EfiMaxMemoryType) {\r
- //\r
- // Accumulate default memory size requirements\r
- //\r
- TempPageNum += MemoryData[Index].NumberOfPages;\r
- Index++;\r
- }\r
-\r
- if (TempPageNum == 0) {\r
- return ;\r
- }\r
-\r
- //\r
- // Add additional pages used by DXE memory manager\r
- //\r
- (*Size) = (TempPageNum + EDKII_DXE_MEM_SIZE_PAGES) * EFI_PAGE_SIZE;\r
-\r
- return ;\r
-}\r
-\r
/**\r
\r
This function returns the memory ranges to be enabled, along with information\r
\r
@param PeiMemoryBaseAddress Base address of memory allocated for PEI.\r
@param PeiMemoryLength Length in bytes of the PEI memory (includes ACPI memory).\r
- @param RequiredMemSize Size in bytes of the ACPI/Runtime memory\r
\r
@return EFI_SUCCESS The function completed successfully.\r
EFI_ACCESS_DENIED Access to IMRs failed.\r
EFI_STATUS\r
SetPlatformImrPolicy (\r
IN EFI_PHYSICAL_ADDRESS PeiMemoryBaseAddress,\r
- IN UINT64 PeiMemoryLength,\r
- IN UINTN RequiredMemSize\r
+ IN UINT64 PeiMemoryLength\r
)\r
{\r
UINT8 Index;\r
}\r
}\r
\r
- //\r
- // Add IMR0 protection for the 'PeiMemory'\r
- //\r
- QncImrWrite (\r
- QUARK_NC_MEMORY_MANAGER_IMR0,\r
- (UINT32)(((RShiftU64(PeiMemoryBaseAddress, 8)) & IMRL_MASK) | IMR_EN),\r
- (UINT32)((RShiftU64((PeiMemoryBaseAddress+PeiMemoryLength-RequiredMemSize + EFI_PAGES_TO_SIZE(EDKII_DXE_MEM_SIZE_PAGES-1) - 1), 8)) & IMRL_MASK),\r
- (UINT32)(CPU_SNOOP + CPU0_NON_SMM),\r
- (UINT32)(CPU_SNOOP + CPU0_NON_SMM)\r
- );\r
-\r
//\r
// Add IMR2 protection for shadowed RMU binary.\r
//\r
(UINT32)(CPU_SNOOP + CPU0_NON_SMM)\r
);\r
\r
- //\r
- // Add IMR5 protection for the legacy S3 and AP Startup Vector region (below 1MB).\r
- //\r
- QncImrWrite (\r
- QUARK_NC_MEMORY_MANAGER_IMR5,\r
- (UINT32)(((RShiftU64(AP_STARTUP_VECTOR, 8)) & IMRL_MASK) | IMR_EN),\r
- (UINT32)((RShiftU64((AP_STARTUP_VECTOR + EFI_PAGE_SIZE - 1), 8)) & IMRH_MASK),\r
- (UINT32)(CPU_SNOOP + CPU0_NON_SMM),\r
- (UINT32)(CPU_SNOOP + CPU0_NON_SMM)\r
- );\r
-\r
- //\r
- // Add IMR6 protection for the ACPI Reclaim/ACPI/Runtime Services.\r
- //\r
- QncImrWrite (\r
- QUARK_NC_MEMORY_MANAGER_IMR6,\r
- (UINT32)(((RShiftU64((PeiMemoryBaseAddress+PeiMemoryLength-RequiredMemSize+EFI_PAGES_TO_SIZE(EDKII_DXE_MEM_SIZE_PAGES-1)), 8)) & IMRL_MASK) | IMR_EN),\r
- (UINT32)((RShiftU64((PeiMemoryBaseAddress+PeiMemoryLength-EFI_PAGE_SIZE-1), 8)) & IMRH_MASK),\r
- (UINT32)(CPU_SNOOP + CPU0_NON_SMM),\r
- (UINT32)(CPU_SNOOP + CPU0_NON_SMM)\r
- );\r
-\r
//\r
// Enable IMR4 protection of eSRAM.\r
//\r
#define ACPI_RECLAIM_SIZE_PAGES 0x20\r
#define EDKII_DXE_MEM_SIZE_PAGES 0x20\r
\r
-#define AP_STARTUP_VECTOR 0x00097000\r
-\r
//\r
// Maximum number of "Socket Sets", where a "Socket Set is a set of matching\r
// DIMM's from the various channels\r
IN MRCParams_t *MrcData\r
);\r
\r
-VOID\r
-RetriveRequiredMemorySize (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- OUT UINTN *Size\r
- );\r
-\r
EFI_STATUS\r
GetMemoryMap (\r
IN EFI_PEI_SERVICES **PeiServices,\r
EFI_STATUS\r
SetPlatformImrPolicy (\r
IN EFI_PHYSICAL_ADDRESS PeiMemoryBaseAddress,\r
- IN UINT64 PeiMemoryLength,\r
- IN UINTN RequiredMemSize\r
+ IN UINT64 PeiMemoryLength\r
);\r
\r
VOID\r
**/\r
EFI_STATUS\r
EarlyPlatformConfigGpioExpanders (\r
- IN CONST EFI_PLATFORM_TYPE PlatformType\r
+ IN CONST EFI_PLATFORM_TYPE PlatformType,\r
+ EFI_BOOT_MODE BootMode\r
)\r
{\r
EFI_STATUS Status;\r
GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2.\r
15 // P1-7.\r
);\r
+\r
+ if (BootMode != BOOT_IN_RECOVERY_MODE) {\r
+ //\r
+ // Read state of Reset Button - EXP2.P1_7\r
+ // This GPIO is pulled high when the button is not pressed\r
+ // This GPIO reads low when button is pressed\r
+ //\r
+ if (!PlatformPcal9555GpioGetState (\r
+ GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2\r
+ 15 // P1-7\r
+ )) {\r
+ DEBUG ((EFI_D_INFO, " Force Recovery mode and reset\n"));\r
+\r
+ //\r
+ // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset\r
+ //\r
+ QNCAltPortWrite (\r
+ QUARK_SCSS_SOC_UNIT_SB_PORT_ID,\r
+ QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW,\r
+ QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW) | B_CFG_STICKY_RW_FORCE_RECOVERY\r
+ );\r
+ ResetWarm();\r
+ }\r
+ }\r
}\r
\r
//\r
&Buffer\r
);\r
ASSERT_EFI_ERROR (Status);\r
+\r
+ if (BootMode != BOOT_IN_RECOVERY_MODE) {\r
+ //\r
+ // Read state of RESET_N_SHLD (GPORT5_BIT0)\r
+ //\r
+ Buffer[1] = 5;\r
+ Length = 1;\r
+ ReadLength = 1;\r
+ Status = I2cReadMultipleByte (\r
+ I2CSlaveAddress,\r
+ EfiI2CSevenBitAddrMode,\r
+ &Length,\r
+ &ReadLength,\r
+ &Buffer[1]\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Return the state of GPORT5_BIT0\r
+ //\r
+ if ((Buffer[1] & BIT0) == 0) {\r
+ DEBUG ((EFI_D_INFO, " Force Recovery mode and reset\n"));\r
+\r
+ //\r
+ // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset\r
+ //\r
+ QNCAltPortWrite (\r
+ QUARK_SCSS_SOC_UNIT_SB_PORT_ID,\r
+ QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW,\r
+ QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW) | B_CFG_STICKY_RW_FORCE_RECOVERY\r
+ );\r
+ ResetWarm();\r
+ }\r
+ }\r
}\r
\r
return EFI_SUCCESS;\r
//\r
//\r
DEBUG ((EFI_D_INFO, "EarlyPlatformConfigGpioExpanders ()\n"));\r
- EarlyPlatformConfigGpioExpanders (PlatformType);\r
+ EarlyPlatformConfigGpioExpanders (PlatformType, BootMode);\r
\r
//\r
// Now that all of the pre-permanent memory activities have\r
//\r
if (CheckForResetDueToErrors (TRUE)) {\r
if(FeaturePcdGet (WaitIfResetDueToError)) {\r
- DEBUG ((EFI_D_ERROR, "Press any key to continue.\n"));\r
- PlatformDebugPortGetChar8 ();\r
+ DEBUG ((EFI_D_ERROR, "Wait 10 seconds.\n"));\r
+ MicroSecondDelay(10000000);\r
}\r
}\r
\r
ResetSystemLib\r
PrintLib\r
TimerLib\r
- RecoveryOemHookLib\r
PcdLib\r
IntelQNCLib\r
ReportStatusCodeLib\r