QuarkPlatformPkg/PlatformInit: Fix recovery detection issues

https://bugzilla.tianocore.org/show_bug.cgi?id=137
https://bugzilla.tianocore.org/show_bug.cgi?id=139

There are four supported methods to generate a boot mode of
BOOT_IN_RECOVERY_MODE on the Galileo platforms:

* Detect a corrupt FV
* Detect a forced recovery from the ForceRecovery UEFI application
  that sets a bit in a sticky R/W register
* The RESET button for the Arduino shield is held while the system
  is powered up
* The RESET button for the Arduino shield is held while the system
  is rebooted using the REBOOT button.

The logic in the PlatformInit module is cleaned up and updated to
support all three of the recovery detection methods.  The clean
ups include:

* Remove extra debug messages
* Remove user input from serial port

In addition, once one of the recovery methods is detected and a
boot mode of BOOT_IN_RECOVERY_MODE is set, the Galileo platforms
would get an error attempting to use the USB host controller to
detect and read a recovery image from a USB drive.  The issue is
the IMR protection registers are programmed to prevent DMA to
memory owned by the PEI Core. The IMR register programming is
updated to allow DMA to memory that is allocated by the recovery
modules using the PEI AllocatePages() service.

Cc: Kelly Steele <kelly.steele@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <michael.d.kinney@intel.com>
Reviewed-by: Kelly Steele <kelly.steele@intel.com>
This commit is contained in:
Michael Kinney
2016-10-03 11:13:42 -07:00
parent 9c3dea8dda
commit 69a0854b8f
6 changed files with 98 additions and 186 deletions

View File

@@ -200,7 +200,8 @@ SetLanControllerMacAddr (
**/
EFI_STATUS
EarlyPlatformConfigGpioExpanders (
IN CONST EFI_PLATFORM_TYPE PlatformType
IN CONST EFI_PLATFORM_TYPE PlatformType,
EFI_BOOT_MODE BootMode
)
{
EFI_STATUS Status;
@@ -266,6 +267,30 @@ EarlyPlatformConfigGpioExpanders (
GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2.
15 // P1-7.
);
if (BootMode != BOOT_IN_RECOVERY_MODE) {
//
// Read state of Reset Button - EXP2.P1_7
// This GPIO is pulled high when the button is not pressed
// This GPIO reads low when button is pressed
//
if (!PlatformPcal9555GpioGetState (
GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2
15 // P1-7
)) {
DEBUG ((EFI_D_INFO, " Force Recovery mode and reset\n"));
//
// Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset
//
QNCAltPortWrite (
QUARK_SCSS_SOC_UNIT_SB_PORT_ID,
QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW,
QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW) | B_CFG_STICKY_RW_FORCE_RECOVERY
);
ResetWarm();
}
}
}
//
@@ -393,6 +418,40 @@ EarlyPlatformConfigGpioExpanders (
&Buffer
);
ASSERT_EFI_ERROR (Status);
if (BootMode != BOOT_IN_RECOVERY_MODE) {
//
// Read state of RESET_N_SHLD (GPORT5_BIT0)
//
Buffer[1] = 5;
Length = 1;
ReadLength = 1;
Status = I2cReadMultipleByte (
I2CSlaveAddress,
EfiI2CSevenBitAddrMode,
&Length,
&ReadLength,
&Buffer[1]
);
ASSERT_EFI_ERROR (Status);
//
// Return the state of GPORT5_BIT0
//
if ((Buffer[1] & BIT0) == 0) {
DEBUG ((EFI_D_INFO, " Force Recovery mode and reset\n"));
//
// Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset
//
QNCAltPortWrite (
QUARK_SCSS_SOC_UNIT_SB_PORT_ID,
QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW,
QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW) | B_CFG_STICKY_RW_FORCE_RECOVERY
);
ResetWarm();
}
}
}
return EFI_SUCCESS;
@@ -514,7 +573,7 @@ PeiInitPlatform (
//
//
DEBUG ((EFI_D_INFO, "EarlyPlatformConfigGpioExpanders ()\n"));
EarlyPlatformConfigGpioExpanders (PlatformType);
EarlyPlatformConfigGpioExpanders (PlatformType, BootMode);
//
// Now that all of the pre-permanent memory activities have
@@ -791,8 +850,8 @@ EarlyPlatformInit (
//
if (CheckForResetDueToErrors (TRUE)) {
if(FeaturePcdGet (WaitIfResetDueToError)) {
DEBUG ((EFI_D_ERROR, "Press any key to continue.\n"));
PlatformDebugPortGetChar8 ();
DEBUG ((EFI_D_ERROR, "Wait 10 seconds.\n"));
MicroSecondDelay(10000000);
}
}