1c98bab51SRamesh Iyyar extern "C" {
2c98bab51SRamesh Iyyar #include <libpdbg.h>
3c98bab51SRamesh Iyyar }
4c98bab51SRamesh Iyyar 
578479605SMarri Devender Rao #include "phalerror/phal_error.hpp"
6b181d3bbSRamesh Iyyar 
7c98bab51SRamesh Iyyar #include <libekb.H>
878479605SMarri Devender Rao #include <libipl.H>
9b181d3bbSRamesh Iyyar 
1075912e83SLakshminarayana R. Kammath #include <ext_interface.hpp>
11b181d3bbSRamesh Iyyar #include <phosphor-logging/log.hpp>
12b181d3bbSRamesh Iyyar #include <registration.hpp>
1375912e83SLakshminarayana R. Kammath 
1475912e83SLakshminarayana R. Kammath #include "attributes_info.H"
15b181d3bbSRamesh Iyyar namespace openpower
16b181d3bbSRamesh Iyyar {
17b181d3bbSRamesh Iyyar namespace phal
18b181d3bbSRamesh Iyyar {
19b181d3bbSRamesh Iyyar 
20b181d3bbSRamesh Iyyar using namespace phosphor::logging;
21b181d3bbSRamesh Iyyar 
22b181d3bbSRamesh Iyyar /**
2375912e83SLakshminarayana R. Kammath  *  @brief  Check if master processor or not
2475912e83SLakshminarayana R. Kammath  *
2575912e83SLakshminarayana R. Kammath  *  @return True/False
2675912e83SLakshminarayana R. Kammath  */
2775912e83SLakshminarayana R. Kammath bool isMasterProc(struct pdbg_target* procTarget)
2875912e83SLakshminarayana R. Kammath {
2975912e83SLakshminarayana R. Kammath     ATTR_PROC_MASTER_TYPE_Type type;
3075912e83SLakshminarayana R. Kammath 
3175912e83SLakshminarayana R. Kammath     // Get processor type (Master or Alt-master)
3275912e83SLakshminarayana R. Kammath     if (DT_GET_PROP(ATTR_PROC_MASTER_TYPE, procTarget, type))
3375912e83SLakshminarayana R. Kammath     {
3475912e83SLakshminarayana R. Kammath         log<level::ERR>("Attribute [ATTR_PROC_MASTER_TYPE] get failed");
3575912e83SLakshminarayana R. Kammath         throw std::runtime_error(
3675912e83SLakshminarayana R. Kammath             "Attribute [ATTR_PROC_MASTER_TYPE] get failed");
3775912e83SLakshminarayana R. Kammath     }
3875912e83SLakshminarayana R. Kammath 
3975912e83SLakshminarayana R. Kammath     /* Attribute value 0 corresponds to master processor */
4075912e83SLakshminarayana R. Kammath     if (type == 0)
4175912e83SLakshminarayana R. Kammath     {
4275912e83SLakshminarayana R. Kammath         return true;
4375912e83SLakshminarayana R. Kammath     }
4475912e83SLakshminarayana R. Kammath     else
4575912e83SLakshminarayana R. Kammath     {
4675912e83SLakshminarayana R. Kammath         return false;
4775912e83SLakshminarayana R. Kammath     }
4875912e83SLakshminarayana R. Kammath }
4975912e83SLakshminarayana R. Kammath 
5075912e83SLakshminarayana R. Kammath /**
5175912e83SLakshminarayana R. Kammath  *  @brief  Select BOOT SEEPROM and Measurement SEEPROM(PRIMARY/BACKUP) on POWER
5275912e83SLakshminarayana R. Kammath  *          processor position 0/1 depending on boot count before kicking off
5375912e83SLakshminarayana R. Kammath  *          the boot.
5475912e83SLakshminarayana R. Kammath  *
5575912e83SLakshminarayana R. Kammath  *  @return void
5675912e83SLakshminarayana R. Kammath  */
5775912e83SLakshminarayana R. Kammath void selectBootSeeprom()
5875912e83SLakshminarayana R. Kammath {
5975912e83SLakshminarayana R. Kammath     struct pdbg_target* procTarget;
6075912e83SLakshminarayana R. Kammath     ATTR_BACKUP_SEEPROM_SELECT_Enum bkpSeePromSelect;
6175912e83SLakshminarayana R. Kammath     ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_Enum bkpMeaSeePromSelect;
6275912e83SLakshminarayana R. Kammath 
6375912e83SLakshminarayana R. Kammath     pdbg_for_each_class_target("proc", procTarget)
6475912e83SLakshminarayana R. Kammath     {
6575912e83SLakshminarayana R. Kammath         if (!isMasterProc(procTarget))
6675912e83SLakshminarayana R. Kammath         {
6775912e83SLakshminarayana R. Kammath             continue;
6875912e83SLakshminarayana R. Kammath         }
6975912e83SLakshminarayana R. Kammath 
7075912e83SLakshminarayana R. Kammath         // Choose seeprom side to boot from based on boot count
7175912e83SLakshminarayana R. Kammath         if (getBootCount() > 0)
7275912e83SLakshminarayana R. Kammath         {
7375912e83SLakshminarayana R. Kammath             log<level::INFO>("Setting SBE seeprom side to 0",
7475912e83SLakshminarayana R. Kammath                              entry("SBE_SIDE_SELECT=%d",
7575912e83SLakshminarayana R. Kammath                                    ENUM_ATTR_BACKUP_SEEPROM_SELECT_PRIMARY));
7675912e83SLakshminarayana R. Kammath 
7775912e83SLakshminarayana R. Kammath             bkpSeePromSelect = ENUM_ATTR_BACKUP_SEEPROM_SELECT_PRIMARY;
7875912e83SLakshminarayana R. Kammath             bkpMeaSeePromSelect =
7975912e83SLakshminarayana R. Kammath                 ENUM_ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_PRIMARY;
8075912e83SLakshminarayana R. Kammath         }
8175912e83SLakshminarayana R. Kammath         else
8275912e83SLakshminarayana R. Kammath         {
8375912e83SLakshminarayana R. Kammath             log<level::INFO>("Setting SBE seeprom side to 1",
8475912e83SLakshminarayana R. Kammath                              entry("SBE_SIDE_SELECT=%d",
8575912e83SLakshminarayana R. Kammath                                    ENUM_ATTR_BACKUP_SEEPROM_SELECT_SECONDARY));
8675912e83SLakshminarayana R. Kammath             bkpSeePromSelect = ENUM_ATTR_BACKUP_SEEPROM_SELECT_SECONDARY;
8775912e83SLakshminarayana R. Kammath             bkpMeaSeePromSelect =
8875912e83SLakshminarayana R. Kammath                 ENUM_ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_SECONDARY;
8975912e83SLakshminarayana R. Kammath         }
9075912e83SLakshminarayana R. Kammath 
9175912e83SLakshminarayana R. Kammath         // Set the Attribute as per bootcount policy for boot seeprom
9275912e83SLakshminarayana R. Kammath         if (DT_SET_PROP(ATTR_BACKUP_SEEPROM_SELECT, procTarget,
9375912e83SLakshminarayana R. Kammath                         bkpSeePromSelect))
9475912e83SLakshminarayana R. Kammath         {
9575912e83SLakshminarayana R. Kammath             log<level::ERR>(
9675912e83SLakshminarayana R. Kammath                 "Attribute [ATTR_BACKUP_SEEPROM_SELECT] set failed");
9775912e83SLakshminarayana R. Kammath             throw std::runtime_error(
9875912e83SLakshminarayana R. Kammath                 "Attribute [ATTR_BACKUP_SEEPROM_SELECT] set failed");
9975912e83SLakshminarayana R. Kammath         }
10075912e83SLakshminarayana R. Kammath 
10175912e83SLakshminarayana R. Kammath         // Set the Attribute as per bootcount policy for measurement seeprom
10275912e83SLakshminarayana R. Kammath         if (DT_SET_PROP(ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT, procTarget,
10375912e83SLakshminarayana R. Kammath                         bkpMeaSeePromSelect))
10475912e83SLakshminarayana R. Kammath         {
10575912e83SLakshminarayana R. Kammath             log<level::ERR>(
10675912e83SLakshminarayana R. Kammath                 "Attribute [ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT] set "
10775912e83SLakshminarayana R. Kammath                 "failed");
10875912e83SLakshminarayana R. Kammath             throw std::runtime_error(
10975912e83SLakshminarayana R. Kammath                 "Attribute [ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT] set "
11075912e83SLakshminarayana R. Kammath                 "failed");
11175912e83SLakshminarayana R. Kammath         }
11275912e83SLakshminarayana R. Kammath     }
11375912e83SLakshminarayana R. Kammath }
11475912e83SLakshminarayana R. Kammath 
11575912e83SLakshminarayana R. Kammath /**
116b181d3bbSRamesh Iyyar  * @brief Starts the self boot engine on POWER processor position 0
117b181d3bbSRamesh Iyyar  *        to kick off a boot.
118b181d3bbSRamesh Iyyar  * @return void
119b181d3bbSRamesh Iyyar  */
120c2e42763SDhruvaraj Subhashchandran void startHost(enum ipl_type iplType = IPL_TYPE_NORMAL)
121b181d3bbSRamesh Iyyar {
12278479605SMarri Devender Rao     // add callback methods for debug traces and for boot failures
12378479605SMarri Devender Rao     openpower::pel::addBootErrorCallbacks();
12478479605SMarri Devender Rao 
125c98bab51SRamesh Iyyar     if (!pdbg_targets_init(NULL))
126c98bab51SRamesh Iyyar     {
127c98bab51SRamesh Iyyar         log<level::ERR>("pdbg_targets_init failed");
128c98bab51SRamesh Iyyar         openpower::pel::detail::processBootErrorCallback(false);
129c98bab51SRamesh Iyyar         throw std::runtime_error("pdbg target initialization failed");
130c98bab51SRamesh Iyyar     }
131c98bab51SRamesh Iyyar     // To clear trace if success
132c98bab51SRamesh Iyyar     openpower::pel::detail::processBootErrorCallback(true);
133c98bab51SRamesh Iyyar 
134c98bab51SRamesh Iyyar     if (libekb_init())
135c98bab51SRamesh Iyyar     {
136c98bab51SRamesh Iyyar         log<level::ERR>("libekb_init failed");
137c98bab51SRamesh Iyyar         openpower::pel::detail::processBootErrorCallback(false);
138c98bab51SRamesh Iyyar         throw std::runtime_error("libekb initialization failed");
139c98bab51SRamesh Iyyar     }
140c98bab51SRamesh Iyyar     // To clear trace if success
141c98bab51SRamesh Iyyar     openpower::pel::detail::processBootErrorCallback(true);
142c98bab51SRamesh Iyyar 
143c98bab51SRamesh Iyyar     if (ipl_init(IPL_AUTOBOOT) != 0)
144b181d3bbSRamesh Iyyar     {
145b181d3bbSRamesh Iyyar         log<level::ERR>("ipl_init failed");
146c98bab51SRamesh Iyyar         openpower::pel::detail::processBootErrorCallback(false);
14778479605SMarri Devender Rao         throw std::runtime_error("Boot initialization failed");
148b181d3bbSRamesh Iyyar     }
149c2e42763SDhruvaraj Subhashchandran 
150c2e42763SDhruvaraj Subhashchandran     ipl_set_type(iplType);
151c2e42763SDhruvaraj Subhashchandran 
152c98bab51SRamesh Iyyar     // To clear trace if success
153c98bab51SRamesh Iyyar     openpower::pel::detail::processBootErrorCallback(true);
154b181d3bbSRamesh Iyyar 
15578479605SMarri Devender Rao     // callback method will be called upon failure which will create the PEL
15678479605SMarri Devender Rao     int rc = ipl_run_major(0);
15778479605SMarri Devender Rao     if (rc > 0)
158b181d3bbSRamesh Iyyar     {
159b181d3bbSRamesh Iyyar         log<level::ERR>("step 0 failed to start the host");
16078479605SMarri Devender Rao         throw std::runtime_error("Failed to execute host start boot step");
161b181d3bbSRamesh Iyyar     }
162b181d3bbSRamesh Iyyar }
163b181d3bbSRamesh Iyyar 
164c2e42763SDhruvaraj Subhashchandran /**
165c2e42763SDhruvaraj Subhashchandran  * @brief Starts the reboot with type memory preserving reboot.
166c2e42763SDhruvaraj Subhashchandran  * @return void
167c2e42763SDhruvaraj Subhashchandran  */
168c2e42763SDhruvaraj Subhashchandran void startHostMpReboot()
169c2e42763SDhruvaraj Subhashchandran {
170c2e42763SDhruvaraj Subhashchandran     // set ipl type as mpipl
171c2e42763SDhruvaraj Subhashchandran     startHost(IPL_TYPE_MPIPL);
172c2e42763SDhruvaraj Subhashchandran }
173c2e42763SDhruvaraj Subhashchandran 
174c2e42763SDhruvaraj Subhashchandran /**
175c2e42763SDhruvaraj Subhashchandran  * @brief Starts the normal boot type.
176c2e42763SDhruvaraj Subhashchandran  * @return void
177c2e42763SDhruvaraj Subhashchandran  */
178c2e42763SDhruvaraj Subhashchandran void startHostNormal()
179c2e42763SDhruvaraj Subhashchandran {
1803ae7ed4fSDhruvaraj Subhashchandran     // Run select seeprom before poweron
1813ae7ed4fSDhruvaraj Subhashchandran     try
1823ae7ed4fSDhruvaraj Subhashchandran     {
1833ae7ed4fSDhruvaraj Subhashchandran         selectBootSeeprom();
1843ae7ed4fSDhruvaraj Subhashchandran 
1853ae7ed4fSDhruvaraj Subhashchandran         // To clear trace as it is success
1863ae7ed4fSDhruvaraj Subhashchandran         openpower::pel::detail::processBootErrorCallback(true);
1873ae7ed4fSDhruvaraj Subhashchandran     }
1883ae7ed4fSDhruvaraj Subhashchandran     catch (const std::exception& ex)
1893ae7ed4fSDhruvaraj Subhashchandran     {
1903ae7ed4fSDhruvaraj Subhashchandran         // create PEL in failure
1913ae7ed4fSDhruvaraj Subhashchandran         openpower::pel::detail::processBootErrorCallback(false);
1923ae7ed4fSDhruvaraj Subhashchandran         log<level::ERR>("SEEPROM selection failed", entry("ERR=%s", ex.what()));
1933ae7ed4fSDhruvaraj Subhashchandran         throw ex;
1943ae7ed4fSDhruvaraj Subhashchandran     }
1953ae7ed4fSDhruvaraj Subhashchandran 
196c2e42763SDhruvaraj Subhashchandran     startHost();
197c2e42763SDhruvaraj Subhashchandran }
198c2e42763SDhruvaraj Subhashchandran 
199*63508a73SBrad Bishop REGISTER_PROCEDURE("startHost", startHostNormal)
200*63508a73SBrad Bishop REGISTER_PROCEDURE("startHostMpReboot", startHostMpReboot)
201b181d3bbSRamesh Iyyar 
202b181d3bbSRamesh Iyyar } // namespace phal
203b181d3bbSRamesh Iyyar } // namespace openpower
204