Skip to content

Commit 9c7a138

Browse files
committed
Update SBE Retry Handling for REIPL_BKP_BMSEEPROM case
This commit updates the hostboot SBE retry handling code for the case of REIPL_BKP_BMSEEPROM. This case requires both the SBE boot seeprom side and the SBE measurement seeprom side to be switched. There were certain places in the code where this case was not being handled properly, including one testcase. Change-Id: Ibc12711f8290c8e90d498300405a3bd46e8611c9 CQ:SW557711 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/142493 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins Combined Simics CI <combined-simics-ci+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Matthew Raybuck <matthew.raybuck@ibm.com> Reviewed-by: Ilya Smirnov <ismirno@us.ibm.com> Reviewed-by: Matt Derksen <mderkse1@us.ibm.com> Reviewed-by: Isaac Salem <isaac.salem@ibm.com> Reviewed-by: Mike Baiocchi <baiocchi@ibm.com>
1 parent f483dd5 commit 9c7a138

3 files changed

Lines changed: 105 additions & 50 deletions

File tree

src/include/usr/sbeio/sbe_retry_handler.H

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class SbeRetryHandler
130130
{TEST_RESTART_SBE, P10_EXTRACT_SBE_RC::RESTART_SBE},
131131
{TEST_RESTART_CBS, P10_EXTRACT_SBE_RC::RESTART_CBS},
132132
{TEST_MAX_LIMITS, P10_EXTRACT_SBE_RC::REIPL_UPD_MSEEPROM},
133-
{TEST_SBE_FAILURE, P10_EXTRACT_SBE_RC::RESTART_SBE},
133+
{TEST_SBE_FAILURE, P10_EXTRACT_SBE_RC::RESTART_SBE}, // NOTE: covers REIPL_BKP_BMSEEPROM
134134
};
135135
#endif
136136

src/usr/sbeio/common/sbe_retry_handler.C

