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 { 180*3ae7ed4fSDhruvaraj Subhashchandran // Run select seeprom before poweron 181*3ae7ed4fSDhruvaraj Subhashchandran try 182*3ae7ed4fSDhruvaraj Subhashchandran { 183*3ae7ed4fSDhruvaraj Subhashchandran selectBootSeeprom(); 184*3ae7ed4fSDhruvaraj Subhashchandran 185*3ae7ed4fSDhruvaraj Subhashchandran // To clear trace as it is success 186*3ae7ed4fSDhruvaraj Subhashchandran openpower::pel::detail::processBootErrorCallback(true); 187*3ae7ed4fSDhruvaraj Subhashchandran } 188*3ae7ed4fSDhruvaraj Subhashchandran catch (const std::exception& ex) 189*3ae7ed4fSDhruvaraj Subhashchandran { 190*3ae7ed4fSDhruvaraj Subhashchandran // create PEL in failure 191*3ae7ed4fSDhruvaraj Subhashchandran openpower::pel::detail::processBootErrorCallback(false); 192*3ae7ed4fSDhruvaraj Subhashchandran log<level::ERR>("SEEPROM selection failed", entry("ERR=%s", ex.what())); 193*3ae7ed4fSDhruvaraj Subhashchandran throw ex; 194*3ae7ed4fSDhruvaraj Subhashchandran } 195*3ae7ed4fSDhruvaraj Subhashchandran 196c2e42763SDhruvaraj Subhashchandran startHost(); 197c2e42763SDhruvaraj Subhashchandran } 198c2e42763SDhruvaraj Subhashchandran 199c2e42763SDhruvaraj Subhashchandran REGISTER_PROCEDURE("startHost", startHostNormal); 200c2e42763SDhruvaraj Subhashchandran REGISTER_PROCEDURE("startHostMpReboot", startHostMpReboot); 201b181d3bbSRamesh Iyyar 202b181d3bbSRamesh Iyyar } // namespace phal 203b181d3bbSRamesh Iyyar } // namespace openpower 204