| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 1 | /* | 
 | 2 | // Copyright (c) 2018 Intel Corporation | 
 | 3 | // | 
 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 | // you may not use this file except in compliance with the License. | 
 | 6 | // You may obtain a copy of the License at | 
 | 7 | // | 
 | 8 | //      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 | // | 
 | 10 | // Unless required by applicable law or agreed to in writing, software | 
 | 11 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 | // See the License for the specific language governing permissions and | 
 | 14 | // limitations under the License. | 
 | 15 | */ | 
 | 16 |  | 
| Patrick Venture | c2a07d4 | 2020-05-30 16:35:03 -0700 | [diff] [blame] | 17 | #include "types.hpp" | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 18 | #include "xyz/openbmc_project/Common/error.hpp" | 
| Kuiying Wang | 45f0498 | 2018-12-26 09:23:08 +0800 | [diff] [blame] | 19 | #include "xyz/openbmc_project/Led/Physical/server.hpp" | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 20 |  | 
| Jayaprakash Mutyala | 9420416 | 2020-10-23 06:17:56 +0000 | [diff] [blame] | 21 | #include <openssl/crypto.h> | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 22 | #include <systemd/sd-journal.h> | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 23 |  | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 24 | #include <appcommands.hpp> | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 25 | #include <boost/container/flat_map.hpp> | 
| Yong Li | 23737fe | 2019-02-19 08:49:55 +0800 | [diff] [blame] | 26 | #include <boost/process/child.hpp> | 
 | 27 | #include <boost/process/io.hpp> | 
| Yong Li | 0669d19 | 2019-05-06 14:01:46 +0800 | [diff] [blame] | 28 | #include <com/intel/Control/OCOTShutdownPolicy/server.hpp> | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 29 | #include <commandutils.hpp> | 
| Zhikui Ren | ce4e73f | 2019-12-06 13:59:47 -0800 | [diff] [blame] | 30 | #include <gpiod.hpp> | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 31 | #include <ipmid/api.hpp> | 
| Vernon Mauery | 5480ef6 | 2019-03-20 13:43:11 -0700 | [diff] [blame] | 32 | #include <ipmid/utils.hpp> | 
| James Feist | 63efafa | 2019-07-24 12:39:21 -0700 | [diff] [blame] | 33 | #include <nlohmann/json.hpp> | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 34 | #include <oemcommands.hpp> | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 35 | #include <phosphor-logging/log.hpp> | 
 | 36 | #include <sdbusplus/bus.hpp> | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 37 | #include <sdbusplus/message/types.hpp> | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 38 | #include <xyz/openbmc_project/Chassis/Control/NMISource/server.hpp> | 
| Chen,Yugang | 4f7e76b | 2019-08-20 09:28:06 +0800 | [diff] [blame] | 39 | #include <xyz/openbmc_project/Control/Boot/Mode/server.hpp> | 
 | 40 | #include <xyz/openbmc_project/Control/Boot/Source/server.hpp> | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 41 | #include <xyz/openbmc_project/Control/PowerSupplyRedundancy/server.hpp> | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 42 | #include <xyz/openbmc_project/Control/Security/RestrictionMode/server.hpp> | 
| Richard Marian Thomaiyar | 8d4f8d7 | 2019-11-11 12:06:40 +0530 | [diff] [blame] | 43 | #include <xyz/openbmc_project/Control/Security/SpecialMode/server.hpp> | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 44 |  | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 45 | #include <array> | 
 | 46 | #include <filesystem> | 
| Jason M. Bills | 493d776 | 2022-05-04 11:13:19 -0700 | [diff] [blame] | 47 | #include <fstream> | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 48 | #include <iostream> | 
 | 49 | #include <regex> | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 50 | #include <set> | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 51 | #include <string> | 
 | 52 | #include <variant> | 
 | 53 | #include <vector> | 
 | 54 |  | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 55 | namespace ipmi | 
 | 56 | { | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 57 | static void registerOEMFunctions() __attribute__((constructor)); | 
| Vernon Mauery | 4ac799d | 2019-05-20 15:50:37 -0700 | [diff] [blame] | 58 |  | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 59 | static constexpr size_t maxFRUStringLength = 0x3F; | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 60 |  | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 61 | static constexpr auto ethernetIntf = | 
 | 62 |     "xyz.openbmc_project.Network.EthernetInterface"; | 
 | 63 | static constexpr auto networkIPIntf = "xyz.openbmc_project.Network.IP"; | 
 | 64 | static constexpr auto networkService = "xyz.openbmc_project.Network"; | 
 | 65 | static constexpr auto networkRoot = "/xyz/openbmc_project/network"; | 
 | 66 |  | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 67 | static constexpr const char* oemNmiSourceIntf = | 
 | 68 |     "xyz.openbmc_project.Chassis.Control.NMISource"; | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 69 | static constexpr const char* oemNmiSourceObjPath = | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 70 |     "/xyz/openbmc_project/Chassis/Control/NMISource"; | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 71 | static constexpr const char* oemNmiBmcSourceObjPathProp = "BMCSource"; | 
 | 72 | static constexpr const char* oemNmiEnabledObjPathProp = "Enabled"; | 
 | 73 |  | 
| James Feist | 63efafa | 2019-07-24 12:39:21 -0700 | [diff] [blame] | 74 | static constexpr const char* dimmOffsetFile = "/var/lib/ipmi/ipmi_dimms.json"; | 
| srikanta mondal | 2030d7c | 2020-05-03 17:25:25 +0000 | [diff] [blame] | 75 | static constexpr const char* multiNodeObjPath = | 
 | 76 |     "/xyz/openbmc_project/MultiNode/Status"; | 
 | 77 | static constexpr const char* multiNodeIntf = | 
 | 78 |     "xyz.openbmc_project.Chassis.MultiNode"; | 
| James Feist | 63efafa | 2019-07-24 12:39:21 -0700 | [diff] [blame] | 79 |  | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 80 | enum class NmiSource : uint8_t | 
 | 81 | { | 
 | 82 |     none = 0, | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 83 |     frontPanelButton = 1, | 
 | 84 |     watchdog = 2, | 
 | 85 |     chassisCmd = 3, | 
 | 86 |     memoryError = 4, | 
 | 87 |     pciBusError = 5, | 
 | 88 |     pch = 6, | 
 | 89 |     chipset = 7, | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 90 | }; | 
 | 91 |  | 
| Suryakanth Sekar | 822b0b4 | 2019-11-15 18:32:53 +0530 | [diff] [blame] | 92 | enum class SpecialUserIndex : uint8_t | 
 | 93 | { | 
 | 94 |     rootUser = 0, | 
 | 95 |     atScaleDebugUser = 1 | 
 | 96 | }; | 
 | 97 |  | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 98 | static constexpr const char* restricionModeService = | 
 | 99 |     "xyz.openbmc_project.RestrictionMode.Manager"; | 
 | 100 | static constexpr const char* restricionModeBasePath = | 
 | 101 |     "/xyz/openbmc_project/control/security/restriction_mode"; | 
 | 102 | static constexpr const char* restricionModeIntf = | 
 | 103 |     "xyz.openbmc_project.Control.Security.RestrictionMode"; | 
 | 104 | static constexpr const char* restricionModeProperty = "RestrictionMode"; | 
 | 105 |  | 
 | 106 | static constexpr const char* specialModeService = | 
 | 107 |     "xyz.openbmc_project.SpecialMode"; | 
 | 108 | static constexpr const char* specialModeBasePath = | 
| Richard Marian Thomaiyar | a7b7428 | 2019-09-22 21:53:14 +0530 | [diff] [blame] | 109 |     "/xyz/openbmc_project/security/special_mode"; | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 110 | static constexpr const char* specialModeIntf = | 
 | 111 |     "xyz.openbmc_project.Security.SpecialMode"; | 
 | 112 | static constexpr const char* specialModeProperty = "SpecialMode"; | 
 | 113 |  | 
 | 114 | static constexpr const char* dBusPropertyIntf = | 
 | 115 |     "org.freedesktop.DBus.Properties"; | 
 | 116 | static constexpr const char* dBusPropertyGetMethod = "Get"; | 
 | 117 | static constexpr const char* dBusPropertySetMethod = "Set"; | 
 | 118 |  | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 119 | // return code: 0 successful | 
| Patrick Williams | f944d2e | 2022-07-22 19:26:52 -0500 | [diff] [blame] | 120 | int8_t getChassisSerialNumber(sdbusplus::bus_t& bus, std::string& serial) | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 121 | { | 
 | 122 |     std::string objpath = "/xyz/openbmc_project/FruDevice"; | 
 | 123 |     std::string intf = "xyz.openbmc_project.FruDeviceManager"; | 
 | 124 |     std::string service = getService(bus, intf, objpath); | 
 | 125 |     ObjectValueTree valueTree = getManagedObjects(bus, service, "/"); | 
 | 126 |     if (valueTree.empty()) | 
 | 127 |     { | 
 | 128 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 129 |             "No object implements interface", | 
 | 130 |             phosphor::logging::entry("INTF=%s", intf.c_str())); | 
 | 131 |         return -1; | 
 | 132 |     } | 
 | 133 |  | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 134 |     for (const auto& item : valueTree) | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 135 |     { | 
 | 136 |         auto interface = item.second.find("xyz.openbmc_project.FruDevice"); | 
 | 137 |         if (interface == item.second.end()) | 
 | 138 |         { | 
 | 139 |             continue; | 
 | 140 |         } | 
 | 141 |  | 
 | 142 |         auto property = interface->second.find("CHASSIS_SERIAL_NUMBER"); | 
 | 143 |         if (property == interface->second.end()) | 
 | 144 |         { | 
 | 145 |             continue; | 
 | 146 |         } | 
 | 147 |  | 
 | 148 |         try | 
 | 149 |         { | 
 | 150 |             Value variant = property->second; | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 151 |             std::string& result = std::get<std::string>(variant); | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 152 |             if (result.size() > maxFRUStringLength) | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 153 |             { | 
 | 154 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 155 |                     "FRU serial number exceed maximum length"); | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 156 |                 return -1; | 
 | 157 |             } | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 158 |             serial = result; | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 159 |             return 0; | 
 | 160 |         } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 161 |         catch (const std::bad_variant_access& e) | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 162 |         { | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 163 |             phosphor::logging::log<phosphor::logging::level::ERR>(e.what()); | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 164 |             return -1; | 
 | 165 |         } | 
 | 166 |     } | 
 | 167 |     return -1; | 
 | 168 | } | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 169 |  | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 170 | namespace mailbox | 
 | 171 | { | 
 | 172 | static uint8_t bus = 4; | 
 | 173 | static std::string i2cBus = "/dev/i2c-" + std::to_string(bus); | 
| Matt Simmering | 80d4d5f | 2023-02-15 15:18:51 -0800 | [diff] [blame] | 174 | static uint8_t targetAddr = 56; | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 175 | static constexpr auto systemRoot = "/xyz/openbmc_project/inventory/system"; | 
 | 176 | static constexpr auto sessionIntf = "xyz.openbmc_project.Configuration.PFR"; | 
 | 177 | const std::string match = "Baseboard/PFR"; | 
 | 178 | static bool i2cConfigLoaded = false; | 
 | 179 | // Command register for UFM provisioning/access commands; read/write allowed | 
 | 180 | // from CPU/BMC. | 
 | 181 | static const constexpr uint8_t provisioningCommand = 0x0b; | 
 | 182 | // Trigger register for the command set in the previous offset. | 
 | 183 | static const constexpr uint8_t triggerCommand = 0x0c; | 
 | 184 | // Set 0x0c to 0x05 to execute command specified at “UFM/Provisioning Command” | 
 | 185 | // register | 
 | 186 | static const constexpr uint8_t flushRead = 0x05; | 
 | 187 | // FIFO read registers | 
 | 188 | std::set<uint8_t> readFifoReg = {0x08, 0x0C, 0x0D, 0x13}; | 
 | 189 |  | 
 | 190 | // UFM Read FIFO | 
 | 191 | static const constexpr uint8_t readFifo = 0x0e; | 
 | 192 |  | 
 | 193 | enum registerType : uint8_t | 
 | 194 | { | 
 | 195 |     singleByteRegister = 0, | 
 | 196 |     fifoReadRegister, | 
 | 197 |  | 
 | 198 | }; | 
 | 199 |  | 
 | 200 | void loadPfrConfig(ipmi::Context::ptr& ctx, bool& i2cConfigLoaded) | 
 | 201 | { | 
 | 202 |     ipmi::ObjectTree objectTree; | 
 | 203 |  | 
 | 204 |     boost::system::error_code ec = ipmi::getAllDbusObjects( | 
 | 205 |         ctx, systemRoot, sessionIntf, match, objectTree); | 
 | 206 |  | 
 | 207 |     if (ec) | 
 | 208 |     { | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 209 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 210 |             "Failed to fetch PFR object from dbus", | 
 | 211 |             phosphor::logging::entry("INTERFACE=%s", sessionIntf), | 
 | 212 |             phosphor::logging::entry("ERROR=%s", ec.message().c_str())); | 
 | 213 |  | 
 | 214 |         return; | 
 | 215 |     } | 
 | 216 |  | 
 | 217 |     for (auto& softObject : objectTree) | 
 | 218 |     { | 
 | 219 |         const std::string& objPath = softObject.first; | 
 | 220 |         const std::string& serviceName = softObject.second.begin()->first; | 
 | 221 |         // PFR object found.. check for PFR support | 
 | 222 |         ipmi::PropertyMap result; | 
 | 223 |  | 
 | 224 |         ec = ipmi::getAllDbusProperties(ctx, serviceName, objPath, sessionIntf, | 
 | 225 |                                         result); | 
 | 226 |  | 
 | 227 |         if (ec) | 
 | 228 |         { | 
 | 229 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 230 |                 "Failed to fetch pfr properties", | 
 | 231 |                 phosphor::logging::entry("ERROR=%s", ec.message().c_str())); | 
 | 232 |             return; | 
 | 233 |         } | 
 | 234 |  | 
 | 235 |         const uint64_t* i2cBusNum = nullptr; | 
 | 236 |         const uint64_t* address = nullptr; | 
 | 237 |  | 
 | 238 |         for (const auto& [propName, propVariant] : result) | 
 | 239 |         { | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 240 |             if (propName == "Address") | 
 | 241 |             { | 
 | 242 |                 address = std::get_if<uint64_t>(&propVariant); | 
 | 243 |             } | 
 | 244 |             else if (propName == "Bus") | 
 | 245 |             { | 
 | 246 |                 i2cBusNum = std::get_if<uint64_t>(&propVariant); | 
 | 247 |             } | 
 | 248 |         } | 
 | 249 |  | 
 | 250 |         if ((address == nullptr) || (i2cBusNum == nullptr)) | 
 | 251 |         { | 
 | 252 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 253 |                 "Unable to read the pfr properties"); | 
 | 254 |             return; | 
 | 255 |         } | 
 | 256 |  | 
 | 257 |         bus = static_cast<int>(*i2cBusNum); | 
 | 258 |         i2cBus = "/dev/i2c-" + std::to_string(bus); | 
| Matt Simmering | 80d4d5f | 2023-02-15 15:18:51 -0800 | [diff] [blame] | 259 |         targetAddr = static_cast<int>(*address); | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 260 |  | 
 | 261 |         i2cConfigLoaded = true; | 
 | 262 |     } | 
 | 263 | } | 
 | 264 |  | 
 | 265 | void writefifo(const uint8_t cmdReg, const uint8_t val) | 
 | 266 | { | 
 | 267 |     // Based on the spec, writing cmdReg to address val on this device, will | 
 | 268 |     // trigger the write FIFO operation. | 
 | 269 |     std::vector<uint8_t> writeData = {cmdReg, val}; | 
 | 270 |     std::vector<uint8_t> readBuf(0); | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 271 |     ipmi::Cc retI2C = ipmi::i2cWriteRead(i2cBus, targetAddr, writeData, | 
 | 272 |                                          readBuf); | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 273 | } | 
 | 274 |  | 
 | 275 | } // namespace mailbox | 
 | 276 |  | 
| Vernon Mauery | af65268 | 2023-08-04 13:37:21 -0700 | [diff] [blame] | 277 | ipmi::RspType<std::string> ipmiOEMGetBmcVersionString() | 
 | 278 | { | 
 | 279 |     static std::string version{}; | 
 | 280 |     if (version.empty()) | 
 | 281 |     { | 
 | 282 |         std::regex expr{"^VERSION_ID=(.*)$"}; | 
 | 283 |         static constexpr auto osReleasePath{"/etc/os-release"}; | 
 | 284 |         std::ifstream ifs(osReleasePath); | 
 | 285 |         if (!ifs.is_open()) | 
 | 286 |         { | 
 | 287 |             version = "os-release not present"; | 
 | 288 |         } | 
 | 289 |         std::string line{}; | 
 | 290 |         while (std::getline(ifs, line)) | 
 | 291 |         { | 
 | 292 |             std::smatch sm; | 
 | 293 |             if (regex_match(line, sm, expr)) | 
 | 294 |             { | 
 | 295 |                 if (sm.size() == 2) | 
 | 296 |                 { | 
 | 297 |                     std::string v = sm[1].str(); | 
 | 298 |                     // remove the quotes | 
 | 299 |                     v.erase(std::remove(v.begin(), v.end(), '\"'), v.end()); | 
 | 300 |                     version = v; | 
 | 301 |                     break; | 
 | 302 |                 } | 
 | 303 |             } | 
 | 304 |         } | 
 | 305 |         ifs.close(); | 
 | 306 |         if (version.empty()) | 
 | 307 |         { | 
 | 308 |             version = "VERSION_ID not present"; | 
 | 309 |         } | 
 | 310 |     } | 
 | 311 |     return ipmi::responseSuccess(version); | 
 | 312 | } | 
 | 313 |  | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 314 | // Returns the Chassis Identifier (serial #) | 
 | 315 | ipmi_ret_t ipmiOEMGetChassisIdentifier(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
 | 316 |                                        ipmi_request_t request, | 
 | 317 |                                        ipmi_response_t response, | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 318 |                                        ipmi_data_len_t dataLen, | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 319 |                                        ipmi_context_t context) | 
 | 320 | { | 
 | 321 |     std::string serial; | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 322 |     if (*dataLen != 0) // invalid request if there are extra parameters | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 323 |     { | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 324 |         *dataLen = 0; | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 325 |         return IPMI_CC_REQ_DATA_LEN_INVALID; | 
 | 326 |     } | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 327 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
 | 328 |     if (getChassisSerialNumber(*dbus, serial) == 0) | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 329 |     { | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 330 |         *dataLen = serial.size(); // length will never exceed response length | 
 | 331 |                                   // as it is checked in getChassisSerialNumber | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 332 |         char* resp = static_cast<char*>(response); | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 333 |         serial.copy(resp, *dataLen); | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 334 |         return IPMI_CC_OK; | 
 | 335 |     } | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 336 |     *dataLen = 0; | 
 | 337 |     return IPMI_CC_RESPONSE_ERROR; | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 338 | } | 
 | 339 |  | 
 | 340 | ipmi_ret_t ipmiOEMSetSystemGUID(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
 | 341 |                                 ipmi_request_t request, | 
 | 342 |                                 ipmi_response_t response, | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 343 |                                 ipmi_data_len_t dataLen, ipmi_context_t context) | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 344 | { | 
 | 345 |     static constexpr size_t safeBufferLength = 50; | 
 | 346 |     char buf[safeBufferLength] = {0}; | 
 | 347 |     GUIDData* Data = reinterpret_cast<GUIDData*>(request); | 
 | 348 |  | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 349 |     if (*dataLen != sizeof(GUIDData)) // 16bytes | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 350 |     { | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 351 |         *dataLen = 0; | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 352 |         return IPMI_CC_REQ_DATA_LEN_INVALID; | 
 | 353 |     } | 
 | 354 |  | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 355 |     *dataLen = 0; | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 356 |  | 
 | 357 |     snprintf( | 
 | 358 |         buf, safeBufferLength, | 
 | 359 |         "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", | 
 | 360 |         Data->timeLow4, Data->timeLow3, Data->timeLow2, Data->timeLow1, | 
 | 361 |         Data->timeMid2, Data->timeMid1, Data->timeHigh2, Data->timeHigh1, | 
 | 362 |         Data->clock2, Data->clock1, Data->node6, Data->node5, Data->node4, | 
 | 363 |         Data->node3, Data->node2, Data->node1); | 
 | 364 |     // UUID is in RFC4122 format. Ex: 61a39523-78f2-11e5-9862-e6402cfc3223 | 
 | 365 |     std::string guid = buf; | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 366 |  | 
 | 367 |     std::string objpath = "/xyz/openbmc_project/control/host0/systemGUID"; | 
 | 368 |     std::string intf = "xyz.openbmc_project.Common.UUID"; | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 369 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
 | 370 |     std::string service = getService(*dbus, intf, objpath); | 
 | 371 |     setDbusProperty(*dbus, service, objpath, intf, "UUID", guid); | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 372 |     return IPMI_CC_OK; | 
 | 373 | } | 
 | 374 |  | 
| Jason M. Bills | b02bf09 | 2019-08-15 13:01:56 -0700 | [diff] [blame] | 375 | ipmi::RspType<> ipmiOEMDisableBMCSystemReset(bool disableResetOnSMI, | 
 | 376 |                                              uint7_t reserved1) | 
 | 377 | { | 
| Jayaprakash Mutyala | 0a652fa | 2021-07-01 17:09:39 +0000 | [diff] [blame] | 378 |     if (reserved1) | 
 | 379 |     { | 
 | 380 |         return ipmi::responseInvalidFieldRequest(); | 
 | 381 |     } | 
 | 382 |  | 
| Jason M. Bills | b02bf09 | 2019-08-15 13:01:56 -0700 | [diff] [blame] | 383 |     std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus(); | 
 | 384 |  | 
 | 385 |     try | 
 | 386 |     { | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 387 |         auto service = ipmi::getService(*busp, bmcResetDisablesIntf, | 
 | 388 |                                         bmcResetDisablesPath); | 
| Jason M. Bills | b02bf09 | 2019-08-15 13:01:56 -0700 | [diff] [blame] | 389 |         ipmi::setDbusProperty(*busp, service, bmcResetDisablesPath, | 
 | 390 |                               bmcResetDisablesIntf, "ResetOnSMI", | 
 | 391 |                               !disableResetOnSMI); | 
 | 392 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 393 |     catch (const std::exception& e) | 
| Jason M. Bills | b02bf09 | 2019-08-15 13:01:56 -0700 | [diff] [blame] | 394 |     { | 
 | 395 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 396 |             "Failed to set BMC reset disables", | 
 | 397 |             phosphor::logging::entry("EXCEPTION=%s", e.what())); | 
 | 398 |         return ipmi::responseUnspecifiedError(); | 
 | 399 |     } | 
 | 400 |  | 
 | 401 |     return ipmi::responseSuccess(); | 
 | 402 | } | 
 | 403 |  | 
 | 404 | ipmi::RspType<bool,   // disableResetOnSMI | 
 | 405 |               uint7_t // reserved | 
 | 406 |               > | 
 | 407 |     ipmiOEMGetBMCResetDisables() | 
 | 408 | { | 
 | 409 |     bool disableResetOnSMI = true; | 
 | 410 |  | 
 | 411 |     std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus(); | 
 | 412 |     try | 
 | 413 |     { | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 414 |         auto service = ipmi::getService(*busp, bmcResetDisablesIntf, | 
 | 415 |                                         bmcResetDisablesPath); | 
| Jason M. Bills | b02bf09 | 2019-08-15 13:01:56 -0700 | [diff] [blame] | 416 |         Value variant = | 
 | 417 |             ipmi::getDbusProperty(*busp, service, bmcResetDisablesPath, | 
 | 418 |                                   bmcResetDisablesIntf, "ResetOnSMI"); | 
 | 419 |         disableResetOnSMI = !std::get<bool>(variant); | 
 | 420 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 421 |     catch (const std::exception& e) | 
| Jason M. Bills | b02bf09 | 2019-08-15 13:01:56 -0700 | [diff] [blame] | 422 |     { | 
 | 423 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 424 |             "Failed to get BMC reset disables", | 
 | 425 |             phosphor::logging::entry("EXCEPTION=%s", e.what())); | 
 | 426 |         return ipmi::responseUnspecifiedError(); | 
 | 427 |     } | 
 | 428 |  | 
 | 429 |     return ipmi::responseSuccess(disableResetOnSMI, 0); | 
 | 430 | } | 
 | 431 |  | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 432 | ipmi_ret_t ipmiOEMSetBIOSID(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
 | 433 |                             ipmi_request_t request, ipmi_response_t response, | 
 | 434 |                             ipmi_data_len_t dataLen, ipmi_context_t context) | 
 | 435 | { | 
 | 436 |     DeviceInfo* data = reinterpret_cast<DeviceInfo*>(request); | 
 | 437 |  | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 438 |     if ((*dataLen < 2) || (*dataLen != (1 + data->biosIDLength))) | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 439 |     { | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 440 |         *dataLen = 0; | 
 | 441 |         return IPMI_CC_REQ_DATA_LEN_INVALID; | 
 | 442 |     } | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 443 |     std::string idString((char*)data->biosId, data->biosIDLength); | 
| Chalapathi Venkataramashetty | fb9f1aa | 2021-05-07 08:37:07 +0000 | [diff] [blame] | 444 |     for (auto idChar : idString) | 
 | 445 |     { | 
 | 446 |         if (!std::isprint(static_cast<unsigned char>(idChar))) | 
 | 447 |         { | 
 | 448 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 449 |                 "BIOS ID contains non printable character"); | 
 | 450 |             return IPMI_CC_INVALID_FIELD_REQUEST; | 
 | 451 |         } | 
 | 452 |     } | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 453 |  | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 454 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| Chalapathi | 899bfd1 | 2020-04-15 15:07:02 +0000 | [diff] [blame] | 455 |     std::string service = getService(*dbus, biosVersionIntf, biosActiveObjPath); | 
 | 456 |     setDbusProperty(*dbus, service, biosActiveObjPath, biosVersionIntf, | 
| Yong Li | 2742b85 | 2019-12-16 14:55:11 +0800 | [diff] [blame] | 457 |                     biosVersionProp, idString); | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 458 |     uint8_t* bytesWritten = static_cast<uint8_t*>(response); | 
 | 459 |     *bytesWritten = | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 460 |         data->biosIDLength; // how many bytes are written into storage | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 461 |     *dataLen = 1; | 
 | 462 |     return IPMI_CC_OK; | 
 | 463 | } | 
 | 464 |  | 
| Jayaprakash Mutyala | 90da3d9 | 2021-11-18 22:01:22 +0000 | [diff] [blame] | 465 | bool getActiveHSCSoftwareVersionInfo(std::string& hscVersion, size_t hscNumber) | 
 | 466 | { | 
 | 467 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
 | 468 |     try | 
 | 469 |     { | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 470 |         std::string hsbpObjPath = "/xyz/openbmc_project/software/HSBP_" + | 
 | 471 |                                   std::to_string(hscNumber); | 
| Jayaprakash Mutyala | 90da3d9 | 2021-11-18 22:01:22 +0000 | [diff] [blame] | 472 |         auto service = getService(*dbus, biosVersionIntf, hsbpObjPath); | 
 | 473 |         Value hscVersionValue = | 
 | 474 |             getDbusProperty(*dbus, "xyz.openbmc_project.HsbpManager", | 
 | 475 |                             hsbpObjPath, biosVersionIntf, "Version"); | 
 | 476 |         hscVersion = std::get<std::string>(hscVersionValue); | 
 | 477 |     } | 
| Patrick Williams | f944d2e | 2022-07-22 19:26:52 -0500 | [diff] [blame] | 478 |     catch (const sdbusplus::exception_t& e) | 
| Jayaprakash Mutyala | 90da3d9 | 2021-11-18 22:01:22 +0000 | [diff] [blame] | 479 |     { | 
 | 480 |         phosphor::logging::log<phosphor::logging::level::INFO>( | 
 | 481 |             "Failed to retrieve HSBP version information", | 
 | 482 |             phosphor::logging::entry("HSBP Number=%d", hscNumber)); | 
 | 483 |         return false; | 
 | 484 |     } | 
 | 485 |     return true; | 
 | 486 | } | 
 | 487 |  | 
 | 488 | bool getHscVerInfo(ipmi::Context::ptr ctx, uint8_t& hsc0Major, | 
 | 489 |                    uint8_t& hsc0Minor, uint8_t& hsc1Major, uint8_t& hsc1Minor, | 
 | 490 |                    uint8_t& hsc2Major, uint8_t& hsc2Minor) | 
 | 491 | { | 
 | 492 |     std::string hscVersion; | 
 | 493 |     std::array<uint8_t, 6> hscVersions{0}; | 
 | 494 |  | 
 | 495 |     for (size_t hscNumber = 1; hscNumber <= 3; hscNumber++) | 
 | 496 |     { | 
 | 497 |         if (!getActiveHSCSoftwareVersionInfo(hscVersion, hscNumber)) | 
 | 498 |         { | 
 | 499 |             continue; | 
 | 500 |         } | 
 | 501 |         std::regex pattern1("(\\d+?).(\\d+?).(\\d+?)"); | 
 | 502 |         constexpr size_t matchedPhosphor = 4; | 
 | 503 |         std::smatch results; | 
 | 504 |         // hscVersion = BOOT_VER.FPGA_VER.SECURITY_REVISION (Example: 00.02.01) | 
 | 505 |         if (std::regex_match(hscVersion, results, pattern1)) | 
 | 506 |         { | 
 | 507 |             // Major version is FPGA_VER and Minor version is SECURITY_REV | 
 | 508 |             if (results.size() == matchedPhosphor) | 
 | 509 |             { | 
 | 510 |                 int index = (hscNumber - 1) * 2; | 
 | 511 |                 hscVersions[index] = | 
 | 512 |                     static_cast<uint8_t>(std::stoi(results[2])); | 
 | 513 |                 hscVersions[index + 1] = | 
 | 514 |                     static_cast<uint8_t>(std::stoi(results[3])); | 
 | 515 |             } | 
 | 516 |         } | 
 | 517 |     } | 
 | 518 |     hsc0Major = hscVersions[0]; | 
 | 519 |     hsc0Minor = hscVersions[1]; | 
 | 520 |     hsc1Major = hscVersions[2]; | 
 | 521 |     hsc1Minor = hscVersions[3]; | 
 | 522 |     hsc2Major = hscVersions[4]; | 
 | 523 |     hsc2Minor = hscVersions[5]; | 
 | 524 |     return true; | 
 | 525 | } | 
 | 526 |  | 
| AppaRao Puli | e99e7ed | 2020-01-17 12:27:10 +0530 | [diff] [blame] | 527 | bool getSwVerInfo(ipmi::Context::ptr ctx, uint8_t& bmcMajor, uint8_t& bmcMinor, | 
 | 528 |                   uint8_t& meMajor, uint8_t& meMinor) | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 529 | { | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 530 |     // step 1 : get BMC Major and Minor numbers from its DBUS property | 
| AppaRao Puli | e99e7ed | 2020-01-17 12:27:10 +0530 | [diff] [blame] | 531 |     std::string bmcVersion; | 
 | 532 |     if (getActiveSoftwareVersionInfo(ctx, versionPurposeBMC, bmcVersion)) | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 533 |     { | 
 | 534 |         return false; | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 535 |     } | 
 | 536 |  | 
| AppaRao Puli | e99e7ed | 2020-01-17 12:27:10 +0530 | [diff] [blame] | 537 |     std::optional<MetaRevision> rev = convertIntelVersion(bmcVersion); | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 538 |     if (rev.has_value()) | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 539 |     { | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 540 |         MetaRevision revision = rev.value(); | 
 | 541 |         bmcMajor = revision.major; | 
 | 542 |  | 
 | 543 |         revision.minor = (revision.minor > 99 ? 99 : revision.minor); | 
 | 544 |         bmcMinor = revision.minor % 10 + (revision.minor / 10) * 16; | 
 | 545 |     } | 
 | 546 |  | 
 | 547 |     // step 2 : get ME Major and Minor numbers from its DBUS property | 
| AppaRao Puli | 32825a2 | 2020-01-17 15:52:41 +0530 | [diff] [blame] | 548 |     std::string meVersion; | 
 | 549 |     if (getActiveSoftwareVersionInfo(ctx, versionPurposeME, meVersion)) | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 550 |     { | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 551 |         return false; | 
 | 552 |     } | 
| AppaRao Puli | 32825a2 | 2020-01-17 15:52:41 +0530 | [diff] [blame] | 553 |     std::regex pattern1("(\\d+?).(\\d+?).(\\d+?).(\\d+?).(\\d+?)"); | 
 | 554 |     constexpr size_t matchedPhosphor = 6; | 
 | 555 |     std::smatch results; | 
 | 556 |     if (std::regex_match(meVersion, results, pattern1)) | 
 | 557 |     { | 
 | 558 |         if (results.size() == matchedPhosphor) | 
 | 559 |         { | 
 | 560 |             meMajor = static_cast<uint8_t>(std::stoi(results[1])); | 
| Jayaprakash Mutyala | d065702 | 2021-08-26 21:18:08 +0000 | [diff] [blame] | 561 |             meMinor = static_cast<uint8_t>(std::stoi(results[2]) << 4 | | 
 | 562 |                                            std::stoi(results[3])); | 
| AppaRao Puli | 32825a2 | 2020-01-17 15:52:41 +0530 | [diff] [blame] | 563 |         } | 
 | 564 |     } | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 565 |     return true; | 
 | 566 | } | 
 | 567 |  | 
 | 568 | ipmi::RspType< | 
 | 569 |     std::variant<std::string, | 
 | 570 |                  std::tuple<uint8_t, std::array<uint8_t, 2>, | 
 | 571 |                             std::array<uint8_t, 2>, std::array<uint8_t, 2>, | 
 | 572 |                             std::array<uint8_t, 2>, std::array<uint8_t, 2>>, | 
 | 573 |                  std::tuple<uint8_t, std::array<uint8_t, 2>>>> | 
