Select primary/secondary BOOT/MEASUREMENT SEEPROM based on boot count
Changes include:
1) selection of primary/secondary seeprom before booting host
2) structure name change from PACKED to PACK to avoid conflict with
attributes_info.H
Tests done :
- Verified the right bit set for Primary Vs Secondary Boot path
- Verified attribute GET/SET working good
Signed-off-by: Lakshminarayana R. Kammath <lkammath@in.ibm.com>
Change-Id: I3017b0e9118119cc0a5e478f262641ce539ac4ff
diff --git a/configure.ac b/configure.ac
index fecae53..971be69 100644
--- a/configure.ac
+++ b/configure.ac
@@ -73,6 +73,10 @@
AC_MSG_ERROR([EKB library not found])
fi
+ PKG_CHECK_MODULES([LIBDT_API], [libdt-api])
+ LIBS="$LIBS $LIBDT_API_LIBS"
+ CFLAGS="$CFLAGS $LIBDT_API_CFLAGS"
+
CHIPS+=" phal common"
AC_CONFIG_FILES([set-spi-mux.service])
]
diff --git a/procedures/common/collect_sbe_hb_data.cpp b/procedures/common/collect_sbe_hb_data.cpp
index b29d194..6cba8ee 100644
--- a/procedures/common/collect_sbe_hb_data.cpp
+++ b/procedures/common/collect_sbe_hb_data.cpp
@@ -52,7 +52,7 @@
uint32_t minorStep : 6;
uint32_t reserved2 : 6;
#endif
- } PACKED;
+ } PACK;
};
// HB mailbox scratch register 5 - cfam 283C
@@ -78,7 +78,7 @@
uint32_t majorStep : 8; // 16:23
uint32_t minorStep : 8; // 24:31
#endif
- } PACKED;
+ } PACK;
};
static constexpr uint8_t HB_MBX5_VALID_FLAG = 0xAA;
@@ -105,8 +105,8 @@
auto msg = reinterpret_cast<const sbeMsgReg_t*>(&readData);
log<level::INFO>("SBE status register",
entry("PROC=%d", proc->getPos()),
- entry("SBE_MAJOR_ISTEP=%d", msg->PACKED.majorStep),
- entry("SBE_MINOR_ISTEP=%d", msg->PACKED.minorStep),
+ entry("SBE_MAJOR_ISTEP=%d", msg->PACK.majorStep),
+ entry("SBE_MINOR_ISTEP=%d", msg->PACK.minorStep),
entry("REG_VAL=0x%08X", msg->data32));
}
catch (const std::exception& e)
@@ -122,11 +122,11 @@
{
auto readData = readReg(master, P9_HB_MBX5_REG);
auto msg = reinterpret_cast<const MboxScratch5_HB_t*>(&readData);
- if (HB_MBX5_VALID_FLAG == msg->PACKED.magic)
+ if (HB_MBX5_VALID_FLAG == msg->PACK.magic)
{
log<level::INFO>("HB MBOX 5 register",
- entry("HB_MAJOR_ISTEP=%d", msg->PACKED.majorStep),
- entry("HB_MINOR_ISTEP=%d", msg->PACKED.minorStep),
+ entry("HB_MAJOR_ISTEP=%d", msg->PACK.majorStep),
+ entry("HB_MINOR_ISTEP=%d", msg->PACK.minorStep),
entry("REG_VAL=0x%08X", msg->data32));
}
}
diff --git a/procedures/phal/start_host.cpp b/procedures/phal/start_host.cpp
index 3899924..39229f4 100644
--- a/procedures/phal/start_host.cpp
+++ b/procedures/phal/start_host.cpp
@@ -7,8 +7,11 @@
#include <libekb.H>
#include <libipl.H>
+#include <ext_interface.hpp>
#include <phosphor-logging/log.hpp>
#include <registration.hpp>
+
+#include "attributes_info.H"
namespace openpower
{
namespace phal
@@ -17,6 +20,99 @@
using namespace phosphor::logging;
/**
+ * @brief Check if master processor or not
+ *
+ * @return True/False
+ */
+bool isMasterProc(struct pdbg_target* procTarget)
+{
+ ATTR_PROC_MASTER_TYPE_Type type;
+
+ // Get processor type (Master or Alt-master)
+ if (DT_GET_PROP(ATTR_PROC_MASTER_TYPE, procTarget, type))
+ {
+ log<level::ERR>("Attribute [ATTR_PROC_MASTER_TYPE] get failed");
+ throw std::runtime_error(
+ "Attribute [ATTR_PROC_MASTER_TYPE] get failed");
+ }
+
+ /* Attribute value 0 corresponds to master processor */
+ if (type == 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+/**
+ * @brief Select BOOT SEEPROM and Measurement SEEPROM(PRIMARY/BACKUP) on POWER
+ * processor position 0/1 depending on boot count before kicking off
+ * the boot.
+ *
+ * @return void
+ */
+void selectBootSeeprom()
+{
+ struct pdbg_target* procTarget;
+ ATTR_BACKUP_SEEPROM_SELECT_Enum bkpSeePromSelect;
+ ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_Enum bkpMeaSeePromSelect;
+
+ pdbg_for_each_class_target("proc", procTarget)
+ {
+ if (!isMasterProc(procTarget))
+ {
+ continue;
+ }
+
+ // Choose seeprom side to boot from based on boot count
+ if (getBootCount() > 0)
+ {
+ log<level::INFO>("Setting SBE seeprom side to 0",
+ entry("SBE_SIDE_SELECT=%d",
+ ENUM_ATTR_BACKUP_SEEPROM_SELECT_PRIMARY));
+
+ bkpSeePromSelect = ENUM_ATTR_BACKUP_SEEPROM_SELECT_PRIMARY;
+ bkpMeaSeePromSelect =
+ ENUM_ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_PRIMARY;
+ }
+ else
+ {
+ log<level::INFO>("Setting SBE seeprom side to 1",
+ entry("SBE_SIDE_SELECT=%d",
+ ENUM_ATTR_BACKUP_SEEPROM_SELECT_SECONDARY));
+ bkpSeePromSelect = ENUM_ATTR_BACKUP_SEEPROM_SELECT_SECONDARY;
+ bkpMeaSeePromSelect =
+ ENUM_ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_SECONDARY;
+ }
+
+ // Set the Attribute as per bootcount policy for boot seeprom
+ if (DT_SET_PROP(ATTR_BACKUP_SEEPROM_SELECT, procTarget,
+ bkpSeePromSelect))
+ {
+ log<level::ERR>(
+ "Attribute [ATTR_BACKUP_SEEPROM_SELECT] set failed");
+ throw std::runtime_error(
+ "Attribute [ATTR_BACKUP_SEEPROM_SELECT] set failed");
+ }
+
+ // Set the Attribute as per bootcount policy for measurement seeprom
+ if (DT_SET_PROP(ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT, procTarget,
+ bkpMeaSeePromSelect))
+ {
+ log<level::ERR>(
+ "Attribute [ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT] set "
+ "failed");
+ throw std::runtime_error(
+ "Attribute [ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT] set "
+ "failed");
+ }
+ }
+}
+
+/**
* @brief Starts the self boot engine on POWER processor position 0
* to kick off a boot.
* @return void
@@ -53,6 +149,22 @@
// To clear trace if success
openpower::pel::detail::processBootErrorCallback(true);
+ // Run select seeprom before poweron
+ try
+ {
+ selectBootSeeprom();
+
+ // To clear trace as it is success
+ openpower::pel::detail::processBootErrorCallback(true);
+ }
+ catch (const std::exception& ex)
+ {
+ // create PEL in failure
+ openpower::pel::detail::processBootErrorCallback(false);
+ log<level::ERR>("SEEPROM selection failed", entry("ERR=%s", ex.what()));
+ throw ex;
+ }
+
// callback method will be called upon failure which will create the PEL
int rc = ipl_run_major(0);
if (rc > 0)