Initial commit
This commit is contained in:
+1
@@ -0,0 +1 @@
|
||||
PATH=$PATH:/usr/local/sbin:/usr/sbin:/sbin
|
||||
@@ -0,0 +1,9 @@
|
||||
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
|
||||
|
||||
SRC_URI += "file://defaut-env.sh"
|
||||
|
||||
|
||||
do_install:append(){
|
||||
install -d ${D}/${sysconfdir}/profile.d/
|
||||
install -m 0755 ${S}/defaut-env.sh ${D}/${sysconfdir}/profile.d/
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
SUMMARY = "factory-reset-reboot"
|
||||
DESCRIPTION = "factory reset reboot delay"
|
||||
|
||||
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
|
||||
|
||||
RDEPENDS:${PN} += "bash"
|
||||
|
||||
PR = "r1"
|
||||
LICENSE = "CLOSED"
|
||||
|
||||
inherit allarch
|
||||
SRC_URI = " \
|
||||
file://obmc-reboot-delay \
|
||||
file://obmc-reboot-delay.service \
|
||||
"
|
||||
|
||||
inherit obmc-phosphor-systemd
|
||||
|
||||
SYSTEMD_SERVICE:${PN} += "obmc-reboot-delay.service"
|
||||
|
||||
do_install() {
|
||||
install -d ${D}${bindir}
|
||||
install -m 0755 ${WORKDIR}/obmc-reboot-delay ${D}${bindir}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
STATE_SERVICE="xyz.openbmc_project.State.BMC"
|
||||
STATE_PATH="/xyz/openbmc_project/state/bmc0"
|
||||
STATE_INTERFACE="xyz.openbmc_project.State.BMC"
|
||||
STATE_PROPERTY="RequestedBMCTransition"
|
||||
STATE_PROPERTY_VALUE="xyz.openbmc_project.State.BMC.Transition.Reboot"
|
||||
|
||||
echo "sleep 5"
|
||||
sleep 5
|
||||
busctl set-property "${STATE_SERVICE}" "${STATE_PATH}" "${STATE_INTERFACE}" \
|
||||
"${STATE_PROPERTY}" s "${STATE_PROPERTY_VALUE}"
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
[Unit]
|
||||
Description=BMC reboot delay
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=true
|
||||
ExecStart=/usr/bin/obmc-reboot-delay
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
IMAGE_INSTALL += " ipmitool \
|
||||
webui-vue \
|
||||
callback-manager \
|
||||
system-watchdog \
|
||||
ipmi-oem \
|
||||
ipmi-standard-override \
|
||||
i3c-tools \
|
||||
factory-reset-reboot \
|
||||
clear-once \
|
||||
"
|
||||
@@ -0,0 +1,23 @@
|
||||
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
|
||||
LICENSE = "CLOSED"
|
||||
SUMMARY = "IPMI OEM Commands"
|
||||
|
||||
TARGET_CC_ARCH += "${LDFLAGS}"
|
||||
|
||||
SRC_URI += " file://ipmi-oem.hpp file://ipmi-oem.cpp file://meson.build "
|
||||
SRCREV = "${AUTOREV}"
|
||||
PR = "r1"
|
||||
S = "${WORKDIR}"
|
||||
DEPENDS = " boost sdbusplus phosphor-ipmi-host phosphor-dbus-interfaces phosphor-logging i2c-tools"
|
||||
RDEPENDS:${PN} += " phosphor-ipmi-host"
|
||||
inherit pkgconfig obmc-phosphor-ipmiprovider-symlink meson
|
||||
|
||||
|
||||
HOSTIPMI_PROVIDER_LIBRARY += "libipmioem.so"
|
||||
|
||||
FILES:${PN}:append = " ${libdir}/host-ipmid/lib*${SOLIBS}"
|
||||
FILES:${PN}:append = " ${libdir}/ipmid-providers/lib*${SOLIBS}"
|
||||
FILES:${PN}:append = " ${libdir}/net-ipmid/lib*${SOLIBS}"
|
||||
FILES:${PN}-dev:append = " ${libdir}/ipmid-providers/lib*${SOLIBSDEV} ${libdir}/ipmid-providers/*.la"
|
||||
|
||||
|
||||
+2058
File diff suppressed because it is too large
Load Diff
+141
@@ -0,0 +1,141 @@
|
||||
#include <ipmid/api-types.hpp>
|
||||
#include <ipmid/api.hpp>
|
||||
#include <ipmid/message.hpp>
|
||||
#include <ipmid/utils.hpp>
|
||||
#include <sdbusplus/message/types.hpp>
|
||||
|
||||
typedef struct {
|
||||
uint8_t socket_id;
|
||||
uint8_t channel_id;
|
||||
uint8_t dimm_id;
|
||||
uint8_t temp_integer;
|
||||
uint8_t temp_decimal;
|
||||
/*Memory temperature infomation(unit °C)*/
|
||||
}memory_info_t;
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
enum class DataType {
|
||||
TEMPERATURE,
|
||||
CURRENT,
|
||||
POWER,
|
||||
VOLTAGE,
|
||||
STATUS
|
||||
};
|
||||
|
||||
enum class TempSensor {
|
||||
TS0,
|
||||
TS1,
|
||||
SPD_TS,
|
||||
MAX_TS01
|
||||
};
|
||||
|
||||
enum class ReqId {
|
||||
TS0 = 0,
|
||||
TS1 = 1,
|
||||
SPD_TEMP = 2,
|
||||
MAX_TEMP = 3,
|
||||
VOLTAGE = 4,
|
||||
CURRENT = 5,
|
||||
STATUS_REG = 6
|
||||
};
|
||||
|
||||
enum class RailChannel {
|
||||
SWA,
|
||||
SWB,
|
||||
SWC,
|
||||
SWD,
|
||||
SWE,
|
||||
SWF
|
||||
};
|
||||
|
||||
enum class StatusReg {
|
||||
REG_04 = 0x04,
|
||||
REG_05 = 0x05,
|
||||
REG_06 = 0x06,
|
||||
REG_07 = 0x07,
|
||||
REG_08 = 0x08,
|
||||
REG_09 = 0x09,
|
||||
REG_0A = 0x0A,
|
||||
REG_0B = 0x0B
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int8_t int_part;
|
||||
uint8_t frac_part;
|
||||
} dimm_temp_sensor_t;
|
||||
typedef struct {
|
||||
int8_t TS0_int;
|
||||
uint8_t TS0_frac;
|
||||
int8_t TS1_int;
|
||||
uint8_t TS1_frac;
|
||||
int8_t SPD_int;
|
||||
uint8_t SPD_frac;
|
||||
} dimm_temp_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t SWA;
|
||||
uint16_t SWB;
|
||||
uint16_t SWC;
|
||||
uint16_t SWD;
|
||||
uint16_t SWE;
|
||||
uint16_t SWF;
|
||||
} dimm_rail_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t dimmId;
|
||||
dimm_temp_t dimmTemp;
|
||||
dimm_rail_t dimmVolt;
|
||||
dimm_rail_t dimmCur;
|
||||
dimm_rail_t dimmPow;
|
||||
} oem_dimm_info_t;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
#define MAX_FSC_PWM_CHANNEL 29
|
||||
#define FSC_FAN_TABLE_AUTO 0
|
||||
#define FSC_FAN_TABLE_MANUAL 1
|
||||
typedef struct
|
||||
{
|
||||
uint8_t u8ControlMode;
|
||||
uint8_t u8PWM[MAX_FSC_PWM_CHANNEL];
|
||||
}SFscControlMode;
|
||||
|
||||
namespace ipmi {
|
||||
constexpr Iana oemIANA =
|
||||
56799; // 0x00dddf https://www.iana.org/assignments/enterprise-numbers/?page=568
|
||||
constexpr int prioOem = ipmi::prioMax;
|
||||
constexpr NetFn netFnOemSelf = ipmi::netFnOemFour; // NetFn is 0x36
|
||||
namespace ipmiOem {
|
||||
|
||||
constexpr Cmd cmdGetDeviceFWVersion = 0x01;
|
||||
constexpr Cmd cmdSetFanSpeedControlMode = 0x04;
|
||||
constexpr Cmd cmdGetFanSpeedControlMode = 0x05;
|
||||
constexpr Cmd cmdSetBIOSPasswordConfig = 0x0E;
|
||||
constexpr Cmd cmdGetBIOSPasswordConfig = 0x0F;
|
||||
constexpr Cmd cmdGetPSUInfo = 0x20;
|
||||
constexpr Cmd cmdSwitchBMCFw = 0x23;
|
||||
constexpr Cmd cmdGetSetBiosVer = 0x34;
|
||||
constexpr Cmd cmdRestoreFactoryDefault = 0x35;
|
||||
constexpr Cmd cmdSetSOLBitrate = 0x36;
|
||||
constexpr Cmd cmdGet12VPSUADCValue = 0x60;
|
||||
constexpr Cmd cmdSet12VPSUADCValue = 0x61;
|
||||
constexpr Cmd cmdDIMMTemperatureValue = 0x62;
|
||||
constexpr Cmd cmdSetDIMMSetPoint = 0x63;
|
||||
constexpr Cmd cmdGetDIMMSetPoint = 0x64;
|
||||
constexpr Cmd cmdSetCoverStatus = 0x65;
|
||||
constexpr Cmd cmdGetCoverStatus = 0x66;
|
||||
constexpr Cmd cmdSetCoverPreHeatTemperature = 0x67;
|
||||
constexpr Cmd cmdGetCoverPreHeatTemperature = 0x68;
|
||||
constexpr Cmd cmdBiosSetDimmState = 0x69;
|
||||
constexpr Cmd cmdBiosSetDimmPara = 0x6a;
|
||||
constexpr Cmd cmdBiosGetDimmPara = 0x6b;
|
||||
constexpr Cmd cmdGetDimmTemp = 0x6c;
|
||||
constexpr Cmd cmdGetCoverCurrentTemp = 0x6d;
|
||||
constexpr Cmd cmdSetCoverFSCEnableStatus = 0x6e;
|
||||
constexpr Cmd cmdGetCoverFSCEnableStatus = 0x6f;
|
||||
constexpr Cmd cmdOemI2CReadWrite = 0xA4;
|
||||
|
||||
constexpr Cc ccOemInvalidIANA = 0x80;
|
||||
} // namespace ipmiOem
|
||||
} // namespace ipmi
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
project(
|
||||
'ipmi-oem',
|
||||
'cpp',
|
||||
version: '0.1',
|
||||
meson_version: '>=1.1.1',
|
||||
default_options: [
|
||||
'werror=true',
|
||||
'warning_level=3',
|
||||
'cpp_std=c++23',
|
||||
])
|
||||
|
||||
root = meson.current_source_dir()
|
||||
root_inc = include_directories('.')
|
||||
cpp = meson.get_compiler('cpp')
|
||||
|
||||
# i2c-tools doesn't ship a pkg-config file for libi2c
|
||||
i2c = cpp.find_library('i2c')
|
||||
|
||||
add_project_arguments(
|
||||
cpp.get_supported_arguments([
|
||||
'-DBOOST_ERROR_CODE_HEADER_ONLY',
|
||||
'-DBOOST_SYSTEM_NO_DEPRECATED',
|
||||
'-DBOOST_COROUTINES_NO_DEPRECATION_WARNING',
|
||||
'-DBOOST_ASIO_DISABLE_THREADS',
|
||||
'-DBOOST_ALL_NO_LIB',
|
||||
]),
|
||||
language : 'cpp')
|
||||
|
||||
add_project_arguments(
|
||||
cpp.get_supported_arguments([
|
||||
'-Wno-psabi',
|
||||
'-Wno-missing-field-initializers',
|
||||
'-Wno-pedantic',
|
||||
'-Wno-non-virtual-dtor'
|
||||
]),
|
||||
language: 'cpp')
|
||||
|
||||
phosphor_logging_dep = dependency('phosphor-logging')
|
||||
phosphor_dbus_interfaces_dep = dependency('phosphor-dbus-interfaces')
|
||||
systemd = dependency('systemd')
|
||||
boost_coroutine = cpp.find_library('boost_coroutine', required: true)
|
||||
sdbusplus_dep = dependency('sdbusplus')
|
||||
ipmid_dep = dependency('libipmid')
|
||||
libs = declare_dependency(
|
||||
include_directories: root_inc,
|
||||
dependencies: [
|
||||
phosphor_dbus_interfaces_dep,
|
||||
phosphor_logging_dep,
|
||||
sdbusplus_dep,
|
||||
ipmid_dep,
|
||||
systemd,
|
||||
i2c
|
||||
])
|
||||
|
||||
ipmi_oem_lib = library(
|
||||
'ipmioem',
|
||||
'ipmi-oem.cpp',
|
||||
implicit_include_directories: false,
|
||||
dependencies: libs,
|
||||
version: meson.project_version(),
|
||||
override_options: ['b_lundef=false'],
|
||||
install: true,
|
||||
install_dir: get_option('libdir') / 'ipmid-providers')
|
||||
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
|
||||
LICENSE = "CLOSED"
|
||||
SUMMARY = "Override Standard IPMI Commands"
|
||||
TARGET_CC_ARCH += "${LDFLAGS}"
|
||||
SRC_URI += " file://ipmi-standard-override.hpp file://ipmi-override-app.cpp file://meson.build "
|
||||
SRCREV = "${AUTOREV}"
|
||||
PR = "r1"
|
||||
S = "${WORKDIR}"
|
||||
DEPENDS = " boost sdbusplus phosphor-ipmi-host "
|
||||
RDEPENDS:${PN} += " phosphor-ipmi-host"
|
||||
inherit pkgconfig obmc-phosphor-ipmiprovider-symlink meson
|
||||
|
||||
HOSTIPMI_PROVIDER_LIBRARY += "libipmioverride.so"
|
||||
|
||||
FILES:${PN}:append = " ${libdir}/host-ipmid/lib*${SOLIBS}"
|
||||
FILES:${PN}:append = " ${libdir}/ipmid-providers/lib*${SOLIBS}"
|
||||
FILES:${PN}:append = " ${libdir}/net-ipmid/lib*${SOLIBS}"
|
||||
FILES:${PN}-dev:append = " ${libdir}/ipmid-providers/lib*${SOLIBSDEV} ${libdir}/ipmid-providers/*.la"
|
||||
meta-luxshare/meta-common/recipes-luxshare/ipmi-lux-oem/ipmi-standard-override/ipmi-override-app.cpp
Executable
+37
@@ -0,0 +1,37 @@
|
||||
#include "ipmi-standard-override.hpp"
|
||||
|
||||
void register_ipmi_override_functions() __attribute__((constructor));
|
||||
|
||||
auto ipmiAppGetSelfTestResultsOverride() -> ipmi::RspType<uint8_t, uint8_t> {
|
||||
// Byte 2:
|
||||
// 55h - No error.
|
||||
// 56h - Self Test function not implemented in this controller.
|
||||
// 57h - Corrupted or inaccesssible data or devices.
|
||||
// 58h - Fatal hardware error.
|
||||
// FFh - reserved.
|
||||
// all other: Device-specific 'internal failure'.
|
||||
// Byte 3:
|
||||
// For byte 2 = 55h, 56h, FFh: 00h
|
||||
// For byte 2 = 58h, all other: Device-specific
|
||||
// For byte 2 = 57h: self-test error bitfield.
|
||||
// Note: returning 57h does not imply that all test were run.
|
||||
// [7] 1b = Cannot access SEL device.
|
||||
// [6] 1b = Cannot access SDR Repository.
|
||||
// [5] 1b = Cannot access BMC FRU device.
|
||||
// [4] 1b = IPMB signal lines do not respond.
|
||||
// [3] 1b = SDR Repository empty.
|
||||
// [2] 1b = Internal Use Area of BMC FRU corrupted.
|
||||
// [1] 1b = controller update 'boot block' firmware corrupted.
|
||||
// [0] 1b = controller operational firmware corrupted.
|
||||
constexpr uint8_t noError = 0x55;
|
||||
constexpr uint8_t bmcOK = 0x55;
|
||||
return ipmi::responseSuccess(noError, bmcOK);
|
||||
}
|
||||
|
||||
void register_ipmi_override_functions() {
|
||||
|
||||
// <Get Self Test Results>
|
||||
ipmi::registerHandler(ipmi::prioOverride, ipmi::netFnApp,
|
||||
ipmi::app::cmdGetSelfTestResults, ipmi::Privilege::User,
|
||||
ipmiAppGetSelfTestResultsOverride);
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
#include <ipmid/api.hpp>
|
||||
#include <ipmid/message.hpp>
|
||||
#include <ipmid/utils.hpp>
|
||||
#include <sdbusplus/message/types.hpp>
|
||||
|
||||
namespace ipmi {
|
||||
constexpr int prioOverride = ipmi::prioMax;
|
||||
namespace ipmiOverride {} // namespace ipmiOverride
|
||||
} // namespace ipmi
|
||||
Executable
+60
@@ -0,0 +1,60 @@
|
||||
project(
|
||||
'ipmi-oem',
|
||||
'cpp',
|
||||
version: '0.1',
|
||||
meson_version: '>=1.1.1',
|
||||
default_options: [
|
||||
'werror=true',
|
||||
'warning_level=3',
|
||||
'cpp_std=c++23',
|
||||
])
|
||||
|
||||
root = meson.current_source_dir()
|
||||
root_inc = include_directories('.')
|
||||
cpp = meson.get_compiler('cpp')
|
||||
add_project_arguments(
|
||||
cpp.get_supported_arguments([
|
||||
'-DBOOST_ERROR_CODE_HEADER_ONLY',
|
||||
'-DBOOST_SYSTEM_NO_DEPRECATED',
|
||||
'-DBOOST_COROUTINES_NO_DEPRECATION_WARNING',
|
||||
'-DBOOST_ASIO_DISABLE_THREADS',
|
||||
'-DBOOST_ALL_NO_LIB',
|
||||
]),
|
||||
language : 'cpp')
|
||||
|
||||
add_project_arguments(
|
||||
cpp.get_supported_arguments([
|
||||
'-Wno-psabi',
|
||||
'-Wno-missing-field-initializers',
|
||||
'-Wno-pedantic',
|
||||
'-Wno-non-virtual-dtor'
|
||||
]),
|
||||
language: 'cpp')
|
||||
|
||||
phosphor_logging_dep = dependency('phosphor-logging')
|
||||
phosphor_dbus_interfaces_dep = dependency('phosphor-dbus-interfaces')
|
||||
systemd = dependency('systemd')
|
||||
boost_coroutine = cpp.find_library('boost_coroutine', required: true)
|
||||
sdbusplus_dep = dependency('sdbusplus')
|
||||
ipmid_dep = dependency('libipmid')
|
||||
libs = declare_dependency(
|
||||
include_directories: root_inc,
|
||||
dependencies: [
|
||||
phosphor_dbus_interfaces_dep,
|
||||
phosphor_logging_dep,
|
||||
sdbusplus_dep,
|
||||
ipmid_dep,
|
||||
systemd
|
||||
])
|
||||
|
||||
ipmi_override_lib = library(
|
||||
'ipmioverride',
|
||||
'ipmi-override-app.cpp',
|
||||
implicit_include_directories: false,
|
||||
dependencies: libs,
|
||||
version: meson.project_version(),
|
||||
override_options: ['b_lundef=false'],
|
||||
install: true,
|
||||
install_dir: get_option('libdir') / 'ipmid-providers')
|
||||
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
From 0852966f5ef9821c291007cfedf7e744d8577215 Mon Sep 17 00:00:00 2001
|
||||
From: hliangs90 <hliangs90@gmail.com>
|
||||
Date: Fri, 23 Aug 2024 21:55:31 +0800
|
||||
Subject: [PATCH] Modify OEM Command to 0x36 to support IANA register
|
||||
|
||||
Signed-off-by: hliangs90 <hliangs90@gmail.com>
|
||||
---
|
||||
ipmid-new.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ipmid-new.cpp b/ipmid-new.cpp
|
||||
index 2a78c68..8f5cd32 100644
|
||||
--- a/ipmid-new.cpp
|
||||
+++ b/ipmid-new.cpp
|
||||
@@ -318,7 +318,7 @@ message::Response::ptr executeIpmiCommand(message::Request::ptr request)
|
||||
{
|
||||
return executeIpmiGroupCommand(request);
|
||||
}
|
||||
- else if (netFnOem == netFn)
|
||||
+ else if (netFnOemFour == netFn || netFn == netFnOem)
|
||||
{
|
||||
return executeIpmiOemCommand(request);
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
From 7305120634cef58af46e98b81418a38a753ffaf5 Mon Sep 17 00:00:00 2001
|
||||
From: hliangs90 <hliangs90@gmail.com>
|
||||
Date: Sat, 24 Aug 2024 02:57:40 +0800
|
||||
Subject: [PATCH] Remove INAN Header In IPMI Response For OEM Command Support
|
||||
|
||||
Signed-off-by: hliangs90 <hliangs90@gmail.com>
|
||||
---
|
||||
ipmid-new.cpp | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/ipmid-new.cpp b/ipmid-new.cpp
|
||||
index 8f5cd32..baa6a19 100644
|
||||
--- a/ipmid-new.cpp
|
||||
+++ b/ipmid-new.cpp
|
||||
@@ -305,9 +305,9 @@ message::Response::ptr executeIpmiOemCommand(message::Request::ptr request)
|
||||
auto iana = static_cast<Iana>(bytes);
|
||||
message::Response::ptr response = executeIpmiCommandCommon(oemHandlerMap,
|
||||
iana, request);
|
||||
- ipmi::message::Payload prefix;
|
||||
- prefix.pack(bytes);
|
||||
- response->prepend(prefix);
|
||||
+ // ipmi::message::Payload prefix;
|
||||
+ // prefix.pack(bytes);
|
||||
+ // response->prepend(prefix);
|
||||
return response;
|
||||
}
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
|
||||
|
||||
SRC_URI += " file://0001-Modify-OEM-Command-to-0x36-to-support-IANA-register.patch \
|
||||
file://0002-Remove-INAN-Header-In-IPMI-Response-For-OEM-Command-.patch "
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
From 573d74d5938907e5c7c110997b1fedac716b0a6c Mon Sep 17 00:00:00 2001
|
||||
From: wangjue <jue.wang2@luxshare-ict.com>
|
||||
Date: Thu, 17 Oct 2024 13:28:54 +0800
|
||||
Subject: [PATCH] Add DIMM Status discrete sensors
|
||||
|
||||
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
|
||||
---
|
||||
fault-monitor/fru-fault-monitor.cpp | 17 +++++++++++------
|
||||
fault-monitor/fru-fault-monitor.hpp | 2 +-
|
||||
2 files changed, 12 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/fault-monitor/fru-fault-monitor.cpp b/fault-monitor/fru-fault-monitor.cpp
|
||||
index d5d6703..8ff5294 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.cpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.cpp
|
||||
@@ -360,7 +360,7 @@ void fillSensorDescription(const std::string& sensorPath, int eventOffset)
|
||||
//}
|
||||
}
|
||||
|
||||
-AlarmType parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
+void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
const std::string& sensorPath,
|
||||
const SensorType& sensorType,
|
||||
const std::string& eventData,
|
||||
@@ -384,7 +384,7 @@ AlarmType parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
}
|
||||
default:
|
||||
{
|
||||
- return alarmStatus;
|
||||
+ return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -405,13 +405,18 @@ AlarmType parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
{
|
||||
alarmStatus = NORMAL;
|
||||
}
|
||||
- return alarmStatus;
|
||||
+ return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
+ case SENSOR_TYPE_MEMORY:
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
+ break;
|
||||
+ }
|
||||
default:
|
||||
- return alarmStatus;
|
||||
+ return;
|
||||
}
|
||||
sensorStatusRec[sensorPath].eventType = SPECIFIC_SENSOR_TYPE;
|
||||
sensorStatusRec[sensorPath].sensorType = sensorType;
|
||||
@@ -420,9 +425,9 @@ AlarmType parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
{
|
||||
fillSensorDescription(sensorPath, ev1Offset);
|
||||
setDiscreteSensorDiscription(bus, sensorPath);
|
||||
- setDiscreteSensorHealth(bus, sensorPath);
|
||||
+ setDiscreteSensorHealth(bus, sensorPath);
|
||||
}
|
||||
- return alarmStatus;
|
||||
+ return;
|
||||
}
|
||||
|
||||
|
||||
diff --git a/fault-monitor/fru-fault-monitor.hpp b/fault-monitor/fru-fault-monitor.hpp
|
||||
index 652fefa..e196287 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.hpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.hpp
|
||||
@@ -34,7 +34,7 @@ enum SensorType
|
||||
{
|
||||
SENSOR_TYPE_EVENT_LOGGING_DISABLED = 0x10,
|
||||
SENSOR_TYPE_SYSTEM_ACPI_POWER_STATE = 0x22,
|
||||
-
|
||||
+ SENSOR_TYPE_MEMORY = 0x0C,
|
||||
SENSOR_TYPE_MAX_NUMBER = 0x100 // Senor Type 为1个byte,最大为0~255,即:256个
|
||||
};
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
From 9560938ad1542c78d977672960bc4e2a90bfb696 Mon Sep 17 00:00:00 2001
|
||||
From: wangjue <jue.wang2@luxshare-ict.com>
|
||||
Date: Thu, 31 Oct 2024 10:59:57 +0800
|
||||
Subject: [PATCH] Add PROCESSOR sensor type
|
||||
|
||||
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
|
||||
|
||||
---
|
||||
fault-monitor/fru-fault-monitor.cpp | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/fault-monitor/fru-fault-monitor.cpp b/fault-monitor/fru-fault-monitor.cpp
|
||||
index 2e99e45..fffb6f7 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.cpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.cpp
|
||||
@@ -678,6 +678,11 @@ void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
setDimmLEDState(bus, sensorPath, "FAULT");
|
||||
break;
|
||||
}
|
||||
+ case SENSOR_TYPE_PROCESSOR:
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
+ break;
|
||||
+ }
|
||||
default:
|
||||
break;
|
||||
}
|
||||
+601
@@ -0,0 +1,601 @@
|
||||
diff --git a/fault-monitor/fru-fault-monitor.cpp b/fault-monitor/fru-fault-monitor.cpp
|
||||
index e6b6a61..3c63735 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.cpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.cpp
|
||||
@@ -5,7 +5,9 @@
|
||||
#include <phosphor-logging/lg2.hpp>
|
||||
#include <sdbusplus/exception.hpp>
|
||||
#include <xyz/openbmc_project/Common/error.hpp>
|
||||
-
|
||||
+#include <string>
|
||||
+#include <vector>
|
||||
+#include <iostream>
|
||||
namespace phosphor
|
||||
{
|
||||
namespace led
|
||||
@@ -24,7 +26,9 @@ static constexpr auto mapperObjPath = "/xyz/openbmc_project/object_mapper";
|
||||
static constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper";
|
||||
static constexpr auto objMgrIntf = "org.freedesktop.DBus.ObjectManager";
|
||||
static constexpr auto ledGroups = "/xyz/openbmc_project/led/groups/";
|
||||
+static constexpr auto logPath = "/xyz/openbmc_project/logging";
|
||||
static constexpr auto logIntf = "xyz.openbmc_project.Logging.Entry";
|
||||
+static constexpr auto logService = "xyz.openbmc_project.Logging";
|
||||
|
||||
using AssociationList =
|
||||
std::vector<std::tuple<std::string, std::string, std::string>>;
|
||||
@@ -46,6 +50,96 @@ using ResourceNotFoundErr =
|
||||
using InvalidArgumentErr =
|
||||
sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
|
||||
|
||||
+constexpr const char* discreteSensorNs = "No state defined";
|
||||
+
|
||||
+// 10H
|
||||
+constexpr auto SYSTEM_EVENT_LOG_CLEARED = 2;
|
||||
+
|
||||
+// 22H
|
||||
+constexpr auto ACPI_S0_STATE = 0;
|
||||
+constexpr auto ACPI_S5_STATE = 6;
|
||||
+
|
||||
+/*sensor object, SensorStatusInfo*/
|
||||
+std::unordered_map<std::string, SensorStatusInfo> sensorStatusRec;
|
||||
+std::unordered_map<std::string, std::unordered_map<uint8_t, DriveStatus>> driveStatusRec;
|
||||
+
|
||||
+enum AlarmType
|
||||
+{
|
||||
+ NORMAL = 0,
|
||||
+ NONCRITICAL = 1,
|
||||
+ CRITICAL = 2,
|
||||
+ NONRECOV = 4,
|
||||
+};
|
||||
+
|
||||
+struct SelSeverityInfo
|
||||
+{
|
||||
+ std::string sensorPath;
|
||||
+ SensorType sensorType;
|
||||
+ uint8_t eventType;
|
||||
+ std::string eventData;
|
||||
+ std::string eventDir;
|
||||
+ AlarmType severity;
|
||||
+ bool assertToAlarm;
|
||||
+};
|
||||
+std::unordered_map<Path, std::vector<SelSeverityInfo>> getPathfailedRec;
|
||||
+
|
||||
+
|
||||
+constexpr auto SENSOR_EVENT_DATA1_EVENT_OFFSET = 0x0F;
|
||||
+
|
||||
+const std::unordered_map<uint64_t, std::string> healthStr{
|
||||
+ {0, "Ok"},
|
||||
+ {1, "Warning"},
|
||||
+ {2, "Critical"},
|
||||
+ {4, "Critical"},
|
||||
+};
|
||||
+
|
||||
+using discrectSensorEvent = std::unordered_map<uint8_t, std::string>;
|
||||
+
|
||||
+using AdditionalList = std::vector<std::string>;
|
||||
+using sensorCodes = std::vector<uint8_t>;
|
||||
+using ipmiSensorsInfo = std::unordered_map<std::string, sensorCodes>;
|
||||
+std::optional<ipmiSensorsInfo> ipmiSensors;
|
||||
+
|
||||
+const std::unordered_map<SensorType, discrectSensorEvent> sensorSpecificTypes{
|
||||
+ {SENSOR_TYPE_SYSTEM_ACPI_POWER_STATE,
|
||||
+ {
|
||||
+ {ACPI_S0_STATE, "S0/G0: working"},
|
||||
+ {ACPI_S5_STATE, "S4/S5: soft-off"},
|
||||
+ }},
|
||||
+ {SENSOR_TYPE_EVENT_LOGGING_DISABLED,
|
||||
+ {
|
||||
+ {SYSTEM_EVENT_LOG_CLEARED, "Log area reset/cleared"},
|
||||
+ }}
|
||||
+};
|
||||
+
|
||||
+std::optional<ipmiSensorsInfo> initIPMISensorInfo(sdbusplus::bus::bus& bus)
|
||||
+{
|
||||
+ constexpr auto service = "xyz.openbmc_project.Ipmi.Host";
|
||||
+ constexpr auto obj = "/xyz/openbmc_project/Ipmi/SensorInfo";
|
||||
+ constexpr auto interface = "xyz.openbmc_project.IPMI.SensorInfo";
|
||||
+ constexpr auto property = "SensorInfo";
|
||||
+
|
||||
+ std::variant<ipmiSensorsInfo> propertyValue{};
|
||||
+
|
||||
+ auto method = bus.new_method_call(service, obj,
|
||||
+ "org.freedesktop.DBus.Properties", "Get");
|
||||
+ method.append(interface, property);
|
||||
+
|
||||
+ try
|
||||
+ {
|
||||
+ auto reply = bus.call(method);
|
||||
+ reply.read(propertyValue);
|
||||
+ }
|
||||
+ catch (const sdbusplus::exception::exception& e)
|
||||
+ {
|
||||
+ lg2::error("Failed to get ipmi sensor info, ERROR = {ERROR}", "ERROR",
|
||||
+ e);
|
||||
+ return {};
|
||||
+ }
|
||||
+
|
||||
+ return std::make_optional(std::get<ipmiSensorsInfo>(propertyValue));
|
||||
+}
|
||||
+
|
||||
std::string getService(sdbusplus::bus_t& bus, const std::string& path)
|
||||
{
|
||||
auto mapper = bus.new_method_call(mapperBusName, mapperObjPath, mapperIntf,
|
||||
@@ -76,6 +170,102 @@ std::string getService(sdbusplus::bus_t& bus, const std::string& path)
|
||||
return mapperResponse.cbegin()->first;
|
||||
}
|
||||
|
||||
+static void setDiscreteSensorStatusValue(sdbusplus::bus::bus& bus,
|
||||
+ const std::string& sensorPath,const std::string& sensorData)
|
||||
+{
|
||||
+ // IPMI spec Table 35-15
|
||||
+ // For discrete reading sensors only. (Optional)
|
||||
+ // [7] - reserved. Returned as 1b. Ignore on read.
|
||||
+ uint16_t reserved = 0x8000;
|
||||
+
|
||||
+ // ipmi spec 42.2 set the sensor-specific offset
|
||||
+ double statusValue = reserved;
|
||||
+
|
||||
+ constexpr auto service = "xyz.openbmc_project.dissen";
|
||||
+ constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
|
||||
+ constexpr auto statusInterface = "xyz.openbmc_project.Configuration.Status";
|
||||
+
|
||||
+ unsigned long dataValue = strtoul(sensorData.c_str(), NULL, 16);
|
||||
+ statusValue = static_cast<double>(statusValue +
|
||||
+ (0x01 << ((dataValue & 0x0f0000) >> 16)));
|
||||
+ auto method = bus.new_method_call(service, sensorPath.c_str(),
|
||||
+ dbusProperties, "Set");
|
||||
+ std::variant<double> value{(double)statusValue};
|
||||
+
|
||||
+ method.append(statusInterface, "Status", value);
|
||||
+ try
|
||||
+ {
|
||||
+ bus.call_noreply(method);
|
||||
+ }
|
||||
+ catch (const sdbusplus::exception::exception& e)
|
||||
+ {
|
||||
+ lg2::info("Error setting discrete sensor status, ERROR = {ERROR}",
|
||||
+ "ERROR", e);
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void setDiscreteSensorDiscription(sdbusplus::bus::bus& bus,
|
||||
+ const std::string& sensorPath)
|
||||
+{
|
||||
+ constexpr auto service = "xyz.openbmc_project.EntityManager";
|
||||
+ constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
|
||||
+ constexpr auto statusInterface = "xyz.openbmc_project.Configuration.Status";
|
||||
+ auto description = sensorStatusRec[sensorPath].description;
|
||||
+ // set discrete sensor description
|
||||
+ auto method = bus.new_method_call(service, sensorPath.c_str(),
|
||||
+ dbusProperties, "Set");
|
||||
+ std::variant<std::string> value{description};
|
||||
+
|
||||
+ method.append(statusInterface, "Description", value);
|
||||
+ try
|
||||
+ {
|
||||
+ bus.call_noreply(method);
|
||||
+ }
|
||||
+ catch (const sdbusplus::exception::exception& e)
|
||||
+ {
|
||||
+ lg2::info("Error setting discrete sensor description, ERROR = {ERROR}",
|
||||
+ "ERROR", e);
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void setDiscreteSensorHealth(sdbusplus::bus::bus& bus,
|
||||
+ const std::string& sensorPath)
|
||||
+{
|
||||
+ constexpr auto service = "xyz.openbmc_project.EntityManager";
|
||||
+ constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
|
||||
+ constexpr auto statusInterface = "xyz.openbmc_project.Configuration.Status";
|
||||
+
|
||||
+ // convert alarmStatus to string
|
||||
+ std::string health = "ns";
|
||||
+ auto it = healthStr.find(sensorStatusRec[sensorPath].alarmStatus);
|
||||
+ if (it != healthStr.end())
|
||||
+ {
|
||||
+ health = it->second;
|
||||
+ }
|
||||
+
|
||||
+ // set discrete sensor health
|
||||
+ auto method = bus.new_method_call(service, sensorPath.c_str(),
|
||||
+ dbusProperties, "Set");
|
||||
+ std::variant<std::string> value{health};
|
||||
+
|
||||
+ method.append(statusInterface, "Health", value);
|
||||
+ try
|
||||
+ {
|
||||
+ bus.call_noreply(method);
|
||||
+ }
|
||||
+ catch (const sdbusplus::exception::exception& e)
|
||||
+ {
|
||||
+ lg2::info("Error setting discrete sensor health, ERROR = {ERROR}",
|
||||
+ "ERROR", e);
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
void action(sdbusplus::bus_t& bus, const std::string& path, bool assert)
|
||||
{
|
||||
std::string service;
|
||||
@@ -124,6 +314,232 @@ void action(sdbusplus::bus_t& bus, const std::string& path, bool assert)
|
||||
return;
|
||||
}
|
||||
|
||||
+enum
|
||||
+{
|
||||
+ UNSPECIFY_SENSOR_TYPE = 0x00,
|
||||
+ THRESHOLD_SENSOR_TYPE = 0x01,
|
||||
+ GENERIC_S_SENSOR_TYPE = 0x02,
|
||||
+ GENERIC_E_SENSOR_TYPE = 0x0C,
|
||||
+ SPECIFIC_SENSOR_TYPE = 0x6F,
|
||||
+ OEM_S_SENSOR_TYPE = 0x70,
|
||||
+ OEM_E_SENSOR_TYPE = 0x7F
|
||||
+};
|
||||
+
|
||||
+void fillSensorDescription(const std::string& sensorPath, int eventOffset)
|
||||
+{
|
||||
+ sensorStatusRec[sensorPath].description = discreteSensorNs;
|
||||
+ // find event description for generic type
|
||||
+ //auto eventType = sensorStatusRec[sensorPath].eventType;
|
||||
+ // if (eventType != SPECIFIC_SENSOR_TYPE)
|
||||
+ // {
|
||||
+ // auto it = genericEventTypes.find(eventType);
|
||||
+ // if (it != genericEventTypes.end())
|
||||
+ // {
|
||||
+ // auto eventType = it->second;
|
||||
+ // auto health = eventType.find(eventOffset);
|
||||
+ // if (health != eventType.end())
|
||||
+ // {
|
||||
+ // sensorStatusRec[sensorPath].description = health->second;
|
||||
+ // }
|
||||
+ // }
|
||||
+ // }
|
||||
+ // else
|
||||
+ //{
|
||||
+ // find event description for sensor specific type
|
||||
+ auto it =
|
||||
+ sensorSpecificTypes.find(sensorStatusRec[sensorPath].sensorType);
|
||||
+ if (it != sensorSpecificTypes.end())
|
||||
+ {
|
||||
+ auto eventType = it->second;
|
||||
+ auto health = eventType.find(eventOffset);
|
||||
+ if (health != eventType.end())
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].description = health->second;
|
||||
+ }
|
||||
+ }
|
||||
+ //}
|
||||
+}
|
||||
+
|
||||
+AlarmType parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
+ const std::string& sensorPath,
|
||||
+ const SensorType& sensorType,
|
||||
+ const std::string& eventData,
|
||||
+ const std::string& eventDir)
|
||||
+{
|
||||
+ std::string eventData1 = eventData.substr(0, 2);
|
||||
+ int ev = std::stol(eventData1, nullptr, 16);
|
||||
+ int ed = std::stol(eventDir);
|
||||
+ AlarmType alarmStatus = NORMAL;
|
||||
+ int ev1Offset = ev & SENSOR_EVENT_DATA1_EVENT_OFFSET;
|
||||
+ switch (sensorType)
|
||||
+ {
|
||||
+ case SENSOR_TYPE_EVENT_LOGGING_DISABLED:
|
||||
+ {
|
||||
+ switch (ev1Offset)
|
||||
+ {
|
||||
+ case SYSTEM_EVENT_LOG_CLEARED:
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ {
|
||||
+ return alarmStatus;
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ case SENSOR_TYPE_SYSTEM_ACPI_POWER_STATE:
|
||||
+ {
|
||||
+ switch (ev1Offset)
|
||||
+ {
|
||||
+ case ACPI_S0_STATE:
|
||||
+ case ACPI_S5_STATE:
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ {
|
||||
+ if (!ed)
|
||||
+ {
|
||||
+ alarmStatus = NORMAL;
|
||||
+ }
|
||||
+ return alarmStatus;
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ return alarmStatus;
|
||||
+ }
|
||||
+ sensorStatusRec[sensorPath].eventType = SPECIFIC_SENSOR_TYPE;
|
||||
+ sensorStatusRec[sensorPath].sensorType = sensorType;
|
||||
+ setDiscreteSensorStatusValue(bus, sensorPath, eventData);
|
||||
+ if(0)
|
||||
+ {
|
||||
+ fillSensorDescription(sensorPath, ev1Offset);
|
||||
+ setDiscreteSensorDiscription(bus, sensorPath);
|
||||
+ setDiscreteSensorHealth(bus, sensorPath);
|
||||
+ }
|
||||
+ return alarmStatus;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+void Add::filterSEL(sdbusplus::bus::bus& bus, const std::string& path)
|
||||
+{
|
||||
+ //AlarmType severity = NORMAL;
|
||||
+ auto method = bus.new_method_call(logService, path.c_str(),
|
||||
+ "org.freedesktop.DBus.Properties", "Get");
|
||||
+ method.append("xyz.openbmc_project.Logging.Entry");
|
||||
+ method.append("AdditionalData");
|
||||
+ std::cerr << "filterSEL path " << path <<"\n";
|
||||
+ std::variant<AdditionalList> additionalData;
|
||||
+ try
|
||||
+ {
|
||||
+ auto reply = bus.call(method);
|
||||
+ reply.read(additionalData);
|
||||
+ }
|
||||
+ catch (const sdbusplus::exception::exception& e)
|
||||
+ {
|
||||
+ lg2::error(
|
||||
+ "Failed to parse existing callouts AdditionalData message. {ERROR}",
|
||||
+ "ERROR", e.what());
|
||||
+ }
|
||||
+
|
||||
+ auto& additionalDatas = std::get<AdditionalList>(additionalData);
|
||||
+ if (additionalDatas.empty())
|
||||
+ {
|
||||
+ lg2::error("additionalDatas is empty");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ uint8_t typeCode = 0;
|
||||
+ uint8_t sensorType = 0;
|
||||
+ std::string sensorData, sensorPath, eventDir;
|
||||
+ for (auto& item : additionalDatas)
|
||||
+ {
|
||||
+ std::string::size_type nStr;
|
||||
+
|
||||
+ if (eventDir.empty())
|
||||
+ {
|
||||
+ nStr = item.find("EVENT_DIR=");
|
||||
+ if (std::string::npos != nStr)
|
||||
+ {
|
||||
+ eventDir = item.substr(nStr + strlen("EVENT_DIR="));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (sensorData.empty())
|
||||
+ {
|
||||
+ nStr = item.find("SENSOR_DATA=");
|
||||
+ if (std::string::npos != nStr)
|
||||
+ {
|
||||
+ sensorData = item.substr(nStr + strlen("SENSOR_DATA="));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (sensorPath.empty())
|
||||
+ {
|
||||
+ nStr = item.find("SENSOR_PATH=");
|
||||
+ if (std::string::npos != nStr)
|
||||
+ {
|
||||
+ sensorPath = item.substr(nStr + strlen("SENSOR_PATH="));
|
||||
+ std::string sensorPathTmp = sensorPath;
|
||||
+ size_t pos = sensorPathTmp.rfind('/');
|
||||
+ if (pos != std::string::npos){
|
||||
+ sensorPath = "/xyz/openbmc_project/sensors/status/" + sensorPathTmp.substr(pos + 1);
|
||||
+ }
|
||||
+ std::cerr << "sensorPath " << sensorPath <<"\n";
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!ipmiSensors)
|
||||
+ {
|
||||
+ ipmiSensors = initIPMISensorInfo(bus);
|
||||
+ }
|
||||
+
|
||||
+ if (ipmiSensors)
|
||||
+ {
|
||||
+ auto iter = ipmiSensors->find(sensorPath);
|
||||
+ if (iter != ipmiSensors->end())
|
||||
+ {
|
||||
+ sensorType = iter->second[0];
|
||||
+ typeCode = iter->second[1];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (sensorData == "" || typeCode == 0 || eventDir == "" || sensorType == 0)
|
||||
+ {
|
||||
+ lg2::error(
|
||||
+ "ERROR: Additional Data parse failed, sensorData = {SENSORDATA} sensorPath = {SENSORPATH} sensorType = {SENSORTYPE} typeCode = {TYPECODE} eventDir = {EVENTDIR}",
|
||||
+ "SENSORDATA", sensorData, "SENSORPATH", sensorPath, "SENSORTYPE",
|
||||
+ sensorType, "TYPECODE", typeCode, "EVENTDIR", eventDir);
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (typeCode == THRESHOLD_SENSOR_TYPE)
|
||||
+ {
|
||||
+ // parse threshold sensors
|
||||
+ //parseThresholdSelSeverity(sensorData, eventDir);
|
||||
+ }
|
||||
+ else if (typeCode == SPECIFIC_SENSOR_TYPE)
|
||||
+ {
|
||||
+ // discrete
|
||||
+ parseSpecificSensorSelSeverity(
|
||||
+ bus, sensorPath, static_cast<SensorType>(sensorType), sensorData,
|
||||
+ eventDir);
|
||||
+ }
|
||||
+
|
||||
+ //controlHealthLed(bus);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
void Add::created(sdbusplus::message_t& msg)
|
||||
{
|
||||
auto bus = msg.get_bus();
|
||||
@@ -147,7 +563,8 @@ void Add::created(sdbusplus::message_t& msg)
|
||||
// Not a new error entry skip
|
||||
return;
|
||||
}
|
||||
- auto iter = interfaces.find("xyz.openbmc_project.Association.Definitions");
|
||||
+ // auto iter = interfaces.find("xyz.openbmc_project.Association.Definitions");
|
||||
+ auto iter = interfaces.find("xyz.openbmc_project.Logging.Entry");
|
||||
if (iter == interfaces.end())
|
||||
{
|
||||
return;
|
||||
@@ -157,29 +574,32 @@ void Add::created(sdbusplus::message_t& msg)
|
||||
// has been created. Do it here.
|
||||
lg2::info("{PATH} created", "PATH", objectPath);
|
||||
|
||||
- auto attr = iter->second.find("Associations");
|
||||
+ //auto attr = iter->second.find("Associations");
|
||||
+ auto attr = iter->second.find("AdditionalData");
|
||||
if (attr == iter->second.end())
|
||||
{
|
||||
+ lg2::info("No AdditionalData");
|
||||
return;
|
||||
}
|
||||
|
||||
- auto& assocs = std::get<AssociationList>(attr->second);
|
||||
- if (assocs.empty())
|
||||
- {
|
||||
- // No associations skip
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- for (const auto& item : assocs)
|
||||
- {
|
||||
- if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
|
||||
- {
|
||||
- removeWatches.emplace_back(
|
||||
- std::make_unique<Remove>(bus, std::get<2>(item)));
|
||||
- action(bus, std::get<2>(item), true);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
+ // auto& assocs = std::get<AssociationList>(attr->second);
|
||||
+ // if (assocs.empty())
|
||||
+ // {
|
||||
+ // // No associations skip
|
||||
+ // return;
|
||||
+ // }
|
||||
+
|
||||
+ // for (const auto& item : assocs)
|
||||
+ // {
|
||||
+ // if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
|
||||
+ // {
|
||||
+ // removeWatches.emplace_back(
|
||||
+ // std::make_unique<Remove>(bus, std::get<2>(item)));
|
||||
+ // action(bus, std::get<2>(item), true);
|
||||
+ // }
|
||||
+ // }
|
||||
+
|
||||
+ filterSEL(bus, objectPath.str);
|
||||
return;
|
||||
}
|
||||
|
||||
diff --git a/fault-monitor/fru-fault-monitor.hpp b/fault-monitor/fru-fault-monitor.hpp
|
||||
index 028e873..652fefa 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.hpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.hpp
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <sdbusplus/server.hpp>
|
||||
|
||||
#include <string>
|
||||
-
|
||||
+#include <iostream>
|
||||
namespace phosphor
|
||||
{
|
||||
namespace led
|
||||
@@ -27,6 +27,33 @@ void action(sdbusplus::bus_t& bus, const std::string& path, bool assert);
|
||||
|
||||
class Remove;
|
||||
|
||||
+/*
|
||||
+ * IPMI Standard Sensor Type Define
|
||||
+ */
|
||||
+enum SensorType
|
||||
+{
|
||||
+ SENSOR_TYPE_EVENT_LOGGING_DISABLED = 0x10,
|
||||
+ SENSOR_TYPE_SYSTEM_ACPI_POWER_STATE = 0x22,
|
||||
+
|
||||
+ SENSOR_TYPE_MAX_NUMBER = 0x100 // Senor Type 为1个byte,最大为0~255,即:256个
|
||||
+};
|
||||
+
|
||||
+struct SensorStatusInfo
|
||||
+{
|
||||
+ uint8_t eventType;
|
||||
+ SensorType sensorType;
|
||||
+ uint16_t sensorStatus;
|
||||
+ uint64_t alarmStatus;
|
||||
+ std::string description; // add description for discrete sensor
|
||||
+};
|
||||
+
|
||||
+struct DriveStatus
|
||||
+{
|
||||
+ uint16_t sensorStatus; /*entity status*/
|
||||
+ uint64_t alarmStatus; /*alarm status*/
|
||||
+};
|
||||
+
|
||||
+
|
||||
/** @class Add
|
||||
* @brief Implementation of LED handling during FRU fault
|
||||
* @details This implements methods for watching for a FRU fault
|
||||
@@ -46,17 +73,19 @@ class Add
|
||||
* @param[in] bus - The Dbus bus object
|
||||
*/
|
||||
explicit Add(sdbusplus::bus_t& bus) :
|
||||
- matchCreated(
|
||||
- bus,
|
||||
- sdbusplus::bus::match::rules::interfacesAdded() +
|
||||
- sdbusplus::bus::match::rules::path_namespace(
|
||||
- "/xyz/openbmc_project/logging"),
|
||||
- std::bind(std::mem_fn(&Add::created), this, std::placeholders::_1))
|
||||
+ bus(bus), matchCreated(bus,
|
||||
+ sdbusplus::bus::match::rules::interfacesAdded() +
|
||||
+ sdbusplus::bus::match::rules::path_namespace(
|
||||
+ "/xyz/openbmc_project/logging"),
|
||||
+ std::bind(std::mem_fn(&Add::created), this,
|
||||
+ std::placeholders::_1))
|
||||
{
|
||||
+ std::cerr << "wangbin matchCreated \n";
|
||||
processExistingCallouts(bus);
|
||||
}
|
||||
|
||||
private:
|
||||
+ sdbusplus::bus::bus& bus;
|
||||
/** @brief sdbusplus signal match for fault created */
|
||||
sdbusplus::bus::match_t matchCreated;
|
||||
|
||||
@@ -67,6 +96,8 @@ class Add
|
||||
*/
|
||||
void created(sdbusplus::message_t& msg);
|
||||
|
||||
+ void filterSEL(sdbusplus::bus::bus& bus, const std::string& path);
|
||||
+
|
||||
/** @brief This function process all callouts at application start
|
||||
* @param[in] bus - The Dbus bus object
|
||||
*/
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
From 7f310f1f1c9f32ec9d94fcc06b25e26faf0b66c4 Mon Sep 17 00:00:00 2001
|
||||
From: wangjue <jue.wang2@luxshare-ict.com>
|
||||
Date: Thu, 12 Dec 2024 09:59:32 +0800
|
||||
Subject: [PATCH] Add watchdog2 sensor type
|
||||
|
||||
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
|
||||
---
|
||||
fault-monitor/fru-fault-monitor.cpp | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fault-monitor/fru-fault-monitor.cpp b/fault-monitor/fru-fault-monitor.cpp
|
||||
index 737c90d..b9f687c 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.cpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.cpp
|
||||
@@ -919,6 +919,11 @@ void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
break;
|
||||
}
|
||||
+ case SENSOR_TYPE_WATCHDOG_2:
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
+ break;
|
||||
+ }
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -987,7 +992,7 @@ using EventAlarm = std::unordered_map<uint8_t, EventActions>;
|
||||
// 'Status'. See: initDiscreteSensorStatusInfo() and sensorMatchHandler().
|
||||
// If true, it means that the 'Status' has been initialized
|
||||
// and the status sensor object on the entity-manager has been created.
|
||||
-
|
||||
+
|
||||
// if (sensorStatusRec.find(sensorPath) == sensorStatusRec.end())
|
||||
// {
|
||||
// lg2::error(
|
||||
--
|
||||
2.34.1
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
From 4b33a41ddbb3dc745a41248070f02d69e21ddf46 Mon Sep 17 00:00:00 2001
|
||||
From: wangjue <jue.wang2@luxshare-ict.com>
|
||||
Date: Mon, 11 Nov 2024 15:29:45 +0800
|
||||
Subject: [PATCH] Enable Orange LED to indicate if dimm is present
|
||||
|
||||
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
|
||||
---
|
||||
fault-monitor/fru-fault-monitor.cpp | 15 ++++++++-------
|
||||
1 file changed, 8 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/fault-monitor/fru-fault-monitor.cpp b/fault-monitor/fru-fault-monitor.cpp
|
||||
index fffb6f7..aa7b8cc 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.cpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.cpp
|
||||
@@ -42,7 +42,7 @@ static constexpr auto logService = "xyz.openbmc_project.Logging";
|
||||
|
||||
#define SET_GREEN_LED(x) (~(uint8_t(1 << (x*2))))
|
||||
#define SET_RED_LED(x) (~(uint8_t(1 << (x*2 + 1))))
|
||||
-#define SET_ORANGE_LED(x) (SET_GREEN_LED(x) | SET_RED_LED(x))
|
||||
+#define SET_ORANGE_LED(x) (SET_GREEN_LED(x) & SET_RED_LED(x))
|
||||
#define UNSET_GREEN_LED(x) (uint8_t(1 << (x*2)))
|
||||
#define UNSET_RED_LED(x) (uint8_t(1 << (x*2 + 1)))
|
||||
#define SET_LED_OFF(x) ((uint8_t(1 << (x*2))) | (uint8_t(1 << (x*2+1))))
|
||||
@@ -1008,10 +1008,6 @@ void Add::updateDimmLed(int cpuId, int dimmRank, std::string ledState)
|
||||
int ret = -1;
|
||||
std::string i2cBus = "/dev/i2c-5";
|
||||
|
||||
- if constexpr (debug) {
|
||||
- std::cout << "cpuId: " << cpuId << " dimmrank: " << dimmRank << " ledState: " << ledState <<std::endl;
|
||||
- }
|
||||
-
|
||||
uint8_t preset = (cpuId * 12 + dimmRank) / 8;
|
||||
if(preset >= 3)
|
||||
{
|
||||
@@ -1041,11 +1037,16 @@ void Add::updateDimmLed(int cpuId, int dimmRank, std::string ledState)
|
||||
wdata = (readBuf[0] & SET_RED_LED(ledSlot)) | UNSET_GREEN_LED(ledSlot);
|
||||
else if(ledState == "OFF")
|
||||
wdata = readBuf[0] | SET_LED_OFF(ledSlot);
|
||||
- else if(ledState == "WAR")
|
||||
- wdata = readBuf[0] | SET_LED_OFF(ledSlot);
|
||||
+ else if(ledState == "NA")
|
||||
+ wdata = readBuf[0] & SET_ORANGE_LED(ledSlot);
|
||||
else
|
||||
std::cerr << " Invalid DIMM CPU" << cpuId << " rank" << dimmRank << " LED State " << ledState << "\n";
|
||||
|
||||
+ if constexpr (debug) {
|
||||
+ std::cout << "cpuId: " << cpuId << " dimmrank: " << dimmRank << " ledState: " << ledState << " wdata:"
|
||||
+ << (int)wdata <<std::endl;
|
||||
+ }
|
||||
+
|
||||
writeData.push_back(wdata);
|
||||
readBuf.resize(0);
|
||||
ret = i2cWriteRead(i2cBus, i2cAddrs[preset], writeData, readBuf);
|
||||
--
|
||||
2.34.1
|
||||
|
||||
+568
@@ -0,0 +1,568 @@
|
||||
From 685ddf56f7f7d5d01ec6285d72dad653962753ef Mon Sep 17 00:00:00 2001
|
||||
From: wangjue <jue.wang2@luxshare-ict.com>
|
||||
Date: Thu, 24 Oct 2024 20:30:19 +0800
|
||||
Subject: [PATCH] Implement DIMM LED control
|
||||
|
||||
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
|
||||
---
|
||||
fault-monitor/fru-fault-monitor.cpp | 313 +++++++++++++++++++++++++++-
|
||||
fault-monitor/fru-fault-monitor.hpp | 72 ++++++-
|
||||
fault-monitor/meson.build | 5 +-
|
||||
fault-monitor/monitor-main.cpp | 13 +-
|
||||
meson.build | 2 +
|
||||
5 files changed, 392 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/fault-monitor/fru-fault-monitor.cpp b/fault-monitor/fru-fault-monitor.cpp
|
||||
index 4946065..03e1700 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.cpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.cpp
|
||||
@@ -8,6 +8,16 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
+
|
||||
+extern "C"
|
||||
+{
|
||||
+#include <i2c/smbus.h>
|
||||
+#include <linux/i2c-dev.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <unistd.h>
|
||||
+#include <sys/ioctl.h>
|
||||
+}
|
||||
+
|
||||
namespace phosphor
|
||||
{
|
||||
namespace led
|
||||
@@ -30,6 +40,13 @@ static constexpr auto logPath = "/xyz/openbmc_project/logging";
|
||||
static constexpr auto logIntf = "xyz.openbmc_project.Logging.Entry";
|
||||
static constexpr auto logService = "xyz.openbmc_project.Logging";
|
||||
|
||||
+#define SET_GREEN_LED(x) (~(uint8_t(1 << (x*2))))
|
||||
+#define SET_RED_LED(x) (~(uint8_t(1 << (x*2 + 1))))
|
||||
+#define SET_ORANGE_LED(x) (SET_GREEN_LED(x) | SET_RED_LED(x))
|
||||
+#define UNSET_GREEN_LED(x) (uint8_t(1 << (x*2)))
|
||||
+#define UNSET_RED_LED(x) (uint8_t(1 << (x*2 + 1)))
|
||||
+#define SET_LED_OFF(x) ((uint8_t(1 << (x*2))) | (uint8_t(1 << (x*2+1))))
|
||||
+
|
||||
using AssociationList =
|
||||
std::vector<std::tuple<std::string, std::string, std::string>>;
|
||||
using Attributes = std::variant<bool, AssociationList>;
|
||||
@@ -68,6 +85,7 @@ constexpr auto ACPI_S5_STATE = 6;
|
||||
std::unordered_map<std::string, SensorStatusInfo> sensorStatusRec;
|
||||
std::unordered_map<std::string, std::unordered_map<uint8_t, DriveStatus>> driveStatusRec;
|
||||
|
||||
+
|
||||
enum AlarmType
|
||||
{
|
||||
NORMAL = 0,
|
||||
@@ -237,6 +255,41 @@ static void setDiscreteSensorDiscription(sdbusplus::bus::bus& bus,
|
||||
return;
|
||||
}
|
||||
|
||||
+static void setDimmLEDState(sdbusplus::bus::bus& bus,
|
||||
+ const std::string& sensorPath,const std::string& ledState)
|
||||
+{
|
||||
+ std::string sensorName;
|
||||
+ std::string ledStatePath;
|
||||
+ size_t lastSlashPos = sensorPath.rfind('/');
|
||||
+ size_t statusPos = sensorPath.find("_Status");
|
||||
+
|
||||
+ if (lastSlashPos != std::string::npos && statusPos != std::string::npos) {
|
||||
+ sensorName = sensorPath.substr(lastSlashPos + 1, statusPos - lastSlashPos - 1);
|
||||
+ ledStatePath = "/xyz/openbmc_project/sensors/temperature/" + sensorName + "_Temp";
|
||||
+ } else {
|
||||
+ lg2::info("Invalid sensorPath, sensorPath = {PATH}",
|
||||
+ "PATH", sensorPath);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ auto method = bus.new_method_call(DIMMTempSensorBusname, ledStatePath.c_str(),
|
||||
+ dbusProperties, "Set");
|
||||
+
|
||||
+ std::variant<std::string> value{ledState};
|
||||
+ method.append(dimmLEDInterface, "LEDState", value);
|
||||
+ try
|
||||
+ {
|
||||
+ bus.call_noreply(method);
|
||||
+ }
|
||||
+ catch (const sdbusplus::exception::exception& e)
|
||||
+ {
|
||||
+ lg2::info("Error setting Dimm LED State, ERROR = {ERROR}",
|
||||
+ "ERROR", e);
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
static void setDiscreteSensorHealth(sdbusplus::bus::bus& bus,
|
||||
const std::string& sensorPath)
|
||||
{
|
||||
@@ -441,6 +494,7 @@ void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
case SENSOR_TYPE_MEMORY:
|
||||
{
|
||||
sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
+ setDimmLEDState(bus, sensorPath, "FAULT");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -458,9 +512,6 @@ void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
return;
|
||||
}
|
||||
|
||||
-
|
||||
-
|
||||
-
|
||||
void Add::filterSEL(sdbusplus::bus::bus& bus, const std::string& path)
|
||||
{
|
||||
//AlarmType severity = NORMAL;
|
||||
@@ -631,6 +682,250 @@ void Add::created(sdbusplus::message_t& msg)
|
||||
return;
|
||||
}
|
||||
|
||||
+std::string getFileName(const std::string& path) {
|
||||
+ size_t lastSlash = path.find_last_of("/\\");
|
||||
+ return (lastSlash == std::string::npos) ? "" : path.substr(lastSlash + 1);
|
||||
+}
|
||||
+
|
||||
+static int i2cWriteRead(std::string& i2cBus, const uint8_t slaveAddr,
|
||||
+ std::vector<uint8_t> writeData,
|
||||
+ std::vector<uint8_t>& readBuf)
|
||||
+{
|
||||
+ int fd = open(i2cBus.c_str(), O_RDWR);
|
||||
+ if (fd < 0)
|
||||
+ {
|
||||
+ std::cerr << " unable to open i2c device" << i2cBus << " err=" << fd
|
||||
+ << "\n";
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ uint8_t writeCount = writeData.size();
|
||||
+ uint8_t readCount = readBuf.size();
|
||||
+ int msgCount = 0;
|
||||
+ struct i2c_msg i2cmsg[2]; // = {0};
|
||||
+
|
||||
+ memset(i2cmsg, 0, sizeof(i2cmsg));
|
||||
+
|
||||
+ if (writeCount)
|
||||
+ {
|
||||
+ // Data will be writtern to the slave address
|
||||
+ i2cmsg[msgCount].addr = slaveAddr;
|
||||
+ i2cmsg[msgCount].flags = 0x00;
|
||||
+ i2cmsg[msgCount].len = writeCount;
|
||||
+ i2cmsg[msgCount].buf = writeData.data();
|
||||
+ msgCount++;
|
||||
+ }
|
||||
+
|
||||
+ if (readCount)
|
||||
+ {
|
||||
+ // Data will be read into the buffer from the slave address
|
||||
+ i2cmsg[msgCount].addr = slaveAddr;
|
||||
+ i2cmsg[msgCount].flags = I2C_M_RD;
|
||||
+ i2cmsg[msgCount].len = readCount;
|
||||
+ i2cmsg[msgCount].buf = readBuf.data();
|
||||
+ msgCount++;
|
||||
+ }
|
||||
+
|
||||
+ struct i2c_rdwr_ioctl_data msgReadWrite; // = {0};
|
||||
+ memset((void*)&msgReadWrite, 0, sizeof(msgReadWrite));
|
||||
+ msgReadWrite.msgs = i2cmsg;
|
||||
+ msgReadWrite.nmsgs = msgCount;
|
||||
+
|
||||
+ // Perform the combined write/read
|
||||
+ int ret = ioctl(fd, I2C_RDWR, &msgReadWrite);
|
||||
+ close(fd);
|
||||
+ if (ret < 0)
|
||||
+ {
|
||||
+ std::cerr << "getDIMMRegsInfoWord I2C Write Failed!"
|
||||
+ << "\n";
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (readCount)
|
||||
+ {
|
||||
+ readBuf.resize(msgReadWrite.msgs[msgCount - 1].len);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void Add::dimmledInit()
|
||||
+{
|
||||
+ int ret = -1;
|
||||
+ std::string i2cBus = "/dev/i2c-5";
|
||||
+
|
||||
+ for(uint8_t addr : i2cAddrs) {
|
||||
+ std::vector<uint8_t> writeData{regConfig[0], 0x0};
|
||||
+ std::vector<uint8_t> readBuf(0);
|
||||
+ ret = i2cWriteRead(i2cBus, addr, writeData, readBuf);
|
||||
+ if (ret < 0)
|
||||
+ goto err;
|
||||
+
|
||||
+ writeData[0] = regConfig[1];
|
||||
+ ret = i2cWriteRead(i2cBus, addr, writeData, readBuf);
|
||||
+ if (ret < 0)
|
||||
+ goto err;
|
||||
+
|
||||
+ writeData[0] = regOutput[0];
|
||||
+ writeData[1] = 0xff;
|
||||
+ ret = i2cWriteRead(i2cBus, addr, writeData, readBuf);
|
||||
+ if (ret < 0)
|
||||
+ goto err;
|
||||
+
|
||||
+ writeData[0] = regOutput[1];
|
||||
+ ret = i2cWriteRead(i2cBus, addr, writeData, readBuf);
|
||||
+ if (ret < 0)
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+ err:
|
||||
+ std::cerr << "i2c read/write error, DIMM ledInit failed. \n";
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+void Add::updateSysHealthLED(std::pair<std::string, std::string>& pair)
|
||||
+{
|
||||
+ if(pair.second == "FAULT") {
|
||||
+ setHealthLED(pair.first);
|
||||
+ } else {
|
||||
+ unsetHealthLED(pair.first);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void Add::setHealthLED(const std::string& path)
|
||||
+{
|
||||
+ if constexpr (debug) {
|
||||
+ std::cout << "setHealthLED path: " << path << std::endl;
|
||||
+ }
|
||||
+
|
||||
+ std::vector<Association> associations;
|
||||
+ associations.emplace_back("", "dimmfault", path.c_str());
|
||||
+
|
||||
+ faultMonitorAssociation->set_property("Associations", associations);
|
||||
+}
|
||||
+
|
||||
+void Add::unsetHealthLED(const std::string& path)
|
||||
+{
|
||||
+ if constexpr (debug) {
|
||||
+ std::cout << "unsetHealthLED path: " << path << std::endl;
|
||||
+ }
|
||||
+
|
||||
+ std::vector<Association> associations;
|
||||
+ associations.emplace_back("", "", path.c_str());
|
||||
+
|
||||
+ faultMonitorAssociation->set_property("Associations", associations);
|
||||
+}
|
||||
+
|
||||
+void Add::updateDimmLed(int cpuId, int dimmRank, std::string ledState)
|
||||
+{
|
||||
+ int ret = -1;
|
||||
+ std::string i2cBus = "/dev/i2c-5";
|
||||
+
|
||||
+ if constexpr (debug) {
|
||||
+ std::cout << "cpuId: " << cpuId << " dimmrank: " << dimmRank << " ledState: " << ledState <<std::endl;
|
||||
+ }
|
||||
+
|
||||
+ uint8_t preset = (cpuId * 12 + dimmRank) / 8;
|
||||
+ if(preset >= 3)
|
||||
+ {
|
||||
+ std::cerr << " fail to update Dimm LED, invalid preset. \n";
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ uint8_t port = ((cpuId * 12 + dimmRank) % 8) / 4;
|
||||
+ if(port >= 2)
|
||||
+ {
|
||||
+ std::cerr << " fail to update Dimm LED, invalid port. \n";
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ uint8_t ledSlot = ((cpuId * 12 + dimmRank) % 8) % 4;
|
||||
+
|
||||
+ std::vector<uint8_t> writeData{regOutput[port]};
|
||||
+ std::vector<uint8_t> readBuf(1);
|
||||
+ ret = i2cWriteRead(i2cBus, i2cAddrs[preset], writeData, readBuf);
|
||||
+ if (ret < 0)
|
||||
+ goto err;
|
||||
+
|
||||
+ uint8_t wdata;
|
||||
+ if(ledState == "ON")
|
||||
+ wdata = (readBuf[0] & SET_GREEN_LED(ledSlot)) | UNSET_RED_LED(ledSlot);
|
||||
+ else if(ledState == "FAULT")
|
||||
+ wdata = (readBuf[0] & SET_RED_LED(ledSlot)) | UNSET_GREEN_LED(ledSlot);
|
||||
+ else if(ledState == "OFF")
|
||||
+ wdata = readBuf[0] | SET_LED_OFF(ledSlot);
|
||||
+ else if(ledState == "WAR")
|
||||
+ wdata = readBuf[0] | SET_LED_OFF(ledSlot);
|
||||
+ else
|
||||
+ std::cerr << " Invalid DIMM CPU" << cpuId << " rank" << dimmRank << " LED State " << ledState << "\n";
|
||||
+
|
||||
+ writeData.push_back(wdata);
|
||||
+ readBuf.resize(0);
|
||||
+ ret = i2cWriteRead(i2cBus, i2cAddrs[preset], writeData, readBuf);
|
||||
+ if (ret < 0)
|
||||
+ goto err;
|
||||
+
|
||||
+ return;
|
||||
+
|
||||
+err:
|
||||
+ std::cerr << "i2c read/write error, update DIMM led failed. \n";
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+void Add::dimmLEDMatchHandler(sdbusplus::message_t& msg)
|
||||
+{
|
||||
+ // Get the ObjectPath of the `xyz.openbmc_project.Inventory.Manager`
|
||||
+ // service
|
||||
+ int cpuId, dimmrank;
|
||||
+ std::pair<std::string, std::string> dimmSensorLEDStatus;
|
||||
+ std::string* ledState;
|
||||
+ std::string dimmTempSensorPath = msg.get_path();
|
||||
+
|
||||
+ std::string dimmTempSenName = getFileName(dimmTempSensorPath);
|
||||
+ if(dimmTempSenName != "" && dimmTempSenName.find("DIMM_CPU") != std::string::npos)
|
||||
+ {
|
||||
+ std::regex regex(R"(CPU(\d+)_([A-Z]))");
|
||||
+ std::smatch match;
|
||||
+
|
||||
+ if (std::regex_search(dimmTempSenName, match, regex)) {
|
||||
+ cpuId = std::stoi(match[1].str());
|
||||
+ dimmrank = match[2].str()[0] - 'A';
|
||||
+ }
|
||||
+ } else {
|
||||
+ lg2::error(
|
||||
+ "Faild to get the DIMM temp sensor path, PATH = {PATH}",
|
||||
+ "PATH", dimmTempSensorPath);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // Get all the properties of
|
||||
+ // "xyz.openbmc_project.State.Decorator.OperationalStatus" interface
|
||||
+ std::string interfaceName{};
|
||||
+ std::unordered_map<std::string, std::variant<std::string>> properties;
|
||||
+ msg.read(interfaceName, properties);
|
||||
+
|
||||
+ const auto it = properties.find("LEDState");
|
||||
+ if (it != properties.end())
|
||||
+ {
|
||||
+ ledState = std::get_if<std::string>(&it->second);
|
||||
+ if (!ledState)
|
||||
+ {
|
||||
+ lg2::error(
|
||||
+ "Faild to get the Functional property, INVENTORY_PATH = {PATH}",
|
||||
+ "PATH", dimmTempSensorPath);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ dimmSensorLEDStatus.first = dimmTempSensorPath;
|
||||
+ dimmSensorLEDStatus.second = *ledState;
|
||||
+
|
||||
+ updateDimmLed(cpuId, dimmrank, *ledState);
|
||||
+
|
||||
+ updateSysHealthLED(dimmSensorLEDStatus);
|
||||
+}
|
||||
+
|
||||
void getLoggingSubTree(sdbusplus::bus_t& bus, MapperResponseType& subtree)
|
||||
{
|
||||
auto depth = 0;
|
||||
@@ -653,6 +948,18 @@ void getLoggingSubTree(sdbusplus::bus_t& bus, MapperResponseType& subtree)
|
||||
}
|
||||
}
|
||||
|
||||
+void Add::createAssociation(sdbusplus::asio::object_server& objectServer)
|
||||
+{
|
||||
+ // Associations interface for led status
|
||||
+ std::vector<Association> associations;
|
||||
+ associations.emplace_back("", "", "");
|
||||
+
|
||||
+ faultMonitorAssociation = objectServer.add_interface(
|
||||
+ monitorPath, associationPath);
|
||||
+ faultMonitorAssociation->register_property("Associations", associations);
|
||||
+ faultMonitorAssociation->initialize();
|
||||
+}
|
||||
+
|
||||
void Add::processExistingCallouts(sdbusplus::bus_t& bus)
|
||||
{
|
||||
MapperResponseType mapperResponse;
|
||||
diff --git a/fault-monitor/fru-fault-monitor.hpp b/fault-monitor/fru-fault-monitor.hpp
|
||||
index 065e8c8..bd4a852 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.hpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.hpp
|
||||
@@ -4,9 +4,18 @@
|
||||
|
||||
#include <sdbusplus/bus.hpp>
|
||||
#include <sdbusplus/server.hpp>
|
||||
+#include <sdbusplus/asio/connection.hpp>
|
||||
+#include <sdbusplus/asio/object_server.hpp>
|
||||
+#include <boost/asio/io_context.hpp>
|
||||
+#include <boost/container/flat_map.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
+#include <regex>
|
||||
+#include <vector>
|
||||
+
|
||||
+constexpr const bool debug = false;
|
||||
+
|
||||
namespace phosphor
|
||||
{
|
||||
namespace led
|
||||
@@ -17,6 +26,25 @@ namespace fault
|
||||
{
|
||||
namespace monitor
|
||||
{
|
||||
+constexpr auto faultLedPath = "/xyz/openbmc_project/led/groups/status_fault";
|
||||
+constexpr auto dimmfaultLedPath = "/xyz/openbmc_project/led/groups/dimm_fault";
|
||||
+constexpr auto okLedPath = "/xyz/openbmc_project/led/groups/status_ok";
|
||||
+constexpr auto ledIface = "xyz.openbmc_project.Led.Group";
|
||||
+constexpr auto ledAssertProp = "Asserted";
|
||||
+constexpr auto ledManagerBusname = "xyz.openbmc_project.LED.GroupManager";
|
||||
+constexpr auto DIMMTempSensorBusname = "xyz.openbmc_project.DIMMTempSensor";
|
||||
+constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
|
||||
+constexpr auto dimmLEDInterface = "xyz.openbmc_project.Sensor.dimmLED";
|
||||
+constexpr auto dimmSensorPath = "/xyz/openbmc_project/sensors/temperature";
|
||||
+constexpr auto monitorPath = "/xyz/openbmc_project/led/fault/monitor";
|
||||
+constexpr auto callbackMgrPath = "/xyz/openbmc_project/CallbackManager";
|
||||
+constexpr auto associationPath = "xyz.openbmc_project.Association.Definitions";
|
||||
+
|
||||
+using Association = std::tuple<std::string, std::string, std::string>;
|
||||
+
|
||||
+const std::vector<uint8_t> i2cAddrs = {0x20, 0x21, 0x22};
|
||||
+const std::vector<uint8_t> regConfig = {0x06, 0x07};
|
||||
+const std::vector<uint8_t> regOutput = {0x02, 0x03};
|
||||
|
||||
/** @brief Assert or deassert an LED based on the input FRU
|
||||
* @param[in] bus - The Dbus bus object
|
||||
@@ -117,31 +145,61 @@ class Add
|
||||
/** @brief constructs Add a watch for FRU faults.
|
||||
* @param[in] bus - The Dbus bus object
|
||||
*/
|
||||
- explicit Add(sdbusplus::bus_t& bus) :
|
||||
- bus(bus), matchCreated(bus,
|
||||
- sdbusplus::bus::match::rules::interfacesAdded() +
|
||||
- sdbusplus::bus::match::rules::path_namespace(
|
||||
- "/xyz/openbmc_project/logging"),
|
||||
- std::bind(std::mem_fn(&Add::created), this,
|
||||
- std::placeholders::_1))
|
||||
+
|
||||
+ explicit Add(sdbusplus::bus_t& bus, sdbusplus::asio::object_server& objectServer) :
|
||||
+ bus(bus),
|
||||
+ matchCreated(bus,
|
||||
+ sdbusplus::bus::match::rules::interfacesAdded() +
|
||||
+ sdbusplus::bus::match::rules::path_namespace(
|
||||
+ "/xyz/openbmc_project/logging"),
|
||||
+ std::bind(std::mem_fn(&Add::created), this,
|
||||
+ std::placeholders::_1)),
|
||||
+ dimmLEDMatch(bus,
|
||||
+ "type='signal',member='PropertiesChanged',path_namespace='" +
|
||||
+ std::string(dimmSensorPath) + "',arg0namespace='" +
|
||||
+ std::string(dimmLEDInterface) + "'",
|
||||
+ std::bind(std::mem_fn(&Add::dimmLEDMatchHandler), this,
|
||||
+ std::placeholders::_1))
|
||||
{
|
||||
+
|
||||
+ createAssociation(objectServer);
|
||||
+ dimmledInit();
|
||||
processExistingCallouts(bus);
|
||||
}
|
||||
|
||||
+
|
||||
private:
|
||||
sdbusplus::bus::bus& bus;
|
||||
/** @brief sdbusplus signal match for fault created */
|
||||
sdbusplus::bus::match_t matchCreated;
|
||||
|
||||
+ sdbusplus::bus::match_t dimmLEDMatch;
|
||||
+
|
||||
std::vector<std::unique_ptr<Remove>> removeWatches;
|
||||
|
||||
+ std::shared_ptr<sdbusplus::asio::dbus_interface> faultMonitorAssociation;
|
||||
+
|
||||
/** @brief Callback function for fru fault created
|
||||
* @param[in] msg - Data associated with subscribed signal
|
||||
*/
|
||||
void created(sdbusplus::message_t& msg);
|
||||
|
||||
+ void dimmLEDMatchHandler(sdbusplus::message_t& msg);
|
||||
+
|
||||
void filterSEL(sdbusplus::bus::bus& bus, const std::string& path);
|
||||
|
||||
+ void dimmledInit();
|
||||
+
|
||||
+ void updateDimmLed(int cpuId, int dimmRank, std::string ledState);
|
||||
+
|
||||
+ void updateSysHealthLED(std::pair<std::string, std::string>& pair);
|
||||
+
|
||||
+ void setHealthLED(const std::string& path);
|
||||
+
|
||||
+ void unsetHealthLED(const std::string& path);
|
||||
+
|
||||
+ void createAssociation(sdbusplus::asio::object_server& objectServer);
|
||||
+
|
||||
/** @brief This function process all callouts at application start
|
||||
* @param[in] bus - The Dbus bus object
|
||||
*/
|
||||
diff --git a/fault-monitor/meson.build b/fault-monitor/meson.build
|
||||
index 39ec458..7ced362 100644
|
||||
--- a/fault-monitor/meson.build
|
||||
+++ b/fault-monitor/meson.build
|
||||
@@ -17,7 +17,10 @@ executable(
|
||||
'phosphor-fru-fault-monitor',
|
||||
fault_monitor_sources,
|
||||
include_directories: ['.', '../'],
|
||||
- dependencies: deps,
|
||||
+ dependencies: [
|
||||
+ deps,
|
||||
+ i2c,
|
||||
+ ],
|
||||
install: true,
|
||||
install_dir: get_option('bindir')
|
||||
)
|
||||
diff --git a/fault-monitor/monitor-main.cpp b/fault-monitor/monitor-main.cpp
|
||||
index 92b332d..3083c13 100644
|
||||
--- a/fault-monitor/monitor-main.cpp
|
||||
+++ b/fault-monitor/monitor-main.cpp
|
||||
@@ -6,15 +6,24 @@
|
||||
#include "fru-fault-monitor.hpp"
|
||||
#endif
|
||||
|
||||
+constexpr auto busName = "xyz.openbmc_project.led.fault.monitor";
|
||||
+
|
||||
int main(void)
|
||||
{
|
||||
+ boost::asio::io_context io;
|
||||
+ auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
|
||||
+ systemBus->request_name(busName);
|
||||
+
|
||||
+ sdbusplus::asio::object_server server =
|
||||
+ sdbusplus::asio::object_server(systemBus);
|
||||
+
|
||||
/** @brief Dbus constructs used by Fault Monitor */
|
||||
- sdbusplus::bus_t bus = sdbusplus::bus::new_default();
|
||||
+ sdbusplus::bus_t& bus = static_cast<sdbusplus::bus_t&>(*systemBus);
|
||||
|
||||
#ifdef MONITOR_OPERATIONAL_STATUS
|
||||
phosphor::led::Operational::status::monitor::Monitor monitor(bus);
|
||||
#else
|
||||
- phosphor::led::fru::fault::monitor::Add monitor(bus);
|
||||
+ phosphor::led::fru::fault::monitor::Add monitor(bus, server);
|
||||
#endif
|
||||
/** @brief Wait for client requests */
|
||||
while (true)
|
||||
diff --git a/meson.build b/meson.build
|
||||
index f1a65a8..bf5fc76 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -31,6 +31,8 @@ phosphor_logging_dep = dependency('phosphor-logging')
|
||||
prog_python = find_program('python3', required: true)
|
||||
realpath_prog = find_program('realpath')
|
||||
|
||||
+i2c = meson.get_compiler('cpp').find_library('i2c')
|
||||
+
|
||||
cpp = meson.get_compiler('cpp')
|
||||
if cpp.has_header('nlohmann/json.hpp')
|
||||
nlohmann_json_dep = declare_dependency()
|
||||
--
|
||||
2.34.1
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
diff --git a/fault-monitor/fru-fault-monitor.cpp b/fault-monitor/fru-fault-monitor.cpp
|
||||
index 3c63735..d5d6703 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.cpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.cpp
|
||||
@@ -181,7 +181,7 @@ static void setDiscreteSensorStatusValue(sdbusplus::bus::bus& bus,
|
||||
// ipmi spec 42.2 set the sensor-specific offset
|
||||
double statusValue = reserved;
|
||||
|
||||
- constexpr auto service = "xyz.openbmc_project.dissen";
|
||||
+ constexpr auto service = "xyz.openbmc_project.EntityManager";
|
||||
constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
|
||||
constexpr auto statusInterface = "xyz.openbmc_project.Configuration.Status";
|
||||
|
||||
@@ -487,11 +487,6 @@ void Add::filterSEL(sdbusplus::bus::bus& bus, const std::string& path)
|
||||
if (std::string::npos != nStr)
|
||||
{
|
||||
sensorPath = item.substr(nStr + strlen("SENSOR_PATH="));
|
||||
- std::string sensorPathTmp = sensorPath;
|
||||
- size_t pos = sensorPathTmp.rfind('/');
|
||||
- if (pos != std::string::npos){
|
||||
- sensorPath = "/xyz/openbmc_project/sensors/status/" + sensorPathTmp.substr(pos + 1);
|
||||
- }
|
||||
std::cerr << "sensorPath " << sensorPath <<"\n";
|
||||
}
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
From 757268065e51263dc760951c535e53f76dac2ffe Mon Sep 17 00:00:00 2001
|
||||
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
|
||||
Date: Wed, 23 Oct 2024 13:29:51 +0800
|
||||
Subject: [PATCH 2/2] Add power button and PSU status sensor
|
||||
|
||||
---
|
||||
fault-monitor/fru-fault-monitor.cpp | 28 +++++++++++++++++
|
||||
fault-monitor/fru-fault-monitor.hpp | 48 +++++++++++++++++++++++++++--
|
||||
2 files changed, 74 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fault-monitor/fru-fault-monitor.cpp b/fault-monitor/fru-fault-monitor.cpp
|
||||
index 8ff5294..4946065 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.cpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.cpp
|
||||
@@ -55,6 +55,11 @@ constexpr const char* discreteSensorNs = "No state defined";
|
||||
// 10H
|
||||
constexpr auto SYSTEM_EVENT_LOG_CLEARED = 2;
|
||||
|
||||
+// 14H
|
||||
+constexpr auto POWER_BUTTON_PRESSED = 0;
|
||||
+constexpr auto SLEEP_BUTTON_PRESSED = 1;
|
||||
+constexpr auto RESET_BUTTON_PRESSED = 2;
|
||||
+
|
||||
// 22H
|
||||
constexpr auto ACPI_S0_STATE = 0;
|
||||
constexpr auto ACPI_S5_STATE = 6;
|
||||
@@ -389,6 +394,29 @@ void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
}
|
||||
break;
|
||||
}
|
||||
+ case SENSOR_TYPE_BUTTON_SWITCH:
|
||||
+ {
|
||||
+ switch (ev1Offset)
|
||||
+ {
|
||||
+ case POWER_BUTTON_PRESSED:
|
||||
+ case SLEEP_BUTTON_PRESSED:
|
||||
+ case RESET_BUTTON_PRESSED:
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ case SENSOR_TYPE_POWER_SUPPLY:
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
+ break;
|
||||
+ }
|
||||
case SENSOR_TYPE_SYSTEM_ACPI_POWER_STATE:
|
||||
{
|
||||
switch (ev1Offset)
|
||||
diff --git a/fault-monitor/fru-fault-monitor.hpp b/fault-monitor/fru-fault-monitor.hpp
|
||||
index e196287..065e8c8 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.hpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.hpp
|
||||
@@ -32,9 +32,54 @@ class Remove;
|
||||
*/
|
||||
enum SensorType
|
||||
{
|
||||
+ SENSOR_TYPE_TEMPERATURE = 0x01,
|
||||
+ SENSOR_TYPE_VOLTAGE = 0x02,
|
||||
+ SENSOR_TYPE_CURRENT = 0x03,
|
||||
+ SENSOR_TYPE_FAN = 0x04,
|
||||
+ SENSOR_TYPE_PHYSICAL_SECURITY = 0x05,
|
||||
+ SENSOR_TYPE_PLATFORM_SECURITY = 0x06,
|
||||
+ SENSOR_TYPE_PROCESSOR = 0x07,
|
||||
+ SENSOR_TYPE_POWER_SUPPLY = 0x08,
|
||||
+ SENSOR_TYPE_POWER_FAULT = 0x09,
|
||||
+ SENSOR_TYPE_COOLING_DEVICE = 0x0A,
|
||||
+ SENSOR_TYPE_OHTER_UNITE_BASED_SENSOR = 0x0B,
|
||||
+ SENSOR_TYPE_MEMORY = 0x0C,
|
||||
+ SENSOR_TYPE_DRIVE_SLOT = 0x0D,
|
||||
+
|
||||
+ SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS = 0x0F, // formerly POST error
|
||||
SENSOR_TYPE_EVENT_LOGGING_DISABLED = 0x10,
|
||||
+ SENSOR_TYPE_WATCHDOG_1 = 0x11,
|
||||
+ SENSOR_TYPE_SYSTEM_EVENT = 0x12,
|
||||
+ SENSOR_TYPE_CRITICAL_INTERRUPT = 0x13,
|
||||
+ SENSOR_TYPE_BUTTON_SWITCH = 0x14,
|
||||
+ SENSOR_TYPE_BOARD_MODULE = 0x15,
|
||||
+ SENSOR_TYPE_MICROCONTROLLER_COPROCESSOR = 0x16,
|
||||
+ SENSOR_TYPE__RESOURCERATE = 0xC1, // jss
|
||||
+
|
||||
+ SENSOR_TYPE_ADD_IN_CARD = 0x17,
|
||||
+ SENSOR_TYPE_CHASSIS = 0x18,
|
||||
+ SENSOR_TYPE_CHIP_SET = 0x19,
|
||||
+
|
||||
+ SENSOR_TYPE_CABLE_INTERCONNECT = 0x1B,
|
||||
+
|
||||
+ SENSOR_TYPE_SYSTEM_BOOT = 0x1D, // Restart Initiated
|
||||
+ SENSOR_TYPE_BOOT_ERROR = 0x1E,
|
||||
+ SENSOR_TYPE_OS_BOOT = 0x1F,
|
||||
+ SENSOR_TYPE_OS_STOP = 0x20,
|
||||
+ SENSOR_TYPE_SLOT_CONNECTOR = 0x21,
|
||||
SENSOR_TYPE_SYSTEM_ACPI_POWER_STATE = 0x22,
|
||||
- SENSOR_TYPE_MEMORY = 0x0C,
|
||||
+ SENSOR_TYPE_WATCHDOG_2 = 0x23,
|
||||
+ SENSOR_TYPE_PLATFORM_ALERT = 0x24,
|
||||
+ SENSOR_TYPE_ENTITY_PRESENCE = 0x25,
|
||||
+
|
||||
+ SENSOR_TYPE_LAN = 0x27,
|
||||
+ SENSOR_TYPE_MANAGEMENT_SUBSYSTEM_HEALTH = 0x28,
|
||||
+ SENSOR_TYPE_BATTERY = 0x29,
|
||||
+ SENSOR_TYPE_SESSION_AUDIT = 0x2A,
|
||||
+ SENSOR_TYPE_HYPERCARD = 0xC0,
|
||||
+
|
||||
+ SENSOR_TYPE_VERSION_CHANGE = 0x2B,
|
||||
+ SENSOR_TYPE_FRU_STATE = 0x2C,
|
||||
SENSOR_TYPE_MAX_NUMBER = 0x100 // Senor Type 为1个byte,最大为0~255,即:256个
|
||||
};
|
||||
|
||||
@@ -80,7 +125,6 @@ class Add
|
||||
std::bind(std::mem_fn(&Add::created), this,
|
||||
std::placeholders::_1))
|
||||
{
|
||||
- std::cerr << "wangbin matchCreated \n";
|
||||
processExistingCallouts(bus);
|
||||
}
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
Executable
+253
@@ -0,0 +1,253 @@
|
||||
From d8b014ef95adfc1ec2d336968cd60c5961ec9824 Mon Sep 17 00:00:00 2001
|
||||
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
|
||||
Date: Fri, 25 Oct 2024 15:46:54 +0800
|
||||
Subject: [PATCH 3/3] Add BMC Boot sensor
|
||||
|
||||
---
|
||||
fault-monitor/fru-fault-monitor.cpp | 191 +++++++++++++++++++++++++++-
|
||||
1 file changed, 186 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/fault-monitor/fru-fault-monitor.cpp b/fault-monitor/fru-fault-monitor.cpp
|
||||
index 03e1700..2e99e45 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.cpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.cpp
|
||||
@@ -69,18 +69,99 @@ using InvalidArgumentErr =
|
||||
|
||||
constexpr const char* discreteSensorNs = "No state defined";
|
||||
|
||||
+/*discrete sensor specific offset*/
|
||||
+// 07H
|
||||
+constexpr auto IPMI_CPU_IERR = 0;
|
||||
+constexpr auto IPMI_CPU_THERMALTRIP = 1;
|
||||
+constexpr auto IPMI_CPU_FBR1_BIST_FAILURE = 2;
|
||||
+constexpr auto IPMI_CPU_FRB2_HANG = 3;
|
||||
+constexpr auto IPMI_CPU_FRB3_STARTUP_FAILURE = 4;
|
||||
+constexpr auto IPMI_CPU_CONFIG_ERROR = 5;
|
||||
+constexpr auto IPMI_CPU_SMBIOS_UC_ERROR = 6;
|
||||
+constexpr auto IPMI_CPU_PRESENT = 7;
|
||||
+constexpr auto IPMI_CPU_DISABLED = 8;
|
||||
+constexpr auto IPMI_CPU_THROTTLED = 10;
|
||||
+constexpr auto IPMI_CPU_MCE = 11;
|
||||
+constexpr auto IPMI_CPU_CMCE = 12;
|
||||
+
|
||||
+// 08H
|
||||
+constexpr auto POWER_SUPPLY_PRESENT = 0;
|
||||
+constexpr auto POWER_SUPPLY_FAILURE = 1;
|
||||
+constexpr auto POWER_SUPPLY_PREDICTIVE_FAILURE = 2;
|
||||
+constexpr auto POWER_SUPPLY_AC_LOST = 3;
|
||||
+constexpr auto POWER_SUPPLY_AC_OUT_OF_RANGE = 5;
|
||||
+constexpr auto POWER_SUPPLY_CONFIG_ERROR = 6;
|
||||
+
|
||||
+// 0CH
|
||||
+constexpr auto MEMORY_OFFSET_CORRECTABLE_ECC = 0;
|
||||
+constexpr auto MEMORY_OFFSET_UNCORRECTABLE_ECC = 1;
|
||||
+constexpr auto MEMORY_OFFSET_PARITY = 2;
|
||||
+constexpr auto MEMORY_OFFSET_MEMORY_SCRUB_FAILED = 3;
|
||||
+constexpr auto MEMORY_OFFSET_MEMORY_DEVICE_DISABLED = 4;
|
||||
+constexpr auto MEMORY_OFFSET_CORRECTABLE_ECC_LOG_LIMIT_REACHED = 5;
|
||||
+constexpr auto MEMORY_OFFSET_PRESENCE_DETECTED = 6;
|
||||
+constexpr auto MEMORY_OFFSET_CONFIGURATION_ERROR = 7;
|
||||
+constexpr auto MEMORY_OFFSET_SPARE = 8;
|
||||
+constexpr auto MEMORY_OFFSET_MEMORY_AUTOMATICALLY_THROTTLED = 9;
|
||||
+constexpr auto MEMORY_OFFSET_CRITICAL_OVER_TEMMPERATURE = 10;
|
||||
+
|
||||
+// 0FH
|
||||
+constexpr auto SYSTEM_FIRMWARE_PROGRESS_OFFSET_ERROR = 0;
|
||||
+constexpr auto SYSTEM_FIRMWARE_PROGRESS_OFFSET_HANG = 1;
|
||||
+
|
||||
+// 0DH
|
||||
+constexpr auto DRIVE_OFFSET_PRESENT = 0;
|
||||
+constexpr auto DRIVE_OFFSET_FAULT = 1;
|
||||
+
|
||||
// 10H
|
||||
constexpr auto SYSTEM_EVENT_LOG_CLEARED = 2;
|
||||
|
||||
+// 13H
|
||||
+constexpr auto CRITICAL_INTERRUPT_OFFSET_FRONT_PANEL_NMI = 0;
|
||||
+constexpr auto CRITICAL_INTERRUPT_OFFSET_BUS_TIMEOUT = 1;
|
||||
+constexpr auto CRITICAL_INTERRUPT_OFFSET_IO_CHANNLE_CHECK_NMI = 2;
|
||||
+constexpr auto CRITICAL_INTERRUPT_OFFSET_SOFTWARE_NMI = 3;
|
||||
+constexpr auto CRITICAL_INTERRUPT_OFFSET_PCI_PERR = 4;
|
||||
+constexpr auto CRITICAL_INTERRUPT_OFFSET_PCI_SERR = 5;
|
||||
+constexpr auto CRITICAL_INTERRUPT_OFFSET_EISA_FAIL_SAFE_TIMEOUT = 6;
|
||||
+constexpr auto CRITICAL_INTERRUPT_OFFSET_BUS_CORRECTABLE_ERROR = 7;
|
||||
+constexpr auto CRITICAL_INTERRUPT_OFFSET_BUS_UNCORRECTABLE_ERRPR = 8;
|
||||
+constexpr auto CRITICAL_INTERRUPT_OFFSET_FATAL_NMI = 9;
|
||||
+constexpr auto CRITICAL_INTERRUPT_OFFSET_BUS_FATAL_ERROR = 10;
|
||||
+constexpr auto CRITICAL_INTERRUPT_OFFSET_BUS_DEGRADED = 11;
|
||||
+constexpr auto CRITICAL_INTERRUPT_OFFSET_BANDWITH_REDUCTION = 12;
|
||||
+constexpr auto CRITICAL_INTERRUPT_OFFSET_RATE_REDUCTION = 13;
|
||||
+
|
||||
// 14H
|
||||
constexpr auto POWER_BUTTON_PRESSED = 0;
|
||||
constexpr auto SLEEP_BUTTON_PRESSED = 1;
|
||||
constexpr auto RESET_BUTTON_PRESSED = 2;
|
||||
|
||||
+// 1BH
|
||||
+constexpr auto CABLE_CONNECTED = 0;
|
||||
+constexpr auto CABLE_CONFIG_ERROR = 1;
|
||||
+
|
||||
+// 1DH
|
||||
+constexpr auto INIT_BY_POWER_UP = 0;
|
||||
+constexpr auto INIT_BY_HARD_RESET = 1;
|
||||
+constexpr auto INIT_BY_WARM_RESET = 2;
|
||||
+
|
||||
+// 1EH
|
||||
+constexpr auto NO_BOOTABLE_MEDIA = 0;
|
||||
+constexpr auto NON_BOOTABLE_DISKETTE = 1;
|
||||
+constexpr auto PXE_SERVER_NOT_FOUND = 2;
|
||||
+constexpr auto INVALID_BOOT_SECTOR = 3;
|
||||
+
|
||||
+// 1FH
|
||||
+constexpr auto OS_BOOT_COMPLETE = 6;
|
||||
+
|
||||
// 22H
|
||||
constexpr auto ACPI_S0_STATE = 0;
|
||||
constexpr auto ACPI_S5_STATE = 6;
|
||||
|
||||
+// 2BH
|
||||
+constexpr auto FIRMWARE_UPDATE_SUCCESS = 7;
|
||||
+
|
||||
/*sensor object, SensorStatusInfo*/
|
||||
std::unordered_map<std::string, SensorStatusInfo> sensorStatusRec;
|
||||
std::unordered_map<std::string, std::unordered_map<uint8_t, DriveStatus>> driveStatusRec;
|
||||
@@ -124,15 +205,115 @@ using ipmiSensorsInfo = std::unordered_map<std::string, sensorCodes>;
|
||||
std::optional<ipmiSensorsInfo> ipmiSensors;
|
||||
|
||||
const std::unordered_map<SensorType, discrectSensorEvent> sensorSpecificTypes{
|
||||
+ {SENSOR_TYPE_PROCESSOR,
|
||||
+ {
|
||||
+ {IPMI_CPU_IERR, "IERR"},
|
||||
+ {IPMI_CPU_THERMALTRIP, "Thermal Trip"},
|
||||
+ {IPMI_CPU_FBR1_BIST_FAILURE, "FRB1/BIST failure"},
|
||||
+ {IPMI_CPU_FRB2_HANG, "FRB2/Hang in POST failure"},
|
||||
+ {IPMI_CPU_FRB3_STARTUP_FAILURE, "FRB3/Processor startup/init failure"},
|
||||
+ {IPMI_CPU_CONFIG_ERROR, "Configuration Error"},
|
||||
+ {IPMI_CPU_SMBIOS_UC_ERROR, "SM BIOS Uncorrectable CPU-complex Error"},
|
||||
+ {IPMI_CPU_PRESENT, "Presence detected"},
|
||||
+ {IPMI_CPU_DISABLED, "Disabled"},
|
||||
+ {IPMI_CPU_THROTTLED, "Throttled"},
|
||||
+ {IPMI_CPU_MCE, "Uncorrectable machine check exception"},
|
||||
+ {IPMI_CPU_CMCE, "Correctable machine check error"},
|
||||
+ }},
|
||||
+ {SENSOR_TYPE_POWER_SUPPLY,
|
||||
+ {
|
||||
+ {POWER_SUPPLY_PRESENT, "Presence detected"},
|
||||
+ {POWER_SUPPLY_FAILURE, "Failure detected"},
|
||||
+ {POWER_SUPPLY_PREDICTIVE_FAILURE, "Predictive failure"},
|
||||
+ {POWER_SUPPLY_AC_LOST, "Power Supply AC lost"},
|
||||
+ {POWER_SUPPLY_AC_OUT_OF_RANGE, "AC out-of-range, but present"},
|
||||
+ {POWER_SUPPLY_CONFIG_ERROR, "Config Error: Vendor Mismatch"},
|
||||
+ }},
|
||||
+ {SENSOR_TYPE_MEMORY,
|
||||
+ {
|
||||
+ {MEMORY_OFFSET_CORRECTABLE_ECC, "Correctable ECC"},
|
||||
+ {MEMORY_OFFSET_UNCORRECTABLE_ECC, "Uncorrectable ECC"},
|
||||
+ {MEMORY_OFFSET_PARITY, "Parity"},
|
||||
+ {MEMORY_OFFSET_MEMORY_SCRUB_FAILED, "Memory Scrub Failed"},
|
||||
+ {MEMORY_OFFSET_MEMORY_DEVICE_DISABLED, "Memory Device Disabled"},
|
||||
+ {MEMORY_OFFSET_CORRECTABLE_ECC_LOG_LIMIT_REACHED,
|
||||
+ "Correctable ECC logging limit reached"},
|
||||
+ {MEMORY_OFFSET_PRESENCE_DETECTED, "Presence Detected"},
|
||||
+ {MEMORY_OFFSET_CONFIGURATION_ERROR, "Configuration Error"},
|
||||
+ {MEMORY_OFFSET_SPARE, "Spare"},
|
||||
+ {MEMORY_OFFSET_MEMORY_AUTOMATICALLY_THROTTLED, "Throttled"},
|
||||
+ {MEMORY_OFFSET_CRITICAL_OVER_TEMMPERATURE, "Critical Overtemperature"},
|
||||
+ }},
|
||||
+ {SENSOR_TYPE_DRIVE_SLOT,
|
||||
+ {
|
||||
+ {DRIVE_OFFSET_PRESENT, "Drive Present"},
|
||||
+ {DRIVE_OFFSET_FAULT, "Drive Fault"},
|
||||
+ }},
|
||||
+ {SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS,
|
||||
+ {
|
||||
+ {SYSTEM_FIRMWARE_PROGRESS_OFFSET_ERROR, "System Firmware Error"},
|
||||
+ {SYSTEM_FIRMWARE_PROGRESS_OFFSET_HANG, "System Firmware Hang"},
|
||||
+ }},
|
||||
+ {SENSOR_TYPE_EVENT_LOGGING_DISABLED,
|
||||
+ {
|
||||
+ {SYSTEM_EVENT_LOG_CLEARED, "Log area reset/cleared"},
|
||||
+ }},
|
||||
+ {SENSOR_TYPE_CRITICAL_INTERRUPT,
|
||||
+ {
|
||||
+ {CRITICAL_INTERRUPT_OFFSET_FRONT_PANEL_NMI, "NMI/Diag Interrupt"},
|
||||
+ {CRITICAL_INTERRUPT_OFFSET_BUS_TIMEOUT, "Bus Timeout"},
|
||||
+ {CRITICAL_INTERRUPT_OFFSET_IO_CHANNLE_CHECK_NMI,
|
||||
+ "I/O Channel check NMI"},
|
||||
+ {CRITICAL_INTERRUPT_OFFSET_SOFTWARE_NMI, "Software NMI"},
|
||||
+ {CRITICAL_INTERRUPT_OFFSET_PCI_PERR, "PCI PERR"},
|
||||
+ {CRITICAL_INTERRUPT_OFFSET_PCI_SERR, "PCI SERR"},
|
||||
+ {CRITICAL_INTERRUPT_OFFSET_EISA_FAIL_SAFE_TIMEOUT,
|
||||
+ "EISA failsafe timeout"},
|
||||
+ {CRITICAL_INTERRUPT_OFFSET_BUS_CORRECTABLE_ERROR,
|
||||
+ "Bus Correctable error"},
|
||||
+ {CRITICAL_INTERRUPT_OFFSET_BUS_UNCORRECTABLE_ERRPR,
|
||||
+ "Bus Uncorrectable error"},
|
||||
+ {CRITICAL_INTERRUPT_OFFSET_FATAL_NMI, "Fatal NMI"},
|
||||
+ {CRITICAL_INTERRUPT_OFFSET_BUS_FATAL_ERROR, "Bus Fatal Error"},
|
||||
+ {CRITICAL_INTERRUPT_OFFSET_BUS_DEGRADED, "Bus Degraded"},
|
||||
+ }},
|
||||
+ {SENSOR_TYPE_BUTTON_SWITCH,
|
||||
+ {
|
||||
+ {POWER_BUTTON_PRESSED, "Power Button pressed"},
|
||||
+ {SLEEP_BUTTON_PRESSED, "Sleep Button pressed"},
|
||||
+ {RESET_BUTTON_PRESSED, "Reset Button pressed"},
|
||||
+ }},
|
||||
+ {SENSOR_TYPE_CABLE_INTERCONNECT,
|
||||
+ {
|
||||
+ {CABLE_CONNECTED, "Connected"},
|
||||
+ {CABLE_CONFIG_ERROR, "Config Error"},
|
||||
+ }},
|
||||
+ {SENSOR_TYPE_SYSTEM_BOOT,
|
||||
+ {
|
||||
+ {INIT_BY_POWER_UP, "Initiated by power up"},
|
||||
+ {INIT_BY_HARD_RESET, "Initiated by hard reset"},
|
||||
+ {INIT_BY_WARM_RESET, "Initiated by warm reset"},
|
||||
+ }},
|
||||
+ {SENSOR_TYPE_BOOT_ERROR,
|
||||
+ {
|
||||
+ {NO_BOOTABLE_MEDIA, "No bootable media"},
|
||||
+ {NON_BOOTABLE_DISKETTE, "Non-bootable disk in drive"},
|
||||
+ {PXE_SERVER_NOT_FOUND, "PXE server not found"},
|
||||
+ {INVALID_BOOT_SECTOR, "Invalid boot sector"},
|
||||
+ }},
|
||||
+ {SENSOR_TYPE_OS_BOOT,
|
||||
+ {
|
||||
+ {OS_BOOT_COMPLETE, "boot completed - device not specified"},
|
||||
+ }},
|
||||
{SENSOR_TYPE_SYSTEM_ACPI_POWER_STATE,
|
||||
{
|
||||
{ACPI_S0_STATE, "S0/G0: working"},
|
||||
{ACPI_S5_STATE, "S4/S5: soft-off"},
|
||||
}},
|
||||
- {SENSOR_TYPE_EVENT_LOGGING_DISABLED,
|
||||
+ {SENSOR_TYPE_VERSION_CHANGE,
|
||||
{
|
||||
- {SYSTEM_EVENT_LOG_CLEARED, "Log area reset/cleared"},
|
||||
- }}
|
||||
+ {FIRMWARE_UPDATE_SUCCESS, "Firmware or software change success"},
|
||||
+ }},
|
||||
};
|
||||
|
||||
std::optional<ipmiSensorsInfo> initIPMISensorInfo(sdbusplus::bus::bus& bus)
|
||||
@@ -214,7 +395,7 @@ static void setDiscreteSensorStatusValue(sdbusplus::bus::bus& bus,
|
||||
auto method = bus.new_method_call(service, sensorPath.c_str(),
|
||||
dbusProperties, "Set");
|
||||
std::variant<double> value{(double)statusValue};
|
||||
-
|
||||
+ std::cerr << "SEL:sensorData = " << sensorData << std::endl;
|
||||
method.append(statusInterface, "Status", value);
|
||||
try
|
||||
{
|
||||
@@ -498,7 +679,7 @@ void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
break;
|
||||
}
|
||||
default:
|
||||
- return;
|
||||
+ break;
|
||||
}
|
||||
sensorStatusRec[sensorPath].eventType = SPECIFIC_SENSOR_TYPE;
|
||||
sensorStatusRec[sensorPath].sensorType = sensorType;
|
||||
--
|
||||
2.25.1
|
||||
|
||||
+501
@@ -0,0 +1,501 @@
|
||||
From 80cb5c7e022af367dd17981f2a0ffe7d5cf4052a Mon Sep 17 00:00:00 2001
|
||||
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
|
||||
Date: Wed, 20 Nov 2024 19:14:14 +0800
|
||||
Subject: [PATCH 4/4] Support discrete generic sensors
|
||||
|
||||
---
|
||||
fault-monitor/fru-fault-monitor.cpp | 393 ++++++++++++++++++++++++++--
|
||||
fault-monitor/fru-fault-monitor.hpp | 3 +-
|
||||
2 files changed, 379 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/fault-monitor/fru-fault-monitor.cpp b/fault-monitor/fru-fault-monitor.cpp
|
||||
index aa7b8cc..737c90d 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.cpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.cpp
|
||||
@@ -69,6 +69,37 @@ using InvalidArgumentErr =
|
||||
|
||||
constexpr const char* discreteSensorNs = "No state defined";
|
||||
|
||||
+enum AlarmType : uint64_t
|
||||
+{
|
||||
+ NORMAL = 0,
|
||||
+ NONCRITICAL = 1,
|
||||
+ CRITICAL = 2,
|
||||
+ NONRECOV = 4,
|
||||
+};
|
||||
+
|
||||
+/*alarms bits: nr, nc, c*/
|
||||
+constexpr auto ALARM_BIT_NUM = 3;
|
||||
+constexpr auto ALARM_ALL_BITS = NONCRITICAL | CRITICAL | NONRECOV;
|
||||
+constexpr uint64_t ALARM_STATUS_MASK_NR = 0x4924924924924924;
|
||||
+constexpr uint64_t ALARM_STATUS_MASK_C = 0x2492492492492492;
|
||||
+constexpr uint64_t ALARM_STATUS_MASK_NC = 0x1249249249249249;
|
||||
+
|
||||
+/*discrete generic offset*/
|
||||
+
|
||||
+constexpr auto EVENT_TYPE_03H_STATE_DEASSERT = 0;
|
||||
+constexpr auto EVENT_TYPE_03H_STATE_ASSERT = 1;
|
||||
+
|
||||
+constexpr auto EVENT_TYPE_07H_TRANSITION_TO_OK = 0;
|
||||
+constexpr auto EVENT_TYPE_07H_TRANSITION_TO_NC_FROM_OK = 1;
|
||||
+
|
||||
+constexpr auto EVENT_TYPE_08H_ABSENT = 0;
|
||||
+constexpr auto EVENT_TYPE_08H_PRESENT = 1;
|
||||
+
|
||||
+constexpr auto EVENT_TYPE_0BH_FULLY_REDUNDANT = 0;
|
||||
+constexpr auto EVENT_TYPE_0BH_REDUNDANT_LOST = 1;
|
||||
+
|
||||
+/*discrete sensor specific offset*/
|
||||
+
|
||||
/*discrete sensor specific offset*/
|
||||
// 07H
|
||||
constexpr auto IPMI_CPU_IERR = 0;
|
||||
@@ -164,16 +195,8 @@ constexpr auto FIRMWARE_UPDATE_SUCCESS = 7;
|
||||
|
||||
/*sensor object, SensorStatusInfo*/
|
||||
std::unordered_map<std::string, SensorStatusInfo> sensorStatusRec;
|
||||
-std::unordered_map<std::string, std::unordered_map<uint8_t, DriveStatus>> driveStatusRec;
|
||||
-
|
||||
-
|
||||
-enum AlarmType
|
||||
-{
|
||||
- NORMAL = 0,
|
||||
- NONCRITICAL = 1,
|
||||
- CRITICAL = 2,
|
||||
- NONRECOV = 4,
|
||||
-};
|
||||
+std::unordered_map<std::string, std::unordered_map<uint8_t, SensorStatus>> driveStatusRec;
|
||||
+std::unordered_map<uint8_t, SensorStatus> powerFaultStatusRec;
|
||||
|
||||
struct SelSeverityInfo
|
||||
{
|
||||
@@ -204,6 +227,30 @@ using sensorCodes = std::vector<uint8_t>;
|
||||
using ipmiSensorsInfo = std::unordered_map<std::string, sensorCodes>;
|
||||
std::optional<ipmiSensorsInfo> ipmiSensors;
|
||||
|
||||
+const std::unordered_map<uint8_t, discrectSensorEvent> genericEventTypes{
|
||||
+ {0x03,
|
||||
+ {
|
||||
+ {EVENT_TYPE_03H_STATE_DEASSERT, "State Deasserted"},
|
||||
+ {EVENT_TYPE_03H_STATE_ASSERT, "State Asserted"},
|
||||
+ }},
|
||||
+ {0x07,
|
||||
+ {
|
||||
+ {EVENT_TYPE_07H_TRANSITION_TO_OK, "Transition to OK"},
|
||||
+ {EVENT_TYPE_07H_TRANSITION_TO_NC_FROM_OK,
|
||||
+ "Transition to Non-critical from OK"},
|
||||
+ }},
|
||||
+ {0x08,
|
||||
+ {
|
||||
+ {EVENT_TYPE_08H_ABSENT, "Device Absent"},
|
||||
+ {EVENT_TYPE_08H_PRESENT, "Device Present"},
|
||||
+ }},
|
||||
+ {0x0B,
|
||||
+ {
|
||||
+ {EVENT_TYPE_0BH_FULLY_REDUNDANT, "Fully Redundant"},
|
||||
+ {EVENT_TYPE_0BH_REDUNDANT_LOST, "Redundancy Lost"},
|
||||
+ }},
|
||||
+};
|
||||
+
|
||||
const std::unordered_map<SensorType, discrectSensorEvent> sensorSpecificTypes{
|
||||
{SENSOR_TYPE_PROCESSOR,
|
||||
{
|
||||
@@ -316,6 +363,15 @@ const std::unordered_map<SensorType, discrectSensorEvent> sensorSpecificTypes{
|
||||
}},
|
||||
};
|
||||
|
||||
+static const std::unordered_map<std::string, std::vector<uint8_t>>
|
||||
+ flipStateSel = {
|
||||
+ {"Redundant_PSU",
|
||||
+ {EVENT_TYPE_0BH_FULLY_REDUNDANT, EVENT_TYPE_0BH_REDUNDANT_LOST}},
|
||||
+ {"SYS_FAN_Status",
|
||||
+ {EVENT_TYPE_07H_TRANSITION_TO_OK,
|
||||
+ EVENT_TYPE_07H_TRANSITION_TO_NC_FROM_OK}},
|
||||
+};
|
||||
+
|
||||
std::optional<ipmiSensorsInfo> initIPMISensorInfo(sdbusplus::bus::bus& bus)
|
||||
{
|
||||
constexpr auto service = "xyz.openbmc_project.Ipmi.Host";
|
||||
@@ -557,13 +613,192 @@ enum
|
||||
{
|
||||
UNSPECIFY_SENSOR_TYPE = 0x00,
|
||||
THRESHOLD_SENSOR_TYPE = 0x01,
|
||||
- GENERIC_S_SENSOR_TYPE = 0x02,
|
||||
- GENERIC_E_SENSOR_TYPE = 0x0C,
|
||||
+ GENERIC_START_SENSOR_TYPE = 0x02,
|
||||
+ GENERIC_END_SENSOR_TYPE = 0x0C,
|
||||
SPECIFIC_SENSOR_TYPE = 0x6F,
|
||||
- OEM_S_SENSOR_TYPE = 0x70,
|
||||
- OEM_E_SENSOR_TYPE = 0x7F
|
||||
+ OEM_START_SENSOR_TYPE = 0x70,
|
||||
+ OEM_END_SENSOR_TYPE = 0x7F
|
||||
+};
|
||||
+
|
||||
+inline void recordAlarmStatus(const std::string& sensorPath,
|
||||
+ AlarmType alarmStatus, int evOffset, int ed,
|
||||
+ bool assertAlarm,
|
||||
+ const bool& isGenericDiscreteSensor)
|
||||
+{
|
||||
+ uint64_t statusBit = static_cast<uint64_t>(alarmStatus);
|
||||
+
|
||||
+ std::string sensorName{sensorPath};
|
||||
+ size_t lastPos = sensorPath.find_last_of('/');
|
||||
+ if (lastPos != std::string::npos)
|
||||
+ {
|
||||
+ // Get sensor name from the sensor full path
|
||||
+ sensorName = sensorPath.substr(lastPos + 1);
|
||||
+ }
|
||||
+
|
||||
+ if (assertAlarm)
|
||||
+ {
|
||||
+ if (ed != 0)
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].alarmStatus |=
|
||||
+ statusBit << (evOffset * ALARM_BIT_NUM);
|
||||
+
|
||||
+ auto it = flipStateSel.find(sensorName);
|
||||
+ if (it != flipStateSel.end())
|
||||
+ {
|
||||
+ auto eventOffsets = it->second;
|
||||
+ auto targetIt = std::find(eventOffsets.begin(),
|
||||
+ eventOffsets.begin(), evOffset);
|
||||
+ if (targetIt != eventOffsets.end())
|
||||
+ {
|
||||
+ for (const auto& offset : eventOffsets)
|
||||
+ {
|
||||
+ if (offset == evOffset)
|
||||
+ {
|
||||
+ continue;
|
||||
+ }
|
||||
+ sensorStatusRec[sensorPath].alarmStatus &=
|
||||
+ ~(statusBit << (offset * ALARM_BIT_NUM));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].alarmStatus &=
|
||||
+ ~(statusBit << (evOffset * ALARM_BIT_NUM));
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (ed != 0)
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].alarmStatus &=
|
||||
+ ~(statusBit << (evOffset * ALARM_BIT_NUM));
|
||||
+
|
||||
+ auto it = flipStateSel.find(sensorName);
|
||||
+ if (it != flipStateSel.end())
|
||||
+ {
|
||||
+ auto eventOffsets = it->second;
|
||||
+ auto targetIt = std::find(eventOffsets.begin(),
|
||||
+ eventOffsets.end(), evOffset);
|
||||
+ if (targetIt != eventOffsets.end())
|
||||
+ {
|
||||
+ for (const auto& offset : eventOffsets)
|
||||
+ {
|
||||
+ if (offset == evOffset)
|
||||
+ {
|
||||
+ continue;
|
||||
+ }
|
||||
+ sensorStatusRec[sensorPath].alarmStatus &=
|
||||
+ ~(statusBit << (offset * ALARM_BIT_NUM));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].alarmStatus |=
|
||||
+ statusBit << (evOffset * ALARM_BIT_NUM);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (isGenericDiscreteSensor)
|
||||
+ {
|
||||
+ if (ed != 0)
|
||||
+ {
|
||||
+ // Generic discrete sensor's events are mutually exclusive,
|
||||
+ // and at the same time, only one bit of 'sensorStatus' will be set,
|
||||
+ // so there is '=', not '|='
|
||||
+ sensorStatusRec[sensorPath].sensorStatus = 1 << evOffset;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].sensorStatus &= ~(1 << evOffset);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (ed != 0)
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].sensorStatus |= 1 << evOffset;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ sensorStatusRec[sensorPath].sensorStatus &= ~(1 << evOffset);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*record led status and entity manager status*/
|
||||
+inline void recordAlarmStatus(SensorStatus& statusRec,
|
||||
+ const AlarmType& alarmStatus, const int& evOffset,
|
||||
+ const int& ed, const bool& assertAlarm,
|
||||
+ const bool& isGenericDiscreteSensor)
|
||||
+{
|
||||
+ uint64_t statusBit = static_cast<uint64_t>(alarmStatus);
|
||||
+ if (assertAlarm)
|
||||
+ {
|
||||
+ if (ed)
|
||||
+ {
|
||||
+ statusRec.alarmStatus |= statusBit << (evOffset * ALARM_BIT_NUM);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ statusRec.alarmStatus &= ~(statusBit << (evOffset * ALARM_BIT_NUM));
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (ed)
|
||||
+ {
|
||||
+ statusRec.alarmStatus &= ~(statusBit << (evOffset * ALARM_BIT_NUM));
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ statusRec.alarmStatus |= statusBit << (evOffset * ALARM_BIT_NUM);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (isGenericDiscreteSensor)
|
||||
+ {
|
||||
+ if (ed)
|
||||
+ {
|
||||
+ // Generic discrete sensor's events are mutually exclusive,
|
||||
+ // and at the same time, only one bit of 'sensorStatus' will be set,
|
||||
+ // so there is '=', not '|='
|
||||
+ statusRec.sensorStatus = 1 << evOffset;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ statusRec.sensorStatus &= ~(1 << evOffset);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (ed)
|
||||
+ {
|
||||
+ statusRec.sensorStatus |= 1 << evOffset;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ statusRec.sensorStatus &= ~(1 << evOffset);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+enum
|
||||
+{
|
||||
+ SYSTEM_FIRMWARE_ERROR_INDEX_START = 0x00,
|
||||
+ SYSTEM_FIRMWARE_ERROR_INDEX_END = 0x0D,
|
||||
+};
|
||||
+
|
||||
+enum
|
||||
+{
|
||||
+ POWER_FAULT_START_EVENT_INDEX = 0x00,
|
||||
+ POWER_FAULT_END_EVENT_INDEX = 0x08,
|
||||
};
|
||||
|
||||
+
|
||||
void fillSensorDescription(const std::string& sensorPath, int eventOffset)
|
||||
{
|
||||
sensorStatusRec[sensorPath].description = discreteSensorNs;
|
||||
@@ -599,6 +834,7 @@ void fillSensorDescription(const std::string& sensorPath, int eventOffset)
|
||||
//}
|
||||
}
|
||||
|
||||
+
|
||||
void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
const std::string& sensorPath,
|
||||
const SensorType& sensorType,
|
||||
@@ -698,6 +934,109 @@ void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
return;
|
||||
}
|
||||
|
||||
+void powerFaultRecAlarmStatus(const std::string& sensorPath)
|
||||
+{
|
||||
+ uint16_t sensorStatus = 0;
|
||||
+ uint64_t alarmStatus = 0;
|
||||
+ constexpr uint64_t eventType03hStateMask =
|
||||
+ (1 << EVENT_TYPE_03H_STATE_DEASSERT) |
|
||||
+ (1 << EVENT_TYPE_03H_STATE_ASSERT);
|
||||
+
|
||||
+ for (const auto& [evIndex, status] : powerFaultStatusRec)
|
||||
+ {
|
||||
+ sensorStatus |= (status.sensorStatus & eventType03hStateMask);
|
||||
+ /*only need to record an alarm on bit0-bit2*/
|
||||
+ uint64_t alarm = status.alarmStatus;
|
||||
+ if (ALARM_STATUS_MASK_C & alarm)
|
||||
+ {
|
||||
+ alarmStatus |= CRITICAL;
|
||||
+ }
|
||||
+ else if (ALARM_STATUS_MASK_NR & alarm)
|
||||
+ {
|
||||
+ alarmStatus |= NONRECOV;
|
||||
+ }
|
||||
+ else if (ALARM_STATUS_MASK_NC & alarm)
|
||||
+ {
|
||||
+ alarmStatus |= NONCRITICAL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ sensorStatusRec[sensorPath].sensorStatus = sensorStatus;
|
||||
+ sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
+}
|
||||
+
|
||||
+struct AlarmAction
|
||||
+{
|
||||
+ AlarmType alarmStatus;
|
||||
+ bool assertToAlarm; /*true: assert to alarm; false: deassert to alarm*/
|
||||
+};
|
||||
+
|
||||
+/*event offset, action*/
|
||||
+using EventActions = std::unordered_map<uint8_t, AlarmAction>;
|
||||
+
|
||||
+/*event type, all actions*/
|
||||
+using EventAlarm = std::unordered_map<uint8_t, EventActions>;
|
||||
+
|
||||
+ void parseDiscreteGenericSelSeverity(
|
||||
+ sdbusplus::bus::bus& bus, const std::string& sensorPath,
|
||||
+ const SensorType& sensorType, const uint8_t& eventType,
|
||||
+ const std::string& eventData, const std::string& eventDir,
|
||||
+ const AlarmType& severity, const bool& assertToAlarm)
|
||||
+{
|
||||
+ // The sensorStatusRec[sensorPath] obj will be created when init the
|
||||
+ // 'Status'. See: initDiscreteSensorStatusInfo() and sensorMatchHandler().
|
||||
+ // If true, it means that the 'Status' has been initialized
|
||||
+ // and the status sensor object on the entity-manager has been created.
|
||||
+
|
||||
+ // if (sensorStatusRec.find(sensorPath) == sensorStatusRec.end())
|
||||
+ // {
|
||||
+ // lg2::error(
|
||||
+ // "sensorPath not found in sensorStatusRec: {PATH}, add sensorPath into getPathfailedRec",
|
||||
+ // "PATH", sensorPath);
|
||||
+ // SelSeverityInfo severityInfo(sensorPath, sensorType, eventType,
|
||||
+ // eventData, eventDir, severity,
|
||||
+ // assertToAlarm);
|
||||
+ // getPathfailedRec[sensorPath].push_back(severityInfo);
|
||||
+ // return;
|
||||
+ // }
|
||||
+
|
||||
+ std::string eventData1 = eventData.substr(0, 2);
|
||||
+ int ev = std::stol(eventData1, nullptr, 16);
|
||||
+ int ed = std::stol(eventDir);
|
||||
+ int ev1Offset = ev & SENSOR_EVENT_DATA1_EVENT_OFFSET;
|
||||
+
|
||||
+ if (sensorType != SENSOR_TYPE_POWER_FAULT)
|
||||
+ {
|
||||
+ recordAlarmStatus(sensorPath, severity, ev1Offset, ed, assertToAlarm,
|
||||
+ true);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ std::string eventData2 = eventData.substr(2, 2);
|
||||
+ int ev2Index = std::stol(eventData2, nullptr, 16);
|
||||
+
|
||||
+ if (ev2Index < POWER_FAULT_START_EVENT_INDEX ||
|
||||
+ ev2Index > POWER_FAULT_END_EVENT_INDEX)
|
||||
+ {
|
||||
+ lg2::error("Invalid event index = {INDEX}", "INDEX", ev2Index);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ recordAlarmStatus(powerFaultStatusRec[ev2Index], severity, ev1Offset,
|
||||
+ ed, assertToAlarm, true);
|
||||
+ powerFaultRecAlarmStatus(sensorPath);
|
||||
+ }
|
||||
+
|
||||
+ sensorStatusRec[sensorPath].eventType = eventType;
|
||||
+ sensorStatusRec[sensorPath].sensorType = sensorType;
|
||||
+
|
||||
+ setDiscreteSensorStatusValue(bus, sensorPath, eventData);
|
||||
+
|
||||
+ //updateSensorStatus(bus, sensorPath);
|
||||
+
|
||||
+ //controlHealthLed(bus);
|
||||
+}
|
||||
+
|
||||
void Add::filterSEL(sdbusplus::bus::bus& bus, const std::string& path)
|
||||
{
|
||||
//AlarmType severity = NORMAL;
|
||||
@@ -728,7 +1067,9 @@ void Add::filterSEL(sdbusplus::bus::bus& bus, const std::string& path)
|
||||
|
||||
uint8_t typeCode = 0;
|
||||
uint8_t sensorType = 0;
|
||||
- std::string sensorData, sensorPath, eventDir;
|
||||
+ std::string sensorData, sensorPath, eventDir, assertAlarm;
|
||||
+ bool assertToAlarm;
|
||||
+ AlarmType confSeverity = AlarmType::NORMAL;
|
||||
for (auto& item : additionalDatas)
|
||||
{
|
||||
std::string::size_type nStr;
|
||||
@@ -760,6 +1101,16 @@ void Add::filterSEL(sdbusplus::bus::bus& bus, const std::string& path)
|
||||
std::cerr << "sensorPath " << sensorPath <<"\n";
|
||||
}
|
||||
}
|
||||
+
|
||||
+ if (assertAlarm.empty())
|
||||
+ {
|
||||
+ nStr = item.find("ASSERT_ALARM=");
|
||||
+ if (std::string::npos != nStr)
|
||||
+ {
|
||||
+ assertAlarm = item.substr(nStr + strlen("ASSERT_ALARM="));
|
||||
+ assertToAlarm = std::stol(assertAlarm, nullptr, 10);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
if (!ipmiSensors)
|
||||
@@ -795,9 +1146,19 @@ void Add::filterSEL(sdbusplus::bus::bus& bus, const std::string& path)
|
||||
else if (typeCode == SPECIFIC_SENSOR_TYPE)
|
||||
{
|
||||
// discrete
|
||||
- parseSpecificSensorSelSeverity(
|
||||
+ parseSpecificSensorSelSeverity(
|
||||
bus, sensorPath, static_cast<SensorType>(sensorType), sensorData,
|
||||
eventDir);
|
||||
+ }else if (typeCode >= GENERIC_START_SENSOR_TYPE &&
|
||||
+ typeCode <= GENERIC_END_SENSOR_TYPE)
|
||||
+ {
|
||||
+ parseDiscreteGenericSelSeverity(
|
||||
+ bus, sensorPath, static_cast<SensorType>(sensorType), typeCode,
|
||||
+ sensorData, eventDir, confSeverity, assertToAlarm);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return;
|
||||
}
|
||||
|
||||
//controlHealthLed(bus);
|
||||
diff --git a/fault-monitor/fru-fault-monitor.hpp b/fault-monitor/fru-fault-monitor.hpp
|
||||
index bd4a852..0dacc0c 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.hpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.hpp
|
||||
@@ -118,9 +118,10 @@ struct SensorStatusInfo
|
||||
uint16_t sensorStatus;
|
||||
uint64_t alarmStatus;
|
||||
std::string description; // add description for discrete sensor
|
||||
+ uint8_t sdrType; // Only for discrete sensors
|
||||
};
|
||||
|
||||
-struct DriveStatus
|
||||
+struct SensorStatus
|
||||
{
|
||||
uint16_t sensorStatus; /*entity status*/
|
||||
uint64_t alarmStatus; /*alarm status*/
|
||||
--
|
||||
2.25.1
|
||||
|
||||
+626
@@ -0,0 +1,626 @@
|
||||
From 133f696e0a75c446b012822473d39b793c77ebc5 Mon Sep 17 00:00:00 2001
|
||||
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
|
||||
Date: Sat, 14 Dec 2024 14:42:08 +0800
|
||||
Subject: [PATCH 5/5] Clear Status of sensors when power on
|
||||
|
||||
---
|
||||
fault-monitor/fru-fault-monitor.cpp | 300 +++++++++++++++++++++-------
|
||||
fault-monitor/fru-fault-monitor.hpp | 62 +++++-
|
||||
fault-monitor/meson.build | 1 +
|
||||
3 files changed, 282 insertions(+), 81 deletions(-)
|
||||
|
||||
diff --git a/fault-monitor/fru-fault-monitor.cpp b/fault-monitor/fru-fault-monitor.cpp
|
||||
index b9f687c..1bc41aa 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.cpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.cpp
|
||||
@@ -7,6 +7,8 @@
|
||||
#include <xyz/openbmc_project/Common/error.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
+#include <string>
|
||||
+#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
extern "C"
|
||||
@@ -67,6 +69,8 @@ using ResourceNotFoundErr =
|
||||
using InvalidArgumentErr =
|
||||
sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
|
||||
|
||||
+bool Add::isPoweredOn = false;
|
||||
+
|
||||
constexpr const char* discreteSensorNs = "No state defined";
|
||||
|
||||
enum AlarmType : uint64_t
|
||||
@@ -430,8 +434,10 @@ std::string getService(sdbusplus::bus_t& bus, const std::string& path)
|
||||
return mapperResponse.cbegin()->first;
|
||||
}
|
||||
|
||||
+using AdditionalList = std::vector<std::string>;
|
||||
+
|
||||
static void setDiscreteSensorStatusValue(sdbusplus::bus::bus& bus,
|
||||
- const std::string& sensorPath,const std::string& sensorData)
|
||||
+ const std::string& sensorPath)
|
||||
{
|
||||
// IPMI spec Table 35-15
|
||||
// For discrete reading sensors only. (Optional)
|
||||
@@ -445,13 +451,13 @@ static void setDiscreteSensorStatusValue(sdbusplus::bus::bus& bus,
|
||||
constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
|
||||
constexpr auto statusInterface = "xyz.openbmc_project.Configuration.Status";
|
||||
|
||||
- unsigned long dataValue = strtoul(sensorData.c_str(), NULL, 16);
|
||||
statusValue = static_cast<double>(statusValue +
|
||||
- (0x01 << ((dataValue & 0x0f0000) >> 16)));
|
||||
+ sensorStatusRec[sensorPath].sensorStatus);
|
||||
auto method = bus.new_method_call(service, sensorPath.c_str(),
|
||||
dbusProperties, "Set");
|
||||
std::variant<double> value{(double)statusValue};
|
||||
- std::cerr << "SEL:sensorData = " << sensorData << std::endl;
|
||||
+ std::cerr << "SEL:sensorData = " << sensorPath << std::endl;
|
||||
+ std::cerr << "SEL:sensorStatus = " << sensorStatusRec[sensorPath].sensorStatus << std::endl;
|
||||
method.append(statusInterface, "Status", value);
|
||||
try
|
||||
{
|
||||
@@ -576,18 +582,16 @@ void action(sdbusplus::bus_t& bus, const std::string& path, bool assert)
|
||||
return;
|
||||
}
|
||||
|
||||
- auto pos = path.rfind("/");
|
||||
- if (pos == std::string::npos)
|
||||
+ std::string ledPath = ledGroups + path;
|
||||
+
|
||||
+ if (assert)
|
||||
{
|
||||
- using namespace xyz::openbmc_project::Common;
|
||||
- report<InvalidArgumentErr>(
|
||||
- InvalidArgument::ARGUMENT_NAME("path"),
|
||||
- InvalidArgument::ARGUMENT_VALUE(path.c_str()));
|
||||
- return;
|
||||
+ lg2::info("{PATH} is on", "PATH", ledPath);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ lg2::info("{PATH} is off", "PATH", ledPath);
|
||||
}
|
||||
- auto unit = path.substr(pos + 1);
|
||||
-
|
||||
- std::string ledPath = ledGroups + unit + '_' + LED_FAULT;
|
||||
|
||||
auto method = bus.new_method_call(service.c_str(), ledPath.c_str(),
|
||||
"org.freedesktop.DBus.Properties", "Set");
|
||||
@@ -609,6 +613,24 @@ void action(sdbusplus::bus_t& bus, const std::string& path, bool assert)
|
||||
return;
|
||||
}
|
||||
|
||||
+enum
|
||||
+{
|
||||
+ NC_L2L_SEVERITY = 0x00,
|
||||
+ NC_L2H_SEVERITY = 0x01,
|
||||
+ NC_H2L_SEVERITY = 0x06,
|
||||
+ NC_H2H_SEVERITY = 0x07,
|
||||
+
|
||||
+ CR_L2L_SEVERITY = 0x02,
|
||||
+ CR_L2H_SEVERITY = 0x03,
|
||||
+ CR_H2L_SEVERITY = 0x08,
|
||||
+ CR_H2H_SEVERITY = 0x09,
|
||||
+
|
||||
+ NR_L2L_SEVERITY = 0x04,
|
||||
+ NR_L2H_SEVERITY = 0x05,
|
||||
+ NR_H2L_SEVERITY = 0x0A,
|
||||
+ NR_H2H_SEVERITY = 0x0B
|
||||
+};
|
||||
+
|
||||
enum
|
||||
{
|
||||
UNSPECIFY_SENSOR_TYPE = 0x00,
|
||||
@@ -620,6 +642,41 @@ enum
|
||||
OEM_END_SENSOR_TYPE = 0x7F
|
||||
};
|
||||
|
||||
+void lightUpHealthLed(sdbusplus::bus::bus& bus, AlarmType ledStatus)
|
||||
+{
|
||||
+ switch (ledStatus)
|
||||
+ {
|
||||
+ case NORMAL:
|
||||
+ action(bus, "status_ok", true);
|
||||
+ action(bus, "status_non_critical", false);
|
||||
+ action(bus, "status_critical", false);
|
||||
+ action(bus, "status_non_recoverable", false);
|
||||
+ break;
|
||||
+ case NONCRITICAL:
|
||||
+ action(bus, "status_ok", false);
|
||||
+ action(bus, "status_non_critical", true);
|
||||
+ action(bus, "status_critical", false);
|
||||
+ action(bus, "status_non_recoverable", false);
|
||||
+ break;
|
||||
+ case CRITICAL:
|
||||
+ action(bus, "status_ok", false);
|
||||
+ action(bus, "status_non_critical", false);
|
||||
+ action(bus, "status_critical", true);
|
||||
+ action(bus, "status_non_recoverable", false);
|
||||
+ break;
|
||||
+ case NONRECOV:
|
||||
+ action(bus, "status_ok", false);
|
||||
+ action(bus, "status_non_critical", false);
|
||||
+ action(bus, "status_critical", false);
|
||||
+ action(bus, "status_non_recoverable", true);
|
||||
+ break;
|
||||
+ default:
|
||||
+ lg2::error("ERROR: Invalid led status {STATUS}", "STATUS",
|
||||
+ static_cast<int>(ledStatus));
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
inline void recordAlarmStatus(const std::string& sensorPath,
|
||||
AlarmType alarmStatus, int evOffset, int ed,
|
||||
bool assertAlarm,
|
||||
@@ -834,12 +891,34 @@ void fillSensorDescription(const std::string& sensorPath, int eventOffset)
|
||||
//}
|
||||
}
|
||||
|
||||
+// void parseThresholdSelSeverity(sdbusplus::bus::bus& bus,
|
||||
+// const std::string& sensorPath,
|
||||
+// const SensorType& sensorType,
|
||||
+// const std::string& eventData,
|
||||
+// const std::string& eventDir,
|
||||
+// const AlarmType& severity,
|
||||
+// const bool& assertToAlarm)
|
||||
+// {
|
||||
+// std::string eventData1 = eventData.substr(0, 2);
|
||||
+// int ev = std::stol(eventData1, nullptr, 16);
|
||||
+// int ed = std::stol(eventDir);
|
||||
+
|
||||
+// ev = (ev & SENSOR_EVENT_DATA1_EVENT_OFFSET);
|
||||
+
|
||||
+// recordAlarmStatus(sensorPath, severity, ev, ed, assertToAlarm, false);
|
||||
+
|
||||
+// sensorStatusRec[sensorPath].eventType = THRESHOLD_SENSOR_TYPE;
|
||||
+// sensorStatusRec[sensorPath].sensorType = sensorType;
|
||||
+
|
||||
+// }
|
||||
|
||||
void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
const std::string& sensorPath,
|
||||
const SensorType& sensorType,
|
||||
const std::string& eventData,
|
||||
- const std::string& eventDir)
|
||||
+ const std::string& eventDir,
|
||||
+ const AlarmType& severity,
|
||||
+ const bool& assertAlarm)
|
||||
{
|
||||
std::string eventData1 = eventData.substr(0, 2);
|
||||
int ev = std::stol(eventData1, nullptr, 16);
|
||||
@@ -854,6 +933,8 @@ void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
{
|
||||
case SYSTEM_EVENT_LOG_CLEARED:
|
||||
{
|
||||
+ recordAlarmStatus(sensorPath, severity, ev1Offset, ed, assertAlarm,
|
||||
+ false);
|
||||
sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
break;
|
||||
}
|
||||
@@ -872,6 +953,8 @@ void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
case SLEEP_BUTTON_PRESSED:
|
||||
case RESET_BUTTON_PRESSED:
|
||||
{
|
||||
+ recordAlarmStatus(sensorPath, severity, ev1Offset, ed, assertAlarm,
|
||||
+ false);
|
||||
sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
break;
|
||||
}
|
||||
@@ -884,6 +967,8 @@ void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
}
|
||||
case SENSOR_TYPE_POWER_SUPPLY:
|
||||
{
|
||||
+ recordAlarmStatus(sensorPath, severity, ev1Offset, ed, assertAlarm,
|
||||
+ true);
|
||||
sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
break;
|
||||
}
|
||||
@@ -894,6 +979,11 @@ void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
case ACPI_S0_STATE:
|
||||
case ACPI_S5_STATE:
|
||||
{
|
||||
+ // The S0 State and S5 State of ACPI State will only exist
|
||||
+ // one, so the passed in arg6: isGenericDiscreteSensor is
|
||||
+ // true.
|
||||
+ recordAlarmStatus(sensorPath, severity, ev1Offset, ed,
|
||||
+ assertAlarm, true);
|
||||
sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
break;
|
||||
}
|
||||
@@ -910,26 +1000,34 @@ void parseSpecificSensorSelSeverity(sdbusplus::bus::bus& bus,
|
||||
}
|
||||
case SENSOR_TYPE_MEMORY:
|
||||
{
|
||||
+ recordAlarmStatus(sensorPath, severity, ev1Offset, ed, assertAlarm,
|
||||
+ false);
|
||||
sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
setDimmLEDState(bus, sensorPath, "FAULT");
|
||||
break;
|
||||
}
|
||||
case SENSOR_TYPE_PROCESSOR:
|
||||
{
|
||||
+ recordAlarmStatus(sensorPath, severity, ev1Offset, ed, assertAlarm,
|
||||
+ false);
|
||||
sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
break;
|
||||
}
|
||||
case SENSOR_TYPE_WATCHDOG_2:
|
||||
{
|
||||
+ recordAlarmStatus(sensorPath, severity, ev1Offset, ed, assertAlarm,
|
||||
+ false);
|
||||
sensorStatusRec[sensorPath].alarmStatus = alarmStatus;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
+ recordAlarmStatus(sensorPath, severity, ev1Offset, ed, assertAlarm,
|
||||
+ false);
|
||||
break;
|
||||
}
|
||||
sensorStatusRec[sensorPath].eventType = SPECIFIC_SENSOR_TYPE;
|
||||
sensorStatusRec[sensorPath].sensorType = sensorType;
|
||||
- setDiscreteSensorStatusValue(bus, sensorPath, eventData);
|
||||
+ setDiscreteSensorStatusValue(bus, sensorPath);
|
||||
if(0)
|
||||
{
|
||||
fillSensorDescription(sensorPath, ev1Offset);
|
||||
@@ -992,7 +1090,6 @@ using EventAlarm = std::unordered_map<uint8_t, EventActions>;
|
||||
// 'Status'. See: initDiscreteSensorStatusInfo() and sensorMatchHandler().
|
||||
// If true, it means that the 'Status' has been initialized
|
||||
// and the status sensor object on the entity-manager has been created.
|
||||
-
|
||||
// if (sensorStatusRec.find(sensorPath) == sensorStatusRec.end())
|
||||
// {
|
||||
// lg2::error(
|
||||
@@ -1034,17 +1131,14 @@ using EventAlarm = std::unordered_map<uint8_t, EventActions>;
|
||||
|
||||
sensorStatusRec[sensorPath].eventType = eventType;
|
||||
sensorStatusRec[sensorPath].sensorType = sensorType;
|
||||
-
|
||||
- setDiscreteSensorStatusValue(bus, sensorPath, eventData);
|
||||
+ setDiscreteSensorStatusValue(bus, sensorPath);
|
||||
|
||||
//updateSensorStatus(bus, sensorPath);
|
||||
|
||||
- //controlHealthLed(bus);
|
||||
}
|
||||
|
||||
void Add::filterSEL(sdbusplus::bus::bus& bus, const std::string& path)
|
||||
{
|
||||
- //AlarmType severity = NORMAL;
|
||||
auto method = bus.new_method_call(logService, path.c_str(),
|
||||
"org.freedesktop.DBus.Properties", "Get");
|
||||
method.append("xyz.openbmc_project.Logging.Entry");
|
||||
@@ -1072,7 +1166,7 @@ void Add::filterSEL(sdbusplus::bus::bus& bus, const std::string& path)
|
||||
|
||||
uint8_t typeCode = 0;
|
||||
uint8_t sensorType = 0;
|
||||
- std::string sensorData, sensorPath, eventDir, assertAlarm;
|
||||
+ std::string sensorData, sensorPath, eventDir, assertAlarm, confSeverityStr;
|
||||
bool assertToAlarm;
|
||||
AlarmType confSeverity = AlarmType::NORMAL;
|
||||
for (auto& item : additionalDatas)
|
||||
@@ -1153,7 +1247,7 @@ void Add::filterSEL(sdbusplus::bus::bus& bus, const std::string& path)
|
||||
// discrete
|
||||
parseSpecificSensorSelSeverity(
|
||||
bus, sensorPath, static_cast<SensorType>(sensorType), sensorData,
|
||||
- eventDir);
|
||||
+ eventDir, confSeverity, assertToAlarm);
|
||||
}else if (typeCode >= GENERIC_START_SENSOR_TYPE &&
|
||||
typeCode <= GENERIC_END_SENSOR_TYPE)
|
||||
{
|
||||
@@ -1166,8 +1260,6 @@ void Add::filterSEL(sdbusplus::bus::bus& bus, const std::string& path)
|
||||
return;
|
||||
}
|
||||
|
||||
- //controlHealthLed(bus);
|
||||
-
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1479,6 +1571,100 @@ void Add::dimmLEDMatchHandler(sdbusplus::message_t& msg)
|
||||
updateSysHealthLED(dimmSensorLEDStatus);
|
||||
}
|
||||
|
||||
+void Add::clearCPUStatusAlarm(SensorStatusInfo& statusInfo)
|
||||
+{
|
||||
+ constexpr std::array<uint16_t, 7> cpuStatToClear{
|
||||
+ IPMI_CPU_IERR, IPMI_CPU_FRB2_HANG, IPMI_CPU_CONFIG_ERROR,
|
||||
+ IPMI_CPU_THROTTLED, IPMI_CPU_DISABLED, IPMI_CPU_MCE,
|
||||
+ IPMI_CPU_CMCE};
|
||||
+
|
||||
+ for (const auto& offset : cpuStatToClear)
|
||||
+ {
|
||||
+ statusInfo.sensorStatus &= ~(1 << offset);
|
||||
+ statusInfo.alarmStatus &= ~(ALARM_ALL_BITS << (offset * ALARM_BIT_NUM));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void Add::clearMEMStatusAlarm(SensorStatusInfo& statusInfo)
|
||||
+{
|
||||
+ constexpr std::array<uint16_t, 5> memStatToClear{
|
||||
+ MEMORY_OFFSET_CORRECTABLE_ECC, MEMORY_OFFSET_UNCORRECTABLE_ECC,
|
||||
+ MEMORY_OFFSET_MEMORY_DEVICE_DISABLED,
|
||||
+ MEMORY_OFFSET_CORRECTABLE_ECC_LOG_LIMIT_REACHED,
|
||||
+ MEMORY_OFFSET_CONFIGURATION_ERROR};
|
||||
+
|
||||
+ for (const auto& offset : memStatToClear)
|
||||
+ {
|
||||
+ statusInfo.sensorStatus &= ~(1 << offset);
|
||||
+ statusInfo.alarmStatus &= ~(ALARM_ALL_BITS << (offset * ALARM_BIT_NUM));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void Add::clearPCIEStatusAlarm(SensorStatusInfo& statusInfo)
|
||||
+{
|
||||
+ constexpr std::array<uint16_t, 6> pcieStatToClear{
|
||||
+ CRITICAL_INTERRUPT_OFFSET_PCI_PERR,
|
||||
+ CRITICAL_INTERRUPT_OFFSET_PCI_SERR,
|
||||
+ CRITICAL_INTERRUPT_OFFSET_BUS_CORRECTABLE_ERROR,
|
||||
+ CRITICAL_INTERRUPT_OFFSET_BUS_UNCORRECTABLE_ERRPR,
|
||||
+ CRITICAL_INTERRUPT_OFFSET_BUS_FATAL_ERROR,
|
||||
+ CRITICAL_INTERRUPT_OFFSET_BUS_DEGRADED};
|
||||
+
|
||||
+ for (const auto& offset : pcieStatToClear)
|
||||
+ {
|
||||
+ statusInfo.sensorStatus &= ~(1 << offset);
|
||||
+ statusInfo.alarmStatus &= ~(ALARM_ALL_BITS << (offset * ALARM_BIT_NUM));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void Add::clearFirmwareProgressAlarm(SensorStatusInfo& statusInfo)
|
||||
+{
|
||||
+ constexpr std::array<uint16_t, 2> statusToClear{
|
||||
+ SYSTEM_FIRMWARE_PROGRESS_OFFSET_ERROR,
|
||||
+ SYSTEM_FIRMWARE_PROGRESS_OFFSET_HANG};
|
||||
+
|
||||
+ for (const auto& offset : statusToClear)
|
||||
+ {
|
||||
+ statusInfo.sensorStatus &= ~(1 << offset);
|
||||
+ statusInfo.alarmStatus &= ~(ALARM_ALL_BITS << (offset * ALARM_BIT_NUM));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void Add::deassertOnPowerReset(void)
|
||||
+{
|
||||
+ for (auto& [sensorObj, statusInfo] : sensorStatusRec)
|
||||
+ {
|
||||
+ if (statusInfo.eventType != SPECIFIC_SENSOR_TYPE)
|
||||
+ {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (SENSOR_TYPE_PROCESSOR == statusInfo.sensorType)
|
||||
+ {
|
||||
+ clearCPUStatusAlarm(statusInfo);
|
||||
+ }
|
||||
+ else if (SENSOR_TYPE_MEMORY == statusInfo.sensorType)
|
||||
+ {
|
||||
+ clearMEMStatusAlarm(statusInfo);
|
||||
+ }
|
||||
+ else if (SENSOR_TYPE_CRITICAL_INTERRUPT == statusInfo.sensorType)
|
||||
+ {
|
||||
+ clearPCIEStatusAlarm(statusInfo);
|
||||
+ }
|
||||
+ else if (SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS == statusInfo.sensorType)
|
||||
+ {
|
||||
+ clearFirmwareProgressAlarm(statusInfo);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ setDiscreteSensorStatusValue(bus, sensorObj);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
void getLoggingSubTree(sdbusplus::bus_t& bus, MapperResponseType& subtree)
|
||||
{
|
||||
auto depth = 0;
|
||||
@@ -1513,60 +1699,22 @@ void Add::createAssociation(sdbusplus::asio::object_server& objectServer)
|
||||
faultMonitorAssociation->initialize();
|
||||
}
|
||||
|
||||
-void Add::processExistingCallouts(sdbusplus::bus_t& bus)
|
||||
+void Add::initPowerStatus()
|
||||
{
|
||||
- MapperResponseType mapperResponse;
|
||||
-
|
||||
- getLoggingSubTree(bus, mapperResponse);
|
||||
- if (mapperResponse.empty())
|
||||
- {
|
||||
- // No errors to process.
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- for (const auto& elem : mapperResponse)
|
||||
+ try
|
||||
{
|
||||
- auto method = bus.new_method_call(
|
||||
- elem.second.begin()->first.c_str(), elem.first.c_str(),
|
||||
- "org.freedesktop.DBus.Properties", "Get");
|
||||
- method.append("xyz.openbmc_project.Association.Definitions");
|
||||
- method.append("Associations");
|
||||
- auto reply = bus.call(method);
|
||||
- if (reply.is_method_error())
|
||||
- {
|
||||
- // do not stop, continue with next elog
|
||||
- lg2::error("Error in getting associations");
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- std::variant<AssociationList> assoc;
|
||||
- try
|
||||
- {
|
||||
- reply.read(assoc);
|
||||
- }
|
||||
- catch (const sdbusplus::exception_t& e)
|
||||
- {
|
||||
- lg2::error(
|
||||
- "Failed to parse existing callouts associations message, ERROR = {ERROR}",
|
||||
- "ERROR", e);
|
||||
- continue;
|
||||
- }
|
||||
- auto& assocs = std::get<AssociationList>(assoc);
|
||||
- if (assocs.empty())
|
||||
- {
|
||||
- // no associations, skip
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- for (const auto& item : assocs)
|
||||
- {
|
||||
- if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
|
||||
- {
|
||||
- removeWatches.emplace_back(
|
||||
- std::make_unique<Remove>(bus, std::get<2>(item)));
|
||||
- action(bus, std::get<2>(item), true);
|
||||
- }
|
||||
+ auto ret = dBusHandler.getProperty(hostPath, hostInterface,
|
||||
+ hostProperty);
|
||||
+ auto status = std::get<std::string>(ret);
|
||||
+ if (status.size() >= running.size()){
|
||||
+ isPoweredOn = (status.compare(status.size() - running.size(),
|
||||
+ running.size(), running.data()) == 0);
|
||||
}
|
||||
+ }
|
||||
+ catch (const sdbusplus::exception::exception& e)
|
||||
+ {
|
||||
+ log<level::ERR>("Failed to get power status",
|
||||
+ entry("ERROR=%s", e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/fault-monitor/fru-fault-monitor.hpp b/fault-monitor/fru-fault-monitor.hpp
|
||||
index 0dacc0c..185693b 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.hpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.hpp
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
+#include "../utils.hpp"
|
||||
+
|
||||
#include <sdbusplus/bus.hpp>
|
||||
+#include <sdbusplus/bus/match.hpp>
|
||||
#include <sdbusplus/server.hpp>
|
||||
#include <sdbusplus/asio/connection.hpp>
|
||||
#include <sdbusplus/asio/object_server.hpp>
|
||||
@@ -26,6 +29,13 @@ namespace fault
|
||||
{
|
||||
namespace monitor
|
||||
{
|
||||
+constexpr auto hostBusname = "xyz.openbmc_project.State.Host";
|
||||
+constexpr auto hostInterface = "xyz.openbmc_project.State.Host";
|
||||
+constexpr auto hostPath = "/xyz/openbmc_project/state/host0";
|
||||
+constexpr auto hostProperty = "CurrentHostState";
|
||||
+constexpr std::string_view running = "Running";
|
||||
+
|
||||
+using namespace phosphor::led::utils;
|
||||
constexpr auto faultLedPath = "/xyz/openbmc_project/led/groups/status_fault";
|
||||
constexpr auto dimmfaultLedPath = "/xyz/openbmc_project/led/groups/dimm_fault";
|
||||
constexpr auto okLedPath = "/xyz/openbmc_project/led/groups/status_ok";
|
||||
@@ -155,6 +165,19 @@ class Add
|
||||
"/xyz/openbmc_project/logging"),
|
||||
std::bind(std::mem_fn(&Add::created), this,
|
||||
std::placeholders::_1)),
|
||||
+ powerMatch(bus,
|
||||
+ sdbusplus::bus::match::rules::propertiesChanged(
|
||||
+ hostPath, hostInterface),
|
||||
+ [this](sdbusplus::message::message& message) {
|
||||
+ std::string objectName;
|
||||
+ std::map<std::string, std::variant<std::string>> values;
|
||||
+ message.read(objectName, values);
|
||||
+ auto findState = values.find(hostProperty);
|
||||
+ if (findState != values.end())
|
||||
+ {
|
||||
+ deassertOnPowerReset();
|
||||
+ }
|
||||
+ }),
|
||||
dimmLEDMatch(bus,
|
||||
"type='signal',member='PropertiesChanged',path_namespace='" +
|
||||
std::string(dimmSensorPath) + "',arg0namespace='" +
|
||||
@@ -165,7 +188,7 @@ class Add
|
||||
|
||||
createAssociation(objectServer);
|
||||
dimmledInit();
|
||||
- processExistingCallouts(bus);
|
||||
+ initPowerStatus();
|
||||
}
|
||||
|
||||
|
||||
@@ -174,12 +197,45 @@ class Add
|
||||
/** @brief sdbusplus signal match for fault created */
|
||||
sdbusplus::bus::match_t matchCreated;
|
||||
|
||||
+ /** Match for host power monitor */
|
||||
+ sdbusplus::bus::match::match powerMatch;
|
||||
+
|
||||
sdbusplus::bus::match_t dimmLEDMatch;
|
||||
|
||||
std::vector<std::unique_ptr<Remove>> removeWatches;
|
||||
|
||||
std::shared_ptr<sdbusplus::asio::dbus_interface> faultMonitorAssociation;
|
||||
|
||||
+ /** @brief Initialize the host power status*/
|
||||
+ void initPowerStatus();
|
||||
+
|
||||
+ /** @brief clear CPU alarm status
|
||||
+ */
|
||||
+ void clearCPUStatusAlarm(SensorStatusInfo& statusInfo);
|
||||
+
|
||||
+ /** @brief clear MEM alarm status
|
||||
+ */
|
||||
+ void clearMEMStatusAlarm(SensorStatusInfo& statusInfo);
|
||||
+
|
||||
+ /** @brief clear PCIE alarm status
|
||||
+ */
|
||||
+ void clearPCIEStatusAlarm(SensorStatusInfo& statusInfo);
|
||||
+
|
||||
+ /** @brief clear FIRMWARE alarm status
|
||||
+ */
|
||||
+ void clearFirmwareProgressAlarm(SensorStatusInfo& statusInfo);
|
||||
+
|
||||
+ /** @brief deassert some alarm bits when the host power restarts.
|
||||
+ */
|
||||
+ void deassertOnPowerReset(void);
|
||||
+
|
||||
+ /* DBusHandler class handles the D-Bus operations */
|
||||
+ DBusHandler dBusHandler;
|
||||
+
|
||||
+ public:
|
||||
+ /** @brief Indicate if the host status is power on */
|
||||
+ static bool isPoweredOn;
|
||||
+
|
||||
/** @brief Callback function for fru fault created
|
||||
* @param[in] msg - Data associated with subscribed signal
|
||||
*/
|
||||
@@ -201,10 +257,6 @@ class Add
|
||||
|
||||
void createAssociation(sdbusplus::asio::object_server& objectServer);
|
||||
|
||||
- /** @brief This function process all callouts at application start
|
||||
- * @param[in] bus - The Dbus bus object
|
||||
- */
|
||||
- void processExistingCallouts(sdbusplus::bus_t& bus);
|
||||
};
|
||||
|
||||
/** @class Remove
|
||||
diff --git a/fault-monitor/meson.build b/fault-monitor/meson.build
|
||||
index 7ced362..a36ef80 100644
|
||||
--- a/fault-monitor/meson.build
|
||||
+++ b/fault-monitor/meson.build
|
||||
@@ -10,6 +10,7 @@ if get_option('monitor-operational-status').enabled()
|
||||
else
|
||||
fault_monitor_sources += [
|
||||
'fru-fault-monitor.cpp',
|
||||
+ '../utils.cpp',
|
||||
]
|
||||
endif
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
From 16a84c977b6a360d7f6a12f578d0480f4c00ec76 Mon Sep 17 00:00:00 2001
|
||||
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
|
||||
Date: Thu, 19 Dec 2024 15:42:26 +0800
|
||||
Subject: [PATCH 6/6] Fix sensor status being cleared due to warm reset during
|
||||
the power on
|
||||
|
||||
---
|
||||
fault-monitor/fru-fault-monitor.cpp | 36 +++++++++++++++++++++++++++++
|
||||
fault-monitor/fru-fault-monitor.hpp | 12 +++++++++-
|
||||
2 files changed, 47 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fault-monitor/fru-fault-monitor.cpp b/fault-monitor/fru-fault-monitor.cpp
|
||||
index 1bc41aa..f8cac9b 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.cpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.cpp
|
||||
@@ -1632,6 +1632,37 @@ void Add::clearFirmwareProgressAlarm(SensorStatusInfo& statusInfo)
|
||||
|
||||
void Add::deassertOnPowerReset(void)
|
||||
{
|
||||
+ std::cout << "Get the current host state" <<std::endl;
|
||||
+ std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
||||
+ // Get the current host state
|
||||
+ constexpr auto HOST_INTERFACE = "xyz.openbmc_project.State.Host";
|
||||
+ std::string HOST_PATH = "/xyz/openbmc_project/state/host0";
|
||||
+ std::string HOST_PROP = "CurrentHostState";
|
||||
+ sdbusplus::bus_t bus= sdbusplus::bus::new_default();;
|
||||
+ std::string settingService = "xyz.openbmc_project.State.Host";
|
||||
+ auto method = bus.new_method_call(settingService.c_str(), HOST_PATH.c_str(),
|
||||
+ "org.freedesktop.DBus.Properties", "Get");
|
||||
+ method.append(HOST_INTERFACE, HOST_PROP);
|
||||
+ std::variant<std::string> propertyValue{};
|
||||
+ std::string value;
|
||||
+ try
|
||||
+ {
|
||||
+ auto reply = bus.call(method);
|
||||
+ reply.read(propertyValue);
|
||||
+ value = std::get<std::string>(propertyValue);
|
||||
+ std::cerr << "value:" << value << "\n";
|
||||
+ }
|
||||
+ catch (const std::exception& e)
|
||||
+ {
|
||||
+ std::cerr << "exception:" << e.what() << "\n";
|
||||
+ }
|
||||
+
|
||||
+ if (value == "xyz.openbmc_project.State.Host.HostState.Running"){
|
||||
+ std::cout << "power on:Do not clear the sensor status" <<std::endl;
|
||||
+ return;
|
||||
+ }
|
||||
+ // Clear the sensor status
|
||||
+ std::cout << "Clear the sensor status" <<std::endl;
|
||||
for (auto& [sensorObj, statusInfo] : sensorStatusRec)
|
||||
{
|
||||
if (statusInfo.eventType != SPECIFIC_SENSOR_TYPE)
|
||||
@@ -1641,18 +1672,22 @@ void Add::deassertOnPowerReset(void)
|
||||
|
||||
if (SENSOR_TYPE_PROCESSOR == statusInfo.sensorType)
|
||||
{
|
||||
+ std::cout << "clearCPUStatusAlarm" <<std::endl;
|
||||
clearCPUStatusAlarm(statusInfo);
|
||||
}
|
||||
else if (SENSOR_TYPE_MEMORY == statusInfo.sensorType)
|
||||
{
|
||||
+ std::cout << "clearMEMStatusAlarm" <<std::endl;
|
||||
clearMEMStatusAlarm(statusInfo);
|
||||
}
|
||||
else if (SENSOR_TYPE_CRITICAL_INTERRUPT == statusInfo.sensorType)
|
||||
{
|
||||
+ std::cout << "clearPCIEStatusAlarm" <<std::endl;
|
||||
clearPCIEStatusAlarm(statusInfo);
|
||||
}
|
||||
else if (SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS == statusInfo.sensorType)
|
||||
{
|
||||
+ std::cout << "clearFirmwareProgressAlarm" <<std::endl;
|
||||
clearFirmwareProgressAlarm(statusInfo);
|
||||
}
|
||||
else
|
||||
@@ -1701,6 +1736,7 @@ void Add::createAssociation(sdbusplus::asio::object_server& objectServer)
|
||||
|
||||
void Add::initPowerStatus()
|
||||
{
|
||||
+ std::cout << "initPowerStatus." <<std::endl;
|
||||
try
|
||||
{
|
||||
auto ret = dBusHandler.getProperty(hostPath, hostInterface,
|
||||
diff --git a/fault-monitor/fru-fault-monitor.hpp b/fault-monitor/fru-fault-monitor.hpp
|
||||
index 185693b..8eeb6e5 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.hpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.hpp
|
||||
@@ -175,7 +175,17 @@ class Add
|
||||
auto findState = values.find(hostProperty);
|
||||
if (findState != values.end())
|
||||
{
|
||||
- deassertOnPowerReset();
|
||||
+ auto status = std::get<std::string>(findState->second);
|
||||
+ if (status.size() >= running.size())
|
||||
+ {
|
||||
+ isPoweredOn =
|
||||
+ (status.compare(status.size() - running.size(),
|
||||
+ running.size(), running.data()) == 0);
|
||||
+ if (!isPoweredOn)
|
||||
+ {
|
||||
+ deassertOnPowerReset();
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}),
|
||||
dimmLEDMatch(bus,
|
||||
--
|
||||
2.25.1
|
||||
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
From baa59772c55c45a237d471b1227296d09b33705d Mon Sep 17 00:00:00 2001
|
||||
From: wangjue <jue.wang2@luxshare-ict.com>
|
||||
Date: Thu, 19 Dec 2024 19:11:25 +0800
|
||||
Subject: [PATCH] Retrieve SEL sensor info from JSON file instead of calling
|
||||
from IPMI service
|
||||
|
||||
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
|
||||
---
|
||||
fault-monitor/fru-fault-monitor.cpp | 95 +++++++++++++++++++++++++----
|
||||
1 file changed, 83 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/fault-monitor/fru-fault-monitor.cpp b/fault-monitor/fru-fault-monitor.cpp
|
||||
index 1bc41aa..a64f375 100644
|
||||
--- a/fault-monitor/fru-fault-monitor.cpp
|
||||
+++ b/fault-monitor/fru-fault-monitor.cpp
|
||||
@@ -5,11 +5,16 @@
|
||||
#include <phosphor-logging/lg2.hpp>
|
||||
#include <sdbusplus/exception.hpp>
|
||||
#include <xyz/openbmc_project/Common/error.hpp>
|
||||
+#include <nlohmann/json.hpp>
|
||||
+#include <phosphor-logging/lg2.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
+#include <unordered_map>
|
||||
+#include <filesystem>
|
||||
+#include <fstream>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@@ -230,6 +235,14 @@ using AdditionalList = std::vector<std::string>;
|
||||
using sensorCodes = std::vector<uint8_t>;
|
||||
using ipmiSensorsInfo = std::unordered_map<std::string, sensorCodes>;
|
||||
std::optional<ipmiSensorsInfo> ipmiSensors;
|
||||
+struct SensorInfo
|
||||
+{
|
||||
+ std::string sensorName;
|
||||
+ uint8_t readingType;
|
||||
+ uint8_t sensorType;
|
||||
+};
|
||||
+
|
||||
+using SensorMessages = std::unordered_map<std::string, SensorInfo>;
|
||||
|
||||
const std::unordered_map<uint8_t, discrectSensorEvent> genericEventTypes{
|
||||
{0x03,
|
||||
@@ -376,6 +389,72 @@ static const std::unordered_map<std::string, std::vector<uint8_t>>
|
||||
EVENT_TYPE_07H_TRANSITION_TO_NC_FROM_OK}},
|
||||
};
|
||||
|
||||
+static constexpr auto sensorJsonPath =
|
||||
+ "/usr/share/ipmi-providers/sensor-data-record.json";
|
||||
+
|
||||
+SensorMessages loadSensorFromJson()
|
||||
+{
|
||||
+ try
|
||||
+ {
|
||||
+ const std::filesystem::path path(sensorJsonPath);
|
||||
+ SensorMessages sensorMessages;
|
||||
+ const nlohmann::json empty{};
|
||||
+ nlohmann::json js;
|
||||
+ if (!std::filesystem::exists(path) || std::filesystem::is_empty(path))
|
||||
+ {
|
||||
+ std::cout << "Incorrect File Path or empty file, FILE_PATH = "
|
||||
+ << path << std::endl;
|
||||
+ return sensorMessages;
|
||||
+ }
|
||||
+
|
||||
+ try
|
||||
+ {
|
||||
+ std::ifstream jsonFile(path);
|
||||
+ js = nlohmann::json::parse(jsonFile);
|
||||
+ }
|
||||
+ catch (const std::exception& e)
|
||||
+ {
|
||||
+ std::cout << "Failed to parse config file, ERROR = " << e.what()
|
||||
+ << ", FILE_PATH = " << path << std::endl;
|
||||
+ throw std::runtime_error("Failed to parse config file");
|
||||
+ }
|
||||
+
|
||||
+ for (const auto& sensor : js.items())
|
||||
+ {
|
||||
+ SensorInfo info;
|
||||
+ std::string sensorPath = sensor.key();
|
||||
+ auto sensorParam = sensor.value();
|
||||
+ info.sensorName = sensorParam["sensorName"];
|
||||
+ info.readingType = sensorParam["sensorReadingType"];
|
||||
+ info.sensorType = sensorParam["sensorType"];
|
||||
+ sensorMessages.insert(std::make_pair(sensorPath, std::move(info)));
|
||||
+ }
|
||||
+ return sensorMessages;
|
||||
+ }
|
||||
+ catch (const std::exception& e)
|
||||
+ {
|
||||
+ throw std::runtime_error("Failed to parse sensor config file");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+const SensorMessages& getSensorMessages()
|
||||
+{
|
||||
+ static const SensorMessages sensorMessages = loadSensorFromJson();
|
||||
+ return sensorMessages;
|
||||
+}
|
||||
+
|
||||
+std::optional<SensorInfo>
|
||||
+ getSensorInfo(const std::string& sensorPath)
|
||||
+{
|
||||
+ const auto& sensorMessages = getSensorMessages();
|
||||
+ auto ite = sensorMessages.find(sensorPath);
|
||||
+ if (ite == sensorMessages.end())
|
||||
+ {
|
||||
+ return std::nullopt;
|
||||
+ }
|
||||
+ return std::make_optional(ite->second);
|
||||
+}
|
||||
+
|
||||
std::optional<ipmiSensorsInfo> initIPMISensorInfo(sdbusplus::bus::bus& bus)
|
||||
{
|
||||
constexpr auto service = "xyz.openbmc_project.Ipmi.Host";
|
||||
@@ -1212,19 +1291,11 @@ void Add::filterSEL(sdbusplus::bus::bus& bus, const std::string& path)
|
||||
}
|
||||
}
|
||||
|
||||
- if (!ipmiSensors)
|
||||
+ auto sensorInfo = getSensorInfo(sensorPath);
|
||||
+ if (sensorInfo != std::nullopt)
|
||||
{
|
||||
- ipmiSensors = initIPMISensorInfo(bus);
|
||||
- }
|
||||
-
|
||||
- if (ipmiSensors)
|
||||
- {
|
||||
- auto iter = ipmiSensors->find(sensorPath);
|
||||
- if (iter != ipmiSensors->end())
|
||||
- {
|
||||
- sensorType = iter->second[0];
|
||||
- typeCode = iter->second[1];
|
||||
- }
|
||||
+ sensorType = sensorInfo->sensorType;
|
||||
+ typeCode = sensorInfo->readingType;
|
||||
}
|
||||
|
||||
if (sensorData == "" || typeCode == 0 || eventDir == "" || sensorType == 0)
|
||||
--
|
||||
2.34.1
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$#" -ne 3 ]; then
|
||||
echo "Usage: ./dimm_led_test.sh <CPU> <LETTER> <LED_STATE>"
|
||||
echo "CPU: 0~1"
|
||||
echo "LETTER: A~L"
|
||||
echo "LED_STATE: ON, FAULT, OFF, NA"
|
||||
echo "Example: ./dimm_led_test.sh 0 A ON"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CPU=\$1
|
||||
LETTER=\$2
|
||||
LED_STATE=\$3
|
||||
|
||||
BASE_COMMAND="busctl set-property xyz.openbmc_project.DIMMTempSensor"
|
||||
|
||||
COMMAND="${BASE_COMMAND} /xyz/openbmc_project/sensors/temperature/DIMM_CPU${CPU}_${LETTER}_Temp xyz.openbmc_project.Sensor.dimmLED LEDState s \"${LED_STATE}\""
|
||||
|
||||
echo "Executing: $COMMAND at $(date)"
|
||||
|
||||
eval $COMMAND
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
|
||||
|
||||
DEPENDS += "i2c-tools"
|
||||
|
||||
SRC_URI += "file://0001-Add-discrete-sensor-status-parsing-according-to-sel.patch \
|
||||
file://0001-Remove-dissen-path-update-sensor-status.patch \
|
||||
file://0001-Add-DIMM-Status-discrete-sensors.patch \
|
||||
file://0002-Add-power-button-and-PSU-status-sensor.patch \
|
||||
file://0001-Implement-DIMM-LED-control.patch \
|
||||
file://0003-Add-BMC-Boot-sensor.patch \
|
||||
file://0001-Add-PROCESSOR-sensor-type.patch \
|
||||
file://0001-Enable-Orange-LED-to-indicate-if-dimm-is-present.patch \
|
||||
file://0004-Support-discrete-generic-sensors.patch \
|
||||
file://0001-Add-watchdog2-sensor-type.patch \
|
||||
file://0005-Clear-Status-of-sensors-when-power-on.patch \
|
||||
file://0006-Fix-sensor-status-being-cleared-due-to-warm-reset.patch \
|
||||
file://0007-Retrieve-SEL-sensor-info-from-JSON-file-instead-of-c.patch \
|
||||
file://dimm_led_test.sh \
|
||||
"
|
||||
|
||||
do_install:append () {
|
||||
install -d ${D}${bindir}
|
||||
install -m 0755 ${WORKDIR}/dimm_led_test.sh ${D}${bindir}/
|
||||
}
|
||||
Reference in New Issue
Block a user