| AppaRao Puli | e99e7ed | 2020-01-17 12:27:10 +0530 | [diff] [blame] | 574 |     ipmiOEMGetDeviceInfo(ipmi::Context::ptr ctx, uint8_t entityType, | 
 | 575 |                          std::optional<uint8_t> countToRead, | 
| AppaRao Puli | d46cb42 | 2020-01-21 18:40:21 +0530 | [diff] [blame] | 576 |                          std::optional<uint8_t> offset) | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 577 | { | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 578 |     if (entityType > static_cast<uint8_t>(OEMDevEntityType::sdrVer)) | 
 | 579 |     { | 
 | 580 |         return ipmi::responseInvalidFieldRequest(); | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 581 |     } | 
 | 582 |  | 
 | 583 |     // handle OEM command items | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 584 |     switch (OEMDevEntityType(entityType)) | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 585 |     { | 
 | 586 |         case OEMDevEntityType::biosId: | 
 | 587 |         { | 
| AppaRao Puli | d46cb42 | 2020-01-21 18:40:21 +0530 | [diff] [blame] | 588 |             // Byte 2&3, Only used with selecting BIOS | 
 | 589 |             if (!countToRead || !offset) | 
 | 590 |             { | 
 | 591 |                 return ipmi::responseReqDataLenInvalid(); | 
 | 592 |             } | 
 | 593 |  | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 594 |             std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 595 |             std::string service = getService(*dbus, biosVersionIntf, | 
 | 596 |                                              biosActiveObjPath); | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 597 |             try | 
 | 598 |             { | 
| Yong Li | 2742b85 | 2019-12-16 14:55:11 +0800 | [diff] [blame] | 599 |                 Value variant = | 
| Chalapathi | 899bfd1 | 2020-04-15 15:07:02 +0000 | [diff] [blame] | 600 |                     getDbusProperty(*dbus, service, biosActiveObjPath, | 
| Yong Li | 2742b85 | 2019-12-16 14:55:11 +0800 | [diff] [blame] | 601 |                                     biosVersionIntf, biosVersionProp); | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 602 |                 std::string& idString = std::get<std::string>(variant); | 
| AppaRao Puli | d46cb42 | 2020-01-21 18:40:21 +0530 | [diff] [blame] | 603 |                 if (*offset >= idString.size()) | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 604 |                 { | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 605 |                     return ipmi::responseParmOutOfRange(); | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 606 |                 } | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 607 |                 size_t length = 0; | 
| AppaRao Puli | d46cb42 | 2020-01-21 18:40:21 +0530 | [diff] [blame] | 608 |                 if (*countToRead > (idString.size() - *offset)) | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 609 |                 { | 
| AppaRao Puli | d46cb42 | 2020-01-21 18:40:21 +0530 | [diff] [blame] | 610 |                     length = idString.size() - *offset; | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 611 |                 } | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 612 |                 else | 
 | 613 |                 { | 
| AppaRao Puli | d46cb42 | 2020-01-21 18:40:21 +0530 | [diff] [blame] | 614 |                     length = *countToRead; | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 615 |                 } | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 616 |  | 
 | 617 |                 std::string readBuf = {0}; | 
 | 618 |                 readBuf.resize(length); | 
| AppaRao Puli | d46cb42 | 2020-01-21 18:40:21 +0530 | [diff] [blame] | 619 |                 std::copy_n(idString.begin() + *offset, length, | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 620 |                             (readBuf.begin())); | 
 | 621 |                 return ipmi::responseSuccess(readBuf); | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 622 |             } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 623 |             catch (const std::bad_variant_access& e) | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 624 |             { | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 625 |                 return ipmi::responseUnspecifiedError(); | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 626 |             } | 
 | 627 |         } | 
 | 628 |         break; | 
 | 629 |  | 
 | 630 |         case OEMDevEntityType::devVer: | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 631 |         { | 
| AppaRao Puli | d46cb42 | 2020-01-21 18:40:21 +0530 | [diff] [blame] | 632 |             // Byte 2&3, Only used with selecting BIOS | 
 | 633 |             if (countToRead || offset) | 
 | 634 |             { | 
 | 635 |                 return ipmi::responseReqDataLenInvalid(); | 
 | 636 |             } | 
 | 637 |  | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 638 |             constexpr const size_t verLen = 2; | 
 | 639 |             constexpr const size_t verTotalLen = 10; | 
 | 640 |             std::array<uint8_t, verLen> bmcBuf = {0xff, 0xff}; | 
 | 641 |             std::array<uint8_t, verLen> hsc0Buf = {0xff, 0xff}; | 
 | 642 |             std::array<uint8_t, verLen> hsc1Buf = {0xff, 0xff}; | 
 | 643 |             std::array<uint8_t, verLen> meBuf = {0xff, 0xff}; | 
 | 644 |             std::array<uint8_t, verLen> hsc2Buf = {0xff, 0xff}; | 
 | 645 |             // data0/1: BMC version number; data6/7: ME version number | 
| AppaRao Puli | e99e7ed | 2020-01-17 12:27:10 +0530 | [diff] [blame] | 646 |             if (!getSwVerInfo(ctx, bmcBuf[0], bmcBuf[1], meBuf[0], meBuf[1])) | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 647 |             { | 
 | 648 |                 return ipmi::responseUnspecifiedError(); | 
 | 649 |             } | 
| Jayaprakash Mutyala | 90da3d9 | 2021-11-18 22:01:22 +0000 | [diff] [blame] | 650 |             if (!getHscVerInfo(ctx, hsc0Buf[0], hsc0Buf[1], hsc1Buf[0], | 
 | 651 |                                hsc1Buf[1], hsc2Buf[0], hsc2Buf[1])) | 
 | 652 |             { | 
 | 653 |                 return ipmi::responseUnspecifiedError(); | 
 | 654 |             } | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 655 |             return ipmi::responseSuccess( | 
 | 656 |                 std::tuple< | 
 | 657 |                     uint8_t, std::array<uint8_t, verLen>, | 
 | 658 |                     std::array<uint8_t, verLen>, std::array<uint8_t, verLen>, | 
 | 659 |                     std::array<uint8_t, verLen>, std::array<uint8_t, verLen>>{ | 
 | 660 |                     verTotalLen, bmcBuf, hsc0Buf, hsc1Buf, meBuf, hsc2Buf}); | 
 | 661 |         } | 
 | 662 |         break; | 
 | 663 |  | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 664 |         case OEMDevEntityType::sdrVer: | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 665 |         { | 
| AppaRao Puli | d46cb42 | 2020-01-21 18:40:21 +0530 | [diff] [blame] | 666 |             // Byte 2&3, Only used with selecting BIOS | 
 | 667 |             if (countToRead || offset) | 
 | 668 |             { | 
 | 669 |                 return ipmi::responseReqDataLenInvalid(); | 
 | 670 |             } | 
 | 671 |  | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 672 |             constexpr const size_t sdrLen = 2; | 
 | 673 |             std::array<uint8_t, sdrLen> readBuf = {0x01, 0x0}; | 
 | 674 |             return ipmi::responseSuccess( | 
 | 675 |                 std::tuple<uint8_t, std::array<uint8_t, sdrLen>>{sdrLen, | 
 | 676 |                                                                  readBuf}); | 
 | 677 |         } | 
 | 678 |         break; | 
 | 679 |  | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 680 |         default: | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 681 |             return ipmi::responseInvalidFieldRequest(); | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 682 |     } | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 683 | } | 
 | 684 |  | 
 | 685 | ipmi_ret_t ipmiOEMGetAICFRU(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
 | 686 |                             ipmi_request_t request, ipmi_response_t response, | 
 | 687 |                             ipmi_data_len_t dataLen, ipmi_context_t context) | 
 | 688 | { | 
 | 689 |     if (*dataLen != 0) | 
 | 690 |     { | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 691 |         *dataLen = 0; | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 692 |         return IPMI_CC_REQ_DATA_LEN_INVALID; | 
 | 693 |     } | 
 | 694 |  | 
 | 695 |     *dataLen = 1; | 
 | 696 |     uint8_t* res = reinterpret_cast<uint8_t*>(response); | 
 | 697 |     // temporary fix. We don't support AIC FRU now. Just tell BIOS that no | 
 | 698 |     // AIC is available so that BIOS will not timeout repeatly which leads to | 
 | 699 |     // slow booting. | 
 | 700 |     *res = 0; // Byte1=Count of SlotPosition/FruID records. | 
 | 701 |     return IPMI_CC_OK; | 
 | 702 | } | 
 | 703 |  | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 704 | ipmi_ret_t ipmiOEMGetPowerRestoreDelay(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
 | 705 |                                        ipmi_request_t request, | 
 | 706 |                                        ipmi_response_t response, | 
 | 707 |                                        ipmi_data_len_t dataLen, | 
 | 708 |                                        ipmi_context_t context) | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 709 | { | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 710 |     GetPowerRestoreDelayRes* resp = | 
 | 711 |         reinterpret_cast<GetPowerRestoreDelayRes*>(response); | 
 | 712 |  | 
 | 713 |     if (*dataLen != 0) | 
 | 714 |     { | 
 | 715 |         *dataLen = 0; | 
 | 716 |         return IPMI_CC_REQ_DATA_LEN_INVALID; | 
 | 717 |     } | 
 | 718 |  | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 719 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 720 |     std::string service = getService(*dbus, powerRestoreDelayIntf, | 
 | 721 |                                      powerRestoreDelayObjPath); | 
 | 722 |     Value variant = getDbusProperty(*dbus, service, powerRestoreDelayObjPath, | 
 | 723 |                                     powerRestoreDelayIntf, | 
 | 724 |                                     powerRestoreDelayProp); | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 725 |  | 
| Andrei Kartashev | c42c7ed | 2022-01-10 12:17:34 +0300 | [diff] [blame] | 726 |     uint64_t val = std::get<uint64_t>(variant); | 
 | 727 |     val /= 1000000UL; | 
 | 728 |     uint16_t delay = val; | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 729 |     resp->byteLSB = delay; | 
 | 730 |     resp->byteMSB = delay >> 8; | 
 | 731 |  | 
 | 732 |     *dataLen = sizeof(GetPowerRestoreDelayRes); | 
 | 733 |  | 
 | 734 |     return IPMI_CC_OK; | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 735 | } | 
 | 736 |  | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 737 | static uint8_t bcdToDec(uint8_t val) | 
 | 738 | { | 
 | 739 |     return ((val / 16 * 10) + (val % 16)); | 
 | 740 | } | 
 | 741 |  | 
 | 742 | // Allows an update utility or system BIOS to send the status of an embedded | 
 | 743 | // firmware update attempt to the BMC. After received, BMC will create a logging | 
 | 744 | // record. | 
 | 745 | ipmi::RspType<> ipmiOEMSendEmbeddedFwUpdStatus(uint8_t status, uint8_t target, | 
 | 746 |                                                uint8_t majorRevision, | 
 | 747 |                                                uint8_t minorRevision, | 
 | 748 |                                                uint32_t auxInfo) | 
 | 749 | { | 
 | 750 |     std::string firmware; | 
| Jason M. Bills | dc24927 | 2019-04-03 09:58:40 -0700 | [diff] [blame] | 751 |     int instance = (target & targetInstanceMask) >> targetInstanceShift; | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 752 |     target = (target & selEvtTargetMask) >> selEvtTargetShift; | 
 | 753 |  | 
 | 754 |     /* make sure the status is 0, 1, or 2 as per the spec */ | 
 | 755 |     if (status > 2) | 
 | 756 |     { | 
 | 757 |         return ipmi::response(ipmi::ccInvalidFieldRequest); | 
 | 758 |     } | 
| Jason M. Bills | dc24927 | 2019-04-03 09:58:40 -0700 | [diff] [blame] | 759 |     /* make sure the target is 0, 1, 2, or 4 as per the spec */ | 
 | 760 |     if (target > 4 || target == 3) | 
 | 761 |     { | 
 | 762 |         return ipmi::response(ipmi::ccInvalidFieldRequest); | 
 | 763 |     } | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 764 |     /*orignal OEM command is to record OEM SEL. | 
 | 765 |     But openbmc does not support OEM SEL, so we redirect it to redfish event | 
 | 766 |     logging. */ | 
 | 767 |     std::string buildInfo; | 
 | 768 |     std::string action; | 
 | 769 |     switch (FWUpdateTarget(target)) | 
 | 770 |     { | 
 | 771 |         case FWUpdateTarget::targetBMC: | 
 | 772 |             firmware = "BMC"; | 
| Jason M. Bills | dc24927 | 2019-04-03 09:58:40 -0700 | [diff] [blame] | 773 |             buildInfo = "major: " + std::to_string(majorRevision) + " minor: " + | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 774 |                         std::to_string(bcdToDec(minorRevision)) + // BCD encoded | 
 | 775 |                         " BuildID: " + std::to_string(auxInfo); | 
 | 776 |             buildInfo += std::to_string(auxInfo); | 
 | 777 |             break; | 
 | 778 |         case FWUpdateTarget::targetBIOS: | 
 | 779 |             firmware = "BIOS"; | 
 | 780 |             buildInfo = | 
| Jason M. Bills | dc24927 | 2019-04-03 09:58:40 -0700 | [diff] [blame] | 781 |                 "major: " + | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 782 |                 std::to_string(bcdToDec(majorRevision)) + // BCD encoded | 
 | 783 |                 " minor: " + | 
 | 784 |                 std::to_string(bcdToDec(minorRevision)) + // BCD encoded | 
 | 785 |                 " ReleaseNumber: " +                      // ASCII encoded | 
 | 786 |                 std::to_string(static_cast<uint8_t>(auxInfo >> 0) - '0') + | 
 | 787 |                 std::to_string(static_cast<uint8_t>(auxInfo >> 8) - '0') + | 
 | 788 |                 std::to_string(static_cast<uint8_t>(auxInfo >> 16) - '0') + | 
 | 789 |                 std::to_string(static_cast<uint8_t>(auxInfo >> 24) - '0'); | 
 | 790 |             break; | 
 | 791 |         case FWUpdateTarget::targetME: | 
 | 792 |             firmware = "ME"; | 
 | 793 |             buildInfo = | 
| Jason M. Bills | dc24927 | 2019-04-03 09:58:40 -0700 | [diff] [blame] | 794 |                 "major: " + std::to_string(majorRevision) + " minor1: " + | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 795 |                 std::to_string(bcdToDec(minorRevision)) + // BCD encoded | 
 | 796 |                 " minor2: " + | 
 | 797 |                 std::to_string(bcdToDec(static_cast<uint8_t>(auxInfo >> 0))) + | 
 | 798 |                 " build1: " + | 
 | 799 |                 std::to_string(bcdToDec(static_cast<uint8_t>(auxInfo >> 8))) + | 
 | 800 |                 " build2: " + | 
 | 801 |                 std::to_string(bcdToDec(static_cast<uint8_t>(auxInfo >> 16))); | 
 | 802 |             break; | 
 | 803 |         case FWUpdateTarget::targetOEMEWS: | 
 | 804 |             firmware = "EWS"; | 
| Jason M. Bills | dc24927 | 2019-04-03 09:58:40 -0700 | [diff] [blame] | 805 |             buildInfo = "major: " + std::to_string(majorRevision) + " minor: " + | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 806 |                         std::to_string(bcdToDec(minorRevision)) + // BCD encoded | 
 | 807 |                         " BuildID: " + std::to_string(auxInfo); | 
 | 808 |             break; | 
 | 809 |     } | 
 | 810 |  | 
| Jason M. Bills | dc24927 | 2019-04-03 09:58:40 -0700 | [diff] [blame] | 811 |     static const std::string openBMCMessageRegistryVersion("0.1"); | 
 | 812 |     std::string redfishMsgID = "OpenBMC." + openBMCMessageRegistryVersion; | 
 | 813 |  | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 814 |     switch (status) | 
 | 815 |     { | 
 | 816 |         case 0x0: | 
 | 817 |             action = "update started"; | 
| Jason M. Bills | dc24927 | 2019-04-03 09:58:40 -0700 | [diff] [blame] | 818 |             redfishMsgID += ".FirmwareUpdateStarted"; | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 819 |             break; | 
 | 820 |         case 0x1: | 
 | 821 |             action = "update completed successfully"; | 
| Jason M. Bills | dc24927 | 2019-04-03 09:58:40 -0700 | [diff] [blame] | 822 |             redfishMsgID += ".FirmwareUpdateCompleted"; | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 823 |             break; | 
 | 824 |         case 0x2: | 
 | 825 |             action = "update failure"; | 
| Jason M. Bills | dc24927 | 2019-04-03 09:58:40 -0700 | [diff] [blame] | 826 |             redfishMsgID += ".FirmwareUpdateFailed"; | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 827 |             break; | 
 | 828 |         default: | 
 | 829 |             action = "unknown"; | 
 | 830 |             break; | 
 | 831 |     } | 
 | 832 |  | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 833 |     std::string firmwareInstanceStr = firmware + | 
 | 834 |                                       " instance: " + std::to_string(instance); | 
| Jason M. Bills | dc24927 | 2019-04-03 09:58:40 -0700 | [diff] [blame] | 835 |     std::string message("[firmware update] " + firmwareInstanceStr + | 
 | 836 |                         " status: <" + action + "> " + buildInfo); | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 837 |  | 
 | 838 |     sd_journal_send("MESSAGE=%s", message.c_str(), "PRIORITY=%i", LOG_INFO, | 
| Jason M. Bills | dc24927 | 2019-04-03 09:58:40 -0700 | [diff] [blame] | 839 |                     "REDFISH_MESSAGE_ID=%s", redfishMsgID.c_str(), | 
 | 840 |                     "REDFISH_MESSAGE_ARGS=%s,%s", firmwareInstanceStr.c_str(), | 
 | 841 |                     buildInfo.c_str(), NULL); | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 842 |     return ipmi::responseSuccess(); | 
 | 843 | } | 
 | 844 |  | 
| Rajashekar Gade Reddy | 2b664d5 | 2020-03-23 22:09:00 +0530 | [diff] [blame] | 845 | ipmi::RspType<uint8_t, std::vector<uint8_t>> | 
 | 846 |     ipmiOEMSlotIpmb(ipmi::Context::ptr ctx, uint6_t reserved1, | 
 | 847 |                     uint2_t slotNumber, uint3_t baseBoardSlotNum, | 
| Matt Simmering | 80d4d5f | 2023-02-15 15:18:51 -0800 | [diff] [blame] | 848 |                     uint3_t riserSlotNum, uint2_t reserved2, uint8_t targetAddr, | 
| Rajashekar Gade Reddy | 2b664d5 | 2020-03-23 22:09:00 +0530 | [diff] [blame] | 849 |                     uint8_t netFn, uint8_t cmd, | 
 | 850 |                     std::optional<std::vector<uint8_t>> writeData) | 
 | 851 | { | 
 | 852 |     if (reserved1 || reserved2) | 
 | 853 |     { | 
 | 854 |         return ipmi::responseInvalidFieldRequest(); | 
 | 855 |     } | 
 | 856 |  | 
 | 857 |     boost::system::error_code ec; | 
 | 858 |     using ipmbResponse = std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, | 
 | 859 |                                     std::vector<uint8_t>>; | 
 | 860 |     ipmbResponse res = ctx->bus->yield_method_call<ipmbResponse>( | 
 | 861 |         ctx->yield, ec, "xyz.openbmc_project.Ipmi.Channel.Ipmb", | 
 | 862 |         "/xyz/openbmc_project/Ipmi/Channel/Ipmb", "org.openbmc.Ipmb", | 
 | 863 |         "SlotIpmbRequest", static_cast<uint8_t>(slotNumber), | 
| Matt Simmering | 80d4d5f | 2023-02-15 15:18:51 -0800 | [diff] [blame] | 864 |         static_cast<uint8_t>(baseBoardSlotNum), targetAddr, netFn, cmd, | 
| Rajashekar Gade Reddy | 2b664d5 | 2020-03-23 22:09:00 +0530 | [diff] [blame] | 865 |         *writeData); | 
 | 866 |     if (ec) | 
 | 867 |     { | 
 | 868 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 869 |             "Failed to call dbus method SlotIpmbRequest"); | 
 | 870 |         return ipmi::responseUnspecifiedError(); | 
 | 871 |     } | 
 | 872 |  | 
 | 873 |     std::vector<uint8_t> dataReceived(0); | 
 | 874 |     int status = -1; | 
 | 875 |     uint8_t resNetFn = 0, resLun = 0, resCmd = 0, cc = 0; | 
 | 876 |  | 
 | 877 |     std::tie(status, resNetFn, resLun, resCmd, cc, dataReceived) = res; | 
 | 878 |  | 
 | 879 |     if (status) | 
 | 880 |     { | 
 | 881 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 882 |             "Failed to get response from SlotIpmbRequest"); | 
 | 883 |         return ipmi::responseResponseError(); | 
 | 884 |     } | 
 | 885 |     return ipmi::responseSuccess(cc, dataReceived); | 
 | 886 | } | 
 | 887 |  | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 888 | ipmi_ret_t ipmiOEMSetPowerRestoreDelay(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
 | 889 |                                        ipmi_request_t request, | 
 | 890 |                                        ipmi_response_t response, | 
 | 891 |                                        ipmi_data_len_t dataLen, | 
 | 892 |                                        ipmi_context_t context) | 
 | 893 | { | 
 | 894 |     SetPowerRestoreDelayReq* data = | 
 | 895 |         reinterpret_cast<SetPowerRestoreDelayReq*>(request); | 
 | 896 |     uint16_t delay = 0; | 
 | 897 |  | 
 | 898 |     if (*dataLen != sizeof(SetPowerRestoreDelayReq)) | 
 | 899 |     { | 
 | 900 |         *dataLen = 0; | 
 | 901 |         return IPMI_CC_REQ_DATA_LEN_INVALID; | 
 | 902 |     } | 
 | 903 |     delay = data->byteMSB; | 
 | 904 |     delay = (delay << 8) | data->byteLSB; | 
| Andrei Kartashev | c42c7ed | 2022-01-10 12:17:34 +0300 | [diff] [blame] | 905 |     uint64_t val = delay * 1000000; | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 906 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 907 |     std::string service = getService(*dbus, powerRestoreDelayIntf, | 
 | 908 |                                      powerRestoreDelayObjPath); | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 909 |     setDbusProperty(*dbus, service, powerRestoreDelayObjPath, | 
| Andrei Kartashev | c42c7ed | 2022-01-10 12:17:34 +0300 | [diff] [blame] | 910 |                     powerRestoreDelayIntf, powerRestoreDelayProp, val); | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 911 |     *dataLen = 0; | 
 | 912 |  | 
 | 913 |     return IPMI_CC_OK; | 
 | 914 | } | 
 | 915 |  | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 916 | static bool cpuPresent(const std::string& cpuName) | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 917 | { | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 918 |     static constexpr const char* cpuPresencePathPrefix = | 
 | 919 |         "/xyz/openbmc_project/inventory/system/chassis/motherboard/"; | 
 | 920 |     static constexpr const char* cpuPresenceIntf = | 
 | 921 |         "xyz.openbmc_project.Inventory.Item"; | 
 | 922 |     std::string cpuPresencePath = cpuPresencePathPrefix + cpuName; | 
 | 923 |     std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus(); | 
 | 924 |     try | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 925 |     { | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 926 |         auto service = ipmi::getService(*busp, cpuPresenceIntf, | 
 | 927 |                                         cpuPresencePath); | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 928 |  | 
 | 929 |         ipmi::Value result = ipmi::getDbusProperty( | 
 | 930 |             *busp, service, cpuPresencePath, cpuPresenceIntf, "Present"); | 
 | 931 |         return std::get<bool>(result); | 
 | 932 |     } | 
 | 933 |     catch (const std::exception& e) | 
 | 934 |     { | 
 | 935 |         phosphor::logging::log<phosphor::logging::level::INFO>( | 
 | 936 |             "Cannot find processor presence", | 
 | 937 |             phosphor::logging::entry("NAME=%s", cpuName.c_str())); | 
 | 938 |         return false; | 
 | 939 |     } | 
 | 940 | } | 
 | 941 |  | 
| Jason M. Bills | f284f85 | 2023-09-07 15:48:48 -0700 | [diff] [blame] | 942 | ipmi::RspType<bool,    // IERR Reset Enabled | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 943 |               bool,    // ERR2 Reset Enabled | 
| Jason M. Bills | 51cf311 | 2023-09-07 15:50:23 -0700 | [diff] [blame^] | 944 |               bool,    // MCERR Reset Enabled | 
 | 945 |               uint5_t, // reserved | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 946 |               uint8_t, // reserved, returns 0x3F | 
| Jason M. Bills | f284f85 | 2023-09-07 15:48:48 -0700 | [diff] [blame] | 947 |               uint6_t, // CPU1 IERR Count | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 948 |               uint2_t, // CPU1 Status | 
| Jason M. Bills | f284f85 | 2023-09-07 15:48:48 -0700 | [diff] [blame] | 949 |               uint6_t, // CPU2 IERR Count | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 950 |               uint2_t, // CPU2 Status | 
| Jason M. Bills | f284f85 | 2023-09-07 15:48:48 -0700 | [diff] [blame] | 951 |               uint6_t, // CPU3 IERR Count | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 952 |               uint2_t, // CPU3 Status | 
| Jason M. Bills | f284f85 | 2023-09-07 15:48:48 -0700 | [diff] [blame] | 953 |               uint6_t, // CPU4 IERR Count | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 954 |               uint2_t, // CPU4 Status | 
 | 955 |               uint8_t  // Crashdump Count | 
 | 956 |               > | 
 | 957 |     ipmiOEMGetProcessorErrConfig() | 
 | 958 | { | 
| Jason M. Bills | f284f85 | 2023-09-07 15:48:48 -0700 | [diff] [blame] | 959 |     bool resetOnIERR = false; | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 960 |     bool resetOnERR2 = false; | 
| Jason M. Bills | 51cf311 | 2023-09-07 15:50:23 -0700 | [diff] [blame^] | 961 |     bool allowResetOnMCERR = false; | 
| Jason M. Bills | f284f85 | 2023-09-07 15:48:48 -0700 | [diff] [blame] | 962 |     uint6_t cpu1IERRCount = 0; | 
 | 963 |     uint6_t cpu2IERRCount = 0; | 
 | 964 |     uint6_t cpu3IERRCount = 0; | 
 | 965 |     uint6_t cpu4IERRCount = 0; | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 966 |     uint8_t crashdumpCount = 0; | 
| Jason M. Bills | 24df90f | 2021-06-15 12:46:13 -0700 | [diff] [blame] | 967 |     uint2_t cpu1Status = cpuPresent("CPU_1") | 
 | 968 |                              ? types::enum_cast<uint8_t>(CPUStatus::enabled) | 
 | 969 |                              : types::enum_cast<uint8_t>(CPUStatus::notPresent); | 
 | 970 |     uint2_t cpu2Status = cpuPresent("CPU_2") | 
 | 971 |                              ? types::enum_cast<uint8_t>(CPUStatus::enabled) | 
 | 972 |                              : types::enum_cast<uint8_t>(CPUStatus::notPresent); | 
 | 973 |     uint2_t cpu3Status = cpuPresent("CPU_3") | 
 | 974 |                              ? types::enum_cast<uint8_t>(CPUStatus::enabled) | 
 | 975 |                              : types::enum_cast<uint8_t>(CPUStatus::notPresent); | 
 | 976 |     uint2_t cpu4Status = cpuPresent("CPU_4") | 
 | 977 |                              ? types::enum_cast<uint8_t>(CPUStatus::enabled) | 
 | 978 |                              : types::enum_cast<uint8_t>(CPUStatus::notPresent); | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 979 |  | 
 | 980 |     std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus(); | 
 | 981 |     try | 
 | 982 |     { | 
 | 983 |         auto service = ipmi::getService(*busp, processorErrConfigIntf, | 
 | 984 |                                         processorErrConfigObjPath); | 
 | 985 |  | 
 | 986 |         ipmi::PropertyMap result = ipmi::getAllDbusProperties( | 
 | 987 |             *busp, service, processorErrConfigObjPath, processorErrConfigIntf); | 
| Jason M. Bills | f284f85 | 2023-09-07 15:48:48 -0700 | [diff] [blame] | 988 |         resetOnIERR = std::get<bool>(result.at("ResetOnIERR")); | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 989 |         resetOnERR2 = std::get<bool>(result.at("ResetOnERR2")); | 
| Jason M. Bills | 51cf311 | 2023-09-07 15:50:23 -0700 | [diff] [blame^] | 990 |         allowResetOnMCERR = std::get<bool>(result.at("AllowResetOnMCERR")); | 
| Jason M. Bills | f284f85 | 2023-09-07 15:48:48 -0700 | [diff] [blame] | 991 |         cpu1IERRCount = std::get<uint8_t>(result.at("ErrorCountCPU1")); | 
 | 992 |         cpu2IERRCount = std::get<uint8_t>(result.at("ErrorCountCPU2")); | 
 | 993 |         cpu3IERRCount = std::get<uint8_t>(result.at("ErrorCountCPU3")); | 
 | 994 |         cpu4IERRCount = std::get<uint8_t>(result.at("ErrorCountCPU4")); | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 995 |         crashdumpCount = std::get<uint8_t>(result.at("CrashdumpCount")); | 
 | 996 |     } | 
 | 997 |     catch (const std::exception& e) | 
 | 998 |     { | 
 | 999 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1000 |             "Failed to fetch processor error config", | 
 | 1001 |             phosphor::logging::entry("ERROR=%s", e.what())); | 
 | 1002 |         return ipmi::responseUnspecifiedError(); | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 1003 |     } | 
 | 1004 |  | 
