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