diff options
Diffstat (limited to 'meta-yadro/recipes-phosphor')
15 files changed, 1132 insertions, 23 deletions
diff --git a/meta-yadro/recipes-phosphor/cli/obmc-yadro-backup_git.bb b/meta-yadro/recipes-phosphor/cli/obmc-yadro-backup_git.bb new file mode 100644 index 000000000..c101d837c --- /dev/null +++ b/meta-yadro/recipes-phosphor/cli/obmc-yadro-backup_git.bb @@ -0,0 +1,16 @@ +SUMMARY = "Command line tool for backup configuration" +DESCRIPTION = "YADRO OpenBMC command line tool for backup and restore configuration" +HOMEPAGE = "https://github.com/YADRO-KNS/obmc-yadro-backup" +PR = "r1" +PV = "1.0+git${SRCPV}" + +inherit meson + +# License info +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" + +# Source code repository +S = "${WORKDIR}/git" +SRC_URI = "git://github.com/YADRO-KNS/obmc-yadro-backup.git" +SRCREV = "dd29c8bdc222de004284faba37d278f8c443b531" diff --git a/meta-yadro/recipes-phosphor/cli/obmc-yadro-cli_git.bb b/meta-yadro/recipes-phosphor/cli/obmc-yadro-cli_git.bb new file mode 100644 index 000000000..1cdecb07c --- /dev/null +++ b/meta-yadro/recipes-phosphor/cli/obmc-yadro-cli_git.bb @@ -0,0 +1,43 @@ +SUMMARY = "Command-line interface" +DESCRIPTION = "YADRO OpenBMC Command Line Interface for end users" +HOMEPAGE = "https://github.com/YADRO-KNS/obmc-yadro-cli" +PR = "r1" +PV = "1.0+git${SRCPV}" + +# License info +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" + +# Dependencies +DEPENDS = "phosphor-user-manager" +RDEPENDS_${PN} = " \ + ${VIRTUAL-RUNTIME_base-utils} \ + bash \ + obmc-console \ + obmc-yadro-fwupdate \ + obmc-yadro-lssensors \ + obmc-yadro-netconfig \ + sudo \ + systemd \ +" +# Some platforms also require some additional packages like +# ipmitool, obmc-yadro-lsinventory, obmc-yadro-backup ... +# They should be appended by bbappend file in their layers + +# Directory with command handlers +FILES_${PN} += "${datadir}/cli" + +# Custom installation procedure +do_install() { + ${B}/install.sh \ + --dir ${D} \ + --machine ${@'${MACHINE}'.split('-')[0]} \ + --admin priv-admin \ + --operator priv-operator \ + --user priv-user +} + +# Source code repository +S = "${WORKDIR}/git" +SRC_URI = "git://github.com/YADRO-KNS/obmc-yadro-cli" +SRCREV = "9457a085c86722214d6c450397ccecd6db4a1071" diff --git a/meta-yadro/recipes-phosphor/cli/obmc-yadro-fwupdate_git.bb b/meta-yadro/recipes-phosphor/cli/obmc-yadro-fwupdate_git.bb new file mode 100644 index 000000000..90f377bbe --- /dev/null +++ b/meta-yadro/recipes-phosphor/cli/obmc-yadro-fwupdate_git.bb @@ -0,0 +1,27 @@ +SUMMARY = "YADRO Firmware update tool" +DESCRIPTION = "Command line tool for update firmware" +HOMEPAGE = "https://github.com/YADRO-KNS/obmc-yadro-fwupdate" +PR = "r1" +PV = "1.0+git${SRCPV}" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" + +inherit meson +inherit pkgconfig + +DEPENDS += " \ + sdbusplus \ + openssl \ +" + +PACKAGECONFIG[obmc-phosphor-image] = "-Dbmc-image-type=obmc-phosphor-image,,,,,intel-platforms" +PACKAGECONFIG[intel-platforms] = "-Dbmc-image-type=intel-platforms,,,,,obmc-phosphor-image" +PACKAGECONFIG[reboot-guard-support] = "-Dreboot-guard-support=true,-Dreboot-guard-support=false" +PACKAGECONFIG[openpower-support] = "-Dopenpower-support=true,-Dopenpower-support=false" + +PACKAGECONFIG ??= " obmc-phosphor-image reboot-guard-support " +PACKAGECONFIG_append_df-openpower = "openpower-support" + +SRC_URI = "git://github.com/YADRO-KNS/obmc-yadro-fwupdate" +SRCREV = "f141bdf92f92971caa4e8e5eb0727821241416e8" +S = "${WORKDIR}/git" diff --git a/meta-yadro/recipes-phosphor/cli/obmc-yadro-lsinventory_git.bb b/meta-yadro/recipes-phosphor/cli/obmc-yadro-lsinventory_git.bb new file mode 100644 index 000000000..89ceb1ee1 --- /dev/null +++ b/meta-yadro/recipes-phosphor/cli/obmc-yadro-lsinventory_git.bb @@ -0,0 +1,22 @@ +SUMMARY = "Command line tool for printing inventory" +DESCRIPTION = "YADRO OpenBMC command line tool for printing inventory list" +HOMEPAGE = "https://github.com/YADRO-KNS/obmc-yadro-lsinventory" +PR = "r1" +PV = "1.0+git${SRCPV}" + +inherit meson + +# License info +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" + +# Dependencies +DEPENDS += " \ + json-c \ + sdbusplus \ + " + +# Source code repository +S = "${WORKDIR}/git" +SRC_URI = "git://github.com/YADRO-KNS/obmc-yadro-lsinventory.git" +SRCREV = "d0bdf0ddd192b9d41c5c5d4af9385122b08c7608" diff --git a/meta-yadro/recipes-phosphor/sensors/obmc-yadro-lssensors_git.bb b/meta-yadro/recipes-phosphor/cli/obmc-yadro-lssensors_git.bb index 55d549500..234d3cdad 100644 --- a/meta-yadro/recipes-phosphor/sensors/obmc-yadro-lssensors_git.bb +++ b/meta-yadro/recipes-phosphor/cli/obmc-yadro-lssensors_git.bb @@ -13,4 +13,4 @@ DEPENDS += "sdbusplus" S = "${WORKDIR}/git" SRC_URI = "git://github.com/YADRO-KNS/obmc-yadro-lssensors.git" -SRCREV = "4f55f0e21c5000d7a9e9c49cc2ad16bc6ba6463e" +SRCREV = "f76bf429d212d803cff7e4f1e3ca21097c65f18f" diff --git a/meta-yadro/recipes-phosphor/cli/obmc-yadro-netconfig_git.bb b/meta-yadro/recipes-phosphor/cli/obmc-yadro-netconfig_git.bb new file mode 100644 index 000000000..e868bbfb4 --- /dev/null +++ b/meta-yadro/recipes-phosphor/cli/obmc-yadro-netconfig_git.bb @@ -0,0 +1,19 @@ +SUMMARY = "Command line tool for configuring network" +DESCRIPTION = "YADRO OpenBMC command line tool for configuring network" +HOMEPAGE = "https://github.com/YADRO-KNS/obmc-yadro-netconfig" +PR = "r1" +PV = "1.0+git${SRCPV}" + +inherit meson + +# License info +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" + +# Dependencies +DEPENDS = "sdbusplus" + +# Source code repository +S = "${WORKDIR}/git" +SRC_URI = "git://github.com/YADRO-KNS/obmc-yadro-netconfig.git" +SRCREV = "b300465732616c6d456bdc2df2cce9d1246636a8" diff --git a/meta-yadro/recipes-phosphor/dbus/phosphor-dbus-interfaces/0001-Add-boot-initiator-mailbox-interface.patch b/meta-yadro/recipes-phosphor/dbus/phosphor-dbus-interfaces/0001-Add-boot-initiator-mailbox-interface.patch new file mode 100644 index 000000000..e3da4378a --- /dev/null +++ b/meta-yadro/recipes-phosphor/dbus/phosphor-dbus-interfaces/0001-Add-boot-initiator-mailbox-interface.patch @@ -0,0 +1,138 @@ +From 104027fff5db49d60d2ff7256580b8efb6429a27 Mon Sep 17 00:00:00 2001 +From: Alexander Amelkin <a.amelkin@yadro.com> +Date: Wed, 20 Mar 2019 19:33:00 +0300 +Subject: [PATCH] Add boot initiator mailbox interface + +Add the xyz.openbmc_project.Control.Boot.Mailbox interface to allow +for provision of the boot initiator (such as Petitboot or UEFI) with +its specific parameters. This is based on IPMI 2.0 Table 28-14 'Boot +Option Parameters' parameter 7 'Boot initiator mailbox'. + +Partially resolves openbmc/openbmc#3391 + +Change-Id: If2a7dce6fae812fc3f1f325cd07c77f31900cf42 +Signed-off-by: Alexander Amelkin <a.amelkin@yadro.com> +--- + .../Control/Boot/Mailbox/meson.build | 14 +++++ + .../openbmc_project/Control/Boot/meson.build | 15 +++++ + .../Control/Boot/Mailbox.interface.yaml | 63 +++++++++++++++++++ + 3 files changed, 92 insertions(+) + create mode 100644 gen/xyz/openbmc_project/Control/Boot/Mailbox/meson.build + create mode 100644 xyz/openbmc_project/Control/Boot/Mailbox.interface.yaml + +diff --git a/gen/xyz/openbmc_project/Control/Boot/Mailbox/meson.build b/gen/xyz/openbmc_project/Control/Boot/Mailbox/meson.build +new file mode 100644 +index 0000000..149e68a +--- /dev/null ++++ b/gen/xyz/openbmc_project/Control/Boot/Mailbox/meson.build +@@ -0,0 +1,14 @@ ++# Generated file; do not modify. ++generated_sources += custom_target( ++ 'xyz/openbmc_project/Control/Boot/Mailbox__cpp'.underscorify(), ++ input: [ meson.source_root() / 'xyz/openbmc_project/Control/Boot/Mailbox.interface.yaml', ], ++ output: [ 'server.cpp', 'server.hpp', 'client.hpp', ], ++ command: [ ++ sdbuspp_gen_meson_prog, '--command', 'cpp', ++ '--output', meson.current_build_dir(), ++ '--tool', sdbusplusplus_prog, ++ '--directory', meson.source_root(), ++ 'xyz/openbmc_project/Control/Boot/Mailbox', ++ ], ++) ++ +diff --git a/gen/xyz/openbmc_project/Control/Boot/meson.build b/gen/xyz/openbmc_project/Control/Boot/meson.build +index ba8a19f..6901fc0 100644 +--- a/gen/xyz/openbmc_project/Control/Boot/meson.build ++++ b/gen/xyz/openbmc_project/Control/Boot/meson.build +@@ -1,4 +1,19 @@ + # Generated file; do not modify. ++subdir('Mailbox') ++generated_others += custom_target( ++ 'xyz/openbmc_project/Control/Boot/Mailbox__markdown'.underscorify(), ++ input: [ meson.source_root() / 'xyz/openbmc_project/Control/Boot/Mailbox.interface.yaml', ], ++ output: [ 'Mailbox.md' ], ++ command: [ ++ sdbuspp_gen_meson_prog, '--command', 'markdown', ++ '--output', meson.current_build_dir(), ++ '--tool', sdbusplusplus_prog, ++ '--directory', meson.source_root(), ++ 'xyz/openbmc_project/Control/Boot/Mailbox', ++ ], ++ build_by_default: true, ++) ++ + subdir('Mode') + generated_others += custom_target( + 'xyz/openbmc_project/Control/Boot/Mode__markdown'.underscorify(), +diff --git a/xyz/openbmc_project/Control/Boot/Mailbox.interface.yaml b/xyz/openbmc_project/Control/Boot/Mailbox.interface.yaml +new file mode 100644 +index 0000000..839e8be +--- /dev/null ++++ b/xyz/openbmc_project/Control/Boot/Mailbox.interface.yaml +@@ -0,0 +1,63 @@ ++description: > ++ Implement to provide the boot initiator (such as Petitboot or UEFI) ++ with its specific parameters. This is based on IPMI 2.0 Table 28-14 ++ 'Boot Option Parameters' parameter 7 'Boot initiator mailbox'. ++ ++properties: ++ - name: Supported ++ type: boolean ++ flags: ++ - const ++ default: false ++ description: > ++ Specifies whether or not the mailbox is supported by the ++ boot initiator on this machine. ++ ++ The property is constant and is only set by the implementation ++ on startup. ++ ++ - name: IANAEnterpriseNumber ++ type: uint32 ++ flags: ++ - const ++ default: 0 ++ description: > ++ The 24-bit IANA Private Enterprise Number for the company or organization ++ that has specified the boot initiator. This is a machine-specific ++ constant. The implementing application is responsible for setting ++ this to the proper machine-specific value (0x000000..0xFFFFFF) ++ according to https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers. ++ ++ The property is constant and is only set by the implementation ++ on startup. ++ ++ - name: Data ++ type: array[byte] ++ description: > ++ The array of data bytes for the boot initiator to treat ++ in its specific way. This interface doesn't impose any ++ limitiations on the format or make any assumptions regarding ++ it. The boot initiator is responsible for parsing this array. ++ ++ The size of the array is a constant depending on the requirements ++ set by the boot initiator used for a particular architecture or ++ a machine. The implementing application is responsible for setting ++ the size of this array to the proper value. ++ ++ For conformance to the IPMI 2.0 specification, the size of the array ++ plus 3 (the size of IPMI 2.0 representation of IANA Enterprise Number) ++ must be a multiple of 16 with the minimum allowed size being 77 ++ (5 x 16-byte blocks, minus 3) if mailbox is at all Supported. ++ ++ For IPMI 2.0 this array is supposed to be split into 16-byte ++ blocks by the implementing service (block 0 being made of IANA PEN ++ plus first 13 bytes of this array). Please pay special attention ++ that this array does NOT include the IANA PEN needed for IPMI 2.0. ++ Only the actual PEN-specific data is stored here. ++ ++ When partially written to, the remaining parts of this array ++ must not be automatically cleared. This is per IPMI 2.0 ++ specification. ++ ++ Other interfaces to the boot initiator (such as MCTP) may process ++ this array differently. +-- +2.26.2 + diff --git a/meta-yadro/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend b/meta-yadro/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend new file mode 100644 index 000000000..8a5b4c363 --- /dev/null +++ b/meta-yadro/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend @@ -0,0 +1,5 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +SRC_URI_append = "\ + file://0001-Add-boot-initiator-mailbox-interface.patch \ +" diff --git a/meta-yadro/recipes-phosphor/flash/obmc-yadro-fwupdate_git.bb b/meta-yadro/recipes-phosphor/flash/obmc-yadro-fwupdate_git.bb deleted file mode 100644 index ae2f7c97a..000000000 --- a/meta-yadro/recipes-phosphor/flash/obmc-yadro-fwupdate_git.bb +++ /dev/null @@ -1,22 +0,0 @@ -SUMMARY = "YADRO Firmware update tool" -DESCRIPTION = "Command line tool for update firmware" -HOMEPAGE = "https://github.com/YADRO-KNS/obmc-yadro-fwupdate" -PR = "r1" -PV = "1.0+git${SRCPV}" -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" - -inherit meson - -DEPENDS += " \ - sdbusplus \ - openssl \ -" - -EXTRA_OEMESON_df-openpower = " \ - -Dopenpower-support=true \ -" - -SRC_URI = "git://github.com/YADRO-KNS/obmc-yadro-fwupdate" -SRCREV = "b922eb474447b76fb72cc615c025e3845b7c4b7e" -S = "${WORKDIR}/git" diff --git a/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-config.bbappend b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-config.bbappend new file mode 100644 index 000000000..72d991c7e --- /dev/null +++ b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-config.bbappend @@ -0,0 +1 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" diff --git a/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-config/cipher_list.json b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-config/cipher_list.json new file mode 100644 index 000000000..767fc708c --- /dev/null +++ b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-config/cipher_list.json @@ -0,0 +1,14 @@ +{ + "a":{ + "cipher":3, + "authentication":1, + "integrity":1, + "confidentiality":1 + }, + "b":{ + "cipher":17, + "authentication":3, + "integrity":4, + "confidentiality":1 + } +} diff --git a/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Add-support-for-persistent-only-settings.patch b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Add-support-for-persistent-only-settings.patch new file mode 100644 index 000000000..f1e2c4ae4 --- /dev/null +++ b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Add-support-for-persistent-only-settings.patch @@ -0,0 +1,92 @@ +From aaf8a4a5b82baff679f557ed83b25af6ff2919cf Mon Sep 17 00:00:00 2001 +From: Alexander Amelkin <a.amelkin@yadro.com> +Date: Thu, 23 May 2019 20:39:57 +0300 +Subject: [PATCH] Add support for persistent-only settings + +Some settings such as Boot Initiator Mailbox do not support +one-time setting mode (as per IPMI 2.0 specification). + +This commit adds support for such persistent-only settings. + +Partially resolves openbmc/openbmc#3391 + +Change-Id: Iec8e2f5bddbc50d270916567effe334f10db2987 +Signed-off-by: Alexander Amelkin <a.amelkin@yadro.com> +Signed-off-by: Ivan Mikhaylov <i.mikhaylov@yadro.com> +--- + settings.cpp | 35 +++++++++++++++++++++++++++++++---- + 1 file changed, 31 insertions(+), 4 deletions(-) + +diff --git a/settings.cpp b/settings.cpp +index 2fa2511..6002365 100644 +--- a/settings.cpp ++++ b/settings.cpp +@@ -95,19 +95,44 @@ namespace boot + std::tuple<Path, OneTimeEnabled> setting(const Objects& objects, + const Interface& iface) + { +- constexpr auto bootObjCount = 2; ++ constexpr auto ambiguousOperationCount = 2; + constexpr auto oneTime = "one_time"; + constexpr auto enabledIntf = "xyz.openbmc_project.Object.Enable"; ++ bool oneTimeEnabled = false; + + const std::vector<Path>& paths = objects.map.at(iface); + auto count = paths.size(); +- if (count != bootObjCount) ++ if (!count) + { +- log<level::ERR>("Exactly two objects expected", ++ // If there are no objects implementing the requested interface, ++ // that must be an error. ++ log<level::ERR>("Interface objects not found", ++ entry("INTERFACE=%s", iface.c_str())); ++ elog<InternalFailure>(); ++ } ++ else if (count < ambiguousOperationCount) ++ { ++ // On the contrary, if there is just one object, that may mean ++ // that this particular interface doesn't support one-time ++ // setting mode (e.g. Boot Initiator Mailbox). ++ // That is not an error, just return the regular setting. ++ // If there's just one object, that's the only kind of setting ++ // mode this interface supports, so just return that setting path. ++ const Path& regularSetting = paths[0]; ++ return std::make_tuple(regularSetting, oneTimeEnabled); ++ } ++ else if (count > ambiguousOperationCount) ++ { ++ // Something must be wrong if there are more objects than expected ++ log<level::ERR>("Exactly 1 or 2 interface objects are required", + entry("INTERFACE=%s", iface.c_str()), + entry("COUNT=%d", count)); + elog<InternalFailure>(); + } ++ ++ // We are here because there were exactly two objects implementing the ++ // same interface. Take those two and find out which of them is the ++ // one-time setting, consider the other the persistent setting. + size_t index = 0; + if (std::string::npos == paths[0].rfind(oneTime)) + { +@@ -116,6 +141,8 @@ std::tuple<Path, OneTimeEnabled> setting(const Objects& objects, + const Path& oneTimeSetting = paths[index]; + const Path& regularSetting = paths[!index]; + ++ // Now see if the one-time setting is enabled and return the path for it ++ // if so. Otherwise return the path for the persistent setting. + auto method = objects.bus.new_method_call( + objects.service(oneTimeSetting, iface).c_str(), oneTimeSetting.c_str(), + ipmi::PROP_INTF, "Get"); +@@ -131,7 +158,7 @@ std::tuple<Path, OneTimeEnabled> setting(const Objects& objects, + + std::variant<bool> enabled; + reply.read(enabled); +- auto oneTimeEnabled = std::get<bool>(enabled); ++ oneTimeEnabled = std::get<bool>(enabled); + const Path& setting = oneTimeEnabled ? oneTimeSetting : regularSetting; + return std::make_tuple(setting, oneTimeEnabled); + } +-- +2.21.1 + diff --git a/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0002-Add-support-for-boot-initiator-mailbox.patch b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0002-Add-support-for-boot-initiator-mailbox.patch new file mode 100644 index 000000000..dd7610975 --- /dev/null +++ b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0002-Add-support-for-boot-initiator-mailbox.patch @@ -0,0 +1,418 @@ +From ec6765e9aa35871f8d02cb0b5b47d96be18f4804 Mon Sep 17 00:00:00 2001 +From: Alexander Amelkin <a.amelkin@yadro.com> +Date: Mon, 8 Apr 2019 17:58:42 +0300 +Subject: [PATCH] Add support for boot initiator mailbox + +Add handlers to process the chassis system option 7 +(boot initiator mailbox). The format of mailbox is +specific to the machine/bootloader. This commit only +adds generic handlers to process getting and setting +of the mailbox data regardless of the content. + +Only the IANA Enterprise number is checked in the data +block 0. Also checked are the data boundaries. + +It is expected that a machine-specific override for +phosphor-settingsd sets the supported state and +the IANA number according to the used bootloader. + +Resolves openbmc/openbmc#3391 + +Change-Id: Iccbf74c0775f20c70e8deaa7b0a8bd995ebbffea +Signed-off-by: Alexander Amelkin <a.amelkin@yadro.com> +Signed-off-by: Ivan Mikhaylov <i.mikhaylov@yadro.com> +--- + chassishandler.cpp | 328 ++++++++++++++++++++++++++++++++++++++++++++- + chassishandler.hpp | 1 + + 2 files changed, 325 insertions(+), 4 deletions(-) + +diff --git a/chassishandler.cpp b/chassishandler.cpp +index 3250b2c..48cda21 100644 +--- a/chassishandler.cpp ++++ b/chassishandler.cpp +@@ -136,6 +136,7 @@ namespace internal + { + + constexpr auto bootModeIntf = "xyz.openbmc_project.Control.Boot.Mode"; ++constexpr auto bootMboxIntf = "xyz.openbmc_project.Control.Boot.Mailbox"; + constexpr auto bootSourceIntf = "xyz.openbmc_project.Control.Boot.Source"; + constexpr auto powerRestoreIntf = + "xyz.openbmc_project.Control.Power.RestorePolicy"; +@@ -151,8 +152,8 @@ settings::Objects& getObjects() + if (objectsPtr == nullptr) + { + objectsPtr = std::make_unique<settings::Objects>( +- dbus, std::vector<std::string>{bootModeIntf, bootSourceIntf, +- powerRestoreIntf}); ++ dbus, std::vector<std::string>{bootMboxIntf, bootModeIntf, ++ bootSourceIntf, powerRestoreIntf}); + } + return *objectsPtr; + } +@@ -1670,6 +1671,127 @@ static ipmi::Cc setBootMode(const Mode::Modes& mode) + return ipmi::ccSuccess; + } + ++using MboxVec = std::vector<uint8_t>; ++ ++// Check if Boot Mailbox is supported. ++static std::optional<bool> isBootMboxSupported() ++{ ++ using namespace chassis::internal; ++ using namespace chassis::internal::cache; ++ ++ try ++ { ++ settings::Objects& objects = getObjects(); ++ auto bootMbox = settings::boot::setting(objects, bootMboxIntf); ++ const auto& bootMboxSetting = std::get<settings::Path>(bootMbox); ++ auto method = dbus.new_method_call( ++ objects.service(bootMboxSetting, bootMboxIntf).c_str(), ++ bootMboxSetting.c_str(), ipmi::PROP_INTF, "Get"); ++ ++ method.append(bootMboxIntf, "Supported"); ++ auto reply = dbus.call(method); ++ std::variant<bool> result; ++ reply.read(result); ++ return std::get<bool>(result); ++ } ++ catch (const std::exception& e) ++ { ++ log<level::ERR>("Error getting Boot/Mailbox/Supported", ++ entry("ERROR=%s", e.what())); ++ report<InternalFailure>(); ++ return std::nullopt; ++ } ++} ++ ++static std::optional<uint24_t> getBootMboxIANA() ++{ ++ using namespace chassis::internal; ++ using namespace chassis::internal::cache; ++ ++ try ++ { ++ settings::Objects& objects = getObjects(); ++ auto bootMbox = settings::boot::setting(objects, bootMboxIntf); ++ const auto& bootMboxSetting = std::get<settings::Path>(bootMbox); ++ auto method = dbus.new_method_call( ++ objects.service(bootMboxSetting, bootMboxIntf).c_str(), ++ bootMboxSetting.c_str(), ipmi::PROP_INTF, "Get"); ++ ++ method.append(bootMboxIntf, "IANAEnterpriseNumber"); ++ auto reply = dbus.call(method); ++ std::variant<uint32_t> result; ++ reply.read(result); ++ return std::get<uint32_t>(result); ++ } ++ catch (const std::exception& e) ++ { ++ log<level::ERR>("Error getting Boot/Mailbox/IANAEnterpriseNumber", ++ entry("ERROR=%s", e.what())); ++ report<InternalFailure>(); ++ return std::nullopt; ++ } ++} ++ ++static std::optional<MboxVec> getBootMbox() ++{ ++ using namespace chassis::internal; ++ using namespace chassis::internal::cache; ++ ++ try ++ { ++ settings::Objects& objects = getObjects(); ++ auto bootMbox = settings::boot::setting(objects, bootMboxIntf); ++ const auto& bootMboxSetting = std::get<settings::Path>(bootMbox); ++ auto method = dbus.new_method_call( ++ objects.service(bootMboxSetting, bootMboxIntf).c_str(), ++ bootMboxSetting.c_str(), ipmi::PROP_INTF, "Get"); ++ ++ method.append(bootMboxIntf, "Data"); ++ auto reply = dbus.call(method); ++ std::variant<MboxVec> result; ++ reply.read(result); ++ return std::get<MboxVec>(result); ++ } ++ catch (const std::exception& e) ++ { ++ log<level::ERR>("Error getting Boot/Mailbox/Data", ++ entry("ERROR=%s", e.what())); ++ report<InternalFailure>(); ++ return std::nullopt; ++ } ++} ++ ++static bool setBootMbox(MboxVec data) ++{ ++ using namespace chassis::internal; ++ using namespace chassis::internal::cache; ++ ++ try ++ { ++ settings::Objects& objects = getObjects(); ++ std::variant<MboxVec> property(data); ++ auto bootMbox = settings::boot::setting(objects, bootMboxIntf); ++ const auto& bootMboxSetting = std::get<settings::Path>(bootMbox); ++ auto method = dbus.new_method_call( ++ objects.service(bootMboxSetting, bootMboxIntf).c_str(), ++ bootMboxSetting.c_str(), ipmi::PROP_INTF, "Set"); ++ ++ method.append(bootMboxIntf, "Data", property); ++ dbus.call(method); ++ return true; ++ } ++ catch (const std::exception& e) ++ { ++ log<level::ERR>("Error setting Boot/Mailbox/Data", ++ entry("ERROR=%s", e.what())); ++ report<InternalFailure>(); ++ return false; ++ } ++} ++ ++static constexpr size_t normalBlockSize = 16; ++static constexpr size_t IANAEnterpriseLength = 3; ++ + /** @brief implements the Get Chassis system boot option + * @param bootOptionParameter - boot option parameter selector + * @param reserved1 - reserved bit +@@ -1783,6 +1905,87 @@ ipmi::RspType<ipmi::message::Payload> + return ipmi::responseUnspecifiedError(); + } + } ++ else if (static_cast<uint8_t>(bootOptionParameter) == ++ static_cast<uint8_t>(BootOptionParameter::bootInitiatorMbox)) ++ { ++ // Only allow reading the boot initiator mailbox if Mailbox is supported ++ // ++ // Algorithm: ++ // 1. Get 'Supported' property from the Control.Boot.Mailbox interface ++ // 2. If {1} is 'false', report Parameter not supported (0x80) ++ // 3. Get Block Selector from request ++ // 4. Get 'Data' vector from Control.Boot.Mailbox ++ // 5. If requested block {3} exceeds total vector size {4}, ++ // report Out of space (0xC4) ++ // 6. Return the selected block (16 bytes) from the vector ++ try ++ { ++ // Check whether this option is supported ++ std::optional<bool> isSupported = isBootMboxSupported(); ++ if (!isSupported) ++ { ++ return ipmi::responseUnspecifiedError(); ++ } ++ ++ if (!*isSupported) ++ { ++ log<level::INFO>("Attempt to read unsupported Boot/Mailbox"); ++ return ipmi::responseParmNotSupported(); ++ } ++ ++ // Initially assume it's block 1+ ++ std::optional<uint24_t> IANAEnterprise; ++ size_t blockDataSize = normalBlockSize; ++ size_t dataVecStartOffset = ++ setSelector * normalBlockSize - IANAEnterpriseLength; ++ ++ response.pack(bootOptionParameter, reserved1, setSelector); ++ ++ // Adjust pointers and sizes for block 0, and fill in the IANA PEN ++ if (0 == setSelector) ++ { ++ IANAEnterprise = getBootMboxIANA(); ++ if (!IANAEnterprise) ++ { ++ return ipmi::responseInvalidCommand(); ++ } ++ ++ blockDataSize = normalBlockSize - IANAEnterpriseLength; ++ dataVecStartOffset = 0; ++ ++ response.pack(*IANAEnterprise); ++ } ++ ++ // Get the total data size ++ std::optional<MboxVec> dataVec = getBootMbox(); ++ if (!dataVec) ++ { ++ return ipmi::responseInvalidCommand(); ++ } ++ ++ if ((*dataVec).size() < dataVecStartOffset + blockDataSize) ++ { ++ size_t totalSize = (*dataVec).size() + IANAEnterpriseLength; ++ log<level::ERR>( ++ "Attempt to read unsupported block", ++ entry("REQUESTED_BLOCK=%d", setSelector), ++ entry("MAX_BLOCK=%d", totalSize / normalBlockSize)); ++ return ipmi::responseParmOutOfRange(); ++ } ++ ++ // Copy the data to response from specified offset in d-bus vector ++ response.append((*dataVec).data() + dataVecStartOffset, ++ (*dataVec).data() + dataVecStartOffset + ++ blockDataSize); ++ ++ return ipmi::responseSuccess(std::move(response)); ++ } ++ catch (InternalFailure& e) ++ { ++ report<InternalFailure>(); ++ return ipmi::responseUnspecifiedError(); ++ } ++ } + else + { + if ((bootOptionParameter >= oemParmStart) && +@@ -1825,9 +2028,8 @@ ipmi::RspType<> ipmiChassisSetSysBootOptions(ipmi::Context::ptr ctx, + using namespace boot_options; + ipmi::Cc rc; + +- /* 000101 ++ /* + * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc. +- * This is the only parameter used by petitboot. + */ + + if (parameterSelector == +@@ -1954,6 +2156,124 @@ ipmi::RspType<> ipmiChassisSetSysBootOptions(ipmi::Context::ptr ctx, + return ipmi::responseUnspecifiedError(); + } + } ++ else if (parameterSelector == ++ static_cast<uint7_t>(BootOptionParameter::bootInitiatorMbox)) ++ { ++ // Only allow writing to boot initiator mailbox if: ++ // 1. Mailbox is supported ++ // 2. IANA PEN matches. ++ // ++ // Algorithm: ++ // 1. Get 'Supported' property from Control.Boot.Mailbox interface ++ // 2. If {1} is 'false', report Parameter not supported (0x80) ++ // 3. Get Block Selector from request ++ // 4. Get 'Data' array from Control.Boot.Mailbox ++ // 5. If requested block {3} exceeds total vector size {4}, ++ // report Out of range (0xC9) ++ // 6. If requsted block {3} is 0: ++ // 4.1. Get IANA PEN from request ++ // 4.2. Get 'IANAEnterpriseNumber' property from Control.Boot.Mailbox ++ // 4.3. If {4.1} doesn't match {4.2}, report 0xCC error (Invalid ++ // data field in request) ++ // 7. Overwrite the 16 bytes at offset {3}*16 with the data from request ++ // 8. Update the 'Data' array in Control.Boot.Mailbox ++ ++ try ++ { ++ std::optional<bool> isSupported = isBootMboxSupported(); ++ if (!isSupported) ++ { ++ return ipmi::responseUnspecifiedError(); ++ } ++ ++ if (!*isSupported) ++ { ++ log<level::INFO>("Attempt to read unsupported Boot/Mailbox"); ++ return ipmi::responseParmNotSupported(); ++ } ++ ++ // Requested block ++ uint8_t reqBlock; ++ if (data.unpack(reqBlock) != 0) ++ { ++ return ipmi::responseReqDataLenInvalid(); ++ } ++ ++ // Initially assume it's blcok 1+ ++ uint24_t reqIANAEnterprise; ++ std::vector<uint8_t> blockData(normalBlockSize); ++ size_t dataVecStartOffset = ++ reqBlock * normalBlockSize - IANAEnterpriseLength; ++ ++ // Adjust pointers and sizes for block 0, and fill in the IANA PEN ++ if (0 == reqBlock) ++ { ++ if (data.unpack(reqIANAEnterprise) != 0) ++ { ++ return ipmi::responseReqDataLenInvalid(); ++ } ++ ++ std::optional<uint24_t> IANAEnterprise = getBootMboxIANA(); ++ if (!IANAEnterprise) ++ { ++ return ipmi::responseInvalidCommand(); ++ } ++ ++ if (*IANAEnterprise != reqIANAEnterprise) ++ { ++ log<level::ERR>( ++ "Unsupported IANA Enterprise number", ++ entry("REQUESTED_IANA=%d", ++ static_cast<uint32_t>(reqIANAEnterprise)), ++ entry("SUPPORTED_IANA=%d", ++ static_cast<uint32_t>(*IANAEnterprise))); ++ return ipmi::responseInvalidFieldRequest(); ++ } ++ ++ // For block 0 operate on data after IANA PEN ++ blockData.resize(normalBlockSize - IANAEnterpriseLength); ++ dataVecStartOffset = 0; ++ } ++ ++ // Get the data vector from d-bus ++ std::optional<MboxVec> dataVec = getBootMbox(); ++ if (!dataVec) ++ { ++ return ipmi::responseInvalidCommand(); ++ } ++ ++ // Does the requested block exist? ++ if ((*dataVec).size() < dataVecStartOffset + blockData.size()) ++ { ++ size_t totalSize = (*dataVec).size() + IANAEnterpriseLength; ++ log<level::ERR>( ++ "Attempt to read unsupported block", ++ entry("REQUESTED_BLOCK=%d", reqBlock), ++ entry("MAX_BLOCK=%d", totalSize / normalBlockSize)); ++ return ipmi::responseParmOutOfRange(); ++ } ++ ++ if (data.unpack(blockData) != 0 || !data.fullyUnpacked()) ++ { ++ return ipmi::responseReqDataLenInvalid(); ++ } ++ ++ // Copy the data from request to specified offset in d-bus vector ++ for (size_t i = 0; i < blockData.size(); ++i) ++ { ++ (*dataVec)[dataVecStartOffset + i] = blockData[i]; ++ } ++ if (!setBootMbox(*dataVec)) ++ { ++ return ipmi::responseUnspecifiedError(); ++ } ++ } ++ catch (InternalFailure& e) ++ { ++ report<InternalFailure>(); ++ return ipmi::responseUnspecifiedError(); ++ } ++ } + else if (parameterSelector == + static_cast<uint7_t>(BootOptionParameter::bootInfo)) + { +diff --git a/chassishandler.hpp b/chassishandler.hpp +index 93de2c0..33ad25f 100644 +--- a/chassishandler.hpp ++++ b/chassishandler.hpp +@@ -48,6 +48,7 @@ enum class BootOptionParameter : size_t + { + bootInfo = 0x4, + bootFlags = 0x5, ++ bootInitiatorMbox = 0x07, + opalNetworkSettings = 0x61 + }; + +-- +2.26.2 + diff --git a/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0003-Fix-version-parsing-update-AUX-revision-info.patch b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0003-Fix-version-parsing-update-AUX-revision-info.patch new file mode 100644 index 000000000..695b16c69 --- /dev/null +++ b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0003-Fix-version-parsing-update-AUX-revision-info.patch @@ -0,0 +1,329 @@ +From 605210dca3d6803839a8bcea4b5b83866c01f2da Mon Sep 17 00:00:00 2001 +From: Alexander Amelkin <alexander@amelkin.msk.ru> +Date: Wed, 11 Jul 2018 13:16:01 +0300 +Subject: [PATCH] Fix version parsing, update AUX revision info + +AUX Revision info was always taken from the dev_id.json +file if it exists, overriding the value calculated from the +active firmware version string. Also, when AUX info was +calculated, it only properly parsed the dirtyness of the +build. + +With this commit the AUX info calculation will properly parse +the git hash part and will include it as higher 3 bytes of +the AUX info. For officially released versions the lower byte +will be zero. + +For development versions, bits [7:1] of the fourth byte will +all be 1 as an indicator of non-release branch. For unofficial +builds from release branches those bits will contain a number +from 1 to 126 indicating a patch level since the release tag. + +In any case the bit 0 of byte 4 is a dirtyness indicator. +If the sources used to build the firmware were modified compared +to the git hash, this bit will be 1. + +WARNING: For the AUX decoding from version string to work + properly, the dev_id.json file must NOT contain + the `aux` property. + +Resolves SRV-775 +End-user-impact: Version info is properly represented in the + AUX Revision Info fields in response to the + IPMI Get Device ID command (ipmitool mc info) +Signed-off-by: Alexander Amelkin <a.filippov@yadro.com> + +--- + apphandler.cpp | 228 +++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 165 insertions(+), 63 deletions(-) + +diff --git a/apphandler.cpp b/apphandler.cpp +index 90818a9..93e3b6c 100644 +--- a/apphandler.cpp ++++ b/apphandler.cpp +@@ -1,4 +1,5 @@ + #include <arpa/inet.h> ++#include <endian.h> + #include <fcntl.h> + #include <limits.h> + #include <linux/i2c-dev.h> +@@ -459,33 +460,112 @@ ipmi::RspType<uint8_t, // acpiSystemPowerState + return ipmi::responseSuccess(sysAcpiState, devAcpiState); + } + ++static ++std::vector<std::string> ++tokenize(std::string const& str, ++ char const token[]) ++{ ++ std::vector<std::string> results; ++ std::string::size_type j = 0; ++ while (j < str.length()) ++ { ++ std::string::size_type k = str.find_first_of(token, j); ++ if (k == std::string::npos) ++ k = str.length(); ++ results.push_back(str.substr(j, k-j)); ++ j = k + 1; ++ } ++ return results; ++} ++ + typedef struct + { +- char major; +- char minor; +- uint16_t d[2]; ++ uint8_t major; ++ uint8_t minor; ++ union { ++ uint8_t aux[4]; // Individual bytes in IPMI big-endian order ++ uint32_t aux32; // use htobe32() on writes to aux32 ++ }; + } Revision; + +-/* Currently supports the vx.x-x-[-x] and v1.x.x-x-[-x] format. It will */ +-/* return -1 if not in those formats, this routine knows how to parse */ ++/* Currently supports the following formats. It will return -1 if not in */ ++/* those formats: */ ++/* */ ++/* Format 1: */ + /* version = v0.6-19-gf363f61-dirty */ +-/* ^ ^ ^^ ^ */ +-/* | | |----------|-- additional details */ +-/* | |---------------- Minor */ +-/* |------------------ Major */ +-/* and version = v1.99.10-113-g65edf7d-r3-0-g9e4f715 */ +-/* ^ ^ ^^ ^ */ +-/* | | |--|---------- additional details */ +-/* | |---------------- Minor */ +-/* |------------------ Major */ +-/* Additional details : If the option group exists it will force Auxiliary */ +-/* Firmware Revision Information 4th byte to 1 indicating the build was */ +-/* derived with additional edits */ ++/* ^ ^ ^^^^^^ ^^^^^ */ ++/* | | | | */ ++/* | | | `-- AUX dirty flag */ ++/* | | `---------- AUX commit hash */ ++/* | `---------------- Minor */ ++/* `------------------ Major */ ++/* */ ++/* Format 2: */ ++/* version = v1.99.10-113-g65edf7d-r3-0-g9e4f715-dirty */ ++/* ^ ^^ ^^^^^^ ^^^^^ */ ++/* | | | .-----------------' */ ++/* | | | `- AUX dirty flag */ ++/* | | `----- AUX commit hash */ ++/* | `---------------- Minor */ ++/* `------------------ Major */ ++/* */ ++/* version = v2.09-dev-794-g196400c89-some-branch-name-dirty */ ++/* ^ ^^ ^^^^^^ ^^^^^ */ ++/* | | | .-----------------------' */ ++/* | | | `- AUX dirty flag */ ++/* | | `---- AUX commit hash */ ++/* | `---------------- Minor */ ++/* `------------------ Major */ ++/* */ ++/* Format 3 (YADRO Releases): */ ++/* version = v1.0rcf2817p7-rc2-unofficial-dirty */ ++/* ^ ^ ^^^^^^ ^^ .----------^^^^^ */ ++/* | | | | `- AUX dirty flag */ ++/* | | | `------- AUX patch level (1-126), optional */ ++/* | | `-------------- AUX release number */ ++/* | `---------------- Minor */ ++/* `------------------ Major */ ++/* */ ++static + int convertVersion(std::string s, Revision& rev) + { +- std::string token; +- uint16_t commits; ++ std::vector<std::string> tokens; ++ bool has_release = false; // version string is of "release" format 3 ++ bool dirty = false; + ++ constexpr int TOKEN_MAJOR = 0; ++ constexpr int TOKEN_MINOR = 1; ++ // These are for "release" format 3 ++ constexpr int TOKEN_MINOR_HASH = 1; ++ constexpr int TOKEN_MINOR_PATCH = 2; ++ // For non-release formats 1 and 2 ++ constexpr int TOKEN_HASH = 3; // Search for git hash starting from this ++ ++ // Hash info is in the higher 24 bits of AUX F/W Revision Info ++ constexpr int AUX_HASH_SHIFT = 8; ++ constexpr int AUX_HASH_LEN = 6; ++ ++ // Non-release indicator is byte 3 (bits 7..1 of AUX F/W Revision Info) ++ constexpr int AUX_NON_REL_BYTE = 3; ++ constexpr int AUX_NON_REL_SHIFT = 1; ++ constexpr uint8_t AUX_NON_REL_VALUE = UINT8_MAX >> AUX_NON_REL_SHIFT; ++ ++ // Release patch level occupies the same bits as the non-release indicator ++ constexpr int AUX_PATCH_BYTE = AUX_NON_REL_BYTE; ++ constexpr int AUX_PATCH_SHIFT = AUX_NON_REL_SHIFT; ++ constexpr int AUX_MAX_PATCH = AUX_NON_REL_VALUE - 1; ++ ++ // The least significant bit of byte 3 is the dirty flag ++ constexpr int AUX_DIRTY_BYTE = 3; ++ constexpr int AUX_DIRTY_SHIFT = 0; ++ ++ // Use base-16 to convert decimals to BCD ++ constexpr int BCD_BASE = 16; ++ ++ // First of all clear the revision ++ rev = {0}; ++ ++ // Cut off the optional 'v' at the beginning + auto location = s.find_first_of('v'); + if (location != std::string::npos) + { +@@ -494,64 +576,77 @@ int convertVersion(std::string s, Revision& rev) + + if (!s.empty()) + { +- location = s.find_first_of("."); +- if (location != std::string::npos) ++ int hash = 0; ++ ++ if (s.find("dirty") != std::string::npos) + { +- rev.major = +- static_cast<char>(std::stoi(s.substr(0, location), 0, 16)); +- token = s.substr(location + 1); ++ dirty = true; + } + +- if (!token.empty()) ++ tokens = tokenize(s, ".-"); ++ ++ if (!tokens.empty()) + { +- location = token.find_first_of(".-"); +- if (location != std::string::npos) ++ rev.major = std::stoi(tokens[TOKEN_MAJOR], 0, BCD_BASE); ++ } ++ ++ if (tokens.size() > TOKEN_MINOR) ++ { ++ rev.minor = std::stoi(tokens[TOKEN_MINOR], 0, BCD_BASE); ++ ++ // Minor version token may also contain release/patchlevel info ++ std::vector<std::string> minortok; ++ ++ minortok = tokenize(tokens[TOKEN_MINOR], "rp"); ++ ++ if (minortok.size() > TOKEN_MINOR_HASH) + { +- rev.minor = static_cast<char>( +- std::stoi(token.substr(0, location), 0, 16)); +- token = token.substr(location + 1); ++ // hash is plain hex ++ hash= std::stoi(minortok[TOKEN_MINOR_HASH], 0, 16); ++ has_release = true; ++ } ++ ++ if (minortok.size() > TOKEN_MINOR_PATCH) ++ { ++ // Patch level is encoded as binary, not BCD. ++ // That is to allow for a wider range. ++ int pl = std::stoi(minortok[TOKEN_MINOR_PATCH], 0, 10); ++ uint8_t patchlevel = (pl > AUX_MAX_PATCH) ++ ? AUX_MAX_PATCH ++ : pl; ++ rev.aux[AUX_PATCH_BYTE] = patchlevel << AUX_PATCH_SHIFT; + } + } + +- // Capture the number of commits on top of the minor tag. +- // I'm using BE format like the ipmi spec asked for +- location = token.find_first_of(".-"); +- if (!token.empty()) ++ // If it's not a "release" format 3, then search for ++ // letter 'g' indicating the position of a git hash ++ // in the version string ++ if (!has_release && tokens.size() > TOKEN_HASH) + { +- commits = std::stoi(token.substr(0, location), 0, 16); +- rev.d[0] = (commits >> 8) | (commits << 8); +- +- // commit number we skip +- location = token.find_first_of(".-"); +- if (location != std::string::npos) ++ std::string hashstr; ++ for (size_t i = TOKEN_HASH; i < tokens.size(); ++i) + { +- token = token.substr(location + 1); ++ // Find the first token that looks like a git hash. ++ // We think here that anything starting with a 'g' is a match. ++ if ('g' == tokens[i][0]) ++ { ++ // Cut off the 'g', take only the first AUX_HASH_LEN digits ++ hashstr = tokens[i].substr(1, AUX_HASH_LEN); ++ break; ++ } + } +- } +- else +- { +- rev.d[0] = 0; +- } + +- if (location != std::string::npos) +- { +- token = token.substr(location + 1); ++ // Hash is plain hex ++ hash = std::stoi(hashstr, 0, 16); ++ rev.aux[AUX_NON_REL_BYTE] |= AUX_NON_REL_VALUE << AUX_NON_REL_SHIFT; + } ++ rev.aux32 |= htobe32(hash << AUX_HASH_SHIFT); ++ rev.aux[AUX_DIRTY_BYTE] |= dirty << AUX_DIRTY_SHIFT; + +- // Any value of the optional parameter forces it to 1 +- location = token.find_first_of(".-"); +- if (location != std::string::npos) +- { +- token = token.substr(location + 1); +- } +- commits = (!token.empty()) ? 1 : 0; +- +- // We do this operation to get this displayed in least significant bytes +- // of ipmitool device id command. +- rev.d[1] = (commits >> 8) | (commits << 8); ++ return 0; + } + +- return 0; ++ return -1; + } + + /* @brief: Implement the Get Device ID IPMI command per the IPMI spec +@@ -623,7 +718,7 @@ ipmi::RspType<uint8_t, // Device ID + + rev.minor = (rev.minor > 99 ? 99 : rev.minor); + devId.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16; +- std::memcpy(&devId.aux, rev.d, 4); ++ std::memcpy(&devId.aux, rev.aux, 4); + } + + // IPMI Spec version 2.0 +@@ -640,7 +735,14 @@ ipmi::RspType<uint8_t, // Device ID + devId.addnDevSupport = data.value("addn_dev_support", 0); + devId.manufId = data.value("manuf_id", 0); + devId.prodId = data.value("prod_id", 0); +- devId.aux = data.value("aux", 0); ++ ++ // Use the AUX data from the file only for overriding ++ // the data obtained from version string. ++ if (data.contains("aux")) ++ { ++ // AUX F/W Revision Info is MSB first (big-endian) ++ devId.aux = htobe32(data.value("aux", 0)); ++ } + + // Set the availablitity of the BMC. + defaultActivationSetting = data.value("availability", true); +-- +2.28.0 + diff --git a/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend new file mode 100644 index 000000000..b4b1a2f1e --- /dev/null +++ b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend @@ -0,0 +1,7 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +SRC_URI += "\ + file://0001-Add-support-for-persistent-only-settings.patch \ + file://0002-Add-support-for-boot-initiator-mailbox.patch \ + file://0003-Fix-version-parsing-update-AUX-revision-info.patch \ +" |