diff options
-rw-r--r-- | Makefile.am | 13 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | fruread.hpp | 29 | ||||
-rw-r--r-- | scripts/example.yaml | 119 | ||||
-rwxr-xr-x | scripts/fru_gen.py | 59 | ||||
-rw-r--r-- | scripts/readfru.mako.cpp | 35 |
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 +}; |