1 #pragma once 2 3 #include "nlohmann/json.hpp" 4 5 #include <map> 6 #include <sdbusplus/bus.hpp> 7 #include <string> 8 #include <vector> 9 10 namespace dcmi 11 { 12 13 using NumInstances = size_t; 14 using Json = nlohmann::json; 15 16 enum Commands 17 { 18 // Get capability bits 19 GET_CAPABILITIES = 0x01, 20 GET_POWER_READING = 0x02, 21 GET_POWER_LIMIT = 0x03, 22 SET_POWER_LIMIT = 0x04, 23 APPLY_POWER_LIMIT = 0x05, 24 GET_ASSET_TAG = 0x06, 25 GET_SENSOR_INFO = 0x07, 26 SET_ASSET_TAG = 0x08, 27 GET_MGMNT_CTRL_ID_STR = 0x09, 28 SET_MGMNT_CTRL_ID_STR = 0x0A, 29 GET_TEMP_READINGS = 0x10, 30 SET_CONF_PARAMS = 0x12, 31 GET_CONF_PARAMS = 0x13, 32 }; 33 34 static constexpr auto propIntf = "org.freedesktop.DBus.Properties"; 35 static constexpr auto assetTagIntf = 36 "xyz.openbmc_project.Inventory.Decorator.AssetTag"; 37 static constexpr auto assetTagProp = "AssetTag"; 38 static constexpr auto networkServiceName = "xyz.openbmc_project.Network"; 39 static constexpr auto networkConfigObj = "/xyz/openbmc_project/network/config"; 40 static constexpr auto networkConfigIntf = 41 "xyz.openbmc_project.Network.SystemConfiguration"; 42 static constexpr auto hostNameProp = "HostName"; 43 static constexpr auto temperatureSensorType = 0x01; 44 static constexpr auto maxInstances = 255; 45 static constexpr auto gDCMISensorsConfig = 46 "/usr/share/ipmi-providers/dcmi_sensors.json"; 47 static constexpr auto ethernetIntf = 48 "xyz.openbmc_project.Network.EthernetInterface"; 49 static constexpr auto ethernetDefaultChannelNum = 0x1; 50 static constexpr auto networkRoot = "/xyz/openbmc_project/network"; 51 static constexpr auto dhcpObj = "/xyz/openbmc_project/network/config/dhcp"; 52 static constexpr auto dhcpIntf = 53 "xyz.openbmc_project.Network.DHCPConfiguration"; 54 static constexpr auto systemBusName = "org.freedesktop.systemd1"; 55 static constexpr auto systemPath = "/org/freedesktop/systemd1"; 56 static constexpr auto systemIntf = "org.freedesktop.systemd1.Manager"; 57 static constexpr auto gDCMICapabilitiesConfig = 58 "/usr/share/ipmi-providers/dcmi_cap.json"; 59 static constexpr auto gDCMIPowerMgmtCapability = "PowerManagement"; 60 static constexpr auto gDCMIPowerMgmtSupported = 0x1; 61 static constexpr auto gMaxSELEntriesMask = 0xFFF; 62 static constexpr auto gByteBitSize = 8; 63 64 namespace assettag 65 { 66 67 using ObjectPath = std::string; 68 using Service = std::string; 69 using Interfaces = std::vector<std::string>; 70 using ObjectTree = std::map<ObjectPath, std::map<Service, Interfaces>>; 71 72 } // namespace assettag 73 74 namespace temp_readings 75 { 76 static constexpr auto maxDataSets = 8; 77 static constexpr auto maxTemp = 127; // degrees C 78 79 /** @struct Response 80 * 81 * DCMI payload for Get Temperature Readings response 82 */ 83 struct Response 84 { 85 #if BYTE_ORDER == LITTLE_ENDIAN 86 uint8_t temperature : 7; //!< Temperature reading in Celsius 87 uint8_t sign : 1; //!< Sign bit 88 #endif 89 #if BYTE_ORDER == BIG_ENDIAN 90 uint8_t sign : 1; //!< Sign bit 91 uint8_t temperature : 7; //!< Temperature reading in Celsius 92 #endif 93 uint8_t instance; //!< Entity instance number 94 } __attribute__((packed)); 95 96 using ResponseList = std::vector<Response>; 97 using Value = uint8_t; 98 using Sign = bool; 99 using Temperature = std::tuple<Value, Sign>; 100 } // namespace temp_readings 101 102 namespace sensor_info 103 { 104 static constexpr auto maxRecords = 8; 105 106 /** @struct Response 107 * 108 * DCMI payload for Get Sensor Info response 109 */ 110 struct Response 111 { 112 uint8_t recordIdLsb; //!< SDR record id LS byte 113 uint8_t recordIdMsb; //!< SDR record id MS byte 114 } __attribute__((packed)); 115 116 using ResponseList = std::vector<Response>; 117 } // namespace sensor_info 118 119 static constexpr auto groupExtId = 0xDC; 120 121 static constexpr auto assetTagMaxOffset = 62; 122 static constexpr auto assetTagMaxSize = 63; 123 static constexpr auto maxBytes = 16; 124 static constexpr size_t maxCtrlIdStrLen = 63; 125 126 /** @struct GetAssetTagRequest 127 * 128 * DCMI payload for Get Asset Tag command request. 129 */ 130 struct GetAssetTagRequest 131 { 132 uint8_t offset; //!< Offset to read. 133 uint8_t bytes; //!< Number of bytes to read. 134 } __attribute__((packed)); 135 136 /** @struct GetAssetTagResponse 137 * 138 * DCMI payload for Get Asset Tag command response. 139 */ 140 struct GetAssetTagResponse 141 { 142 uint8_t tagLength; //!< Total asset tag length. 143 } __attribute__((packed)); 144 145 /** @struct SetAssetTagRequest 146 * 147 * DCMI payload for Set Asset Tag command request. 148 */ 149 struct SetAssetTagRequest 150 { 151 uint8_t offset; //!< Offset to write. 152 uint8_t bytes; //!< Number of bytes to write. 153 } __attribute__((packed)); 154 155 /** @struct SetAssetTagResponse 156 * 157 * DCMI payload for Set Asset Tag command response. 158 */ 159 struct SetAssetTagResponse 160 { 161 uint8_t tagLength; //!< Total asset tag length. 162 } __attribute__((packed)); 163 164 /** @brief Check whether DCMI power management is supported 165 * in the DCMI Capabilities config file. 166 * 167 * @return True if DCMI power management is supported 168 */ 169 bool isDCMIPowerMgmtSupported(); 170 171 /** @brief Read the object tree to fetch the object path that implemented the 172 * Asset tag interface. 173 * 174 * @param[in,out] objectTree - object tree 175 * 176 * @return On success return the object tree with the object path that 177 * implemented the AssetTag interface. 178 */ 179 void readAssetTagObjectTree(dcmi::assettag::ObjectTree& objectTree); 180 181 /** @brief Read the asset tag of the server 182 * 183 * @return On success return the asset tag. 184 */ 185 std::string readAssetTag(); 186 187 /** @brief Write the asset tag to the asset tag DBUS property 188 * 189 * @param[in] assetTag - Asset Tag to be written to the property. 190 */ 191 void writeAssetTag(const std::string& assetTag); 192 193 /** @brief Read the current power cap value 194 * 195 * @param[in] bus - dbus connection 196 * 197 * @return On success return the power cap value. 198 */ 199 uint32_t getPcap(sdbusplus::bus::bus& bus); 200 201 /** @brief Check if the power capping is enabled 202 * 203 * @param[in] bus - dbus connection 204 * 205 * @return true if the powerCap is enabled and false if the powercap 206 * is disabled. 207 */ 208 bool getPcapEnabled(sdbusplus::bus::bus& bus); 209 210 /** @struct GetPowerLimitResponse 211 * 212 * DCMI payload for Get Power Limit command response. 213 */ 214 struct GetPowerLimitResponse 215 { 216 uint16_t reserved; //!< Reserved. 217 uint8_t exceptionAction; //!< Exception action. 218 uint16_t powerLimit; //!< Power limit requested in watts. 219 uint32_t correctionTime; //!< Correction time limit in milliseconds. 220 uint16_t reserved1; //!< Reserved. 221 uint16_t samplingPeriod; //!< Statistics sampling period in seconds. 222 } __attribute__((packed)); 223 224 /** @brief Set the power cap value 225 * 226 * @param[in] bus - dbus connection 227 * @param[in] powerCap - power cap value 228 */ 229 void setPcap(sdbusplus::bus::bus& bus, const uint32_t powerCap); 230 231 /** @struct SetPowerLimitRequest 232 * 233 * DCMI payload for Set Power Limit command request. 234 */ 235 struct SetPowerLimitRequest 236 { 237 uint16_t reserved; //!< Reserved 238 uint8_t reserved1; //!< Reserved 239 uint8_t exceptionAction; //!< Exception action. 240 uint16_t powerLimit; //!< Power limit requested in watts. 241 uint32_t correctionTime; //!< Correction time limit in milliseconds. 242 uint16_t reserved2; //!< Reserved. 243 uint16_t samplingPeriod; //!< Statistics sampling period in seconds. 244 } __attribute__((packed)); 245 246 /** @brief Enable or disable the power capping 247 * 248 * @param[in] bus - dbus connection 249 * @param[in] enabled - enable/disable 250 */ 251 void setPcapEnable(sdbusplus::bus::bus& bus, bool enabled); 252 253 /** @struct ApplyPowerLimitRequest 254 * 255 * DCMI payload for Activate/Deactivate Power Limit command request. 256 */ 257 struct ApplyPowerLimitRequest 258 { 259 uint8_t powerLimitAction; //!< Power limit activation 260 uint16_t reserved; //!< Reserved 261 } __attribute__((packed)); 262 263 /** @struct GetMgmntCtrlIdStrRequest 264 * 265 * DCMI payload for Get Management Controller Identifier String cmd request. 266 */ 267 struct GetMgmntCtrlIdStrRequest 268 { 269 uint8_t offset; //!< Offset to read. 270 uint8_t bytes; //!< Number of bytes to read. 271 } __attribute__((packed)); 272 273 /** @struct GetMgmntCtrlIdStrResponse 274 * 275 * DCMI payload for Get Management Controller Identifier String cmd response. 276 */ 277 struct GetMgmntCtrlIdStrResponse 278 { 279 uint8_t strLen; //!< ID string length. 280 char data[]; //!< ID string 281 } __attribute__((packed)); 282 283 /** @struct SetMgmntCtrlIdStrRequest 284 * 285 * DCMI payload for Set Management Controller Identifier String cmd request. 286 */ 287 struct SetMgmntCtrlIdStrRequest 288 { 289 uint8_t offset; //!< Offset to write. 290 uint8_t bytes; //!< Number of bytes to read. 291 char data[]; //!< ID string 292 } __attribute__((packed)); 293 294 /** @struct GetMgmntCtrlIdStrResponse 295 * 296 * DCMI payload for Get Management Controller Identifier String cmd response. 297 */ 298 struct SetMgmntCtrlIdStrResponse 299 { 300 uint8_t offset; //!< Last Offset Written. 301 } __attribute__((packed)); 302 303 /** @enum DCMICapParameters 304 * 305 * DCMI Capability parameters 306 */ 307 enum class DCMICapParameters 308 { 309 SUPPORTED_DCMI_CAPS = 0x01, //!< Supported DCMI Capabilities 310 MANDATORY_PLAT_ATTRIBUTES = 0x02, //!< Mandatory Platform Attributes 311 OPTIONAL_PLAT_ATTRIBUTES = 0x03, //!< Optional Platform Attributes 312 MANAGEABILITY_ACCESS_ATTRIBUTES = 0x04, //!< Manageability Access Attributes 313 }; 314 315 /** @struct GetDCMICapRequest 316 * 317 * DCMI payload for Get capabilities cmd request. 318 */ 319 struct GetDCMICapRequest 320 { 321 uint8_t param; //!< Capability parameter selector. 322 } __attribute__((packed)); 323 324 /** @struct GetDCMICapRequest 325 * 326 * DCMI payload for Get capabilities cmd response. 327 */ 328 struct GetDCMICapResponse 329 { 330 uint8_t major; //!< DCMI Specification Conformance - major ver 331 uint8_t minor; //!< DCMI Specification Conformance - minor ver 332 uint8_t paramRevision; //!< Parameter Revision = 02h 333 uint8_t data[]; //!< Capability array 334 } __attribute__((packed)); 335 336 /** @struct DCMICap 337 * 338 * DCMI capabilities protocol info. 339 */ 340 struct DCMICap 341 { 342 std::string name; //!< Name of DCMI capability. 343 uint8_t bytePosition; //!< Starting byte number from DCMI spec. 344 uint8_t position; //!< bit position from the DCMI spec. 345 uint8_t length; //!< Length of the value from DCMI spec. 346 }; 347 348 using DCMICapList = std::vector<DCMICap>; 349 350 /** @struct DCMICapEntry 351 * 352 * DCMI capabilities list and size for each parameter. 353 */ 354 struct DCMICapEntry 355 { 356 uint8_t size; //!< Size of capability array in bytes. 357 DCMICapList capList; //!< List of capabilities for a parameter. 358 }; 359 360 using DCMICaps = std::map<DCMICapParameters, DCMICapEntry>; 361 362 /** @struct GetTempReadingsRequest 363 * 364 * DCMI payload for Get Temperature Readings request 365 */ 366 struct GetTempReadingsRequest 367 { 368 uint8_t sensorType; //!< Type of the sensor 369 uint8_t entityId; //!< Entity ID 370 uint8_t entityInstance; //!< Entity Instance (0 means all instances) 371 uint8_t instanceStart; //!< Instance start (used if instance is 0) 372 } __attribute__((packed)); 373 374 /** @struct GetTempReadingsResponse 375 * 376 * DCMI header for Get Temperature Readings response 377 */ 378 struct GetTempReadingsResponseHdr 379 { 380 uint8_t numInstances; //!< No. of instances for requested id 381 uint8_t numDataSets; //!< No. of sets of temperature data 382 } __attribute__((packed)); 383 384 /** @brief Parse out JSON config file. 385 * 386 * @param[in] configFile - JSON config file name 387 * 388 * @return A json object 389 */ 390 Json parseJSONConfig(const std::string& configFile); 391 392 namespace temp_readings 393 { 394 /** @brief Read temperature from a d-bus object, scale it as per dcmi 395 * get temperature reading requirements. 396 * 397 * @param[in] dbusService - the D-Bus service 398 * @param[in] dbusPath - the D-Bus path 399 * 400 * @return A temperature reading 401 */ 402 Temperature readTemp(const std::string& dbusService, 403 const std::string& dbusPath); 404 405 /** @brief Read temperatures and fill up DCMI response for the Get 406 * Temperature Readings command. This looks at a specific 407 * instance. 408 * 409 * @param[in] type - one of "inlet", "cpu", "baseboard" 410 * @param[in] instance - A non-zero Entity instance number 411 * 412 * @return A tuple, containing a temperature reading and the 413 * number of instances. 414 */ 415 std::tuple<Response, NumInstances> read(const std::string& type, 416 uint8_t instance); 417 418 /** @brief Read temperatures and fill up DCMI response for the Get 419 * Temperature Readings command. This looks at a range of 420 * instances. 421 * 422 * @param[in] type - one of "inlet", "cpu", "baseboard" 423 * @param[in] instanceStart - Entity instance start index 424 * 425 * @return A tuple, containing a list of temperature readings and the 426 * number of instances. 427 */ 428 std::tuple<ResponseList, NumInstances> readAll(const std::string& type, 429 uint8_t instanceStart); 430 } // namespace temp_readings 431 432 namespace sensor_info 433 { 434 /** @brief Create response from JSON config. 435 * 436 * @param[in] config - JSON config info about DCMI sensors 437 * 438 * @return Sensor info response 439 */ 440 Response createFromJson(const Json& config); 441 442 /** @brief Read sensor info and fill up DCMI response for the Get 443 * Sensor Info command. This looks at a specific 444 * instance. 445 * 446 * @param[in] type - one of "inlet", "cpu", "baseboard" 447 * @param[in] instance - A non-zero Entity instance number 448 * @param[in] config - JSON config info about DCMI sensors 449 * 450 * @return A tuple, containing a sensor info response and 451 * number of instances. 452 */ 453 std::tuple<Response, NumInstances> read(const std::string& type, 454 uint8_t instance, const Json& config); 455 456 /** @brief Read sensor info and fill up DCMI response for the Get 457 * Sensor Info command. This looks at a range of 458 * instances. 459 * 460 * @param[in] type - one of "inlet", "cpu", "baseboard" 461 * @param[in] instanceStart - Entity instance start index 462 * @param[in] config - JSON config info about DCMI sensors 463 * 464 * @return A tuple, containing a list of sensor info responses and the 465 * number of instances. 466 */ 467 std::tuple<ResponseList, NumInstances> 468 readAll(const std::string& type, uint8_t instanceStart, const Json& config); 469 } // namespace sensor_info 470 471 /** @brief Read power reading from power reading sensor object 472 * 473 * @param[in] bus - dbus connection 474 * 475 * @return total power reading 476 */ 477 int64_t getPowerReading(sdbusplus::bus::bus& bus); 478 479 /** @struct GetPowerReadingRequest 480 * 481 * DCMI Get Power Reading command request. 482 * Refer DCMI specification Version 1.1 Section 6.6.1 483 */ 484 struct GetPowerReadingRequest 485 { 486 uint8_t mode; //!< Mode 487 uint8_t modeAttribute; //!< Mode Attributes 488 } __attribute__((packed)); 489 490 /** @struct GetPowerReadingResponse 491 * 492 * DCMI Get Power Reading command response. 493 * Refer DCMI specification Version 1.1 Section 6.6.1 494 */ 495 struct GetPowerReadingResponse 496 { 497 uint16_t currentPower; //!< Current power in watts 498 uint16_t minimumPower; //!< Minimum power over sampling duration 499 //!< in watts 500 uint16_t maximumPower; //!< Maximum power over sampling duration 501 //!< in watts 502 uint16_t averagePower; //!< Average power over sampling duration 503 //!< in watts 504 uint32_t timeStamp; //!< IPMI specification based time stamp 505 uint32_t timeFrame; //!< Statistics reporting time period in milli 506 //!< seconds. 507 uint8_t powerReadingState; //!< Power Reading State 508 } __attribute__((packed)); 509 510 /** @struct GetSensorInfoRequest 511 * 512 * DCMI payload for Get Sensor Info request 513 */ 514 struct GetSensorInfoRequest 515 { 516 uint8_t sensorType; //!< Type of the sensor 517 uint8_t entityId; //!< Entity ID 518 uint8_t entityInstance; //!< Entity Instance (0 means all instances) 519 uint8_t instanceStart; //!< Instance start (used if instance is 0) 520 } __attribute__((packed)); 521 522 /** @struct GetSensorInfoResponseHdr 523 * 524 * DCMI header for Get Sensor Info response 525 */ 526 struct GetSensorInfoResponseHdr 527 { 528 uint8_t numInstances; //!< No. of instances for requested id 529 uint8_t numRecords; //!< No. of record ids in the response 530 } __attribute__((packed)); 531 /** 532 * @brief Parameters for DCMI Configuration Parameters 533 */ 534 enum class DCMIConfigParameters : uint8_t 535 { 536 ActivateDHCP = 1, 537 DiscoveryConfig, 538 DHCPTiming1, 539 DHCPTiming2, 540 DHCPTiming3, 541 }; 542 543 /** @struct SetConfParamsRequest 544 * 545 * DCMI Set DCMI Configuration Parameters Command. 546 * Refer DCMI specification Version 1.1 Section 6.1.2 547 */ 548 struct SetConfParamsRequest 549 { 550 uint8_t paramSelect; //!< Parameter selector. 551 uint8_t setSelect; //!< Set Selector (use 00h for parameters that only 552 //!< have one set). 553 uint8_t data[]; //!< Configuration parameter data. 554 } __attribute__((packed)); 555 556 /** @struct GetConfParamsRequest 557 * 558 * DCMI Get DCMI Configuration Parameters Command. 559 * Refer DCMI specification Version 1.1 Section 6.1.3 560 */ 561 struct GetConfParamsRequest 562 { 563 uint8_t paramSelect; //!< Parameter selector. 564 uint8_t setSelect; //!< Set Selector. Selects a given set of parameters 565 //!< under a given Parameter selector value. 00h if 566 //!< parameter doesn't use a Set Selector. 567 } __attribute__((packed)); 568 569 /** @struct GetConfParamsResponse 570 * 571 * DCMI Get DCMI Configuration Parameters Command response. 572 * Refer DCMI specification Version 1.1 Section 6.1.3 573 */ 574 struct GetConfParamsResponse 575 { 576 uint8_t major; //!< DCMI Spec Conformance - major ver = 01h. 577 uint8_t minor; //!< DCMI Spec Conformance - minor ver = 05h. 578 uint8_t paramRevision; //!< Parameter Revision = 01h. 579 uint8_t data[]; //!< Parameter data. 580 581 } __attribute__((packed)); 582 583 } // namespace dcmi 584