15e5d4451SBrad Bishop extern "C" 25e5d4451SBrad Bishop { 3c98bab51SRamesh Iyyar #include <libpdbg.h> 4c98bab51SRamesh Iyyar } 5c98bab51SRamesh Iyyar 65e5d4451SBrad Bishop #include "attributes_info.H" 75e5d4451SBrad Bishop 8*6552de05SJayanth Othayoth #include "extensions/phal/phal_error.hpp" 9a257693aSChirag Sharma #include "procedures/phal/common_utils.hpp" 10e22e8231SJayanth Othayoth #include "util.hpp" 11b181d3bbSRamesh Iyyar 12e22e8231SJayanth Othayoth #include <fmt/format.h> 13c98bab51SRamesh Iyyar #include <libekb.H> 14b181d3bbSRamesh Iyyar 1575912e83SLakshminarayana R. Kammath #include <ext_interface.hpp> 16b181d3bbSRamesh Iyyar #include <phosphor-logging/log.hpp> 17b181d3bbSRamesh Iyyar #include <registration.hpp> 18e22e8231SJayanth Othayoth 19b181d3bbSRamesh Iyyar namespace openpower 20b181d3bbSRamesh Iyyar { 21b181d3bbSRamesh Iyyar namespace phal 22b181d3bbSRamesh Iyyar { 23b181d3bbSRamesh Iyyar 24b181d3bbSRamesh Iyyar using namespace phosphor::logging; 25b181d3bbSRamesh Iyyar 26b181d3bbSRamesh Iyyar /** 2775912e83SLakshminarayana R. Kammath * @brief Select BOOT SEEPROM and Measurement SEEPROM(PRIMARY/BACKUP) on POWER 2875912e83SLakshminarayana R. Kammath * processor position 0/1 depending on boot count before kicking off 2975912e83SLakshminarayana R. Kammath * the boot. 3075912e83SLakshminarayana R. Kammath * 3175912e83SLakshminarayana R. Kammath * @return void 3275912e83SLakshminarayana R. Kammath */ 3375912e83SLakshminarayana R. Kammath void selectBootSeeprom() 3475912e83SLakshminarayana R. Kammath { 3575912e83SLakshminarayana R. Kammath struct pdbg_target* procTarget; 3675912e83SLakshminarayana R. Kammath ATTR_BACKUP_SEEPROM_SELECT_Enum bkpSeePromSelect; 3775912e83SLakshminarayana R. Kammath ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_Enum bkpMeaSeePromSelect; 3875912e83SLakshminarayana R. Kammath 3975912e83SLakshminarayana R. Kammath pdbg_for_each_class_target("proc", procTarget) 4075912e83SLakshminarayana R. Kammath { 415c3f9258SAndrew Geissler if (!isPrimaryProc(procTarget)) 4275912e83SLakshminarayana R. Kammath { 4375912e83SLakshminarayana R. Kammath continue; 4475912e83SLakshminarayana R. Kammath } 4575912e83SLakshminarayana R. Kammath 4675912e83SLakshminarayana R. Kammath // Choose seeprom side to boot from based on boot count 4775912e83SLakshminarayana R. Kammath if (getBootCount() > 0) 4875912e83SLakshminarayana R. Kammath { 4975912e83SLakshminarayana R. Kammath log<level::INFO>("Setting SBE seeprom side to 0", 5075912e83SLakshminarayana R. Kammath entry("SBE_SIDE_SELECT=%d", 5175912e83SLakshminarayana R. Kammath ENUM_ATTR_BACKUP_SEEPROM_SELECT_PRIMARY)); 5275912e83SLakshminarayana R. Kammath 5375912e83SLakshminarayana R. Kammath bkpSeePromSelect = ENUM_ATTR_BACKUP_SEEPROM_SELECT_PRIMARY; 5475912e83SLakshminarayana R. Kammath bkpMeaSeePromSelect = 5575912e83SLakshminarayana R. Kammath ENUM_ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_PRIMARY; 5675912e83SLakshminarayana R. Kammath } 5775912e83SLakshminarayana R. Kammath else 5875912e83SLakshminarayana R. Kammath { 5975912e83SLakshminarayana R. Kammath log<level::INFO>("Setting SBE seeprom side to 1", 6075912e83SLakshminarayana R. Kammath entry("SBE_SIDE_SELECT=%d", 6175912e83SLakshminarayana R. Kammath ENUM_ATTR_BACKUP_SEEPROM_SELECT_SECONDARY)); 6275912e83SLakshminarayana R. Kammath bkpSeePromSelect = ENUM_ATTR_BACKUP_SEEPROM_SELECT_SECONDARY; 6375912e83SLakshminarayana R. Kammath bkpMeaSeePromSelect = 6475912e83SLakshminarayana R. Kammath ENUM_ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_SECONDARY; 6575912e83SLakshminarayana R. Kammath } 6675912e83SLakshminarayana R. Kammath 6775912e83SLakshminarayana R. Kammath // Set the Attribute as per bootcount policy for boot seeprom 6875912e83SLakshminarayana R. Kammath if (DT_SET_PROP(ATTR_BACKUP_SEEPROM_SELECT, procTarget, 6975912e83SLakshminarayana R. Kammath bkpSeePromSelect)) 7075912e83SLakshminarayana R. Kammath { 7175912e83SLakshminarayana R. Kammath log<level::ERR>( 7275912e83SLakshminarayana R. Kammath "Attribute [ATTR_BACKUP_SEEPROM_SELECT] set failed"); 7375912e83SLakshminarayana R. Kammath throw std::runtime_error( 7475912e83SLakshminarayana R. Kammath "Attribute [ATTR_BACKUP_SEEPROM_SELECT] set failed"); 7575912e83SLakshminarayana R. Kammath } 7675912e83SLakshminarayana R. Kammath 7775912e83SLakshminarayana R. Kammath // Set the Attribute as per bootcount policy for measurement seeprom 7875912e83SLakshminarayana R. Kammath if (DT_SET_PROP(ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT, procTarget, 7975912e83SLakshminarayana R. Kammath bkpMeaSeePromSelect)) 8075912e83SLakshminarayana R. Kammath { 8175912e83SLakshminarayana R. Kammath log<level::ERR>( 8275912e83SLakshminarayana R. Kammath "Attribute [ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT] set " 8375912e83SLakshminarayana R. Kammath "failed"); 8475912e83SLakshminarayana R. Kammath throw std::runtime_error( 8575912e83SLakshminarayana R. Kammath "Attribute [ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT] set " 8675912e83SLakshminarayana R. Kammath "failed"); 8775912e83SLakshminarayana R. Kammath } 8875912e83SLakshminarayana R. Kammath } 8975912e83SLakshminarayana R. Kammath } 9075912e83SLakshminarayana R. Kammath 9175912e83SLakshminarayana R. Kammath /** 92e22e8231SJayanth Othayoth * @brief Read the HW Level from VPD and set CLK NE termination site 93e22e8231SJayanth Othayoth * Note any failure in this function will result startHost failure. 94e22e8231SJayanth Othayoth */ 95e22e8231SJayanth Othayoth void setClkNETerminationSite() 96e22e8231SJayanth Othayoth { 97e22e8231SJayanth Othayoth // Get Motherborad VINI Recored "HW" keyword 98e22e8231SJayanth Othayoth constexpr auto objPath = 99e22e8231SJayanth Othayoth "/xyz/openbmc_project/inventory/system/chassis/motherboard"; 100e22e8231SJayanth Othayoth constexpr auto kwdVpdInf = "com.ibm.ipzvpd.VINI"; 101e22e8231SJayanth Othayoth constexpr auto hwKwd = "HW"; 102e22e8231SJayanth Othayoth 103e22e8231SJayanth Othayoth auto bus = sdbusplus::bus::new_default(); 104e22e8231SJayanth Othayoth 105e22e8231SJayanth Othayoth std::string service = util::getService(bus, objPath, kwdVpdInf); 106e22e8231SJayanth Othayoth 107e22e8231SJayanth Othayoth auto properties = bus.new_method_call( 108e22e8231SJayanth Othayoth service.c_str(), objPath, "org.freedesktop.DBus.Properties", "Get"); 109e22e8231SJayanth Othayoth properties.append(kwdVpdInf); 110e22e8231SJayanth Othayoth properties.append(hwKwd); 111e22e8231SJayanth Othayoth 112e22e8231SJayanth Othayoth // Store "HW" Keyword data. 113e22e8231SJayanth Othayoth std::variant<std::vector<uint8_t>> val; 114e22e8231SJayanth Othayoth try 115e22e8231SJayanth Othayoth { 116e22e8231SJayanth Othayoth auto result = bus.call(properties); 117e22e8231SJayanth Othayoth result.read(val); 118e22e8231SJayanth Othayoth } 119e22e8231SJayanth Othayoth catch (const sdbusplus::exception::SdBusError& e) 120e22e8231SJayanth Othayoth { 121e22e8231SJayanth Othayoth log<level::ERR>("Get HW Keyword read from VINI Failed"); 122e22e8231SJayanth Othayoth throw std::runtime_error("Get HW Keyword read from VINI Failed"); 123e22e8231SJayanth Othayoth } 124e22e8231SJayanth Othayoth 125e22e8231SJayanth Othayoth auto hwData = std::get<std::vector<uint8_t>>(val); 126e22e8231SJayanth Othayoth 127e22e8231SJayanth Othayoth //"HW" Keyword size is 2 as per VPD spec. 128e22e8231SJayanth Othayoth constexpr auto hwKwdSize = 2; 129e22e8231SJayanth Othayoth if (hwKwdSize != hwData.size()) 130e22e8231SJayanth Othayoth { 131e22e8231SJayanth Othayoth log<level::ERR>( 132e22e8231SJayanth Othayoth fmt::format("Incorrect VINI records HW Keyword data size({})", 133e22e8231SJayanth Othayoth hwData.size()) 134e22e8231SJayanth Othayoth .c_str()); 135e22e8231SJayanth Othayoth throw std::runtime_error("Incorrect VINI records HW Keyword data size"); 136e22e8231SJayanth Othayoth } 137e22e8231SJayanth Othayoth 138e22e8231SJayanth Othayoth log<level::DEBUG>(fmt::format("VINI Records HW[0]:{} HW[1]:{}", 139e22e8231SJayanth Othayoth hwData.at(0), hwData.at(1)) 140e22e8231SJayanth Othayoth .c_str()); 141e22e8231SJayanth Othayoth 142e22e8231SJayanth Othayoth // VINI Record "HW" keyword's Byte 0's MSB bit indicates 143e22e8231SJayanth Othayoth // proc or planar type need to choose. 144e22e8231SJayanth Othayoth constexpr uint8_t SYS_CLK_NE_TERMINATION_ON_MASK = 0x80; 145e22e8231SJayanth Othayoth 146e22e8231SJayanth Othayoth ATTR_SYS_CLK_NE_TERMINATION_SITE_Type clockTerm = 147e22e8231SJayanth Othayoth ENUM_ATTR_SYS_CLK_NE_TERMINATION_SITE_PLANAR; 148e22e8231SJayanth Othayoth 149e22e8231SJayanth Othayoth if (SYS_CLK_NE_TERMINATION_ON_MASK & hwData.at(0)) 150e22e8231SJayanth Othayoth { 151e22e8231SJayanth Othayoth clockTerm = ENUM_ATTR_SYS_CLK_NE_TERMINATION_SITE_PROC; 152e22e8231SJayanth Othayoth } 153e22e8231SJayanth Othayoth 154e22e8231SJayanth Othayoth // update all the processor attributes 155e22e8231SJayanth Othayoth struct pdbg_target* procTarget; 156e22e8231SJayanth Othayoth pdbg_for_each_class_target("proc", procTarget) 157e22e8231SJayanth Othayoth { 158e22e8231SJayanth Othayoth 159e22e8231SJayanth Othayoth if (DT_SET_PROP(ATTR_SYS_CLK_NE_TERMINATION_SITE, procTarget, 160e22e8231SJayanth Othayoth clockTerm)) 161e22e8231SJayanth Othayoth { 162e22e8231SJayanth Othayoth log<level::ERR>( 163e22e8231SJayanth Othayoth "Attribute ATTR_SYS_CLK_NE_TERMINATION_SITE set failed"); 164e22e8231SJayanth Othayoth throw std::runtime_error( 165e22e8231SJayanth Othayoth "Attribute ATTR_SYS_CLK_NE_TERMINATION_SITE set failed"); 166e22e8231SJayanth Othayoth } 167e22e8231SJayanth Othayoth } 168e22e8231SJayanth Othayoth } 169e22e8231SJayanth Othayoth 170e22e8231SJayanth Othayoth /** 171b181d3bbSRamesh Iyyar * @brief Starts the self boot engine on POWER processor position 0 172b181d3bbSRamesh Iyyar * to kick off a boot. 173b181d3bbSRamesh Iyyar * @return void 174b181d3bbSRamesh Iyyar */ 175c2e42763SDhruvaraj Subhashchandran void startHost(enum ipl_type iplType = IPL_TYPE_NORMAL) 176b181d3bbSRamesh Iyyar { 177a257693aSChirag Sharma try 178c98bab51SRamesh Iyyar { 179a257693aSChirag Sharma phal_init(); 180c2e42763SDhruvaraj Subhashchandran ipl_set_type(iplType); 181a257693aSChirag Sharma } 182a257693aSChirag Sharma catch (std::exception& ex) 183a257693aSChirag Sharma { 184a257693aSChirag Sharma log<level::ERR>("Exception raised during init PHAL", 185a257693aSChirag Sharma entry("EXCEPTION=%s", ex.what())); 186a257693aSChirag Sharma openpower::pel::detail::processBootErrorCallback(false); 187a257693aSChirag Sharma throw std::runtime_error("PHAL initialization failed"); 188a257693aSChirag Sharma } 189c2e42763SDhruvaraj Subhashchandran 190c98bab51SRamesh Iyyar // To clear trace if success 191c98bab51SRamesh Iyyar openpower::pel::detail::processBootErrorCallback(true); 192b181d3bbSRamesh Iyyar 193e22e8231SJayanth Othayoth setClkNETerminationSite(); 194e22e8231SJayanth Othayoth 19578479605SMarri Devender Rao // callback method will be called upon failure which will create the PEL 19678479605SMarri Devender Rao int rc = ipl_run_major(0); 19778479605SMarri Devender Rao if (rc > 0) 198b181d3bbSRamesh Iyyar { 199b181d3bbSRamesh Iyyar log<level::ERR>("step 0 failed to start the host"); 20078479605SMarri Devender Rao throw std::runtime_error("Failed to execute host start boot step"); 201b181d3bbSRamesh Iyyar } 202b181d3bbSRamesh Iyyar } 203b181d3bbSRamesh Iyyar 204c2e42763SDhruvaraj Subhashchandran /** 205c2e42763SDhruvaraj Subhashchandran * @brief Starts the reboot with type memory preserving reboot. 206c2e42763SDhruvaraj Subhashchandran * @return void 207c2e42763SDhruvaraj Subhashchandran */ 208c2e42763SDhruvaraj Subhashchandran void startHostMpReboot() 209c2e42763SDhruvaraj Subhashchandran { 210c2e42763SDhruvaraj Subhashchandran // set ipl type as mpipl 211c2e42763SDhruvaraj Subhashchandran startHost(IPL_TYPE_MPIPL); 212c2e42763SDhruvaraj Subhashchandran } 213c2e42763SDhruvaraj Subhashchandran 214c2e42763SDhruvaraj Subhashchandran /** 215c2e42763SDhruvaraj Subhashchandran * @brief Starts the normal boot type. 216c2e42763SDhruvaraj Subhashchandran * @return void 217c2e42763SDhruvaraj Subhashchandran */ 218c2e42763SDhruvaraj Subhashchandran void startHostNormal() 219c2e42763SDhruvaraj Subhashchandran { 2203ae7ed4fSDhruvaraj Subhashchandran // Run select seeprom before poweron 2213ae7ed4fSDhruvaraj Subhashchandran try 2223ae7ed4fSDhruvaraj Subhashchandran { 2233ae7ed4fSDhruvaraj Subhashchandran selectBootSeeprom(); 2243ae7ed4fSDhruvaraj Subhashchandran 2253ae7ed4fSDhruvaraj Subhashchandran // To clear trace as it is success 2263ae7ed4fSDhruvaraj Subhashchandran openpower::pel::detail::processBootErrorCallback(true); 2273ae7ed4fSDhruvaraj Subhashchandran } 2283ae7ed4fSDhruvaraj Subhashchandran catch (const std::exception& ex) 2293ae7ed4fSDhruvaraj Subhashchandran { 2303ae7ed4fSDhruvaraj Subhashchandran // create PEL in failure 2313ae7ed4fSDhruvaraj Subhashchandran openpower::pel::detail::processBootErrorCallback(false); 2323ae7ed4fSDhruvaraj Subhashchandran log<level::ERR>("SEEPROM selection failed", entry("ERR=%s", ex.what())); 2333ae7ed4fSDhruvaraj Subhashchandran throw ex; 2343ae7ed4fSDhruvaraj Subhashchandran } 2353ae7ed4fSDhruvaraj Subhashchandran 236c2e42763SDhruvaraj Subhashchandran startHost(); 237c2e42763SDhruvaraj Subhashchandran } 238c2e42763SDhruvaraj Subhashchandran 23963508a73SBrad Bishop REGISTER_PROCEDURE("startHost", startHostNormal) 24063508a73SBrad Bishop REGISTER_PROCEDURE("startHostMpReboot", startHostMpReboot) 241b181d3bbSRamesh Iyyar 242b181d3bbSRamesh Iyyar } // namespace phal 243b181d3bbSRamesh Iyyar } // namespace openpower 244