| Jason M. Bills | 51cf311 | 2023-09-07 15:50:23 -0700 | [diff] [blame^] | 1005 |     return ipmi::responseSuccess(resetOnIERR, resetOnERR2, allowResetOnMCERR, 0, | 
 | 1006 |                                  0x3F, cpu1IERRCount, cpu1Status, cpu2IERRCount, | 
| Jason M. Bills | f284f85 | 2023-09-07 15:48:48 -0700 | [diff] [blame] | 1007 |                                  cpu2Status, cpu3IERRCount, cpu3Status, | 
 | 1008 |                                  cpu4IERRCount, cpu4Status, crashdumpCount); | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 1009 | } | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 1010 |  | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 1011 | ipmi::RspType<> ipmiOEMSetProcessorErrConfig( | 
| Jason M. Bills | 51cf311 | 2023-09-07 15:50:23 -0700 | [diff] [blame^] | 1012 |     bool resetOnIERR, bool resetOnERR2, bool allowResetOnMCERR, | 
 | 1013 |     uint5_t reserved1, uint8_t reserved2, | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 1014 |     std::optional<bool> clearCPUErrorCount, | 
 | 1015 |     std::optional<bool> clearCrashdumpCount, std::optional<uint6_t> reserved3) | 
 | 1016 | { | 
| Jayaprakash Mutyala | 0a652fa | 2021-07-01 17:09:39 +0000 | [diff] [blame] | 1017 |     if (reserved1 || reserved2) | 
 | 1018 |     { | 
 | 1019 |         return ipmi::responseInvalidFieldRequest(); | 
 | 1020 |     } | 
 | 1021 |  | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 1022 |     std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus(); | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 1023 |  | 
 | 1024 |     try | 
 | 1025 |     { | 
| Jayaprakash Mutyala | 0a652fa | 2021-07-01 17:09:39 +0000 | [diff] [blame] | 1026 |         if (reserved3.value_or(0)) | 
 | 1027 |         { | 
 | 1028 |             return ipmi::responseInvalidFieldRequest(); | 
 | 1029 |         } | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 1030 |         auto service = ipmi::getService(*busp, processorErrConfigIntf, | 
 | 1031 |                                         processorErrConfigObjPath); | 
 | 1032 |         ipmi::setDbusProperty(*busp, service, processorErrConfigObjPath, | 
| Jason M. Bills | f284f85 | 2023-09-07 15:48:48 -0700 | [diff] [blame] | 1033 |                               processorErrConfigIntf, "ResetOnIERR", | 
 | 1034 |                               resetOnIERR); | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 1035 |         ipmi::setDbusProperty(*busp, service, processorErrConfigObjPath, | 
 | 1036 |                               processorErrConfigIntf, "ResetOnERR2", | 
 | 1037 |                               resetOnERR2); | 
| Jason M. Bills | 51cf311 | 2023-09-07 15:50:23 -0700 | [diff] [blame^] | 1038 |         ipmi::setDbusProperty(*busp, service, processorErrConfigObjPath, | 
 | 1039 |                               processorErrConfigIntf, "AllowResetOnMCERR", | 
 | 1040 |                               allowResetOnMCERR); | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 1041 |         if (clearCPUErrorCount.value_or(false)) | 
 | 1042 |         { | 
 | 1043 |             ipmi::setDbusProperty(*busp, service, processorErrConfigObjPath, | 
| Jason M. Bills | d3e1993 | 2019-08-15 12:39:03 -0700 | [diff] [blame] | 1044 |                                   processorErrConfigIntf, "ErrorCountCPU1", | 
 | 1045 |                                   static_cast<uint8_t>(0)); | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 1046 |             ipmi::setDbusProperty(*busp, service, processorErrConfigObjPath, | 
| Jason M. Bills | d3e1993 | 2019-08-15 12:39:03 -0700 | [diff] [blame] | 1047 |                                   processorErrConfigIntf, "ErrorCountCPU2", | 
 | 1048 |                                   static_cast<uint8_t>(0)); | 
 | 1049 |             ipmi::setDbusProperty(*busp, service, processorErrConfigObjPath, | 
 | 1050 |                                   processorErrConfigIntf, "ErrorCountCPU3", | 
 | 1051 |                                   static_cast<uint8_t>(0)); | 
 | 1052 |             ipmi::setDbusProperty(*busp, service, processorErrConfigObjPath, | 
 | 1053 |                                   processorErrConfigIntf, "ErrorCountCPU4", | 
 | 1054 |                                   static_cast<uint8_t>(0)); | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 1055 |         } | 
 | 1056 |         if (clearCrashdumpCount.value_or(false)) | 
 | 1057 |         { | 
 | 1058 |             ipmi::setDbusProperty(*busp, service, processorErrConfigObjPath, | 
| Jason M. Bills | d3e1993 | 2019-08-15 12:39:03 -0700 | [diff] [blame] | 1059 |                                   processorErrConfigIntf, "CrashdumpCount", | 
 | 1060 |                                   static_cast<uint8_t>(0)); | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 1061 |         } | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 1062 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 1063 |     catch (const std::exception& e) | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 1064 |     { | 
| Kuiying Wang | bc54667 | 2018-11-23 15:41:05 +0800 | [diff] [blame] | 1065 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 1066 |             "Failed to set processor error config", | 
 | 1067 |             phosphor::logging::entry("EXCEPTION=%s", e.what())); | 
 | 1068 |         return ipmi::responseUnspecifiedError(); | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 1069 |     } | 
 | 1070 |  | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 1071 |     return ipmi::responseSuccess(); | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 1072 | } | 
 | 1073 |  | 
| Yong Li | 703922d | 2018-11-06 13:25:31 +0800 | [diff] [blame] | 1074 | ipmi_ret_t ipmiOEMGetShutdownPolicy(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
 | 1075 |                                     ipmi_request_t request, | 
 | 1076 |                                     ipmi_response_t response, | 
 | 1077 |                                     ipmi_data_len_t dataLen, | 
 | 1078 |                                     ipmi_context_t context) | 
 | 1079 | { | 
 | 1080 |     GetOEMShutdownPolicyRes* resp = | 
 | 1081 |         reinterpret_cast<GetOEMShutdownPolicyRes*>(response); | 
 | 1082 |  | 
 | 1083 |     if (*dataLen != 0) | 
 | 1084 |     { | 
 | 1085 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
| Kuiying Wang | 45f0498 | 2018-12-26 09:23:08 +0800 | [diff] [blame] | 1086 |             "oem_get_shutdown_policy: invalid input len!"); | 
| Yong Li | 703922d | 2018-11-06 13:25:31 +0800 | [diff] [blame] | 1087 |         *dataLen = 0; | 
 | 1088 |         return IPMI_CC_REQ_DATA_LEN_INVALID; | 
 | 1089 |     } | 
 | 1090 |  | 
 | 1091 |     *dataLen = 0; | 
 | 1092 |  | 
 | 1093 |     try | 
 | 1094 |     { | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1095 |         std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 1096 |         std::string service = getService(*dbus, oemShutdownPolicyIntf, | 
 | 1097 |                                          oemShutdownPolicyObjPath); | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1098 |         Value variant = getDbusProperty( | 
 | 1099 |             *dbus, service, oemShutdownPolicyObjPath, oemShutdownPolicyIntf, | 
 | 1100 |             oemShutdownPolicyObjPathProp); | 
| Yong Li | 0669d19 | 2019-05-06 14:01:46 +0800 | [diff] [blame] | 1101 |  | 
 | 1102 |         if (sdbusplus::com::intel::Control::server::OCOTShutdownPolicy:: | 
 | 1103 |                 convertPolicyFromString(std::get<std::string>(variant)) == | 
 | 1104 |             sdbusplus::com::intel::Control::server::OCOTShutdownPolicy::Policy:: | 
 | 1105 |                 NoShutdownOnOCOT) | 
 | 1106 |         { | 
 | 1107 |             resp->policy = 0; | 
 | 1108 |         } | 
 | 1109 |         else if (sdbusplus::com::intel::Control::server::OCOTShutdownPolicy:: | 
 | 1110 |                      convertPolicyFromString(std::get<std::string>(variant)) == | 
 | 1111 |                  sdbusplus::com::intel::Control::server::OCOTShutdownPolicy:: | 
 | 1112 |                      Policy::ShutdownOnOCOT) | 
 | 1113 |         { | 
 | 1114 |             resp->policy = 1; | 
 | 1115 |         } | 
 | 1116 |         else | 
 | 1117 |         { | 
 | 1118 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1119 |                 "oem_set_shutdown_policy: invalid property!", | 
 | 1120 |                 phosphor::logging::entry( | 
 | 1121 |                     "PROP=%s", std::get<std::string>(variant).c_str())); | 
 | 1122 |             return IPMI_CC_UNSPECIFIED_ERROR; | 
 | 1123 |         } | 
| Yong Li | 703922d | 2018-11-06 13:25:31 +0800 | [diff] [blame] | 1124 |         // TODO needs to check if it is multi-node products, | 
 | 1125 |         // policy is only supported on node 3/4 | 
 | 1126 |         resp->policySupport = shutdownPolicySupported; | 
 | 1127 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 1128 |     catch (const sdbusplus::exception_t& e) | 
| Yong Li | 703922d | 2018-11-06 13:25:31 +0800 | [diff] [blame] | 1129 |     { | 
 | 1130 |         phosphor::logging::log<phosphor::logging::level::ERR>(e.description()); | 
 | 1131 |         return IPMI_CC_UNSPECIFIED_ERROR; | 
 | 1132 |     } | 
 | 1133 |  | 
 | 1134 |     *dataLen = sizeof(GetOEMShutdownPolicyRes); | 
 | 1135 |     return IPMI_CC_OK; | 
 | 1136 | } | 
 | 1137 |  | 
 | 1138 | ipmi_ret_t ipmiOEMSetShutdownPolicy(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
 | 1139 |                                     ipmi_request_t request, | 
 | 1140 |                                     ipmi_response_t response, | 
 | 1141 |                                     ipmi_data_len_t dataLen, | 
 | 1142 |                                     ipmi_context_t context) | 
 | 1143 | { | 
 | 1144 |     uint8_t* req = reinterpret_cast<uint8_t*>(request); | 
| Yong Li | 0669d19 | 2019-05-06 14:01:46 +0800 | [diff] [blame] | 1145 |     sdbusplus::com::intel::Control::server::OCOTShutdownPolicy::Policy policy = | 
 | 1146 |         sdbusplus::com::intel::Control::server::OCOTShutdownPolicy::Policy:: | 
 | 1147 |             NoShutdownOnOCOT; | 
| Yong Li | 703922d | 2018-11-06 13:25:31 +0800 | [diff] [blame] | 1148 |  | 
 | 1149 |     // TODO needs to check if it is multi-node products, | 
 | 1150 |     // policy is only supported on node 3/4 | 
 | 1151 |     if (*dataLen != 1) | 
 | 1152 |     { | 
 | 1153 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1154 |             "oem_set_shutdown_policy: invalid input len!"); | 
 | 1155 |         *dataLen = 0; | 
 | 1156 |         return IPMI_CC_REQ_DATA_LEN_INVALID; | 
 | 1157 |     } | 
 | 1158 |  | 
 | 1159 |     *dataLen = 0; | 
 | 1160 |     if ((*req != noShutdownOnOCOT) && (*req != shutdownOnOCOT)) | 
 | 1161 |     { | 
 | 1162 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1163 |             "oem_set_shutdown_policy: invalid input!"); | 
 | 1164 |         return IPMI_CC_INVALID_FIELD_REQUEST; | 
 | 1165 |     } | 
 | 1166 |  | 
| Yong Li | 0669d19 | 2019-05-06 14:01:46 +0800 | [diff] [blame] | 1167 |     if (*req == noShutdownOnOCOT) | 
 | 1168 |     { | 
 | 1169 |         policy = sdbusplus::com::intel::Control::server::OCOTShutdownPolicy:: | 
 | 1170 |             Policy::NoShutdownOnOCOT; | 
 | 1171 |     } | 
 | 1172 |     else | 
 | 1173 |     { | 
 | 1174 |         policy = sdbusplus::com::intel::Control::server::OCOTShutdownPolicy:: | 
 | 1175 |             Policy::ShutdownOnOCOT; | 
 | 1176 |     } | 
 | 1177 |  | 
| Yong Li | 703922d | 2018-11-06 13:25:31 +0800 | [diff] [blame] | 1178 |     try | 
 | 1179 |     { | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1180 |         std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 1181 |         std::string service = getService(*dbus, oemShutdownPolicyIntf, | 
 | 1182 |                                          oemShutdownPolicyObjPath); | 
| Yong Li | 0669d19 | 2019-05-06 14:01:46 +0800 | [diff] [blame] | 1183 |         setDbusProperty( | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1184 |             *dbus, service, oemShutdownPolicyObjPath, oemShutdownPolicyIntf, | 
| Yong Li | 0669d19 | 2019-05-06 14:01:46 +0800 | [diff] [blame] | 1185 |             oemShutdownPolicyObjPathProp, | 
 | 1186 |             sdbusplus::com::intel::Control::server::convertForMessage(policy)); | 
| Yong Li | 703922d | 2018-11-06 13:25:31 +0800 | [diff] [blame] | 1187 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 1188 |     catch (const sdbusplus::exception_t& e) | 
| Yong Li | 703922d | 2018-11-06 13:25:31 +0800 | [diff] [blame] | 1189 |     { | 
 | 1190 |         phosphor::logging::log<phosphor::logging::level::ERR>(e.description()); | 
 | 1191 |         return IPMI_CC_UNSPECIFIED_ERROR; | 
 | 1192 |     } | 
 | 1193 |  | 
 | 1194 |     return IPMI_CC_OK; | 
 | 1195 | } | 
 | 1196 |  | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1197 | /** @brief implementation for check the DHCP or not in IPv4 | 
 | 1198 |  *  @param[in] Channel - Channel number | 
 | 1199 |  *  @returns true or false. | 
 | 1200 |  */ | 
 | 1201 | static bool isDHCPEnabled(uint8_t Channel) | 
 | 1202 | { | 
 | 1203 |     try | 
 | 1204 |     { | 
 | 1205 |         auto ethdevice = getChannelName(Channel); | 
 | 1206 |         if (ethdevice.empty()) | 
 | 1207 |         { | 
 | 1208 |             return false; | 
 | 1209 |         } | 
 | 1210 |         auto ethIP = ethdevice + "/ipv4"; | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1211 |         std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 1212 |         auto ethernetObj = getDbusObject(*dbus, networkIPIntf, networkRoot, | 
 | 1213 |                                          ethIP); | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1214 |         auto value = getDbusProperty(*dbus, networkService, ethernetObj.first, | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1215 |                                      networkIPIntf, "Origin"); | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 1216 |         if (std::get<std::string>(value) == | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1217 |             "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP") | 
 | 1218 |         { | 
 | 1219 |             return true; | 
 | 1220 |         } | 
 | 1221 |         else | 
 | 1222 |         { | 
 | 1223 |             return false; | 
 | 1224 |         } | 
 | 1225 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 1226 |     catch (const sdbusplus::exception_t& e) | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1227 |     { | 
 | 1228 |         phosphor::logging::log<phosphor::logging::level::ERR>(e.description()); | 
 | 1229 |         return true; | 
 | 1230 |     } | 
 | 1231 | } | 
 | 1232 |  | 
 | 1233 | /** @brief implementes for check the DHCP or not in IPv6 | 
 | 1234 |  *  @param[in] Channel - Channel number | 
 | 1235 |  *  @returns true or false. | 
 | 1236 |  */ | 
 | 1237 | static bool isDHCPIPv6Enabled(uint8_t Channel) | 
 | 1238 | { | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1239 |     try | 
 | 1240 |     { | 
 | 1241 |         auto ethdevice = getChannelName(Channel); | 
 | 1242 |         if (ethdevice.empty()) | 
 | 1243 |         { | 
 | 1244 |             return false; | 
 | 1245 |         } | 
 | 1246 |         auto ethIP = ethdevice + "/ipv6"; | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1247 |         std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 1248 |         auto objectInfo = getDbusObject(*dbus, networkIPIntf, networkRoot, | 
 | 1249 |                                         ethIP); | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1250 |         auto properties = getAllDbusProperties(*dbus, objectInfo.second, | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1251 |                                                objectInfo.first, networkIPIntf); | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 1252 |         if (std::get<std::string>(properties["Origin"]) == | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1253 |             "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP") | 
 | 1254 |         { | 
 | 1255 |             return true; | 
 | 1256 |         } | 
 | 1257 |         else | 
 | 1258 |         { | 
 | 1259 |             return false; | 
 | 1260 |         } | 
 | 1261 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 1262 |     catch (const sdbusplus::exception_t& e) | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1263 |     { | 
 | 1264 |         phosphor::logging::log<phosphor::logging::level::ERR>(e.description()); | 
 | 1265 |         return true; | 
 | 1266 |     } | 
 | 1267 | } | 
 | 1268 |  | 
 | 1269 | /** @brief implementes the creating of default new user | 
 | 1270 |  *  @param[in] userName - new username in 16 bytes. | 
 | 1271 |  *  @param[in] userPassword - new password in 20 bytes | 
 | 1272 |  *  @returns ipmi completion code. | 
 | 1273 |  */ | 
 | 1274 | ipmi::RspType<> ipmiOEMSetUser2Activation( | 
 | 1275 |     std::array<uint8_t, ipmi::ipmiMaxUserName>& userName, | 
| Vernon Mauery | 3b3d29b | 2021-08-05 15:03:35 -0700 | [diff] [blame] | 1276 |     const SecureBuffer& userPassword) | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1277 | { | 
| Vernon Mauery | 3b3d29b | 2021-08-05 15:03:35 -0700 | [diff] [blame] | 1278 |     if (userPassword.size() != ipmi::maxIpmi20PasswordSize) | 
 | 1279 |     { | 
 | 1280 |         return ipmi::responseReqDataLenInvalid(); | 
 | 1281 |     } | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1282 |     bool userState = false; | 
 | 1283 |     // Check for System Interface not exist and LAN should be static | 
 | 1284 |     for (uint8_t channel = 0; channel < maxIpmiChannels; channel++) | 
 | 1285 |     { | 
| Manish Baing | 440f62b | 2021-07-15 22:00:37 +0000 | [diff] [blame] | 1286 |         ChannelInfo chInfo{}; | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1287 |         try | 
 | 1288 |         { | 
 | 1289 |             getChannelInfo(channel, chInfo); | 
 | 1290 |         } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 1291 |         catch (const sdbusplus::exception_t& e) | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1292 |         { | 
 | 1293 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1294 |                 "ipmiOEMSetUser2Activation: Failed to get Channel Info", | 
 | 1295 |                 phosphor::logging::entry("MSG: %s", e.description())); | 
 | 1296 |             return ipmi::response(ipmi::ccUnspecifiedError); | 
 | 1297 |         } | 
 | 1298 |         if (chInfo.mediumType == | 
 | 1299 |             static_cast<uint8_t>(EChannelMediumType::systemInterface)) | 
 | 1300 |         { | 
 | 1301 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1302 |                 "ipmiOEMSetUser2Activation: system interface  exist ."); | 
 | 1303 |             return ipmi::response(ipmi::ccCommandNotAvailable); | 
 | 1304 |         } | 
 | 1305 |         else | 
 | 1306 |         { | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1307 |             if (chInfo.mediumType == | 
 | 1308 |                 static_cast<uint8_t>(EChannelMediumType::lan8032)) | 
 | 1309 |             { | 
 | 1310 |                 if (isDHCPIPv6Enabled(channel) || isDHCPEnabled(channel)) | 
 | 1311 |                 { | 
 | 1312 |                     phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1313 |                         "ipmiOEMSetUser2Activation: DHCP enabled ."); | 
 | 1314 |                     return ipmi::response(ipmi::ccCommandNotAvailable); | 
 | 1315 |                 } | 
 | 1316 |             } | 
 | 1317 |         } | 
 | 1318 |     } | 
 | 1319 |     uint8_t maxChUsers = 0, enabledUsers = 0, fixedUsers = 0; | 
 | 1320 |     if (ipmi::ccSuccess == | 
 | 1321 |         ipmiUserGetAllCounts(maxChUsers, enabledUsers, fixedUsers)) | 
 | 1322 |     { | 
 | 1323 |         if (enabledUsers > 1) | 
 | 1324 |         { | 
 | 1325 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1326 |                 "ipmiOEMSetUser2Activation: more than one user is enabled."); | 
 | 1327 |             return ipmi::response(ipmi::ccCommandNotAvailable); | 
 | 1328 |         } | 
 | 1329 |         // Check the user 2 is enabled or not | 
 | 1330 |         ipmiUserCheckEnabled(ipmiDefaultUserId, userState); | 
 | 1331 |         if (userState == true) | 
 | 1332 |         { | 
 | 1333 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1334 |                 "ipmiOEMSetUser2Activation: user 2 already enabled ."); | 
 | 1335 |             return ipmi::response(ipmi::ccCommandNotAvailable); | 
 | 1336 |         } | 
 | 1337 |     } | 
 | 1338 |     else | 
 | 1339 |     { | 
 | 1340 |         return ipmi::response(ipmi::ccUnspecifiedError); | 
 | 1341 |     } | 
 | 1342 |  | 
 | 1343 | #if BYTE_ORDER == LITTLE_ENDIAN | 
 | 1344 |     PrivAccess privAccess = {PRIVILEGE_ADMIN, true, true, true, 0}; | 
 | 1345 | #endif | 
 | 1346 | #if BYTE_ORDER == BIG_ENDIAN | 
 | 1347 |     PrivAccess privAccess = {0, true, true, true, PRIVILEGE_ADMIN}; | 
 | 1348 | #endif | 
 | 1349 |  | 
| Vernon Mauery | 037cabd | 2020-05-14 12:16:01 -0700 | [diff] [blame] | 1350 |     // ipmiUserSetUserName correctly handles char*, possibly non-null | 
 | 1351 |     // terminated strings using ipmiMaxUserName size | 
| Jayaprakash Mutyala | 3fbe8d2 | 2020-10-29 14:42:59 +0000 | [diff] [blame] | 1352 |     size_t nameLen = strnlen(reinterpret_cast<const char*>(userName.data()), | 
 | 1353 |                              sizeof(userName)); | 
 | 1354 |     const std::string userNameRaw( | 
 | 1355 |         reinterpret_cast<const char*>(userName.data()), nameLen); | 
| jayaprakash Mutyala | 1429d4f | 2020-03-04 18:20:16 +0000 | [diff] [blame] | 1356 |  | 
| Vernon Mauery | 037cabd | 2020-05-14 12:16:01 -0700 | [diff] [blame] | 1357 |     if (ipmi::ccSuccess == ipmiUserSetUserName(ipmiDefaultUserId, userNameRaw)) | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1358 |     { | 
 | 1359 |         if (ipmi::ccSuccess == | 
 | 1360 |             ipmiUserSetUserPassword( | 
 | 1361 |                 ipmiDefaultUserId, | 
 | 1362 |                 reinterpret_cast<const char*>(userPassword.data()))) | 
 | 1363 |         { | 
 | 1364 |             if (ipmi::ccSuccess == | 
 | 1365 |                 ipmiUserSetPrivilegeAccess( | 
 | 1366 |                     ipmiDefaultUserId, | 
 | 1367 |                     static_cast<uint8_t>(ipmi::EChannelID::chanLan1), | 
 | 1368 |                     privAccess, true)) | 
 | 1369 |             { | 
 | 1370 |                 phosphor::logging::log<phosphor::logging::level::INFO>( | 
 | 1371 |                     "ipmiOEMSetUser2Activation: user created successfully "); | 
| Jayaprakash Mutyala | 9420416 | 2020-10-23 06:17:56 +0000 | [diff] [blame] | 1372 |  | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1373 |                 return ipmi::responseSuccess(); | 
 | 1374 |             } | 
 | 1375 |         } | 
 | 1376 |         // we need to delete  the default user id which added in this command as | 
 | 1377 |         // password / priv setting is failed. | 
| Jayaprakash Mutyala | 3fbe8d2 | 2020-10-29 14:42:59 +0000 | [diff] [blame] | 1378 |         ipmiUserSetUserName(ipmiDefaultUserId, static_cast<std::string>("")); | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 1379 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1380 |             "ipmiOEMSetUser2Activation: password / priv setting is failed."); | 
 | 1381 |     } | 
 | 1382 |     else | 
 | 1383 |     { | 
 | 1384 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1385 |             "ipmiOEMSetUser2Activation: Setting username failed."); | 
 | 1386 |     } | 
 | 1387 |  | 
 | 1388 |     return ipmi::response(ipmi::ccCommandNotAvailable); | 
 | 1389 | } | 
 | 1390 |  | 
| Suryakanth Sekar | 822b0b4 | 2019-11-15 18:32:53 +0530 | [diff] [blame] | 1391 | /** @brief implementes executing the linux command | 
 | 1392 |  *  @param[in] linux command | 
 | 1393 |  *  @returns status | 
 | 1394 |  */ | 
 | 1395 |  | 
 | 1396 | static uint8_t executeCmd(const char* path) | 
 | 1397 | { | 
 | 1398 |     boost::process::child execProg(path); | 
 | 1399 |     execProg.wait(); | 
 | 1400 |  | 
 | 1401 |     int retCode = execProg.exit_code(); | 
 | 1402 |     if (retCode) | 
 | 1403 |     { | 
 | 1404 |         return ipmi::ccUnspecifiedError; | 
 | 1405 |     } | 
 | 1406 |     return ipmi::ccSuccess; | 
 | 1407 | } | 
 | 1408 |  | 
 | 1409 | /** @brief implementes ASD Security event logging | 
 | 1410 |  *  @param[in] Event message string | 
 | 1411 |  *  @param[in] Event Severity | 
 | 1412 |  *  @returns status | 
 | 1413 |  */ | 
 | 1414 |  | 
 | 1415 | static void atScaleDebugEventlog(std::string msg, int severity) | 
 | 1416 | { | 
 | 1417 |     std::string eventStr = "OpenBMC.0.1." + msg; | 
 | 1418 |     sd_journal_send("MESSAGE=Security Event: %s", eventStr.c_str(), | 
 | 1419 |                     "PRIORITY=%i", severity, "REDFISH_MESSAGE_ID=%s", | 
 | 1420 |                     eventStr.c_str(), NULL); | 
 | 1421 | } | 
 | 1422 |  | 
| Richard Marian Thomaiyar | fc5e985 | 2019-04-14 15:06:27 +0530 | [diff] [blame] | 1423 | /** @brief implementes setting password for special user | 
 | 1424 |  *  @param[in] specialUserIndex | 
 | 1425 |  *  @param[in] userPassword - new password in 20 bytes | 
 | 1426 |  *  @returns ipmi completion code. | 
 | 1427 |  */ | 
 | 1428 | ipmi::RspType<> ipmiOEMSetSpecialUserPassword(ipmi::Context::ptr ctx, | 
 | 1429 |                                               uint8_t specialUserIndex, | 
 | 1430 |                                               std::vector<uint8_t> userPassword) | 
 | 1431 | { | 
 | 1432 |     ChannelInfo chInfo; | 
| Suryakanth Sekar | 822b0b4 | 2019-11-15 18:32:53 +0530 | [diff] [blame] | 1433 |     ipmi_ret_t status = ipmi::ccSuccess; | 
 | 1434 |  | 
| Richard Marian Thomaiyar | fc5e985 | 2019-04-14 15:06:27 +0530 | [diff] [blame] | 1435 |     try | 
 | 1436 |     { | 
 | 1437 |         getChannelInfo(ctx->channel, chInfo); | 
 | 1438 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 1439 |     catch (const sdbusplus::exception_t& e) | 
| Richard Marian Thomaiyar | fc5e985 | 2019-04-14 15:06:27 +0530 | [diff] [blame] | 1440 |     { | 
 | 1441 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1442 |             "ipmiOEMSetSpecialUserPassword: Failed to get Channel Info", | 
 | 1443 |             phosphor::logging::entry("MSG: %s", e.description())); | 
 | 1444 |         return ipmi::responseUnspecifiedError(); | 
 | 1445 |     } | 
 | 1446 |     if (chInfo.mediumType != | 
 | 1447 |         static_cast<uint8_t>(EChannelMediumType::systemInterface)) | 
 | 1448 |     { | 
 | 1449 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1450 |             "ipmiOEMSetSpecialUserPassword: Error - supported only in KCS " | 
 | 1451 |             "interface"); | 
 | 1452 |         return ipmi::responseCommandNotAvailable(); | 
 | 1453 |     } | 
| Suryakanth Sekar | 822b0b4 | 2019-11-15 18:32:53 +0530 | [diff] [blame] | 1454 |  | 
 | 1455 |     // 0 for root user  and 1 for AtScaleDebug is allowed | 
 | 1456 |     if (specialUserIndex > | 
 | 1457 |         static_cast<uint8_t>(SpecialUserIndex::atScaleDebugUser)) | 
| Richard Marian Thomaiyar | fc5e985 | 2019-04-14 15:06:27 +0530 | [diff] [blame] | 1458 |     { | 
 | 1459 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1460 |             "ipmiOEMSetSpecialUserPassword: Invalid user account"); | 
 | 1461 |         return ipmi::responseParmOutOfRange(); | 
 | 1462 |     } | 
| Suryakanth Sekar | 822b0b4 | 2019-11-15 18:32:53 +0530 | [diff] [blame] | 1463 |     if (userPassword.size() != 0) | 
| Richard Marian Thomaiyar | fc5e985 | 2019-04-14 15:06:27 +0530 | [diff] [blame] | 1464 |     { | 
| Suryakanth Sekar | 822b0b4 | 2019-11-15 18:32:53 +0530 | [diff] [blame] | 1465 |         constexpr uint8_t minPasswordSizeRequired = 6; | 
| Patrick Williams | 2393985 | 2021-09-02 11:18:35 -0500 | [diff] [blame] | 1466 |         SecureString passwd; | 
| Suryakanth Sekar | 822b0b4 | 2019-11-15 18:32:53 +0530 | [diff] [blame] | 1467 |         if (userPassword.size() < minPasswordSizeRequired || | 
 | 1468 |             userPassword.size() > ipmi::maxIpmi20PasswordSize) | 
 | 1469 |         { | 
| Jayaprakash Mutyala | 9420416 | 2020-10-23 06:17:56 +0000 | [diff] [blame] | 1470 |             OPENSSL_cleanse(userPassword.data(), userPassword.size()); | 
| Suryakanth Sekar | 822b0b4 | 2019-11-15 18:32:53 +0530 | [diff] [blame] | 1471 |             return ipmi::responseReqDataLenInvalid(); | 
 | 1472 |         } | 
 | 1473 |         passwd.assign(reinterpret_cast<const char*>(userPassword.data()), | 
 | 1474 |                       userPassword.size()); | 
| Jayaprakash Mutyala | 9420416 | 2020-10-23 06:17:56 +0000 | [diff] [blame] | 1475 |         // Clear sensitive data | 
 | 1476 |         OPENSSL_cleanse(userPassword.data(), userPassword.size()); | 
| Suryakanth Sekar | 822b0b4 | 2019-11-15 18:32:53 +0530 | [diff] [blame] | 1477 |         if (specialUserIndex == | 
 | 1478 |             static_cast<uint8_t>(SpecialUserIndex::atScaleDebugUser)) | 
 | 1479 |         { | 
 | 1480 |             status = ipmiSetSpecialUserPassword("asdbg", passwd); | 
 | 1481 |  | 
 | 1482 |             atScaleDebugEventlog("AtScaleDebugSpecialUserEnabled", LOG_CRIT); | 
 | 1483 |         } | 
 | 1484 |         else | 
 | 1485 |         { | 
 | 1486 |             status = ipmiSetSpecialUserPassword("root", passwd); | 
 | 1487 |         } | 
 | 1488 |         return ipmi::response(status); | 
| Richard Marian Thomaiyar | fc5e985 | 2019-04-14 15:06:27 +0530 | [diff] [blame] | 1489 |     } | 
| Suryakanth Sekar | 822b0b4 | 2019-11-15 18:32:53 +0530 | [diff] [blame] | 1490 |     else | 
 | 1491 |     { | 
 | 1492 |         if (specialUserIndex == | 
 | 1493 |             static_cast<uint8_t>(SpecialUserIndex::rootUser)) | 
 | 1494 |         { | 
 | 1495 |             status = executeCmd("passwd -d root"); | 
 | 1496 |         } | 
 | 1497 |         else | 
 | 1498 |         { | 
| Suryakanth Sekar | 822b0b4 | 2019-11-15 18:32:53 +0530 | [diff] [blame] | 1499 |             status = executeCmd("passwd -d asdbg"); | 
 | 1500 |  | 
 | 1501 |             if (status == 0) | 
 | 1502 |             { | 
 | 1503 |                 atScaleDebugEventlog("AtScaleDebugSpecialUserDisabled", | 
 | 1504 |                                      LOG_INFO); | 
 | 1505 |             } | 
 | 1506 |         } | 
 | 1507 |         return ipmi::response(status); | 
 | 1508 |     } | 
| Richard Marian Thomaiyar | fc5e985 | 2019-04-14 15:06:27 +0530 | [diff] [blame] | 1509 | } | 
 | 1510 |  | 
