blob: c07893d52591af7028d4bff540f7297a6bffa3b8 [file] [log] [blame]
Jayanth Othayothda9b5832021-11-05 04:19:43 -05001#include "phal_service_actions.hpp"
2
3#include <attributes_info.H>
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -06004#include <libphal.H>
Jayanth Othayothda9b5832021-11-05 04:19:43 -05005
6#include <phosphor-logging/log.hpp>
7
Jayanth Othayoth1aa90d42023-09-13 04:25:45 -05008#include <format>
9
Jayanth Othayothda9b5832021-11-05 04:19:43 -050010namespace openpower
11{
12namespace pels
13{
14namespace phal
15{
16using namespace phosphor::logging;
17
18/**
19 * @brief Helper function to get EntrySeverity based on
20 * the given GardType
21 *
22 * @param[in] guardType openpower gard type
23 *
24 * @return EntrySeverity on success
25 * Empty optional on failure
26 */
27std::optional<EntrySeverity> getEntrySeverityType(const std::string& guardType)
28{
29 if ((guardType == "GARD_Unrecoverable") || (guardType == "GARD_Fatal"))
30 {
31 return EntrySeverity::Critical;
32 }
33 else if (guardType == "GARD_User_Manual")
34 {
35 return EntrySeverity::Manual;
36 }
37 else if (guardType == "GARD_Predictive")
38 {
39 return EntrySeverity::Warning;
40 }
41 else
42 {
43 log<level::ERR>(
Jayanth Othayoth1aa90d42023-09-13 04:25:45 -050044 std::format("GUARD: Unsupported GardType [{}] was given ",
Jayanth Othayothda9b5832021-11-05 04:19:43 -050045 "to get the hardware isolation entry severity type",
46 guardType.c_str())
47 .c_str());
48 }
49 return std::nullopt;
50}
51
52/**
53 * @brief Helper function to create guard records.
54 *
55 * User need to fill the JSON callouts array with below keywords/data
56 * "Entitypath": entity path of the hardware from the PHAL device tree.
57 * "Guardtype": The hardware isolation severity which is defined in
58 * xyz.openbmc_project.HardwareIsolation.Entry
59 * "Guarded": boolean, true to create gurad records.
60 *
61 * @param[in] jsonCallouts - The array of JSON callouts, or an empty object.
62 * @param[in] path - The BMC error log object path
63 * @param[in] dataIface - The DataInterface object
64 */
65void createGuardRecords(const nlohmann::json& jsonCallouts,
66 const std::string& path,
67 const DataInterfaceBase& dataIface)
68{
69 if (jsonCallouts.empty())
70 {
71 return;
72 }
73
74 if (!jsonCallouts.is_array())
75 {
76 log<level::ERR>("GUARD: Callout JSON isn't an array");
77 return;
78 }
79 for (const auto& _callout : jsonCallouts)
80 {
81 try
82 {
83 // Check Callout data conatains Guarded requests.
84 if (!_callout.contains("Guarded"))
85 {
86 continue;
87 }
88 if (!_callout.at("Guarded").get<bool>())
89 {
90 continue;
91 }
92 // Get Entity path required for guard D-bus method
93 // "CreateWithEntityPath"
94 if (!_callout.contains("EntityPath"))
95 {
96 log<level::ERR>(
97 "GUARD: Callout data, missing EntityPath information");
98 continue;
99 }
100 using EntityPath = std::vector<uint8_t>;
101
102 auto entityPath = _callout.at("EntityPath").get<EntityPath>();
103
104 std::stringstream ss;
105 for (uint32_t a = 0; a < sizeof(ATTR_PHYS_BIN_PATH_Type); a++)
106 {
107 ss << " 0x" << std::hex << static_cast<int>(entityPath[a]);
108 }
109 std::string s = ss.str();
Jayanth Othayoth1aa90d42023-09-13 04:25:45 -0500110 log<level::INFO>(std::format("GUARD :({})", s).c_str());
Jayanth Othayothda9b5832021-11-05 04:19:43 -0500111
112 // Get Guard type
113 auto severity = EntrySeverity::Warning;
114 if (!_callout.contains("GuardType"))
115 {
116 log<level::ERR>(
117 "GUARD: doesn't have Severity, setting to warning");
118 }
119 else
120 {
121 auto guardType = _callout.at("GuardType").get<std::string>();
122 // convert GuardType to severity type.
123 auto sType = getEntrySeverityType(guardType);
124 if (sType.has_value())
125 {
126 severity = sType.value();
127 }
128 }
129 // Create guard record
130 auto type = sdbusplus::xyz::openbmc_project::HardwareIsolation::
131 server::convertForMessage(severity);
132 dataIface.createGuardRecord(entityPath, type, path);
133 }
134 catch (const std::exception& e)
135 {
136 log<level::INFO>(
Jayanth Othayoth1aa90d42023-09-13 04:25:45 -0500137 std::format("GUARD: Failed entry creation exception:({})",
Jayanth Othayothda9b5832021-11-05 04:19:43 -0500138 e.what())
139 .c_str());
140 }
141 }
142}
143
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -0600144/**
145 * @brief Helper function to create deconfig records.
146 *
147 * User need to fill the JSON callouts array with below keywords/data
148 * "EntityPath": entity path of the hardware from the PHAL device tree.
149 * "Deconfigured": boolean, true to create deconfigure records.
150 *
151 * libphal api is used for creating deconfigure records, which includes
152 * update HWAS_STATE attribute to non functional with PLID information.
153 *
154 * @param[in] jsonCallouts - The array of JSON callouts, or an empty object.
155 * @param[in] plid - PLID value
156 */
157void createDeconfigRecords(const nlohmann::json& jsonCallouts,
158 const uint32_t plid)
159{
160 using namespace openpower::phal::pdbg;
161
162 if (jsonCallouts.empty())
163 {
164 return;
165 }
166
167 if (!jsonCallouts.is_array())
168 {
169 log<level::ERR>("Deconfig: Callout JSON isn't an array");
170 return;
171 }
172 for (const auto& _callout : jsonCallouts)
173 {
174 try
175 {
176 // Check Callout data conatains Guarded requests.
177 if (!_callout.contains("Deconfigured"))
178 {
179 continue;
180 }
181
182 if (!_callout.at("Deconfigured").get<bool>())
183 {
184 continue;
185 }
186
187 if (!_callout.contains("EntityPath"))
188 {
189 log<level::ERR>(
190 "Deconfig: Callout data missing EntityPath information");
191 continue;
192 }
193 using EntityPath = std::vector<uint8_t>;
194 auto entityPath = _callout.at("EntityPath").get<EntityPath>();
195 log<level::INFO>("Deconfig: adding deconfigure record");
196 // convert to libphal required format.
197 ATTR_PHYS_BIN_PATH_Type physBinPath;
198 std::copy(entityPath.begin(), entityPath.end(), physBinPath);
199 // libphal api to deconfigure the target
200 if (!pdbg_targets_init(NULL))
201 {
202 log<level::ERR>("pdbg_targets_init failed, skipping deconfig "
203 "record update");
204 return;
205 }
206 openpower::phal::pdbg::deconfigureTgt(physBinPath, plid);
207 }
208 catch (const std::exception& e)
209 {
210 log<level::INFO>(
Jayanth Othayoth1aa90d42023-09-13 04:25:45 -0500211 std::format(
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -0600212 "Deconfig: Failed to create records, exception:({})",
213 e.what())
214 .c_str());
215 }
216 }
217}
218
Jayanth Othayothda9b5832021-11-05 04:19:43 -0500219void createServiceActions(const nlohmann::json& jsonCallouts,
220 const std::string& path,
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -0600221 const DataInterfaceBase& dataIface,
222 const uint32_t plid)
Jayanth Othayothda9b5832021-11-05 04:19:43 -0500223{
224 // Create Guard records.
225 createGuardRecords(jsonCallouts, path, dataIface);
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -0600226 // Create Deconfigure records.
227 createDeconfigRecords(jsonCallouts, plid);
Jayanth Othayothda9b5832021-11-05 04:19:43 -0500228}
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -0600229
Jayanth Othayothda9b5832021-11-05 04:19:43 -0500230} // namespace phal
231} // namespace pels
232} // namespace openpower