blob: db323cada29142ee75d233114b2fcb7f12bc3d8e [file] [log] [blame]
Brad Bishop5e5d4452020-10-27 19:46:13 -04001extern "C"
2{
Ramesh Iyyarc98bab52020-04-16 04:04:29 -05003#include <libpdbg.h>
4}
5
Brad Bishop5e5d4452020-10-27 19:46:13 -04006#include "attributes_info.H"
7
Jayanth Othayoth25e39c82021-07-12 01:00:17 -05008#include "extensions/phal/common_utils.hpp"
Jayanth Othayothad3ff0f2021-11-01 06:35:17 -05009#include "extensions/phal/create_pel.hpp"
Jayanth Othayoth6552de02021-07-12 00:55:57 -050010#include "extensions/phal/phal_error.hpp"
Jayanth Othayothe22e8232021-06-08 03:34:34 -050011#include "util.hpp"
Ramesh Iyyarb181d3b2019-10-17 13:39:10 -050012
Jayanth Othayothe22e8232021-06-08 03:34:34 -050013#include <fmt/format.h>
Ramesh Iyyarc98bab52020-04-16 04:04:29 -050014#include <libekb.H>
Ramesh Iyyarb181d3b2019-10-17 13:39:10 -050015
Lakshminarayana R. Kammath75912e82020-04-28 07:37:17 -050016#include <ext_interface.hpp>
Ramesh Iyyarb181d3b2019-10-17 13:39:10 -050017#include <phosphor-logging/log.hpp>
18#include <registration.hpp>
Jayanth Othayothe22e8232021-06-08 03:34:34 -050019
Ramesh Iyyarb181d3b2019-10-17 13:39:10 -050020namespace openpower
21{
22namespace phal
23{
24
25using namespace phosphor::logging;
Ramesh Iyyarb181d3b2019-10-17 13:39:10 -050026
27/**
Lakshminarayana R. Kammath75912e82020-04-28 07:37:17 -050028 * @brief Select BOOT SEEPROM and Measurement SEEPROM(PRIMARY/BACKUP) on POWER
29 * processor position 0/1 depending on boot count before kicking off
30 * the boot.
31 *
32 * @return void
33 */
34void selectBootSeeprom()
35{
36 struct pdbg_target* procTarget;
37 ATTR_BACKUP_SEEPROM_SELECT_Enum bkpSeePromSelect;
38 ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_Enum bkpMeaSeePromSelect;
39
40 pdbg_for_each_class_target("proc", procTarget)
41 {
Andrew Geissler5c3f9252021-06-10 10:53:05 -050042 if (!isPrimaryProc(procTarget))
Lakshminarayana R. Kammath75912e82020-04-28 07:37:17 -050043 {
44 continue;
45 }
46
47 // Choose seeprom side to boot from based on boot count
48 if (getBootCount() > 0)
49 {
50 log<level::INFO>("Setting SBE seeprom side to 0",
51 entry("SBE_SIDE_SELECT=%d",
52 ENUM_ATTR_BACKUP_SEEPROM_SELECT_PRIMARY));
53
54 bkpSeePromSelect = ENUM_ATTR_BACKUP_SEEPROM_SELECT_PRIMARY;
55 bkpMeaSeePromSelect =
56 ENUM_ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_PRIMARY;
57 }
58 else
59 {
60 log<level::INFO>("Setting SBE seeprom side to 1",
61 entry("SBE_SIDE_SELECT=%d",
62 ENUM_ATTR_BACKUP_SEEPROM_SELECT_SECONDARY));
63 bkpSeePromSelect = ENUM_ATTR_BACKUP_SEEPROM_SELECT_SECONDARY;
64 bkpMeaSeePromSelect =
65 ENUM_ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT_SECONDARY;
66 }
67
68 // Set the Attribute as per bootcount policy for boot seeprom
69 if (DT_SET_PROP(ATTR_BACKUP_SEEPROM_SELECT, procTarget,
70 bkpSeePromSelect))
71 {
72 log<level::ERR>(
73 "Attribute [ATTR_BACKUP_SEEPROM_SELECT] set failed");
74 throw std::runtime_error(
75 "Attribute [ATTR_BACKUP_SEEPROM_SELECT] set failed");
76 }
77
78 // Set the Attribute as per bootcount policy for measurement seeprom
79 if (DT_SET_PROP(ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT, procTarget,
80 bkpMeaSeePromSelect))
81 {
82 log<level::ERR>(
83 "Attribute [ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT] set "
84 "failed");
85 throw std::runtime_error(
86 "Attribute [ATTR_BACKUP_MEASUREMENT_SEEPROM_SELECT] set "
87 "failed");
88 }
89 }
90}
91
92/**
Jayanth Othayothe22e8232021-06-08 03:34:34 -050093 * @brief Read the HW Level from VPD and set CLK NE termination site
94 * Note any failure in this function will result startHost failure.
95 */
96void setClkNETerminationSite()
97{
98 // Get Motherborad VINI Recored "HW" keyword
99 constexpr auto objPath =
100 "/xyz/openbmc_project/inventory/system/chassis/motherboard";
101 constexpr auto kwdVpdInf = "com.ibm.ipzvpd.VINI";
102 constexpr auto hwKwd = "HW";
103
104 auto bus = sdbusplus::bus::new_default();
105
106 std::string service = util::getService(bus, objPath, kwdVpdInf);
107
108 auto properties = bus.new_method_call(
109 service.c_str(), objPath, "org.freedesktop.DBus.Properties", "Get");
110 properties.append(kwdVpdInf);
111 properties.append(hwKwd);
112
113 // Store "HW" Keyword data.
114 std::variant<std::vector<uint8_t>> val;
115 try
116 {
117 auto result = bus.call(properties);
118 result.read(val);
119 }
Patrick Williams2246cca2021-09-02 09:32:52 -0500120 catch (const sdbusplus::exception::exception& e)
Jayanth Othayothe22e8232021-06-08 03:34:34 -0500121 {
122 log<level::ERR>("Get HW Keyword read from VINI Failed");
123 throw std::runtime_error("Get HW Keyword read from VINI Failed");
124 }
125
126 auto hwData = std::get<std::vector<uint8_t>>(val);
127
128 //"HW" Keyword size is 2 as per VPD spec.
129 constexpr auto hwKwdSize = 2;
130 if (hwKwdSize != hwData.size())
131 {
132 log<level::ERR>(
133 fmt::format("Incorrect VINI records HW Keyword data size({})",
134 hwData.size())
135 .c_str());
136 throw std::runtime_error("Incorrect VINI records HW Keyword data size");
137 }
138
139 log<level::DEBUG>(fmt::format("VINI Records HW[0]:{} HW[1]:{}",
140 hwData.at(0), hwData.at(1))
141 .c_str());
142
143 // VINI Record "HW" keyword's Byte 0's MSB bit indicates
144 // proc or planar type need to choose.
145 constexpr uint8_t SYS_CLK_NE_TERMINATION_ON_MASK = 0x80;
146
147 ATTR_SYS_CLK_NE_TERMINATION_SITE_Type clockTerm =
148 ENUM_ATTR_SYS_CLK_NE_TERMINATION_SITE_PLANAR;
149
150 if (SYS_CLK_NE_TERMINATION_ON_MASK & hwData.at(0))
151 {
152 clockTerm = ENUM_ATTR_SYS_CLK_NE_TERMINATION_SITE_PROC;
153 }
154
155 // update all the processor attributes
156 struct pdbg_target* procTarget;
157 pdbg_for_each_class_target("proc", procTarget)
158 {
159
160 if (DT_SET_PROP(ATTR_SYS_CLK_NE_TERMINATION_SITE, procTarget,
161 clockTerm))
162 {
163 log<level::ERR>(
164 "Attribute ATTR_SYS_CLK_NE_TERMINATION_SITE set failed");
165 throw std::runtime_error(
166 "Attribute ATTR_SYS_CLK_NE_TERMINATION_SITE set failed");
167 }
168 }
169}
170
171/**
Ramesh Iyyarb181d3b2019-10-17 13:39:10 -0500172 * @brief Starts the self boot engine on POWER processor position 0
173 * to kick off a boot.
174 * @return void
175 */
Dhruvaraj Subhashchandranc2e42762020-06-17 00:30:12 -0500176void startHost(enum ipl_type iplType = IPL_TYPE_NORMAL)
Ramesh Iyyarb181d3b2019-10-17 13:39:10 -0500177{
Chirag Sharmaa2576932020-12-05 23:17:41 -0600178 try
Ramesh Iyyarc98bab52020-04-16 04:04:29 -0500179 {
Chirag Sharmaa2576932020-12-05 23:17:41 -0600180 phal_init();
181 ipl_set_type(iplType);
Jayanth Othayothad3ff0f2021-11-01 06:35:17 -0500182 if (iplType == IPL_TYPE_NORMAL)
183 {
184 // Update SEEPROM side only for NORMAL boot
185 selectBootSeeprom();
186 }
187 setClkNETerminationSite();
Ramesh Iyyarc98bab52020-04-16 04:04:29 -0500188 }
Patrick Williams1a9a5a62021-10-06 13:05:06 -0500189 catch (const std::exception& ex)
Ramesh Iyyarc98bab52020-04-16 04:04:29 -0500190 {
Jayanth Othayothad3ff0f2021-11-01 06:35:17 -0500191 log<level::ERR>("Exception raised during ipl initialisation",
Chirag Sharmaa2576932020-12-05 23:17:41 -0600192 entry("EXCEPTION=%s", ex.what()));
Jayanth Othayothad3ff0f2021-11-01 06:35:17 -0500193 openpower::pel::createPEL("org.open_power.PHAL.Error.Boot");
Jayanth Othayoth2b211702021-09-06 05:14:23 -0500194 openpower::pel::detail::processBootError(false);
Jayanth Othayothad3ff0f2021-11-01 06:35:17 -0500195 throw std::runtime_error("IPL initialization failed");
Ramesh Iyyarc98bab52020-04-16 04:04:29 -0500196 }
Dhruvaraj Subhashchandranc2e42762020-06-17 00:30:12 -0500197
Ramesh Iyyarc98bab52020-04-16 04:04:29 -0500198 // To clear trace if success
Jayanth Othayoth2b211702021-09-06 05:14:23 -0500199 openpower::pel::detail::processBootError(true);
Ramesh Iyyarb181d3b2019-10-17 13:39:10 -0500200
Marri Devender Rao78479602020-01-06 03:45:11 -0600201 // callback method will be called upon failure which will create the PEL
202 int rc = ipl_run_major(0);
203 if (rc > 0)
Ramesh Iyyarb181d3b2019-10-17 13:39:10 -0500204 {
205 log<level::ERR>("step 0 failed to start the host");
Marri Devender Rao78479602020-01-06 03:45:11 -0600206 throw std::runtime_error("Failed to execute host start boot step");
Ramesh Iyyarb181d3b2019-10-17 13:39:10 -0500207 }
208}
209
Dhruvaraj Subhashchandranc2e42762020-06-17 00:30:12 -0500210/**
211 * @brief Starts the reboot with type memory preserving reboot.
212 * @return void
213 */
214void startHostMpReboot()
215{
216 // set ipl type as mpipl
217 startHost(IPL_TYPE_MPIPL);
218}
219
220/**
221 * @brief Starts the normal boot type.
222 * @return void
223 */
224void startHostNormal()
225{
Jayanth Othayothad3ff0f2021-11-01 06:35:17 -0500226 startHost(IPL_TYPE_NORMAL);
Dhruvaraj Subhashchandranc2e42762020-06-17 00:30:12 -0500227}
228
Brad Bishop63508a72020-10-27 18:55:01 -0400229REGISTER_PROCEDURE("startHost", startHostNormal)
230REGISTER_PROCEDURE("startHostMpReboot", startHostMpReboot)
Ramesh Iyyarb181d3b2019-10-17 13:39:10 -0500231
232} // namespace phal
233} // namespace openpower