diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6d0cfea..f7b4fd5 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,6 +67,7 @@
 
 if (CPU_INFO)
     add_executable (cpuinfoapp src/cpuinfo_main.cpp src/speed_select.cpp
+        src/sst_mailbox.cpp
         src/cpuinfo_utils.cpp)
     target_link_libraries (cpuinfoapp ${SYSTEMD_LIBRARIES})
     target_link_libraries (cpuinfoapp ${DBUSINTERFACE_LIBRARIES})
diff --git a/include/cpuinfo_utils.hpp b/include/cpuinfo_utils.hpp
index ab2ea92..926c2d1 100644
--- a/include/cpuinfo_utils.hpp
+++ b/include/cpuinfo_utils.hpp
@@ -47,4 +47,43 @@
  */
 void hostStateSetup(const std::shared_ptr<sdbusplus::asio::connection>& conn);
 
+constexpr uint64_t bit(uint8_t index)
+{
+    return (1ull << index);
+}
+
+/**
+ * Extract a bitfield from an input data by shifting and masking.
+ *
+ * @tparam Dest Destination type - mostly useful to avoid an extra static_cast
+ *              at the call site. Defaults to the Src type if unspecified.
+ * @tparam Src  Automatically deduced from the first positional parameter.
+ *
+ * @param data  Input data.
+ * @param loBit 0-based index of the least significant bit to return.
+ * @param hiBit 0-based index of the most significant bit to return.
+ */
+template <typename Dest = std::monostate, typename Src>
+auto mask(Src data, unsigned int loBit, unsigned int hiBit)
+{
+    assert(hiBit >= loBit);
+    uint64_t d = data;
+    d >>= loBit;
+    d &= (1ull << (hiBit - loBit + 1)) - 1;
+    if constexpr (std::is_same_v<Dest, std::monostate>)
+    {
+        return static_cast<Src>(d);
+    }
+    else
+    {
+        return static_cast<Dest>(d);
+    }
+}
+
+namespace dbus
+{
+boost::asio::io_context& getIOContext();
+std::shared_ptr<sdbusplus::asio::connection> getConnection();
+} // namespace dbus
+
 } // namespace cpu_info
diff --git a/include/speed_select.hpp b/include/speed_select.hpp
index aaa8b70..4b4189f 100644
--- a/include/speed_select.hpp
+++ b/include/speed_select.hpp
@@ -13,9 +13,14 @@
 // limitations under the License.
 #pragma once
 
+#include <peci.h>
+
 #include <boost/asio/io_context.hpp>
 #include <sdbusplus/asio/connection.hpp>
 
+#include <bitset>
+#include <iostream>
+
 namespace cpu_info
 {
 namespace sst
@@ -36,5 +41,148 @@
 void init(boost::asio::io_context& ioc,
           const std::shared_ptr<sdbusplus::asio::connection>& conn);
 
+class PECIError : public std::runtime_error
+{
+    using std::runtime_error::runtime_error;
+};
+
+bool checkPECIStatus(EPECIStatus libStatus, uint8_t completionCode);
+
+constexpr int extendedModel(CPUModel model)
+{
+    return (model >> 16) & 0xF;
+}
+
+/**
+ * Construct a list of indexes of the set bits in the input value.
+ * E.g. fn(0x7A) -> {1,3,4,5,6}
+ *
+ * @param[in]   mask    Bitmask to convert.
+ *
+ * @return  List of bit indexes.
+ */
+static std::vector<uint32_t> convertMaskToList(std::bitset<64> mask)
+{
+    std::vector<uint32_t> bitList;
+    for (size_t i = 0; i < mask.size(); ++i)
+    {
+        if (mask.test(i))
+        {
+            bitList.push_back(i);
+        }
+    }
+    return bitList;
+}
+
+using TurboEntry = std::tuple<uint32_t, size_t>;
+
+/**
+ * Abstract interface that must be implemented by backends, allowing discovery
+ * and control of a single CPU package.
+ */
+class SSTInterface
+{
+  public:
+    virtual ~SSTInterface()
+    {}
+
+    /**
+     * Whether the interface is ready to be used, or we need to wait longer. The
+     * backend may need to wait e.g. for the host BIOS to initialize the
+     * interface.
+     */
+    virtual bool ready() = 0;
+
+    /** Whether the processor supports the control ("set") functions. */
+    virtual bool supportsControl() = 0;
+
+    /** Whether SST-PP is enabled on the processor. */
+    virtual bool ppEnabled() = 0;
+    /** Return the current SST-PP configuration level */
+    virtual unsigned int currentLevel() = 0;
+    /** Return the maximum valid SST-PP configuration level */
+    virtual unsigned int numLevels() = 0;
+
+    /**
+     * Whether the given level is supported. The level indices may be
+     * discontinuous, so this function should be used before querying deeper
+     * properties of a level.
+     */
+    virtual bool levelSupported(unsigned int level) = 0;
+    /** Whether SST-BF is supported in a given level. */
+    virtual bool bfSupported(unsigned int level) = 0;
+    /** Whether SST-TF is supported in a given level. */
+    virtual bool tfSupported(unsigned int level) = 0;
+    /** Whether SST-BF is enabled in a given level. */
+    virtual bool bfEnabled(unsigned int level) = 0;
+    /** Whether SST-TF is enabled in a given level. */
+    virtual bool tfEnabled(unsigned int level) = 0;
+    /** Return the package Thermal Design Power in Watts for a given level. */
+    virtual unsigned int tdp(unsigned int level) = 0;
+    /** Return the number of cores enabled in a given level. */
+    virtual unsigned int coreCount(unsigned int level) = 0;
+    /** Return the list of enabled logical core indices for a given level. */
+    virtual std::vector<unsigned int> enabledCoreList(unsigned int level) = 0;
+    /**
+     * Return the list of TurboEntrys which define the SSE turbo profile for a
+     * given level.
+     */
+    virtual std::vector<TurboEntry> sseTurboProfile(unsigned int level) = 0;
+    /** Return the base frequency (P1) for a given level. */
+    virtual unsigned int p1Freq(unsigned int level) = 0;
+    /** Return the maximum single-core frequency (P0) for a given level. */
+    virtual unsigned int p0Freq(unsigned int level) = 0;
+    /**
+     * Return the DTS max or external Prochot temperature in degrees Celsius
+     * for a given level.
+     */
+    virtual unsigned int prochotTemp(unsigned int level) = 0;
+    /**
+     * Return the list of logical core indices which have high priority when
+     * SST-BF is enabled for a given level.
+     */
+    virtual std::vector<unsigned int>
+        bfHighPriorityCoreList(unsigned int level) = 0;
+    /** Return the high priority base frequency for a given level. */
+    virtual unsigned int bfHighPriorityFreq(unsigned int level) = 0;
+    /** Return the low priority base frequency for a given level. */
+    virtual unsigned int bfLowPriorityFreq(unsigned int level) = 0;
+
+    /** Enable or disable SST-BF for the current configuration. */
+    virtual void setBfEnabled(bool enable) = 0;
+    /** Enable or disable SST-TF for the current configuration. */
+    virtual void setTfEnabled(bool enable) = 0;
+    /** Change the current configuration to the given level. */
+    virtual void setCurrentLevel(unsigned int level) = 0;
+};
+
+/**
+ * BackendProvider represents a function which may create an SSTInterface given
+ * a CPU PECI address, and the CPU Model information. Usually the CPUModel is
+ * sufficient to determine if the backend is supported.
+ * Backend should return nullptr to indicate it doesn't support a given CPU.
+ * The SST upper layer will call the registered backend provider functions in
+ * arbitrary order until one of them returns a non-null pointer.
+ */
+using BackendProvider =
+    std::function<std::unique_ptr<SSTInterface>(uint8_t, CPUModel)>;
+
+/**
+ * Backends should use 1 instance of the SSTProviderRegistration macro at file
+ * scope to register their provider function. This static struct instance
+ * register the backend before main() is run, and prevents the upper layer from
+ * having to know about which backends exist.
+ */
+#define SSTProviderRegistration(fn)                                            \
+    struct fn##Register                                                        \
+    {                                                                          \
+        fn##Register()                                                         \
+        {                                                                      \
+            std::cerr << "Registering SST Provider " #fn << std::endl;         \
+            registerBackend(fn);                                               \
+        }                                                                      \
+    } fn##Instance;
+void registerBackend(BackendProvider);
+
 } // namespace sst
 } // namespace cpu_info