| Kuiying Wang | 45f0498 | 2018-12-26 09:23:08 +0800 | [diff] [blame] | 1511 | namespace ledAction | 
 | 1512 | { | 
 | 1513 | using namespace sdbusplus::xyz::openbmc_project::Led::server; | 
 | 1514 | std::map<Physical::Action, uint8_t> actionDbusToIpmi = { | 
| jayaprakash Mutyala | 934ee9c | 2019-12-13 17:49:27 +0000 | [diff] [blame] | 1515 |     {Physical::Action::Off, 0}, | 
 | 1516 |     {Physical::Action::On, 2}, | 
 | 1517 |     {Physical::Action::Blink, 1}}; | 
| Kuiying Wang | 45f0498 | 2018-12-26 09:23:08 +0800 | [diff] [blame] | 1518 |  | 
 | 1519 | std::map<uint8_t, std::string> offsetObjPath = { | 
 | 1520 |     {2, statusAmberObjPath}, {4, statusGreenObjPath}, {6, identifyLEDObjPath}}; | 
 | 1521 |  | 
 | 1522 | } // namespace ledAction | 
 | 1523 |  | 
| Patrick Williams | f944d2e | 2022-07-22 19:26:52 -0500 | [diff] [blame] | 1524 | int8_t getLEDState(sdbusplus::bus_t& bus, const std::string& intf, | 
| Kuiying Wang | 45f0498 | 2018-12-26 09:23:08 +0800 | [diff] [blame] | 1525 |                    const std::string& objPath, uint8_t& state) | 
 | 1526 | { | 
 | 1527 |     try | 
 | 1528 |     { | 
 | 1529 |         std::string service = getService(bus, intf, objPath); | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 1530 |         Value stateValue = getDbusProperty(bus, service, objPath, intf, | 
 | 1531 |                                            "State"); | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 1532 |         std::string strState = std::get<std::string>(stateValue); | 
| Kuiying Wang | 45f0498 | 2018-12-26 09:23:08 +0800 | [diff] [blame] | 1533 |         state = ledAction::actionDbusToIpmi.at( | 
 | 1534 |             sdbusplus::xyz::openbmc_project::Led::server::Physical:: | 
 | 1535 |                 convertActionFromString(strState)); | 
 | 1536 |     } | 
| Patrick Williams | f944d2e | 2022-07-22 19:26:52 -0500 | [diff] [blame] | 1537 |     catch (const sdbusplus::exception_t& e) | 
| Kuiying Wang | 45f0498 | 2018-12-26 09:23:08 +0800 | [diff] [blame] | 1538 |     { | 
 | 1539 |         phosphor::logging::log<phosphor::logging::level::ERR>(e.what()); | 
 | 1540 |         return -1; | 
 | 1541 |     } | 
 | 1542 |     return 0; | 
 | 1543 | } | 
 | 1544 |  | 
| NITIN SHARMA | abd11ca | 2019-06-12 12:31:42 +0000 | [diff] [blame] | 1545 | ipmi::RspType<uint8_t> ipmiOEMGetLEDStatus() | 
| Kuiying Wang | 45f0498 | 2018-12-26 09:23:08 +0800 | [diff] [blame] | 1546 | { | 
| NITIN SHARMA | abd11ca | 2019-06-12 12:31:42 +0000 | [diff] [blame] | 1547 |     uint8_t ledstate = 0; | 
| Kuiying Wang | 45f0498 | 2018-12-26 09:23:08 +0800 | [diff] [blame] | 1548 |     phosphor::logging::log<phosphor::logging::level::DEBUG>("GET led status"); | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1549 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| Kuiying Wang | 45f0498 | 2018-12-26 09:23:08 +0800 | [diff] [blame] | 1550 |     for (auto it = ledAction::offsetObjPath.begin(); | 
 | 1551 |          it != ledAction::offsetObjPath.end(); ++it) | 
 | 1552 |     { | 
 | 1553 |         uint8_t state = 0; | 
| NITIN SHARMA | abd11ca | 2019-06-12 12:31:42 +0000 | [diff] [blame] | 1554 |         if (getLEDState(*dbus, ledIntf, it->second, state) == -1) | 
| Kuiying Wang | 45f0498 | 2018-12-26 09:23:08 +0800 | [diff] [blame] | 1555 |         { | 
 | 1556 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1557 |                 "oem_get_led_status: fail to get ID LED status!"); | 
| NITIN SHARMA | abd11ca | 2019-06-12 12:31:42 +0000 | [diff] [blame] | 1558 |             return ipmi::responseUnspecifiedError(); | 
| Kuiying Wang | 45f0498 | 2018-12-26 09:23:08 +0800 | [diff] [blame] | 1559 |         } | 
| NITIN SHARMA | abd11ca | 2019-06-12 12:31:42 +0000 | [diff] [blame] | 1560 |         ledstate |= state << it->first; | 
| Kuiying Wang | 45f0498 | 2018-12-26 09:23:08 +0800 | [diff] [blame] | 1561 |     } | 
| NITIN SHARMA | abd11ca | 2019-06-12 12:31:42 +0000 | [diff] [blame] | 1562 |     return ipmi::responseSuccess(ledstate); | 
| Kuiying Wang | 45f0498 | 2018-12-26 09:23:08 +0800 | [diff] [blame] | 1563 | } | 
 | 1564 |  | 
| Yong Li | 23737fe | 2019-02-19 08:49:55 +0800 | [diff] [blame] | 1565 | ipmi_ret_t ipmiOEMCfgHostSerialPortSpeed(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
 | 1566 |                                          ipmi_request_t request, | 
 | 1567 |                                          ipmi_response_t response, | 
 | 1568 |                                          ipmi_data_len_t dataLen, | 
 | 1569 |                                          ipmi_context_t context) | 
 | 1570 | { | 
 | 1571 |     CfgHostSerialReq* req = reinterpret_cast<CfgHostSerialReq*>(request); | 
 | 1572 |     uint8_t* resp = reinterpret_cast<uint8_t*>(response); | 
 | 1573 |  | 
 | 1574 |     if (*dataLen == 0) | 
 | 1575 |     { | 
 | 1576 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1577 |             "CfgHostSerial: invalid input len!", | 
 | 1578 |             phosphor::logging::entry("LEN=%d", *dataLen)); | 
 | 1579 |         return IPMI_CC_REQ_DATA_LEN_INVALID; | 
 | 1580 |     } | 
 | 1581 |  | 
 | 1582 |     switch (req->command) | 
 | 1583 |     { | 
 | 1584 |         case getHostSerialCfgCmd: | 
 | 1585 |         { | 
 | 1586 |             if (*dataLen != 1) | 
 | 1587 |             { | 
 | 1588 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1589 |                     "CfgHostSerial: invalid input len!"); | 
 | 1590 |                 *dataLen = 0; | 
 | 1591 |                 return IPMI_CC_REQ_DATA_LEN_INVALID; | 
 | 1592 |             } | 
 | 1593 |  | 
 | 1594 |             *dataLen = 0; | 
 | 1595 |  | 
 | 1596 |             boost::process::ipstream is; | 
 | 1597 |             std::vector<std::string> data; | 
 | 1598 |             std::string line; | 
 | 1599 |             boost::process::child c1(fwGetEnvCmd, "-n", fwHostSerailCfgEnvName, | 
 | 1600 |                                      boost::process::std_out > is); | 
 | 1601 |  | 
 | 1602 |             while (c1.running() && std::getline(is, line) && !line.empty()) | 
 | 1603 |             { | 
 | 1604 |                 data.push_back(line); | 
 | 1605 |             } | 
 | 1606 |  | 
 | 1607 |             c1.wait(); | 
 | 1608 |             if (c1.exit_code()) | 
 | 1609 |             { | 
 | 1610 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1611 |                     "CfgHostSerial:: error on execute", | 
 | 1612 |                     phosphor::logging::entry("EXECUTE=%s", fwSetEnvCmd)); | 
 | 1613 |                 // Using the default value | 
 | 1614 |                 *resp = 0; | 
 | 1615 |             } | 
 | 1616 |             else | 
 | 1617 |             { | 
 | 1618 |                 if (data.size() != 1) | 
 | 1619 |                 { | 
 | 1620 |                     phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1621 |                         "CfgHostSerial:: error on read env"); | 
 | 1622 |                     return IPMI_CC_UNSPECIFIED_ERROR; | 
 | 1623 |                 } | 
 | 1624 |                 try | 
 | 1625 |                 { | 
 | 1626 |                     unsigned long tmp = std::stoul(data[0]); | 
 | 1627 |                     if (tmp > std::numeric_limits<uint8_t>::max()) | 
 | 1628 |                     { | 
 | 1629 |                         throw std::out_of_range("Out of range"); | 
 | 1630 |                     } | 
 | 1631 |                     *resp = static_cast<uint8_t>(tmp); | 
 | 1632 |                 } | 
 | 1633 |                 catch (const std::invalid_argument& e) | 
 | 1634 |                 { | 
 | 1635 |                     phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1636 |                         "invalid config ", | 
 | 1637 |                         phosphor::logging::entry("ERR=%s", e.what())); | 
 | 1638 |                     return IPMI_CC_UNSPECIFIED_ERROR; | 
 | 1639 |                 } | 
 | 1640 |                 catch (const std::out_of_range& e) | 
 | 1641 |                 { | 
 | 1642 |                     phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1643 |                         "out_of_range config ", | 
 | 1644 |                         phosphor::logging::entry("ERR=%s", e.what())); | 
 | 1645 |                     return IPMI_CC_UNSPECIFIED_ERROR; | 
 | 1646 |                 } | 
 | 1647 |             } | 
 | 1648 |  | 
 | 1649 |             *dataLen = 1; | 
 | 1650 |             break; | 
 | 1651 |         } | 
 | 1652 |         case setHostSerialCfgCmd: | 
 | 1653 |         { | 
 | 1654 |             if (*dataLen != sizeof(CfgHostSerialReq)) | 
 | 1655 |             { | 
 | 1656 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1657 |                     "CfgHostSerial: invalid input len!"); | 
 | 1658 |                 *dataLen = 0; | 
 | 1659 |                 return IPMI_CC_REQ_DATA_LEN_INVALID; | 
 | 1660 |             } | 
 | 1661 |  | 
 | 1662 |             *dataLen = 0; | 
 | 1663 |  | 
 | 1664 |             if (req->parameter > HostSerialCfgParamMax) | 
 | 1665 |             { | 
 | 1666 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1667 |                     "CfgHostSerial: invalid input!"); | 
 | 1668 |                 return IPMI_CC_INVALID_FIELD_REQUEST; | 
 | 1669 |             } | 
 | 1670 |  | 
 | 1671 |             boost::process::child c1(fwSetEnvCmd, fwHostSerailCfgEnvName, | 
 | 1672 |                                      std::to_string(req->parameter)); | 
 | 1673 |  | 
 | 1674 |             c1.wait(); | 
 | 1675 |             if (c1.exit_code()) | 
 | 1676 |             { | 
 | 1677 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1678 |                     "CfgHostSerial:: error on execute", | 
 | 1679 |                     phosphor::logging::entry("EXECUTE=%s", fwGetEnvCmd)); | 
 | 1680 |                 return IPMI_CC_UNSPECIFIED_ERROR; | 
 | 1681 |             } | 
 | 1682 |             break; | 
 | 1683 |         } | 
 | 1684 |         default: | 
 | 1685 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1686 |                 "CfgHostSerial: invalid input!"); | 
 | 1687 |             *dataLen = 0; | 
 | 1688 |             return IPMI_CC_INVALID_FIELD_REQUEST; | 
 | 1689 |     } | 
 | 1690 |  | 
 | 1691 |     return IPMI_CC_OK; | 
 | 1692 | } | 
 | 1693 |  | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1694 | constexpr const char* thermalModeInterface = | 
 | 1695 |     "xyz.openbmc_project.Control.ThermalMode"; | 
 | 1696 | constexpr const char* thermalModePath = | 
 | 1697 |     "/xyz/openbmc_project/control/thermal_mode"; | 
 | 1698 |  | 
 | 1699 | bool getFanProfileInterface( | 
| Patrick Williams | f944d2e | 2022-07-22 19:26:52 -0500 | [diff] [blame] | 1700 |     sdbusplus::bus_t& bus, | 
| Jason M. Bills | 0748c69 | 2022-09-08 15:34:08 -0700 | [diff] [blame] | 1701 |     boost::container::flat_map<std::string, ipmi::DbusVariant>& resp) | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1702 | { | 
 | 1703 |     auto call = bus.new_method_call(settingsBusName, thermalModePath, PROP_INTF, | 
 | 1704 |                                     "GetAll"); | 
 | 1705 |     call.append(thermalModeInterface); | 
 | 1706 |     try | 
 | 1707 |     { | 
 | 1708 |         auto data = bus.call(call); | 
 | 1709 |         data.read(resp); | 
 | 1710 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 1711 |     catch (const sdbusplus::exception_t& e) | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1712 |     { | 
 | 1713 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1714 |             "getFanProfileInterface: can't get thermal mode!", | 
 | 1715 |             phosphor::logging::entry("ERR=%s", e.what())); | 
 | 1716 |         return false; | 
 | 1717 |     } | 
 | 1718 |     return true; | 
 | 1719 | } | 
 | 1720 |  | 
| anil kumar appana | f945eee | 2019-09-25 23:29:11 +0000 | [diff] [blame] | 1721 | /**@brief implements the OEM set fan config. | 
 | 1722 |  * @param selectedFanProfile - fan profile to enable | 
 | 1723 |  * @param reserved1 | 
 | 1724 |  * @param performanceMode - Performance/Acoustic mode | 
 | 1725 |  * @param reserved2 | 
 | 1726 |  * @param setPerformanceMode - set Performance/Acoustic mode | 
 | 1727 |  * @param setFanProfile - set fan profile | 
 | 1728 |  * | 
 | 1729 |  * @return IPMI completion code. | 
 | 1730 |  **/ | 
 | 1731 | ipmi::RspType<> ipmiOEMSetFanConfig(uint8_t selectedFanProfile, | 
 | 1732 |  | 
 | 1733 |                                     uint2_t reserved1, bool performanceMode, | 
 | 1734 |                                     uint3_t reserved2, bool setPerformanceMode, | 
| Joshi-Mansi | 619186d | 2020-01-27 19:16:03 +0530 | [diff] [blame] | 1735 |                                     bool setFanProfile, | 
 | 1736 |                                     std::optional<uint8_t> dimmGroupId, | 
 | 1737 |                                     std::optional<uint32_t> dimmPresenceBitmap) | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1738 | { | 
| anil kumar appana | f945eee | 2019-09-25 23:29:11 +0000 | [diff] [blame] | 1739 |     if (reserved1 || reserved2) | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1740 |     { | 
| anil kumar appana | f945eee | 2019-09-25 23:29:11 +0000 | [diff] [blame] | 1741 |         return ipmi::responseInvalidFieldRequest(); | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1742 |     } | 
| Joshi-Mansi | 619186d | 2020-01-27 19:16:03 +0530 | [diff] [blame] | 1743 |  | 
 | 1744 |     if (dimmGroupId) | 
 | 1745 |     { | 
 | 1746 |         if (*dimmGroupId >= maxCPUNum) | 
 | 1747 |         { | 
 | 1748 |             return ipmi::responseInvalidFieldRequest(); | 
 | 1749 |         } | 
| Snehalatha Venkatesh | 6224dec | 2023-01-24 11:28:53 +0000 | [diff] [blame] | 1750 |         if (!cpuPresent("cpu" + std::to_string(*dimmGroupId))) | 
| Joshi-Mansi | 619186d | 2020-01-27 19:16:03 +0530 | [diff] [blame] | 1751 |         { | 
 | 1752 |             return ipmi::responseInvalidFieldRequest(); | 
 | 1753 |         } | 
 | 1754 |     } | 
 | 1755 |  | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1756 |     // todo: tell bios to only send first 2 bytes | 
| Jason M. Bills | 0748c69 | 2022-09-08 15:34:08 -0700 | [diff] [blame] | 1757 |     boost::container::flat_map<std::string, ipmi::DbusVariant> profileData; | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1758 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
 | 1759 |     if (!getFanProfileInterface(*dbus, profileData)) | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1760 |     { | 
| anil kumar appana | f945eee | 2019-09-25 23:29:11 +0000 | [diff] [blame] | 1761 |         return ipmi::responseUnspecifiedError(); | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1762 |     } | 
 | 1763 |  | 
 | 1764 |     std::vector<std::string>* supported = | 
 | 1765 |         std::get_if<std::vector<std::string>>(&profileData["Supported"]); | 
 | 1766 |     if (supported == nullptr) | 
 | 1767 |     { | 
| anil kumar appana | f945eee | 2019-09-25 23:29:11 +0000 | [diff] [blame] | 1768 |         return ipmi::responseInvalidFieldRequest(); | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1769 |     } | 
 | 1770 |     std::string mode; | 
| anil kumar appana | f945eee | 2019-09-25 23:29:11 +0000 | [diff] [blame] | 1771 |     if (setPerformanceMode) | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1772 |     { | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1773 |         if (performanceMode) | 
 | 1774 |         { | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1775 |             if (std::find(supported->begin(), supported->end(), | 
 | 1776 |                           "Performance") != supported->end()) | 
 | 1777 |             { | 
 | 1778 |                 mode = "Performance"; | 
 | 1779 |             } | 
 | 1780 |         } | 
 | 1781 |         else | 
 | 1782 |         { | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1783 |             if (std::find(supported->begin(), supported->end(), "Acoustic") != | 
 | 1784 |                 supported->end()) | 
 | 1785 |             { | 
 | 1786 |                 mode = "Acoustic"; | 
 | 1787 |             } | 
 | 1788 |         } | 
 | 1789 |         if (mode.empty()) | 
 | 1790 |         { | 
| anil kumar appana | f945eee | 2019-09-25 23:29:11 +0000 | [diff] [blame] | 1791 |             return ipmi::responseInvalidFieldRequest(); | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1792 |         } | 
| anil kumar appana | f945eee | 2019-09-25 23:29:11 +0000 | [diff] [blame] | 1793 |  | 
 | 1794 |         try | 
 | 1795 |         { | 
 | 1796 |             setDbusProperty(*dbus, settingsBusName, thermalModePath, | 
 | 1797 |                             thermalModeInterface, "Current", mode); | 
 | 1798 |         } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 1799 |         catch (const sdbusplus::exception_t& e) | 
| anil kumar appana | f945eee | 2019-09-25 23:29:11 +0000 | [diff] [blame] | 1800 |         { | 
 | 1801 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1802 |                 "ipmiOEMSetFanConfig: can't set thermal mode!", | 
 | 1803 |                 phosphor::logging::entry("EXCEPTION=%s", e.what())); | 
 | 1804 |             return ipmi::responseResponseError(); | 
 | 1805 |         } | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1806 |     } | 
 | 1807 |  | 
| anil kumar appana | f945eee | 2019-09-25 23:29:11 +0000 | [diff] [blame] | 1808 |     return ipmi::responseSuccess(); | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1809 | } | 
 | 1810 |  | 
| James Feist | 5b69363 | 2019-07-09 09:06:09 -0700 | [diff] [blame] | 1811 | ipmi::RspType<uint8_t, // profile support map | 
 | 1812 |               uint8_t, // fan control profile enable | 
 | 1813 |               uint8_t, // flags | 
 | 1814 |               uint32_t // dimm presence bit map | 
 | 1815 |               > | 
 | 1816 |     ipmiOEMGetFanConfig(uint8_t dimmGroupId) | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1817 | { | 
| Joshi-Mansi | 36f05ce | 2020-01-14 14:29:34 +0530 | [diff] [blame] | 1818 |     if (dimmGroupId >= maxCPUNum) | 
 | 1819 |     { | 
 | 1820 |         return ipmi::responseInvalidFieldRequest(); | 
 | 1821 |     } | 
 | 1822 |  | 
| Snehalatha Venkatesh | 6224dec | 2023-01-24 11:28:53 +0000 | [diff] [blame] | 1823 |     bool cpuStatus = cpuPresent("cpu" + std::to_string(dimmGroupId)); | 
| Joshi-Mansi | 36f05ce | 2020-01-14 14:29:34 +0530 | [diff] [blame] | 1824 |  | 
 | 1825 |     if (!cpuStatus) | 
 | 1826 |     { | 
 | 1827 |         return ipmi::responseInvalidFieldRequest(); | 
 | 1828 |     } | 
 | 1829 |  | 
| Jason M. Bills | 0748c69 | 2022-09-08 15:34:08 -0700 | [diff] [blame] | 1830 |     boost::container::flat_map<std::string, ipmi::DbusVariant> profileData; | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1831 |  | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1832 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
 | 1833 |     if (!getFanProfileInterface(*dbus, profileData)) | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1834 |     { | 
| James Feist | 5b69363 | 2019-07-09 09:06:09 -0700 | [diff] [blame] | 1835 |         return ipmi::responseResponseError(); | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1836 |     } | 
 | 1837 |  | 
 | 1838 |     std::string* current = std::get_if<std::string>(&profileData["Current"]); | 
 | 1839 |  | 
 | 1840 |     if (current == nullptr) | 
 | 1841 |     { | 
 | 1842 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1843 |             "ipmiOEMGetFanConfig: can't get current mode!"); | 
| James Feist | 5b69363 | 2019-07-09 09:06:09 -0700 | [diff] [blame] | 1844 |         return ipmi::responseResponseError(); | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1845 |     } | 
 | 1846 |     bool performance = (*current == "Performance"); | 
 | 1847 |  | 
| James Feist | 5b69363 | 2019-07-09 09:06:09 -0700 | [diff] [blame] | 1848 |     uint8_t flags = 0; | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1849 |     if (performance) | 
 | 1850 |     { | 
| James Feist | 5b69363 | 2019-07-09 09:06:09 -0700 | [diff] [blame] | 1851 |         flags |= 1 << 2; | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1852 |     } | 
 | 1853 |  | 
| jayaprakash Mutyala | 4b1552d | 2020-02-11 12:07:29 +0000 | [diff] [blame] | 1854 |     constexpr uint8_t fanControlDefaultProfile = 0x80; | 
 | 1855 |     constexpr uint8_t fanControlProfileState = 0x00; | 
 | 1856 |     constexpr uint32_t dimmPresenceBitmap = 0x00; | 
 | 1857 |  | 
 | 1858 |     return ipmi::responseSuccess(fanControlDefaultProfile, | 
 | 1859 |                                  fanControlProfileState, flags, | 
 | 1860 |                                  dimmPresenceBitmap); | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 1861 | } | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 1862 | constexpr const char* cfmLimitSettingPath = | 
 | 1863 |     "/xyz/openbmc_project/control/cfm_limit"; | 
 | 1864 | constexpr const char* cfmLimitIface = "xyz.openbmc_project.Control.CFMLimit"; | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 1865 | constexpr const size_t legacyExitAirSensorNumber = 0x2e; | 
| James Feist | 09f6b60 | 2019-08-08 11:30:03 -0700 | [diff] [blame] | 1866 | constexpr const size_t legacyPCHSensorNumber = 0x22; | 
 | 1867 | constexpr const char* exitAirPathName = "Exit_Air"; | 
 | 1868 | constexpr const char* pchPathName = "SSB_Temp"; | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 1869 | constexpr const char* pidConfigurationIface = | 
 | 1870 |     "xyz.openbmc_project.Configuration.Pid"; | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 1871 |  | 
