Read mode support from entity manager and update dbus

1. Attempt to read several power mode properties from entity-manager.
Reject any mode change requests that are not in the CustomerModes list.
If the CustomerModes list is empty, all supported mode changes will be
allowed.

CustomerModes: List of power modes that are settable from a customer
user interface.
OemModes: List of OEM power modes that are supported on the system.
EcoModeSupport: Flag to indicate if the system supports a set of
efficiency based settings.

If any of these are not found, occ-control will use the default
supported modes.

Use default if persisted power mode is not supported

2. If previous (persisted) power mode is not supported, the default
power mode for the system will be used. If that default is not found
MaximumPerformance will be used.

Tested on Rainier

'''
xyz.openbmc_project.Control.Power.Mode interface -         -                                                                                                                                                                                                -
.AllowedPowerModes                     property  as        3 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance" "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving" "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static" const
.PowerMode                             property  s         "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving"                                                                                                                                   emits-change writable
.SafeMode                              property  b         false                                                                                                                                                                                            emits-change
'''

Change-Id: Id9b2b493e420fc60b3c29d581d63e9ed0f71c4fc
Signed-off-by: Chris Cain <cjcain@us.ibm.com>
diff --git a/powermode.hpp b/powermode.hpp
index 9a191f7..7133948 100644
--- a/powermode.hpp
+++ b/powermode.hpp
@@ -158,14 +158,12 @@
      */
     bool getMode(SysPwrMode& mode, uint16_t& oemModeData) const
     {
-        if (!modeData.modeInitialized)
+        if (modeData.modeInitialized)
         {
-            return false;
+            mode = modeData.mode;
+            oemModeData = modeData.oemModeData;
         }
-
-        mode = modeData.mode;
-        oemModeData = modeData.oemModeData;
-        return true;
+        return modeData.modeInitialized;
     }
 
     /** @brief Get the Idle Power Saver properties from DBus
@@ -218,6 +216,12 @@
     /** @brief Trace the Power Mode and IPS parameters. */
     void print();
 
+    /** @brief Invalidate the persisted mode */
+    void invalidateMode()
+    {
+        modeData.modeInitialized = false;
+    }
+
   private:
     /** @brief Power Mode data filename to store persistent data */
     static constexpr auto powerModeFilename = "powerModeData";
@@ -251,58 +255,7 @@
      * @param[in] ipsPath - Idle Power Saver dbus path
      */
     explicit PowerMode(const Manager& managerRef, const char* modePath,
-                       const char* ipsPath
-#ifdef POWER10
-                       ,
-                       EventPtr& event
-#endif
-                       ) :
-        ModeInterface(utils::getBus(), modePath,
-                      ModeInterface::action::emit_no_signals),
-        IpsInterface(utils::getBus(), ipsPath,
-                     IpsInterface::action::emit_no_signals),
-        manager(managerRef),
-        pmodeMatch(utils::getBus(),
-                   sdbusplus::bus::match::rules::propertiesChanged(
-                       PMODE_PATH, PMODE_INTERFACE),
-                   [this](auto& msg) { this->modeChanged(msg); }),
-        ipsMatch(utils::getBus(),
-                 sdbusplus::bus::match::rules::propertiesChanged(
-                     PIPS_PATH, PIPS_INTERFACE),
-                 [this](auto& msg) { this->ipsChanged(msg); }),
-        defaultsUpdateMatch(
-            utils::getBus(),
-            sdbusplus::bus::match::rules::propertiesChangedNamespace(
-                "/xyz/openbmc_project/inventory", PMODE_DEFAULT_INTERFACE),
-            [this](auto& msg) { this->defaultsReady(msg); }),
-        masterOccSet(false), masterActive(false)
-#ifdef POWER10
-        ,
-        event(event)
-#endif
-    {
-        using Mode =
-            sdbusplus::xyz::openbmc_project::Control::Power::server::Mode;
-        ModeInterface::allowedPowerModes({Mode::PowerMode::Static,
-                                          Mode::PowerMode::MaximumPerformance,
-                                          Mode::PowerMode::PowerSaving});
-
-        // restore Power Mode to DBus
-        SysPwrMode currentMode;
-        uint16_t oemModeData = 0;
-        if (getMode(currentMode, oemModeData))
-        {
-            updateDbusMode(currentMode);
-        }
-        // restore Idle Power Saver parameters to DBus
-        uint8_t enterUtil, exitUtil;
-        uint16_t enterTime, exitTime;
-        bool ipsEnabled;
-        if (getIPSParms(ipsEnabled, enterUtil, enterTime, exitUtil, exitTime))
-        {
-            updateDbusIPS(ipsEnabled, enterUtil, enterTime, exitUtil, exitTime);
-        }
-    };
+                       const char* ipsPath, EventPtr& event);
 
     /** @brief Initialize the persistent data with default values
      *
@@ -357,7 +310,6 @@
         masterActive = isActive;
     };
 
-#ifdef POWER10
     /** @brief Starts to monitor for IPS active state change conditions
      *
      *  @param[in] poll - Indicates whether or not the IPS state file should
@@ -367,7 +319,6 @@
 
     /** @brief Removes IPS active watch */
     void removeIpsWatch();