diff --git a/src/cpuinfo_main.cpp b/src/cpuinfo_main.cpp
index c9dd3e5..1d91f17 100644
--- a/src/cpuinfo_main.cpp
+++ b/src/cpuinfo_main.cpp
@@ -636,9 +636,9 @@
 int main(int argc, char* argv[])
 {
     // setup connection to dbus
-    boost::asio::io_service io;
+    boost::asio::io_service& io = cpu_info::dbus::getIOContext();
     std::shared_ptr<sdbusplus::asio::connection> conn =
-        std::make_shared<sdbusplus::asio::connection>(io);
+        cpu_info::dbus::getConnection();
 
     // CPUInfo Object
     conn->request_name(cpu_info::cpuInfoObject);
diff --git a/src/cpuinfo_utils.cpp b/src/cpuinfo_utils.cpp
index e30a275..1c69e6a 100644
--- a/src/cpuinfo_utils.cpp
+++ b/src/cpuinfo_utils.cpp
@@ -288,4 +288,18 @@
     initialized = true;
 }
 
+namespace dbus
+{
+boost::asio::io_context& getIOContext()
+{
+    static boost::asio::io_context ioc;
+    return ioc;
+}
+std::shared_ptr<sdbusplus::asio::connection> getConnection()
+{
+    static auto conn =
+        std::make_shared<sdbusplus::asio::connection>(getIOContext());
+    return conn;
+}
+} // namespace dbus
 } // namespace cpu_info
diff --git a/src/speed_select.cpp b/src/speed_select.cpp
index c320e39..3a2f8f4 100644
--- a/src/speed_select.cpp
+++ b/src/speed_select.cpp
@@ -25,8 +25,10 @@
 #include <xyz/openbmc_project/Control/Processor/CurrentOperatingConfig/server.hpp>
 #include <xyz/openbmc_project/Inventory/Item/Cpu/OperatingConfig/server.hpp>
 
+#include <algorithm>
 #include <iostream>
 #include <memory>
+#include <stdexcept>
 #include <string>
 
 namespace cpu_info