| James Feist | 09f6b60 | 2019-08-08 11:30:03 -0700 | [diff] [blame] | 1872 | static std::string getConfigPath(const std::string& name) | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 1873 | { | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1874 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 1875 |     auto method = dbus->new_method_call("xyz.openbmc_project.ObjectMapper", | 
 | 1876 |                                         "/xyz/openbmc_project/object_mapper", | 
 | 1877 |                                         "xyz.openbmc_project.ObjectMapper", | 
 | 1878 |                                         "GetSubTree"); | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 1879 |  | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 1880 |     method.append("/", 0, std::array<const char*, 1>{pidConfigurationIface}); | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 1881 |     std::string path; | 
 | 1882 |     GetSubTreeType resp; | 
 | 1883 |     try | 
 | 1884 |     { | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1885 |         auto reply = dbus->call(method); | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 1886 |         reply.read(resp); | 
 | 1887 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 1888 |     catch (const sdbusplus::exception_t&) | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 1889 |     { | 
 | 1890 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1891 |             "ipmiOEMGetFscParameter: mapper error"); | 
 | 1892 |     }; | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 1893 |     auto config = std::find_if(resp.begin(), resp.end(), | 
 | 1894 |                                [&name](const auto& pair) { | 
 | 1895 |         return pair.first.find(name) != std::string::npos; | 
 | 1896 |     }); | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 1897 |     if (config != resp.end()) | 
 | 1898 |     { | 
 | 1899 |         path = std::move(config->first); | 
 | 1900 |     } | 
 | 1901 |     return path; | 
 | 1902 | } | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 1903 |  | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 1904 | // flat map to make alphabetical | 
 | 1905 | static boost::container::flat_map<std::string, PropertyMap> getPidConfigs() | 
 | 1906 | { | 
 | 1907 |     boost::container::flat_map<std::string, PropertyMap> ret; | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1908 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 1909 |     auto method = dbus->new_method_call("xyz.openbmc_project.ObjectMapper", | 
 | 1910 |                                         "/xyz/openbmc_project/object_mapper", | 
 | 1911 |                                         "xyz.openbmc_project.ObjectMapper", | 
 | 1912 |                                         "GetSubTree"); | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 1913 |  | 
 | 1914 |     method.append("/", 0, std::array<const char*, 1>{pidConfigurationIface}); | 
 | 1915 |     GetSubTreeType resp; | 
 | 1916 |  | 
 | 1917 |     try | 
 | 1918 |     { | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1919 |         auto reply = dbus->call(method); | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 1920 |         reply.read(resp); | 
 | 1921 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 1922 |     catch (const sdbusplus::exception_t&) | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 1923 |     { | 
 | 1924 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1925 |             "getFanConfigPaths: mapper error"); | 
 | 1926 |     }; | 
 | 1927 |     for (const auto& [path, objects] : resp) | 
 | 1928 |     { | 
 | 1929 |         if (objects.empty()) | 
 | 1930 |         { | 
 | 1931 |             continue; // should be impossible | 
 | 1932 |         } | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 1933 |  | 
 | 1934 |         try | 
 | 1935 |         { | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 1936 |             ret.emplace(path, | 
 | 1937 |                         getAllDbusProperties(*dbus, objects[0].first, path, | 
 | 1938 |                                              pidConfigurationIface)); | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 1939 |         } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 1940 |         catch (const sdbusplus::exception_t& e) | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 1941 |         { | 
 | 1942 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1943 |                 "getPidConfigs: can't get DbusProperties!", | 
 | 1944 |                 phosphor::logging::entry("ERR=%s", e.what())); | 
 | 1945 |         } | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 1946 |     } | 
 | 1947 |     return ret; | 
 | 1948 | } | 
 | 1949 |  | 
 | 1950 | ipmi::RspType<uint8_t> ipmiOEMGetFanSpeedOffset(void) | 
 | 1951 | { | 
 | 1952 |     boost::container::flat_map<std::string, PropertyMap> data = getPidConfigs(); | 
 | 1953 |     if (data.empty()) | 
 | 1954 |     { | 
 | 1955 |         return ipmi::responseResponseError(); | 
 | 1956 |     } | 
 | 1957 |     uint8_t minOffset = std::numeric_limits<uint8_t>::max(); | 
 | 1958 |     for (const auto& [_, pid] : data) | 
 | 1959 |     { | 
 | 1960 |         auto findClass = pid.find("Class"); | 
 | 1961 |         if (findClass == pid.end()) | 
 | 1962 |         { | 
 | 1963 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1964 |                 "ipmiOEMGetFscParameter: found illegal pid " | 
 | 1965 |                 "configurations"); | 
 | 1966 |             return ipmi::responseResponseError(); | 
 | 1967 |         } | 
 | 1968 |         std::string type = std::get<std::string>(findClass->second); | 
 | 1969 |         if (type == "fan") | 
 | 1970 |         { | 
 | 1971 |             auto findOutLimit = pid.find("OutLimitMin"); | 
 | 1972 |             if (findOutLimit == pid.end()) | 
 | 1973 |             { | 
 | 1974 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1975 |                     "ipmiOEMGetFscParameter: found illegal pid " | 
 | 1976 |                     "configurations"); | 
 | 1977 |                 return ipmi::responseResponseError(); | 
 | 1978 |             } | 
 | 1979 |             // get the min out of all the offsets | 
 | 1980 |             minOffset = std::min( | 
 | 1981 |                 minOffset, | 
 | 1982 |                 static_cast<uint8_t>(std::get<double>(findOutLimit->second))); | 
 | 1983 |         } | 
 | 1984 |     } | 
 | 1985 |     if (minOffset == std::numeric_limits<uint8_t>::max()) | 
 | 1986 |     { | 
 | 1987 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1988 |             "ipmiOEMGetFscParameter: found no fan configurations!"); | 
 | 1989 |         return ipmi::responseResponseError(); | 
 | 1990 |     } | 
 | 1991 |  | 
 | 1992 |     return ipmi::responseSuccess(minOffset); | 
 | 1993 | } | 
 | 1994 |  | 
 | 1995 | ipmi::RspType<> ipmiOEMSetFanSpeedOffset(uint8_t offset) | 
 | 1996 | { | 
| Manish Baing | baa579f | 2021-10-08 22:30:32 +0000 | [diff] [blame] | 1997 |     constexpr uint8_t maxFanSpeedOffset = 100; | 
 | 1998 |     if (offset > maxFanSpeedOffset) | 
 | 1999 |     { | 
 | 2000 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2001 |             "ipmiOEMSetFanSpeedOffset: fan offset greater than limit"); | 
 | 2002 |         return ipmi::responseInvalidFieldRequest(); | 
 | 2003 |     } | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2004 |     boost::container::flat_map<std::string, PropertyMap> data = getPidConfigs(); | 
 | 2005 |     if (data.empty()) | 
 | 2006 |     { | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2007 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2008 |             "ipmiOEMSetFanSpeedOffset: found no pid configurations!"); | 
 | 2009 |         return ipmi::responseResponseError(); | 
 | 2010 |     } | 
 | 2011 |  | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 2012 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2013 |     bool found = false; | 
 | 2014 |     for (const auto& [path, pid] : data) | 
 | 2015 |     { | 
 | 2016 |         auto findClass = pid.find("Class"); | 
 | 2017 |         if (findClass == pid.end()) | 
 | 2018 |         { | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2019 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2020 |                 "ipmiOEMSetFanSpeedOffset: found illegal pid " | 
 | 2021 |                 "configurations"); | 
 | 2022 |             return ipmi::responseResponseError(); | 
 | 2023 |         } | 
 | 2024 |         std::string type = std::get<std::string>(findClass->second); | 
 | 2025 |         if (type == "fan") | 
 | 2026 |         { | 
 | 2027 |             auto findOutLimit = pid.find("OutLimitMin"); | 
 | 2028 |             if (findOutLimit == pid.end()) | 
 | 2029 |             { | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2030 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2031 |                     "ipmiOEMSetFanSpeedOffset: found illegal pid " | 
 | 2032 |                     "configurations"); | 
 | 2033 |                 return ipmi::responseResponseError(); | 
 | 2034 |             } | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 2035 |             ipmi::setDbusProperty(*dbus, "xyz.openbmc_project.EntityManager", | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2036 |                                   path, pidConfigurationIface, "OutLimitMin", | 
 | 2037 |                                   static_cast<double>(offset)); | 
 | 2038 |             found = true; | 
 | 2039 |         } | 
 | 2040 |     } | 
 | 2041 |     if (!found) | 
 | 2042 |     { | 
 | 2043 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2044 |             "ipmiOEMSetFanSpeedOffset: set no fan offsets"); | 
 | 2045 |         return ipmi::responseResponseError(); | 
 | 2046 |     } | 
 | 2047 |  | 
 | 2048 |     return ipmi::responseSuccess(); | 
 | 2049 | } | 
 | 2050 |  | 
 | 2051 | ipmi::RspType<> ipmiOEMSetFscParameter(uint8_t command, uint8_t param1, | 
 | 2052 |                                        uint8_t param2) | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2053 | { | 
 | 2054 |     constexpr const size_t disableLimiting = 0x0; | 
 | 2055 |  | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 2056 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2057 |     if (command == static_cast<uint8_t>(setFscParamFlags::tcontrol)) | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2058 |     { | 
| James Feist | 09f6b60 | 2019-08-08 11:30:03 -0700 | [diff] [blame] | 2059 |         std::string pathName; | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2060 |         if (param1 == legacyExitAirSensorNumber) | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 2061 |         { | 
| James Feist | 09f6b60 | 2019-08-08 11:30:03 -0700 | [diff] [blame] | 2062 |             pathName = exitAirPathName; | 
 | 2063 |         } | 
 | 2064 |         else if (param1 == legacyPCHSensorNumber) | 
 | 2065 |         { | 
 | 2066 |             pathName = pchPathName; | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 2067 |         } | 
 | 2068 |         else | 
 | 2069 |         { | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2070 |             return ipmi::responseParmOutOfRange(); | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 2071 |         } | 
| James Feist | 09f6b60 | 2019-08-08 11:30:03 -0700 | [diff] [blame] | 2072 |         std::string path = getConfigPath(pathName); | 
 | 2073 |         ipmi::setDbusProperty(*dbus, "xyz.openbmc_project.EntityManager", path, | 
 | 2074 |                               pidConfigurationIface, "SetPoint", | 
 | 2075 |                               static_cast<double>(param2)); | 
 | 2076 |         return ipmi::responseSuccess(); | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 2077 |     } | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2078 |     else if (command == static_cast<uint8_t>(setFscParamFlags::cfm)) | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2079 |     { | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2080 |         uint16_t cfm = param1 | (static_cast<uint16_t>(param2) << 8); | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2081 |  | 
 | 2082 |         // must be greater than 50 based on eps | 
 | 2083 |         if (cfm < 50 && cfm != disableLimiting) | 
 | 2084 |         { | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2085 |             return ipmi::responseParmOutOfRange(); | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2086 |         } | 
 | 2087 |  | 
 | 2088 |         try | 
 | 2089 |         { | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 2090 |             ipmi::setDbusProperty(*dbus, settingsBusName, cfmLimitSettingPath, | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2091 |                                   cfmLimitIface, "Limit", | 
 | 2092 |                                   static_cast<double>(cfm)); | 
 | 2093 |         } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 2094 |         catch (const sdbusplus::exception_t& e) | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2095 |         { | 
 | 2096 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2097 |                 "ipmiOEMSetFscParameter: can't set cfm setting!", | 
 | 2098 |                 phosphor::logging::entry("ERR=%s", e.what())); | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2099 |             return ipmi::responseResponseError(); | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2100 |         } | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2101 |         return ipmi::responseSuccess(); | 
 | 2102 |     } | 
 | 2103 |     else if (command == static_cast<uint8_t>(setFscParamFlags::maxPwm)) | 
 | 2104 |     { | 
 | 2105 |         constexpr const size_t maxDomainCount = 8; | 
 | 2106 |         uint8_t requestedDomainMask = param1; | 
 | 2107 |         boost::container::flat_map data = getPidConfigs(); | 
 | 2108 |         if (data.empty()) | 
 | 2109 |         { | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2110 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2111 |                 "ipmiOEMSetFscParameter: found no pid configurations!"); | 
 | 2112 |             return ipmi::responseResponseError(); | 
 | 2113 |         } | 
 | 2114 |         size_t count = 0; | 
 | 2115 |         for (const auto& [path, pid] : data) | 
 | 2116 |         { | 
 | 2117 |             auto findClass = pid.find("Class"); | 
 | 2118 |             if (findClass == pid.end()) | 
 | 2119 |             { | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2120 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2121 |                     "ipmiOEMSetFscParameter: found illegal pid " | 
 | 2122 |                     "configurations"); | 
 | 2123 |                 return ipmi::responseResponseError(); | 
 | 2124 |             } | 
 | 2125 |             std::string type = std::get<std::string>(findClass->second); | 
 | 2126 |             if (type == "fan") | 
 | 2127 |             { | 
 | 2128 |                 if (requestedDomainMask & (1 << count)) | 
 | 2129 |                 { | 
 | 2130 |                     ipmi::setDbusProperty( | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 2131 |                         *dbus, "xyz.openbmc_project.EntityManager", path, | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2132 |                         pidConfigurationIface, "OutLimitMax", | 
 | 2133 |                         static_cast<double>(param2)); | 
 | 2134 |                 } | 
 | 2135 |                 count++; | 
 | 2136 |             } | 
 | 2137 |         } | 
 | 2138 |         return ipmi::responseSuccess(); | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2139 |     } | 
 | 2140 |     else | 
 | 2141 |     { | 
 | 2142 |         // todo other command parts possibly | 
 | 2143 |         // tcontrol is handled in peci now | 
 | 2144 |         // fan speed offset not implemented yet | 
 | 2145 |         // domain pwm limit not implemented | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2146 |         return ipmi::responseParmOutOfRange(); | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2147 |     } | 
 | 2148 | } | 
 | 2149 |  | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2150 | ipmi::RspType< | 
 | 2151 |     std::variant<uint8_t, std::array<uint8_t, 2>, std::array<uint16_t, 2>>> | 
 | 2152 |     ipmiOEMGetFscParameter(uint8_t command, std::optional<uint8_t> param) | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2153 | { | 
| James Feist | 09f6b60 | 2019-08-08 11:30:03 -0700 | [diff] [blame] | 2154 |     constexpr uint8_t legacyDefaultSetpoint = -128; | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2155 |  | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 2156 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2157 |     if (command == static_cast<uint8_t>(setFscParamFlags::tcontrol)) | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2158 |     { | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2159 |         if (!param) | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 2160 |         { | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2161 |             return ipmi::responseReqDataLenInvalid(); | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 2162 |         } | 
 | 2163 |  | 
| James Feist | 09f6b60 | 2019-08-08 11:30:03 -0700 | [diff] [blame] | 2164 |         std::string pathName; | 
 | 2165 |  | 
 | 2166 |         if (*param == legacyExitAirSensorNumber) | 
 | 2167 |         { | 
 | 2168 |             pathName = exitAirPathName; | 
 | 2169 |         } | 
 | 2170 |         else if (*param == legacyPCHSensorNumber) | 
 | 2171 |         { | 
 | 2172 |             pathName = pchPathName; | 
 | 2173 |         } | 
 | 2174 |         else | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 2175 |         { | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2176 |             return ipmi::responseParmOutOfRange(); | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 2177 |         } | 
| James Feist | 09f6b60 | 2019-08-08 11:30:03 -0700 | [diff] [blame] | 2178 |  | 
 | 2179 |         uint8_t setpoint = legacyDefaultSetpoint; | 
 | 2180 |         std::string path = getConfigPath(pathName); | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 2181 |         if (path.size()) | 
 | 2182 |         { | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 2183 |             Value val = ipmi::getDbusProperty( | 
 | 2184 |                 *dbus, "xyz.openbmc_project.EntityManager", path, | 
 | 2185 |                 pidConfigurationIface, "SetPoint"); | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 2186 |             setpoint = std::floor(std::get<double>(val) + 0.5); | 
 | 2187 |         } | 
 | 2188 |  | 
 | 2189 |         // old implementation used to return the "default" and current, we | 
 | 2190 |         // don't make the default readily available so just make both the | 
 | 2191 |         // same | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 2192 |  | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2193 |         return ipmi::responseSuccess( | 
 | 2194 |             std::array<uint8_t, 2>{setpoint, setpoint}); | 
| James Feist | faa4f22 | 2019-03-21 16:21:55 -0700 | [diff] [blame] | 2195 |     } | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2196 |     else if (command == static_cast<uint8_t>(setFscParamFlags::maxPwm)) | 
 | 2197 |     { | 
 | 2198 |         constexpr const size_t maxDomainCount = 8; | 
 | 2199 |  | 
 | 2200 |         if (!param) | 
 | 2201 |         { | 
 | 2202 |             return ipmi::responseReqDataLenInvalid(); | 
 | 2203 |         } | 
 | 2204 |         uint8_t requestedDomain = *param; | 
 | 2205 |         if (requestedDomain >= maxDomainCount) | 
 | 2206 |         { | 
 | 2207 |             return ipmi::responseInvalidFieldRequest(); | 
 | 2208 |         } | 
 | 2209 |  | 
 | 2210 |         boost::container::flat_map data = getPidConfigs(); | 
 | 2211 |         if (data.empty()) | 
 | 2212 |         { | 
 | 2213 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2214 |                 "ipmiOEMGetFscParameter: found no pid configurations!"); | 
 | 2215 |             return ipmi::responseResponseError(); | 
 | 2216 |         } | 
 | 2217 |         size_t count = 0; | 
 | 2218 |         for (const auto& [_, pid] : data) | 
 | 2219 |         { | 
 | 2220 |             auto findClass = pid.find("Class"); | 
 | 2221 |             if (findClass == pid.end()) | 
 | 2222 |             { | 
 | 2223 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2224 |                     "ipmiOEMGetFscParameter: found illegal pid " | 
 | 2225 |                     "configurations"); | 
 | 2226 |                 return ipmi::responseResponseError(); | 
 | 2227 |             } | 
 | 2228 |             std::string type = std::get<std::string>(findClass->second); | 
 | 2229 |             if (type == "fan") | 
 | 2230 |             { | 
 | 2231 |                 if (requestedDomain == count) | 
 | 2232 |                 { | 
 | 2233 |                     auto findOutLimit = pid.find("OutLimitMax"); | 
 | 2234 |                     if (findOutLimit == pid.end()) | 
 | 2235 |                     { | 
 | 2236 |                         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2237 |                             "ipmiOEMGetFscParameter: found illegal pid " | 
 | 2238 |                             "configurations"); | 
 | 2239 |                         return ipmi::responseResponseError(); | 
 | 2240 |                     } | 
 | 2241 |  | 
 | 2242 |                     return ipmi::responseSuccess( | 
 | 2243 |                         static_cast<uint8_t>(std::floor( | 
 | 2244 |                             std::get<double>(findOutLimit->second) + 0.5))); | 
 | 2245 |                 } | 
 | 2246 |                 else | 
 | 2247 |                 { | 
 | 2248 |                     count++; | 
 | 2249 |                 } | 
 | 2250 |             } | 
 | 2251 |         } | 
 | 2252 |  | 
 | 2253 |         return ipmi::responseInvalidFieldRequest(); | 
 | 2254 |     } | 
 | 2255 |     else if (command == static_cast<uint8_t>(setFscParamFlags::cfm)) | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2256 |     { | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2257 |         /* | 
 | 2258 |         DataLen should be 1, but host is sending us an extra bit. As the | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2259 |         previous behavior didn't seem to prevent this, ignore the check for | 
 | 2260 |         now. | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2261 |  | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2262 |         if (param) | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2263 |         { | 
 | 2264 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2265 |                 "ipmiOEMGetFscParameter: invalid input len!"); | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2266 |             return IPMI_CC_REQ_DATA_LEN_INVALID; | 
 | 2267 |         } | 
 | 2268 |         */ | 
 | 2269 |         Value cfmLimit; | 
 | 2270 |         Value cfmMaximum; | 
 | 2271 |         try | 
 | 2272 |         { | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 2273 |             cfmLimit = ipmi::getDbusProperty(*dbus, settingsBusName, | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2274 |                                              cfmLimitSettingPath, cfmLimitIface, | 
 | 2275 |                                              "Limit"); | 
 | 2276 |             cfmMaximum = ipmi::getDbusProperty( | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 2277 |                 *dbus, "xyz.openbmc_project.ExitAirTempSensor", | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2278 |                 "/xyz/openbmc_project/control/MaxCFM", cfmLimitIface, "Limit"); | 
 | 2279 |         } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 2280 |         catch (const sdbusplus::exception_t& e) | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2281 |         { | 
 | 2282 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2283 |                 "ipmiOEMGetFscParameter: can't get cfm setting!", | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2284 |                 phosphor::logging::entry("ERR=%s", e.what())); | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2285 |             return ipmi::responseResponseError(); | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2286 |         } | 
 | 2287 |  | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2288 |         double cfmMax = std::get<double>(cfmMaximum); | 
 | 2289 |         double cfmLim = std::get<double>(cfmLimit); | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2290 |  | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2291 |         cfmLim = std::floor(cfmLim + 0.5); | 
 | 2292 |         cfmMax = std::floor(cfmMax + 0.5); | 
 | 2293 |         uint16_t cfmLimResp = static_cast<uint16_t>(cfmLim); | 
 | 2294 |         uint16_t cfmMaxResp = static_cast<uint16_t>(cfmMax); | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2295 |  | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2296 |         return ipmi::responseSuccess( | 
 | 2297 |             std::array<uint16_t, 2>{cfmLimResp, cfmMaxResp}); | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2298 |     } | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2299 |  | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2300 |     else | 
 | 2301 |     { | 
 | 2302 |         // todo other command parts possibly | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2303 |         // domain pwm limit not implemented | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 2304 |         return ipmi::responseParmOutOfRange(); | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 2305 |     } | 
 | 2306 | } | 
 | 2307 |  | 
| Jason M. Bills | 0748c69 | 2022-09-08 15:34:08 -0700 | [diff] [blame] | 2308 | using crConfigVariant = ipmi::DbusVariant; | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2309 |  | 
 | 2310 | int setCRConfig(ipmi::Context::ptr ctx, const std::string& property, | 
 | 2311 |                 const crConfigVariant& value, | 
 | 2312 |                 std::chrono::microseconds timeout = ipmi::IPMI_DBUS_TIMEOUT) | 
 | 2313 | { | 
 | 2314 |     boost::system::error_code ec; | 
 | 2315 |     ctx->bus->yield_method_call<void>( | 
| Kuiying Wang | e45333a | 2020-07-22 22:06:37 +0800 | [diff] [blame] | 2316 |         ctx->yield, ec, "xyz.openbmc_project.PSURedundancy", | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2317 |         "/xyz/openbmc_project/control/power_supply_redundancy", | 
 | 2318 |         "org.freedesktop.DBus.Properties", "Set", | 
 | 2319 |         "xyz.openbmc_project.Control.PowerSupplyRedundancy", property, value); | 
 | 2320 |     if (ec) | 
 | 2321 |     { | 
 | 2322 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2323 |             "Failed to set dbus property to cold redundancy"); | 
 | 2324 |         return -1; | 
 | 2325 |     } | 
 | 2326 |  | 
 | 2327 |     return 0; | 
 | 2328 | } | 
 | 2329 |  | 
| Kuiying Wang | e45333a | 2020-07-22 22:06:37 +0800 | [diff] [blame] | 2330 | int getCRConfig( | 
 | 2331 |     ipmi::Context::ptr ctx, const std::string& property, crConfigVariant& value, | 
 | 2332 |     const std::string& service = "xyz.openbmc_project.PSURedundancy", | 
 | 2333 |     std::chrono::microseconds timeout = ipmi::IPMI_DBUS_TIMEOUT) | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2334 | { | 
 | 2335 |     boost::system::error_code ec; | 
 | 2336 |     value = ctx->bus->yield_method_call<crConfigVariant>( | 
| Yong Li | 19445ab | 2019-12-20 18:25:29 +0800 | [diff] [blame] | 2337 |         ctx->yield, ec, service, | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2338 |         "/xyz/openbmc_project/control/power_supply_redundancy", | 
 | 2339 |         "org.freedesktop.DBus.Properties", "Get", | 
 | 2340 |         "xyz.openbmc_project.Control.PowerSupplyRedundancy", property); | 
 | 2341 |     if (ec) | 
 | 2342 |     { | 
 | 2343 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2344 |             "Failed to get dbus property to cold redundancy"); | 
 | 2345 |         return -1; | 
 | 2346 |     } | 
 | 2347 |     return 0; | 
 | 2348 | } | 
 | 2349 |  | 
 | 2350 | uint8_t getPSUCount(void) | 
 | 2351 | { | 
 | 2352 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
 | 2353 |     ipmi::Value num; | 
 | 2354 |     try | 
 | 2355 |     { | 
 | 2356 |         num = ipmi::getDbusProperty( | 
 | 2357 |             *dbus, "xyz.openbmc_project.PSURedundancy", | 
 | 2358 |             "/xyz/openbmc_project/control/power_supply_redundancy", | 
 | 2359 |             "xyz.openbmc_project.Control.PowerSupplyRedundancy", "PSUNumber"); | 
 | 2360 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 2361 |     catch (const sdbusplus::exception_t& e) | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2362 |     { | 
 | 2363 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2364 |             "Failed to get PSUNumber property from dbus interface"); | 
 | 2365 |         return 0; | 
 | 2366 |     } | 
 | 2367 |     uint8_t* pNum = std::get_if<uint8_t>(&num); | 
 | 2368 |     if (!pNum) | 
 | 2369 |     { | 
 | 2370 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2371 |             "Error to get PSU Number"); | 
 | 2372 |         return 0; | 
 | 2373 |     } | 
 | 2374 |     return *pNum; | 
 | 2375 | } | 
 | 2376 |  | 
 | 2377 | bool validateCRAlgo(std::vector<uint8_t>& conf, uint8_t num) | 
 | 2378 | { | 
 | 2379 |     if (conf.size() < num) | 
 | 2380 |     { | 
 | 2381 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2382 |             "Invalid PSU Ranking"); | 
 | 2383 |         return false; | 
 | 2384 |     } | 
 | 2385 |     std::set<uint8_t> confSet; | 
 | 2386 |     for (uint8_t i = 0; i < num; i++) | 
 | 2387 |     { | 
 | 2388 |         if (conf[i] > num) | 
 | 2389 |         { | 
 | 2390 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2391 |                 "PSU Ranking is larger than current PSU number"); | 
 | 2392 |             return false; | 
 | 2393 |         } | 
 | 2394 |         confSet.emplace(conf[i]); | 
 | 2395 |     } | 
 | 2396 |  | 
 | 2397 |     if (confSet.size() != num) | 
 | 2398 |     { | 
 | 2399 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2400 |             "duplicate PSU Ranking"); | 
 | 2401 |         return false; | 
 | 2402 |     } | 
 | 2403 |     return true; | 
 | 2404 | } | 
 | 2405 |  | 
 | 2406 | enum class crParameter | 
 | 2407 | { | 
 | 2408 |     crStatus = 0, | 
 | 2409 |     crFeature = 1, | 
 | 2410 |     rotationFeature = 2, | 
 | 2411 |     rotationAlgo = 3, | 
 | 2412 |     rotationPeriod = 4, | 
| Yong Li | 19445ab | 2019-12-20 18:25:29 +0800 | [diff] [blame] | 2413 |     numOfPSU = 5, | 
 | 2414 |     rotationRankOrderEffective = 6 | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2415 | }; | 
 | 2416 |  | 
 | 2417 | constexpr ipmi::Cc ccParameterNotSupported = 0x80; | 
 | 2418 | static const constexpr uint32_t oneDay = 0x15180; | 
 | 2419 | static const constexpr uint32_t oneMonth = 0xf53700; | 
 | 2420 | static const constexpr uint8_t userSpecific = 0x01; | 
 | 2421 | static const constexpr uint8_t crSetCompleted = 0; | 
 | 2422 | ipmi::RspType<uint8_t> ipmiOEMSetCRConfig(ipmi::Context::ptr ctx, | 
 | 2423 |                                           uint8_t parameter, | 
 | 2424 |                                           ipmi::message::Payload& payload) | 
 | 2425 | { | 
 | 2426 |     switch (static_cast<crParameter>(parameter)) | 
 | 2427 |     { | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2428 |         case crParameter::rotationFeature: | 
 | 2429 |         { | 
 | 2430 |             uint8_t param1; | 
 | 2431 |             if (payload.unpack(param1) || !payload.fullyUnpacked()) | 
 | 2432 |             { | 
 | 2433 |                 return ipmi::responseReqDataLenInvalid(); | 
 | 2434 |             } | 
 | 2435 |             // Rotation Enable can only be true or false | 
 | 2436 |             if (param1 > 1) | 
 | 2437 |             { | 
 | 2438 |                 return ipmi::responseInvalidFieldRequest(); | 
 | 2439 |             } | 
 | 2440 |             if (setCRConfig(ctx, "RotationEnabled", static_cast<bool>(param1))) | 
 | 2441 |             { | 
 | 2442 |                 return ipmi::responseResponseError(); | 
 | 2443 |             } | 
 | 2444 |             break; | 
 | 2445 |         } | 
 | 2446 |         case crParameter::rotationAlgo: | 
 | 2447 |         { | 
 | 2448 |             // Rotation Algorithm can only be 0-BMC Specific or 1-User Specific | 
 | 2449 |             std::string algoName; | 
 | 2450 |             uint8_t param1; | 
 | 2451 |             if (payload.unpack(param1)) | 
 | 2452 |             { | 
 | 2453 |                 return ipmi::responseReqDataLenInvalid(); | 
 | 2454 |             } | 
 | 2455 |             switch (param1) | 
 | 2456 |             { | 
 | 2457 |                 case 0: | 
 | 2458 |                     algoName = "xyz.openbmc_project.Control." | 
 | 2459 |                                "PowerSupplyRedundancy.Algo.bmcSpecific"; | 
 | 2460 |                     break; | 
 | 2461 |                 case 1: | 
 | 2462 |                     algoName = "xyz.openbmc_project.Control." | 
 | 2463 |                                "PowerSupplyRedundancy.Algo.userSpecific"; | 
 | 2464 |                     break; | 
 | 2465 |                 default: | 
 | 2466 |                     return ipmi::responseInvalidFieldRequest(); | 
 | 2467 |             } | 
 | 2468 |             if (setCRConfig(ctx, "RotationAlgorithm", algoName)) | 
 | 2469 |             { | 
 | 2470 |                 return ipmi::responseResponseError(); | 
 | 2471 |             } | 
 | 2472 |  | 
 | 2473 |             uint8_t numberOfPSU = getPSUCount(); | 
 | 2474 |             if (!numberOfPSU) | 
 | 2475 |             { | 
 | 2476 |                 return ipmi::responseResponseError(); | 
 | 2477 |             } | 
 | 2478 |             std::vector<uint8_t> rankOrder; | 
 | 2479 |  | 
 | 2480 |             if (param1 == userSpecific) | 
 | 2481 |             { | 
 | 2482 |                 if (payload.unpack(rankOrder) || !payload.fullyUnpacked()) | 
 | 2483 |                 { | 
 | 2484 |                     ipmi::responseReqDataLenInvalid(); | 
 | 2485 |                 } | 
| Yong Li | 8331513 | 2019-10-23 17:42:24 +0800 | [diff] [blame] | 2486 |                 if (rankOrder.size() != numberOfPSU) | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2487 |                 { | 
 | 2488 |                     return ipmi::responseReqDataLenInvalid(); | 
 | 2489 |                 } | 
 | 2490 |  | 
 | 2491 |                 if (!validateCRAlgo(rankOrder, numberOfPSU)) | 
 | 2492 |                 { | 
 | 2493 |                     return ipmi::responseInvalidFieldRequest(); | 
 | 2494 |                 } | 
 | 2495 |             } | 
 | 2496 |             else | 
 | 2497 |             { | 
 | 2498 |                 if (rankOrder.size() > 0) | 
 | 2499 |                 { | 
 | 2500 |                     return ipmi::responseReqDataLenInvalid(); | 
 | 2501 |                 } | 
 | 2502 |                 for (uint8_t i = 1; i <= numberOfPSU; i++) | 
 | 2503 |                 { | 
 | 2504 |                     rankOrder.emplace_back(i); | 
 | 2505 |                 } | 
 | 2506 |             } | 
 | 2507 |             if (setCRConfig(ctx, "RotationRankOrder", rankOrder)) | 
 | 2508 |             { | 
 | 2509 |                 return ipmi::responseResponseError(); | 
 | 2510 |             } | 
 | 2511 |             break; | 
 | 2512 |         } | 
 | 2513 |         case crParameter::rotationPeriod: | 
 | 2514 |         { | 
 | 2515 |             // Minimum Rotation period is  One day (86400 seconds) and Max | 
 | 2516 |             // Rotation Period is 6 month (0xf53700 seconds) | 
 | 2517 |             uint32_t period; | 
 | 2518 |             if (payload.unpack(period) || !payload.fullyUnpacked()) | 
 | 2519 |             { | 
 | 2520 |                 return ipmi::responseReqDataLenInvalid(); | 
 | 2521 |             } | 
 | 2522 |             if ((period < oneDay) || (period > oneMonth)) | 
 | 2523 |             { | 
 | 2524 |                 return ipmi::responseInvalidFieldRequest(); | 
 | 2525 |             } | 
 | 2526 |             if (setCRConfig(ctx, "PeriodOfRotation", period)) | 
 | 2527 |             { | 
 | 2528 |                 return ipmi::responseResponseError(); | 
 | 2529 |             } | 
 | 2530 |             break; | 
 | 2531 |         } | 
 | 2532 |         default: | 
 | 2533 |         { | 
 | 2534 |             return ipmi::response(ccParameterNotSupported); | 
 | 2535 |         } | 
 | 2536 |     } | 
 | 2537 |  | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2538 |     return ipmi::responseSuccess(crSetCompleted); | 
 | 2539 | } | 
 | 2540 |  | 
| Yong Li | 8331513 | 2019-10-23 17:42:24 +0800 | [diff] [blame] | 2541 | ipmi::RspType<uint8_t, std::variant<uint8_t, uint32_t, std::vector<uint8_t>>> | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2542 |     ipmiOEMGetCRConfig(ipmi::Context::ptr ctx, uint8_t parameter) | 
 | 2543 | { | 
 | 2544 |     crConfigVariant value; | 
 | 2545 |     switch (static_cast<crParameter>(parameter)) | 
 | 2546 |     { | 
 | 2547 |         case crParameter::crStatus: | 
 | 2548 |         { | 
 | 2549 |             if (getCRConfig(ctx, "ColdRedundancyStatus", value)) | 
 | 2550 |             { | 
 | 2551 |                 return ipmi::responseResponseError(); | 
 | 2552 |             } | 
 | 2553 |             std::string* pStatus = std::get_if<std::string>(&value); | 
 | 2554 |             if (!pStatus) | 
 | 2555 |             { | 
 | 2556 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2557 |                     "Error to get ColdRedundancyStatus property"); | 
 | 2558 |                 return ipmi::responseResponseError(); | 
 | 2559 |             } | 
 | 2560 |             namespace server = sdbusplus::xyz::openbmc_project::Control::server; | 
 | 2561 |             auto status = | 
 | 2562 |                 server::PowerSupplyRedundancy::convertStatusFromString( | 
 | 2563 |                     *pStatus); | 
 | 2564 |             switch (status) | 
 | 2565 |             { | 
 | 2566 |                 case server::PowerSupplyRedundancy::Status::inProgress: | 
| Cheng C Yang | f41e334 | 2019-09-10 04:47:23 +0800 | [diff] [blame] | 2567 |                     return ipmi::responseSuccess(parameter, | 
| Kuiying Wang | e45333a | 2020-07-22 22:06:37 +0800 | [diff] [blame] | 2568 |                                                  static_cast<uint8_t>(1)); | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2569 |  | 
 | 2570 |                 case server::PowerSupplyRedundancy::Status::completed: | 
| Cheng C Yang | f41e334 | 2019-09-10 04:47:23 +0800 | [diff] [blame] | 2571 |                     return ipmi::responseSuccess(parameter, | 
| Kuiying Wang | e45333a | 2020-07-22 22:06:37 +0800 | [diff] [blame] | 2572 |                                                  static_cast<uint8_t>(0)); | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2573 |                 default: | 
 | 2574 |                     phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2575 |                         "Error to get valid status"); | 
 | 2576 |                     return ipmi::responseResponseError(); | 
 | 2577 |             } | 
 | 2578 |         } | 
 | 2579 |         case crParameter::crFeature: | 
 | 2580 |         { | 
| Kuiying Wang | e45333a | 2020-07-22 22:06:37 +0800 | [diff] [blame] | 2581 |             if (getCRConfig(ctx, "PowerSupplyRedundancyEnabled", value)) | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2582 |             { | 
 | 2583 |                 return ipmi::responseResponseError(); | 
 | 2584 |             } | 
 | 2585 |             bool* pResponse = std::get_if<bool>(&value); | 
 | 2586 |             if (!pResponse) | 
 | 2587 |             { | 
 | 2588 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
| Kuiying Wang | e45333a | 2020-07-22 22:06:37 +0800 | [diff] [blame] | 2589 |                     "Error to get PowerSupplyRedundancyEnabled property"); | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2590 |                 return ipmi::responseResponseError(); | 
 | 2591 |             } | 
 | 2592 |  | 
| Cheng C Yang | f41e334 | 2019-09-10 04:47:23 +0800 | [diff] [blame] | 2593 |             return ipmi::responseSuccess(parameter, | 
 | 2594 |                                          static_cast<uint8_t>(*pResponse)); | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2595 |         } | 
 | 2596 |         case crParameter::rotationFeature: | 
 | 2597 |         { | 
 | 2598 |             if (getCRConfig(ctx, "RotationEnabled", value)) | 
 | 2599 |             { | 
 | 2600 |                 return ipmi::responseResponseError(); | 
 | 2601 |             } | 
 | 2602 |             bool* pResponse = std::get_if<bool>(&value); | 
 | 2603 |             if (!pResponse) | 
 | 2604 |             { | 
 | 2605 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2606 |                     "Error to get RotationEnabled property"); | 
 | 2607 |                 return ipmi::responseResponseError(); | 
 | 2608 |             } | 
| Cheng C Yang | f41e334 | 2019-09-10 04:47:23 +0800 | [diff] [blame] | 2609 |             return ipmi::responseSuccess(parameter, | 
 | 2610 |                                          static_cast<uint8_t>(*pResponse)); | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2611 |         } | 
 | 2612 |         case crParameter::rotationAlgo: | 
 | 2613 |         { | 
 | 2614 |             if (getCRConfig(ctx, "RotationAlgorithm", value)) | 
 | 2615 |             { | 
 | 2616 |                 return ipmi::responseResponseError(); | 
 | 2617 |             } | 
 | 2618 |  | 
 | 2619 |             std::string* pAlgo = std::get_if<std::string>(&value); | 
 | 2620 |             if (!pAlgo) | 
 | 2621 |             { | 
 | 2622 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2623 |                     "Error to get RotationAlgorithm property"); | 
 | 2624 |                 return ipmi::responseResponseError(); | 
 | 2625 |             } | 
| Yong Li | 8331513 | 2019-10-23 17:42:24 +0800 | [diff] [blame] | 2626 |             std::vector<uint8_t> response; | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2627 |             namespace server = sdbusplus::xyz::openbmc_project::Control::server; | 
 | 2628 |             auto algo = | 
 | 2629 |                 server::PowerSupplyRedundancy::convertAlgoFromString(*pAlgo); | 
| Yong Li | 8331513 | 2019-10-23 17:42:24 +0800 | [diff] [blame] | 2630 |  | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2631 |             switch (algo) | 
 | 2632 |             { | 
 | 2633 |                 case server::PowerSupplyRedundancy::Algo::bmcSpecific: | 
| Yong Li | 8331513 | 2019-10-23 17:42:24 +0800 | [diff] [blame] | 2634 |                     response.push_back(0); | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2635 |                     break; | 
 | 2636 |                 case server::PowerSupplyRedundancy::Algo::userSpecific: | 
| Yong Li | 8331513 | 2019-10-23 17:42:24 +0800 | [diff] [blame] | 2637 |                     response.push_back(1); | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2638 |                     break; | 
 | 2639 |                 default: | 
 | 2640 |                     phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2641 |                         "Error to get valid algo"); | 
 | 2642 |                     return ipmi::responseResponseError(); | 
 | 2643 |             } | 
 | 2644 |  | 
 | 2645 |             if (getCRConfig(ctx, "RotationRankOrder", value)) | 
 | 2646 |             { | 
 | 2647 |                 return ipmi::responseResponseError(); | 
 | 2648 |             } | 
 | 2649 |             std::vector<uint8_t>* pResponse = | 
 | 2650 |                 std::get_if<std::vector<uint8_t>>(&value); | 
 | 2651 |             if (!pResponse) | 
 | 2652 |             { | 
 | 2653 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2654 |                     "Error to get RotationRankOrder property"); | 
 | 2655 |                 return ipmi::responseResponseError(); | 
 | 2656 |             } | 
| Yong Li | 8331513 | 2019-10-23 17:42:24 +0800 | [diff] [blame] | 2657 |  | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2658 |             std::copy(pResponse->begin(), pResponse->end(), | 
| Yong Li | 8331513 | 2019-10-23 17:42:24 +0800 | [diff] [blame] | 2659 |                       std::back_inserter(response)); | 
 | 2660 |  | 
