1 #include "phal_service_actions.hpp" 2 3 #include <attributes_info.H> 4 #include <libphal.H> 5 6 #include <phosphor-logging/log.hpp> 7 8 #include <format> 9 10 namespace openpower 11 { 12 namespace pels 13 { 14 namespace phal 15 { 16 using 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 */ 27 std::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>( 44 std::format("GUARD: Unsupported GardType [{}] was given ", 45 "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 */ 65 void 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(); 110 log<level::INFO>(std::format("GUARD :({})", s).c_str()); 111 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>( 137 std::format("GUARD: Failed entry creation exception:({})", 138 e.what()) 139 .c_str()); 140 } 141 } 142 } 143 144 /** 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 */ 157 void 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>( 211 std::format( 212 "Deconfig: Failed to create records, exception:({})", 213 e.what()) 214 .c_str()); 215 } 216 } 217 } 218 219 void createServiceActions(const nlohmann::json& jsonCallouts, 220 const std::string& path, 221 const DataInterfaceBase& dataIface, 222 const uint32_t plid) 223 { 224 // Create Guard records. 225 createGuardRecords(jsonCallouts, path, dataIface); 226 // Create Deconfigure records. 227 createDeconfigRecords(jsonCallouts, plid); 228 } 229 230 } // namespace phal 231 } // namespace pels 232 } // namespace openpower 233