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