Lines changed: 93 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,9 @@ void SbeRetryHandler::main_sbe_handler( bool i_sbeHalted )
357357
// - then attempt to restart the sbe w/ iv_sbeRestartMethod
358358
// NO_RECOVERY_ACTION = 8,
359359
// - we deconfigure the processor we are retrying and fail out
360+
// REIPL_BKP_BMSEEPROM = 9,
361+
// - Select the backup Measurement and Boot seeproms
362+
// - then attempt to restart the sbe w/ iv_sbeRestartMethod
360363
// RECONFIG_WITH_CLOCK_GARD = 10,
361364
// - we deconfigure the processor we are retrying and fail out
362365
//
@@ -620,11 +623,14 @@ void SbeRetryHandler::main_sbe_handler( bool i_sbeHalted )
620623
// OPTION 2 - Check if we are DONE on THIS SIDE BOOT ATTEMPTS for MAX on seeprom or mseeprom
621624
// each cycle we are working on the SEEPROM or MSEEPROM, so each cycle a new object is instantiated
622625
if( ((this->iv_currentSideBootAttempts >= MAX_SIDE_BOOT_ATTEMPTS) &&
623-
((this->iv_currentAction == P10_EXTRACT_SBE_RC::REIPL_BKP_SEEPROM) ||
624-
(this->iv_currentAction == P10_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM)) ) ||
625-
((this->iv_currentSideBootAttempts_mseeprom >= MAX_SIDE_BOOT_ATTEMPTS) &&
626-
((this->iv_currentAction == P10_EXTRACT_SBE_RC::REIPL_BKP_MSEEPROM) ||
627-
(this->iv_currentAction == P10_EXTRACT_SBE_RC::REIPL_UPD_MSEEPROM)) ) )
626+
((this->iv_currentAction == P10_EXTRACT_SBE_RC::REIPL_BKP_SEEPROM) ||
627+
(this->iv_currentAction == P10_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM) ||
628+
(this->iv_currentAction == P10_EXTRACT_SBE_RC::REIPL_BKP_BMSEEPROM)))
629+
||
630+
((this->iv_currentSideBootAttempts_mseeprom >= MAX_SIDE_BOOT_ATTEMPTS)&&
631+
((this->iv_currentAction == P10_EXTRACT_SBE_RC::REIPL_BKP_MSEEPROM) ||
632+
(this->iv_currentAction == P10_EXTRACT_SBE_RC::REIPL_UPD_MSEEPROM) ||
633+
(this->iv_currentAction == P10_EXTRACT_SBE_RC::REIPL_BKP_BMSEEPROM))))
628634
{
629635
/*@
630636
* @errortype ERRL_SEV_PREDICTIVE
@@ -677,7 +683,7 @@ void SbeRetryHandler::main_sbe_handler( bool i_sbeHalted )
677683
this->iv_currentSideBootAttempts_mseeprom++;
678684
// increment even though we may switch sides later
679685
}
680-
else
686+
else //catch all other cases, i.e. REIPL_BKP_BMSEEPROM and any other future proofing
681687
{
682688
this->iv_currentSideBootAttempts++;
683689
this->iv_currentSideBootAttempts_mseeprom++;
@@ -1644,6 +1650,19 @@ void SbeRetryHandler::bestEffortCheck()
16441650
this->iv_currentAction = P10_EXTRACT_SBE_RC::NO_RECOVERY_ACTION;
16451651
}
16461652
}
1653+
else if(this->iv_currentAction == P10_EXTRACT_SBE_RC::REIPL_BKP_BMSEEPROM)
1654+
{
1655+
// Only switch to NO_RECOVERY_ACTION if BOTH sides have reached the maximum limit
1656+
// - This means if (only) 1 side has reached the limit both sides will still be switched
1657+
// as there is still a chance that switching the other side might help
1658+
if ((this->iv_switchSidesCount >= MAX_SWITCH_SIDE_COUNT) &&
1659+
(this->iv_switchSidesCount_mseeprom >= MAX_SWITCH_SIDE_COUNT))
1660+
{
1661+
SBE_TRACF("bestEffortCheck(): suggested action was REIPL_BKP_BMSEEPROM but that is not possible so changing to NO_RECOVERY_ACTION");
1662+
this->iv_currentAction = P10_EXTRACT_SBE_RC::NO_RECOVERY_ACTION;
1663+
}
1664+
}
1665+
16471666
// If the extract sbe rc hwp tells us to restart, and we have already
16481667
// done 2 retries on this side, then attempt to switch sides, if we can't
16491668
// switch sides, set currentAction to NO_RECOVERY_ACTION
@@ -1679,6 +1698,7 @@ void SbeRetryHandler::bestEffortCheck()
16791698
}
16801699
}
16811700
}
1701+
16821702
SBE_TRACF(EXIT_MRK"bestEffortCheck: iv_switchSidesCount=%llx iv_switchSidesCount_mseeprom=%llx "
16831703
"iv_currentSideBootAttempts=%llx iv_currentSideBootAttempts_mseeprom=%llx iv_boot_restart_count=%d",
16841704
this->iv_switchSidesCount, this->iv_switchSidesCount_mseeprom,
@@ -1740,35 +1760,38 @@ errlHndl_t SbeRetryHandler::switch_sbe_sides(P10_EXTRACT_SBE_RC::RETURN_ACTION i
17401760
}
17411761
#endif
17421762

1743-
// Default values are FAIL SAFE case in below logic
1744-
uint32_t l_sbeOperationMask = SBE::SBE_BOOT_SELECT_MASK >> 32; // PROC register bit 17 and bit 18 value handling
1745-
uint8_t l_sbe_mvpd_reipl_mask = REIPL_MSEEPROM_MASK; // MVPD masking flags on struct mvpdSbKeyword_t
1763+
bool l_switch_boot_seeprom = false;
1764+
bool l_switch_measurement_seeprom = false;
17461765

17471766
if ((i_action == P10_EXTRACT_SBE_RC::REIPL_BKP_SEEPROM) ||
17481767
(i_action == P10_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM))
17491768
{
1750-
l_sbeOperationMask = SBE::SBE_BOOT_SELECT_MASK >> 32;
1751-
// currently only setting MVPD for the MSEEPROM, so this is for future exploitation
1752-
// Should never hit this branch today, but for future
1753-
l_sbe_mvpd_reipl_mask = REIPL_SEEPROM_MASK;
1769+
l_switch_boot_seeprom = true;
17541770
}
17551771
else if ((i_action == P10_EXTRACT_SBE_RC::REIPL_BKP_MSEEPROM) ||
17561772
(i_action == P10_EXTRACT_SBE_RC::REIPL_UPD_MSEEPROM))
17571773
{
1758-
l_sbeOperationMask = SBE::SBE_MBOOT_SELECT_MASK >> 32;
1759-
// used for setting MVPD for MSEEPROM
1760-
l_sbe_mvpd_reipl_mask = REIPL_MSEEPROM_MASK;
1774+
l_switch_measurement_seeprom = true;
1775+
}
1776+
else if (i_action == P10_EXTRACT_SBE_RC::REIPL_BKP_BMSEEPROM)
1777+
{
1778+
l_switch_boot_seeprom = true;
1779+
l_switch_measurement_seeprom = true;
17611780
}
17621781
else
17631782
{
1764-
SBE_TRACF("switch_sbe_sides: Working on FAIL SAFE case i_action=0x%X", i_action);
1783+
// FAIL SAFE option is to flip both boot and measurement
1784+
l_switch_boot_seeprom = true;
1785+
l_switch_measurement_seeprom = true;
1786+
SBE_TRACF("switch_sbe_sides: FAIL SAFE case i_action=0x%X, switch boot and measurement seeprom sides",
1787+
i_action);
17651788
}
1766-
SBE_TRACF("switch_sbe_sides: i_action=0x%X l_sbeOperationMask=0x%X l_sbe_mvpd_reipl_mask=0x%X l_mvpdSbKeyword.flags=0x%X",
1767-
i_action, l_sbeOperationMask, l_sbe_mvpd_reipl_mask, l_mvpdSbKeyword.flags);
1768-
1789+
SBE_TRACF("switch_sbe_sides: i_action=0x%X l_switch_boot_seeprom=%d, "
1790+
"l_switch_measurement_seeprom=%d l_mvpdSbKeyword.flags=0x%X",
1791+
i_action, l_switch_boot_seeprom, l_switch_measurement_seeprom, l_mvpdSbKeyword.flags);
17691792

17701793
do{
1771-
// Read the Selfboot Control/Status register from the appropriate place
1794+
// Read the Selfboot Control/Status reg (used as the authoritative source at this point)
17721795
uint32_t l_ctl_reg = 0;
17731796
l_errl = accessControlReg( ACCESS_READ, l_ctl_reg );
17741797
if( l_errl )
@@ -1780,31 +1803,55 @@ errlHndl_t SbeRetryHandler::switch_sbe_sides(P10_EXTRACT_SBE_RC::RETURN_ACTION i
17801803
break;
17811804
}
17821805

1783-
// Determine how boot side is currently set
1784-
// Works on the previously set l_sbeOperationMask which is either the SEEPROM or MSEEPROM
1785-
// We check either bit 17 (SEEPROM) or bit 18 (MSEEPROM) based on the previous logic above
1786-
// Operations are done on single SEEPROM at a time
1806+
// Determine which boot and measurement sides are currently set and
1807+
// then flip sides accordingly based on logic above
1808+
// NOTE: bit 17 represents the boot seeprm (SEEPROM)
1809+
// bit 18 represents the measurement seeprom (MSEEPROM)
17871810
SBE_TRACF("switch_sbe_sides: HUID=0x%X Currently l_ctl_reg=0x%.8X",
17881811
TARGETING::get_huid(iv_proc), l_ctl_reg);
1789-
// Check if bit 17 or bit 18 currently set for Boot Side 1, mask set previously for which SEEPROM
1790-
if(l_ctl_reg & l_sbeOperationMask)
1812+
1813+
if (l_switch_boot_seeprom)
17911814
{
1792-
// Set Boot Side 0
1793-
SBE_TRACF( "switch_sbe_sides: iv_switchSidesCount=%d iv_switchSidesCount_mseeprom=%d: Flip to Set Boot Side 0 for HUID 0x%08X",
1794-
iv_switchSidesCount, iv_switchSidesCount_mseeprom,
1795-
TARGETING::get_huid(iv_proc));
1796-
l_ctl_reg &= ~l_sbeOperationMask; // clear bit 17 or bit 18 based on previously set mask for SEEPROM
1797-
l_mvpdSbKeyword.flags &= ~l_sbe_mvpd_reipl_mask; // clear MVPD SEEPROM flag bit
1798-
// We are reading the PROC register as the authoritative source at this point in time
1815+
if (l_ctl_reg & (SBE::SBE_BOOT_SELECT_MASK >> 32))
1816+
{
1817+
// bit17 already set, so clear it
1818+
// Set Boot Side 0
1819+
SBE_TRACF("switch_sbe_sides: iv_switchSidesCount=%d, Flip to Set Boot Seeprom Side 0 for HUID 0x%08X",
1820+
iv_switchSidesCount, TARGETING::get_huid(iv_proc));
1821+
l_ctl_reg &= ~(SBE::SBE_BOOT_SELECT_MASK >> 32); // clear bit 17
1822+
l_mvpdSbKeyword.flags &= ~REIPL_SEEPROM_MASK; // clear MVPD SEEPROM flag bit
1823+
}
1824+
else
1825+
{
1826+
// bit17 is not set, so set it
1827+
// Set Boot Side 1
1828+
SBE_TRACF("switch_sbe_sides: iv_switchSidesCount=%d, Flip to Set Boot Seeprom Side 1 for HUID 0x%08X",
1829+
iv_switchSidesCount, TARGETING::get_huid(iv_proc));
1830+
l_ctl_reg |= (SBE::SBE_BOOT_SELECT_MASK >> 32); // set bit 17
1831+
l_mvpdSbKeyword.flags |= REIPL_SEEPROM_MASK; // set MVPD SEEPROM flag bit
1832+
}
17991833
}
1800-
else // Opposite case for the mask previously set for SEEPROM
1834+
1835+
if (l_switch_measurement_seeprom)
18011836
{
1802-
// Set Boot Side 1
1803-
SBE_TRACF( "switch_sbe_sides: iv_switchSidesCount=%d iv_switchSidesCount_mseeprom=%d: Flip to Set Boot Side 1 for HUID 0x%08X",
1804-
iv_switchSidesCount, iv_switchSidesCount_mseeprom,
1805-
TARGETING::get_huid(iv_proc));
1806-
l_ctl_reg |= l_sbeOperationMask; // set bit 17 or bit 18 based on previously set mask for SEEPROM
1807-
l_mvpdSbKeyword.flags |= l_sbe_mvpd_reipl_mask; // set MVPD SEEPROM flag bit
1837+
if (l_ctl_reg & (SBE::SBE_MBOOT_SELECT_MASK >> 32))
1838+
{
1839+
// bit18 already set, so clear it
1840+
// Set Measurement Side 0
1841+
SBE_TRACF("switch_sbe_sides: iv_switchSidesCount_mseeprom=%d, Flip to Set Measurement Seeprom Side 0 for HUID 0x%08X",
1842+
iv_switchSidesCount_mseeprom, TARGETING::get_huid(iv_proc));
1843+
l_ctl_reg &= ~(SBE::SBE_MBOOT_SELECT_MASK >> 32); // clear bit 18
1844+
l_mvpdSbKeyword.flags &= ~REIPL_MSEEPROM_MASK; // clear MVPD MSEEPROM flag bit
1845+
}
1846+
else
1847+
{
1848+
// bit18 is not set, so set it
1849+
// Set Measurement Side 1
1850+
SBE_TRACF("switch_sbe_sides: iv_switchSidesCount_mseeprom=%d, Flip to Set Measurement Seeprom Side 1 for HUID 0x%08X",
1851+
iv_switchSidesCount_mseeprom, TARGETING::get_huid(iv_proc));
1852+
l_ctl_reg |= (SBE::SBE_MBOOT_SELECT_MASK >> 32); // set bit 18
1853+
l_mvpdSbKeyword.flags |= REIPL_MSEEPROM_MASK; // set MVPD MSEEPROM flag bit
1854+
}
18081855
}
18091856
SBE_TRACF("switch_sbe_sides: HUID=0x%X register to WRITE l_read_reg=0x%.8X MVPDOP_WRITE l_mvpdSbKeyword.flags=0x%X",
18101857
TARGETING::get_huid(iv_proc), l_ctl_reg, l_mvpdSbKeyword.flags);
@@ -1861,15 +1908,15 @@ errlHndl_t SbeRetryHandler::switch_sbe_sides(P10_EXTRACT_SBE_RC::RETURN_ACTION i
18611908
#endif
18621909

18631910
// Increment switch sides count
1864-
if (l_sbeOperationMask == SBE::SBE_BOOT_SELECT_MASK >> 32) // SEEPROM
1911+
if (l_switch_boot_seeprom) // SEEPROM
18651912
{
18661913
++(this->iv_switchSidesCount);
18671914
++(this->iv_switchSidesFlag);
18681915
// Since we just switched sides, and we havent attempted a boot yet,
18691916
// set the current attempts for this side to be 0
18701917
this->iv_currentSideBootAttempts = 0;
18711918
}
1872-
else if (l_sbeOperationMask == SBE::SBE_MBOOT_SELECT_MASK >> 32) // MSEEPROM
1919+
if (l_switch_measurement_seeprom) // MSEEPROM
18731920
{
18741921
++(this->iv_switchSidesCount_mseeprom);
18751922
++(this->iv_switchSidesFlag);
@@ -1878,9 +1925,9 @@ errlHndl_t SbeRetryHandler::switch_sbe_sides(P10_EXTRACT_SBE_RC::RETURN_ACTION i
18781925
this->iv_currentSideBootAttempts_mseeprom = 0;
18791926
}
18801927
SBE_TRACF("switch_sbe_sides: iv_switchSidesCount=%llx iv_switchSidesCount_mseeprom=%llx "
1881-
"iv_currentSideBootAttempts=%llx iv_currentSideBootAttempts_mseeprom=%llx iv_boot_restart_count=%d",
1882-
this->iv_switchSidesCount, this->iv_switchSidesCount_mseeprom,
1883-
this->iv_currentSideBootAttempts, this->iv_currentSideBootAttempts_mseeprom, this->iv_boot_restart_count);
1928+
"iv_currentSideBootAttempts=%llx iv_currentSideBootAttempts_mseeprom=%llx iv_boot_restart_count=%d",
1929+
this->iv_switchSidesCount, this->iv_switchSidesCount_mseeprom,
1930+
this->iv_currentSideBootAttempts, this->iv_currentSideBootAttempts_mseeprom, this->iv_boot_restart_count);
18841931
}while(0);
18851932

18861933
if (l_errl)

src/usr/sbeio/test/sbe_retry_handler_test.H

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,8 @@ class SbeRetryHandlerTest : public CxxTest::TestSuite
599599
* and test out
600600
*
601601
* This will not run fully without a slave SBE
602+
*
603+
* NOTE: This covers the case of recovery action REIPL_BKP_BMSEEPROM
602604
*/
603605
void testSBEFlowRESTART_SBE_FAILURE(void)
604606
{
@@ -650,11 +652,17 @@ class SbeRetryHandlerTest : public CxxTest::TestSuite
650652
// Most important values here are the SwitchSidesCount, CurrentSideCount and RestartCount
651653
// The flow would have switched sides on just the boot seeprom and
652654
// not the mseeprom and finally given up
653-
if ((l_sbeTestSwitchSidesCount != 1) || (l_sbeTestSwitchSidesCountMseeprom != 0) ||
654-
(l_sbeTestCurrentSideCount != 1) || (l_sbeTestCurrentSideCountMseeprom != 3) ||
655+
if ((l_sbeTestSwitchSidesCount != 1) || (l_sbeTestSwitchSidesCountMseeprom != 1) ||
656+
(l_sbeTestCurrentSideCount != 1) || (l_sbeTestCurrentSideCountMseeprom != 1) ||
655657
(l_sbeTestBootRestartCount != 2))
656658
{
657-
TS_FAIL("testSBEFlowRESTART_SBE_FAILURE failed to properly handle SBE Failures");
659+
TS_FAIL("testSBEFlowRESTART_SBE_FAILURE failed to properly handle SBE Failures: "
660+
"l_sbeTestSwitchSidesCount=%d, l_sbeTestSwitchSidesCountMseeprom=%d, "
661+
"l_sbeTestCurrentSideCount=%d, l_sbeTestCurrentSideCountMseeprom=%d, "
662+
"l_sbeTestBootRestartCount=%d",
663+
l_sbeTestSwitchSidesCount, l_sbeTestSwitchSidesCountMseeprom,
664+
l_sbeTestCurrentSideCount, l_sbeTestCurrentSideCountMseeprom,
665+
l_sbeTestBootRestartCount);
658666
}
659667
else
660668
{

0 commit comments

Comments
 (0)