@@ -34,418 +36,57 @@
 namespace sst
 {
 
-class PECIError : public std::runtime_error
+// Specialize char to print the integer value instead of ascii. We basically
+// never want to print a single ascii char.
+std::ostream& operator<<(std::ostream& os, uint8_t value)
 {
-    using std::runtime_error::runtime_error;
-};
-
-constexpr uint64_t bit(int index)
-{
-    return (1ull << index);
+    return os << static_cast<int>(value);
 }
 
-constexpr int extendedModel(CPUModel model)
-{
-    return (model >> 16) & 0xF;
-}
-
-constexpr bool modelSupportsDiscovery(CPUModel model)
-{
-    return extendedModel(model) >= extendedModel(icx);
-}
-
-constexpr bool modelSupportsControl(CPUModel model)
-{
-    return extendedModel(model) > extendedModel(icx);
-}
-
-/**
- * Construct a list of indexes of the set bits in the input value.
- * E.g. fn(0x7A) -> {1,3,4,5,6}
- *
- * @param[in]   mask    Bitmask to convert.
- *
- * @return  List of bit indexes.
- */
-static std::vector<uint32_t> convertMaskToList(std::bitset<64> mask)
-{
-    std::vector<uint32_t> bitList;
-    for (size_t i = 0; i < mask.size(); ++i)
-    {
-        if (mask.test(i))
-        {
-            bitList.push_back(i);
-        }
-    }
-    return bitList;
-}
-
-static bool checkPECIStatus(EPECIStatus libStatus, uint8_t completionCode)
+bool checkPECIStatus(EPECIStatus libStatus, uint8_t completionCode)
 {
     if (libStatus != PECI_CC_SUCCESS || completionCode != PECI_DEV_CC_SUCCESS)
     {
         std::cerr << "PECI command failed."
                   << " Driver Status = " << libStatus << ","
-                  << " Completion Code = " << static_cast<int>(completionCode)
-                  << '\n';
+                  << " Completion Code = " << completionCode << '\n';
         return false;
     }
     return true;
 }
 
-/**
- * Convenience RAII object for Wake-On-PECI (WOP) management, since PECI Config
- * Local accesses to the OS Mailbox require the package to pop up to PC2. Also
- * provides PCode OS Mailbox routine.
- *
- * Since multiple applications may be modifing WOP, we'll use this algorithm:
- * Whenever a PECI command fails with associated error code, set WOP bit and
- * retry command. Upon manager destruction, clear WOP bit only if we previously
- * set it.
- */
-struct PECIManager
+static std::vector<BackendProvider>& getProviders()
 {
-    int peciAddress;
-    bool peciWoken;
-    CPUModel cpuModel;
-    int mbBus;
+    static auto* providers = new std::vector<BackendProvider>;
+    return *providers;
+}
 
-    PECIManager(int address, CPUModel model) :
-        peciAddress(address), peciWoken(false), cpuModel(model)
-    {
-        mbBus = (model == icx) ? 14 : 31;
-    }
+void registerBackend(BackendProvider providerFn)
+{
+    getProviders().push_back(providerFn);
+}
 
-    ~PECIManager()
+std::unique_ptr<SSTInterface> getInstance(uint8_t address, CPUModel model)
+{
+    DEBUG_PRINT << "Searching for provider for " << address << ", model "
+                << std::hex << model << '\n';
+    for (const auto& provider : getProviders())
     {
-        // If we're being destroyed due to a PECIError, try to clear the mode
-        // bit, but catch and ignore any duplicate error it might raise to
-        // prevent termination.
         try
         {
-            if (peciWoken)
+            auto interface = provider(address, model);
+            DEBUG_PRINT << "returned " << interface << '\n';
+            if (interface)
             {
-                setWakeOnPECI(false);
+                return interface;
             }
         }
-        catch (const PECIError& err)
+        catch (...)
         {}
     }
-
-    static bool isSleeping(EPECIStatus libStatus, uint8_t completionCode)
-    {
-        // PECI completion code defined in peci-ioctl.h which is not available
-        // for us to include.
-        constexpr int PECI_DEV_CC_UNAVAIL_RESOURCE = 0x82;
-        // Observed library returning DRIVER_ERR for reads and TIMEOUT for
-        // writes while PECI is sleeping. Either way, the completion code from
-        // PECI client should be reliable indicator of need to set WOP.
-        return libStatus != PECI_CC_SUCCESS &&
-               completionCode == PECI_DEV_CC_UNAVAIL_RESOURCE;
-    }
-
-    /**
-     * Send a single PECI PCS write to modify the Wake-On-PECI mode bit
-     */
-    void setWakeOnPECI(bool enable)
-    {
-        uint8_t completionCode;
-        EPECIStatus libStatus =
-            peci_WrPkgConfig(peciAddress, 5, enable ? 1 : 0, 0,
-                             sizeof(uint32_t), &completionCode);
-        if (!checkPECIStatus(libStatus, completionCode))
-        {
-            throw PECIError("Failed to set Wake-On-PECI mode bit");
-        }
-
-        if (enable)
-        {
-            peciWoken = true;
-        }
-    }
-
-    // PCode OS Mailbox interface register locations
-    static constexpr int mbSegment = 0;
-    static constexpr int mbDevice = 30;
-    static constexpr int mbFunction = 1;
-    static constexpr int mbDataReg = 0xA0;
-    static constexpr int mbInterfaceReg = 0xA4;
-    static constexpr int mbRegSize = sizeof(uint32_t);
-
-    enum class MailboxStatus
-    {
-        NoError = 0x0,
-        InvalidCommand = 0x1,
-        IllegalData = 0x16
-    };
-
-    /**
-     * Send a single Write PCI Config Local command, targeting the PCU CR1
-     * register block.
-     *
-     * @param[in]   regAddress  PCI Offset of register.
-     * @param[in]   data        Data to write.
-     */
-    void wrMailboxReg(uint16_t regAddress, uint32_t data)
-    {
-        uint8_t completionCode;
-        bool tryWaking = true;
-        while (true)
-        {
-            EPECIStatus libStatus = peci_WrEndPointPCIConfigLocal(
-                peciAddress, mbSegment, mbBus, mbDevice, mbFunction, regAddress,
-                mbRegSize, data, &completionCode);
-            if (tryWaking && isSleeping(libStatus, completionCode))
-            {
-                setWakeOnPECI(true);
-                tryWaking = false;
-                continue;
-            }
-            else if (!checkPECIStatus(libStatus, completionCode))
-            {
-                throw PECIError("Failed to write mailbox reg");
-            }
-            break;
-        }
-    }
-
-    /**
-     * Send a single Read PCI Config Local command, targeting the PCU CR1
-     * register block.
-     *
-     * @param[in]   regAddress  PCI offset of register.
-     *
-     * @return  Register value
-     */
-    uint32_t rdMailboxReg(uint16_t regAddress)
-    {
-        uint8_t completionCode;
-        uint32_t outputData;
-        bool tryWaking = true;
-        while (true)
-        {
-            EPECIStatus libStatus = peci_RdEndPointConfigPciLocal(
-                peciAddress, mbSegment, mbBus, mbDevice, mbFunction, regAddress,
-                mbRegSize, reinterpret_cast<uint8_t*>(&outputData),
-                &completionCode);
-            if (tryWaking && isSleeping(libStatus, completionCode))
-            {
-                setWakeOnPECI(true);
-                tryWaking = false;
-                continue;
-            }
-            if (!checkPECIStatus(libStatus, completionCode))
-            {
-                throw PECIError("Failed to read mailbox reg");
-            }
-            break;
-        }
-        return outputData;
-    }
-
-    /**
-     * Send command on PCode OS Mailbox interface.
-     *
-     * @param[in]   command     Main command ID.
-     * @param[in]   subCommand  Sub command ID.
-     * @param[in]   inputData   Data to put in mailbox. Is always written, but
-     *                          will be ignored by PCode if command is a
-     *                          "getter".
-     * @param[out]  responseCode    Optional parameter to receive the
-     *                              mailbox-level response status. If null, a
-     *                              PECIError will be thrown for error status.
-     *
-     * @return  Data returned in mailbox. Value is undefined if command is a
-     *          "setter".
-     */
-    uint32_t sendPECIOSMailboxCmd(uint8_t command, uint8_t subCommand,
-                                  uint32_t inputData = 0,
-                                  MailboxStatus* responseCode = nullptr)
-    {
-        // The simple mailbox algorithm just says to wait until the busy bit
-        // is clear, but we'll give up after 10 tries. It's arbitrary but that's
-        // quite long wall clock time.
-        constexpr int mbRetries = 10;
-        constexpr uint32_t mbBusyBit = bit(31);
-
-        // Wait until RUN_BUSY == 0
-        int attempts = mbRetries;
-        while ((rdMailboxReg(mbInterfaceReg) & mbBusyBit) != 0 &&
-               --attempts > 0)
-            ;
-        if (attempts == 0)
-        {
-            throw PECIError("OS Mailbox failed to become free");
-        }
-
-        // Write required command specific input data to data register
-        wrMailboxReg(mbDataReg, inputData);
-
-        // Write required command specific command/sub-command values and set
-        // RUN_BUSY bit in interface register.
-        uint32_t interfaceReg =
-            mbBusyBit | (static_cast<uint32_t>(subCommand) << 8) | command;
-        wrMailboxReg(mbInterfaceReg, interfaceReg);
-
-        // Wait until RUN_BUSY == 0
-        attempts = mbRetries;
-        do
-        {
-            interfaceReg = rdMailboxReg(mbInterfaceReg);
-        } while ((interfaceReg & mbBusyBit) != 0 && --attempts > 0);
-        if (attempts == 0)
-        {
-            throw PECIError("OS Mailbox failed to return");
-        }
-
-        // Read command return status or error code from interface register
-        auto status = static_cast<MailboxStatus>(interfaceReg & 0xFF);
-        if (responseCode != nullptr)
-        {
-            *responseCode = status;
-        }
-        else if (status != MailboxStatus::NoError)
-        {
-            throw PECIError(std::string("OS Mailbox returned with error: ") +
-                            std::to_string(static_cast<int>(status)));
-        }
-
-        // Read command return data from the data register
-        return rdMailboxReg(mbDataReg);
-    }
-};
-
-/**
- * Base class for set of PECI OS Mailbox commands.
- * Constructing it runs the command and stores the value for use by derived
- * class accessor methods.
- */
-template <uint8_t subcommand>
-struct OsMailboxCommand
-{
-    enum ErrorPolicy
-    {
-        Throw,
-        NoThrow
-    };
-
-    uint32_t value;
-    PECIManager::MailboxStatus status;
-    /**
-     * Construct the command object with required PECI address and up to 4
-     * optional 1-byte input data parameters.
-     */
-    OsMailboxCommand(PECIManager& pm, uint8_t param1 = 0, uint8_t param2 = 0,
-                     uint8_t param3 = 0, uint8_t param4 = 0) :
-        OsMailboxCommand(pm, ErrorPolicy::Throw, param1, param2, param3, param4)
-    {}
-
-    OsMailboxCommand(PECIManager& pm, ErrorPolicy errorPolicy,
-                     uint8_t param1 = 0, uint8_t param2 = 0, uint8_t param3 = 0,
-                     uint8_t param4 = 0)
-    {
-        PECIManager::MailboxStatus* callStatus =
-            errorPolicy == Throw ? nullptr : &status;
-        uint32_t param =
-            (param4 << 24) | (param3 << 16) | (param2 << 8) | param1;
-        value = pm.sendPECIOSMailboxCmd(0x7F, subcommand, param, callStatus);
-    }
-
-    /** Return whether the mailbox status indicated success or not. */
-    bool success() const
-    {
-        return status == PECIManager::MailboxStatus::NoError;
-    }
-};
-
-/**
- * Macro to define a derived class accessor method.
- *
- * @param[in]   type    Return type of accessor method.
- * @param[in]   name    Name of accessor method.
- * @param[in]   hibit   Most significant bit of field to access.
- * @param[in]   lobit   Least significant bit of field to access.
- */
-#define FIELD(type, name, hibit, lobit)                                        \
-    type name() const                                                          \
-    {                                                                          \
-        return (value >> lobit) & (bit(hibit - lobit + 1) - 1);                \
-    }
-
-struct GetLevelsInfo : OsMailboxCommand<0x0>
-{
-    using OsMailboxCommand::OsMailboxCommand;
-    FIELD(bool, enabled, 31, 31)
-    FIELD(bool, lock, 24, 24)
-    FIELD(int, currentConfigTdpLevel, 23, 16)
-    FIELD(int, configTdpLevels, 15, 8)
-    FIELD(int, version, 7, 0)
-};
-
-struct GetConfigTdpControl : OsMailboxCommand<0x1>
-{
-    using OsMailboxCommand::OsMailboxCommand;
-    FIELD(bool, pbfEnabled, 17, 17);
-    FIELD(bool, factEnabled, 16, 16);
-    FIELD(bool, pbfSupport, 1, 1);
-    FIELD(bool, factSupport, 0, 0);
-};
-
-struct SetConfigTdpControl : OsMailboxCommand<0x2>
-{
-    using OsMailboxCommand::OsMailboxCommand;
-};
-
-struct GetTdpInfo : OsMailboxCommand<0x3>
-{
-    using OsMailboxCommand::OsMailboxCommand;
-    FIELD(int, tdpRatio, 23, 16);
-    FIELD(int, pkgTdp, 14, 0);
-};
-
-struct GetCoreMask : OsMailboxCommand<0x6>
-{
-    using OsMailboxCommand::OsMailboxCommand;
-    FIELD(uint32_t, coresMask, 31, 0);
-};
-
-struct GetTurboLimitRatios : OsMailboxCommand<0x7>
-{
-    using OsMailboxCommand::OsMailboxCommand;
-};
-
-struct SetLevel : OsMailboxCommand<0x8>
-{
-    using OsMailboxCommand::OsMailboxCommand;
-};
-
-struct GetRatioInfo : OsMailboxCommand<0xC>
-{
-    using OsMailboxCommand::OsMailboxCommand;
-    FIELD(int, pm, 31, 24);
-    FIELD(int, pn, 23, 16);
-    FIELD(int, p1, 15, 8);
-    FIELD(int, p0, 7, 0);
-};
-
-struct GetTjmaxInfo : OsMailboxCommand<0x5>
-{
-    using OsMailboxCommand::OsMailboxCommand;
-    FIELD(int, tProchot, 7, 0);
-};
-
-struct PbfGetCoreMaskInfo : OsMailboxCommand<0x20>
-{
-    using OsMailboxCommand::OsMailboxCommand;
-    FIELD(uint32_t, p1HiCoreMask, 31, 0);
-};
-
-struct PbfGetP1HiP1LoInfo : OsMailboxCommand<0x21>
-{
-    using OsMailboxCommand::OsMailboxCommand;
-    FIELD(int, p1Hi, 15, 8);
-    FIELD(int, p1Lo, 7, 0);
-};
+    DEBUG_PRINT << "No supported backends found\n";
+    return nullptr;
+}
 
 using BaseCurrentOperatingConfig =
     sdbusplus::server::object_t<sdbusplus::xyz::openbmc_project::Control::