| Cheng C Yang | f41e334 | 2019-09-10 04:47:23 +0800 | [diff] [blame] | 2661 |             return ipmi::responseSuccess(parameter, response); | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2662 |         } | 
 | 2663 |         case crParameter::rotationPeriod: | 
 | 2664 |         { | 
 | 2665 |             if (getCRConfig(ctx, "PeriodOfRotation", value)) | 
 | 2666 |             { | 
 | 2667 |                 return ipmi::responseResponseError(); | 
 | 2668 |             } | 
 | 2669 |             uint32_t* pResponse = std::get_if<uint32_t>(&value); | 
 | 2670 |             if (!pResponse) | 
 | 2671 |             { | 
 | 2672 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2673 |                     "Error to get RotationAlgorithm property"); | 
 | 2674 |                 return ipmi::responseResponseError(); | 
 | 2675 |             } | 
| Cheng C Yang | f41e334 | 2019-09-10 04:47:23 +0800 | [diff] [blame] | 2676 |             return ipmi::responseSuccess(parameter, *pResponse); | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2677 |         } | 
 | 2678 |         case crParameter::numOfPSU: | 
 | 2679 |         { | 
 | 2680 |             uint8_t numberOfPSU = getPSUCount(); | 
 | 2681 |             if (!numberOfPSU) | 
 | 2682 |             { | 
 | 2683 |                 return ipmi::responseResponseError(); | 
 | 2684 |             } | 
| Cheng C Yang | f41e334 | 2019-09-10 04:47:23 +0800 | [diff] [blame] | 2685 |             return ipmi::responseSuccess(parameter, numberOfPSU); | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2686 |         } | 
| Yong Li | 19445ab | 2019-12-20 18:25:29 +0800 | [diff] [blame] | 2687 |         case crParameter::rotationRankOrderEffective: | 
 | 2688 |         { | 
 | 2689 |             if (getCRConfig(ctx, "RotationRankOrder", value, | 
 | 2690 |                             "xyz.openbmc_project.PSURedundancy")) | 
 | 2691 |             { | 
 | 2692 |                 return ipmi::responseResponseError(); | 
 | 2693 |             } | 
 | 2694 |             std::vector<uint8_t>* pResponse = | 
 | 2695 |                 std::get_if<std::vector<uint8_t>>(&value); | 
 | 2696 |             if (!pResponse) | 
 | 2697 |             { | 
 | 2698 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2699 |                     "Error to get effective RotationRankOrder property"); | 
 | 2700 |                 return ipmi::responseResponseError(); | 
 | 2701 |             } | 
 | 2702 |             return ipmi::responseSuccess(parameter, *pResponse); | 
 | 2703 |         } | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 2704 |         default: | 
 | 2705 |         { | 
 | 2706 |             return ipmi::response(ccParameterNotSupported); | 
 | 2707 |         } | 
 | 2708 |     } | 
 | 2709 | } | 
 | 2710 |  | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2711 | ipmi::RspType<> ipmiOEMSetFaultIndication(uint8_t sourceId, uint8_t faultType, | 
 | 2712 |                                           uint8_t faultState, | 
 | 2713 |                                           uint8_t faultGroup, | 
 | 2714 |                                           std::array<uint8_t, 8>& ledStateData) | 
 | 2715 | { | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2716 |     constexpr auto maxFaultType = static_cast<size_t>(RemoteFaultType::max); | 
 | 2717 |     static const std::array<std::string, maxFaultType> faultNames = { | 
 | 2718 |         "faultFan",       "faultTemp",     "faultPower", | 
 | 2719 |         "faultDriveSlot", "faultSoftware", "faultMemory"}; | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2720 |  | 
 | 2721 |     constexpr uint8_t maxFaultSource = 0x4; | 
 | 2722 |     constexpr uint8_t skipLEDs = 0xFF; | 
 | 2723 |     constexpr uint8_t pinSize = 64; | 
 | 2724 |     constexpr uint8_t groupSize = 16; | 
| Zhikui Ren | ce4e73f | 2019-12-06 13:59:47 -0800 | [diff] [blame] | 2725 |     constexpr uint8_t groupNum = 5; // 4 for fault memory, 1 for faultFan | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2726 |  | 
| Zhikui Ren | ce4e73f | 2019-12-06 13:59:47 -0800 | [diff] [blame] | 2727 |     // same pin names need to be defined in dts file | 
 | 2728 |     static const std::array<std::array<std::string, groupSize>, groupNum> | 
 | 2729 |         faultLedPinNames = {{ | 
 | 2730 |             "LED_CPU1_CH1_DIMM1_FAULT", | 
 | 2731 |             "LED_CPU1_CH1_DIMM2_FAULT", | 
 | 2732 |             "LED_CPU1_CH2_DIMM1_FAULT", | 
 | 2733 |             "LED_CPU1_CH2_DIMM2_FAULT", | 
 | 2734 |             "LED_CPU1_CH3_DIMM1_FAULT", | 
 | 2735 |             "LED_CPU1_CH3_DIMM2_FAULT", | 
 | 2736 |             "LED_CPU1_CH4_DIMM1_FAULT", | 
 | 2737 |             "LED_CPU1_CH4_DIMM2_FAULT", | 
 | 2738 |             "LED_CPU1_CH5_DIMM1_FAULT", | 
 | 2739 |             "LED_CPU1_CH5_DIMM2_FAULT", | 
 | 2740 |             "LED_CPU1_CH6_DIMM1_FAULT", | 
 | 2741 |             "LED_CPU1_CH6_DIMM2_FAULT", | 
 | 2742 |             "", | 
 | 2743 |             "", | 
 | 2744 |             "", | 
 | 2745 |             "", // end of group1 | 
 | 2746 |             "LED_CPU2_CH1_DIMM1_FAULT", | 
 | 2747 |             "LED_CPU2_CH1_DIMM2_FAULT", | 
 | 2748 |             "LED_CPU2_CH2_DIMM1_FAULT", | 
 | 2749 |             "LED_CPU2_CH2_DIMM2_FAULT", | 
 | 2750 |             "LED_CPU2_CH3_DIMM1_FAULT", | 
 | 2751 |             "LED_CPU2_CH3_DIMM2_FAULT", | 
 | 2752 |             "LED_CPU2_CH4_DIMM1_FAULT", | 
 | 2753 |             "LED_CPU2_CH4_DIMM2_FAULT", | 
 | 2754 |             "LED_CPU2_CH5_DIMM1_FAULT", | 
 | 2755 |             "LED_CPU2_CH5_DIMM2_FAULT", | 
 | 2756 |             "LED_CPU2_CH6_DIMM1_FAULT", | 
 | 2757 |             "LED_CPU2_CH6_DIMM2_FAULT", | 
 | 2758 |             "", | 
 | 2759 |             "", | 
 | 2760 |             "", | 
 | 2761 |             "", // endof group2 | 
 | 2762 |             "LED_CPU3_CH1_DIMM1_FAULT", | 
 | 2763 |             "LED_CPU3_CH1_DIMM2_FAULT", | 
 | 2764 |             "LED_CPU3_CH2_DIMM1_FAULT", | 
 | 2765 |             "LED_CPU3_CH2_DIMM2_FAULT", | 
 | 2766 |             "LED_CPU3_CH3_DIMM1_FAULT", | 
 | 2767 |             "LED_CPU3_CH3_DIMM2_FAULT", | 
 | 2768 |             "LED_CPU3_CH4_DIMM1_FAULT", | 
 | 2769 |             "LED_CPU3_CH4_DIMM2_FAULT", | 
 | 2770 |             "LED_CPU3_CH5_DIMM1_FAULT", | 
 | 2771 |             "LED_CPU3_CH5_DIMM2_FAULT", | 
 | 2772 |             "LED_CPU3_CH6_DIMM1_FAULT", | 
 | 2773 |             "LED_CPU3_CH6_DIMM2_FAULT", | 
 | 2774 |             "", | 
 | 2775 |             "", | 
 | 2776 |             "", | 
 | 2777 |             "", // end of group3 | 
 | 2778 |             "LED_CPU4_CH1_DIMM1_FAULT", | 
 | 2779 |             "LED_CPU4_CH1_DIMM2_FAULT", | 
 | 2780 |             "LED_CPU4_CH2_DIMM1_FAULT", | 
 | 2781 |             "LED_CPU4_CH2_DIMM2_FAULT", | 
 | 2782 |             "LED_CPU4_CH3_DIMM1_FAULT", | 
 | 2783 |             "LED_CPU4_CH3_DIMM2_FAULT", | 
 | 2784 |             "LED_CPU4_CH4_DIMM1_FAULT", | 
 | 2785 |             "LED_CPU4_CH4_DIMM2_FAULT", | 
 | 2786 |             "LED_CPU4_CH5_DIMM1_FAULT", | 
 | 2787 |             "LED_CPU4_CH5_DIMM2_FAULT", | 
 | 2788 |             "LED_CPU4_CH6_DIMM1_FAULT", | 
 | 2789 |             "LED_CPU4_CH6_DIMM2_FAULT", | 
 | 2790 |             "", | 
 | 2791 |             "", | 
 | 2792 |             "", | 
 | 2793 |             "", // end of group4 | 
 | 2794 |             "LED_FAN1_FAULT", | 
 | 2795 |             "LED_FAN2_FAULT", | 
 | 2796 |             "LED_FAN3_FAULT", | 
 | 2797 |             "LED_FAN4_FAULT", | 
 | 2798 |             "LED_FAN5_FAULT", | 
 | 2799 |             "LED_FAN6_FAULT", | 
 | 2800 |             "LED_FAN7_FAULT", | 
 | 2801 |             "LED_FAN8_FAULT", | 
 | 2802 |             "", | 
 | 2803 |             "", | 
 | 2804 |             "", | 
 | 2805 |             "", | 
 | 2806 |             "", | 
 | 2807 |             "", | 
 | 2808 |             "", | 
 | 2809 |             "" // end of group5 | 
 | 2810 |         }}; | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2811 |  | 
| Zhikui Ren | ce4e73f | 2019-12-06 13:59:47 -0800 | [diff] [blame] | 2812 |     // Validate the source, fault type -- | 
 | 2813 |     // (Byte 1) sourceId: Unspecified, Hot-Swap Controller 0, Hot-Swap | 
 | 2814 |     // Controller 1, BIOS (Byte 2) fault type: fan, temperature, power, | 
 | 2815 |     // driveslot, software, memory (Byte 3) FaultState: OK, Degraded, | 
 | 2816 |     // Non-Critical, Critical, Non-Recoverable, (Byte 4) is faultGroup, | 
 | 2817 |     // definition differs based on fault type (Byte 2) | 
 | 2818 |     //          Type Fan=> Group: 0=FanGroupID, FF-not used | 
 | 2819 |     //                  Byte 5-11 00h, not used | 
 | 2820 |     //                  Byte12 FanLedState [7:0]-Fans 7:0 | 
 | 2821 |     //          Type Memory=> Group: 0 = DIMM GroupID, FF-not used | 
 | 2822 |     //                  Byte 5:12 - DIMM LED state (64bit field, LS Byte first) | 
 | 2823 |     //                  [63:48] = CPU4 channels 7:0, 2 bits per channel | 
 | 2824 |     //                  [47:32] = CPU3 channels 7:0, 2 bits per channel | 
 | 2825 |     //                  [31:16] = CPU2 channels 7:0, 2 bits per channel | 
 | 2826 |     //                  [15:0] =  CPU1 channels 7:0, 2 bits per channel | 
 | 2827 |     //          Type Other=> Component Fault LED Group ID, not used set to 0xFF | 
 | 2828 |     //                  Byte[5:12]: reserved 0x00h | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2829 |     if ((sourceId >= maxFaultSource) || | 
 | 2830 |         (faultType >= static_cast<int8_t>(RemoteFaultType::max)) || | 
 | 2831 |         (faultState >= static_cast<int8_t>(RemoteFaultState::maxFaultState)) || | 
 | 2832 |         (faultGroup >= static_cast<int8_t>(DimmFaultType::maxFaultGroup))) | 
 | 2833 |     { | 
 | 2834 |         return ipmi::responseParmOutOfRange(); | 
 | 2835 |     } | 
 | 2836 |  | 
| Zhikui Ren | ce4e73f | 2019-12-06 13:59:47 -0800 | [diff] [blame] | 2837 |     size_t pinGroupOffset = 0; | 
 | 2838 |     size_t pinGroupMax = pinSize / groupSize; | 
 | 2839 |     if (RemoteFaultType::fan == RemoteFaultType(faultType)) | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2840 |     { | 
| Zhikui Ren | ce4e73f | 2019-12-06 13:59:47 -0800 | [diff] [blame] | 2841 |         pinGroupOffset = 4; | 
 | 2842 |         pinGroupMax = groupNum - pinSize / groupSize; | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2843 |     } | 
 | 2844 |  | 
 | 2845 |     switch (RemoteFaultType(faultType)) | 
 | 2846 |     { | 
 | 2847 |         case (RemoteFaultType::fan): | 
 | 2848 |         case (RemoteFaultType::memory): | 
 | 2849 |         { | 
 | 2850 |             if (faultGroup == skipLEDs) | 
 | 2851 |             { | 
 | 2852 |                 return ipmi::responseSuccess(); | 
 | 2853 |             } | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2854 |             // calculate led state bit filed count, each byte has 8bits | 
 | 2855 |             // the maximum bits will be 8 * 8 bits | 
 | 2856 |             constexpr uint8_t size = sizeof(ledStateData) * 8; | 
| Zhikui Ren | ce4e73f | 2019-12-06 13:59:47 -0800 | [diff] [blame] | 2857 |  | 
 | 2858 |             // assemble ledState | 
 | 2859 |             uint64_t ledState = 0; | 
 | 2860 |             bool hasError = false; | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2861 |             for (int i = 0; i < sizeof(ledStateData); i++) | 
 | 2862 |             { | 
 | 2863 |                 ledState = (uint64_t)(ledState << 8); | 
 | 2864 |                 ledState = (uint64_t)(ledState | (uint64_t)ledStateData[i]); | 
 | 2865 |             } | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2866 |             std::bitset<size> ledStateBits(ledState); | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2867 |  | 
| Zhikui Ren | ce4e73f | 2019-12-06 13:59:47 -0800 | [diff] [blame] | 2868 |             for (int group = 0; group < pinGroupMax; group++) | 
 | 2869 |             { | 
 | 2870 |                 for (int i = 0; i < groupSize; i++) | 
 | 2871 |                 { // skip non-existing pins | 
 | 2872 |                     if (0 == faultLedPinNames[group + pinGroupOffset][i].size()) | 
 | 2873 |                     { | 
 | 2874 |                         continue; | 
 | 2875 |                     } | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2876 |  | 
| Zhikui Ren | ce4e73f | 2019-12-06 13:59:47 -0800 | [diff] [blame] | 2877 |                     gpiod::line line = gpiod::find_line( | 
 | 2878 |                         faultLedPinNames[group + pinGroupOffset][i]); | 
 | 2879 |                     if (!line) | 
 | 2880 |                     { | 
 | 2881 |                         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2882 |                             "Not Find Led Gpio Device!", | 
 | 2883 |                             phosphor::logging::entry( | 
 | 2884 |                                 "DEVICE=%s", | 
 | 2885 |                                 faultLedPinNames[group + pinGroupOffset][i] | 
 | 2886 |                                     .c_str())); | 
 | 2887 |                         hasError = true; | 
 | 2888 |                         continue; | 
 | 2889 |                     } | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2890 |  | 
| Zhikui Ren | ce4e73f | 2019-12-06 13:59:47 -0800 | [diff] [blame] | 2891 |                     bool activeHigh = | 
 | 2892 |                         (line.active_state() == gpiod::line::ACTIVE_HIGH); | 
 | 2893 |                     try | 
 | 2894 |                     { | 
 | 2895 |                         line.request( | 
 | 2896 |                             {"faultLed", gpiod::line_request::DIRECTION_OUTPUT, | 
 | 2897 |                              activeHigh | 
 | 2898 |                                  ? 0 | 
 | 2899 |                                  : gpiod::line_request::FLAG_ACTIVE_LOW}); | 
 | 2900 |                         line.set_value(ledStateBits[i + group * groupSize]); | 
 | 2901 |                     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 2902 |                     catch (const std::system_error&) | 
| Zhikui Ren | ce4e73f | 2019-12-06 13:59:47 -0800 | [diff] [blame] | 2903 |                     { | 
 | 2904 |                         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2905 |                             "Error write Led Gpio Device!", | 
 | 2906 |                             phosphor::logging::entry( | 
 | 2907 |                                 "DEVICE=%s", | 
 | 2908 |                                 faultLedPinNames[group + pinGroupOffset][i] | 
 | 2909 |                                     .c_str())); | 
 | 2910 |                         hasError = true; | 
 | 2911 |                         continue; | 
 | 2912 |                     } | 
 | 2913 |                 } // for int i | 
 | 2914 |             } | 
 | 2915 |             if (hasError) | 
 | 2916 |             { | 
 | 2917 |                 return ipmi::responseResponseError(); | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2918 |             } | 
 | 2919 |             break; | 
 | 2920 |         } | 
 | 2921 |         default: | 
 | 2922 |         { | 
 | 2923 |             // now only support two fault types | 
 | 2924 |             return ipmi::responseParmOutOfRange(); | 
 | 2925 |         } | 
| Zhikui Ren | ce4e73f | 2019-12-06 13:59:47 -0800 | [diff] [blame] | 2926 |     } // switch | 
| Zhu, Yunge | be560b0 | 2019-04-21 21:19:21 -0400 | [diff] [blame] | 2927 |     return ipmi::responseSuccess(); | 
 | 2928 | } | 
 | 2929 |  | 
| Richard Marian Thomaiyar | ea537d5 | 2019-04-24 21:33:48 +0530 | [diff] [blame] | 2930 | ipmi::RspType<uint8_t> ipmiOEMReadBoardProductId() | 
 | 2931 | { | 
 | 2932 |     uint8_t prodId = 0; | 
 | 2933 |     try | 
 | 2934 |     { | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 2935 |         std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| Richard Marian Thomaiyar | ea537d5 | 2019-04-24 21:33:48 +0530 | [diff] [blame] | 2936 |         const DbusObjectInfo& object = getDbusObject( | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 2937 |             *dbus, "xyz.openbmc_project.Inventory.Item.Board", | 
| Richard Marian Thomaiyar | ea537d5 | 2019-04-24 21:33:48 +0530 | [diff] [blame] | 2938 |             "/xyz/openbmc_project/inventory/system/board/", "Baseboard"); | 
 | 2939 |         const Value& propValue = getDbusProperty( | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 2940 |             *dbus, object.second, object.first, | 
| Suryakanth Sekar | 6c57e5c | 2020-01-10 17:11:58 +0530 | [diff] [blame] | 2941 |             "xyz.openbmc_project.Inventory.Item.Board.Motherboard", | 
 | 2942 |             "ProductId"); | 
| Richard Marian Thomaiyar | ea537d5 | 2019-04-24 21:33:48 +0530 | [diff] [blame] | 2943 |         prodId = static_cast<uint8_t>(std::get<uint64_t>(propValue)); | 
 | 2944 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 2945 |     catch (const std::exception& e) | 
| Richard Marian Thomaiyar | ea537d5 | 2019-04-24 21:33:48 +0530 | [diff] [blame] | 2946 |     { | 
 | 2947 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2948 |             "ipmiOEMReadBoardProductId: Product ID read failed!", | 
 | 2949 |             phosphor::logging::entry("ERR=%s", e.what())); | 
 | 2950 |     } | 
 | 2951 |     return ipmi::responseSuccess(prodId); | 
 | 2952 | } | 
 | 2953 |  | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 2954 | /** @brief implements the get security mode command | 
 | 2955 |  *  @param ctx - ctx pointer | 
 | 2956 |  * | 
 | 2957 |  *  @returns IPMI completion code with following data | 
 | 2958 |  *   - restriction mode value - As specified in | 
 | 2959 |  * xyz.openbmc_project.Control.Security.RestrictionMode.interface.yaml | 
 | 2960 |  *   - special mode value - As specified in | 
 | 2961 |  * xyz.openbmc_project.Control.Security.SpecialMode.interface.yaml | 
 | 2962 |  */ | 
 | 2963 | ipmi::RspType<uint8_t, uint8_t> ipmiGetSecurityMode(ipmi::Context::ptr ctx) | 
 | 2964 | { | 
 | 2965 |     namespace securityNameSpace = | 
 | 2966 |         sdbusplus::xyz::openbmc_project::Control::Security::server; | 
 | 2967 |     uint8_t restrictionModeValue = 0; | 
 | 2968 |     uint8_t specialModeValue = 0; | 
 | 2969 |  | 
 | 2970 |     boost::system::error_code ec; | 
| Jason M. Bills | 0748c69 | 2022-09-08 15:34:08 -0700 | [diff] [blame] | 2971 |     auto varRestrMode = ctx->bus->yield_method_call<ipmi::DbusVariant>( | 
| James Feist | 28c7290 | 2019-09-16 10:34:07 -0700 | [diff] [blame] | 2972 |         ctx->yield, ec, restricionModeService, restricionModeBasePath, | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 2973 |         dBusPropertyIntf, dBusPropertyGetMethod, restricionModeIntf, | 
 | 2974 |         restricionModeProperty); | 
 | 2975 |     if (ec) | 
 | 2976 |     { | 
 | 2977 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2978 |             "ipmiGetSecurityMode: failed to get RestrictionMode property", | 
 | 2979 |             phosphor::logging::entry("ERROR=%s", ec.message().c_str())); | 
 | 2980 |         return ipmi::responseUnspecifiedError(); | 
 | 2981 |     } | 
 | 2982 |     restrictionModeValue = static_cast<uint8_t>( | 
 | 2983 |         securityNameSpace::RestrictionMode::convertModesFromString( | 
 | 2984 |             std::get<std::string>(varRestrMode))); | 
| Jason M. Bills | 0748c69 | 2022-09-08 15:34:08 -0700 | [diff] [blame] | 2985 |     auto varSpecialMode = ctx->bus->yield_method_call<ipmi::DbusVariant>( | 
 | 2986 |         ctx->yield, ec, specialModeService, specialModeBasePath, | 
 | 2987 |         dBusPropertyIntf, dBusPropertyGetMethod, specialModeIntf, | 
 | 2988 |         specialModeProperty); | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 2989 |     if (ec) | 
 | 2990 |     { | 
 | 2991 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 2992 |             "ipmiGetSecurityMode: failed to get SpecialMode property", | 
 | 2993 |             phosphor::logging::entry("ERROR=%s", ec.message().c_str())); | 
 | 2994 |         // fall through, let us not worry about SpecialMode property, which is | 
 | 2995 |         // not required in user scenario | 
 | 2996 |     } | 
 | 2997 |     else | 
 | 2998 |     { | 
| Richard Marian Thomaiyar | 8d4f8d7 | 2019-11-11 12:06:40 +0530 | [diff] [blame] | 2999 |         specialModeValue = static_cast<uint8_t>( | 
 | 3000 |             securityNameSpace::SpecialMode::convertModesFromString( | 
 | 3001 |                 std::get<std::string>(varSpecialMode))); | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 3002 |     } | 
 | 3003 |     return ipmi::responseSuccess(restrictionModeValue, specialModeValue); | 
 | 3004 | } | 
 | 3005 |  | 
 | 3006 | /** @brief implements the set security mode command | 
 | 3007 |  *  Command allows to upgrade the restriction mode and won't allow | 
 | 3008 |  *  to downgrade from system interface | 
 | 3009 |  *  @param ctx - ctx pointer | 
 | 3010 |  *  @param restrictionMode - restriction mode value to be set. | 
 | 3011 |  * | 
 | 3012 |  *  @returns IPMI completion code | 
 | 3013 |  */ | 
 | 3014 | ipmi::RspType<> ipmiSetSecurityMode(ipmi::Context::ptr ctx, | 
| Richard Marian Thomaiyar | 1079106 | 2019-11-11 12:19:53 +0530 | [diff] [blame] | 3015 |                                     uint8_t restrictionMode, | 
 | 3016 |                                     std::optional<uint8_t> specialMode) | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 3017 | { | 
| Richard Marian Thomaiyar | 1079106 | 2019-11-11 12:19:53 +0530 | [diff] [blame] | 3018 | #ifndef BMC_VALIDATION_UNSECURE_FEATURE | 
 | 3019 |     if (specialMode) | 
 | 3020 |     { | 
 | 3021 |         return ipmi::responseReqDataLenInvalid(); | 
 | 3022 |     } | 
 | 3023 | #endif | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 3024 |     namespace securityNameSpace = | 
 | 3025 |         sdbusplus::xyz::openbmc_project::Control::Security::server; | 
 | 3026 |  | 
 | 3027 |     ChannelInfo chInfo; | 
 | 3028 |     if (getChannelInfo(ctx->channel, chInfo) != ccSuccess) | 
 | 3029 |     { | 
 | 3030 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3031 |             "ipmiSetSecurityMode: Failed to get Channel Info", | 
 | 3032 |             phosphor::logging::entry("CHANNEL=%d", ctx->channel)); | 
 | 3033 |         return ipmi::responseUnspecifiedError(); | 
 | 3034 |     } | 
 | 3035 |     auto reqMode = | 
 | 3036 |         static_cast<securityNameSpace::RestrictionMode::Modes>(restrictionMode); | 
 | 3037 |  | 
 | 3038 |     if ((reqMode < securityNameSpace::RestrictionMode::Modes::Provisioning) || | 
 | 3039 |         (reqMode > | 
 | 3040 |          securityNameSpace::RestrictionMode::Modes::ProvisionedHostDisabled)) | 
 | 3041 |     { | 
 | 3042 |         return ipmi::responseInvalidFieldRequest(); | 
 | 3043 |     } | 
 | 3044 |  | 
 | 3045 |     boost::system::error_code ec; | 
| Jason M. Bills | 0748c69 | 2022-09-08 15:34:08 -0700 | [diff] [blame] | 3046 |     auto varRestrMode = ctx->bus->yield_method_call<ipmi::DbusVariant>( | 
| James Feist | 28c7290 | 2019-09-16 10:34:07 -0700 | [diff] [blame] | 3047 |         ctx->yield, ec, restricionModeService, restricionModeBasePath, | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 3048 |         dBusPropertyIntf, dBusPropertyGetMethod, restricionModeIntf, | 
 | 3049 |         restricionModeProperty); | 
 | 3050 |     if (ec) | 
 | 3051 |     { | 
 | 3052 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3053 |             "ipmiSetSecurityMode: failed to get RestrictionMode property", | 
 | 3054 |             phosphor::logging::entry("ERROR=%s", ec.message().c_str())); | 
 | 3055 |         return ipmi::responseUnspecifiedError(); | 
 | 3056 |     } | 
 | 3057 |     auto currentRestrictionMode = | 
 | 3058 |         securityNameSpace::RestrictionMode::convertModesFromString( | 
 | 3059 |             std::get<std::string>(varRestrMode)); | 
 | 3060 |  | 
 | 3061 |     if (chInfo.mediumType != | 
 | 3062 |             static_cast<uint8_t>(EChannelMediumType::lan8032) && | 
 | 3063 |         currentRestrictionMode > reqMode) | 
 | 3064 |     { | 
 | 3065 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3066 |             "ipmiSetSecurityMode - Downgrading security mode not supported " | 
 | 3067 |             "through system interface", | 
 | 3068 |             phosphor::logging::entry( | 
 | 3069 |                 "CUR_MODE=%d", static_cast<uint8_t>(currentRestrictionMode)), | 
 | 3070 |             phosphor::logging::entry("REQ_MODE=%d", restrictionMode)); | 
 | 3071 |         return ipmi::responseCommandNotAvailable(); | 
 | 3072 |     } | 
 | 3073 |  | 
 | 3074 |     ec.clear(); | 
 | 3075 |     ctx->bus->yield_method_call<>( | 
| James Feist | 28c7290 | 2019-09-16 10:34:07 -0700 | [diff] [blame] | 3076 |         ctx->yield, ec, restricionModeService, restricionModeBasePath, | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 3077 |         dBusPropertyIntf, dBusPropertySetMethod, restricionModeIntf, | 
 | 3078 |         restricionModeProperty, | 
| Jason M. Bills | 0748c69 | 2022-09-08 15:34:08 -0700 | [diff] [blame] | 3079 |         static_cast<ipmi::DbusVariant>( | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 3080 |             securityNameSpace::convertForMessage(reqMode))); | 
 | 3081 |  | 
 | 3082 |     if (ec) | 
 | 3083 |     { | 
 | 3084 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3085 |             "ipmiSetSecurityMode: failed to set RestrictionMode property", | 
 | 3086 |             phosphor::logging::entry("ERROR=%s", ec.message().c_str())); | 
 | 3087 |         return ipmi::responseUnspecifiedError(); | 
 | 3088 |     } | 
| Richard Marian Thomaiyar | 1079106 | 2019-11-11 12:19:53 +0530 | [diff] [blame] | 3089 |  | 
 | 3090 | #ifdef BMC_VALIDATION_UNSECURE_FEATURE | 
 | 3091 |     if (specialMode) | 
 | 3092 |     { | 
| Jayaprakash Mutyala | d77489f | 2020-09-05 01:00:04 +0000 | [diff] [blame] | 3093 |         constexpr uint8_t mfgMode = 0x01; | 
 | 3094 |         // Manufacturing mode is reserved. So can't enable this mode. | 
 | 3095 |         if (specialMode.value() == mfgMode) | 
 | 3096 |         { | 
 | 3097 |             phosphor::logging::log<phosphor::logging::level::INFO>( | 
 | 3098 |                 "ipmiSetSecurityMode: Can't enable Manufacturing mode"); | 
 | 3099 |             return ipmi::responseInvalidFieldRequest(); | 
 | 3100 |         } | 
 | 3101 |  | 
| Richard Marian Thomaiyar | 1079106 | 2019-11-11 12:19:53 +0530 | [diff] [blame] | 3102 |         ec.clear(); | 
 | 3103 |         ctx->bus->yield_method_call<>( | 
 | 3104 |             ctx->yield, ec, specialModeService, specialModeBasePath, | 
 | 3105 |             dBusPropertyIntf, dBusPropertySetMethod, specialModeIntf, | 
 | 3106 |             specialModeProperty, | 
| Jason M. Bills | 0748c69 | 2022-09-08 15:34:08 -0700 | [diff] [blame] | 3107 |             static_cast<ipmi::DbusVariant>(securityNameSpace::convertForMessage( | 
 | 3108 |                 static_cast<securityNameSpace::SpecialMode::Modes>( | 
 | 3109 |                     specialMode.value())))); | 
| Richard Marian Thomaiyar | 1079106 | 2019-11-11 12:19:53 +0530 | [diff] [blame] | 3110 |  | 
 | 3111 |         if (ec) | 
 | 3112 |         { | 
 | 3113 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3114 |                 "ipmiSetSecurityMode: failed to set SpecialMode property", | 
 | 3115 |                 phosphor::logging::entry("ERROR=%s", ec.message().c_str())); | 
 | 3116 |             return ipmi::responseUnspecifiedError(); | 
 | 3117 |         } | 
 | 3118 |     } | 
 | 3119 | #endif | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 3120 |     return ipmi::responseSuccess(); | 
 | 3121 | } | 
 | 3122 |  | 