-#endif
 
     /** @brief Set dbus property to SAFE Mode(true) or clear SAFE Mode(false)*/
     void updateDbusSafeMode(const bool safeMode);
@@ -380,6 +331,14 @@
      */
     Base::Mode::PowerMode powerMode(Base::Mode::PowerMode value) override;
 
+    /** @brief Determine if the supplied mode is valid for the system
+     *
+     *  @param[in] mode  - potential mode
+     *
+     *  @return          - true if the mode is valid
+     */
+    bool isValidMode(const SysPwrMode mode);
+
   private:
     /** @brief OCC manager object */
     const Manager& manager;
@@ -393,9 +352,6 @@
     /** @brief Object to send commands to the OCC */
     std::unique_ptr<open_power::occ::OccCommand> occCmd;
 
-    /** @brief Used to subscribe to dbus pmode property changes **/
-    sdbusplus::bus::match_t pmodeMatch;
-
     /** @brief Used to subscribe to dbus IPS property changes **/
     sdbusplus::bus::match_t ipsMatch;
 
@@ -404,13 +360,23 @@
 
     OccPersistData persistedData;
 
-    /** @brief True when the master OCC has been established */
+    /** @brief True when the master OCC has been established **/
     bool masterOccSet;
 
-    /** @brief True when the master OCC is active */
+    /** @brief True when the master OCC is active **/
     bool masterActive;
 
-#ifdef POWER10
+    /** @brief True when the ecoModes are supported for this system **/
+    bool ecoModeSupport = false;
+
+    /** @brief List of customer supported power modes **/
+    std::set<SysPwrMode> customerModeList = {
+        SysPwrMode::STATIC, SysPwrMode::POWER_SAVING, SysPwrMode::MAX_PERF};
+
+    /** @brief List of OEM supported power modes **/
+    std::set<SysPwrMode> oemModeList = {SysPwrMode::SFP, SysPwrMode::FFO,
+                                        SysPwrMode::MAX_FREQ};
+
     /** @brief IPS status data filename to read */
     const fs::path ipsStatusFile = std::filesystem::path{OCC_HWMON_PATH} /
                                    std::filesystem::path{OCC_MASTER_NAME} /
@@ -421,16 +387,6 @@
 
     /** @brief register for the callback from the POLL IPS changed event */
     void registerIpsStatusCallBack();
-#endif
-
-    /** @brief Callback for pmode setting changes
-     *
-     * Process change and inform OCC
-     *
-     * @param[in]  msg       - Data associated with pmode change signal
-     *
-     */
-    void modeChanged(sdbusplus::message_t& msg);
 
     /** @brief Get the current power mode property
      *
@@ -520,7 +476,13 @@
      */
     bool useDefaultIPSParms();
 
-#ifdef POWER10
+    /** @brief Read the supported power modes from entity-manager and update
+     * AllowedPowerModes on dbus
+     *
+     * @return true if data was found/updated
+     */
+    bool getSupportedModes();
+
     /** @brief callback for the POLL IPS changed event
      *
      *  @param[in] es       - Populated event source
@@ -546,7 +508,6 @@
   protected:
     /** @brief File descriptor to watch for errors */
     int fd = -1;
-#endif
 };
 
 } // namespace powermode