summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am13
-rw-r--r--configure.ac4
-rw-r--r--fruread.hpp29
-rw-r--r--scripts/example.yaml119
-rwxr-xr-xscripts/fru_gen.py59
-rw-r--r--scripts/readfru.mako.cpp35
6 files changed, 257 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index d987cc3..7317cce 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,7 +6,12 @@ sbin_PROGRAMS = \
ipmid_SOURCES = \
ipmid.cpp
nodist_ipmid_SOURCES = ipmiwhitelist.cpp
-BUILT_SOURCES = ipmiwhitelist.cpp sensor-gen.cpp inventory-sensor-gen.cpp
+BUILT_SOURCES = \
+ ipmiwhitelist.cpp \
+ sensor-gen.cpp \
+ inventory-sensor-gen.cpp \
+ fru-read-gen.cpp
+
CLEANFILES = $(BUILT_SOURCES)
#TODO - Make this path a configure option (bitbake parameter)
@@ -24,6 +29,9 @@ sensor-gen.cpp:
inventory-sensor-gen.cpp:
$(AM_V_GEN)@INVSENSORGEN@ -o $(top_builddir) generate-cpp
+fru-read-gen.cpp:
+ $(AM_V_GEN)@FRUGEN@ -o $(top_builddir) generate-cpp
+
libapphandlerdir = ${libdir}/ipmid-providers
libapphandler_LTLIBRARIES = libapphandler.la
libapphandler_la_SOURCES = \
@@ -39,7 +47,8 @@ libapphandler_la_SOURCES = \
groupext.cpp \
sensor-gen.cpp \
utils.cpp \
- inventory-sensor-gen.cpp
+ inventory-sensor-gen.cpp \
+ fru-read-gen.cpp
libapphandler_la_LDFLAGS = $(SYSTEMD_LIBS) $(libmapper_LIBS) $(PHOSPHOR_LOGGING_LIBS) $(PHOSPHOR_DBUS_INTERFACES_LIBS) -lstdc++fs -version-info 0:0:0 -shared
libapphandler_la_CXXFLAGS = $(SYSTEMD_CFLAGS) $(libmapper_CFLAGS) $(PHOSPHOR_LOGGING_CFLAGS) $(PHOSPHOR_DBUS_INTERFACES_CFLAGS)
diff --git a/configure.ac b/configure.ac
index 8c6cd05..4e8476a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -81,6 +81,10 @@ AS_IF([test "x$INVSENSOR_YAML_GEN" == "x"], [INVSENSOR_YAML_GEN="inventory-senso
INVSENSORGEN="$PYTHON ${srcdir}/scripts/inventory-sensor.py -i $INVSENSOR_YAML_GEN"
AC_SUBST(INVSENSORGEN)
+AS_IF([test "x$FRU_YAML_GEN" == "x"], [FRU_YAML_GEN="example.yaml"])
+FRUGEN="$PYTHON $srcdir/scripts/fru_gen.py -i $FRU_YAML_GEN"
+AC_SUBST(FRUGEN)
+
# Soft Power off related.
AS_IF([test "x$enable_softoff" != "xno"],
# Dbus service name
diff --git a/fruread.hpp b/fruread.hpp
new file mode 100644
index 0000000..203dfa0
--- /dev/null
+++ b/fruread.hpp
@@ -0,0 +1,29 @@
+#ifndef OPENBMC_IPMI_FRU_READ_H
+#define OPENBMC_IPMI_FRU_READ_H
+
+#include <systemd/sd-bus.h>
+#include <array>
+#include <string>
+#include <map>
+#include <vector>
+
+struct IPMIFruData
+{
+ std::string section;
+ std::string property;
+ std::string delimiter;
+};
+
+using DbusProperty = std::string;
+using DbusPropertyVec = std::vector<std::pair<DbusProperty, IPMIFruData>>;
+
+using DbusInterface = std::string;
+using DbusInterfaceVec = std::vector<std::pair<DbusInterface, DbusPropertyVec>>;
+
+using FruInstancePath = std::string;
+using FruInstanceVec = std::vector<std::pair<FruInstancePath, DbusInterfaceVec>>;
+
+using FruId = uint32_t;
+using FruMap = std::map<FruId, FruInstanceVec>;
+
+#endif
diff --git a/scripts/example.yaml b/scripts/example.yaml
new file mode 100644
index 0000000..1bb8e5d
--- /dev/null
+++ b/scripts/example.yaml
@@ -0,0 +1,119 @@
+# A YAML similar to this example would have to be generated, for eg with MRW
+# inputs and system configuration, to depict IPMI Fru information.
+#
+# This file maps IPMI properties to phosphor dbus inventory properties
+#
+# This YAML could help generate C++ code.
+# Format of the YAML:
+# Fruid:
+# Associated Fru paths
+# d-bus Interfaces
+# d-bus Properties
+# IPMI Fru mapping
+0:
+ /system:
+ xyz.openbmc_project.Inventory.Item:
+ PrettyName:
+ IPMIFruProperty: Product Name
+ IPMIFruSection: Product
+ xyz.openbmc_project.Inventory.Decorator.Asset:
+ Manufacturer:
+ IPMIFruProperty: Manufacturer
+ IPMIFruSection: Product
+ PartNumber:
+ IPMIFruProperty: Part Number
+ IPMIFruSection: Product
+ SerialNumber:
+ IPMIFruProperty: Serial Number
+ IPMIFruSection: Product
+ BuildDate:
+ IPMIFruProperty: Mfg Date
+ IPMIFruSection: Product
+ xyz.openbmc_project.Inventory.Revision:
+ Version:
+ IPMIFruProperty: Version
+ IPMIFruSection: Product
+1:
+ /system/chassis/motherboard/dimm0:
+ xyz.openbmc_project.Inventory.Item:
+ PrettyName:
+ IPMIFruProperty: Product Name
+ IPMIFruSection: Product
+ xyz.openbmc_project.Inventory.Decorator.Asset:
+ Manufacturer:
+ IPMIFruProperty: Manufacturer
+ IPMIFruSection: Product
+ BuildDate:
+ IPMIFruProperty: Mfg Date
+ IPMIFruSection: Product
+ SerialNumber:
+ IPMIFruProperty: Serial Number
+ IPMIFruSection: Product
+ PartNumber:
+ IPMIFruProperty: Part Number
+ IPMIFruSection: Product
+ xyz.openbmc_project.Inventory.Revision:
+ Version:
+ IPMIFruProperty: Version
+ IPMIFruSection: Product
+2:
+ /system/chassis/motherboard/dimm1:
+ xyz.openbmc_project.Inventory.Item:
+ PrettyName:
+ IPMIFruProperty: Product Name
+ IPMIFruSection: Product
+ xyz.openbmc_project.Inventory.Decorator.Asset:
+ Manufacturer:
+ IPMIFruProperty: Manufacturer
+ IPMIFruSection: Product
+ BuildDate:
+ IPMIFruProperty: Mfg Date
+ IPMIFruSection: Product
+ SerialNumber:
+ IPMIFruProperty: Serial Number
+ IPMIFruSection: Product
+ PartNumber:
+ IPMIFruProperty: Part Number
+ IPMIFruSection: Product
+ xyz.openbmc_project.Inventory.Revision:
+ Version:
+ IPMIFruProperty: Version
+ IPMIFruSection: Product
+3:
+ /system/chassis/motherboard/cpu0:
+ xyz.openbmc_project.Inventory.Item:
+ PrettyName:
+ IPMIFruProperty: Product Name
+ IPMIFruSection: Board
+ xyz.openbmc_project.Inventory.Decorator.Asset:
+ BuildDate:
+ IPMIFruProperty: Mfg Date
+ IPMIFruSection: Board
+ SerialNumber:
+ IPMIFruProperty: Serial Number
+ IPMIFruSection: Board
+ PartNumber:
+ IPMIFruProperty: Part Number
+ IPMIFruSection: Board
+ Manufacturer:
+ IPMIFruProperty: Manufacturer
+ IPMIFruSection: Board
+4:
+ /system/chassis/motherboard/cpu1:
+ xyz.openbmc_project.Inventory.Item:
+ PrettyName:
+ IPMIFruProperty: Product Name
+ IPMIFruSection: Board
+ xyz.openbmc_project.Inventory.Decorator.Asset:
+ BuildDate:
+ IPMIFruProperty: Mfg Date
+ IPMIFruSection: Board
+ SerialNumber:
+ IPMIFruProperty: Serial Number
+ IPMIFruSection: Board
+ PartNumber:
+ IPMIFruProperty: Part Number
+ IPMIFruSection: Board
+ Manufacturer:
+ IPMIFruProperty: Manufacturer
+ IPMIFruSection: Board
diff --git a/scripts/fru_gen.py b/scripts/fru_gen.py
new file mode 100755
index 0000000..f6111b7
--- /dev/null
+++ b/scripts/fru_gen.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import yaml
+import argparse
+from mako.template import Template
+
+
+def generate_cpp(inventory_yaml, output_dir):
+ with open(os.path.join(script_dir, inventory_yaml), 'r') as f:
+ ifile = yaml.safe_load(f)
+ if not isinstance(ifile, dict):
+ ifile = {}
+
+ # Render the mako template
+
+ t = Template(filename=os.path.join(
+ script_dir,
+ "readfru.mako.cpp"))
+
+ output_hpp = os.path.join(output_dir, "fru-read-gen.cpp")
+ with open(output_hpp, 'w') as fd:
+ fd.write(t.render(fruDict=ifile))
+
+
+def main():
+
+ valid_commands = {
+ 'generate-cpp': generate_cpp
+ }
+ parser = argparse.ArgumentParser(
+ description="IPMI FRU map code generator")
+
+ parser.add_argument(
+ '-i', '--inventory_yaml', dest='inventory_yaml',
+ default='example.yaml', help='input inventory yaml file to parse')
+
+ parser.add_argument(
+ "-o", "--output-dir", dest="outputdir",
+ default=".",
+ help="output directory")
+
+ parser.add_argument(
+ 'command', metavar='COMMAND', type=str,
+ choices=valid_commands.keys(),
+ help='Command to run.')
+
+ args = parser.parse_args()
+
+ if (not (os.path.isfile(os.path.join(script_dir, args.inventory_yaml)))):
+ sys.exit("Can not find input yaml file " + args.inventory_yaml)
+
+ function = valid_commands[args.command]
+ function(args.inventory_yaml, args.outputdir)
+
+if __name__ == '__main__':
+ script_dir = os.path.dirname(os.path.realpath(__file__))
+ main()
diff --git a/scripts/readfru.mako.cpp b/scripts/readfru.mako.cpp
new file mode 100644
index 0000000..40e4812
--- /dev/null
+++ b/scripts/readfru.mako.cpp
@@ -0,0 +1,35 @@
+// !!! WARNING: This is a GENERATED Code..Please do NOT Edit !!!
+#include <iostream>
+#include "fruread.hpp"
+
+extern const FruMap frus = {
+% for key in fruDict.keys():
+ {${key},{
+<%
+ fru = fruDict[key]
+%>
+ % for object,interfaces in fru.items():
+ {"${object}",{
+ % for interface,properties in interfaces.items():
+ {"${interface}",{
+ % for dbus_property,property_value in properties.items():
+ {"${dbus_property}",{
+ "${property_value.get("IPMIFruSection", "")}",
+ "${property_value.get("IPMIFruProperty", "")}",\
+<%
+ delimiter = property_value.get("IPMIFruValueDelimiter")
+ if not delimiter:
+ delimiter = ""
+ else:
+ delimiter = '\\' + hex(delimiter)[1:]
+%>
+ "${delimiter}"
+ }},
+ % endfor
+ }},
+ % endfor
+ }},
+ % endfor
+ }},
+% endfor
+};
OpenPOWER on IntegriCloud