Initial commit

This commit is contained in:
Your Name
2026-04-23 17:07:55 +08:00
commit b7e39e063b
16725 changed files with 1625565 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+41
View File
@@ -0,0 +1,41 @@
This README file contains information on the contents of the meta-common layer.
Please see the corresponding sections below for details.
Dependencies
============
URI: <first dependency>
branch: <branch name>
URI: <second dependency>
branch: <branch name>
.
.
.
Patches
=======
Please submit any patches against the meta-common layer to the xxxx mailing list (xxxx@zzzz.org)
and cc: the maintainer:
Maintainer: XXX YYYYYY <xxx.yyyyyy@zzzzz.com>
Table of Contents
=================
I. Adding the meta-common layer to your build
II. Misc
I. Adding the meta-common layer to your build
=================================================
Run 'bitbake-layers add-layer meta-common'
II. Misc
========
--- replace with specific information about the meta-common layer ---
+13
View File
@@ -0,0 +1,13 @@
# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"
# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "meta-common"
BBFILE_PATTERN_meta-common = "^${LAYERDIR}/"
BBFILE_PRIORITY_meta-common = "13"
LAYERDEPENDS_meta-common = "core"
LAYERSERIES_COMPAT_meta-common = "mickledore"
@@ -0,0 +1,61 @@
From 4d636c9d43fcaec7807e08c5cc7ba7984e18a58a Mon Sep 17 00:00:00 2001
From: "Chen.Zhao" <zhao.chen@luxshare-ict.com>
Date: Mon, 23 Dec 2024 16:29:06 +0800
Subject: [PATCH] Force set mac from eeprom even if current mac is valid
---
board/aspeed/evb_ast2600/evb_ast2600.c | 2 ++
cmd/nvedit.c | 3 +++
include/configs/aspeed-common.h | 2 ++
3 files changed, 7 insertions(+)
diff --git a/board/aspeed/evb_ast2600/evb_ast2600.c b/board/aspeed/evb_ast2600/evb_ast2600.c
index dfb4c7c7ef..62b2cb3585 100644
--- a/board/aspeed/evb_ast2600/evb_ast2600.c
+++ b/board/aspeed/evb_ast2600/evb_ast2600.c
@@ -220,6 +220,7 @@ int mac_read_from_eeprom(void)
u8 ethaddr[MAC_NUM*MAC_BYTE_SIZE];
char addr_str[100];
+ printf("mac_read_from_eeprom\n");
memset(ethaddr, 0, sizeof(ethaddr));
if (get_ethaddr_from_eeprom(ethaddr)) {
@@ -228,6 +229,7 @@ int mac_read_from_eeprom(void)
}
for (int i = 0; i < MAC_NUM; i++) {
if (is_valid_ethaddr(&ethaddr[MAC_BYTE_SIZE*i])) {
+ printf("eth%d mac:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",i,ethaddr[0+6*i],ethaddr[1+6*i],ethaddr[2+6*i],ethaddr[3+6*i],ethaddr[4+6*i],ethaddr[5+6*i]);
memset(addr_str, 0, sizeof(addr_str));
if (i == 0) {
snprintf(addr_str, sizeof(addr_str), "ethaddr");
diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 24a6cf7824..2df944eefb 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -373,8 +373,11 @@ int eth_env_set_enetaddr(const char *name, const uint8_t *enetaddr)
{
char buf[ARP_HLEN_ASCII + 1];
+ /*Luxshare remark this code to force write ethaddr and not check current mac address */
+ #if 0
if (eth_env_get_enetaddr(name, (uint8_t *)buf))
return -EEXIST;
+ #endif
sprintf(buf, "%pM", enetaddr);
diff --git a/include/configs/aspeed-common.h b/include/configs/aspeed-common.h
index 62570cea47..5892b28b2f 100644
--- a/include/configs/aspeed-common.h
+++ b/include/configs/aspeed-common.h
@@ -86,4 +86,6 @@
#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
#endif
+#define CONFIG_ENV_OVERWRITE
+
#endif /* __ASPEED_COMMON_CONFIG_H */
--
2.25.1
@@ -0,0 +1,57 @@
From d562b57f2a21125bcfb7268099aa29dea6f005f2 Mon Sep 17 00:00:00 2001
From: "Chen.Zhao" <zhao.chen@luxshare-ict.com>
Date: Tue, 18 Mar 2025 17:43:34 +0800
Subject: [PATCH] Force use ctrl l to entre uboot command line
---
common/autoboot.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/common/autoboot.c b/common/autoboot.c
index d54f1c431f..9c1edfb16e 100644
--- a/common/autoboot.c
+++ b/common/autoboot.c
@@ -216,9 +216,9 @@ static int __abortboot(int bootdelay)
#ifdef CONFIG_MENUPROMPT
printf(CONFIG_MENUPROMPT);
#else
- printf("Hit any key to stop autoboot: %2d ", bootdelay);
+ printf("Hit ctrl+l to stop autoboot: %2d ", bootdelay);
#endif
-
+#if 0
/*
* Check if key already pressed
*/
@@ -227,21 +227,21 @@ static int __abortboot(int bootdelay)
puts("\b\b\b 0");
abort = 1; /* don't auto boot */
}
-
+#endif
while ((bootdelay > 0) && (!abort)) {
--bootdelay;
/* delay 1000 ms */
ts = get_timer(0);
do {
if (tstc()) { /* we got a key press */
- abort = 1; /* don't auto boot */
- bootdelay = 0; /* no more delay */
+ if(0x0c == getc()){ /* 0x0c is ctrl+l */
+ abort = 1; /* don't auto boot */
+ bootdelay = 0; /* no more delay */
# ifdef CONFIG_MENUKEY
- menukey = getc();
-# else
- (void) getc(); /* consume input */
+ menukey = getc();
# endif
- break;
+ break;
+ }
}
udelay(10000);
} while (!abort && get_timer(ts) < 1000);
--
2.25.1
@@ -0,0 +1,380 @@
From 96a4361b92455982ea3e9c71aae436a65a7a6a3e Mon Sep 17 00:00:00 2001
From: "Zhao.Chen" <zhao.chen@luxshare-ict.com>
Date: 10 Sep 2024 14:37:07 +0000
Read the MAC address from EEPROM and set it to env.
Tested:
printenv
ethaddr=88:88:88:88:88:8b
eth1addr=88:88:88:88:88:8d
%% original patch: 0002-read-mac-address-from-eeprom.patch
---
board/aspeed/evb_ast2600/Kconfig | 5 +
board/aspeed/evb_ast2600/evb_ast2600.c | 79 ++++++++++
common/board_r.c | 3 +-
drivers/misc/Kconfig | 6 +
drivers/misc/Makefile | 1 +
drivers/misc/at24.c | 204 +++++++++++++++++++++++++
6 files changed, 297 insertions(+), 1 deletion(-)
create mode 100644 drivers/misc/at24.c
diff --git a/board/aspeed/evb_ast2600/Kconfig b/board/aspeed/evb_ast2600/Kconfig
index a5d105199f..839cd0e649 100644
--- a/board/aspeed/evb_ast2600/Kconfig
+++ b/board/aspeed/evb_ast2600/Kconfig
@@ -10,4 +10,9 @@ config SYS_CONFIG_NAME
string "board configuration name"
default "evb_ast2600"
+config MAC_ADDR_IN_EEPROM
+ bool "MAC address in EEPROM"
+ help
+ Enable this option to read the MAC from the EEPROM
+
endif
diff --git a/board/aspeed/evb_ast2600/evb_ast2600.c b/board/aspeed/evb_ast2600/evb_ast2600.c
index 72ecb18c15..7244686bb1 100644
--- a/board/aspeed/evb_ast2600/evb_ast2600.c
+++ b/board/aspeed/evb_ast2600/evb_ast2600.c
@@ -131,3 +131,82 @@ int board_early_init_f(void)
espi_init();
return 0;
}
+
+#if defined(CONFIG_MAC_ADDR_IN_EEPROM)
+
+#include <dm.h>
+#include <environment.h>
+#include <i2c_eeprom.h>
+
+#define MAC_NUM 2
+#define MAC_BYTE_SIZE 6
+
+static int get_ethaddr_from_eeprom(u8 *addr)
+{
+ struct udevice *dev;
+ u32 mac_offset[MAC_NUM];
+ int i, ret, mac_read;
+
+ uclass_first_device_check(UCLASS_I2C_EEPROM, &dev);
+ if (!dev) {
+ printf("No eeprom found.\n");
+ } else {
+ do {
+ if (dev_read_bool(dev, "ethaddr-in-eeprom")) {
+ char prop_mac_offset[32];
+ mac_read = 0;
+ for (i = 0; i < MAC_NUM; i++) {
+ snprintf(prop_mac_offset, 32, "eth%d-offset", i);
+ ret = dev_read_u32(dev, prop_mac_offset, &mac_offset[i]);
+ if (0 == ret) {
+ ret = i2c_eeprom_read(dev, mac_offset[i],
+ addr+i*MAC_BYTE_SIZE, MAC_BYTE_SIZE);
+ if (ret != 0) {
+ printf("get eth%d from eeprom failed, offset=0x%x\n",
+ i, mac_offset[i]);
+ return -1;
+ } else {
+ mac_read++;
+ }
+ }
+ }
+ if (mac_read > 0)
+ return 0;
+ }
+ uclass_next_device_check(&dev);
+ } while (dev);
+ }
+ return -1;
+}
+
+int mac_read_from_eeprom(void)
+{
+ u8 ethaddr[MAC_NUM*MAC_BYTE_SIZE];
+ char addr_str[100];
+
+ memset(ethaddr, 0, sizeof(ethaddr));
+
+ if (get_ethaddr_from_eeprom(ethaddr)) {
+ printf("get ethaddr from eeprom failed.\n");
+ return 0;
+ }
+ for (int i = 0; i < MAC_NUM; i++) {
+ if (is_valid_ethaddr(&ethaddr[MAC_BYTE_SIZE*i])) {
+ memset(addr_str, 0, sizeof(addr_str));
+ if (i == 0) {
+ snprintf(addr_str, sizeof(addr_str), "ethaddr");
+ } else {
+ snprintf(addr_str, sizeof(addr_str), "eth%daddr", i);
+ }
+ eth_env_set_enetaddr(addr_str, &ethaddr[MAC_BYTE_SIZE*i]);
+ env_save();
+ } else {
+ printf("eeprom mac%d address invaild:%pM\n", i, \
+ &ethaddr[MAC_BYTE_SIZE*i]);
+ }
+ }
+
+ return 0;
+}
+#endif
+
diff --git a/common/board_r.c b/common/board_r.c
index 429b9a2833..f1c98362ac 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -744,7 +744,8 @@ static init_fnc_t init_sequence_r[] = {
#endif
INIT_FUNC_WATCHDOG_RESET
initr_secondary_cpu,
-#if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET)
+#if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET) \
+ || defined(CONFIG_MAC_ADDR_IN_EEPROM)
mac_read_from_eeprom,
#endif
INIT_FUNC_WATCHDOG_RESET
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index c2a188ac29..69eeaf51fa 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -260,6 +260,12 @@ config SPL_I2C_EEPROM
This option is an SPL-variant of the I2C_EEPROM option.
See the help of I2C_EEPROM for details.
+config EEPROM_AT24
+ bool "Enable driver for AT24 EEPROMs"
+ depends on MISC
+ help
+ Enable a driver for AT24 EEPROMs attached via I2C.
+
config ZYNQ_GEM_I2C_MAC_OFFSET
hex "Set the I2C MAC offset"
default 0x0
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index bee53a3559..4e76c7d398 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_GDSYS_IOEP) += gdsys_ioep.o
obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o
obj-$(CONFIG_GDSYS_SOC) += gdsys_soc.o
obj-$(CONFIG_$(SPL_)I2C_EEPROM) += i2c_eeprom.o
+obj-$(CONFIG_$(SPL_)EEPROM_AT24) += at24.o
obj-$(CONFIG_IHS_FPGA) += ihs_fpga.o
obj-$(CONFIG_IMX8) += imx8/
obj-$(CONFIG_LED_STATUS) += status_led.o
diff --git a/drivers/misc/at24.c b/drivers/misc/at24.c
new file mode 100644
index 0000000000..e117098766
--- /dev/null
+++ b/drivers/misc/at24.c
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2014 Google, Inc
+ */
+
+#include <common.h>
+#include <linux/err.h>
+#include <dm.h>
+#include <i2c.h>
+#include <i2c_eeprom.h>
+
+/* Address pointer is 16 bit. */
+#define AT24_FLAG_ADDR16 BIT(7)
+/* sysfs-entry will be read-only. */
+#define AT24_FLAG_READONLY BIT(6)
+/* sysfs-entry will be world-readable. */
+#define AT24_FLAG_IRUGO BIT(5)
+/* Take always 8 addresses (24c00). */
+#define AT24_FLAG_TAKE8ADDR BIT(4)
+/* Factory-programmed serial number. */
+#define AT24_FLAG_SERIAL BIT(3)
+/* Factory-programmed mac address. */
+#define AT24_FLAG_MAC BIT(2)
+/* Does not auto-rollover reads to the next slave address. */
+#define AT24_FLAG_NO_RDROL BIT(1)
+
+struct at24_chip_data {
+ struct udevice *dev;
+ u32 byte_len;
+ u8 flags;
+ void (*read_post)(unsigned int off, char *buf, size_t count);
+};
+
+#define AT24_CHIP_DATA(_name, _len, _flags) \
+ static const struct at24_chip_data _name = { \
+ .byte_len = _len, .flags = _flags, \
+ }
+
+AT24_CHIP_DATA(at24_data_24c08, 8192 / 8, AT24_FLAG_NO_RDROL);
+AT24_CHIP_DATA(at24_data_24c16, 16384 / 8, AT24_FLAG_NO_RDROL);
+AT24_CHIP_DATA(at24_data_24c32, 32768 / 8, AT24_FLAG_ADDR16);
+AT24_CHIP_DATA(at24_data_24c64, 65536 / 8, AT24_FLAG_ADDR16);
+
+int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int size)
+{
+ const struct i2c_eeprom_ops *ops = device_get_ops(dev);
+
+ if (!ops->read)
+ return -ENOSYS;
+
+ return ops->read(dev, offset, buf, size);
+}
+
+int i2c_eeprom_write(struct udevice *dev, int offset, uint8_t *buf, int size)
+{
+ const struct i2c_eeprom_ops *ops = device_get_ops(dev);
+
+ if (!ops->write)
+ return -ENOSYS;
+
+ return ops->write(dev, offset, buf, size);
+}
+
+/*
+ * This routine supports chips which consume multiple I2C addresses. It
+ * computes the addressing information to be used for a given r/w request.
+ * Assumes that sanity checks for offset happened at sysfs-layer.
+ *
+ * Slave address and byte offset derive from the offset. Always
+ * set the byte address; on a multi-master board, another master
+ * may have changed the chip's "current" address pointer.
+ */
+static unsigned int at24_translate_offset(struct at24_chip_data *at24,
+ unsigned int *offset)
+{
+ unsigned int i = 0;
+
+ if (at24->flags & AT24_FLAG_ADDR16) {
+ i = *offset >> 16;
+ *offset &= 0xffff;
+ } else {
+ i = *offset >> 8;
+ *offset &= 0xff;
+ }
+
+ return i;
+}
+
+static size_t at24_adjust_read_count(struct at24_chip_data *at24,
+ unsigned int offset, size_t count)
+{
+ unsigned int bits;
+ size_t remainder;
+
+ /*
+ * In case of multi-address chips that don't rollover reads to
+ * the next slave address: truncate the count to the slave boundary,
+ * so that the read never straddles slaves.
+ */
+ if (at24->flags & AT24_FLAG_NO_RDROL) {
+ bits = (at24->flags & AT24_FLAG_ADDR16) ? 16 : 8;
+ remainder = BIT(bits) - offset;
+ if (count > remainder)
+ count = remainder;
+ }
+
+ return count;
+}
+
+static ssize_t at24_read(struct at24_chip_data *at24, uint8_t *buf,
+ unsigned int offset, size_t count)
+{
+ int ret;
+ struct dm_i2c_chip *chip = dev_get_parent_platdata(at24->dev);
+ u8 chip_addr = chip->chip_addr;
+ int chip_addr_offset = at24_translate_offset(at24, &offset);
+
+ count = at24_adjust_read_count(at24, offset, count);
+ chip->chip_addr += chip_addr_offset;
+ ret = dm_i2c_read(at24->dev, offset, buf, count);
+ chip->chip_addr = chip_addr;
+
+ if (0 == ret) {
+ return count;
+ } else {
+ return -ETIMEDOUT;
+ }
+}
+
+static int i2c_eeprom_std_read(struct udevice *dev, int off, uint8_t *buf,
+ int size)
+{
+ struct at24_chip_data *at24;
+ int i, ret;
+
+ at24 = (struct at24_chip_data *)dev_get_driver_data(dev);
+
+ if (off + size > at24->byte_len)
+ return -EINVAL;
+
+ for (i = 0; size; i += ret, size -= ret) {
+ ret = at24_read(at24, buf + i, off + i, size);
+ if (ret < 0) {
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+static int i2c_eeprom_std_write(struct udevice *dev, int offset,
+ const uint8_t *buf, int size)
+{
+ return -ENODEV;
+}
+
+static const struct i2c_eeprom_ops i2c_eeprom_std_ops = {
+ .read = i2c_eeprom_std_read,
+ .write = i2c_eeprom_std_write,
+};
+
+static int i2c_eeprom_std_ofdata_to_platdata(struct udevice *dev)
+{
+ struct at24_chip_data *data;
+ struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+
+ data = (struct at24_chip_data *)dev_get_driver_data(dev);
+ data->dev = dev;
+
+ if (data->flags & AT24_FLAG_ADDR16)
+ chip->offset_len = 2;
+ else
+ chip->offset_len = 1;
+
+ return 0;
+}
+
+static int i2c_eeprom_std_probe(struct udevice *dev)
+{
+ return 0;
+}
+
+static const struct udevice_id i2c_eeprom_std_ids[] = {
+ { .compatible = "atmel,24c08", .data = (ulong)&at24_data_24c08 },
+ { .compatible = "atmel,24c16", .data = (ulong)&at24_data_24c16 },
+ { .compatible = "atmel,24c32", .data = (ulong)&at24_data_24c32 },
+ { .compatible = "atmel,24c64", .data = (ulong)&at24_data_24c64 },
+ { /* END OF LIST */ },
+};
+
+U_BOOT_DRIVER(i2c_eeprom_std) = {
+ .name = "i2c_eeprom_at24",
+ .id = UCLASS_I2C_EEPROM,
+ .of_match = i2c_eeprom_std_ids,
+ .probe = i2c_eeprom_std_probe,
+ .ofdata_to_platdata = i2c_eeprom_std_ofdata_to_platdata,
+ .priv_auto_alloc_size = sizeof(struct i2c_eeprom),
+ .ops = &i2c_eeprom_std_ops,
+};
+
+UCLASS_DRIVER(i2c_eeprom) = {
+ .id = UCLASS_I2C_EEPROM,
+ .name = "i2c_eeprom_at24",
+};
--
2.35.3
@@ -0,0 +1,110 @@
From 119df9b1a20361b1721dd72803caa9986af5e582 Mon Sep 17 00:00:00 2001
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
Date: Fri, 25 Oct 2024 14:28:46 +0800
Subject: [PATCH 2/2] u boot Update system reset event Test:
/usr/sbin/fw_printenv system_reset_event=0xff31
---
arch/arm/mach-aspeed/ast2600/scu_info.c | 5 ++++-
board/aspeed/evb_ast2600/evb_ast2600.c | 11 +++++++++++
common/board_r.c | 3 +++
include/asm-generic/global_data.h | 3 +++
include/init.h | 4 ++++
5 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-aspeed/ast2600/scu_info.c b/arch/arm/mach-aspeed/ast2600/scu_info.c
index a2277eec58..cf5cea3b12 100644
--- a/arch/arm/mach-aspeed/ast2600/scu_info.c
+++ b/arch/arm/mach-aspeed/ast2600/scu_info.c
@@ -9,6 +9,8 @@
#include <asm/io.h>
#include <asm/arch/aspeed_scu_info.h>
+DECLARE_GLOBAL_DATA_PTR;
+
/* SoC mapping Table */
#define SOC_ID(str, rev) { .name = str, .rev_id = rev, }
@@ -217,7 +219,8 @@ void aspeed_print_sysrst_info(void)
{
u32 rest = readl(ASPEED_SYS_RESET_CTRL);
u32 rest3 = readl(ASPEED_SYS_RESET_CTRL3);
-
+
+ gd->reset_reason = rest;
if (rest & SYS_PWR_RESET_FLAG) {
printf("RST: Power On \n");
writel(rest, ASPEED_SYS_RESET_CTRL);
diff --git a/board/aspeed/evb_ast2600/evb_ast2600.c b/board/aspeed/evb_ast2600/evb_ast2600.c
index 7244686bb1..668ae5c855 100644
--- a/board/aspeed/evb_ast2600/evb_ast2600.c
+++ b/board/aspeed/evb_ast2600/evb_ast2600.c
@@ -30,6 +30,8 @@
/* HICRB Bits */
#define HICRB_EN80HSGIO (1 << 13) /* Enable 80hSGIO */
+DECLARE_GLOBAL_DATA_PTR;
+
static void __maybe_unused port80h_snoop_init(void)
{
u32 value;
@@ -210,3 +212,12 @@ int mac_read_from_eeprom(void)
}
#endif
+int update_system_reset_event(void)
+{
+ char str_value[20];
+ memset(str_value, 0, sizeof(str_value));
+ snprintf(str_value, sizeof(str_value), "0x%x", gd->reset_reason);
+ env_set("system_reset_event", str_value);
+ env_save();
+ return 0;
+}
\ No newline at end of file
diff --git a/common/board_r.c b/common/board_r.c
index f1c98362ac..3ad64b881a 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -747,6 +747,9 @@ static init_fnc_t init_sequence_r[] = {
#if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET) \
|| defined(CONFIG_MAC_ADDR_IN_EEPROM)
mac_read_from_eeprom,
+#endif
+#ifdef CONFIG_ASPEED_AST2600
+ update_system_reset_event,
#endif
INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_PCI) && !defined(CONFIG_SYS_EARLY_PCI_INIT)
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 78dcf40bff..e81adabf1e 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -133,6 +133,9 @@ typedef struct global_data {
struct spl_handoff *spl_handoff;
# endif
#endif
+#ifdef CONFIG_ASPEED_AST2600
+ u32 reset_reason;
+#endif
} gd_t;
#endif
diff --git a/include/init.h b/include/init.h
index afc953d51e..009f591ea2 100644
--- a/include/init.h
+++ b/include/init.h
@@ -177,6 +177,10 @@ int misc_init_r(void);
int init_func_vid(void);
#endif
+#ifdef CONFIG_ASPEED_AST2600
+int update_system_reset_event(void);
+#endif
+
/* common/board_info.c */
int checkboard(void);
int show_board_info(void);
--
2.25.1
@@ -0,0 +1,97 @@
From b3de8eb1967673d858fee96531698d8aab436a78 Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Wed, 27 Nov 2024 17:45:08 +0800
Subject: [PATCH] Enable FMC WDT2
---
board/aspeed/evb_ast2600/evb_ast2600.c | 42 ++++++++++++++++++++++++++
common/autoboot.c | 5 +++
2 files changed, 47 insertions(+)
diff --git a/board/aspeed/evb_ast2600/evb_ast2600.c b/board/aspeed/evb_ast2600/evb_ast2600.c
index 668ae5c855..dfb4c7c7ef 100644
--- a/board/aspeed/evb_ast2600/evb_ast2600.c
+++ b/board/aspeed/evb_ast2600/evb_ast2600.c
@@ -13,6 +13,11 @@
#define LPC_SNPWADR (LPC_BASE + 0x90)
#define LPC_HICRB (LPC_BASE + 0x100)
#define GPIO_BASE 0x1e780000
+#define FMC_BASE 0x1e620000
+#define FMC_WDT2_CTRL (FMC_BASE + 0x64)
+#define FMC_WDT2_TIMER_RELOAD_VALUE (FMC_BASE + 0x68)
+#define FMC_WDT2_TIMER_RESTART (FMC_BASE + 0x6c)
+#define WDT2_CTRL_ENABLE_WDT (1 << 0)
/* HICR5 Bits */
#define HICR5_EN_SIOGIO (1 << 31) /* Enable SIOGIO */
@@ -124,8 +129,37 @@ static void __maybe_unused espi_init(void)
writel(reg, ESPI_BASE + 0x000);
}
+static void __maybe_unused enable_fmc_wdt2(uint16_t expire_time)
+{
+ const u16 max_expire_time = 0x1fff;
+ const u16 timer_restart_cmd = 0x4755;
+ u32 reg;
+
+ if (expire_time > max_expire_time) {
+ expire_time = max_expire_time;
+ }
+
+ // The time unit is 0.1 second. The range is 0 to 0x1fff.
+ writel(expire_time, FMC_WDT2_TIMER_RELOAD_VALUE);
+ // Write 0x4755 value to load the reload value into watchdog counter
+ writel(timer_restart_cmd, FMC_WDT2_TIMER_RESTART);
+ // Enable FMC WDT2
+ reg = readl(FMC_WDT2_CTRL) | (WDT2_CTRL_ENABLE_WDT);
+ writel(reg, FMC_WDT2_CTRL);
+}
+
+void __maybe_unused disable_fmc_wdt2(void)
+{
+ u32 reg;
+
+ reg = readl(FMC_WDT2_CTRL) & ~(WDT2_CTRL_ENABLE_WDT);
+ writel(reg, FMC_WDT2_CTRL);
+}
+
int board_early_init_f(void)
{
+ disable_fmc_wdt2();
+ enable_fmc_wdt2(7800); // expire time: 13 minutes
#if 0
port80h_snoop_init();
sgpio_init();
@@ -220,4 +254,12 @@ int update_system_reset_event(void)
env_set("system_reset_event", str_value);
env_save();
return 0;
+}
+
+void board_preboot_os(void)
+{
+ const u16 expire_time = 780; // 13 minutes
+
+ enable_fmc_wdt2(expire_time * 10);
+ printf("Enable FMC WDT2: expire time is %d seconds.", expire_time);
}
\ No newline at end of file
diff --git a/common/autoboot.c b/common/autoboot.c
index 94133eaeda..d54f1c431f 100644
--- a/common/autoboot.c
+++ b/common/autoboot.c
@@ -267,6 +267,11 @@ static int abortboot(int bootdelay)
gd->flags &= ~GD_FLG_SILENT;
#endif
+#ifdef CONFIG_ASPEED_AST2600
+ if (abort)
+ disable_fmc_wdt2();
+#endif
+
return abort;
}
--
2.25.1
@@ -0,0 +1,9 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI:append = " \
file://0001-Read-mac-address-from-eeprom.patch \
file://0002-u-boot-Update-system-reset-event.patch \
file://0003-Enable-FMC-WDT2.patch \
file://0001-Force-set-mac-from-eeprom-even-if-current-mac-is-val.patch \
file://0001-Force-use-ctrl-l-to-entre-uboot-command-line.patch \
"
@@ -0,0 +1,2 @@
CONFIG_DEVMEM=y
CONFIG_DEVMEM_BOOTPARAM=n
@@ -0,0 +1,16 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
KBRANCH = "master"
LINUX_VERSION = "6.1.61"
KBUILD_DEFCONFIG = "intel_bmc_defconfig"
SRC_URI = "\
git://${THISDIR}/../../../meta-luxshare/source/${PN};branch=${KBRANCH} \
file://debug.cfg \
"
SRCREV="b3896e5dc826a3d88eb6dd11d99c60a64c7370a3"
do_compile:prepend(){
# device tree compiler flags
export DTC_FLAGS=-@
}
@@ -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/
}
@@ -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}
}
@@ -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}"
@@ -0,0 +1,7 @@
[Unit]
Description=BMC reboot delay
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/obmc-reboot-delay
@@ -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"
File diff suppressed because it is too large Load Diff
@@ -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
@@ -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')
@@ -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"
@@ -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);
}
@@ -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
@@ -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')
@@ -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
@@ -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
@@ -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 "
@@ -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
@@ -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;
}
@@ -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
*/
@@ -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
@@ -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
@@ -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
@@ -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";
}
}
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 onDo 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
@@ -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
@@ -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
@@ -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}/
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,18 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI += " \
file://ipmi_user.json \
file://ipmi_user_public.json \
"
do_install:append(){
install -d ${D}/${localstatedir}/lib/ipmi
install -m 644 ${WORKDIR}/ipmi_user.json ${D}/${localstatedir}/lib/ipmi/ipmi_user.json
}
do_install:append(){
install -d ${D}/${localstatedir}/lib/ipmi
install -m 644 ${WORKDIR}/ipmi_user_public.json ${D}/${localstatedir}/lib/ipmi/ipmi_user.json
}
PACKAGECONFIG:remove = " allowlist "
@@ -0,0 +1,51 @@
From 195d528024bda107f9b7ab883883db9d0a917f3d Mon Sep 17 00:00:00 2001
From: Jonathan Doman <jonathan.doman@intel.com>
Date: Fri, 11 Mar 2022 11:58:55 -0800
Subject: [PATCH] Output error message for invalid device
Lack of error message when user provided invalid device results in
confusion. Make it clear what is wrong.
Signed-off-by: Jonathan Doman <jonathan.doman@intel.com>
Upstream-Status: Pending
---
i3ctransfer.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/i3ctransfer.c b/i3ctransfer.c
index 816b9ad..413f547 100644
--- a/i3ctransfer.c
+++ b/i3ctransfer.c
@@ -103,9 +103,9 @@ static void print_rx_data(struct i3c_ioc_priv_xfer *xfer)
int main(int argc, char *argv[])
{
struct i3c_ioc_priv_xfer *xfers;
- int file, ret, opt, i;
+ int file = -1, ret, opt, i;
int nxfers = 0;
- char *device;
+ char *device = NULL;
while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != EOF) {
switch (opt) {
@@ -130,12 +130,13 @@ int main(int argc, char *argv[])
}
}
- if (!device)
- exit(EXIT_FAILURE);
+ if (device)
+ file = open(device, O_RDWR);
- file = open(device, O_RDWR);
- if (file < 0)
+ if (file < 0) {
+ fprintf(stderr, "Error: %s\n", device ? strerror(errno) : "No device provided");
exit(EXIT_FAILURE);
+ }
xfers = (struct i3c_ioc_priv_xfer *)calloc(nxfers, sizeof(*xfers));
if (!xfers)
--
2.35.1
@@ -0,0 +1,18 @@
SUMMARY = "i3c-tools"
DESCRIPTION = "Set of tools to interact with i3c devices from user space"
SRC_URI = "git://github.com/vitor-soares-snps/i3c-tools.git;branch=master;protocol=https \
file://0001-Output-error-message-for-invalid-device.patch \
"
SRCREV = "5d752038c72af8e011a2cf988b1476872206e706"
S = "${WORKDIR}/git"
PV = "0.1+git${SRCPV}"
LICENSE = "GPL-2.0"
LIC_FILES_CHKSUM = "\
file://i3ctransfer.c;beginline=1;endline=6;md5=8a1ae5c1aaf128e640de497ceaa9935e \
"
inherit meson