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