| Vernon Mauery | 4ac799d | 2019-05-20 15:50:37 -0700 | [diff] [blame] | 3123 | ipmi::RspType<uint8_t /* restore status */> | 
 | 3124 |     ipmiRestoreConfiguration(const std::array<uint8_t, 3>& clr, uint8_t cmd) | 
 | 3125 | { | 
 | 3126 |     static constexpr std::array<uint8_t, 3> expClr = {'C', 'L', 'R'}; | 
 | 3127 |  | 
 | 3128 |     if (clr != expClr) | 
 | 3129 |     { | 
 | 3130 |         return ipmi::responseInvalidFieldRequest(); | 
 | 3131 |     } | 
 | 3132 |     constexpr uint8_t cmdStatus = 0; | 
 | 3133 |     constexpr uint8_t cmdDefaultRestore = 0xaa; | 
 | 3134 |     constexpr uint8_t cmdFullRestore = 0xbb; | 
 | 3135 |     constexpr uint8_t cmdFormat = 0xcc; | 
 | 3136 |  | 
 | 3137 |     constexpr const char* restoreOpFname = "/tmp/.rwfs/.restore_op"; | 
 | 3138 |  | 
 | 3139 |     switch (cmd) | 
 | 3140 |     { | 
 | 3141 |         case cmdStatus: | 
 | 3142 |             break; | 
 | 3143 |         case cmdDefaultRestore: | 
 | 3144 |         case cmdFullRestore: | 
 | 3145 |         case cmdFormat: | 
 | 3146 |         { | 
 | 3147 |             // write file to rwfs root | 
 | 3148 |             int value = (cmd - 1) & 0x03; // map aa, bb, cc => 1, 2, 3 | 
 | 3149 |             std::ofstream restoreFile(restoreOpFname); | 
 | 3150 |             if (!restoreFile) | 
 | 3151 |             { | 
 | 3152 |                 return ipmi::responseUnspecifiedError(); | 
 | 3153 |             } | 
 | 3154 |             restoreFile << value << "\n"; | 
| Arun P. Mohanan | ba1fbc8 | 2021-04-26 11:26:53 +0530 | [diff] [blame] | 3155 |  | 
 | 3156 |             phosphor::logging::log<phosphor::logging::level::WARNING>( | 
 | 3157 |                 "Restore to default will be performed on next BMC boot", | 
 | 3158 |                 phosphor::logging::entry("ACTION=0x%0X", cmd)); | 
 | 3159 |  | 
| Vernon Mauery | 4ac799d | 2019-05-20 15:50:37 -0700 | [diff] [blame] | 3160 |             break; | 
 | 3161 |         } | 
 | 3162 |         default: | 
 | 3163 |             return ipmi::responseInvalidFieldRequest(); | 
 | 3164 |     } | 
 | 3165 |  | 
 | 3166 |     constexpr uint8_t restorePending = 0; | 
 | 3167 |     constexpr uint8_t restoreComplete = 1; | 
 | 3168 |  | 
 | 3169 |     uint8_t restoreStatus = std::filesystem::exists(restoreOpFname) | 
 | 3170 |                                 ? restorePending | 
 | 3171 |                                 : restoreComplete; | 
 | 3172 |     return ipmi::responseSuccess(restoreStatus); | 
 | 3173 | } | 
 | 3174 |  | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3175 | ipmi::RspType<uint8_t> ipmiOEMGetNmiSource(void) | 
 | 3176 | { | 
 | 3177 |     uint8_t bmcSource; | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 3178 |     namespace nmi = sdbusplus::xyz::openbmc_project::Chassis::Control::server; | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3179 |  | 
 | 3180 |     try | 
 | 3181 |     { | 
 | 3182 |         std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 3183 |         std::string service = getService(*dbus, oemNmiSourceIntf, | 
 | 3184 |                                          oemNmiSourceObjPath); | 
 | 3185 |         Value variant = getDbusProperty(*dbus, service, oemNmiSourceObjPath, | 
 | 3186 |                                         oemNmiSourceIntf, | 
 | 3187 |                                         oemNmiBmcSourceObjPathProp); | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3188 |  | 
 | 3189 |         switch (nmi::NMISource::convertBMCSourceSignalFromString( | 
 | 3190 |             std::get<std::string>(variant))) | 
 | 3191 |         { | 
 | 3192 |             case nmi::NMISource::BMCSourceSignal::None: | 
 | 3193 |                 bmcSource = static_cast<uint8_t>(NmiSource::none); | 
 | 3194 |                 break; | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 3195 |             case nmi::NMISource::BMCSourceSignal::FrontPanelButton: | 
 | 3196 |                 bmcSource = static_cast<uint8_t>(NmiSource::frontPanelButton); | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3197 |                 break; | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 3198 |             case nmi::NMISource::BMCSourceSignal::Watchdog: | 
 | 3199 |                 bmcSource = static_cast<uint8_t>(NmiSource::watchdog); | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3200 |                 break; | 
 | 3201 |             case nmi::NMISource::BMCSourceSignal::ChassisCmd: | 
 | 3202 |                 bmcSource = static_cast<uint8_t>(NmiSource::chassisCmd); | 
 | 3203 |                 break; | 
 | 3204 |             case nmi::NMISource::BMCSourceSignal::MemoryError: | 
 | 3205 |                 bmcSource = static_cast<uint8_t>(NmiSource::memoryError); | 
 | 3206 |                 break; | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 3207 |             case nmi::NMISource::BMCSourceSignal::PciBusError: | 
 | 3208 |                 bmcSource = static_cast<uint8_t>(NmiSource::pciBusError); | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3209 |                 break; | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 3210 |             case nmi::NMISource::BMCSourceSignal::PCH: | 
 | 3211 |                 bmcSource = static_cast<uint8_t>(NmiSource::pch); | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3212 |                 break; | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 3213 |             case nmi::NMISource::BMCSourceSignal::Chipset: | 
 | 3214 |                 bmcSource = static_cast<uint8_t>(NmiSource::chipset); | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3215 |                 break; | 
 | 3216 |             default: | 
 | 3217 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3218 |                     "NMI source: invalid property!", | 
 | 3219 |                     phosphor::logging::entry( | 
 | 3220 |                         "PROP=%s", std::get<std::string>(variant).c_str())); | 
 | 3221 |                 return ipmi::responseResponseError(); | 
 | 3222 |         } | 
 | 3223 |     } | 
| Patrick Williams | f944d2e | 2022-07-22 19:26:52 -0500 | [diff] [blame] | 3224 |     catch (const sdbusplus::exception_t& e) | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3225 |     { | 
 | 3226 |         phosphor::logging::log<phosphor::logging::level::ERR>(e.what()); | 
 | 3227 |         return ipmi::responseResponseError(); | 
 | 3228 |     } | 
 | 3229 |  | 
 | 3230 |     return ipmi::responseSuccess(bmcSource); | 
 | 3231 | } | 
 | 3232 |  | 
 | 3233 | ipmi::RspType<> ipmiOEMSetNmiSource(uint8_t sourceId) | 
 | 3234 | { | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 3235 |     namespace nmi = sdbusplus::xyz::openbmc_project::Chassis::Control::server; | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3236 |  | 
 | 3237 |     nmi::NMISource::BMCSourceSignal bmcSourceSignal = | 
 | 3238 |         nmi::NMISource::BMCSourceSignal::None; | 
 | 3239 |  | 
 | 3240 |     switch (NmiSource(sourceId)) | 
 | 3241 |     { | 
 | 3242 |         case NmiSource::none: | 
 | 3243 |             bmcSourceSignal = nmi::NMISource::BMCSourceSignal::None; | 
 | 3244 |             break; | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 3245 |         case NmiSource::frontPanelButton: | 
 | 3246 |             bmcSourceSignal = nmi::NMISource::BMCSourceSignal::FrontPanelButton; | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3247 |             break; | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 3248 |         case NmiSource::watchdog: | 
 | 3249 |             bmcSourceSignal = nmi::NMISource::BMCSourceSignal::Watchdog; | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3250 |             break; | 
 | 3251 |         case NmiSource::chassisCmd: | 
 | 3252 |             bmcSourceSignal = nmi::NMISource::BMCSourceSignal::ChassisCmd; | 
 | 3253 |             break; | 
 | 3254 |         case NmiSource::memoryError: | 
 | 3255 |             bmcSourceSignal = nmi::NMISource::BMCSourceSignal::MemoryError; | 
 | 3256 |             break; | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 3257 |         case NmiSource::pciBusError: | 
 | 3258 |             bmcSourceSignal = nmi::NMISource::BMCSourceSignal::PciBusError; | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3259 |             break; | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 3260 |         case NmiSource::pch: | 
 | 3261 |             bmcSourceSignal = nmi::NMISource::BMCSourceSignal::PCH; | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3262 |             break; | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 3263 |         case NmiSource::chipset: | 
 | 3264 |             bmcSourceSignal = nmi::NMISource::BMCSourceSignal::Chipset; | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3265 |             break; | 
 | 3266 |         default: | 
 | 3267 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3268 |                 "NMI source: invalid property!"); | 
 | 3269 |             return ipmi::responseResponseError(); | 
 | 3270 |     } | 
 | 3271 |  | 
 | 3272 |     try | 
 | 3273 |     { | 
 | 3274 |         // keep NMI signal source | 
 | 3275 |         std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 3276 |         std::string service = getService(*dbus, oemNmiSourceIntf, | 
 | 3277 |                                          oemNmiSourceObjPath); | 
| Chen Yugang | 97cf96e | 2019-11-01 08:55:11 +0800 | [diff] [blame] | 3278 |         setDbusProperty(*dbus, service, oemNmiSourceObjPath, oemNmiSourceIntf, | 
 | 3279 |                         oemNmiBmcSourceObjPathProp, | 
 | 3280 |                         nmi::convertForMessage(bmcSourceSignal)); | 
| Chen Yugang | 99be633 | 2019-08-09 16:20:48 +0800 | [diff] [blame] | 3281 |         // set Enabled property to inform NMI source handling | 
 | 3282 |         // to trigger a NMI_OUT BSOD. | 
 | 3283 |         // if it's triggered by NMI source property changed, | 
 | 3284 |         // NMI_OUT BSOD could be missed if the same source occurs twice in a row | 
 | 3285 |         if (bmcSourceSignal != nmi::NMISource::BMCSourceSignal::None) | 
 | 3286 |         { | 
 | 3287 |             setDbusProperty(*dbus, service, oemNmiSourceObjPath, | 
 | 3288 |                             oemNmiSourceIntf, oemNmiEnabledObjPathProp, | 
 | 3289 |                             static_cast<bool>(true)); | 
 | 3290 |         } | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3291 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 3292 |     catch (const sdbusplus::exception_t& e) | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 3293 |     { | 
 | 3294 |         phosphor::logging::log<phosphor::logging::level::ERR>(e.what()); | 
 | 3295 |         return ipmi::responseResponseError(); | 
 | 3296 |     } | 
 | 3297 |  | 
 | 3298 |     return ipmi::responseSuccess(); | 
 | 3299 | } | 
 | 3300 |  | 
| James Feist | 63efafa | 2019-07-24 12:39:21 -0700 | [diff] [blame] | 3301 | namespace dimmOffset | 
 | 3302 | { | 
 | 3303 | constexpr const char* dimmPower = "DimmPower"; | 
 | 3304 | constexpr const char* staticCltt = "StaticCltt"; | 
 | 3305 | constexpr const char* offsetPath = "/xyz/openbmc_project/Inventory/Item/Dimm"; | 
 | 3306 | constexpr const char* offsetInterface = | 
 | 3307 |     "xyz.openbmc_project.Inventory.Item.Dimm.Offset"; | 
 | 3308 | constexpr const char* property = "DimmOffset"; | 
 | 3309 |  | 
 | 3310 | }; // namespace dimmOffset | 
 | 3311 |  | 
 | 3312 | ipmi::RspType<> | 
 | 3313 |     ipmiOEMSetDimmOffset(uint8_t type, | 
 | 3314 |                          const std::vector<std::tuple<uint8_t, uint8_t>>& data) | 
 | 3315 | { | 
 | 3316 |     if (type != static_cast<uint8_t>(dimmOffsetTypes::dimmPower) && | 
 | 3317 |         type != static_cast<uint8_t>(dimmOffsetTypes::staticCltt)) | 
 | 3318 |     { | 
 | 3319 |         return ipmi::responseInvalidFieldRequest(); | 
 | 3320 |     } | 
 | 3321 |  | 
 | 3322 |     if (data.empty()) | 
 | 3323 |     { | 
 | 3324 |         return ipmi::responseInvalidFieldRequest(); | 
 | 3325 |     } | 
 | 3326 |     nlohmann::json json; | 
 | 3327 |  | 
 | 3328 |     std::ifstream jsonStream(dimmOffsetFile); | 
 | 3329 |     if (jsonStream.good()) | 
 | 3330 |     { | 
 | 3331 |         json = nlohmann::json::parse(jsonStream, nullptr, false); | 
 | 3332 |         if (json.is_discarded()) | 
 | 3333 |         { | 
 | 3334 |             json = nlohmann::json(); | 
 | 3335 |         } | 
 | 3336 |         jsonStream.close(); | 
 | 3337 |     } | 
 | 3338 |  | 
 | 3339 |     std::string typeName; | 
 | 3340 |     if (type == static_cast<uint8_t>(dimmOffsetTypes::dimmPower)) | 
 | 3341 |     { | 
 | 3342 |         typeName = dimmOffset::dimmPower; | 
 | 3343 |     } | 
 | 3344 |     else | 
 | 3345 |     { | 
 | 3346 |         typeName = dimmOffset::staticCltt; | 
 | 3347 |     } | 
 | 3348 |  | 
 | 3349 |     nlohmann::json& field = json[typeName]; | 
 | 3350 |  | 
 | 3351 |     for (const auto& [index, value] : data) | 
 | 3352 |     { | 
 | 3353 |         field[index] = value; | 
 | 3354 |     } | 
 | 3355 |  | 
 | 3356 |     for (nlohmann::json& val : field) | 
 | 3357 |     { | 
 | 3358 |         if (val == nullptr) | 
 | 3359 |         { | 
 | 3360 |             val = static_cast<uint8_t>(0); | 
 | 3361 |         } | 
 | 3362 |     } | 
 | 3363 |  | 
 | 3364 |     std::ofstream output(dimmOffsetFile); | 
 | 3365 |     if (!output.good()) | 
 | 3366 |     { | 
 | 3367 |         std::cerr << "Error writing json file\n"; | 
 | 3368 |         return ipmi::responseResponseError(); | 
 | 3369 |     } | 
 | 3370 |  | 
 | 3371 |     output << json.dump(4); | 
 | 3372 |  | 
 | 3373 |     if (type == static_cast<uint8_t>(dimmOffsetTypes::staticCltt)) | 
 | 3374 |     { | 
 | 3375 |         std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus(); | 
 | 3376 |  | 
| Jason M. Bills | 0748c69 | 2022-09-08 15:34:08 -0700 | [diff] [blame] | 3377 |         ipmi::DbusVariant offsets = field.get<std::vector<uint8_t>>(); | 
| James Feist | 63efafa | 2019-07-24 12:39:21 -0700 | [diff] [blame] | 3378 |         auto call = bus->new_method_call( | 
 | 3379 |             settingsBusName, dimmOffset::offsetPath, PROP_INTF, "Set"); | 
 | 3380 |         call.append(dimmOffset::offsetInterface, dimmOffset::property, offsets); | 
 | 3381 |         try | 
 | 3382 |         { | 
 | 3383 |             bus->call(call); | 
 | 3384 |         } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 3385 |         catch (const sdbusplus::exception_t& e) | 
| James Feist | 63efafa | 2019-07-24 12:39:21 -0700 | [diff] [blame] | 3386 |         { | 
 | 3387 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3388 |                 "ipmiOEMSetDimmOffset: can't set dimm offsets!", | 
 | 3389 |                 phosphor::logging::entry("ERR=%s", e.what())); | 
 | 3390 |             return ipmi::responseResponseError(); | 
 | 3391 |         } | 
 | 3392 |     } | 
 | 3393 |  | 
 | 3394 |     return ipmi::responseSuccess(); | 
 | 3395 | } | 
 | 3396 |  | 
 | 3397 | ipmi::RspType<uint8_t> ipmiOEMGetDimmOffset(uint8_t type, uint8_t index) | 
 | 3398 | { | 
| James Feist | 63efafa | 2019-07-24 12:39:21 -0700 | [diff] [blame] | 3399 |     if (type != static_cast<uint8_t>(dimmOffsetTypes::dimmPower) && | 
 | 3400 |         type != static_cast<uint8_t>(dimmOffsetTypes::staticCltt)) | 
 | 3401 |     { | 
 | 3402 |         return ipmi::responseInvalidFieldRequest(); | 
 | 3403 |     } | 
 | 3404 |  | 
 | 3405 |     std::ifstream jsonStream(dimmOffsetFile); | 
 | 3406 |  | 
 | 3407 |     auto json = nlohmann::json::parse(jsonStream, nullptr, false); | 
 | 3408 |     if (json.is_discarded()) | 
 | 3409 |     { | 
 | 3410 |         std::cerr << "File error in " << dimmOffsetFile << "\n"; | 
 | 3411 |         return ipmi::responseResponseError(); | 
 | 3412 |     } | 
 | 3413 |  | 
 | 3414 |     std::string typeName; | 
 | 3415 |     if (type == static_cast<uint8_t>(dimmOffsetTypes::dimmPower)) | 
 | 3416 |     { | 
 | 3417 |         typeName = dimmOffset::dimmPower; | 
 | 3418 |     } | 
 | 3419 |     else | 
 | 3420 |     { | 
 | 3421 |         typeName = dimmOffset::staticCltt; | 
 | 3422 |     } | 
 | 3423 |  | 
 | 3424 |     auto it = json.find(typeName); | 
 | 3425 |     if (it == json.end()) | 
 | 3426 |     { | 
 | 3427 |         return ipmi::responseInvalidFieldRequest(); | 
 | 3428 |     } | 
 | 3429 |  | 
 | 3430 |     if (it->size() <= index) | 
 | 3431 |     { | 
 | 3432 |         return ipmi::responseInvalidFieldRequest(); | 
 | 3433 |     } | 
 | 3434 |  | 
 | 3435 |     uint8_t resp = it->at(index).get<uint8_t>(); | 
 | 3436 |     return ipmi::responseSuccess(resp); | 
 | 3437 | } | 
 | 3438 |  | 
| Chen,Yugang | 4f7e76b | 2019-08-20 09:28:06 +0800 | [diff] [blame] | 3439 | namespace boot_options | 
 | 3440 | { | 
 | 3441 |  | 
 | 3442 | using namespace sdbusplus::xyz::openbmc_project::Control::Boot::server; | 
 | 3443 | using IpmiValue = uint8_t; | 
 | 3444 | constexpr auto ipmiDefault = 0; | 
 | 3445 |  | 
 | 3446 | std::map<IpmiValue, Source::Sources> sourceIpmiToDbus = { | 
 | 3447 |     {0x01, Source::Sources::Network}, | 
 | 3448 |     {0x02, Source::Sources::Disk}, | 
 | 3449 |     {0x05, Source::Sources::ExternalMedia}, | 
 | 3450 |     {0x0f, Source::Sources::RemovableMedia}, | 
 | 3451 |     {ipmiDefault, Source::Sources::Default}}; | 
 | 3452 |  | 
 | 3453 | std::map<IpmiValue, Mode::Modes> modeIpmiToDbus = { | 
| Chen Yugang | ca12a7b | 2019-09-03 18:11:44 +0800 | [diff] [blame] | 3454 |     {0x06, Mode::Modes::Setup}, {ipmiDefault, Mode::Modes::Regular}}; | 
| Chen,Yugang | 4f7e76b | 2019-08-20 09:28:06 +0800 | [diff] [blame] | 3455 |  | 
 | 3456 | std::map<Source::Sources, IpmiValue> sourceDbusToIpmi = { | 
 | 3457 |     {Source::Sources::Network, 0x01}, | 
 | 3458 |     {Source::Sources::Disk, 0x02}, | 
 | 3459 |     {Source::Sources::ExternalMedia, 0x05}, | 
 | 3460 |     {Source::Sources::RemovableMedia, 0x0f}, | 
 | 3461 |     {Source::Sources::Default, ipmiDefault}}; | 
 | 3462 |  | 
 | 3463 | std::map<Mode::Modes, IpmiValue> modeDbusToIpmi = { | 
| Chen Yugang | ca12a7b | 2019-09-03 18:11:44 +0800 | [diff] [blame] | 3464 |     {Mode::Modes::Setup, 0x06}, {Mode::Modes::Regular, ipmiDefault}}; | 
| Chen,Yugang | 4f7e76b | 2019-08-20 09:28:06 +0800 | [diff] [blame] | 3465 |  | 
 | 3466 | static constexpr auto bootModeIntf = "xyz.openbmc_project.Control.Boot.Mode"; | 
 | 3467 | static constexpr auto bootSourceIntf = | 
 | 3468 |     "xyz.openbmc_project.Control.Boot.Source"; | 
 | 3469 | static constexpr auto enabledIntf = "xyz.openbmc_project.Object.Enable"; | 
 | 3470 | static constexpr auto persistentObjPath = | 
 | 3471 |     "/xyz/openbmc_project/control/host0/boot"; | 
 | 3472 | static constexpr auto oneTimePath = | 
 | 3473 |     "/xyz/openbmc_project/control/host0/boot/one_time"; | 
 | 3474 | static constexpr auto bootSourceProp = "BootSource"; | 
 | 3475 | static constexpr auto bootModeProp = "BootMode"; | 
 | 3476 | static constexpr auto oneTimeBootEnableProp = "Enabled"; | 
 | 3477 | static constexpr auto httpBootMode = | 
 | 3478 |     "xyz.openbmc_project.Control.Boot.Source.Sources.Http"; | 
 | 3479 |  | 
 | 3480 | enum class BootOptionParameter : size_t | 
 | 3481 | { | 
 | 3482 |     setInProgress = 0x0, | 
 | 3483 |     bootFlags = 0x5, | 
 | 3484 | }; | 
 | 3485 | static constexpr uint8_t setComplete = 0x0; | 
 | 3486 | static constexpr uint8_t setInProgress = 0x1; | 
 | 3487 | static uint8_t transferStatus = setComplete; | 
 | 3488 | static constexpr uint8_t setParmVersion = 0x01; | 
 | 3489 | static constexpr uint8_t setParmBootFlagsPermanent = 0x40; | 
 | 3490 | static constexpr uint8_t setParmBootFlagsValidOneTime = 0x80; | 
 | 3491 | static constexpr uint8_t setParmBootFlagsValidPermanent = 0xC0; | 
 | 3492 | static constexpr uint8_t httpBoot = 0xd; | 
 | 3493 | static constexpr uint8_t bootSourceMask = 0x3c; | 
 | 3494 |  | 
 | 3495 | } // namespace boot_options | 
 | 3496 |  | 
 | 3497 | ipmi::RspType<uint8_t,               // version | 
 | 3498 |               uint8_t,               // param | 
 | 3499 |               uint8_t,               // data0, dependent on parameter | 
 | 3500 |               std::optional<uint8_t> // data1, dependent on parameter | 
 | 3501 |               > | 
 | 3502 |     ipmiOemGetEfiBootOptions(uint8_t parameter, uint8_t set, uint8_t block) | 
 | 3503 | { | 
 | 3504 |     using namespace boot_options; | 
 | 3505 |     uint8_t bootOption = 0; | 
 | 3506 |  | 
 | 3507 |     if (parameter == static_cast<uint8_t>(BootOptionParameter::setInProgress)) | 
 | 3508 |     { | 
 | 3509 |         return ipmi::responseSuccess(setParmVersion, parameter, transferStatus, | 
 | 3510 |                                      std::nullopt); | 
 | 3511 |     } | 
 | 3512 |  | 
 | 3513 |     if (parameter != static_cast<uint8_t>(BootOptionParameter::bootFlags)) | 
 | 3514 |     { | 
 | 3515 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3516 |             "Unsupported parameter"); | 
| Jayaprakash Mutyala | 3694d07 | 2021-07-22 10:34:37 +0000 | [diff] [blame] | 3517 |         return ipmi::response(ccParameterNotSupported); | 
| Chen,Yugang | 4f7e76b | 2019-08-20 09:28:06 +0800 | [diff] [blame] | 3518 |     } | 
 | 3519 |  | 
 | 3520 |     try | 
 | 3521 |     { | 
 | 3522 |         auto oneTimeEnabled = false; | 
 | 3523 |         // read one time Enabled property | 
 | 3524 |         std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
 | 3525 |         std::string service = getService(*dbus, enabledIntf, oneTimePath); | 
 | 3526 |         Value variant = getDbusProperty(*dbus, service, oneTimePath, | 
 | 3527 |                                         enabledIntf, oneTimeBootEnableProp); | 
 | 3528 |         oneTimeEnabled = std::get<bool>(variant); | 
 | 3529 |  | 
 | 3530 |         // get BootSource and BootMode properties | 
 | 3531 |         // according to oneTimeEnable | 
 | 3532 |         auto bootObjPath = oneTimePath; | 
 | 3533 |         if (oneTimeEnabled == false) | 
 | 3534 |         { | 
 | 3535 |             bootObjPath = persistentObjPath; | 
 | 3536 |         } | 
 | 3537 |  | 
 | 3538 |         service = getService(*dbus, bootModeIntf, bootObjPath); | 
 | 3539 |         variant = getDbusProperty(*dbus, service, bootObjPath, bootModeIntf, | 
 | 3540 |                                   bootModeProp); | 
 | 3541 |  | 
 | 3542 |         auto bootMode = | 
 | 3543 |             Mode::convertModesFromString(std::get<std::string>(variant)); | 
 | 3544 |  | 
 | 3545 |         service = getService(*dbus, bootSourceIntf, bootObjPath); | 
 | 3546 |         variant = getDbusProperty(*dbus, service, bootObjPath, bootSourceIntf, | 
 | 3547 |                                   bootSourceProp); | 
 | 3548 |  | 
 | 3549 |         if (std::get<std::string>(variant) == httpBootMode) | 
 | 3550 |         { | 
 | 3551 |             bootOption = httpBoot; | 
 | 3552 |         } | 
 | 3553 |         else | 
 | 3554 |         { | 
 | 3555 |             auto bootSource = Source::convertSourcesFromString( | 
 | 3556 |                 std::get<std::string>(variant)); | 
 | 3557 |             bootOption = sourceDbusToIpmi.at(bootSource); | 
 | 3558 |             if (Source::Sources::Default == bootSource) | 
 | 3559 |             { | 
 | 3560 |                 bootOption = modeDbusToIpmi.at(bootMode); | 
 | 3561 |             } | 
 | 3562 |         } | 
 | 3563 |  | 
 | 3564 |         uint8_t oneTime = oneTimeEnabled ? setParmBootFlagsValidOneTime | 
 | 3565 |                                          : setParmBootFlagsValidPermanent; | 
 | 3566 |         bootOption <<= 2; // shift for responseconstexpr | 
 | 3567 |         return ipmi::responseSuccess(setParmVersion, parameter, oneTime, | 
 | 3568 |                                      bootOption); | 
 | 3569 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 3570 |     catch (const sdbusplus::exception_t& e) | 
| Chen,Yugang | 4f7e76b | 2019-08-20 09:28:06 +0800 | [diff] [blame] | 3571 |     { | 
 | 3572 |         phosphor::logging::log<phosphor::logging::level::ERR>(e.what()); | 
 | 3573 |         return ipmi::responseResponseError(); | 
 | 3574 |     } | 
 | 3575 | } | 
 | 3576 |  | 
 | 3577 | ipmi::RspType<> ipmiOemSetEfiBootOptions(uint8_t bootFlag, uint8_t bootParam, | 
 | 3578 |                                          std::optional<uint8_t> bootOption) | 
 | 3579 | { | 
 | 3580 |     using namespace boot_options; | 
 | 3581 |     auto oneTimeEnabled = false; | 
 | 3582 |  | 
| Mike Jones | bc01d21 | 2022-06-16 12:41:33 -0700 | [diff] [blame] | 3583 |     if (bootFlag == 0 && bootParam == 0) | 
 | 3584 |     { | 
 | 3585 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3586 |             "Unsupported parameter"); | 
 | 3587 |         return ipmi::response(ccParameterNotSupported); | 
 | 3588 |     } | 
| Chen,Yugang | 4f7e76b | 2019-08-20 09:28:06 +0800 | [diff] [blame] | 3589 |     if (bootFlag == static_cast<uint8_t>(BootOptionParameter::setInProgress)) | 
 | 3590 |     { | 
 | 3591 |         if (bootOption) | 
 | 3592 |         { | 
 | 3593 |             return ipmi::responseReqDataLenInvalid(); | 
 | 3594 |         } | 
 | 3595 |  | 
 | 3596 |         if (transferStatus == setInProgress) | 
 | 3597 |         { | 
 | 3598 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3599 |                 "boot option set in progress!"); | 
 | 3600 |             return ipmi::responseResponseError(); | 
 | 3601 |         } | 
 | 3602 |  | 
 | 3603 |         transferStatus = bootParam; | 
 | 3604 |         return ipmi::responseSuccess(); | 
 | 3605 |     } | 
 | 3606 |  | 
 | 3607 |     if (bootFlag != (uint8_t)BootOptionParameter::bootFlags) | 
 | 3608 |     { | 
 | 3609 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3610 |             "Unsupported parameter"); | 
| Jayaprakash Mutyala | 3694d07 | 2021-07-22 10:34:37 +0000 | [diff] [blame] | 3611 |         return ipmi::response(ccParameterNotSupported); | 
| Chen,Yugang | 4f7e76b | 2019-08-20 09:28:06 +0800 | [diff] [blame] | 3612 |     } | 
 | 3613 |  | 
 | 3614 |     if (!bootOption) | 
 | 3615 |     { | 
 | 3616 |         return ipmi::responseReqDataLenInvalid(); | 
 | 3617 |     } | 
 | 3618 |  | 
 | 3619 |     if (((bootOption.value() & bootSourceMask) >> 2) != | 
 | 3620 |         httpBoot) // not http boot, exit | 
 | 3621 |     { | 
 | 3622 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3623 |             "wrong boot option parameter!"); | 
 | 3624 |         return ipmi::responseParmOutOfRange(); | 
 | 3625 |     } | 
 | 3626 |  | 
 | 3627 |     try | 
 | 3628 |     { | 
 | 3629 |         bool permanent = (bootParam & setParmBootFlagsPermanent) == | 
 | 3630 |                          setParmBootFlagsPermanent; | 
 | 3631 |  | 
 | 3632 |         // read one time Enabled property | 
 | 3633 |         std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
 | 3634 |         std::string service = getService(*dbus, enabledIntf, oneTimePath); | 
 | 3635 |         Value variant = getDbusProperty(*dbus, service, oneTimePath, | 
 | 3636 |                                         enabledIntf, oneTimeBootEnableProp); | 
 | 3637 |         oneTimeEnabled = std::get<bool>(variant); | 
 | 3638 |  | 
 | 3639 |         /* | 
 | 3640 |          * Check if the current boot setting is onetime or permanent, if the | 
 | 3641 |          * request in the command is otherwise, then set the "Enabled" | 
 | 3642 |          * property in one_time object path to 'True' to indicate onetime | 
 | 3643 |          * and 'False' to indicate permanent. | 
 | 3644 |          * | 
 | 3645 |          * Once the onetime/permanent setting is applied, then the bootMode | 
 | 3646 |          * and bootSource is updated for the corresponding object. | 
 | 3647 |          */ | 
 | 3648 |         if (permanent == oneTimeEnabled) | 
 | 3649 |         { | 
 | 3650 |             setDbusProperty(*dbus, service, oneTimePath, enabledIntf, | 
 | 3651 |                             oneTimeBootEnableProp, !permanent); | 
 | 3652 |         } | 
 | 3653 |  | 
 | 3654 |         // set BootSource and BootMode properties | 
 | 3655 |         // according to oneTimeEnable or persistent | 
 | 3656 |         auto bootObjPath = oneTimePath; | 
 | 3657 |         if (oneTimeEnabled == false) | 
 | 3658 |         { | 
 | 3659 |             bootObjPath = persistentObjPath; | 
 | 3660 |         } | 
 | 3661 |         std::string bootMode = | 
 | 3662 |             "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; | 
 | 3663 |         std::string bootSource = httpBootMode; | 
 | 3664 |  | 
 | 3665 |         service = getService(*dbus, bootModeIntf, bootObjPath); | 
 | 3666 |         setDbusProperty(*dbus, service, bootObjPath, bootModeIntf, bootModeProp, | 
 | 3667 |                         bootMode); | 
 | 3668 |  | 
 | 3669 |         service = getService(*dbus, bootSourceIntf, bootObjPath); | 
 | 3670 |         setDbusProperty(*dbus, service, bootObjPath, bootSourceIntf, | 
 | 3671 |                         bootSourceProp, bootSource); | 
 | 3672 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 3673 |     catch (const sdbusplus::exception_t& e) | 
| Chen,Yugang | 4f7e76b | 2019-08-20 09:28:06 +0800 | [diff] [blame] | 3674 |     { | 
 | 3675 |         phosphor::logging::log<phosphor::logging::level::ERR>(e.what()); | 
 | 3676 |         return ipmi::responseResponseError(); | 
 | 3677 |     } | 
 | 3678 |  | 
 | 3679 |     return ipmi::responseSuccess(); | 
 | 3680 | } | 
 | 3681 |  | 