@@ -459,11 +100,12 @@
 {
   public:
     std::string path;
-    int level;
+    unsigned int level;
 
   public:
     using BaseOperatingConfig::BaseOperatingConfig;
-    OperatingConfig(sdbusplus::bus::bus& bus, int level_, std::string path_) :
+    OperatingConfig(sdbusplus::bus::bus& bus, unsigned int level_,
+                    std::string path_) :
         BaseOperatingConfig(bus, path_.c_str(), action::defer_emit),
         path(std::move(path_)), level(level_)
     {}
@@ -475,10 +117,9 @@
     /** Objects describing all available SST configs - not modifiable. */
     std::vector<std::unique_ptr<OperatingConfig>> availConfigs;
     sdbusplus::bus::bus& bus;
-    const int peciAddress;
+    const uint8_t peciAddress;
     const std::string path; ///< D-Bus path of CPU object
     const CPUModel cpuModel;
-    const bool modificationAllowed;
 
     // Keep mutable copies of the properties so we can cache values that we
     // retrieve in the getters. We don't want to throw an error on a D-Bus
@@ -487,38 +128,31 @@
     // These values can be changed by in-band software so we have to do a full
     // PECI read on every get-property, and can't assume that values will change
     // only when set-property is done.
-    mutable int currentLevel;
+    mutable unsigned int currentLevel;
     mutable bool bfEnabled;
-    /**
-     * Cached SST-TF enablement status. This is not exposed on D-Bus, but it's
-     * needed because the command SetConfigTdpControl requires setting both
-     * bits at once.
-     */
-    mutable bool tfEnabled;
 
     /**
      * Enforce common pre-conditions for D-Bus set property handlers.
      */
-    void setPropertyCheckOrThrow()
+    void setPropertyCheckOrThrow(SSTInterface& sst)
     {
-        if (!modificationAllowed)
+        if (!sst.supportsControl())
         {
             throw sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed();
         }
-        if (hostState != HostState::postComplete)
+        if (hostState != HostState::postComplete || !sst.ready())
         {
             throw sdbusplus::xyz::openbmc_project::Common::Error::Unavailable();
         }
     }
 
   public:
-    CPUConfig(sdbusplus::bus::bus& bus_, int index, CPUModel model) :
+    CPUConfig(sdbusplus::bus::bus& bus_, uint8_t index, CPUModel model) :
         BaseCurrentOperatingConfig(bus_, generatePath(index).c_str(),
                                    action::defer_emit),
         bus(bus_), peciAddress(index + MIN_CLIENT_ADDR),
-        path(generatePath(index)), cpuModel(model),
-        modificationAllowed(modelSupportsControl(model)), currentLevel(0),
-        bfEnabled(false), tfEnabled(false)
+        path(generatePath(index)), cpuModel(model), currentLevel(0),
+        bfEnabled(false)
     {}
 
     //
@@ -527,20 +161,29 @@
 
     sdbusplus::message::object_path appliedConfig() const override
     {
+        DEBUG_PRINT << "Reading AppliedConfig\n";
         // If CPU is powered off, return power-up default value of Level 0.
-        int level = 0;
+        unsigned int level = 0;
         if (hostState != HostState::off)
         {
             // Otherwise, try to read current state
-            try
+            auto sst = getInstance(peciAddress, cpuModel);
+            if (!sst)
             {
-                PECIManager pm(peciAddress, cpuModel);
-                currentLevel = GetLevelsInfo(pm).currentConfigTdpLevel();
+                std::cerr << __func__
+                          << ": Failed to get SST provider instance\n";
             }
-            catch (const PECIError& error)
+            else
             {
-                std::cerr << "Failed to get SST-PP level: " << error.what()
-                          << "\n";
+                try
+                {
+                    currentLevel = sst->currentLevel();
+                }
+                catch (const PECIError& error)
+                {
+                    std::cerr << "Failed to get SST-PP level: " << error.what()
+                              << "\n";
+                }
             }
             level = currentLevel;
         }
@@ -549,20 +192,27 @@
 
     bool baseSpeedPriorityEnabled() const override
     {
+        DEBUG_PRINT << "Reading BaseSpeedPriorityEnabled\n";
         bool enabled = false;
         if (hostState != HostState::off)
         {
-            try
+            auto sst = getInstance(peciAddress, cpuModel);
+            if (!sst)
             {
-                PECIManager pm(peciAddress, cpuModel);
-                GetConfigTdpControl tdpControl(pm, currentLevel);
-                bfEnabled = tdpControl.pbfEnabled();
-                tfEnabled = tdpControl.factEnabled();
+                std::cerr << __func__
+                          << ": Failed to get SST provider instance\n";
             }
-            catch (const PECIError& error)
+            else
             {
-                std::cerr << "Failed to get SST-BF status: " << error.what()
-                          << "\n";
+                try
+                {
+                    bfEnabled = sst->bfEnabled(currentLevel);
+                }
+                catch (const PECIError& error)
+                {
+                    std::cerr << "Failed to get SST-BF status: " << error.what()
+                              << "\n";
+                }
             }
             enabled = bfEnabled;
         }
@@ -572,8 +222,7 @@
     sdbusplus::message::object_path
         appliedConfig(sdbusplus::message::object_path value) override
     {
-        setPropertyCheckOrThrow();
-
+        DEBUG_PRINT << "Writing AppliedConfig\n";
         const OperatingConfig* newConfig = nullptr;
         for (const auto& config : availConfigs)
         {
@@ -589,10 +238,16 @@
                 InvalidArgument();
         }
 
+        auto sst = getInstance(peciAddress, cpuModel);
+        if (!sst)
+        {
+            std::cerr << __func__ << ": Failed to get SST provider instance\n";
+            return sdbusplus::message::object_path();
+        }
+        setPropertyCheckOrThrow(*sst);
         try
         {
-            PECIManager pm(peciAddress, cpuModel);
-            SetLevel(pm, newConfig->level);
+            sst->setCurrentLevel(newConfig->level);
             currentLevel = newConfig->level;
         }
         catch (const PECIError& error)
@@ -609,16 +264,17 @@
 
     bool baseSpeedPriorityEnabled(bool value) override
     {
-        setPropertyCheckOrThrow();
-
+        DEBUG_PRINT << "Writing BaseSpeedPriorityEnabled\n";
+        auto sst = getInstance(peciAddress, cpuModel);
+        if (!sst)
+        {
+            std::cerr << __func__ << ": Failed to get SST provider instance\n";
+            return false;
+        }
+        setPropertyCheckOrThrow(*sst);
         try
         {
-            constexpr uint32_t bfEnabledBit = bit(17);
-            constexpr uint32_t tfEnabledBit = bit(16);
-            PECIManager pm(peciAddress, cpuModel);
-            uint32_t param =
-                (value ? bfEnabledBit : 0) | (tfEnabled ? tfEnabledBit : 0);
-            SetConfigTdpControl tdpControl(pm, 0, 0, param >> 16);
+            sst->setBfEnabled(value);
         }
         catch (const PECIError& error)
         {
@@ -636,14 +292,14 @@
     // Additions
     //
 
-    OperatingConfig& newConfig(int level)
+    OperatingConfig& newConfig(unsigned int level)
     {
         availConfigs.emplace_back(std::make_unique<OperatingConfig>(
             bus, level, generateConfigPath(level)));
         return *availConfigs.back();
     }
 
-    std::string generateConfigPath(int level) const
+    std::string generateConfigPath(unsigned int level) const
     {
         return path + "/config" + std::to_string(level);
     }
@@ -672,78 +328,41 @@
  * Retrieve the SST parameters for a single config and fill the values into the
  * properties on the D-Bus interface.
  *
- * @param[in,out]   peciManager     PECI context to use.
- * @param[in]       level           Config TDP level to retrieve.
- * @param[out]      config          D-Bus interface to update.
- * @param[in]       trlCores        Turbo ratio limit core ranges from MSR
- *                                  0x1AE. This is constant across all configs
- *                                  in a CPU.
+ * @param[in,out]   sst         Interface to SST backend.
+ * @param[in]       level       Config TDP level to retrieve.
+ * @param[out]      config      D-Bus interface to update.
  */
-static void getSingleConfig(PECIManager& peciManager, int level,
-                            OperatingConfig& config, uint64_t trlCores)
+static void getSingleConfig(SSTInterface& sst, unsigned int level,
+                            OperatingConfig& config)
 {
-    constexpr int mhzPerRatio = 100;
+    config.powerLimit(sst.tdp(level));
 
-    // PowerLimit <= GET_TDP_INFO.PKG_TDP
-    config.powerLimit(GetTdpInfo(peciManager, level).pkgTdp());
+    config.availableCoreCount(sst.coreCount(level));
 
-    // AvailableCoreCount <= GET_CORE_MASK.CORES_MASK
-    uint64_t coreMaskLo = GetCoreMask(peciManager, level, 0).coresMask();
-    uint64_t coreMaskHi = GetCoreMask(peciManager, level, 1).coresMask();
-    std::bitset<64> coreMask = (coreMaskHi << 32) | coreMaskLo;
-    config.availableCoreCount(coreMask.count());
+    config.baseSpeed(sst.p1Freq(level));
 
-    // BaseSpeed <= GET_RATIO_INFO.P1
-    GetRatioInfo getRatioInfo(peciManager, level);
-    config.baseSpeed(getRatioInfo.p1() * mhzPerRatio);
+    config.maxSpeed(sst.p0Freq(level));
 
-    // MaxSpeed <= GET_RATIO_INFO.P0
-    config.maxSpeed(getRatioInfo.p0() * mhzPerRatio);
-
-    // MaxJunctionTemperature <= GET_TJMAX_INFO.T_PROCHOT
-    config.maxJunctionTemperature(GetTjmaxInfo(peciManager, level).tProchot());
+    config.maxJunctionTemperature(sst.prochotTemp(level));
 
     // Construct BaseSpeedPrioritySettings
-    GetConfigTdpControl getConfigTdpControl(peciManager, level);
     std::vector<std::tuple<uint32_t, std::vector<uint32_t>>> baseSpeeds;
-    if (getConfigTdpControl.pbfSupport())
+    if (sst.bfSupported(level))
     {
-        coreMaskLo = PbfGetCoreMaskInfo(peciManager, level, 0).p1HiCoreMask();
-        coreMaskHi = PbfGetCoreMaskInfo(peciManager, level, 1).p1HiCoreMask();
-        std::bitset<64> hiFreqCoreMask = (coreMaskHi << 32) | coreMaskLo;
+        std::vector<uint32_t> totalCoreList, loFreqCoreList, hiFreqCoreList;
+        totalCoreList = sst.enabledCoreList(level);
+        hiFreqCoreList = sst.bfHighPriorityCoreList(level);
+        std::set_difference(
+            totalCoreList.begin(), totalCoreList.end(), hiFreqCoreList.begin(),
+            hiFreqCoreList.end(),
+            std::inserter(loFreqCoreList, loFreqCoreList.begin()));
 
-        std::vector<uint32_t> hiFreqCoreList, loFreqCoreList;
-        hiFreqCoreList = convertMaskToList(hiFreqCoreMask);
-        loFreqCoreList = convertMaskToList(coreMask & ~hiFreqCoreMask);
-
-        PbfGetP1HiP1LoInfo pbfGetP1HiP1LoInfo(peciManager, level);
-        baseSpeeds = {
-            {pbfGetP1HiP1LoInfo.p1Hi() * mhzPerRatio, hiFreqCoreList},
-            {pbfGetP1HiP1LoInfo.p1Lo() * mhzPerRatio, loFreqCoreList}};
+        baseSpeeds = {{sst.bfHighPriorityFreq(level), hiFreqCoreList},
+                      {sst.bfLowPriorityFreq(level), loFreqCoreList}};
     }
     config.baseSpeedPrioritySettings(baseSpeeds);
 
-    // Construct TurboProfile
-    std::vector<std::tuple<uint32_t, size_t>> turboSpeeds;
-
-    // Only read the SSE ratios (don't need AVX2/AVX512).
-    uint64_t limitRatioLo = GetTurboLimitRatios(peciManager, level, 0, 0).value;
-    uint64_t limitRatioHi = GetTurboLimitRatios(peciManager, level, 1, 0).value;
-    uint64_t limitRatios = (limitRatioHi << 32) | limitRatioLo;
-
-    constexpr int maxTFBuckets = 8;
-    for (int i = 0; i < maxTFBuckets; ++i)
-    {
-        size_t bucketCount = trlCores & 0xFF;
-        int bucketSpeed = limitRatios & 0xFF;
-        if (bucketCount != 0 && bucketSpeed != 0)
-        {
-            turboSpeeds.push_back({bucketSpeed * mhzPerRatio, bucketCount});
-        }
-        trlCores >>= 8;
-        limitRatios >>= 8;
-    }
-    config.turboProfile(turboSpeeds);
+    config.turboProfile(sst.sseTurboProfile(level));
 }
 
 /**
@@ -754,6 +373,7 @@
  *                          including pointers to D-Bus objects to keep them
  *                          alive. No items may be added to list in case host
  *                          system is powered off and no CPUs are accessible.
+ * @param[in,out]   ioc     ASIO context.
  * @param[in,out]   conn    D-Bus ASIO connection.
  *
  * @return  Whether discovery was successfully finished.
@@ -766,7 +386,7 @@
                            boost::asio::io_context& ioc,
                            sdbusplus::asio::connection& conn)
 {
-    for (int i = MIN_CLIENT_ADDR; i <= MAX_CLIENT_ADDR; ++i)
+    for (uint8_t i = MIN_CLIENT_ADDR; i <= MAX_CLIENT_ADDR; ++i)
     {
         // Let the event handler run any waiting tasks. If there is a lot of
         // PECI contention, SST discovery could take a long time. This lets us
@@ -778,6 +398,9 @@
             return false;
         }
 
+        unsigned int cpuIndex = i - MIN_CLIENT_ADDR;
+        DEBUG_PRINT << "Discovering CPU " << cpuIndex << '\n';
+
         // We could possibly check D-Bus for CPU presence and model, but PECI is
         // 10x faster and so much simpler.
         uint8_t cc, stepping;
@@ -789,32 +412,37 @@
             // working yet. Try again later.
             throw PECIError("Get CPUID timed out");
         }
-        if (status != PECI_CC_SUCCESS || cc != PECI_DEV_CC_SUCCESS ||
-            !modelSupportsDiscovery(cpuModel))
+        if (status == PECI_CC_CPU_NOT_PRESENT)
         {
             continue;
         }
-
-        PECIManager peciManager(i, cpuModel);
-
-        // Continue if processor does not support SST-PP
-        GetLevelsInfo getLevelsInfo(peciManager);
-        if (!getLevelsInfo.enabled())
+        if (status != PECI_CC_SUCCESS || cc != PECI_DEV_CC_SUCCESS)
         {
+            std::cerr << "GetCPUID returned status " << status
+                      << ", cc = " << cc << '\n';
             continue;
         }
 
-        // Generate D-Bus object path for this processor.
-        int cpuIndex = i - MIN_CLIENT_ADDR;
+        std::unique_ptr<SSTInterface> sst = getInstance(i, cpuModel);
 
-        // Read the Turbo Ratio Limit Cores MSR which is used to generate the
-        // Turbo Profile for each profile. This is a package scope MSR, so just
-        // read thread 0.
-        uint64_t trlCores;
-        status = peci_RdIAMSR(i, 0, 0x1AE, &trlCores, &cc);
-        if (!checkPECIStatus(status, cc))
+        if (!sst)
         {
-            throw PECIError("Failed to read TRL MSR");
+            // No supported backend for this CPU.
+            continue;
+        }
+
+        if (!sst->ready())
+        {
+            // Supported CPU but it can't be queried yet. Try again later.
+            std::cerr << "sst not ready yet\n";
+            return false;
+        }
+
+        if (!sst->ppEnabled())
+        {
+            // Supported CPU but the specific SKU doesn't support SST-PP.
+            std::cerr << "CPU doesn't support SST-PP\n";
+            continue;
         }
 
         // Create the per-CPU configuration object
@@ -824,23 +452,19 @@
 
         bool foundCurrentLevel = false;
 
-        for (int level = 0; level <= getLevelsInfo.configTdpLevels(); ++level)
+        for (unsigned int level = 0; level <= sst->numLevels(); ++level)
         {
-            // levels 1 and 2 are legacy/deprecated, originally used for AVX
+            // levels 1 and 2 were legacy/deprecated, originally used for AVX
             // license pre-granting. They may be reused for more levels in
-            // future generations.
-            // We can check if they are supported by running any command for
-            // this level and checking the mailbox return status.
-            GetConfigTdpControl tdpControl(
-                peciManager, GetConfigTdpControl::ErrorPolicy::NoThrow, level);
-            if (!tdpControl.success())
+            // future generations. So we need to check for discontinuities.
+            if (!sst->levelSupported(level))
             {
                 continue;
             }
 
-            getSingleConfig(peciManager, level, cpu.newConfig(level), trlCores);
+            getSingleConfig(*sst, level, cpu.newConfig(level));
 
-            if (level == getLevelsInfo.currentConfigTdpLevel())
+            if (level == sst->currentLevel())
             {
                 foundCurrentLevel = true;
             }
@@ -883,7 +507,7 @@
 
         // In case of repeated failure to finish discovery, turn off this
         // feature altogether. Possible cause is that the CPU model does not
-        // actually support the necessary mailbox commands.
+        // actually support the necessary commands.
         if (++peciErrorCount >= 50)
         {
             std::cerr << "Aborting SST discovery\n";
diff --git a/src/sst_mailbox.cpp b/src/sst_mailbox.cpp
new file mode 100644
index 0000000..bd929d4
--- /dev/null
+++ b/src/sst_mailbox.cpp
@@ -0,0 +1,580 @@
+// Copyright (c) 2022 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "cpuinfo_utils.hpp"
+#include "speed_select.hpp"
+
+#include <iostream>
+
+namespace cpu_info
+{
+namespace sst
+{
+
+/**
+ * Convenience RAII object for Wake-On-PECI (WOP) management, since PECI Config
+ * Local accesses to the OS Mailbox require the package to pop up to PC2. Also
+ * provides PCode OS Mailbox routine.
+ *
+ * Since multiple applications may be modifing WOP, we'll use this algorithm:
+ * Whenever a PECI command fails with associated error code, set WOP bit and
+ * retry command. Upon manager destruction, clear WOP bit only if we previously
+ * set it.
+ */
+struct PECIManager
+{
+    uint8_t peciAddress;
+    bool peciWoken;
+    CPUModel cpuModel;
+    uint8_t mbBus;
+
+    PECIManager(uint8_t address, CPUModel model) :
+        peciAddress(address), peciWoken(false), cpuModel(model)
+    {
+        mbBus = (model == icx) ? mbBusICX : mbBusOther;
+    }
+
+    ~PECIManager()
+    {
+        // If we're being destroyed due to a PECIError, try to clear the mode
+        // bit, but catch and ignore any duplicate error it might raise to
+        // prevent termination.
+        try
+        {
+            if (peciWoken)
+            {
+                setWakeOnPECI(false);
+            }
+        }
+        catch (const PECIError& err)
+        {}
+    }
+
+    static bool isSleeping(EPECIStatus libStatus, uint8_t completionCode)
+    {
+        // PECI completion code defined in peci-ioctl.h which is not available
+        // for us to include.
+        constexpr int PECI_DEV_CC_UNAVAIL_RESOURCE = 0x82;
+        // Observed library returning DRIVER_ERR for reads and TIMEOUT for
+        // writes while PECI is sleeping. Either way, the completion code from
+        // PECI client should be reliable indicator of need to set WOP.
+        return libStatus != PECI_CC_SUCCESS &&
+               completionCode == PECI_DEV_CC_UNAVAIL_RESOURCE;
+    }
+
+    /**
+     * Send a single PECI PCS write to modify the Wake-On-PECI mode bit
+     */
+    void setWakeOnPECI(bool enable)
+    {
+        uint8_t completionCode;
+        EPECIStatus libStatus =
+            peci_WrPkgConfig(peciAddress, 5, enable ? 1 : 0, 0,
+                             sizeof(uint32_t), &completionCode);
+        if (!checkPECIStatus(libStatus, completionCode))
+        {
+            throw PECIError("Failed to set Wake-On-PECI mode bit");
+        }
+
+        if (enable)
+        {
+            peciWoken = true;
+        }
+    }
+
+    // PCode OS Mailbox interface register locations
+    static constexpr int mbBusICX = 14;
+    static constexpr int mbBusOther = 31;
+    static constexpr int mbSegment = 0;
+    static constexpr int mbDevice = 30;
+    static constexpr int mbFunction = 1;
+    static constexpr int mbDataReg = 0xA0;
+    static constexpr int mbInterfaceReg = 0xA4;
+    static constexpr int mbRegSize = sizeof(uint32_t);
+
+    enum class MailboxStatus
+    {
+        NoError = 0x0,
+        InvalidCommand = 0x1,
+        IllegalData = 0x16
+    };
+
+    /**
+     * Send a single Write PCI Config Local command, targeting the PCU CR1
+     * register block.
+     *
+     * @param[in]   regAddress  PCI Offset of register.
+     * @param[in]   data        Data to write.
+     */
+    void wrMailboxReg(uint16_t regAddress, uint32_t data)
+    {
+        uint8_t completionCode;
+        bool tryWaking = true;
+        while (true)
+        {
+            EPECIStatus libStatus = peci_WrEndPointPCIConfigLocal(
+                peciAddress, mbSegment, mbBus, mbDevice, mbFunction, regAddress,
+                mbRegSize, data, &completionCode);
+            if (tryWaking && isSleeping(libStatus, completionCode))
+            {
+                setWakeOnPECI(true);
+                tryWaking = false;
+                continue;
+            }
+            else if (!checkPECIStatus(libStatus, completionCode))
+            {
+                throw PECIError("Failed to write mailbox reg");
+            }
+            break;
+        }
+    }
+
+    /**
+     * Send a single Read PCI Config Local command, targeting the PCU CR1
+     * register block.
+     *
+     * @param[in]   regAddress  PCI offset of register.
+     *
+     * @return  Register value
+     */
+    uint32_t rdMailboxReg(uint16_t regAddress)
+    {
+        uint8_t completionCode;
+        uint32_t outputData;
+        bool tryWaking = true;
+        while (true)
+        {
+            EPECIStatus libStatus = peci_RdEndPointConfigPciLocal(
+                peciAddress, mbSegment, mbBus, mbDevice, mbFunction, regAddress,
+                mbRegSize, reinterpret_cast<uint8_t*>(&outputData),
+                &completionCode);
+            if (tryWaking && isSleeping(libStatus, completionCode))
+            {
+                setWakeOnPECI(true);
+                tryWaking = false;
+                continue;
+            }
+            if (!checkPECIStatus(libStatus, completionCode))
+            {
+                throw PECIError("Failed to read mailbox reg");
+            }
+            break;
+        }
+        return outputData;
+    }
+
+    /**
+     * Send command on PCode OS Mailbox interface.
+     *
+     * @param[in]   command     Main command ID.
+     * @param[in]   subCommand  Sub command ID.
+     * @param[in]   inputData   Data to put in mailbox. Is always written, but
+     *                          will be ignored by PCode if command is a
+     *                          "getter".
+     * @param[out]  responseCode    Optional parameter to receive the
+     *                              mailbox-level response status. If null, a
+     *                              PECIError will be thrown for error status.
+     *
+     * @return  Data returned in mailbox. Value is undefined if command is a
+     *          "setter".
+     */
+    uint32_t sendPECIOSMailboxCmd(uint8_t command, uint8_t subCommand,
+                                  uint32_t inputData = 0,
+                                  MailboxStatus* responseCode = nullptr)
+    {
+        // The simple mailbox algorithm just says to wait until the busy bit
+        // is clear, but we'll give up after 10 tries. It's arbitrary but that's
+        // quite long wall clock time.
+        constexpr int mbRetries = 10;
+        constexpr uint32_t mbBusyBit = bit(31);
+
+        // Wait until RUN_BUSY == 0
+        int attempts = mbRetries;
+        while ((rdMailboxReg(mbInterfaceReg) & mbBusyBit) != 0 &&
+               --attempts > 0)
+            ;
+        if (attempts == 0)
+        {
+            throw PECIError("OS Mailbox failed to become free");
+        }
+
+        // Write required command specific input data to data register
+        wrMailboxReg(mbDataReg, inputData);
+
+        // Write required command specific command/sub-command values and set
+        // RUN_BUSY bit in interface register.
+        uint32_t interfaceReg =
+            mbBusyBit | (static_cast<uint32_t>(subCommand) << 8) | command;
+        wrMailboxReg(mbInterfaceReg, interfaceReg);
+
+        // Wait until RUN_BUSY == 0
+        attempts = mbRetries;
+        do
+        {
+            interfaceReg = rdMailboxReg(mbInterfaceReg);
+        } while ((interfaceReg & mbBusyBit) != 0 && --attempts > 0);
+        if (attempts == 0)
+        {
+            throw PECIError("OS Mailbox failed to return");
+        }
+
+        // Read command return status or error code from interface register
+        auto status = static_cast<MailboxStatus>(interfaceReg & 0xFF);
+        if (responseCode != nullptr)
+        {
+            *responseCode = status;
+        }
+        else if (status != MailboxStatus::NoError)
+        {
+            throw PECIError(std::string("OS Mailbox returned with error: ") +
+                            std::to_string(static_cast<int>(status)));
+        }
+
+        // Read command return data from the data register
+        return rdMailboxReg(mbDataReg);
+    }
+};
+
+/**
+ * Base class for set of PECI OS Mailbox commands.
+ * Constructing it runs the command and stores the value for use by derived
+ * class accessor methods.
+ */
+template <uint8_t subcommand>
+struct OsMailboxCommand
+{
+    enum ErrorPolicy
+    {
+        Throw,
+        NoThrow
+    };
+
+    uint32_t value;
+    PECIManager::MailboxStatus status;
+    /**
+     * Construct the command object with required PECI address and up to 4
+     * optional 1-byte input data parameters.
+     */
+    OsMailboxCommand(PECIManager& pm, uint8_t param1 = 0, uint8_t param2 = 0,
+                     uint8_t param3 = 0, uint8_t param4 = 0) :
+        OsMailboxCommand(pm, ErrorPolicy::Throw, param1, param2, param3, param4)
+    {}
+
+    OsMailboxCommand(PECIManager& pm, ErrorPolicy errorPolicy,
+                     uint8_t param1 = 0, uint8_t param2 = 0, uint8_t param3 = 0,
+                     uint8_t param4 = 0)
+    {
+        DEBUG_PRINT << "Running OS Mailbox command "
+                    << static_cast<int>(subcommand) << '\n';
+        PECIManager::MailboxStatus* callStatus =
+            errorPolicy == Throw ? nullptr : &status;
+        uint32_t param = (static_cast<uint32_t>(param4) << 24) |
+                         (static_cast<uint32_t>(param3) << 16) |
+                         (static_cast<uint32_t>(param2) << 8) | param1;
+        value = pm.sendPECIOSMailboxCmd(0x7F, subcommand, param, callStatus);
+    }
+
+    /** Return whether the mailbox status indicated success or not. */
+    bool success() const
+    {
+        return status == PECIManager::MailboxStatus::NoError;
+    }
+};
+
+/**
+ * Macro to define a derived class accessor method.
+ *
+ * @param[in]   type    Return type of accessor method.
+ * @param[in]   name    Name of accessor method.
+ * @param[in]   hibit   Most significant bit of field to access.
+ * @param[in]   lobit   Least significant bit of field to access.
+ */
+#define FIELD(type, name, hibit, lobit)                                        \
+    type name() const                                                          \
+    {                                                                          \
+        return (value >> lobit) & (bit(hibit - lobit + 1) - 1);                \
+    }
+
+struct GetLevelsInfo : OsMailboxCommand<0x0>
+{
+    using OsMailboxCommand::OsMailboxCommand;
+    FIELD(bool, enabled, 31, 31)
+    FIELD(bool, lock, 24, 24)
+    FIELD(unsigned, currentConfigTdpLevel, 23, 16)
+    FIELD(unsigned, configTdpLevels, 15, 8)
+    FIELD(unsigned, version, 7, 0)
+};
+
+struct GetConfigTdpControl : OsMailboxCommand<0x1>
+{
+    using OsMailboxCommand::OsMailboxCommand;
+    FIELD(bool, pbfEnabled, 17, 17);
+    FIELD(bool, factEnabled, 16, 16);
+    FIELD(bool, pbfSupport, 1, 1);
+    FIELD(bool, factSupport, 0, 0);
+};
+
+struct SetConfigTdpControl : OsMailboxCommand<0x2>
+{
+    using OsMailboxCommand::OsMailboxCommand;
+};
+
+struct GetTdpInfo : OsMailboxCommand<0x3>
+{
+    using OsMailboxCommand::OsMailboxCommand;
+    FIELD(unsigned, tdpRatio, 23, 16);
+    FIELD(unsigned, pkgTdp, 14, 0);
+};
+
+struct GetCoreMask : OsMailboxCommand<0x6>
+{
+    using OsMailboxCommand::OsMailboxCommand;
+    FIELD(uint32_t, coresMask, 31, 0);
+};
+
+struct GetTurboLimitRatios : OsMailboxCommand<0x7>
+{
+    using OsMailboxCommand::OsMailboxCommand;
+};
+
+struct SetLevel : OsMailboxCommand<0x8>
+{
+    using OsMailboxCommand::OsMailboxCommand;
+};
+
+struct GetRatioInfo : OsMailboxCommand<0xC>
+{
+    using OsMailboxCommand::OsMailboxCommand;
+    FIELD(unsigned, pm, 31, 24);
+    FIELD(unsigned, pn, 23, 16);
+    FIELD(unsigned, p1, 15, 8);
+    FIELD(unsigned, p0, 7, 0);
+};
+
+struct GetTjmaxInfo : OsMailboxCommand<0x5>
+{
+    using OsMailboxCommand::OsMailboxCommand;
+    FIELD(unsigned, tProchot, 7, 0);
+};
+
+struct PbfGetCoreMaskInfo : OsMailboxCommand<0x20>
+{
+    using OsMailboxCommand::OsMailboxCommand;
+    FIELD(uint32_t, p1HiCoreMask, 31, 0);
+};
+
+struct PbfGetP1HiP1LoInfo : OsMailboxCommand<0x21>
+{
+    using OsMailboxCommand::OsMailboxCommand;
+    FIELD(unsigned, p1Hi, 15, 8);
+    FIELD(unsigned, p1Lo, 7, 0);
+};
+
+/**
+ * Implementation of SSTInterface based on OS Mailbox interface supported on ICX
+ * and SPR processors.
+ * It's expected that an instance of this class will be created for each
+ * "atomic" set of operations.
+ */
+class SSTMailbox : public SSTInterface
+{
+  private:
+    uint8_t address;
+    CPUModel model;
+    PECIManager pm;
+
+    static constexpr int mhzPerRatio = 100;
+
+  public:
+    SSTMailbox(uint8_t _address, CPUModel _model) :
+        address(_address), model(_model),
+        pm(static_cast<uint8_t>(address), model)
+    {}
+    ~SSTMailbox()
+    {}
+
+    bool ready() override
+    {
+        return true;
+    }
+
+    bool supportsControl() override
+    {
+        return model == spr;
+    }
+
+    unsigned int currentLevel() override
+    {
+        return GetLevelsInfo(pm).currentConfigTdpLevel();
+    }
+    unsigned int numLevels() override
+    {
+        return GetLevelsInfo(pm).configTdpLevels();
+    }
+    bool ppEnabled() override
+    {
+        return GetLevelsInfo(pm).enabled();
+    }
+
+    bool levelSupported(unsigned int level) override
+    {
+        GetConfigTdpControl tdpControl(
+            pm, GetConfigTdpControl::ErrorPolicy::NoThrow,
+            static_cast<uint8_t>(level));
+        return tdpControl.success();
+    }
+    bool bfSupported(unsigned int level) override
+    {
+        return GetConfigTdpControl(pm, static_cast<uint8_t>(level))
+            .pbfSupport();
+    }
+    bool tfSupported(unsigned int level) override
+    {
+        return GetConfigTdpControl(pm, static_cast<uint8_t>(level))
+            .factSupport();
+    }
+    bool bfEnabled(unsigned int level) override
+    {
+        return GetConfigTdpControl(pm, static_cast<uint8_t>(level))
+            .pbfEnabled();
+    }
+    bool tfEnabled(unsigned int level) override
+    {
+        return GetConfigTdpControl(pm, static_cast<uint8_t>(level))
+            .factEnabled();
+    }
+    unsigned int tdp(unsigned int level) override
+    {
+        return GetTdpInfo(pm, static_cast<uint8_t>(level)).pkgTdp();
+    }
+    unsigned int coreCount(unsigned int level) override
+    {
+        return enabledCoreList(level).size();
+    }
+    std::vector<unsigned int> enabledCoreList(unsigned int level) override
+    {
+        uint64_t coreMaskLo =
+            GetCoreMask(pm, static_cast<uint8_t>(level), 0).coresMask();
+        uint64_t coreMaskHi =
+            GetCoreMask(pm, static_cast<uint8_t>(level), 1).coresMask();
+        std::bitset<64> coreMask = (coreMaskHi << 32 | coreMaskLo);
+        return convertMaskToList(coreMask);
+    }
+    std::vector<TurboEntry> sseTurboProfile(unsigned int level) override
+    {
+        // Read the Turbo Ratio Limit Cores MSR which is used to generate the
+        // Turbo Profile for each profile. This is a package scope MSR, so just
+        // read thread 0.
+        uint64_t trlCores;
+        uint8_t cc;
+        EPECIStatus status = peci_RdIAMSR(static_cast<uint8_t>(address), 0,
+                                          0x1AE, &trlCores, &cc);
+        if (!checkPECIStatus(status, cc))
+        {
+            throw PECIError("Failed to read TRL MSR");
+        }
+
+        std::vector<TurboEntry> turboSpeeds;
+        uint64_t limitRatioLo =
+            GetTurboLimitRatios(pm, static_cast<uint8_t>(level), 0, 0).value;
+        uint64_t limitRatioHi =
+            GetTurboLimitRatios(pm, static_cast<uint8_t>(level), 1, 0).value;
+        uint64_t limitRatios = (limitRatioHi << 32) | limitRatioLo;
+
+        constexpr int maxTFBuckets = 8;
+        for (int i = 0; i < maxTFBuckets; ++i)
+        {
+            size_t bucketCount = trlCores & 0xFF;
+            int bucketSpeed = limitRatios & 0xFF;
+            if (bucketCount != 0 && bucketSpeed != 0)
+            {
+                turboSpeeds.push_back({bucketSpeed * mhzPerRatio, bucketCount});
+            }
+
+            trlCores >>= 8;
+            limitRatios >>= 8;
+        }
+        return turboSpeeds;
+    }
+    unsigned int p1Freq(unsigned int level) override
+    {
+        return GetRatioInfo(pm, static_cast<uint8_t>(level)).p1() * mhzPerRatio;
+    }
+    unsigned int p0Freq(unsigned int level) override
+    {
+        return GetRatioInfo(pm, static_cast<uint8_t>(level)).p0() * mhzPerRatio;
+    }
+    unsigned int prochotTemp(unsigned int level) override
+    {
+        return GetTjmaxInfo(pm, static_cast<uint8_t>(level)).tProchot();
+    }
+    std::vector<unsigned int>
+        bfHighPriorityCoreList(unsigned int level) override
+    {
+        uint64_t coreMaskLo =
+            PbfGetCoreMaskInfo(pm, static_cast<uint8_t>(level), 0)
+                .p1HiCoreMask();
+        uint64_t coreMaskHi =
+            PbfGetCoreMaskInfo(pm, static_cast<uint8_t>(level), 1)
+                .p1HiCoreMask();
+        std::bitset<64> hiFreqCoreList = (coreMaskHi << 32) | coreMaskLo;
+        return convertMaskToList(hiFreqCoreList);
+    }
+    unsigned int bfHighPriorityFreq(unsigned int level) override
+    {
+        return PbfGetP1HiP1LoInfo(pm, static_cast<uint8_t>(level)).p1Hi() *
+               mhzPerRatio;
+    }
+    unsigned int bfLowPriorityFreq(unsigned int level) override
+    {
+        return PbfGetP1HiP1LoInfo(pm, static_cast<uint8_t>(level)).p1Lo() *
+               mhzPerRatio;
+    }
+
+    void setBfEnabled(bool enable) override
+    {
+        GetConfigTdpControl getTDPControl(pm);
+        bool tfEnabled = false;
+        uint8_t param = (enable ? bit(1) : 0) | (tfEnabled ? bit(0) : 0);
+        SetConfigTdpControl(pm, 0, 0, param);
+    }
+    void setTfEnabled(bool enable) override
+    {
+        // TODO: use cached BF value
+        bool bfEnabled = false;
+        uint8_t param = (bfEnabled ? bit(1) : 0) | (enable ? bit(0) : 0);
+        SetConfigTdpControl(pm, 0, 0, param);
+    }
+    void setCurrentLevel(unsigned int level) override
+    {
+        SetLevel(pm, static_cast<uint8_t>(level));
+    }
+};
+
+static std::unique_ptr<SSTInterface> createMailbox(uint8_t address,
+                                                   CPUModel model)
+{
+    DEBUG_PRINT << "createMailbox\n";
+    if (model == icx || model == icxd || model == spr)
+    {
+        return std::make_unique<SSTMailbox>(address, model);
+    }
+
+    return nullptr;
+}
+
+SSTProviderRegistration(createMailbox);
+
+} // namespace sst
+} // namespace cpu_info
