1 #include "phal_service_actions.hpp" 2 3 #include <attributes_info.H> 4 #include <fmt/format.h> 5 #include <libphal.H> 6 7 #include <phosphor-logging/log.hpp> 8 9 namespace openpower 10 { 11 namespace pels 12 { 13 namespace phal 14 { 15 using namespace phosphor::logging; 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 */ 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 log<level::ERR>( 43 fmt::format("GUARD: Unsupported GardType [{}] was given ", 44 "to get the hardware isolation entry severity type", 45 guardType.c_str()) 46 .c_str()); 47 } 48 return std::nullopt; 49 } 50 51 /** 52 * @brief Helper function to create guard records. 53 * 54 * User need to fill the JSON callouts array with below keywords/data 55 * "Entitypath": entity path of the hardware from the PHAL device tree. 56 * "Guardtype": The hardware isolation severity which is defined in 57 * xyz.openbmc_project.HardwareIsolation.Entry 58 * "Guarded": boolean, true to create gurad records. 59 * 60 * @param[in] jsonCallouts - The array of JSON callouts, or an empty object. 61 * @param[in] path - The BMC error log object path 62 * @param[in] dataIface - The DataInterface object 63 */ 64 void createGuardRecords(const nlohmann::json& jsonCallouts, 65 const std::string& path, 66 const DataInterfaceBase& dataIface) 67 { 68 if (jsonCallouts.empty()) 69 { 70 return; 71 } 72 73 if (!jsonCallouts.is_array()) 74 { 75 log<level::ERR>("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 log<level::ERR>( 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 for (uint32_t a = 0; a < sizeof(ATTR_PHYS_BIN_PATH_Type); a++) 105 { 106 ss << " 0x" << std::hex << static_cast<int>(entityPath[a]); 107 } 108 std::string s = ss.str(); 109 log<level::INFO>(fmt::format("GUARD :({})", s).c_str()); 110 111 // Get Guard type 112 auto severity = EntrySeverity::Warning; 113 if (!_callout.contains("GuardType")) 114 { 115 log<level::ERR>( 116 "GUARD: doesn't have Severity, setting to warning"); 117 } 118 else 119 { 120 auto guardType = _callout.at("GuardType").get<std::string>(); 121 // convert GuardType to severity type. 122 auto sType = getEntrySeverityType(guardType); 123 if (sType.has_value()) 124 { 125 severity = sType.value(); 126 } 127 } 128 // Create guard record 129 auto type = sdbusplus::xyz::openbmc_project::HardwareIsolation:: 130 server::convertForMessage(severity); 131 dataIface.createGuardRecord(entityPath, type, path); 132 } 133 catch (const std::exception& e) 134 { 135 log<level::INFO>( 136 fmt::format("GUARD: Failed entry creation exception:({})", 137 e.what()) 138 .c_str()); 139 } 140 } 141 } 142 143 /** 144 * @brief Helper function to create deconfig records. 145 * 146 * User need to fill the JSON callouts array with below keywords/data 147 * "EntityPath": entity path of the hardware from the PHAL device tree. 148 * "Deconfigured": boolean, true to create deconfigure records. 149 * 150 * libphal api is used for creating deconfigure records, which includes 151 * update HWAS_STATE attribute to non functional with PLID information. 152 * 153 * @param[in] jsonCallouts - The array of JSON callouts, or an empty object. 154 * @param[in] plid - PLID value 155 */ 156 void createDeconfigRecords(const nlohmann::json& jsonCallouts, 157 const uint32_t plid) 158 { 159 using namespace openpower::phal::pdbg; 160 161 if (jsonCallouts.empty()) 162 { 163 return; 164 } 165 166 if (!jsonCallouts.is_array()) 167 { 168 log<level::ERR>("Deconfig: Callout JSON isn't an array"); 169 return; 170 } 171 for (const auto& _callout : jsonCallouts) 172 { 173 try 174 { 175 // Check Callout data conatains Guarded requests. 176 if (!_callout.contains("Deconfigured")) 177 { 178 continue; 179 } 180 181 if (!_callout.at("Deconfigured").get<bool>()) 182 { 183 continue; 184 } 185 186 if (!_callout.contains("EntityPath")) 187 { 188 log<level::ERR>( 189 "Deconfig: Callout data missing EntityPath information"); 190 continue; 191 } 192 using EntityPath = std::vector<uint8_t>; 193 auto entityPath = _callout.at("EntityPath").get<EntityPath>(); 194 log<level::INFO>("Deconfig: adding deconfigure record"); 195 // convert to libphal required format. 196 ATTR_PHYS_BIN_PATH_Type physBinPath; 197 std::copy(entityPath.begin(), entityPath.end(), physBinPath); 198 // libphal api to deconfigure the target 199 if (!pdbg_targets_init(NULL)) 200 { 201 log<level::ERR>("pdbg_targets_init failed, skipping deconfig " 202 "record update"); 203 return; 204 } 205 openpower::phal::pdbg::deconfigureTgt(physBinPath, plid); 206 } 207 catch (const std::exception& e) 208 { 209 log<level::INFO>( 210 fmt::format( 211 "Deconfig: Failed to create records, exception:({})", 212 e.what()) 213 .c_str()); 214 } 215 } 216 } 217 218 void createServiceActions(const nlohmann::json& jsonCallouts, 219 const std::string& path, 220 const DataInterfaceBase& dataIface, 221 const uint32_t plid) 222 { 223 // Create Guard records. 224 createGuardRecords(jsonCallouts, path, dataIface); 225 // Create Deconfigure records. 226 createDeconfigRecords(jsonCallouts, plid); 227 } 228 229 } // namespace phal 230 } // namespace pels 231 } // namespace openpower 232