1 extern "C" 2 { 3 #include <libpdbg.h> 4 } 5 6 #include "attributes_info.H" 7 8 #include "phalerror/phal_error.hpp" 9 #include "procedures/phal/common_utils.hpp" 10 11 #include <libekb.H> 12 13 #include <ext_interface.hpp> 14 #include <phosphor-logging/log.hpp> 15 #include <registration.hpp> 16 namespace openpower 17 { 18 namespace phal 19 { 20 21 using namespace phosphor::logging; 22 23 /** 24 * @brief Check if master processor or not 25 * 26 * @return True/False 27 */ 28 bool isMasterProc(struct pdbg_target* procTarget) 29 { 30 ATTR_PROC_MASTER_TYPE_Type type; 31 32 // Get processor type (Master or Alt-master) 33 if (DT_GET_PROP(ATTR_PROC_MASTER_TYPE, procTarget, type)) 34 { 35 log<level::ERR>("Attribute [ATTR_PROC_MASTER_TYPE] get failed"); 36 throw std::runtime_error( 37 "Attribute [ATTR_PROC_MASTER_TYPE] get failed"); 38 } 39 40 /* Attribute value 0 corresponds to master processor */ 41 if (type == 0) 42 { 43 return true; 44 } 45 else 46 { 47 return false; 48 } 49 } 50 51 /** 52 * @brief Select BOOT SEEPROM and Measurement SEEPROM(PRIMARY/BACKUP) on POWER 53 * processor position 0/1 depending on boot count before kicking off 54 * the boot. 55 * 56 * @return void 57 */ 58 void selectBootSeeprom() 59 { 60 struct pdbg_target* procTarget; 61 ATTR_BACKUP_SEEPROM_SELECT_Enum bkpSeePromSelect; 62 ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_Enum bkpMeaSeePromSelect; 63 64 pdbg_for_each_class_target("proc", procTarget) 65 { 66 if (!isMasterProc(procTarget)) 67 { 68 continue; 69 } 70 71 // Choose seeprom side to boot from based on boot count 72 if (getBootCount() > 0) 73 { 74 log<level::INFO>("Setting SBE seeprom side to 0", 75 entry("SBE_SIDE_SELECT=%d", 76 ENUM_ATTR_BACKUP_SEEPROM_SELECT_PRIMARY)); 77 78 bkpSeePromSelect = ENUM_ATTR_BACKUP_SEEPROM_SELECT_PRIMARY; 79 bkpMeaSeePromSelect = 80 ENUM_ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_PRIMARY; 81 } 82 else 83 { 84 log<level::INFO>("Setting SBE seeprom side to 1", 85 entry("SBE_SIDE_SELECT=%d", 86 ENUM_ATTR_BACKUP_SEEPROM_SELECT_SECONDARY)); 87 bkpSeePromSelect = ENUM_ATTR_BACKUP_SEEPROM_SELECT_SECONDARY; 88 bkpMeaSeePromSelect = 89 ENUM_ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_SECONDARY; 90 } 91 92 // Set the Attribute as per bootcount policy for boot seeprom 93 if (DT_SET_PROP(ATTR_BACKUP_SEEPROM_SELECT, procTarget, 94 bkpSeePromSelect)) 95 { 96 log<level::ERR>( 97 "Attribute [ATTR_BACKUP_SEEPROM_SELECT] set failed"); 98 throw std::runtime_error( 99 "Attribute [ATTR_BACKUP_SEEPROM_SELECT] set failed"); 100 } 101 102 // Set the Attribute as per bootcount policy for measurement seeprom 103 if (DT_SET_PROP(ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT, procTarget, 104 bkpMeaSeePromSelect)) 105 { 106 log<level::ERR>( 107 "Attribute [ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT] set " 108 "failed"); 109 throw std::runtime_error( 110 "Attribute [ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT] set " 111 "failed"); 112 } 113 } 114 } 115 116 /** 117 * @brief Starts the self boot engine on POWER processor position 0 118 * to kick off a boot. 119 * @return void 120 */ 121 void startHost(enum ipl_type iplType = IPL_TYPE_NORMAL) 122 { 123 try 124 { 125 phal_init(); 126 ipl_set_type(iplType); 127 } 128 catch (std::exception& ex) 129 { 130 log<level::ERR>("Exception raised during init PHAL", 131 entry("EXCEPTION=%s", ex.what())); 132 openpower::pel::detail::processBootErrorCallback(false); 133 throw std::runtime_error("PHAL initialization failed"); 134 } 135 136 // To clear trace if success 137 openpower::pel::detail::processBootErrorCallback(true); 138 139 // callback method will be called upon failure which will create the PEL 140 int rc = ipl_run_major(0); 141 if (rc > 0) 142 { 143 log<level::ERR>("step 0 failed to start the host"); 144 throw std::runtime_error("Failed to execute host start boot step"); 145 } 146 } 147 148 /** 149 * @brief Starts the reboot with type memory preserving reboot. 150 * @return void 151 */ 152 void startHostMpReboot() 153 { 154 // set ipl type as mpipl 155 startHost(IPL_TYPE_MPIPL); 156 } 157 158 /** 159 * @brief Starts the normal boot type. 160 * @return void 161 */ 162 void startHostNormal() 163 { 164 // Run select seeprom before poweron 165 try 166 { 167 selectBootSeeprom(); 168 169 // To clear trace as it is success 170 openpower::pel::detail::processBootErrorCallback(true); 171 } 172 catch (const std::exception& ex) 173 { 174 // create PEL in failure 175 openpower::pel::detail::processBootErrorCallback(false); 176 log<level::ERR>("SEEPROM selection failed", entry("ERR=%s", ex.what())); 177 throw ex; 178 } 179 180 startHost(); 181 } 182 183 REGISTER_PROCEDURE("startHost", startHostNormal) 184 REGISTER_PROCEDURE("startHostMpReboot", startHostMpReboot) 185 186 } // namespace phal 187 } // namespace openpower 188