summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0001-Add-check-for-min-max-received-from-hwmon-files.patch108
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0002-Fix-PECI-client-creation-flow.patch159
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0003-Fix-missing-threshold-de-assert-event-when-threshold.patch143
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0004-Fan-Tach-Sensor-Threshold-Ignore-Zero.patch54
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0005-Fix-PECI-ioctl-number.patch29
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0006-CPUSensor-create-RequirediTempSensor-if-defined.patch233
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0007-Add-support-for-the-energy-hwmon-type.patch266
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0008-CPUSensor-additional-debug-message.patch69
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0009-CPUSensor-Create-CPUConfig-for-each-PECI-adapter.patch147
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/intrusionsensor-depend-on-networkd.conf3
10 files changed, 1211 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0001-Add-check-for-min-max-received-from-hwmon-files.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0001-Add-check-for-min-max-received-from-hwmon-files.patch
new file mode 100644
index 000000000..33d35ec5e
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0001-Add-check-for-min-max-received-from-hwmon-files.patch
@@ -0,0 +1,108 @@
+From 2516d67f8bb5ecd241b8dcdec3f8c58d0e3c4744 Mon Sep 17 00:00:00 2001
+From: Wojciech Dembinski <wojciech.dembinski@intel.com>
+Date: Mon, 7 Dec 2020 19:23:10 +0100
+Subject: [PATCH] Add check for min/max received from hwmon files
+
+When hwmon reports incorrect min/max values or CPU Sensor cannot access
+readings, it shall keep the last known good readings and not update
+DBus with incorrect values.
+This patch adds min < max verification check for the values received
+from hwmon and removes check for power on/off in the case of a read
+failure.
+
+Tested manually on a physical platform, test cases cover incorrect
+max/min values and failing access to hwmon files.
+SDR over IPMI can be fully received in the case of error.
+
+Signed-off-by: Wojciech Dembinski <wojciech.dembinski@intel.com>
+Change-Id: Ia061f849b0f434812f822ed1902c8964d4c64b45
+---
+ src/CPUSensor.cpp | 50 ++++++++++++++++++++++++-----------------------
+ 1 file changed, 26 insertions(+), 24 deletions(-)
+
+diff --git a/src/CPUSensor.cpp b/src/CPUSensor.cpp
+index 2356821..01f5eb6 100644
+--- a/src/CPUSensor.cpp
++++ b/src/CPUSensor.cpp
+@@ -1,5 +1,5 @@
+ /*
+-// Copyright (c) 2018 Intel Corporation
++// Copyright (c) 2018-2021 Intel Corporation
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+@@ -146,19 +146,22 @@ void CPUSensor::setupRead(void)
+
+ void CPUSensor::updateMinMaxValues(void)
+ {
++ double newMin = std::numeric_limits<double>::quiet_NaN();
++ double newMax = std::numeric_limits<double>::quiet_NaN();
++
+ const boost::container::flat_map<
+ std::string,
+ std::vector<std::tuple<const char*, std::reference_wrapper<double>,
+- const char*>>>
+- map = {
++ const char*, std::reference_wrapper<double>>>>
++ map = {
++ {
++ "cap",
+ {
+- "cap",
+- {
+- std::make_tuple("cap_max", std::ref(maxValue), "MaxValue"),
+- std::make_tuple("cap_min", std::ref(minValue), "MinValue"),
+- },
++ std::make_tuple("cap_max", std::ref(maxValue), "MaxValue", std::ref(newMax)),
++ std::make_tuple("cap_min", std::ref(minValue), "MinValue", std::ref(newMin)),
+ },
+- };
++ },
++ };
+
+ if (auto fileParts = splitFileName(path))
+ {
+@@ -168,26 +171,25 @@ void CPUSensor::updateMinMaxValues(void)
+ {
+ for (const auto& vectorItem : mapIt->second)
+ {
+- auto& [suffix, oldValue, dbusName] = vectorItem;
++ auto& [suffix, oldValue, dbusName, newValue] = vectorItem;
+ auto attrPath = boost::replace_all_copy(path, fileItem, suffix);
+- if (auto newVal =
+- readFile(attrPath, CPUSensor::sensorScaleFactor))
++
++ if(auto tmp = readFile(attrPath, CPUSensor::sensorScaleFactor))
+ {
+- updateProperty(sensorInterface, oldValue, *newVal,
+- dbusName);
++ newValue.get() = *tmp;
+ }
+ else
+ {
+- if (isPowerOn())
+- {
+- updateProperty(sensorInterface, oldValue, 0, dbusName);
+- }
+- else
+- {
+- updateProperty(sensorInterface, oldValue,
+- std::numeric_limits<double>::quiet_NaN(),
+- dbusName);
+- }
++ newValue.get() = std::numeric_limits<double>::quiet_NaN();
++ }
++ }
++
++ if(std::isfinite(newMin) && std::isfinite(newMax) && (newMin < newMax))
++ {
++ for (const auto& vectorItem : mapIt->second)
++ {
++ auto& [suffix, oldValue, dbusName, newValue] = vectorItem;
++ updateProperty(sensorInterface, oldValue, newValue, dbusName);
+ }
+ }
+ }
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0002-Fix-PECI-client-creation-flow.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0002-Fix-PECI-client-creation-flow.patch
new file mode 100644
index 000000000..cfdc99d66
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0002-Fix-PECI-client-creation-flow.patch
@@ -0,0 +1,159 @@
+From 0a1b2a13f6dbc64b5851ac2b1ca99d57afa78d60 Mon Sep 17 00:00:00 2001
+From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+Date: Wed, 27 Jan 2021 15:52:16 -0800
+Subject: [PATCH] Fix PECI client creation flow
+
+This commit fixes the PECI client creation flow to make it retry
+the creation when the client is not exposed correctly.
+
+Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+---
+ src/CPUSensorMain.cpp | 66 +++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 54 insertions(+), 12 deletions(-)
+
+diff --git a/src/CPUSensorMain.cpp b/src/CPUSensorMain.cpp
+index f304e3f..92c1716 100644
+--- a/src/CPUSensorMain.cpp
++++ b/src/CPUSensorMain.cpp
+@@ -82,6 +82,7 @@ struct CPUConfig
+ };
+
+ static constexpr const char* peciDev = "/dev/peci-";
++static constexpr const char* peciDevPath = "/sys/bus/peci/devices/";
+ static constexpr const unsigned int rankNumMax = 8;
+
+ namespace fs = std::filesystem;
+@@ -167,7 +168,7 @@ bool createSensors(boost::asio::io_service& io,
+ }
+
+ std::vector<fs::path> hwmonNamePaths;
+- if (!findFiles(fs::path(R"(/sys/bus/peci/devices)"),
++ if (!findFiles(fs::path(peciDevPath),
+ R"(peci-\d+/\d+-.+/peci-.+/hwmon/hwmon\d+/name$)",
+ hwmonNamePaths, 6))
+ {
+@@ -403,7 +404,7 @@ bool createSensors(boost::asio::io_service& io,
+ return true;
+ }
+
+-void exportDevice(const CPUConfig& config)
++int exportDevice(const CPUConfig& config)
+ {
+ std::ostringstream hex;
+ hex << std::hex << config.addr;
+@@ -411,9 +412,12 @@ void exportDevice(const CPUConfig& config)
+ std::string busStr = std::to_string(config.bus);
+
+ std::string parameters = "peci-client 0x" + addrHexStr;
+- std::string device = "/sys/bus/peci/devices/peci-" + busStr + "/new_device";
++ std::string devPath = peciDevPath;
++ std::string delDevice = devPath + "peci-" + busStr + "/delete_device";
++ std::string newDevice = devPath + "peci-" + busStr + "/new_device";
++ std::string newClient = devPath + busStr + "-" + addrHexStr + "/driver";
+
+- std::filesystem::path devicePath(device);
++ std::filesystem::path devicePath(newDevice);
+ const std::string& dir = devicePath.parent_path().string();
+ for (const auto& path : std::filesystem::directory_iterator(dir))
+ {
+@@ -431,20 +435,38 @@ void exportDevice(const CPUConfig& config)
+ std::cout << parameters << " on bus " << busStr
+ << " is already exported\n";
+ }
+- return;
++
++ std::ofstream delDeviceFile(delDevice);
++ if (!delDeviceFile.good())
++ {
++ std::cerr << "Error opening " << delDevice << "\n";
++ return -1;
++ }
++ delDeviceFile << parameters;
++ delDeviceFile.close();
++
++ break;
+ }
+ }
+
+- std::ofstream deviceFile(device);
++ std::ofstream deviceFile(newDevice);
+ if (!deviceFile.good())
+ {
+- std::cerr << "Error writing " << device << "\n";
+- return;
++ std::cerr << "Error opening " << newDevice << "\n";
++ return -1;
+ }
+ deviceFile << parameters;
+ deviceFile.close();
+
++ if (!std::filesystem::exists(newClient))
++ {
++ std::cerr << "Error creating " << newClient << "\n";
++ return -1;
++ }
++
+ std::cout << parameters << " on bus " << busStr << " is exported\n";
++
++ return 0;
+ }
+
+ void detectCpu(boost::asio::deadline_timer& pingTimer,
+@@ -460,6 +482,11 @@ void detectCpu(boost::asio::deadline_timer& pingTimer,
+
+ for (CPUConfig& config : cpuConfigs)
+ {
++ if (config.state == State::READY)
++ {
++ continue;
++ }
++
+ std::string peciDevPath = peciDev + std::to_string(config.bus);
+ auto file = open(peciDevPath.c_str(), O_RDWR | O_CLOEXEC);
+ if (file < 0)
+@@ -510,16 +537,29 @@ void detectCpu(boost::asio::deadline_timer& pingTimer,
+ newState = State::OFF;
+ }
+
+- close(file);
+-
+ if (config.state != newState)
+ {
+ if (newState != State::OFF)
+ {
+ if (config.state == State::OFF)
+ {
+- std::cout << config.name << " is detected\n";
+- exportDevice(config);
++ struct peci_rd_pkg_cfg_msg msg;
++ msg.addr = config.addr;
++ msg.index = PECI_MBX_INDEX_CPU_ID;
++ msg.param = 0;
++ msg.rx_len = 4;
++ if (!ioctl(file, PECI_IOC_RD_PKG_CFG, &msg))
++ {
++ std::cout << config.name << " is detected\n";
++ if (exportDevice(config))
++ {
++ newState = State::OFF;
++ }
++ }
++ else
++ {
++ newState = State::OFF;
++ }
+ }
+
+ if (newState == State::ON)
+@@ -542,6 +582,8 @@ void detectCpu(boost::asio::deadline_timer& pingTimer,
+ keepPinging = true;
+ }
+
++ close(file);
++
+ if (debug)
+ {
+ std::cout << config.name << ", state: " << config.state << "\n";
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0003-Fix-missing-threshold-de-assert-event-when-threshold.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0003-Fix-missing-threshold-de-assert-event-when-threshold.patch
new file mode 100644
index 000000000..1cba1095d
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0003-Fix-missing-threshold-de-assert-event-when-threshold.patch
@@ -0,0 +1,143 @@
+From db4353de222b51726c8e3c765cc8f1df4ad67687 Mon Sep 17 00:00:00 2001
+From: Zhikui Ren <zhikui.ren@intel.com>
+Date: Tue, 22 Jun 2021 11:35:12 -0700
+Subject: [PATCH] Fix missing de-assert event when threshold changes
+
+Issue:
+Sensor can be re-constructed when sensor configuration changes
+like a new threshold value. Threshold deassert can be missed
+if the new threshold value fixes the alarm because the
+default state for new threshold interface is de-asserted.
+
+Resolution:
+Add a member variable hadValidSensor that is initialized to false
+for new sensor. When hadValidSensor is false, threshold property changed
+message will be emitted even if threshold property did not change,
+If the previous sensor instance had the threshold raised,
+Phosphor-sel-logger would notice the change and log a de-assert event.
+If the previous sensor instance did not have the threshold raised,
+Phosphor-sel-logger would notice this is not a change and not create
+new SEL log.
+Set hadValidSensor to true when sensor value is updated with a value
+that is not NaN. This is done after threshold property changed message
+is emitted.
+
+Tested:
+1. Change threshold value for a voltage sensor to force a SEL.
+ ipmitool raw 0x04 0x26 0x60 0x1b 0x95 0x6b 0x00 0x99 0xa6 0x00
+
+2. Verify SEL logged threshold assert event as expected
+ ipmitool sel list
+ 1 | Pre-Init |0000007277| Voltage #0x60 | Upper Non-critical going high | Asserted
+
+3. Use ipmitool to change threshold value back to normal
+ ipmitool raw 0x04 0x26 0x60 0x1b 0x95 0x6b 0x00 0xa4 0xa6 0x00
+
+4. Verify SEL logged threshold de-assert event as expected
+ ipmitool sel list
+ 1 | Pre-Init |0000007277| Voltage #0x60 | Upper Non-critical going high | Asserted
+ 2 | Pre-Init |0000007304| Voltage #0x60 | Upper Non-critical going high | Deasserted
+
+Signed-off-by: Zhikui Ren <zhikui.ren@intel.com>
+---
+ include/Thresholds.hpp | 2 +-
+ include/sensor.hpp | 2 ++
+ src/Thresholds.cpp | 20 ++++++++++++++++----
+ 3 files changed, 19 insertions(+), 5 deletions(-)
+
+diff --git a/include/Thresholds.hpp b/include/Thresholds.hpp
+index af63f72..fd507d0 100644
+--- a/include/Thresholds.hpp
++++ b/include/Thresholds.hpp
+@@ -44,7 +44,7 @@ struct Threshold
+
+ void assertThresholds(Sensor* sensor, double assertValue,
+ thresholds::Level level, thresholds::Direction direction,
+- bool assert);
++ bool assert, bool force = false);
+
+ struct TimerUsed
+ {
+diff --git a/include/sensor.hpp b/include/sensor.hpp
+index b98241b..6235674 100644
+--- a/include/sensor.hpp
++++ b/include/sensor.hpp
+@@ -71,6 +71,7 @@ struct Sensor
+ std::shared_ptr<sdbusplus::asio::dbus_interface> operationalInterface;
+ double value = std::numeric_limits<double>::quiet_NaN();
+ double rawValue = std::numeric_limits<double>::quiet_NaN();
++ bool hadValidValue = false;
+ bool overriddenState = false;
+ bool internalSet = false;
+ double hysteresisTrigger;
+@@ -432,6 +433,7 @@ struct Sensor
+ {
+ markFunctional(true);
+ markAvailable(true);
++ hadValidValue = true;
+ }
+ }
+
+diff --git a/src/Thresholds.cpp b/src/Thresholds.cpp
+index 821083a..da0d650 100644
+--- a/src/Thresholds.cpp
++++ b/src/Thresholds.cpp
+@@ -418,10 +418,19 @@ bool checkThresholds(Sensor* sensor)
+ {
+ bool status = true;
+ std::vector<ChangeParam> changes = checkThresholds(sensor, sensor->value);
++
++ // Sensor can be reconstructed when sensor configuration changes
++ // like a new threshold value. Threshold deassert can be missed
++ // if the new threshold value fixes the alarm because
++ // default state for new threshold interface is de-asserted.
++ // force sending assert/de-assert message when a not NaN value is updated
++ // for the first time even when threshold property did not change.
++ bool forceAssert = !sensor->hadValidValue;
+ for (const auto& change : changes)
+ {
+ assertThresholds(sensor, change.assertValue, change.threshold.level,
+- change.threshold.direction, change.asserted);
++ change.threshold.direction, change.asserted,
++ forceAssert);
+ if (change.threshold.level == thresholds::Level::CRITICAL &&
+ change.asserted)
+ {
+@@ -443,6 +452,7 @@ void checkThresholdsPowerDelay(const std::weak_ptr<Sensor>& weakSensor,
+
+ Sensor* sensor = sensorPtr.get();
+ std::vector<ChangeParam> changes = checkThresholds(sensor, sensor->value);
++ bool forceAssert = !sensor->hadValidValue;
+ for (const auto& change : changes)
+ {
+ // When CPU is powered off, some volatges are expected to
+@@ -467,13 +477,13 @@ void checkThresholdsPowerDelay(const std::weak_ptr<Sensor>& weakSensor,
+ }
+ }
+ assertThresholds(sensor, change.assertValue, change.threshold.level,
+- change.threshold.direction, change.asserted);
++ change.threshold.direction, change.asserted, forceAssert);
+ }
+ }
+
+ void assertThresholds(Sensor* sensor, double assertValue,
+ thresholds::Level level, thresholds::Direction direction,
+- bool assert)
++ bool assert, bool force)
+ {
+ std::string property;
+ std::shared_ptr<sdbusplus::asio::dbus_interface> interface;
+@@ -513,7 +523,9 @@ void assertThresholds(Sensor* sensor, double assertValue,
+ return;
+ }
+
+- if (interface->set_property<bool, true>(property, assert))
++ bool propertyChanged =
++ interface->set_property<bool, true>(property, assert);
++ if (force || propertyChanged)
+ {
+ try
+ {
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0004-Fan-Tach-Sensor-Threshold-Ignore-Zero.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0004-Fan-Tach-Sensor-Threshold-Ignore-Zero.patch
new file mode 100644
index 000000000..214fbe888
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0004-Fan-Tach-Sensor-Threshold-Ignore-Zero.patch
@@ -0,0 +1,54 @@
+From 221aaf1431a01fefb5e7df2461a1c691738a50a7 Mon Sep 17 00:00:00 2001
+From: Zhikui Ren <zhikui.ren@intel.com>
+Date: Fri, 19 Feb 2021 12:14:05 -0800
+Subject: [PATCH] Fan Tach Sensor Threshold Ignore Zero
+
+Currently there are systems that have system fans plugged
+into different fan connectors. Fan present detection is
+not supported in most of these systems. Critical low
+threshold is asserted for the non-utilized fans
+resulting in FSC boost all fans.
+
+Skip threshold checking for fan tach reading less or equal
+to zero. This is a temporary WA until a more robust solution
+is available.
+
+Note: with this workaround a completely non-working fan
+will not be detected. FSC will still boost fans due to other
+constraints if the system can't be cooled with the working fans.
+
+Tested:
+No cr event for the missing fans.
+
+Signed-off-by: Zhikui Ren <zhikui.ren@intel.com>
+---
+ src/TachSensor.cpp | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/src/TachSensor.cpp b/src/TachSensor.cpp
+index c375dbf..e85a2a2 100644
+--- a/src/TachSensor.cpp
++++ b/src/TachSensor.cpp
+@@ -186,10 +186,16 @@ void TachSensor::checkThresholds(void)
+ // WA - treat value <= 0 as not present
+ bool status = false;
+
+- if (redundancy && *redundancy)
++ if (value > 0)
+ {
+- (*redundancy)
+- ->update("/xyz/openbmc_project/sensors/fan_tach/" + name, !status);
++ status = thresholds::checkThresholds(this);
++
++ if (redundancy && *redundancy)
++ {
++ (*redundancy)
++ ->update("/xyz/openbmc_project/sensors/fan_tach/" + name,
++ !status);
++ }
+ }
+
+ bool curLed = !status;
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0005-Fix-PECI-ioctl-number.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0005-Fix-PECI-ioctl-number.patch
new file mode 100644
index 000000000..8119f7542
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0005-Fix-PECI-ioctl-number.patch
@@ -0,0 +1,29 @@
+From f85dd776301371892ff5197c1995bf2224dd87ab Mon Sep 17 00:00:00 2001
+From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+Date: Mon, 22 Feb 2021 15:57:20 -0800
+Subject: [PATCH] Fix PECI ioctl number
+
+This commit fixes PECI ioctl number to 0xb8 to avoid conflicts in
+kernel v5.10.
+
+Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+---
+ include/linux/peci-ioctl.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/peci-ioctl.h b/include/linux/peci-ioctl.h
+index e5b4b8bd3275..1f44edf4fc04 100644
+--- a/include/linux/peci-ioctl.h
++++ b/include/linux/peci-ioctl.h
+@@ -601,7 +601,7 @@ struct peci_crashdump_get_frame_msg {
+ __u8 data[16];
+ } __attribute__((__packed__));
+
+-#define PECI_IOC_BASE 0xb7
++#define PECI_IOC_BASE 0xb8
+
+ #define PECI_IOC_XFER \
+ _IOWR(PECI_IOC_BASE, PECI_CMD_XFER, struct peci_xfer_msg)
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0006-CPUSensor-create-RequirediTempSensor-if-defined.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0006-CPUSensor-create-RequirediTempSensor-if-defined.patch
new file mode 100644
index 000000000..2083adfef
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0006-CPUSensor-create-RequirediTempSensor-if-defined.patch
@@ -0,0 +1,233 @@
+From 6ace96be5a7b6763545c1dfc572f8e2790d99d4b Mon Sep 17 00:00:00 2001
+From: Zhikui Ren <zhikui.ren@intel.com>
+Date: Tue, 11 May 2021 11:14:55 -0700
+Subject: [PATCH] CPUSensor: create RequiredTempSensor if defined
+
+When BMC fails to talk to CPU through PECI, no
+CPU sensors are created. Fan speed control only boost
+fan when input sensor is not available. It does not
+have the knowledge of which sensors are expected to
+be present and can't treat "missing" sensor as failed one.
+The failure on PECI goes unnoticed and we can have a thermal
+run away.
+
+Query sensor config for RequiredTempSensor for any present
+CPUs. Create a CPU sensor that is not available.
+This sensor will be replaced by a normal CPU sensor when
+peci detect the CPU and associated hwmon file is discovered.
+
+This is an initial patch that target to address the particular
+failure case. More work will follow to support a more generic
+"Required" sensor config.
+
+Signed-off-by: Zhikui Ren <zhikui.ren@intel.com>
+---
+ include/CPUSensor.hpp | 9 ++++++
+ src/CPUSensor.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++
+ src/CPUSensorMain.cpp | 54 +++++++++++++++++++++++++++++-----
+ 3 files changed, 123 insertions(+), 8 deletions(-)
+
+diff --git a/include/CPUSensor.hpp b/include/CPUSensor.hpp
+index 8b51b76..93b7fcc 100644
+--- a/include/CPUSensor.hpp
++++ b/include/CPUSensor.hpp
+@@ -26,6 +26,15 @@ class CPUSensor : public Sensor
+ std::vector<thresholds::Threshold>&& thresholds,
+ const std::string& configuration, int cpuId, bool show,
+ double dtsOffset);
++
++ // Create a CPUSensor without a path to sensor value
++ CPUSensor(const std::string& objectType,
++ sdbusplus::asio::object_server& objectServer,
++ std::shared_ptr<sdbusplus::asio::connection>& conn,
++ boost::asio::io_service& io, const std::string& sensorName,
++ std::vector<thresholds::Threshold>&& thresholdsIn,
++ const std::string& sensorConfiguration);
++
+ ~CPUSensor() override;
+ static constexpr unsigned int sensorScaleFactor = 1000;
+ static constexpr unsigned int sensorPollMs = 1000;
+diff --git a/src/CPUSensor.cpp b/src/CPUSensor.cpp
+index c330088..3861ade 100644
+--- a/src/CPUSensor.cpp
++++ b/src/CPUSensor.cpp
+@@ -98,6 +98,74 @@ CPUSensor::CPUSensor(const std::string& path, const std::string& objectType,
+ setupRead();
+ }
+
++// Create a dummy "not available" CPUSensor
++// This is used to indicate a missing required sensor for
++// other services like fan control
++CPUSensor::CPUSensor(const std::string& objectType,
++ sdbusplus::asio::object_server& objectServer,
++ std::shared_ptr<sdbusplus::asio::connection>& conn,
++ boost::asio::io_service& io, const std::string& sensorName,
++ std::vector<thresholds::Threshold>&& thresholdsIn,
++ const std::string& sensorConfiguration) :
++ Sensor(escapeName(sensorName), std::move(thresholdsIn), sensorConfiguration,
++ objectType, false, false, 0, 0, conn, PowerState::on),
++ objServer(objectServer), inputDev(io), waitTimer(io),
++ privTcontrol(std::numeric_limits<double>::quiet_NaN()), dtsOffset(0),
++ show(true), pollTime(CPUSensor::sensorPollMs), minMaxReadCounter(0)
++{
++ // assume it is a temperature sensor for now
++ // support for other type can be added later
++ std::string interfacePath =
++ "/xyz/openbmc_project/sensors/temperature/" + name;
++ const char* units = sensor_paths::unitDegreesC;
++ minValue = -128;
++ maxValue = 127;
++
++ sensorInterface = objectServer.add_interface(
++ interfacePath, "xyz.openbmc_project.Sensor.Value");
++
++ sensorInterface->register_property("Unit", units);
++ sensorInterface->register_property("MaxValue", maxValue);
++ sensorInterface->register_property("MinValue", minValue);
++ sensorInterface->register_property(
++ "Value", value, [&](const double& newValue, double& oldValue) {
++ return setSensorValue(newValue, oldValue);
++ });
++ if (!sensorInterface->initialize())
++ {
++ std::cerr << "error initializing value interface\n";
++ }
++
++ if (!availableInterface)
++ {
++ availableInterface = std::make_shared<sdbusplus::asio::dbus_interface>(
++ conn, sensorInterface->get_object_path(), availableInterfaceName);
++ availableInterface->register_property(
++ "Available", false, [this](const bool propIn, bool& old) {
++ if (propIn == old)
++ {
++ return 1;
++ }
++ old = propIn;
++ if (!propIn)
++ {
++ updateValue(std::numeric_limits<double>::quiet_NaN());
++ }
++ return 1;
++ });
++ availableInterface->initialize();
++ }
++ if (!operationalInterface)
++ {
++ operationalInterface =
++ std::make_shared<sdbusplus::asio::dbus_interface>(
++ conn, sensorInterface->get_object_path(),
++ operationalInterfaceName);
++ operationalInterface->register_property("Functional", true);
++ operationalInterface->initialize();
++ }
++}
++
+ CPUSensor::~CPUSensor()
+ {
+ // close the input dev to cancel async operations
+diff --git a/src/CPUSensorMain.cpp b/src/CPUSensorMain.cpp
+index 0d94e4b..1d12fa6 100644
+--- a/src/CPUSensorMain.cpp
++++ b/src/CPUSensorMain.cpp
+@@ -332,10 +332,9 @@ bool createSensors(boost::asio::io_service& io,
+ {
+ if (debug)
+ {
+- std::cout << "Skipped: " << inputPath << ": " << sensorName
+- << " is already created\n";
++ std::cout << "Will be replaced: " << inputPath << ": "
++ << sensorName << " is already created\n";
+ }
+- continue;
+ }
+
+ // check hidden properties
+@@ -636,9 +635,9 @@ void detectCpuAsync(
+ });
+ }
+
+-bool getCpuConfig(const std::shared_ptr<sdbusplus::asio::connection>& systemBus,
++bool getCpuConfig(std::shared_ptr<sdbusplus::asio::connection>& systemBus,
+ boost::container::flat_set<CPUConfig>& cpuConfigs,
+- ManagedObjectType& sensorConfigs,
++ ManagedObjectType& sensorConfigs, boost::asio::io_service& io,
+ sdbusplus::asio::object_server& objectServer)
+ {
+ bool useCache = false;
+@@ -700,6 +699,45 @@ bool getCpuConfig(const std::shared_ptr<sdbusplus::asio::connection>& systemBus,
+ iface->register_property("Present", *present);
+ iface->initialize();
+ inventoryIfaces[name] = std::move(iface);
++ if (*present)
++ {
++ // create required CPU sensors here in unavailable state
++ auto findRequiredTempSensor =
++ config.second.find("RequiredTempSensor");
++ auto findCpuId = config.second.find("CpuID");
++ if (findRequiredTempSensor != config.second.end() &&
++ findCpuId != config.second.end())
++ {
++ std::string label =
++ std::visit(VariantToStringVisitor(),
++ findRequiredTempSensor->second);
++ // for temp sensor hwmon sysfs use input
++ std::string item{"input"};
++ int cpuId =
++ std::visit(VariantToUnsignedIntVisitor(),
++ findCpuId->second);
++ std::string requiredSensorName =
++ createSensorName(label, item, cpuId);
++
++ auto& sensorPtr = gCpuSensors[requiredSensorName];
++ if (sensorPtr == nullptr)
++ {
++ // created a dummy sensor for required sensor,
++ // will be replaced with a real one if it is
++ // detected
++ std::string objectType{};
++ std::vector<thresholds::Threshold>
++ emptyThreshold{};
++ std::string emptyConfig{};
++ sensorPtr = std::make_unique<CPUSensor>(
++ objectType, objectServer, systemBus, io,
++ requiredSensorName,
++ std::move(emptyThreshold), emptyConfig);
++ std::cout << "created required CPU sensor "
++ << requiredSensorName << "\n";
++ }
++ }
++ }
+ }
+
+ auto findBus = config.second.find("Bus");
+@@ -728,7 +766,6 @@ bool getCpuConfig(const std::shared_ptr<sdbusplus::asio::connection>& systemBus,
+ std::cout << "name: " << name << "\n";
+ std::cout << "type: " << type << "\n";
+ }
+-
+ cpuConfigs.emplace(bus, addr, name, State::OFF);
+ }
+ }
+@@ -764,7 +801,8 @@ int main()
+ return; // we're being canceled
+ }
+
+- if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs, objectServer))
++ if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs, io,
++ objectServer))
+ {
+ detectCpuAsync(pingTimer, creationTimer, io, objectServer,
+ systemBus, cpuConfigs, sensorConfigs);
+@@ -792,7 +830,7 @@ int main()
+ return; // we're being canceled
+ }
+
+- if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs,
++ if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs, io,
+ objectServer))
+ {
+ detectCpuAsync(pingTimer, creationTimer, io, objectServer,
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0007-Add-support-for-the-energy-hwmon-type.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0007-Add-support-for-the-energy-hwmon-type.patch
new file mode 100644
index 000000000..daaca7fae
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0007-Add-support-for-the-energy-hwmon-type.patch
@@ -0,0 +1,266 @@
+From 9f5ef2e8d9c34d9d9ddce34d450aaedd5c122b22 Mon Sep 17 00:00:00 2001
+From: Szymon Dompke <szymon.dompke@intel.com>
+Date: Tue, 18 May 2021 05:22:33 +0200
+Subject: [PATCH] Add support for the energy hwmon type
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+With this commit CPUSensors should be able detect hwmon files of type
+‘energy’ described here:
+
+ https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
+
+These files hold a cumulative energy [micro Joule].
+Values read from these type of files will be exposed on dbus as a new
+sensor. An example:
+
+└─/xyz
+ └─/xyz/openbmc_project
+ └─/xyz/openbmc_project/sensors
+ ├─/xyz/openbmc_project/sensors/energy
+ │ └─/xyz/openbmc_project/sensors/energy/Cumulative_Energy_CPU1
+
+The energy counter will have different scale factor and different
+default min/max values than other types of CPU sensors (power/temp).
+
+Tested:
+ Tested on physical machine where the `energy_input` files were present,
+ works as desired no regression detected.
+
+Authored-by: Zbigniew Kurzynski <zbigniew.kurzynski@intel.com>
+Signed-off-by: Szymon Dompke <szymon.dompke@intel.com>
+---
+ include/CPUSensor.hpp | 13 +++++++--
+ src/CPUSensor.cpp | 68 +++++++++++++++----------------------------
+ src/CPUSensorMain.cpp | 30 ++++++++++++++++---
+ 3 files changed, 60 insertions(+), 51 deletions(-)
+
+diff --git a/include/CPUSensor.hpp b/include/CPUSensor.hpp
+index 93b7fcc..76e43dc 100644
+--- a/include/CPUSensor.hpp
++++ b/include/CPUSensor.hpp
+@@ -16,6 +16,15 @@
+ #include <variant>
+ #include <vector>
+
++struct SensorProperties
++{
++ std::string path;
++ std::string units;
++ double max;
++ double min;
++ unsigned int scaleFactor;
++};
++
+ class CPUSensor : public Sensor
+ {
+ public:
+@@ -25,7 +34,7 @@ class CPUSensor : public Sensor
+ boost::asio::io_service& io, const std::string& sensorName,
+ std::vector<thresholds::Threshold>&& thresholds,
+ const std::string& configuration, int cpuId, bool show,
+- double dtsOffset);
++ double dtsOffset, const SensorProperties& sensorProperties);
+
+ // Create a CPUSensor without a path to sensor value
+ CPUSensor(const std::string& objectType,
+@@ -36,7 +45,6 @@ class CPUSensor : public Sensor
+ const std::string& sensorConfiguration);
+
+ ~CPUSensor() override;
+- static constexpr unsigned int sensorScaleFactor = 1000;
+ static constexpr unsigned int sensorPollMs = 1000;
+ static constexpr size_t warnAfterErrorCount = 10;
+ static constexpr const char* labelTcontrol = "Tcontrol";
+@@ -54,6 +62,7 @@ class CPUSensor : public Sensor
+ size_t pollTime;
+ bool loggedInterfaceDown = false;
+ uint8_t minMaxReadCounter;
++ unsigned int scaleFactor;
+ void setupRead(void);
+ void handleResponse(const boost::system::error_code& err);
+ void checkThresholds(void) override;
+diff --git a/src/CPUSensor.cpp b/src/CPUSensor.cpp
+index 3861ade..6737151 100644
+--- a/src/CPUSensor.cpp
++++ b/src/CPUSensor.cpp
+@@ -39,58 +39,37 @@ CPUSensor::CPUSensor(const std::string& path, const std::string& objectType,
+ boost::asio::io_service& io, const std::string& sensorName,
+ std::vector<thresholds::Threshold>&& thresholdsIn,
+ const std::string& sensorConfiguration, int cpuId,
+- bool show, double dtsOffset) :
++ bool show, double dtsOffset,
++ const SensorProperties& sensorProperties) :
+ Sensor(escapeName(sensorName), std::move(thresholdsIn), sensorConfiguration,
+- objectType, false, false, 0, 0, conn, PowerState::on),
++ objectType, false, false, sensorProperties.max, sensorProperties.min,
++ conn, PowerState::on),
+ objServer(objectServer), inputDev(io), waitTimer(io), path(path),
+ privTcontrol(std::numeric_limits<double>::quiet_NaN()),
+ dtsOffset(dtsOffset), show(show), pollTime(CPUSensor::sensorPollMs),
+- minMaxReadCounter(0)
++ minMaxReadCounter(0), scaleFactor(sensorProperties.scaleFactor)
+ {
+ nameTcontrol = labelTcontrol;
+ nameTcontrol += " CPU" + std::to_string(cpuId);
+ if (show)
+ {
+- if (auto fileParts = splitFileName(path))
++ std::string interfacePath = sensorProperties.path + name;
++ sensorInterface = objectServer.add_interface(
++ interfacePath, "xyz.openbmc_project.Sensor.Value");
++ if (thresholds::hasWarningInterface(thresholds))
+ {
+- auto& [type, nr, item] = *fileParts;
+- std::string interfacePath;
+- const char* units;
+- if (type.compare("power") == 0)
+- {
+- interfacePath = "/xyz/openbmc_project/sensors/power/" + name;
+- units = sensor_paths::unitWatts;
+- minValue = 0;
+- maxValue = 511;
+- }
+- else
+- {
+- interfacePath =
+- "/xyz/openbmc_project/sensors/temperature/" + name;
+- units = sensor_paths::unitDegreesC;
+- minValue = -128;
+- maxValue = 127;
+- }
+-
+- sensorInterface = objectServer.add_interface(
+- interfacePath, "xyz.openbmc_project.Sensor.Value");
+- if (thresholds::hasWarningInterface(thresholds))
+- {
+- thresholdInterfaceWarning = objectServer.add_interface(
+- interfacePath,
+- "xyz.openbmc_project.Sensor.Threshold.Warning");
+- }
+- if (thresholds::hasCriticalInterface(thresholds))
+- {
+- thresholdInterfaceCritical = objectServer.add_interface(
+- interfacePath,
+- "xyz.openbmc_project.Sensor.Threshold.Critical");
+- }
+- association = objectServer.add_interface(interfacePath,
+- association::interface);
+-
+- setInitialProperties(conn, units);
++ thresholdInterfaceWarning = objectServer.add_interface(
++ interfacePath, "xyz.openbmc_project.Sensor.Threshold.Warning");
+ }
++ if (thresholds::hasCriticalInterface(thresholds))
++ {
++ thresholdInterfaceCritical = objectServer.add_interface(
++ interfacePath, "xyz.openbmc_project.Sensor.Threshold.Critical");
++ }
++ association =
++ objectServer.add_interface(interfacePath, association::interface);
++
++ setInitialProperties(conn, sensorProperties.units);
+ }
+
+ // call setup always as not all sensors call setInitialProperties
+@@ -248,7 +227,7 @@ void CPUSensor::updateMinMaxValues(void)
+ auto& [suffix, oldValue, dbusName, newValue] = vectorItem;
+ auto attrPath = boost::replace_all_copy(path, fileItem, suffix);
+
+- if(auto tmp = readFile(attrPath, CPUSensor::sensorScaleFactor))
++ if (auto tmp = readFile(attrPath, scaleFactor))
+ {
+ newValue.get() = *tmp;
+ }
+@@ -302,7 +281,7 @@ void CPUSensor::handleResponse(const boost::system::error_code& err)
+ std::getline(responseStream, response);
+ rawValue = std::stod(response);
+ responseStream.clear();
+- double nvalue = rawValue / CPUSensor::sensorScaleFactor;
++ double nvalue = rawValue / scaleFactor;
+
+ if (show)
+ {
+@@ -328,8 +307,7 @@ void CPUSensor::handleResponse(const boost::system::error_code& err)
+ {
+ std::vector<thresholds::Threshold> newThresholds;
+ if (parseThresholdsFromAttr(newThresholds, path,
+- CPUSensor::sensorScaleFactor,
+- dtsOffset))
++ scaleFactor, dtsOffset))
+ {
+ if (!std::equal(thresholds.begin(), thresholds.end(),
+ newThresholds.begin(),
+diff --git a/src/CPUSensorMain.cpp b/src/CPUSensorMain.cpp
+index 1d12fa6..e348aa7 100644
+--- a/src/CPUSensorMain.cpp
++++ b/src/CPUSensorMain.cpp
+@@ -94,6 +94,18 @@ static constexpr auto sensorTypes{std::to_array<const char*>({"XeonCPU"})};
+ static constexpr auto hiddenProps{std::to_array<const char*>(
+ {CPUSensor::labelTcontrol, "Tthrottle", "Tjmax"})};
+
++static const boost::container::flat_map<std::string, SensorProperties>
++ sensorPropertiesMap = {
++ {"power",
++ {"/xyz/openbmc_project/sensors/power/", sensor_paths::unitWatts, 511,
++ 0, 1000}},
++ {"energy",
++ {"/xyz/openbmc_project/sensors/energy/", sensor_paths::unitJoules,
++ std::numeric_limits<uint32_t>::max() / 1000000, 0.0, 1000000}},
++ {"temp",
++ {"/xyz/openbmc_project/sensors/temperature/",
++ sensor_paths::unitDegreesC, 127.0, -128.0, 1000}}};
++
+ void detectCpuAsync(
+ boost::asio::deadline_timer& pingTimer,
+ boost::asio::deadline_timer& creationTimer, boost::asio::io_service& io,
+@@ -296,7 +308,8 @@ bool createSensors(boost::asio::io_service& io,
+
+ auto directory = hwmonNamePath.parent_path();
+ std::vector<fs::path> inputPaths;
+- if (!findFiles(directory, R"((temp|power)\d+_(input|average|cap)$)",
++ if (!findFiles(directory,
++ R"((temp|power|energy)\d+_(input|average|cap)$)",
+ inputPaths, 0))
+ {
+ std::cerr << "No temperature sensors in system\n";
+@@ -364,6 +377,16 @@ bool createSensors(boost::asio::io_service& io,
+ }
+ }
+
++ const auto& it = sensorPropertiesMap.find(type);
++ if (it == sensorPropertiesMap.end())
++ {
++ std::cerr
++ << "Failure getting sensor properties for sensor type: "
++ << type << "\n";
++ continue;
++ }
++ const SensorProperties& prop = it->second;
++
+ std::vector<thresholds::Threshold> sensorThresholds;
+ std::string labelHead = label.substr(0, label.find(' '));
+ parseThresholdsFromConfig(*sensorData, sensorThresholds,
+@@ -371,8 +394,7 @@ bool createSensors(boost::asio::io_service& io,
+ if (sensorThresholds.empty())
+ {
+ if (!parseThresholdsFromAttr(sensorThresholds, inputPathStr,
+- CPUSensor::sensorScaleFactor,
+- dtsOffset))
++ prop.scaleFactor, dtsOffset))
+ {
+ std::cerr << "error populating thresholds for "
+ << sensorName << "\n";
+@@ -384,7 +406,7 @@ bool createSensors(boost::asio::io_service& io,
+ sensorPtr = std::make_unique<CPUSensor>(
+ inputPathStr, sensorType, objectServer, dbusConnection, io,
+ sensorName, std::move(sensorThresholds), *interfacePath, cpuId,
+- show, dtsOffset);
++ show, dtsOffset, prop);
+ createdSensors.insert(sensorName);
+ if (debug)
+ {
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0008-CPUSensor-additional-debug-message.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0008-CPUSensor-additional-debug-message.patch
new file mode 100644
index 000000000..40c8d46bd
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0008-CPUSensor-additional-debug-message.patch
@@ -0,0 +1,69 @@
+From c045d0ace218a8f0c9e9af0b04aed24ec733fc79 Mon Sep 17 00:00:00 2001
+From: Zhikui Ren <zhikui.ren@intel.com>
+Date: Tue, 22 Jun 2021 14:49:44 -0700
+Subject: [PATCH] CPUSensor: additional debug message
+
+Add debug message to capture more information on threshold changes.
+
+Example output - DTS threshold changes when Tcontrol was first read
+ Jan 01 00:06:06 intel-obmc cpusensor[461]: Core_16_CPU1: Tcontrol changed from nan to 92
+ Jan 01 00:06:06 intel-obmc cpusensor[461]: Core_22_CPU1: Tcontrol changed from nan to 92
+ Jan 01 00:06:06 intel-obmc cpusensor[461]: Core_24_CPU1: Tcontrol changed from nan to 92
+ Jan 01 00:06:06 intel-obmc cpusensor[461]: DTS_CPU1: Tcontrol changed from nan to 92
+ Jan 01 00:06:06 intel-obmc cpusensor[461]: Threshold: /sys/bus/peci/devices/peci-0/0-30/peci-cputemp.0/hwmon/hwmon12/temp2_max: 92
+ Jan 01 00:06:06 intel-obmc cpusensor[461]: Threshold: /sys/bus/peci/devices/peci-0/0-30/peci-cputemp.0/hwmon/hwmon12/temp2_crit: 100
+ Jan 01 00:06:06 intel-obmc cpusensor[461]: DTS_CPU1: new threshold value 92
+ Jan 01 00:06:06 intel-obmc cpusensor[461]: DTS_CPU1: new threshold value 100
+
+The above message will be logged when BMC reset or host resets.
+
+Signed-off-by: Zhikui Ren <zhikui.ren@intel.com>
+---
+ src/CPUSensor.cpp | 5 +++++
+ src/Thresholds.cpp | 7 ++-----
+ 2 files changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/src/CPUSensor.cpp b/src/CPUSensor.cpp
+index 0621e04..65acdac 100644
+--- a/src/CPUSensor.cpp
++++ b/src/CPUSensor.cpp
+@@ -300,6 +300,7 @@ void CPUSensor::handleResponse(const boost::system::error_code& err)
+ : std::numeric_limits<double>::quiet_NaN();
+ if (gTcontrol != privTcontrol)
+ {
++ std::cout << name << ": Tcontrol changed from " << privTcontrol << " to " << gTcontrol << "\n";
+ privTcontrol = gTcontrol;
+
+ if (!thresholds.empty())
+@@ -318,6 +319,10 @@ void CPUSensor::handleResponse(const boost::system::error_code& err)
+ thresholds::updateThresholds(this);
+ }
+ }
++ for (auto& threshold : thresholds)
++ {
++ std::cout << name << ": new threshold value " << threshold.value << "\n";
++ }
+ }
+ else
+ {
+diff --git a/src/Thresholds.cpp b/src/Thresholds.cpp
+index 78ded55..283dacf 100644
+--- a/src/Thresholds.cpp
++++ b/src/Thresholds.cpp
+@@ -583,11 +583,8 @@ bool parseThresholdsFromAttr(
+ if (auto val = readFile(attrPath, scaleFactor))
+ {
+ *val += offset;
+- if (debug)
+- {
+- std::cout << "Threshold: " << attrPath << ": " << *val
+- << "\n";
+- }
++ std::cout << "Threshold: " << attrPath << ": " << *val
++ << "\n";
+ thresholdVector.emplace_back(level, direction, *val);
+ }
+ }
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0009-CPUSensor-Create-CPUConfig-for-each-PECI-adapter.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0009-CPUSensor-Create-CPUConfig-for-each-PECI-adapter.patch
new file mode 100644
index 000000000..737ba9128
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0009-CPUSensor-Create-CPUConfig-for-each-PECI-adapter.patch
@@ -0,0 +1,147 @@
+From 262682632ee493d0b6593540cfc902d11286b7c3 Mon Sep 17 00:00:00 2001
+From: Iwona Winiarska <iwona.winiarska@intel.com>
+Date: Tue, 13 Jul 2021 15:16:16 +0200
+Subject: [PATCH] CPUSensor: Create CPUConfig for each PECI adapter
+
+Currently CPUSensor is based on configuration that defines CPUs for the
+specific PECI adapter (usually peci-wire). As a consequence, MFD devices
+are created only for the defined adapter.
+
+Since duplicating static CPU records in configuration file for other
+PECI adapters may be confusing to users, let's add CPUConfig for other
+PECI adapters dynamically by detecting if there is more than one PECI
+adapter driver bound in the system.
+
+Please note, that this change is limited to enabling HWMON driver,
+sensors for all adapters will not be exposed on D-Bus.
+
+Tested:
+No changes if only one PECI interface is available, HWMON drivers
+creation will be based on provided configuration.
+When both peci-aspeed (peci-wire) and peci-mctp are bound in the system,
+HWMON drivers are created for each PECI interface.
+
+Signed-off-by: Iwona Winiarska <iwona.winiarska@intel.com>
+---
+ src/CPUSensorMain.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 90 insertions(+)
+
+diff --git a/src/CPUSensorMain.cpp b/src/CPUSensorMain.cpp
+index 744ca50..6850df7 100644
+--- a/src/CPUSensorMain.cpp
++++ b/src/CPUSensorMain.cpp
+@@ -33,6 +33,7 @@
+ #include <fstream>
+ #include <functional>
+ #include <memory>
++#include <optional>
+ #include <regex>
+ #include <sstream>
+ #include <stdexcept>
+@@ -658,6 +659,91 @@ void detectCpuAsync(
+ });
+ }
+
++std::optional<uint64_t> getPeciDeviceNum(const fs::path& peciAdapterNamePath)
++{
++ fs::path::iterator it = peciAdapterNamePath.begin();
++ std::advance(it, 5); // /sys/bus/peci/devices/peci-xxxx
++ std::string peciDeviceName = *it;
++ auto pos = peciDeviceName.find('-');
++ if (pos == std::string::npos)
++ {
++ std::cerr << "Incorrect PECI device name: " << peciDeviceName << "\n";
++ return std::nullopt;
++ }
++
++ try
++ {
++ return std::stoull(peciDeviceName.substr(pos + 1, 1));
++ }
++ catch (std::logic_error&)
++ {
++ return std::nullopt;
++ }
++}
++
++std::optional<std::string>
++ readPeciAdapterNameFromFile(const fs::path& peciAdapterNamePath)
++{
++ std::ifstream nameFile(peciAdapterNamePath);
++ if (!nameFile.good())
++ {
++ std::cerr << "Cannot read: " << peciAdapterNamePath << "\n";
++ return std::nullopt;
++ }
++
++ std::string peciAdapterName;
++ std::getline(nameFile, peciAdapterName);
++ nameFile.close();
++ if (peciAdapterName.empty())
++ {
++ return std::nullopt;
++ }
++
++ auto pos = peciAdapterName.find('-');
++ peciAdapterName = peciAdapterName.substr(pos + 1);
++
++ return peciAdapterName;
++}
++
++void addConfigsForOtherPeciAdapters(
++ boost::container::flat_set<CPUConfig>& cpuConfigs, uint64_t& bus,
++ uint64_t& addr, std::string& name, const State& state)
++{
++ std::vector<fs::path> peciAdapterNamePaths;
++ if (!findFiles(fs::path(peciDevPath), R"(peci-\d+/name$)",
++ peciAdapterNamePaths, 1))
++ {
++ std::cerr << "No PECI adapters in system\n";
++ return;
++ }
++
++ for (const fs::path& peciAdapterNamePath : peciAdapterNamePaths)
++ {
++ std::optional<uint64_t> peciDeviceNum =
++ getPeciDeviceNum(peciAdapterNamePath);
++ if (!peciDeviceNum || peciDeviceNum == bus)
++ {
++ continue;
++ }
++
++ std::optional<std::string> peciAdapterName =
++ readPeciAdapterNameFromFile(peciAdapterNamePath);
++ if (!peciAdapterName)
++ {
++ continue;
++ }
++
++ // Change result for peci-aspeed
++ if (peciAdapterName->compare("bus") == 0)
++ {
++ peciAdapterName = "wire";
++ }
++
++ cpuConfigs.emplace(*peciDeviceNum, addr, name + "_" + *peciAdapterName,
++ state);
++ }
++}
++
+ bool getCpuConfig(std::shared_ptr<sdbusplus::asio::connection>& systemBus,
+ boost::container::flat_set<CPUConfig>& cpuConfigs,
+ ManagedObjectType& sensorConfigs, boost::asio::io_service& io,
+@@ -789,7 +875,11 @@ bool getCpuConfig(std::shared_ptr<sdbusplus::asio::connection>& systemBus,
+ std::cout << "name: " << name << "\n";
+ std::cout << "type: " << type << "\n";
+ }
++
+ cpuConfigs.emplace(bus, addr, name, State::OFF);
++
++ addConfigsForOtherPeciAdapters(cpuConfigs, bus, addr, name,
++ State::OFF);
+ }
+ }
+ }
+--
+2.31.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/intrusionsensor-depend-on-networkd.conf b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/intrusionsensor-depend-on-networkd.conf
new file mode 100644
index 000000000..6f0fd3ffc
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/intrusionsensor-depend-on-networkd.conf
@@ -0,0 +1,3 @@
+[Unit]
+After=systemd-networkd.service
+Requires=systemd-networkd.service