| Jason M. Bills | 0748c69 | 2022-09-08 15:34:08 -0700 | [diff] [blame] | 3682 | using BasicVariantType = ipmi::DbusVariant; | 
| Cheng C Yang | 4e6ee15 | 2019-09-25 10:27:44 +0800 | [diff] [blame] | 3683 | using PropertyMapType = | 
 | 3684 |     boost::container::flat_map<std::string, BasicVariantType>; | 
 | 3685 | static constexpr const std::array<const char*, 1> psuPresenceTypes = { | 
 | 3686 |     "xyz.openbmc_project.Configuration.PSUPresence"}; | 
 | 3687 | int getPSUAddress(ipmi::Context::ptr ctx, uint8_t& bus, | 
 | 3688 |                   std::vector<uint64_t>& addrTable) | 
 | 3689 | { | 
 | 3690 |     boost::system::error_code ec; | 
 | 3691 |     GetSubTreeType subtree = ctx->bus->yield_method_call<GetSubTreeType>( | 
 | 3692 |         ctx->yield, ec, "xyz.openbmc_project.ObjectMapper", | 
 | 3693 |         "/xyz/openbmc_project/object_mapper", | 
 | 3694 |         "xyz.openbmc_project.ObjectMapper", "GetSubTree", | 
 | 3695 |         "/xyz/openbmc_project/inventory/system", 3, psuPresenceTypes); | 
 | 3696 |     if (ec) | 
 | 3697 |     { | 
 | 3698 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3699 |             "Failed to set dbus property to cold redundancy"); | 
 | 3700 |         return -1; | 
 | 3701 |     } | 
 | 3702 |     for (const auto& object : subtree) | 
 | 3703 |     { | 
 | 3704 |         std::string pathName = object.first; | 
 | 3705 |         for (const auto& serviceIface : object.second) | 
 | 3706 |         { | 
 | 3707 |             std::string serviceName = serviceIface.first; | 
 | 3708 |  | 
 | 3709 |             ec.clear(); | 
 | 3710 |             PropertyMapType propMap = | 
 | 3711 |                 ctx->bus->yield_method_call<PropertyMapType>( | 
 | 3712 |                     ctx->yield, ec, serviceName, pathName, | 
 | 3713 |                     "org.freedesktop.DBus.Properties", "GetAll", | 
 | 3714 |                     "xyz.openbmc_project.Configuration.PSUPresence"); | 
 | 3715 |             if (ec) | 
 | 3716 |             { | 
 | 3717 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3718 |                     "Failed to set dbus property to cold redundancy"); | 
 | 3719 |                 return -1; | 
 | 3720 |             } | 
 | 3721 |             auto psuBus = std::get_if<uint64_t>(&propMap["Bus"]); | 
 | 3722 |             auto psuAddress = | 
 | 3723 |                 std::get_if<std::vector<uint64_t>>(&propMap["Address"]); | 
 | 3724 |  | 
 | 3725 |             if (psuBus == nullptr || psuAddress == nullptr) | 
 | 3726 |             { | 
 | 3727 |                 std::cerr << "error finding necessary " | 
 | 3728 |                              "entry in configuration\n"; | 
 | 3729 |                 return -1; | 
 | 3730 |             } | 
 | 3731 |             bus = static_cast<uint8_t>(*psuBus); | 
 | 3732 |             addrTable = *psuAddress; | 
 | 3733 |             return 0; | 
 | 3734 |         } | 
 | 3735 |     } | 
 | 3736 |     return -1; | 
 | 3737 | } | 
 | 3738 |  | 
 | 3739 | static const constexpr uint8_t addrOffset = 8; | 
 | 3740 | static const constexpr uint8_t psuRevision = 0xd9; | 
 | 3741 | static const constexpr uint8_t defaultPSUBus = 7; | 
 | 3742 | // Second Minor, Primary Minor, Major | 
 | 3743 | static const constexpr size_t verLen = 3; | 
 | 3744 | ipmi::RspType<std::vector<uint8_t>> ipmiOEMGetPSUVersion(ipmi::Context::ptr ctx) | 
 | 3745 | { | 
 | 3746 |     uint8_t bus = defaultPSUBus; | 
 | 3747 |     std::vector<uint64_t> addrTable; | 
 | 3748 |     std::vector<uint8_t> result; | 
 | 3749 |     if (getPSUAddress(ctx, bus, addrTable)) | 
 | 3750 |     { | 
 | 3751 |         std::cerr << "Failed to get PSU bus and address\n"; | 
 | 3752 |         return ipmi::responseResponseError(); | 
 | 3753 |     } | 
 | 3754 |  | 
| Matt Simmering | 80d4d5f | 2023-02-15 15:18:51 -0800 | [diff] [blame] | 3755 |     for (const auto& targetAddr : addrTable) | 
| Cheng C Yang | 4e6ee15 | 2019-09-25 10:27:44 +0800 | [diff] [blame] | 3756 |     { | 
 | 3757 |         std::vector<uint8_t> writeData = {psuRevision}; | 
 | 3758 |         std::vector<uint8_t> readBuf(verLen); | 
| Matt Simmering | 80d4d5f | 2023-02-15 15:18:51 -0800 | [diff] [blame] | 3759 |         uint8_t addr = static_cast<uint8_t>(targetAddr) + addrOffset; | 
| Cheng C Yang | 4e6ee15 | 2019-09-25 10:27:44 +0800 | [diff] [blame] | 3760 |         std::string i2cBus = "/dev/i2c-" + std::to_string(bus); | 
 | 3761 |  | 
 | 3762 |         auto retI2C = ipmi::i2cWriteRead(i2cBus, addr, writeData, readBuf); | 
 | 3763 |         if (retI2C != ipmi::ccSuccess) | 
 | 3764 |         { | 
 | 3765 |             for (size_t idx = 0; idx < verLen; idx++) | 
 | 3766 |             { | 
 | 3767 |                 result.emplace_back(0x00); | 
 | 3768 |             } | 
 | 3769 |         } | 
 | 3770 |         else | 
 | 3771 |         { | 
 | 3772 |             for (const uint8_t& data : readBuf) | 
 | 3773 |             { | 
 | 3774 |                 result.emplace_back(data); | 
 | 3775 |             } | 
 | 3776 |         } | 
 | 3777 |     } | 
 | 3778 |  | 
 | 3779 |     return ipmi::responseSuccess(result); | 
 | 3780 | } | 
 | 3781 |  | 
| srikanta mondal | 2030d7c | 2020-05-03 17:25:25 +0000 | [diff] [blame] | 3782 | std::optional<uint8_t> getMultiNodeInfoPresence(ipmi::Context::ptr ctx, | 
 | 3783 |                                                 const std::string& name) | 
 | 3784 | { | 
 | 3785 |     Value dbusValue = 0; | 
 | 3786 |     std::string serviceName; | 
 | 3787 |  | 
 | 3788 |     boost::system::error_code ec = | 
 | 3789 |         ipmi::getService(ctx, multiNodeIntf, multiNodeObjPath, serviceName); | 
 | 3790 |  | 
 | 3791 |     if (ec) | 
 | 3792 |     { | 
 | 3793 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3794 |             "Failed to perform Multinode getService."); | 
 | 3795 |         return std::nullopt; | 
 | 3796 |     } | 
 | 3797 |  | 
 | 3798 |     ec = ipmi::getDbusProperty(ctx, serviceName, multiNodeObjPath, | 
 | 3799 |                                multiNodeIntf, name, dbusValue); | 
 | 3800 |     if (ec) | 
 | 3801 |     { | 
 | 3802 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3803 |             "Failed to perform Multinode get property"); | 
 | 3804 |         return std::nullopt; | 
 | 3805 |     } | 
 | 3806 |  | 
 | 3807 |     auto multiNodeVal = std::get_if<uint8_t>(&dbusValue); | 
 | 3808 |     if (!multiNodeVal) | 
 | 3809 |     { | 
 | 3810 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3811 |             "getMultiNodeInfoPresence: error to get multinode"); | 
 | 3812 |         return std::nullopt; | 
 | 3813 |     } | 
 | 3814 |     return *multiNodeVal; | 
 | 3815 | } | 
 | 3816 |  | 
 | 3817 | /** @brief implements OEM get reading command | 
 | 3818 |  *  @param domain ID | 
 | 3819 |  *  @param reading Type | 
 | 3820 |  *    - 00h = platform Power Consumption | 
 | 3821 |  *    - 01h = inlet Air Temp | 
 | 3822 |  *    - 02h = icc_TDC from PECI | 
 | 3823 |  *  @param reserved, write as 0000h | 
 | 3824 |  * | 
 | 3825 |  *  @returns IPMI completion code plus response data | 
 | 3826 |  *  - response | 
 | 3827 |  *     - domain ID | 
 | 3828 |  *     - reading Type | 
 | 3829 |  *       - 00h = platform Power Consumption | 
 | 3830 |  *       - 01h = inlet Air Temp | 
 | 3831 |  *       - 02h = icc_TDC from PECI | 
 | 3832 |  *     - reading | 
 | 3833 |  */ | 
 | 3834 | ipmi::RspType<uint4_t, // domain ID | 
 | 3835 |               uint4_t, // reading Type | 
 | 3836 |               uint16_t // reading Value | 
 | 3837 |               > | 
 | 3838 |     ipmiOEMGetReading(ipmi::Context::ptr ctx, uint4_t domainId, | 
 | 3839 |                       uint4_t readingType, uint16_t reserved) | 
 | 3840 | { | 
 | 3841 |     constexpr uint8_t platformPower = 0; | 
 | 3842 |     constexpr uint8_t inletAirTemp = 1; | 
 | 3843 |     constexpr uint8_t iccTdc = 2; | 
 | 3844 |  | 
 | 3845 |     if ((static_cast<uint8_t>(readingType) > iccTdc) || domainId || reserved) | 
 | 3846 |     { | 
 | 3847 |         return ipmi::responseInvalidFieldRequest(); | 
 | 3848 |     } | 
 | 3849 |  | 
 | 3850 |     // This command should run only from multi-node product. | 
 | 3851 |     // For all other platforms this command will return invalid. | 
 | 3852 |  | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 3853 |     std::optional<uint8_t> nodeInfo = getMultiNodeInfoPresence(ctx, | 
 | 3854 |                                                                "NodePresence"); | 
| srikanta mondal | 2030d7c | 2020-05-03 17:25:25 +0000 | [diff] [blame] | 3855 |     if (!nodeInfo || !*nodeInfo) | 
 | 3856 |     { | 
 | 3857 |         return ipmi::responseInvalidCommand(); | 
 | 3858 |     } | 
 | 3859 |  | 
 | 3860 |     uint16_t oemReadingValue = 0; | 
 | 3861 |     if (static_cast<uint8_t>(readingType) == inletAirTemp) | 
 | 3862 |     { | 
 | 3863 |         double value = 0; | 
 | 3864 |         boost::system::error_code ec = ipmi::getDbusProperty( | 
 | 3865 |             ctx, "xyz.openbmc_project.HwmonTempSensor", | 
 | 3866 |             "/xyz/openbmc_project/sensors/temperature/Inlet_BRD_Temp", | 
 | 3867 |             "xyz.openbmc_project.Sensor.Value", "Value", value); | 
 | 3868 |         if (ec) | 
 | 3869 |         { | 
 | 3870 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3871 |                 "Failed to get BMC Get OEM temperature", | 
 | 3872 |                 phosphor::logging::entry("EXCEPTION=%s", ec.message().c_str())); | 
 | 3873 |             return ipmi::responseUnspecifiedError(); | 
 | 3874 |         } | 
 | 3875 |         // Take the Inlet temperature | 
 | 3876 |         oemReadingValue = static_cast<uint16_t>(value); | 
 | 3877 |     } | 
 | 3878 |     else | 
 | 3879 |     { | 
 | 3880 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3881 |             "Currently Get OEM Reading support only for Inlet Air Temp"); | 
 | 3882 |         return ipmi::responseParmOutOfRange(); | 
 | 3883 |     } | 
 | 3884 |     return ipmi::responseSuccess(domainId, readingType, oemReadingValue); | 
 | 3885 | } | 
 | 3886 |  | 
| AppaRao Puli | 2897206 | 2019-11-11 02:04:45 +0530 | [diff] [blame] | 3887 | /** @brief implements the maximum size of | 
 | 3888 |  *  bridgeable messages used between KCS and | 
 | 3889 |  *  IPMB interfacesget security mode command. | 
 | 3890 |  * | 
 | 3891 |  *  @returns IPMI completion code with following data | 
 | 3892 |  *   - KCS Buffer Size (In multiples of four bytes) | 
 | 3893 |  *   - IPMB Buffer Size (In multiples of four bytes) | 
 | 3894 |  **/ | 
 | 3895 | ipmi::RspType<uint8_t, uint8_t> ipmiOEMGetBufferSize() | 
 | 3896 | { | 
 | 3897 |     // for now this is hard coded; really this number is dependent on | 
 | 3898 |     // the BMC kcs driver as well as the host kcs driver.... | 
 | 3899 |     // we can't know the latter. | 
 | 3900 |     uint8_t kcsMaxBufferSize = 63 / 4; | 
 | 3901 |     uint8_t ipmbMaxBufferSize = 128 / 4; | 
 | 3902 |  | 
 | 3903 |     return ipmi::responseSuccess(kcsMaxBufferSize, ipmbMaxBufferSize); | 
 | 3904 | } | 
 | 3905 |  | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 3906 | ipmi::RspType<std::vector<uint8_t>> | 
 | 3907 |     ipmiOEMReadPFRMailbox(ipmi::Context::ptr& ctx, const uint8_t readRegister, | 
 | 3908 |                           const uint8_t numOfBytes, uint8_t registerIdentifier) | 
 | 3909 | { | 
 | 3910 |     if (!ipmi::mailbox::i2cConfigLoaded) | 
 | 3911 |     { | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 3912 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
| Matt Simmering | 80d4d5f | 2023-02-15 15:18:51 -0800 | [diff] [blame] | 3913 |             "Calling PFR Load Configuration Function to Get I2C Bus and Target " | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 3914 |             "Address "); | 
 | 3915 |  | 
 | 3916 |         ipmi::mailbox::loadPfrConfig(ctx, ipmi::mailbox::i2cConfigLoaded); | 
 | 3917 |     } | 
 | 3918 |  | 
 | 3919 |     if (!numOfBytes && !readRegister) | 
 | 3920 |     { | 
 | 3921 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3922 |             "OEM IPMI command: Read & write count are 0 which is invalid "); | 
 | 3923 |         return ipmi::responseInvalidFieldRequest(); | 
 | 3924 |     } | 
 | 3925 |  | 
 | 3926 |     switch (registerIdentifier) | 
 | 3927 |     { | 
 | 3928 |         case ipmi::mailbox::registerType::fifoReadRegister: | 
 | 3929 |         { | 
 | 3930 |             // Check if readRegister is an FIFO read register | 
 | 3931 |             if (registerIdentifier == 1) | 
 | 3932 |             { | 
 | 3933 |                 if (ipmi::mailbox::readFifoReg.find(readRegister) == | 
 | 3934 |                     ipmi::mailbox::readFifoReg.end()) | 
 | 3935 |                 { | 
 | 3936 |                     phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3937 |                         "OEM IPMI command: Register is not a Read FIFO  "); | 
 | 3938 |                     return ipmi::responseInvalidFieldRequest(); | 
 | 3939 |                 } | 
 | 3940 |  | 
 | 3941 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3942 |                     "OEM IPMI command: Register is a Read FIFO  "); | 
 | 3943 |  | 
 | 3944 |                 ipmi::mailbox::writefifo(ipmi::mailbox::provisioningCommand, | 
 | 3945 |                                          readRegister); | 
 | 3946 |                 ipmi::mailbox::writefifo(ipmi::mailbox::triggerCommand, | 
 | 3947 |                                          ipmi::mailbox::flushRead); | 
 | 3948 |  | 
 | 3949 |                 std::vector<uint8_t> writeData = {ipmi::mailbox::readFifo}; | 
 | 3950 |                 std::vector<uint8_t> readBuf(1); | 
 | 3951 |                 std::vector<uint8_t> result; | 
 | 3952 |  | 
 | 3953 |                 for (int i = 0; i < numOfBytes; i++) | 
 | 3954 |                 { | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 3955 |                     ipmi::Cc ret = ipmi::i2cWriteRead(ipmi::mailbox::i2cBus, | 
| Matt Simmering | 80d4d5f | 2023-02-15 15:18:51 -0800 | [diff] [blame] | 3956 |                                                       ipmi::mailbox::targetAddr, | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 3957 |                                                       writeData, readBuf); | 
 | 3958 |                     if (ret != ipmi::ccSuccess) | 
 | 3959 |                     { | 
 | 3960 |                         return ipmi::response(ret); | 
 | 3961 |                     } | 
 | 3962 |  | 
 | 3963 |                     else | 
 | 3964 |                     { | 
 | 3965 |                         for (const uint8_t& data : readBuf) | 
 | 3966 |                         { | 
 | 3967 |                             result.emplace_back(data); | 
 | 3968 |                         } | 
 | 3969 |                     } | 
 | 3970 |                 } | 
 | 3971 |  | 
 | 3972 |                 return ipmi::responseSuccess(result); | 
 | 3973 |             } | 
 | 3974 |         } | 
 | 3975 |  | 
 | 3976 |         case ipmi::mailbox::registerType::singleByteRegister: | 
 | 3977 |         { | 
 | 3978 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3979 |                 "OEM IPMI command: Register is a Single Byte Register "); | 
 | 3980 |  | 
 | 3981 |             std::vector<uint8_t> writeData = {readRegister}; | 
 | 3982 |             std::vector<uint8_t> readBuf(numOfBytes); | 
 | 3983 |  | 
 | 3984 |             ipmi::Cc ret = ipmi::i2cWriteRead(ipmi::mailbox::i2cBus, | 
| Matt Simmering | 80d4d5f | 2023-02-15 15:18:51 -0800 | [diff] [blame] | 3985 |                                               ipmi::mailbox::targetAddr, | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 3986 |                                               writeData, readBuf); | 
 | 3987 |             if (ret != ipmi::ccSuccess) | 
 | 3988 |             { | 
 | 3989 |                 return ipmi::response(ret); | 
 | 3990 |             } | 
 | 3991 |             return ipmi::responseSuccess(readBuf); | 
 | 3992 |         } | 
 | 3993 |  | 
 | 3994 |         default: | 
 | 3995 |         { | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 3996 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 3997 |                 "OEM IPMI command: Register identifier is not valid.It should " | 
 | 3998 |                 "be 0 " | 
 | 3999 |                 "for Single Byte Register and 1 for FIFO Read Register"); | 
 | 4000 |  | 
 | 4001 |             return ipmi::responseInvalidFieldRequest(); | 
 | 4002 |         } | 
 | 4003 |     } | 
 | 4004 | } | 
 | 4005 |  | 
| Jason M. Bills | 6479604 | 2018-10-03 16:51:55 -0700 | [diff] [blame] | 4006 | static void registerOEMFunctions(void) | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 4007 | { | 
 | 4008 |     phosphor::logging::log<phosphor::logging::level::INFO>( | 
 | 4009 |         "Registering OEM commands"); | 
| Vernon Mauery | af65268 | 2023-08-04 13:37:21 -0700 | [diff] [blame] | 4010 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4011 |                     intel::general::cmdGetBmcVersionString, Privilege::User, | 
 | 4012 |                     ipmiOEMGetBmcVersionString); | 
 | 4013 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4014 |     ipmiPrintAndRegister(intel::netFnGeneral, | 
 | 4015 |                          intel::general::cmdGetChassisIdentifier, NULL, | 
 | 4016 |                          ipmiOEMGetChassisIdentifier, | 
 | 4017 |                          PRIVILEGE_USER); // get chassis identifier | 
 | 4018 |  | 
 | 4019 |     ipmiPrintAndRegister(intel::netFnGeneral, intel::general::cmdSetSystemGUID, | 
 | 4020 |                          NULL, ipmiOEMSetSystemGUID, | 
 | 4021 |                          PRIVILEGE_ADMIN); // set system guid | 
| Jason M. Bills | b02bf09 | 2019-08-15 13:01:56 -0700 | [diff] [blame] | 4022 |  | 
 | 4023 |     // <Disable BMC System Reset Action> | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4024 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4025 |                     intel::general::cmdDisableBMCSystemReset, Privilege::Admin, | 
 | 4026 |                     ipmiOEMDisableBMCSystemReset); | 
 | 4027 |  | 
| Jason M. Bills | b02bf09 | 2019-08-15 13:01:56 -0700 | [diff] [blame] | 4028 |     // <Get BMC Reset Disables> | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4029 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4030 |                     intel::general::cmdGetBMCResetDisables, Privilege::Admin, | 
 | 4031 |                     ipmiOEMGetBMCResetDisables); | 
| Jason M. Bills | b02bf09 | 2019-08-15 13:01:56 -0700 | [diff] [blame] | 4032 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4033 |     ipmiPrintAndRegister(intel::netFnGeneral, intel::general::cmdSetBIOSID, | 
 | 4034 |                          NULL, ipmiOEMSetBIOSID, PRIVILEGE_ADMIN); | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 4035 |  | 
| Chen Yugang | 7a04f3a | 2019-10-08 11:12:35 +0800 | [diff] [blame] | 4036 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4037 |                     intel::general::cmdGetOEMDeviceInfo, Privilege::User, | 
 | 4038 |                     ipmiOEMGetDeviceInfo); | 
| Jia, Chunhui | cc49b54 | 2019-03-20 15:41:07 +0800 | [diff] [blame] | 4039 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4040 |     ipmiPrintAndRegister(intel::netFnGeneral, | 
 | 4041 |                          intel::general::cmdGetAICSlotFRUIDSlotPosRecords, NULL, | 
 | 4042 |                          ipmiOEMGetAICFRU, PRIVILEGE_USER); | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 4043 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4044 |     registerHandler(prioOpenBmcBase, intel::netFnGeneral, | 
 | 4045 |                     intel::general::cmdSendEmbeddedFWUpdStatus, | 
 | 4046 |                     Privilege::Operator, ipmiOEMSendEmbeddedFwUpdStatus); | 
| Suryakanth Sekar | d509eb9 | 2018-11-15 17:44:11 +0530 | [diff] [blame] | 4047 |  | 
| Rajashekar Gade Reddy | 2b664d5 | 2020-03-23 22:09:00 +0530 | [diff] [blame] | 4048 |     registerHandler(prioOpenBmcBase, intel::netFnApp, intel::app::cmdSlotIpmb, | 
 | 4049 |                     Privilege::Admin, ipmiOEMSlotIpmb); | 
 | 4050 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4051 |     ipmiPrintAndRegister(intel::netFnGeneral, | 
 | 4052 |                          intel::general::cmdSetPowerRestoreDelay, NULL, | 
 | 4053 |                          ipmiOEMSetPowerRestoreDelay, PRIVILEGE_OPERATOR); | 
 | 4054 |  | 
 | 4055 |     ipmiPrintAndRegister(intel::netFnGeneral, | 
 | 4056 |                          intel::general::cmdGetPowerRestoreDelay, NULL, | 
 | 4057 |                          ipmiOEMGetPowerRestoreDelay, PRIVILEGE_USER); | 
 | 4058 |  | 
 | 4059 |     registerHandler(prioOpenBmcBase, intel::netFnGeneral, | 
 | 4060 |                     intel::general::cmdSetOEMUser2Activation, | 
 | 4061 |                     Privilege::Callback, ipmiOEMSetUser2Activation); | 
 | 4062 |  | 
 | 4063 |     registerHandler(prioOpenBmcBase, intel::netFnGeneral, | 
 | 4064 |                     intel::general::cmdSetSpecialUserPassword, | 
 | 4065 |                     Privilege::Callback, ipmiOEMSetSpecialUserPassword); | 
| Richard Marian Thomaiyar | fc5e985 | 2019-04-14 15:06:27 +0530 | [diff] [blame] | 4066 |  | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 4067 |     // <Get Processor Error Config> | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4068 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4069 |                     intel::general::cmdGetProcessorErrConfig, Privilege::User, | 
 | 4070 |                     ipmiOEMGetProcessorErrConfig); | 
 | 4071 |  | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 4072 |     // <Set Processor Error Config> | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4073 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4074 |                     intel::general::cmdSetProcessorErrConfig, Privilege::Admin, | 
 | 4075 |                     ipmiOEMSetProcessorErrConfig); | 
| Jason M. Bills | 42bd9c8 | 2019-06-28 16:39:34 -0700 | [diff] [blame] | 4076 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4077 |     ipmiPrintAndRegister(intel::netFnGeneral, | 
 | 4078 |                          intel::general::cmdSetShutdownPolicy, NULL, | 
 | 4079 |                          ipmiOEMSetShutdownPolicy, PRIVILEGE_ADMIN); | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 4080 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4081 |     ipmiPrintAndRegister(intel::netFnGeneral, | 
 | 4082 |                          intel::general::cmdGetShutdownPolicy, NULL, | 
 | 4083 |                          ipmiOEMGetShutdownPolicy, PRIVILEGE_ADMIN); | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 4084 |  | 
| anil kumar appana | f945eee | 2019-09-25 23:29:11 +0000 | [diff] [blame] | 4085 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4086 |                     intel::general::cmdSetFanConfig, Privilege::User, | 
 | 4087 |                     ipmiOEMSetFanConfig); | 
| James Feist | 91244a6 | 2019-02-19 15:04:54 -0800 | [diff] [blame] | 4088 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4089 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4090 |                     intel::general::cmdGetFanConfig, Privilege::User, | 
 | 4091 |                     ipmiOEMGetFanConfig); | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 4092 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4093 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4094 |                     intel::general::cmdGetFanSpeedOffset, Privilege::User, | 
 | 4095 |                     ipmiOEMGetFanSpeedOffset); | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 4096 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4097 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4098 |                     intel::general::cmdSetFanSpeedOffset, Privilege::User, | 
 | 4099 |                     ipmiOEMSetFanSpeedOffset); | 
| James Feist | acc8a4e | 2019-04-02 14:23:57 -0700 | [diff] [blame] | 4100 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4101 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4102 |                     intel::general::cmdSetFscParameter, Privilege::User, | 
 | 4103 |                     ipmiOEMSetFscParameter); | 
| James Feist | 5f957ca | 2019-03-14 15:33:55 -0700 | [diff] [blame] | 4104 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4105 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4106 |                     intel::general::cmdGetFscParameter, Privilege::User, | 
 | 4107 |                     ipmiOEMGetFscParameter); | 
| Richard Marian Thomaiyar | ea537d5 | 2019-04-24 21:33:48 +0530 | [diff] [blame] | 4108 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4109 |     registerHandler(prioOpenBmcBase, intel::netFnGeneral, | 
 | 4110 |                     intel::general::cmdReadBaseBoardProductId, Privilege::Admin, | 
 | 4111 |                     ipmiOEMReadBoardProductId); | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 4112 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4113 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4114 |                     intel::general::cmdGetNmiStatus, Privilege::User, | 
 | 4115 |                     ipmiOEMGetNmiSource); | 
| Chen Yugang | 39736d5 | 2019-07-12 16:24:33 +0800 | [diff] [blame] | 4116 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4117 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4118 |                     intel::general::cmdSetNmiStatus, Privilege::Operator, | 
 | 4119 |                     ipmiOEMSetNmiSource); | 
| Chen,Yugang | 4f7e76b | 2019-08-20 09:28:06 +0800 | [diff] [blame] | 4120 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4121 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4122 |                     intel::general::cmdGetEfiBootOptions, Privilege::User, | 
 | 4123 |                     ipmiOemGetEfiBootOptions); | 
| Chen,Yugang | 4f7e76b | 2019-08-20 09:28:06 +0800 | [diff] [blame] | 4124 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4125 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4126 |                     intel::general::cmdSetEfiBootOptions, Privilege::Operator, | 
 | 4127 |                     ipmiOemSetEfiBootOptions); | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 4128 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4129 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4130 |                     intel::general::cmdGetSecurityMode, Privilege::User, | 
 | 4131 |                     ipmiGetSecurityMode); | 
| Richard Marian Thomaiyar | d801e46 | 2019-06-20 01:05:40 +0530 | [diff] [blame] | 4132 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4133 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4134 |                     intel::general::cmdSetSecurityMode, Privilege::Admin, | 
 | 4135 |                     ipmiSetSecurityMode); | 
| Vernon Mauery | 4ac799d | 2019-05-20 15:50:37 -0700 | [diff] [blame] | 4136 |  | 
| NITIN SHARMA | abd11ca | 2019-06-12 12:31:42 +0000 | [diff] [blame] | 4137 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4138 |                     intel::general::cmdGetLEDStatus, Privilege::Admin, | 
 | 4139 |                     ipmiOEMGetLEDStatus); | 
| Cheng C Yang | 773703a | 2019-08-15 09:41:11 +0800 | [diff] [blame] | 4140 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4141 |     ipmiPrintAndRegister(ipmi::intel::netFnPlatform, | 
 | 4142 |                          ipmi::intel::platform::cmdCfgHostSerialPortSpeed, NULL, | 
 | 4143 |                          ipmiOEMCfgHostSerialPortSpeed, PRIVILEGE_ADMIN); | 
 | 4144 |  | 
 | 4145 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4146 |                     intel::general::cmdSetFaultIndication, Privilege::Operator, | 
 | 4147 |                     ipmiOEMSetFaultIndication); | 
 | 4148 |  | 
 | 4149 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4150 |                     intel::general::cmdSetColdRedundancyConfig, Privilege::User, | 
 | 4151 |                     ipmiOEMSetCRConfig); | 
 | 4152 |  | 
 | 4153 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4154 |                     intel::general::cmdGetColdRedundancyConfig, Privilege::User, | 
 | 4155 |                     ipmiOEMGetCRConfig); | 
 | 4156 |  | 
 | 4157 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4158 |                     intel::general::cmdRestoreConfiguration, Privilege::Admin, | 
| Vernon Mauery | 4ac799d | 2019-05-20 15:50:37 -0700 | [diff] [blame] | 4159 |                     ipmiRestoreConfiguration); | 
| James Feist | 63efafa | 2019-07-24 12:39:21 -0700 | [diff] [blame] | 4160 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4161 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4162 |                     intel::general::cmdSetDimmOffset, Privilege::Operator, | 
 | 4163 |                     ipmiOEMSetDimmOffset); | 
| James Feist | 63efafa | 2019-07-24 12:39:21 -0700 | [diff] [blame] | 4164 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 4165 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4166 |                     intel::general::cmdGetDimmOffset, Privilege::Operator, | 
 | 4167 |                     ipmiOEMGetDimmOffset); | 
| Chen Yugang | ca12a7b | 2019-09-03 18:11:44 +0800 | [diff] [blame] | 4168 |  | 
| Cheng C Yang | 4e6ee15 | 2019-09-25 10:27:44 +0800 | [diff] [blame] | 4169 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4170 |                     intel::general::cmdGetPSUVersion, Privilege::User, | 
 | 4171 |                     ipmiOEMGetPSUVersion); | 
| AppaRao Puli | 2897206 | 2019-11-11 02:04:45 +0530 | [diff] [blame] | 4172 |  | 
 | 4173 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4174 |                     intel::general::cmdGetBufferSize, Privilege::User, | 
 | 4175 |                     ipmiOEMGetBufferSize); | 
| srikanta mondal | 2030d7c | 2020-05-03 17:25:25 +0000 | [diff] [blame] | 4176 |  | 
 | 4177 |     registerHandler(prioOemBase, intel::netFnGeneral, | 
 | 4178 |                     intel::general::cmdOEMGetReading, Privilege::User, | 
 | 4179 |                     ipmiOEMGetReading); | 
| Ankita Vilas Gawade | a165038 | 2022-01-08 10:30:40 +0000 | [diff] [blame] | 4180 |  | 
 | 4181 |     registerHandler(prioOemBase, intel::netFnApp, intel::app::cmdPFRMailboxRead, | 
 | 4182 |                     Privilege::Admin, ipmiOEMReadPFRMailbox); | 
| Jia, Chunhui | a835eaa | 2018-09-05 09:00:41 +0800 | [diff] [blame] | 4183 | } | 
 | 4184 |  | 
 | 4185 | } // namespace ipmi |