[TGL] Fix infinite reset loop caused by bad DSO
This patch solves an infinite reset loop issue caused by bad DSO with the scenario: After platform reset (due to WDT timeout), FSPm asks for another reset, but before that, WDT_FLAG_TCC_DSO_IN_PROGRESS is already cleaned. As a result, in the thrid reset, stage1B will have no idea about the DSO is corrupted and it continues boot with Tcc Tuning flow, which causes WDT timeout reset again. This patch introduces a WDT_FLAG_TCC_BAD_DSO flag in WDT scrachpad (bit 18). The flag is a marker that is set when a bad DSO is detected. The new booting flow for "bad DSO" case if Tcc_Tuning enabled will be: 1st boot: (after fwupdate) - TCC_DSO and WDT set by stage1b and stage2 - FSP hangs and trigger WDT reset 2nd boot: - Stage1b detects "bad DSO" because of WDT and TCC_DSO_IN_PROGRESS. For this case: Clear TCC_DSO_IN_PROGRESS and WDT. Set TCC_BAD_DSO. Then it continues boot that will skip Tcc Tuning (because of TCC_DSO_IN_PROGRESS unset) - FSPm asks for a reset 3rd boot: - Stage1b detects "bad DSO" because of TCC_BAD_DSO It continues boot that will skip Tcc Tuning (because of TCC_DSO_IN_PROGRESS unset) The patch does not remove the 200-sec abnormal boot-up symptom because the symptom is noticeable to user. So user can be aware of something wrong (bad DSO). The "bad DSO" flag will be clear before fwupdate, so a fwupdate with a correct DSO can solve the 200 sec abnormal boot up time. Signed-off-by: Stanley Chang <stanley.chang@intel.com>
This commit is contained in:
parent
1e5a04030c
commit
bfbc7943e0
|
@ -108,13 +108,15 @@ TccModePreMemConfig (
|
|||
DEBUG ((DEBUG_INFO, "S0ix is turned off when TCC is enabled\n"));
|
||||
}
|
||||
|
||||
if (IsWdtFlagsSet(WDT_FLAG_TCC_DSO) && IsWdtTimeout()) {
|
||||
DEBUG ((DEBUG_INFO, "Incorrect TCC tuning parameters. Platform rebooted with default values.\n"));
|
||||
WdtClearFlags (WDT_FLAG_TCC_DSO);
|
||||
if (IsWdtFlagsSet(WDT_FLAG_TCC_BAD_DSO) ||
|
||||
(IsWdtFlagsSet(WDT_FLAG_TCC_DSO_IN_PROGRESS) && IsWdtTimeout())) {
|
||||
DEBUG ((DEBUG_ERROR, "Incorrect TCC tuning parameters. Platform rebooted with default values.\n"));
|
||||
WdtClearScratchpad (WDT_FLAG_TCC_DSO_IN_PROGRESS);
|
||||
WdtSetScratchpad (WDT_FLAG_TCC_BAD_DSO);
|
||||
FspmUpd->FspmConfig.TccStreamCfgStatusPreMem = 1;
|
||||
} else if (TccCfgData->TccTuning != 0) {
|
||||
// Setup Watch dog timer
|
||||
WdtReloadAndStart (WDT_TIMEOUT_TCC_DSO, WDT_FLAG_TCC_DSO);
|
||||
WdtReloadAndStart (WDT_TIMEOUT_TCC_DSO, WDT_FLAG_TCC_DSO_IN_PROGRESS);
|
||||
|
||||
// Load TCC stream config from container
|
||||
TccStreamBase = NULL;
|
||||
|
|
|
@ -902,8 +902,8 @@ BoardInit (
|
|||
Status = PcdSet32S (PcdAcpiTableTemplatePtr, (UINT32)(UINTN)mPlatformAcpiTables);
|
||||
break;
|
||||
case PostSiliconInit:
|
||||
if (IsWdtFlagsSet(WDT_FLAG_TCC_DSO)) {
|
||||
WdtDisable (WDT_FLAG_TCC_DSO);
|
||||
if (IsWdtFlagsSet(WDT_FLAG_TCC_DSO_IN_PROGRESS)) {
|
||||
WdtDisable (WDT_FLAG_TCC_DSO_IN_PROGRESS);
|
||||
}
|
||||
// Set TSEG base/size PCD
|
||||
TsegBase = MmioRead32 (TO_MM_PCI_ADDRESS (0x00000000) + R_SA_TSEGMB) & ~0xF;
|
||||
|
@ -1024,6 +1024,9 @@ BoardInit (
|
|||
case ReadyToBoot:
|
||||
if ((GetBootMode() != BOOT_ON_FLASH_UPDATE) && (GetPayloadId() == 0)) {
|
||||
ProgramSecuritySetting ();
|
||||
} else if (GetBootMode() == BOOT_ON_FLASH_UPDATE) {
|
||||
/* clear bad DSO mark (if have), so next boot is a fresh restart */
|
||||
WdtClearScratchpad (WDT_FLAG_TCC_BAD_DSO);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -1190,7 +1193,7 @@ TccModePostMemConfig (
|
|||
FspsUpd->FspsConfig.TccErrorLogEn = TccCfgData->TccErrorLog;
|
||||
FspsUpd->FspsConfig.IfuEnable = 0;
|
||||
|
||||
if (!IsWdtFlagsSet(WDT_FLAG_TCC_DSO)) {
|
||||
if (!IsWdtFlagsSet(WDT_FLAG_TCC_DSO_IN_PROGRESS)) {
|
||||
//
|
||||
// If FSPM doesn't enable TCC DSO timer, FSPS should also skip TCC DSO.
|
||||
//
|
||||
|
@ -1198,7 +1201,7 @@ TccModePostMemConfig (
|
|||
FspsUpd->FspsConfig.TccStreamCfgStatus = 1;
|
||||
} else if (TccCfgData->TccTuning != 0) {
|
||||
// Reload Watch dog timer
|
||||
WdtReloadAndStart (WDT_TIMEOUT_TCC_DSO, WDT_FLAG_TCC_DSO);
|
||||
WdtReloadAndStart (WDT_TIMEOUT_TCC_DSO, WDT_FLAG_TCC_DSO_IN_PROGRESS);
|
||||
|
||||
// Load TCC stream config from container
|
||||
TccStreamBase = NULL;
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
#ifndef WATCH_DOG_TIMBER_LIB_H_
|
||||
#define WATCH_DOG_TIMBER_LIB_H_
|
||||
|
||||
#define WDT_TIMEOUT_TCC_DSO 200 // 200 seconds
|
||||
#define WDT_FLAG_TCC_DSO BIT17
|
||||
#define WDT_FLAG_MASK BIT17
|
||||
#define WDT_TIMEOUT_TCC_DSO 200 // 200 seconds
|
||||
#define WDT_FLAG_TCC_DSO_IN_PROGRESS BIT17
|
||||
#define WDT_FLAG_TCC_BAD_DSO BIT18
|
||||
|
||||
|
||||
/**
|
||||
|
@ -44,14 +44,26 @@ WdtDisable (
|
|||
|
||||
|
||||
/**
|
||||
Clear WDT timer flags.
|
||||
Clear WDT flags in scratchpad
|
||||
|
||||
@param[in] Flags The timer flags that would be cleared.
|
||||
@param[in] Flags The scratchpad flags that would be cleared.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
WdtClearFlags (
|
||||
WdtClearScratchpad (
|
||||
IN UINT32 Flags
|
||||
);
|
||||
|
||||
/**
|
||||
Set WDT flags in scratchpad
|
||||
|
||||
@param[in] Flags The scratchpad flags that would be set.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
WdtSetScratchpad (
|
||||
IN UINT32 Flags
|
||||
);
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define B_ACPI_IO_OC_WDT_CTL_ICCSURV BIT13
|
||||
#define B_ACPI_IO_OC_WDT_CTL_LCK BIT12
|
||||
#define B_ACPI_IO_OC_WDT_CTL_TOV_MASK 0x3FF
|
||||
#define B_ACPI_IO_OC_WDT_CTL_SCRATCHPAD_MASK 0xFF0000
|
||||
|
||||
|
||||
/**
|
||||
|
@ -62,7 +63,8 @@ WdtReloadAndStart (
|
|||
}
|
||||
|
||||
Readback = IoRead32 (WdtGetAddress ());
|
||||
Readback |= (B_ACPI_IO_OC_WDT_CTL_EN | B_ACPI_IO_OC_WDT_CTL_ICCSURV | (Flags & WDT_FLAG_MASK));
|
||||
Readback |= (B_ACPI_IO_OC_WDT_CTL_EN | B_ACPI_IO_OC_WDT_CTL_ICCSURV |
|
||||
(Flags & B_ACPI_IO_OC_WDT_CTL_SCRATCHPAD_MASK));
|
||||
|
||||
Readback &= ~(B_ACPI_IO_OC_WDT_CTL_TOV_MASK);
|
||||
Readback |= ((TimeoutValue - 1) & B_ACPI_IO_OC_WDT_CTL_TOV_MASK);
|
||||
|
@ -88,7 +90,7 @@ WdtDisable (
|
|||
UINT32 Readback;
|
||||
|
||||
Readback = IoRead32 (WdtGetAddress ());
|
||||
Readback &= ~(B_ACPI_IO_OC_WDT_CTL_EN | (Flags & WDT_FLAG_MASK));
|
||||
Readback &= ~(B_ACPI_IO_OC_WDT_CTL_EN | (Flags & B_ACPI_IO_OC_WDT_CTL_SCRATCHPAD_MASK));
|
||||
|
||||
// Clear the status bits
|
||||
Readback |= (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS);
|
||||
|
@ -98,21 +100,46 @@ WdtDisable (
|
|||
|
||||
|
||||
/**
|
||||
Clear WDT timer flags.
|
||||
Clear WDT flags in scratchpad
|
||||
|
||||
@param[in] Flags The timer flags that would be cleared.
|
||||
@param[in] Flags The scratchpad flags that would be cleared.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
WdtClearFlags (
|
||||
WdtClearScratchpad (
|
||||
IN UINT32 Flags
|
||||
)
|
||||
{
|
||||
UINT32 Readback;
|
||||
|
||||
Readback = IoRead32 (WdtGetAddress ());
|
||||
Readback &= ~(Flags & WDT_FLAG_MASK);
|
||||
/* only clear flags in scratchpad */
|
||||
Readback &= ~(Flags & B_ACPI_IO_OC_WDT_CTL_SCRATCHPAD_MASK);
|
||||
/* exclude status fields */
|
||||
Readback &= ~(B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS);
|
||||
IoWrite32 (WdtGetAddress (), Readback);
|
||||
}
|
||||
|
||||
/**
|
||||
Set WDT flags in scratchpad
|
||||
|
||||
@param[in] Flags The scratchpad flags that would be set.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
WdtSetScratchpad (
|
||||
IN UINT32 Flags
|
||||
)
|
||||
{
|
||||
UINT32 Readback;
|
||||
|
||||
Readback = IoRead32 (WdtGetAddress ());
|
||||
/* only set flags in scratchpad */
|
||||
Readback |= (Flags & B_ACPI_IO_OC_WDT_CTL_SCRATCHPAD_MASK);
|
||||
/* exclude status fields */
|
||||
Readback &= ~(B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS);
|
||||
IoWrite32 (WdtGetAddress (), Readback);
|
||||
}
|
||||
|
||||
|
@ -160,7 +187,7 @@ IsWdtFlagsSet (
|
|||
|
||||
Readback = IoRead32 (WdtGetAddress ());
|
||||
|
||||
if ((Readback & (Flags & WDT_FLAG_MASK)) != 0) {
|
||||
if ((Readback & Flags) != 0) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
|
|
Loading…
Reference in New Issue