platform-mc: sensor: Support HardShutdown threshold in pldm sensors
To support UNR in pldm sensors, add fatal_high/fatal_low bit
of PDR, and then the values will update to ThresholdHardShutdown
interface for pldm sensors.
Tested:
- Check the UNR of the pldm sensors
root@bmc:~# mfg-tool sensor-display 2>/dev/null | table-sensor-display
sensor ... units ... UNR
----------------------------------------... -------- ... -------
SENTINEL_DOME_SLOT_1_MB_SSD_BOOT_TEMP_C DegreesC 85
SENTINEL_DOME_SLOT_1_MB_SSD_DATA_TEMP_C DegreesC 85
SENTINEL_DOME_SLOT_1_MB_VR_CPU0_TEMP_C DegreesC 125
SENTINEL_DOME_SLOT_1_MB_VR_CPU1_TEMP_C DegreesC 125
SENTINEL_DOME_SLOT_1_MB_VR_PVDD11_TEMP_C DegreesC 125
SENTINEL_DOME_SLOT_1_MB_VR_PVDDIO_TEMP_C DegreesC 125
Change-Id: If146a6191fc864988218c39f36038abff1f5d772
Signed-off-by: Zoey YJ Chung <zoey.yj.chung.wiwynn@gmail.com>
diff --git a/platform-mc/numeric_sensor.cpp b/platform-mc/numeric_sensor.cpp
index a0d5dbb..e501ed6 100644
--- a/platform-mc/numeric_sensor.cpp
+++ b/platform-mc/numeric_sensor.cpp
@@ -215,10 +215,13 @@
bool hasCriticalThresholds = false;
bool hasWarningThresholds = false;
+ bool hasFatalThresholds = false;
double criticalHigh = std::numeric_limits<double>::quiet_NaN();
double criticalLow = std::numeric_limits<double>::quiet_NaN();
double warningHigh = std::numeric_limits<double>::quiet_NaN();
double warningLow = std::numeric_limits<double>::quiet_NaN();
+ double fatalHigh = std::numeric_limits<double>::quiet_NaN();
+ double fatalLow = std::numeric_limits<double>::quiet_NaN();
if (pdr->supported_thresholds.bits.bit0)
{
@@ -247,6 +250,17 @@
criticalLow =
getRangeFieldValue(pdr->range_field_format, pdr->critical_low);
}
+ if (pdr->supported_thresholds.bits.bit2)
+ {
+ hasFatalThresholds = true;
+ fatalHigh =
+ getRangeFieldValue(pdr->range_field_format, pdr->fatal_high);
+ }
+ if (pdr->supported_thresholds.bits.bit5)
+ {
+ hasFatalThresholds = true;
+ fatalLow = getRangeFieldValue(pdr->range_field_format, pdr->fatal_low);
+ }
resolution = pdr->resolution;
offset = pdr->offset;
@@ -373,6 +387,25 @@
thresholdCriticalIntf->criticalHigh(unitModifier(criticalHigh));
thresholdCriticalIntf->criticalLow(unitModifier(criticalLow));
}
+
+ if (hasFatalThresholds && !useMetricInterface)
+ {
+ try
+ {
+ thresholdHardShutdownIntf =
+ std::make_unique<ThresholdHardShutdownIntf>(bus, path.c_str());
+ }
+ catch (const sdbusplus::exception_t& e)
+ {
+ lg2::error(
+ "Failed to create HardShutdown threshold interface for numeric sensor {PATH} error - {ERROR}",
+ "PATH", path, "ERROR", e);
+ throw sdbusplus::xyz::openbmc_project::Common::Error::
+ InvalidArgument();
+ }
+ thresholdHardShutdownIntf->hardShutdownHigh(unitModifier(fatalHigh));
+ thresholdHardShutdownIntf->hardShutdownLow(unitModifier(fatalLow));
+ }
}
NumericSensor::NumericSensor(
@@ -434,10 +467,13 @@
double minValue = std::numeric_limits<double>::quiet_NaN();
bool hasWarningThresholds = false;
bool hasCriticalThresholds = false;
+ bool hasFatalThresholds = false;
double criticalHigh = std::numeric_limits<double>::quiet_NaN();
double criticalLow = std::numeric_limits<double>::quiet_NaN();
double warningHigh = std::numeric_limits<double>::quiet_NaN();
double warningLow = std::numeric_limits<double>::quiet_NaN();
+ double fatalHigh = std::numeric_limits<double>::quiet_NaN();
+ double fatalLow = std::numeric_limits<double>::quiet_NaN();
if (pdr->range_field_support.bits.bit0)
{
@@ -461,6 +497,16 @@
hasCriticalThresholds = true;
criticalLow = pdr->critical_low;
}
+ if (pdr->range_field_support.bits.bit4)
+ {
+ hasFatalThresholds = true;
+ fatalHigh = pdr->fatal_high;
+ }
+ if (pdr->range_field_support.bits.bit5)
+ {
+ hasFatalThresholds = true;
+ fatalLow = pdr->fatal_low;
+ }
resolution = std::numeric_limits<double>::quiet_NaN();
offset = std::numeric_limits<double>::quiet_NaN();
@@ -584,6 +630,25 @@
thresholdCriticalIntf->criticalHigh(unitModifier(criticalHigh));
thresholdCriticalIntf->criticalLow(unitModifier(criticalLow));
}
+
+ if (hasFatalThresholds && !useMetricInterface)
+ {
+ try
+ {
+ thresholdHardShutdownIntf =
+ std::make_unique<ThresholdHardShutdownIntf>(bus, path.c_str());
+ }
+ catch (const sdbusplus::exception_t& e)
+ {
+ lg2::error(
+ "Failed to create HardShutdown threshold interface for numeric sensor {PATH} error - {ERROR}",
+ "PATH", path, "ERROR", e);
+ throw sdbusplus::xyz::openbmc_project::Common::Error::
+ InvalidArgument();
+ }
+ thresholdHardShutdownIntf->hardShutdownHigh(unitModifier(fatalHigh));
+ thresholdHardShutdownIntf->hardShutdownLow(unitModifier(fatalLow));
+ }
}
double NumericSensor::conversionFormula(double value)
@@ -819,6 +884,50 @@
}
}
}
+
+ if (thresholdHardShutdownIntf &&
+ std::isfinite(thresholdHardShutdownIntf->hardShutdownHigh()))
+ {
+ auto threshold = thresholdHardShutdownIntf->hardShutdownHigh();
+ auto alarm = thresholdHardShutdownIntf->hardShutdownAlarmHigh();
+ auto newAlarm =
+ checkThreshold(alarm, true, value, threshold, hysteresis);
+ if (alarm != newAlarm)
+ {
+ thresholdHardShutdownIntf->hardShutdownAlarmHigh(newAlarm);
+ if (newAlarm)
+ {
+ thresholdHardShutdownIntf->hardShutdownHighAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdHardShutdownIntf->hardShutdownHighAlarmDeasserted(
+ value);
+ }
+ }
+ }
+
+ if (thresholdHardShutdownIntf &&
+ std::isfinite(thresholdHardShutdownIntf->hardShutdownLow()))
+ {
+ auto threshold = thresholdHardShutdownIntf->hardShutdownLow();
+ auto alarm = thresholdHardShutdownIntf->hardShutdownAlarmLow();
+ auto newAlarm =
+ checkThreshold(alarm, false, value, threshold, hysteresis);
+ if (alarm != newAlarm)
+ {
+ thresholdHardShutdownIntf->hardShutdownAlarmLow(newAlarm);
+ if (newAlarm)
+ {
+ thresholdHardShutdownIntf->hardShutdownLowAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdHardShutdownIntf->hardShutdownLowAlarmDeasserted(
+ value);
+ }
+ }
+ }
}
int NumericSensor::triggerThresholdEvent(
diff --git a/platform-mc/numeric_sensor.hpp b/platform-mc/numeric_sensor.hpp
index f085b07..37f4695 100644
--- a/platform-mc/numeric_sensor.hpp
+++ b/platform-mc/numeric_sensor.hpp
@@ -11,6 +11,7 @@
#include <xyz/openbmc_project/Inventory/Source/PLDM/Entity/server.hpp>
#include <xyz/openbmc_project/Metric/Value/server.hpp>
#include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp>
+#include <xyz/openbmc_project/Sensor/Threshold/HardShutdown/server.hpp>
#include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp>
#include <xyz/openbmc_project/Sensor/Value/server.hpp>
#include <xyz/openbmc_project/State/Decorator/Availability/server.hpp>
@@ -36,6 +37,8 @@
sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Warning>;
using ThresholdCriticalIntf = sdbusplus::server::object_t<
sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Critical>;
+using ThresholdHardShutdownIntf = sdbusplus::server::object_t<
+ sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::HardShutdown>;
using OperationalStatusIntf =
sdbusplus::server::object_t<sdbusplus::xyz::openbmc_project::State::
Decorator::server::OperationalStatus>;
@@ -177,6 +180,38 @@
}
};
+ /** @brief Get Upper HardShutdown threshold
+ *
+ * @return double - Upper HardShutdown threshold
+ */
+ double getThresholdUpperHardShutdown()
+ {
+ if (thresholdHardShutdownIntf)
+ {
+ return thresholdHardShutdownIntf->hardShutdownHigh();
+ }
+ else
+ {
+ return std::numeric_limits<double>::quiet_NaN();
+ }
+ };
+
+ /** @brief Get Lower HardShutdown threshold
+ *
+ * @return double - Lower HardShutdown threshold
+ */
+ double getThresholdLowerHardShutdownl()
+ {
+ if (thresholdHardShutdownIntf)
+ {
+ return thresholdHardShutdownIntf->hardShutdownLow();
+ }
+ else
+ {
+ return std::numeric_limits<double>::quiet_NaN();
+ }
+ };
+
/** @brief Check if value is over threshold.
*
* @param[in] eventType - event level in pldm::utils::Level
@@ -243,6 +278,8 @@
std::unique_ptr<ValueIntf> valueIntf = nullptr;
std::unique_ptr<ThresholdWarningIntf> thresholdWarningIntf = nullptr;
std::unique_ptr<ThresholdCriticalIntf> thresholdCriticalIntf = nullptr;
+ std::unique_ptr<ThresholdHardShutdownIntf> thresholdHardShutdownIntf =
+ nullptr;
std::unique_ptr<AvailabilityIntf> availabilityIntf = nullptr;
std::unique_ptr<OperationalStatusIntf> operationalStatusIntf = nullptr;
std::unique_ptr<AssociationDefinitionsInft> associationDefinitionsIntf =