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 groupID; //!< Group extension identification. 133 uint8_t offset; //!< Offset to read. 134 uint8_t bytes; //!< Number of bytes to read. 135 } __attribute__((packed)); 136 137 /** @struct GetAssetTagResponse 138 * 139 * DCMI payload for Get Asset Tag command response. 140 */ 141 struct GetAssetTagResponse 142 { 143 uint8_t groupID; //!< Group extension identification. 144 uint8_t tagLength; //!< Total asset tag length. 145 } __attribute__((packed)); 146 147 /** @struct SetAssetTagRequest 148 * 149 * DCMI payload for Set Asset Tag command request. 150 */ 151 struct SetAssetTagRequest 152 { 153 uint8_t groupID; //!< Group extension identification. 154 uint8_t offset; //!< Offset to write. 155 uint8_t bytes; //!< Number of bytes to write. 156 } __attribute__((packed)); 157 158 /** @struct SetAssetTagResponse 159 * 160 * DCMI payload for Set Asset Tag command response. 161 */ 162 struct SetAssetTagResponse 163 { 164 uint8_t groupID; //!< Group extension identification. 165 uint8_t tagLength; //!< Total asset tag length. 166 } __attribute__((packed)); 167 168 /** @brief Check whether DCMI power management is supported 169 * in the DCMI Capabilities config file. 170 * 171 * @return True if DCMI power management is supported 172 */ 173 bool isDCMIPowerMgmtSupported(); 174 175 /** @brief Read the object tree to fetch the object path that implemented the 176 * Asset tag interface. 177 * 178 * @param[in,out] objectTree - object tree 179 * 180 * @return On success return the object tree with the object path that 181 * implemented the AssetTag interface. 182 */ 183 void readAssetTagObjectTree(dcmi::assettag::ObjectTree& objectTree); 184 185 /** @brief Read the asset tag of the server 186 * 187 * @return On success return the asset tag. 188 */ 189 std::string readAssetTag(); 190 191 /** @brief Write the asset tag to the asset tag DBUS property 192 * 193 * @param[in] assetTag - Asset Tag to be written to the property. 194 */ 195 void writeAssetTag(const std::string& assetTag); 196 197 /** @brief Read the current power cap value 198 * 199 * @param[in] bus - dbus connection 200 * 201 * @return On success return the power cap value. 202 */ 203 uint32_t getPcap(sdbusplus::bus::bus& bus); 204 205 /** @brief Check if the power capping is enabled 206 * 207 * @param[in] bus - dbus connection 208 * 209 * @return true if the powerCap is enabled and false if the powercap 210 * is disabled. 211 */ 212 bool getPcapEnabled(sdbusplus::bus::bus& bus); 213 214 /** @struct GetPowerLimitRequest 215 * 216 * DCMI payload for Get Power Limit command request. 217 */ 218 struct GetPowerLimitRequest 219 { 220 uint8_t groupID; //!< Group extension identification. 221 uint16_t reserved; //!< Reserved 222 } __attribute__((packed)); 223 224 /** @struct GetPowerLimitResponse 225 * 226 * DCMI payload for Get Power Limit command response. 227 */ 228 struct GetPowerLimitResponse 229 { 230 uint8_t groupID; //!< Group extension identification. 231 uint16_t reserved; //!< Reserved. 232 uint8_t exceptionAction; //!< Exception action. 233 uint16_t powerLimit; //!< Power limit requested in watts. 234 uint32_t correctionTime; //!< Correction time limit in milliseconds. 235 uint16_t reserved1; //!< Reserved. 236 uint16_t samplingPeriod; //!< Statistics sampling period in seconds. 237 } __attribute__((packed)); 238 239 /** @brief Set the power cap value 240 * 241 * @param[in] bus - dbus connection 242 * @param[in] powerCap - power cap value 243 */ 244 void setPcap(sdbusplus::bus::bus& bus, const uint32_t powerCap); 245 246 /** @struct SetPowerLimitRequest 247 * 248 * DCMI payload for Set Power Limit command request. 249 */ 250 struct SetPowerLimitRequest 251 { 252 uint8_t groupID; //!< Group extension identification. 253 uint16_t reserved; //!< Reserved 254 uint8_t reserved1; //!< Reserved 255 uint8_t exceptionAction; //!< Exception action. 256 uint16_t powerLimit; //!< Power limit requested in watts. 257 uint32_t correctionTime; //!< Correction time limit in milliseconds. 258 uint16_t reserved2; //!< Reserved. 259 uint16_t samplingPeriod; //!< Statistics sampling period in seconds. 260 } __attribute__((packed)); 261 262 /** @struct SetPowerLimitResponse 263 * 264 * DCMI payload for Set Power Limit command response. 265 */ 266 struct SetPowerLimitResponse 267 { 268 uint8_t groupID; //!< Group extension identification. 269 } __attribute__((packed)); 270 271 /** @brief Enable or disable the power capping 272 * 273 * @param[in] bus - dbus connection 274 * @param[in] enabled - enable/disable 275 */ 276 void setPcapEnable(sdbusplus::bus::bus& bus, bool enabled); 277 278 /** @struct ApplyPowerLimitRequest 279 * 280 * DCMI payload for Activate/Deactivate Power Limit command request. 281 */ 282 struct ApplyPowerLimitRequest 283 { 284 uint8_t groupID; //!< Group extension identification. 285 uint8_t powerLimitAction; //!< Power limit activation 286 uint16_t reserved; //!< Reserved 287 } __attribute__((packed)); 288 289 /** @struct ApplyPowerLimitResponse 290 * 291 * DCMI payload for Acticate/Deactivate Power Limit command response. 292 */ 293 struct ApplyPowerLimitResponse 294 { 295 uint8_t groupID; //!< Group extension identification. 296 } __attribute__((packed)); 297 298 /** @struct GetMgmntCtrlIdStrRequest 299 * 300 * DCMI payload for Get Management Controller Identifier String cmd request. 301 */ 302 struct GetMgmntCtrlIdStrRequest 303 { 304 uint8_t groupID; //!< Group extension identification. 305 uint8_t offset; //!< Offset to read. 306 uint8_t bytes; //!< Number of bytes to read. 307 } __attribute__((packed)); 308 309 /** @struct GetMgmntCtrlIdStrResponse 310 * 311 * DCMI payload for Get Management Controller Identifier String cmd response. 312 */ 313 struct GetMgmntCtrlIdStrResponse 314 { 315 uint8_t groupID; //!< Group extension identification. 316 uint8_t strLen; //!< ID string length. 317 char data[]; //!< ID string 318 } __attribute__((packed)); 319 320 /** @struct SetMgmntCtrlIdStrRequest 321 * 322 * DCMI payload for Set Management Controller Identifier String cmd request. 323 */ 324 struct SetMgmntCtrlIdStrRequest 325 { 326 uint8_t groupID; //!< Group extension identification. 327 uint8_t offset; //!< Offset to write. 328 uint8_t bytes; //!< Number of bytes to read. 329 char data[]; //!< ID string 330 } __attribute__((packed)); 331 332 /** @struct GetMgmntCtrlIdStrResponse 333 * 334 * DCMI payload for Get Management Controller Identifier String cmd response. 335 */ 336 struct SetMgmntCtrlIdStrResponse 337 { 338 uint8_t groupID; //!< Group extension identification. 339 uint8_t offset; //!< Last Offset Written. 340 } __attribute__((packed)); 341 342 /** @enum DCMICapParameters 343 * 344 * DCMI Capability parameters 345 */ 346 enum class DCMICapParameters 347 { 348 SUPPORTED_DCMI_CAPS = 0x01, //!< Supported DCMI Capabilities 349 MANDATORY_PLAT_ATTRIBUTES = 0x02, //!< Mandatory Platform Attributes 350 OPTIONAL_PLAT_ATTRIBUTES = 0x03, //!< Optional Platform Attributes 351 MANAGEABILITY_ACCESS_ATTRIBUTES = 0x04, //!< Manageability Access Attributes 352 }; 353 354 /** @struct GetDCMICapRequest 355 * 356 * DCMI payload for Get capabilities cmd request. 357 */ 358 struct GetDCMICapRequest 359 { 360 uint8_t groupID; //!< Group extension identification. 361 uint8_t param; //!< Capability parameter selector. 362 } __attribute__((packed)); 363 364 /** @struct GetDCMICapRequest 365 * 366 * DCMI payload for Get capabilities cmd response. 367 */ 368 struct GetDCMICapResponse 369 { 370 uint8_t groupID; //!< Group extension identification. 371 uint8_t major; //!< DCMI Specification Conformance - major ver 372 uint8_t minor; //!< DCMI Specification Conformance - minor ver 373 uint8_t paramRevision; //!< Parameter Revision = 02h 374 uint8_t data[]; //!< Capability array 375 } __attribute__((packed)); 376 377 /** @struct DCMICap 378 * 379 * DCMI capabilities protocol info. 380 */ 381 struct DCMICap 382 { 383 std::string name; //!< Name of DCMI capability. 384 uint8_t bytePosition; //!< Starting byte number from DCMI spec. 385 uint8_t position; //!< bit position from the DCMI spec. 386 uint8_t length; //!< Length of the value from DCMI spec. 387 }; 388 389 using DCMICapList = std::vector<DCMICap>; 390 391 /** @struct DCMICapEntry 392 * 393 * DCMI capabilities list and size for each parameter. 394 */ 395 struct DCMICapEntry 396 { 397 uint8_t size; //!< Size of capability array in bytes. 398 DCMICapList capList; //!< List of capabilities for a parameter. 399 }; 400 401 using DCMICaps = std::map<DCMICapParameters, DCMICapEntry>; 402 403 /** @struct GetTempReadingsRequest 404 * 405 * DCMI payload for Get Temperature Readings request 406 */ 407 struct GetTempReadingsRequest 408 { 409 uint8_t groupID; //!< Group extension identification. 410 uint8_t sensorType; //!< Type of the sensor 411 uint8_t entityId; //!< Entity ID 412 uint8_t entityInstance; //!< Entity Instance (0 means all instances) 413 uint8_t instanceStart; //!< Instance start (used if instance is 0) 414 } __attribute__((packed)); 415 416 /** @struct GetTempReadingsResponse 417 * 418 * DCMI header for Get Temperature Readings response 419 */ 420 struct GetTempReadingsResponseHdr 421 { 422 uint8_t groupID; //!< Group extension identification. 423 uint8_t numInstances; //!< No. of instances for requested id 424 uint8_t numDataSets; //!< No. of sets of temperature data 425 } __attribute__((packed)); 426 427 /** @brief Parse out JSON config file. 428 * 429 * @param[in] configFile - JSON config file name 430 * 431 * @return A json object 432 */ 433 Json parseJSONConfig(const std::string& configFile); 434 435 namespace temp_readings 436 { 437 /** @brief Read temperature from a d-bus object, scale it as per dcmi 438 * get temperature reading requirements. 439 * 440 * @param[in] dbusService - the D-Bus service 441 * @param[in] dbusPath - the D-Bus path 442 * 443 * @return A temperature reading 444 */ 445 Temperature readTemp(const std::string& dbusService, 446 const std::string& dbusPath); 447 448 /** @brief Read temperatures and fill up DCMI response for the Get 449 * Temperature Readings command. This looks at a specific 450 * instance. 451 * 452 * @param[in] type - one of "inlet", "cpu", "baseboard" 453 * @param[in] instance - A non-zero Entity instance number 454 * 455 * @return A tuple, containing a temperature reading and the 456 * number of instances. 457 */ 458 std::tuple<Response, NumInstances> read(const std::string& type, 459 uint8_t instance); 460 461 /** @brief Read temperatures and fill up DCMI response for the Get 462 * Temperature Readings command. This looks at a range of 463 * instances. 464 * 465 * @param[in] type - one of "inlet", "cpu", "baseboard" 466 * @param[in] instanceStart - Entity instance start index 467 * 468 * @return A tuple, containing a list of temperature readings and the 469 * number of instances. 470 */ 471 std::tuple<ResponseList, NumInstances> readAll(const std::string& type, 472 uint8_t instanceStart); 473 } // namespace temp_readings 474 475 namespace sensor_info 476 { 477 /** @brief Create response from JSON config. 478 * 479 * @param[in] config - JSON config info about DCMI sensors 480 * 481 * @return Sensor info response 482 */ 483 Response createFromJson(const Json& config); 484 485 /** @brief Read sensor info and fill up DCMI response for the Get 486 * Sensor Info command. This looks at a specific 487 * instance. 488 * 489 * @param[in] type - one of "inlet", "cpu", "baseboard" 490 * @param[in] instance - A non-zero Entity instance number 491 * @param[in] config - JSON config info about DCMI sensors 492 * 493 * @return A tuple, containing a sensor info response and 494 * number of instances. 495 */ 496 std::tuple<Response, NumInstances> read(const std::string& type, 497 uint8_t instance, const Json& config); 498 499 /** @brief Read sensor info and fill up DCMI response for the Get 500 * Sensor Info command. This looks at a range of 501 * instances. 502 * 503 * @param[in] type - one of "inlet", "cpu", "baseboard" 504 * @param[in] instanceStart - Entity instance start index 505 * @param[in] config - JSON config info about DCMI sensors 506 * 507 * @return A tuple, containing a list of sensor info responses and the 508 * number of instances. 509 */ 510 std::tuple<ResponseList, NumInstances> 511 readAll(const std::string& type, uint8_t instanceStart, const Json& config); 512 } // namespace sensor_info 513 514 /** @brief Read power reading from power reading sensor object 515 * 516 * @param[in] bus - dbus connection 517 * 518 * @return total power reading 519 */ 520 int64_t getPowerReading(sdbusplus::bus::bus& bus); 521 522 /** @struct GetPowerReadingRequest 523 * 524 * DCMI Get Power Reading command request. 525 * Refer DCMI specification Version 1.1 Section 6.6.1 526 */ 527 struct GetPowerReadingRequest 528 { 529 uint8_t groupID; //!< Group extension identification. 530 uint8_t mode; //!< Mode 531 uint8_t modeAttribute; //!< Mode Attributes 532 } __attribute__((packed)); 533 534 /** @struct GetPowerReadingResponse 535 * 536 * DCMI Get Power Reading command response. 537 * Refer DCMI specification Version 1.1 Section 6.6.1 538 */ 539 struct GetPowerReadingResponse 540 { 541 uint8_t groupID; //!< Group extension identification. 542 uint16_t currentPower; //!< Current power in watts 543 uint16_t minimumPower; //!< Minimum power over sampling duration 544 //!< in watts 545 uint16_t maximumPower; //!< Maximum power over sampling duration 546 //!< in watts 547 uint16_t averagePower; //!< Average power over sampling duration 548 //!< in watts 549 uint32_t timeStamp; //!< IPMI specification based time stamp 550 uint32_t timeFrame; //!< Statistics reporting time period in milli 551 //!< seconds. 552 uint8_t powerReadingState; //!< Power Reading State 553 } __attribute__((packed)); 554 555 /** @struct GetSensorInfoRequest 556 * 557 * DCMI payload for Get Sensor Info request 558 */ 559 struct GetSensorInfoRequest 560 { 561 uint8_t groupID; //!< Group extension identification. 562 uint8_t sensorType; //!< Type of the sensor 563 uint8_t entityId; //!< Entity ID 564 uint8_t entityInstance; //!< Entity Instance (0 means all instances) 565 uint8_t instanceStart; //!< Instance start (used if instance is 0) 566 } __attribute__((packed)); 567 568 /** @struct GetSensorInfoResponseHdr 569 * 570 * DCMI header for Get Sensor Info response 571 */ 572 struct GetSensorInfoResponseHdr 573 { 574 uint8_t groupID; //!< Group extension identification. 575 uint8_t numInstances; //!< No. of instances for requested id 576 uint8_t numRecords; //!< No. of record ids in the response 577 } __attribute__((packed)); 578 /** 579 * @brief Parameters for DCMI Configuration Parameters 580 */ 581 enum class DCMIConfigParameters : uint8_t 582 { 583 ActivateDHCP = 1, 584 DiscoveryConfig, 585 DHCPTiming1, 586 DHCPTiming2, 587 DHCPTiming3, 588 }; 589 590 /** @struct SetConfParamsRequest 591 * 592 * DCMI Set DCMI Configuration Parameters Command. 593 * Refer DCMI specification Version 1.1 Section 6.1.2 594 */ 595 struct SetConfParamsRequest 596 { 597 uint8_t groupID; //!< Group extension identification. 598 uint8_t paramSelect; //!< Parameter selector. 599 uint8_t setSelect; //!< Set Selector (use 00h for parameters that only 600 //!< have one set). 601 uint8_t data[]; //!< Configuration parameter data. 602 } __attribute__((packed)); 603 604 /** @struct SetConfParamsResponse 605 * 606 * DCMI Set DCMI Configuration Parameters Command response. 607 * Refer DCMI specification Version 1.1 Section 6.1.2 608 */ 609 struct SetConfParamsResponse 610 { 611 uint8_t groupID; //!< Group extension identification. 612 } __attribute__((packed)); 613 614 /** @struct GetConfParamsRequest 615 * 616 * DCMI Get DCMI Configuration Parameters Command. 617 * Refer DCMI specification Version 1.1 Section 6.1.3 618 */ 619 struct GetConfParamsRequest 620 { 621 uint8_t groupID; //!< Group extension identification. 622 uint8_t paramSelect; //!< Parameter selector. 623 uint8_t setSelect; //!< Set Selector. Selects a given set of parameters 624 //!< under a given Parameter selector value. 00h if 625 //!< parameter doesn't use a Set Selector. 626 } __attribute__((packed)); 627 628 /** @struct GetConfParamsResponse 629 * 630 * DCMI Get DCMI Configuration Parameters Command response. 631 * Refer DCMI specification Version 1.1 Section 6.1.3 632 */ 633 struct GetConfParamsResponse 634 { 635 uint8_t groupID; //!< Group extension identification. 636 uint8_t major; //!< DCMI Spec Conformance - major ver = 01h. 637 uint8_t minor; //!< DCMI Spec Conformance - minor ver = 05h. 638 uint8_t paramRevision; //!< Parameter Revision = 01h. 639 uint8_t data[]; //!< Parameter data. 640 641 } __attribute__((packed)); 642 643 } // namespace dcmi 644