1 #pragma once 2 3 #include "dbus_types.hpp" 4 #include "dbus_watcher.hpp" 5 6 #ifdef PEL_ENABLE_PHAL 7 #include <libguard/guard_interface.hpp> 8 #include <libguard/include/guard_record.hpp> 9 #endif 10 11 #include <phosphor-logging/lg2.hpp> 12 #include <sdbusplus/bus.hpp> 13 #include <sdbusplus/bus/match.hpp> 14 15 #include <expected> 16 #include <filesystem> 17 #include <fstream> 18 #include <unordered_map> 19 20 #ifdef PEL_ENABLE_PHAL 21 using GardType = openpower::guard::GardType; 22 namespace libguard = openpower::guard; 23 #endif 24 25 namespace openpower 26 { 27 namespace pels 28 { 29 30 /** 31 * @class DataInterface 32 * 33 * A base class for gathering data about the system for use 34 * in PELs. Implemented this way to facilitate mocking. 35 */ 36 class DataInterfaceBase 37 { 38 public: 39 DataInterfaceBase() = default; 40 virtual ~DataInterfaceBase() = default; 41 DataInterfaceBase(const DataInterfaceBase&) = default; 42 DataInterfaceBase& operator=(const DataInterfaceBase&) = default; 43 DataInterfaceBase(DataInterfaceBase&&) = default; 44 DataInterfaceBase& operator=(DataInterfaceBase&&) = default; 45 46 /** 47 * @brief Returns the machine Type/Model 48 * 49 * @return string - The machine Type/Model string 50 */ 51 virtual std::string getMachineTypeModel() const = 0; 52 53 /** 54 * @brief Returns the machine serial number 55 * 56 * @return string - The machine serial number 57 */ 58 virtual std::string getMachineSerialNumber() const = 0; 59 60 /** 61 * @brief Says if the system is managed by a hardware 62 * management console. 63 * @return bool - If the system is HMC managed 64 */ isHMCManaged() const65 virtual bool isHMCManaged() const 66 { 67 return _hmcManaged; 68 } 69 70 /** 71 * @brief Says if the host is up and running 72 * 73 * @return bool - If the host is running 74 */ isHostUp() const75 virtual bool isHostUp() const 76 { 77 return _hostUp; 78 } 79 80 using HostStateChangeFunc = std::function<void(bool)>; 81 82 /** 83 * @brief Register a callback function that will get 84 * called on all host on/off transitions. 85 * 86 * The void(bool) function will get passed the new 87 * value of the host state. 88 * 89 * @param[in] name - The subscription name 90 * @param[in] func - The function to run 91 */ subscribeToHostStateChange(const std::string & name,HostStateChangeFunc func)92 void subscribeToHostStateChange(const std::string& name, 93 HostStateChangeFunc func) 94 { 95 _hostChangeCallbacks[name] = func; 96 } 97 98 /** 99 * @brief Unsubscribe from host state changes. 100 * 101 * @param[in] name - The subscription name 102 */ unsubscribeFromHostStateChange(const std::string & name)103 void unsubscribeFromHostStateChange(const std::string& name) 104 { 105 _hostChangeCallbacks.erase(name); 106 } 107 108 using FRUPresentFunc = 109 std::function<void(const std::string& /* locationCode */)>; 110 111 /** 112 * @brief Register a callback function that will get 113 * called when certain FRUs become present. 114 * 115 * The void(std::string) function will get passed the 116 * location code of the FRU. 117 * 118 * @param[in] name - The subscription name 119 * @param[in] func - The function to run 120 */ subscribeToFruPresent(const std::string & name,FRUPresentFunc func)121 void subscribeToFruPresent(const std::string& name, FRUPresentFunc func) 122 { 123 _fruPresentCallbacks[name] = std::move(func); 124 } 125 126 /** 127 * @brief Returns the BMC firmware version 128 * 129 * @return std::string - The BMC version 130 */ getBMCFWVersion() const131 virtual std::string getBMCFWVersion() const 132 { 133 return _bmcFWVersion; 134 } 135 136 /** 137 * @brief Returns the server firmware version 138 * 139 * @return std::string - The server firmware version 140 */ getServerFWVersion() const141 virtual std::string getServerFWVersion() const 142 { 143 return _serverFWVersion; 144 } 145 146 /** 147 * @brief Returns the BMC FW version ID 148 * 149 * @return std::string - The BMC FW version ID 150 */ getBMCFWVersionID() const151 virtual std::string getBMCFWVersionID() const 152 { 153 return _bmcFWVersionID; 154 } 155 156 /** 157 * @brief Returns the process name given its PID. 158 * 159 * @param[in] pid - The PID value as a string 160 * 161 * @return std::optional<std::string> - The name, or std::nullopt 162 */ getProcessName(const std::string & pid) const163 std::optional<std::string> getProcessName(const std::string& pid) const 164 { 165 namespace fs = std::filesystem; 166 167 fs::path path{"/proc"}; 168 path /= fs::path{pid} / "exe"; 169 170 if (fs::exists(path)) 171 { 172 return fs::read_symlink(path); 173 } 174 175 return std::nullopt; 176 } 177 178 /** 179 * @brief Returns the time the system was running. 180 * 181 * @return std::optional<uint64_t> - The System uptime or std::nullopt 182 */ getUptimeInSeconds() const183 std::optional<uint64_t> getUptimeInSeconds() const 184 { 185 std::ifstream versionFile{"/proc/uptime"}; 186 std::string line{}; 187 188 std::getline(versionFile, line); 189 auto pos = line.find(" "); 190 if (pos == std::string::npos) 191 { 192 return std::nullopt; 193 } 194 195 uint64_t seconds = atol(line.substr(0, pos).c_str()); 196 if (seconds == 0) 197 { 198 return std::nullopt; 199 } 200 201 return seconds; 202 } 203 204 /** 205 * @brief Returns the time the system was running. 206 * 207 * @param[in] seconds - The number of seconds the system has been running 208 * 209 * @return std::string - days/hours/minutes/seconds 210 */ getBMCUptime(uint64_t seconds) const211 std::string getBMCUptime(uint64_t seconds) const 212 { 213 time_t t(seconds); 214 tm* p = gmtime(&t); 215 216 std::string uptime = 217 std::to_string(p->tm_year - 70) + "y " + 218 std::to_string(p->tm_yday) + "d " + std::to_string(p->tm_hour) + 219 "h " + std::to_string(p->tm_min) + "m " + 220 std::to_string(p->tm_sec) + "s"; 221 222 return uptime; 223 } 224 225 /** 226 * @brief Returns the system load average over the past 1 minute, 5 minutes 227 * and 15 minutes. 228 * 229 * @return std::string - The system load average 230 */ getBMCLoadAvg() const231 std::string getBMCLoadAvg() const 232 { 233 std::string loadavg{}; 234 235 std::ifstream loadavgFile{"/proc/loadavg"}; 236 std::string line; 237 std::getline(loadavgFile, line); 238 239 size_t count = 3; 240 for (size_t i = 0; i < count; i++) 241 { 242 auto pos = line.find(" "); 243 if (pos == std::string::npos) 244 { 245 return {}; 246 } 247 248 if (i != count - 1) 249 { 250 loadavg.append(line.substr(0, pos + 1)); 251 } 252 else 253 { 254 loadavg.append(line.substr(0, pos)); 255 } 256 257 line = line.substr(pos + 1); 258 } 259 260 return loadavg; 261 } 262 263 /** 264 * @brief Returns the 'send event logs to host' setting. 265 * 266 * @return bool - If sending PELs to the host is enabled. 267 */ getHostPELEnablement() const268 virtual bool getHostPELEnablement() const 269 { 270 return _sendPELsToHost; 271 } 272 273 /** 274 * @brief Returns the BMC state 275 * 276 * @return std::string - The BMC state property value 277 */ getBMCState() const278 virtual std::string getBMCState() const 279 { 280 return _bmcState; 281 } 282 283 /** 284 * @brief Returns the Chassis state 285 * 286 * @return std::string - The chassis state property value 287 */ getChassisState() const288 virtual std::string getChassisState() const 289 { 290 return _chassisState; 291 } 292 293 /** 294 * @brief Returns the chassis requested power 295 * transition value. 296 * 297 * @return std::string - The chassis transition property 298 */ getChassisTransition() const299 virtual std::string getChassisTransition() const 300 { 301 return _chassisTransition; 302 } 303 304 /** 305 * @brief Returns the Host state 306 * 307 * @return std::string - The Host state property value 308 */ getHostState() const309 virtual std::string getHostState() const 310 { 311 return _hostState; 312 } 313 314 /** 315 * @brief Returns the Boot state 316 * 317 * @return std::string - The Boot state property value 318 */ getBootState() const319 virtual std::string getBootState() const 320 { 321 return _bootState; 322 } 323 324 /** 325 * @brief Returns the motherboard CCIN 326 * 327 * @return std::string The motherboard CCIN 328 */ 329 virtual std::string getMotherboardCCIN() const = 0; 330 331 /** 332 * @brief Returns the system IM 333 * 334 * @return std::string The system IM 335 */ 336 virtual std::vector<uint8_t> getSystemIMKeyword() const = 0; 337 338 /** 339 * @brief Get the fields from the inventory necessary for doing 340 * a callout on an inventory path. 341 * 342 * @param[in] inventoryPath - The item to get the data for 343 * @param[out] fruPartNumber - Filled in with the VINI/FN keyword 344 * @param[out] ccin - Filled in with the VINI/CC keyword 345 * @param[out] serialNumber - Filled in with the VINI/SN keyword 346 */ 347 virtual void getHWCalloutFields( 348 const std::string& inventoryPath, std::string& fruPartNumber, 349 std::string& ccin, std::string& serialNumber) const = 0; 350 351 /** 352 * @brief Get the location code for an inventory item. 353 * 354 * @param[in] inventoryPath - The item to get the data for 355 * 356 * @return std::string - The location code 357 */ 358 virtual std::string 359 getLocationCode(const std::string& inventoryPath) const = 0; 360 361 /** 362 * @brief Get the list of system type names the system is called. 363 * 364 * @return std::vector<std::string> - The list of names 365 */ 366 virtual std::vector<std::string> getSystemNames() const = 0; 367 368 /** 369 * @brief Fills in the placeholder 'Ufcs' in the passed in location 370 * code with the machine feature code and serial number, which 371 * is needed to create a valid location code. 372 * 373 * @param[in] locationCode - Location code value starting with Ufcs-, and 374 * if that isn't present it will be added first. 375 * 376 * @param[in] node - The node number the location is on. 377 * 378 * @return std::string - The expanded location code 379 */ 380 virtual std::string expandLocationCode(const std::string& locationCode, 381 uint16_t node) const = 0; 382 383 /** 384 * @brief Returns the inventory paths for the FRU that the location 385 * code represents. 386 * 387 * @param[in] locationCode - If an expanded location code, then the 388 * full location code. 389 * If not expanded, a location code value 390 * starting with Ufcs-, and if that isn't 391 * present it will be added first. 392 * 393 * @param[in] node - The node number the location is on. Ignored if the 394 * expanded location code is passed in. 395 * 396 * @param[in] expanded - If the location code already has the relevent 397 * VPD fields embedded in it. 398 * 399 * @return std::vector<std::string> - The inventory D-Bus objects 400 */ 401 virtual std::vector<std::string> 402 getInventoryFromLocCode(const std::string& LocationCode, uint16_t node, 403 bool expanded) const = 0; 404 405 /** 406 * @brief Sets the Asserted property on the LED group passed in. 407 * 408 * @param[in] ledGroup - The LED group D-Bus path 409 * @param[in] value - The value to set it to 410 */ 411 virtual void assertLEDGroup(const std::string& ledGroup, 412 bool value) const = 0; 413 414 /** 415 * @brief Sets the Functional property on the OperationalStatus 416 * interface on a D-Bus object. 417 * 418 * @param[in] objectPath - The D-Bus object path 419 * @param[in] functional - The value 420 */ 421 virtual void setFunctional(const std::string& objectPath, 422 bool functional) const = 0; 423 424 /** 425 * @brief Sets the critical association on the D-Bus object. 426 * 427 * @param[in] objectPath - The D-Bus object path 428 */ 429 virtual void 430 setCriticalAssociation(const std::string& objectPath) const = 0; 431 432 /** 433 * @brief Returns the manufacturing QuiesceOnError property 434 * 435 * @return bool - Manufacturing QuiesceOnError property 436 */ 437 virtual bool getQuiesceOnError() const = 0; 438 439 /** 440 * @brief Split location code into base and connector segments 441 * 442 * A location code that ends in '-Tx', where 'x' is a number, 443 * represents a connector, such as a USB cable connector. 444 * 445 * This function splits the passed in location code into a 446 * base and connector segment. e.g.: 447 * P0-T1 -> ['P0', '-T1'] 448 * P0 -> ['P0', ''] 449 * 450 * @param[in] locationCode - location code to split 451 * @return pair<string, string> - The base and connector segments 452 */ 453 static std::pair<std::string, std::string> 454 extractConnectorFromLocCode(const std::string& locationCode); 455 456 #ifdef PEL_ENABLE_PHAL 457 /** 458 * @brief Create guard record 459 * 460 * @param[in] binPath: phal devtree binary path used as key 461 * @param[in] eGardType: Guard type enum value 462 * @param[in] plid: Pel ID 463 */ 464 virtual void createGuardRecord(const std::vector<uint8_t>& binPath, 465 GardType eGardType, uint32_t plid) const = 0; 466 #endif 467 468 /** 469 * @brief Create Progress SRC property on the boot progress 470 * interface on a D-Bus object. 471 * 472 * @param[in] priSRC - Primary SRC value (e.g. BD8D1001) 473 * @param[in] srcStruct - Full SRC base structure 474 */ 475 virtual void 476 createProgressSRC(const uint64_t& priSRC, 477 const std::vector<uint8_t>& srcStruct) const = 0; 478 479 /** 480 * @brief Get the list of unresolved OpenBMC event log ids that have an 481 * associated hardware isolation entry. 482 * 483 * @return std::vector<uint32_t> - The list of log ids 484 */ 485 virtual std::vector<uint32_t> getLogIDWithHwIsolation() const = 0; 486 487 /** 488 * @brief Returns the latest raw progress SRC from the State.Boot.Raw 489 * D-Bus interface. 490 * 491 * @return std::vector<uint8_t> - The progress SRC bytes 492 */ 493 virtual std::vector<uint8_t> getRawProgressSRC() const = 0; 494 495 /** 496 * @brief Returns the FRUs DI property value hosted on the VINI iterface for 497 * the given location code. 498 * 499 * @param[in] locationCode - The location code of the FRU 500 * 501 * @return std::optional<std::vector<uint8_t>> - The FRUs DI or 502 * std::nullopt 503 */ 504 virtual std::optional<std::vector<uint8_t>> 505 getDIProperty(const std::string& locationCode) const = 0; 506 507 /** 508 * @brief Wrpper API to call pHAL API 'getFRUType()' and check whether the 509 * given location code is DIMM or not 510 * 511 * @param[in] locCode - The location code of the FRU 512 * 513 * @return - true, if the given location code is DIMM 514 * - false, if the given location code is not DIMM or if it fails to 515 * determine the FRU type. 516 */ 517 bool isDIMM(const std::string& locCode); 518 519 /** 520 * @brief Check whether the given location code present in the cache 521 * memory 522 * 523 * @param[in] locCode - The location code of the FRU 524 * 525 * @return true, if the given location code present in cache and is a DIMM 526 * false, if the given location code present in cache, but a non 527 * DIMM FRU 528 * std::nullopt, if the given location code is not present in the 529 * cache. 530 */ 531 std::optional<bool> isDIMMLocCode(const std::string& locCode) const; 532 533 /** 534 * @brief add the given location code to the cache memory 535 * 536 * @param[in] locCode - The location code of the FRU 537 * @param[in] isFRUDIMM - true indicates the FRU is a DIMM 538 * false indicates the FRU is a non DIMM 539 * 540 */ 541 void addDIMMLocCode(const std::string& locCode, bool isFRUDIMM); 542 543 /** 544 * @brief Finds all D-Bus Associated paths that contain any of the 545 * interfaces passed in, by using GetAssociatedSubTreePaths. 546 * 547 * @param[in] associatedPath - The D-Bus object path 548 * @param[in] subtree - The subtree path for which the result should be 549 * fetched 550 * @param[in] depth - The maximum subtree depth for which results should be 551 * fetched 552 * @param[in] interfaces - The desired interfaces 553 * 554 * @return The D-Bus paths. 555 */ 556 virtual DBusPathList getAssociatedPaths( 557 const DBusPath& associatedPath, const DBusPath& subtree, int32_t depth, 558 const DBusInterfaceList& interfaces) const = 0; 559 560 protected: 561 /** 562 * @brief Sets the host on/off state and runs any 563 * callback functions (if there was a change). 564 */ setHostUp(bool hostUp)565 void setHostUp(bool hostUp) 566 { 567 if (_hostUp != hostUp) 568 { 569 _hostUp = hostUp; 570 571 for (auto& [name, func] : _hostChangeCallbacks) 572 { 573 try 574 { 575 func(_hostUp); 576 } 577 catch (const std::exception& e) 578 { 579 lg2::error( 580 "A host state change callback threw an exception"); 581 } 582 } 583 } 584 } 585 586 /** 587 * @brief Runs the callback functions registered when 588 * FRUs become present. 589 */ setFruPresent(const std::string & locationCode)590 void setFruPresent(const std::string& locationCode) 591 { 592 for (const auto& [_, func] : _fruPresentCallbacks) 593 { 594 try 595 { 596 func(locationCode); 597 } 598 catch (const std::exception& e) 599 { 600 lg2::error("A FRU present callback threw an exception"); 601 } 602 } 603 } 604 605 /** 606 * @brief The hardware management console status. Always kept 607 * up to date. 608 */ 609 bool _hmcManaged = false; 610 611 /** 612 * @brief The host up status. Always kept up to date. 613 */ 614 bool _hostUp = false; 615 616 /** 617 * @brief The map of host state change subscriber 618 * names to callback functions. 619 */ 620 std::map<std::string, HostStateChangeFunc> _hostChangeCallbacks; 621 622 /** 623 * @brief The map of FRU present subscriber 624 * names to callback functions. 625 */ 626 std::map<std::string, FRUPresentFunc> _fruPresentCallbacks; 627 628 /** 629 * @brief The BMC firmware version string 630 */ 631 std::string _bmcFWVersion; 632 633 /** 634 * @brief The server firmware version string 635 */ 636 std::string _serverFWVersion; 637 638 /** 639 * @brief The BMC firmware version ID string 640 */ 641 std::string _bmcFWVersionID; 642 643 /** 644 * @brief If sending PELs is enabled. 645 * 646 * This is usually set to false in manufacturing test. 647 */ 648 bool _sendPELsToHost = true; 649 650 /** 651 * @brief The BMC state property 652 */ 653 std::string _bmcState; 654 655 /** 656 * @brief The Chassis current power state property 657 */ 658 std::string _chassisState; 659 660 /** 661 * @brief The Chassis requested power transition property 662 */ 663 std::string _chassisTransition; 664 665 /** 666 * @brief The host state property 667 */ 668 std::string _hostState; 669 670 /** 671 * @brief The boot state property 672 */ 673 std::string _bootState; 674 675 /** 676 * @brief A cache storage for location code and its FRU Type 677 * - The key 'std::string' represents the locationCode of the FRU 678 * - The bool value - true indicates the FRU is a DIMM 679 * false indicates the FRU is a non DIMM. 680 */ 681 std::unordered_map<std::string, bool> _locationCache; 682 }; 683 684 /** 685 * @class DataInterface 686 * 687 * Concrete implementation of DataInterfaceBase. 688 */ 689 class DataInterface : public DataInterfaceBase 690 { 691 public: 692 DataInterface() = delete; 693 ~DataInterface() = default; 694 DataInterface(const DataInterface&) = default; 695 DataInterface& operator=(const DataInterface&) = default; 696 DataInterface(DataInterface&&) = default; 697 DataInterface& operator=(DataInterface&&) = default; 698 699 /** 700 * @brief Constructor 701 * 702 * @param[in] bus - The sdbusplus bus object 703 */ 704 explicit DataInterface(sdbusplus::bus_t& bus); 705 706 /** 707 * @brief Finds the D-Bus service name that hosts the 708 * passed in path and interface. 709 * 710 * @param[in] objectPath - The D-Bus object path 711 * @param[in] interface - The D-Bus interface 712 */ 713 DBusService getService(const std::string& objectPath, 714 const std::string& interface) const; 715 716 /** 717 * @brief Wrapper for the 'GetAll' properties method call 718 * 719 * @param[in] service - The D-Bus service to call it on 720 * @param[in] objectPath - The D-Bus object path 721 * @param[in] interface - The interface to get the props on 722 * 723 * @return DBusPropertyMap - The property results 724 */ 725 DBusPropertyMap getAllProperties(const std::string& service, 726 const std::string& objectPath, 727 const std::string& interface) const; 728 /** 729 * @brief Wrapper for the 'Get' properties method call 730 * 731 * @param[in] service - The D-Bus service to call it on 732 * @param[in] objectPath - The D-Bus object path 733 * @param[in] interface - The interface to get the property on 734 * @param[in] property - The property name 735 * @param[out] value - Filled in with the property value. 736 */ 737 void getProperty(const std::string& service, const std::string& objectPath, 738 const std::string& interface, const std::string& property, 739 DBusValue& value) const; 740 /** 741 * @brief Returns the machine Type/Model 742 * 743 * @return string - The machine Type/Model string 744 */ 745 std::string getMachineTypeModel() const override; 746 747 /** 748 * @brief Returns the machine serial number 749 * 750 * @return string - The machine serial number 751 */ 752 std::string getMachineSerialNumber() const override; 753 754 /** 755 * @brief Returns the motherboard CCIN 756 * 757 * @return std::string The motherboard CCIN 758 */ 759 std::string getMotherboardCCIN() const override; 760 761 /** 762 * @brief Returns the system IM 763 * 764 * @return std::vector The system IM keyword in 4 byte vector 765 */ 766 std::vector<uint8_t> getSystemIMKeyword() const override; 767 768 /** 769 * @brief Get the fields from the inventory necessary for doing 770 * a callout on an inventory path. 771 * 772 * @param[in] inventoryPath - The item to get the data for 773 * @param[out] fruPartNumber - Filled in with the VINI/FN keyword 774 * @param[out] ccin - Filled in with the VINI/CC keyword 775 * @param[out] serialNumber - Filled in with the VINI/SN keyword 776 */ 777 void getHWCalloutFields(const std::string& inventoryPath, 778 std::string& fruPartNumber, std::string& ccin, 779 std::string& serialNumber) const override; 780 781 /** 782 * @brief Get the location code for an inventory item. 783 * 784 * Throws an exception if the inventory item doesn't have the 785 * location code interface. 786 * 787 * @param[in] inventoryPath - The item to get the data for 788 * 789 * @return std::string - The location code 790 */ 791 std::string 792 getLocationCode(const std::string& inventoryPath) const override; 793 794 /** 795 * @brief Get the list of system type names the system is called. 796 * 797 * @return std::vector<std::string> - The list of names 798 */ 799 std::vector<std::string> getSystemNames() const override; 800 801 /** 802 * @brief Fills in the placeholder 'Ufcs' in the passed in location 803 * code with the machine feature code and serial number, which 804 * is needed to create a valid location code. 805 * 806 * @param[in] locationCode - Location code value starting with Ufcs-, and 807 * if that isn't present it will be added first. 808 * 809 * @param[in] node - The node number the location is one. 810 * 811 * @return std::string - The expanded location code 812 */ 813 std::string expandLocationCode(const std::string& locationCode, 814 uint16_t node) const override; 815 816 /** 817 * @brief Returns the inventory paths for the FRU that the location 818 * code represents. 819 * 820 * @param[in] locationCode - If an expanded location code, then the 821 * full location code. 822 * If not expanded, a location code value 823 * starting with Ufcs-, and if that isn't 824 * present it will be added first. 825 * 826 * @param[in] node - The node number the location is on. Ignored if the 827 * expanded location code is passed in. 828 * 829 * @param[in] expanded - If the location code already has the relevent 830 * VPD fields embedded in it. 831 * 832 * @return std::vector<std::string> - The inventory D-Bus objects 833 */ 834 std::vector<std::string> 835 getInventoryFromLocCode(const std::string& locationCode, uint16_t node, 836 bool expanded) const override; 837 838 /** 839 * @brief Sets the Asserted property on the LED group passed in. 840 * 841 * @param[in] ledGroup - The LED group D-Bus path 842 * @param[in] value - The value to set it to 843 */ 844 void assertLEDGroup(const std::string& ledGroup, bool value) const override; 845 846 /** 847 * @brief Sets the Functional property on the OperationalStatus 848 * interface on a D-Bus object. 849 * 850 * @param[in] objectPath - The D-Bus object path 851 * @param[in] functional - The value 852 */ 853 void setFunctional(const std::string& objectPath, 854 bool functional) const override; 855 856 /** 857 * @brief Sets the critical association on the D-Bus object. 858 * 859 * @param[in] objectPath - The D-Bus object path 860 */ 861 void setCriticalAssociation(const std::string& objectPath) const override; 862 863 /** 864 * @brief Returns the manufacturing QuiesceOnError property 865 * 866 * @return bool - Manufacturing QuiesceOnError property 867 */ 868 bool getQuiesceOnError() const override; 869 870 #ifdef PEL_ENABLE_PHAL 871 /** 872 * @brief Create guard record 873 * 874 * @param[in] binPath: phal devtree binary path used as key 875 * @param[in] eGardType: Guard type enum value 876 * @param[in] plid: pel id to be associated to the guard record 877 */ 878 void createGuardRecord(const std::vector<uint8_t>& binPath, 879 GardType eGardType, uint32_t plid) const override; 880 #endif 881 882 /** 883 * @brief Create Progress SRC property on the boot progress 884 * interface on a D-Bus object. 885 * 886 * @param[in] priSRC - Primary SRC value 887 * @param[in] srcStruct - Full SRC base structure 888 */ 889 void 890 createProgressSRC(const uint64_t& priSRC, 891 const std::vector<uint8_t>& srcStruct) const override; 892 893 /** 894 * @brief Get the list of unresolved OpenBMC event log ids that have an 895 * associated hardware isolation entry. 896 * 897 * @return std::vector<uint32_t> - The list of log ids 898 */ 899 std::vector<uint32_t> getLogIDWithHwIsolation() const override; 900 901 /** 902 * @brief Returns the latest raw progress SRC from the State.Boot.Raw 903 * D-Bus interface. 904 * 905 * @return std::vector<uint8_t>: The progress SRC bytes 906 */ 907 std::vector<uint8_t> getRawProgressSRC() const override; 908 909 /** 910 * @brief Returns the FRUs DI property value hosted on the VINI iterface for 911 * the given location code. 912 * 913 * @param[in] locationCode - The location code of the FRU 914 * 915 * @return std::optional<std::vector<uint8_t>> - The FRUs DI or 916 * std::nullopt 917 */ 918 std::optional<std::vector<uint8_t>> 919 getDIProperty(const std::string& locationCode) const override; 920 921 /** 922 * @brief Finds all D-Bus Associated paths that contain any of the 923 * interfaces passed in, by using GetAssociatedSubTreePaths. 924 * 925 * @param[in] associatedPath - The D-Bus object path 926 * @param[in] subtree - The subtree path for which the result should be 927 * fetched 928 * @param[in] depth - The maximum subtree depth for which results should be 929 * fetched 930 * @param[in] interfaces - The desired interfaces 931 * 932 * @return The D-Bus paths. 933 */ 934 DBusPathList getAssociatedPaths( 935 const DBusPath& associatedPath, const DBusPath& subtree, int32_t depth, 936 const DBusInterfaceList& interfaces) const override; 937 938 private: 939 /** 940 * @brief Reads the BMC firmware version string and puts it into 941 * _bmcFWVersion. 942 */ 943 void readBMCFWVersion(); 944 945 /** 946 * @brief Reads the server firmware version string and puts it into 947 * _serverFWVersion. 948 */ 949 void readServerFWVersion(); 950 951 /** 952 * @brief Reads the BMC firmware version ID and puts it into 953 * _bmcFWVersionID. 954 */ 955 void readBMCFWVersionID(); 956 957 /** 958 * @brief Finds all D-Bus paths that contain any of the interfaces 959 * passed in, by using GetSubTreePaths. 960 * 961 * @param[in] interfaces - The desired interfaces 962 * 963 * @return The D-Bus paths. 964 */ 965 DBusPathList getPaths(const DBusInterfaceList& interfaces) const; 966 967 /** 968 * @brief The interfacesAdded callback used on the inventory to 969 * find the D-Bus object that has the motherboard interface. 970 * When the motherboard is found, it then adds a PropertyWatcher 971 * for the motherboard CCIN. 972 */ 973 void motherboardIfaceAdded(sdbusplus::message_t& msg); 974 975 /** 976 * @brief Start watching for the hotpluggable FRUs to become 977 * present. 978 */ 979 void startFruPlugWatch(); 980 981 /** 982 * @brief Create a D-Bus match object for the Present property 983 * to change on the path passed in. 984 * @param[in] path - The path to watch. 985 */ 986 void addHotplugWatch(const std::string& path); 987 988 /** 989 * @brief Callback when an inventory interface was added. 990 * 991 * Only does something if it's one of the hotpluggable FRUs, 992 * in which case it will treat it as a hotplug if the 993 * Present property is true. 994 * 995 * @param[in] msg - The InterfacesAdded signal contents. 996 */ 997 void inventoryIfaceAdded(sdbusplus::message_t& msg); 998 999 /** 1000 * @brief Callback when the Present property changes. 1001 * 1002 * If present, will run the registered callbacks. 1003 * 1004 * @param[in] msg - The PropertiesChanged signal contents. 1005 */ 1006 void presenceChanged(sdbusplus::message_t& msg); 1007 1008 /** 1009 * @brief If the Present property is in the properties map 1010 * passed in and it is true, notify the subscribers. 1011 * 1012 * @param[in] path - The object path of the inventory item. 1013 * @param[in] properties - The properties map 1014 */ 1015 void notifyPresenceSubsribers(const std::string& path, 1016 const DBusPropertyMap& properties); 1017 1018 /** 1019 * @brief Adds the Ufcs- prefix to the location code passed in 1020 * if necessary. 1021 * 1022 * Needed because the location codes that come back from the 1023 * message registry and device callout JSON don't have it. 1024 * 1025 * @param[in] - The location code without a prefix, like P1-C1 1026 * 1027 * @return std::string - The location code with the prefix 1028 */ 1029 static std::string addLocationCodePrefix(const std::string& locationCode); 1030 1031 /** 1032 * @brief A helper API to check whether the PHAL device tree is exists, 1033 * ensuring the PHAL init API can be invoked. 1034 * 1035 * @return true if the PHAL device tree is exists, otherwise false 1036 */ 1037 bool isPHALDevTreeExist() const; 1038 1039 #ifdef PEL_ENABLE_PHAL 1040 /** 1041 * @brief A helper API to init PHAL libraries 1042 * 1043 * @return None 1044 */ 1045 void initPHAL(); 1046 #endif // PEL_ENABLE_PHAL 1047 1048 /** 1049 * @brief A helper API to subscribe to systemd signals 1050 * 1051 * @return None 1052 */ 1053 void subscribeToSystemdSignals(); 1054 1055 /** 1056 * @brief A helper API to unsubscribe to systemd signals 1057 * 1058 * @return None 1059 */ 1060 void unsubscribeFromSystemdSignals(); 1061 1062 /** 1063 * @brief The D-Bus property or interface watchers that have callbacks 1064 * registered that will set members in this class when 1065 * they change. 1066 */ 1067 std::vector<std::unique_ptr<DBusWatcher>> _properties; 1068 1069 std::unique_ptr<sdbusplus::bus::match_t> _invIaMatch; 1070 1071 /** 1072 * @brief The matches for watching for hotplugs. 1073 * 1074 * A map so we can check that we never get duplicates. 1075 */ 1076 std::map<std::string, std::unique_ptr<sdbusplus::bus::match_t>> 1077 _invPresentMatches; 1078 1079 /** 1080 * @brief The sdbusplus bus object for making D-Bus calls. 1081 */ 1082 sdbusplus::bus_t& _bus; 1083 1084 /** 1085 * @brief Watcher to check "openpower-update-bios-attr-table" service 1086 * is "done" to init PHAL libraires 1087 */ 1088 std::unique_ptr<sdbusplus::bus::match_t> _systemdMatch; 1089 1090 /** 1091 * @brief A slot object for async dbus call 1092 */ 1093 sdbusplus::slot_t _systemdSlot; 1094 }; 1095 1096 } // namespace pels 1097 } // namespace openpower 1098