blob: aaa3c9d0dec8d0611509a2f93c368af8b2ce2b6f [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
Arya K Padman5bc26532024-04-10 06:19:25 -05006#include <phosphor-logging/lg2.hpp>
Jayanth Othayothda9b5832021-11-05 04:19:43 -05007
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{
Jayanth Othayothda9b5832021-11-05 04:19:43 -050016
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 */
26std::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 {
Arya K Padman5bc26532024-04-10 06:19:25 -050042 lg2::error(
43 "GUARD: Unsupported GuardType [{GUARD_TYPE}] was given to get the "
44 "hardware isolation entry severity type",
45 "GUARD_TYPE", guardType);
Jayanth Othayothda9b5832021-11-05 04:19:43 -050046 }
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 */
63void 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 {
Arya K Padman5bc26532024-04-10 06:19:25 -050074 lg2::error("GUARD: Callout JSON isn't an array");
Jayanth Othayothda9b5832021-11-05 04:19:43 -050075 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 {
Arya K Padman5bc26532024-04-10 06:19:25 -050094 lg2::error(
Jayanth Othayothda9b5832021-11-05 04:19:43 -050095 "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();
Arya K Padman5bc26532024-04-10 06:19:25 -0500108 lg2::info("GUARD: ({GUARD_TARGET})", "GUARD_TARGET", s);
Jayanth Othayothda9b5832021-11-05 04:19:43 -0500109
110 // Get Guard type
111 auto severity = EntrySeverity::Warning;
112 if (!_callout.contains("GuardType"))
113 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500114 lg2::error("GUARD: doesn't have Severity, setting to warning");
Jayanth Othayothda9b5832021-11-05 04:19:43 -0500115 }
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 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500133 lg2::info("GUARD: Failed entry creation exception:({EXCEPTION})",
134 "EXCEPTION", e);
Jayanth Othayothda9b5832021-11-05 04:19:43 -0500135 }
136 }
137}
138
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -0600139/**
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 */
152void 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 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500164 lg2::error("Deconfig: Callout JSON isn't an array");
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -0600165 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 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500184 lg2::error(
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -0600185 "Deconfig: Callout data missing EntityPath information");
186 continue;
187 }
188 using EntityPath = std::vector<uint8_t>;
189 auto entityPath = _callout.at("EntityPath").get<EntityPath>();
Arya K Padman5bc26532024-04-10 06:19:25 -0500190 lg2::info("Deconfig: adding deconfigure record");
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -0600191 // 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 if (!pdbg_targets_init(NULL))
196 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500197 lg2::error(
198 "pdbg_targets_init failed, skipping deconfig record update");
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -0600199 return;
200 }
201 openpower::phal::pdbg::deconfigureTgt(physBinPath, plid);
202 }
203 catch (const std::exception& e)
204 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500205 lg2::info(
206 "Deconfig: Failed to create records, exception:({EXCEPTION})",
207 "EXCEPTION", e);
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -0600208 }
209 }
210}
211
Jayanth Othayothda9b5832021-11-05 04:19:43 -0500212void createServiceActions(const nlohmann::json& jsonCallouts,
213 const std::string& path,
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -0600214 const DataInterfaceBase& dataIface,
215 const uint32_t plid)
Jayanth Othayothda9b5832021-11-05 04:19:43 -0500216{
217 // Create Guard records.
218 createGuardRecords(jsonCallouts, path, dataIface);
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -0600219 // Create Deconfigure records.
220 createDeconfigRecords(jsonCallouts, plid);
Jayanth Othayothda9b5832021-11-05 04:19:43 -0500221}
Jayanth Othayoth3ef7b602021-11-09 06:40:38 -0600222
Jayanth Othayothda9b5832021-11-05 04:19:43 -0500223} // namespace phal
224} // namespace pels
225} // namespace openpower