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/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)