summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager/xyz.openbmc_project.CloseMuxes.service10
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend18
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0002-Modify-Dbus-for-IPv6.patch61
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0003-Chassis-Power-Control-are-implemented.patch264
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0005-Add-DBUS-interface-of-CPU-and-Memory-s-properties.patch120
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0007-ipmi-set-BIOS-id.patch32
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0009-Add-host-restart-cause-property.patch98
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0010-Increase-the-default-watchdog-timeout-value.patch34
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0012-Add-RestoreDelay-interface-for-power-restore-delay.patch34
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0013-Add-ErrConfig.yaml-interface-for-processor-error-config.patch86
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0014-Add-multiple-state-signal-for-host-start-and-stop.patch63
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0016-Add-DBUS-interface-of-SMBIOS-MDR-V2.patch227
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0018-Define-post-code-interfaces-for-post-code-manager.patch64
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0019-Creating-the-Session-interface-for-Host-and-LAN.patch116
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0020-Create-dbus-interface-for-SOL-commands.patch76
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0021-Add-interface-suppot-for-provisioning-modes.patch52
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0022-Add-chassis-power-cycle-and-reset-to-Chassis-State.patch40
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0023-Add-host-interrupt-to-the-Host-State.patch31
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch57
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend22
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper/xyz.openbmc_project.ObjectMapper.service20
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper_%.bbappend1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control/phosphor-pid-control.service14
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control_%.bbappend10
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0002-Redfish-firmware-activation.patch44
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0004-Changed-the-condition-of-software-version-service-wa.patch41
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0005-Modified-firmware-activation-to-launch-fwupd.sh-thro.patch188
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0006-Modify-the-ID-of-software-image-updater-object-on-DB.patch44
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/fwupd@.service8
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager_%.bbappend13
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/gpiodaemon/gpiodaemon.bb18
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/host/obmc-op-control-host%.bbappend6
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/bmcweb.socket9
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend17
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config.bbappend21
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/channel_access.json23
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/channel_config.json178
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/dev_id.json2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/master_write_read_white_list.json76
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-fru-merge-config-native.bbappend8
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-fru-merge-config-native/config.yaml31
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0002-Modify-dbus-interface-for-power-control.patch31
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0009-IPv6-Network-changes.patch899
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0010-fix-get-system-GUID-ipmi-command.patch56
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0013-ipmi-add-set-bios-id-to-whitelist.patch25
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0021-Implement-IPMI-Commmand-Get-Host-Restart-Cause.patch143
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0039-ipmi-add-oem-command-get-AIC-FRU-to-whitelist.patch25
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0049-Fix-Unspecified-error-on-ipmi-restart-cause-command.patch71
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0050-enable-6-oem-commands.patch15
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0053-Fix-keep-looping-issue-when-entering-OS.patch80
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0054-Fix-User-commands-require-channel-layer-lib.patch37
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0055-Implement-set-front-panel-button-enables-command.patch176
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0056-add-SetInProgress-to-get-set-boot-option-cmd.patch102
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0057-Add-timer-use-actions-support.patch195
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0058-Add-AC-failed-bit-support-for-get-chassis-status-com.patch76
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0059-Move-Set-SOL-config-parameter-to-host-ipmid.patch415
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0060-Move-Get-SOL-config-parameter-to-host-ipmid.patch342
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0061-Use-xyz.openbmc_project.State.Chassis-for-IPMI-chass.patch127
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0062-Update-IPMI-Chassis-Control-command.patch214
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch140
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/phosphor-ipmi-host.service26
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend41
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-ipmb_%.bbappend2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs/99-ipmi-kcs.rules2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs_%.bbappend21
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/00010-Change-Authentication-Parameter.patch40
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0006-Modify-dbus-namespace-of-chassis-control-for-guid.patch39
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0007-Adding-support-for-GetSessionInfo-command.patch418
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0008-Sync-GetSession-Info-cmd-based-on-Upstream-review.patch282
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0009-Add-dbus-interface-for-sol-commands.patch311
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0011-Remove-Get-SOL-Config-Command-from-Netipmid.patch336
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net_%.bbappend29
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-sensor-inventory%.bbappend1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-sensor-inventory%/config.yaml0
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-node-manager-proxy_git.bb19
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/leds/intel-led-manager-config-native.bb21
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/leds/intel-led-manager-config/led.yaml48
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/logging/phosphor-logging_%.bbappend2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/multi-node-manager/multi-node-manager.bb15
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/preinit-mounts/preinit-mounts.bbappend3
-rwxr-xr-xmeta-openbmc-mods/meta-common/recipes-phosphor/preinit-mounts/preinit-mounts/init203
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sel-logger/phosphor-sel-logger_%.bbappend7
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/selftest/intel-self-test/xyz.openbmc_project.selftest.service10
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/selftest/intel-self-test_git.bb38
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend7
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-defaults-native.bbappend4
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-defaults-native/defaults.yaml209
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-manager/0001-settings-initialize-data-file-with-default-setting.patch37
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-manager_%.bbappend9
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/settings/settings_git.bb20
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/special-mode-mgr/special-mode-mgr_git.bb28
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/srvcfg-manager/srvcfg-manager_git.bb28
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0001-Modify-dbus-interface-for-power-control.patch38
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0002-Capture-host-restart-cause.patch338
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0003-Use-warm-reboot-for-the-Reboot-host-state-transition.patch71
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0004-Add-Power-Restore-delay-support.patch141
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/phosphor-reboot-host@.service18
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/phosphor-reset-host-check@.service19
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/phosphor-reset-host-reboot-attempts@.service14
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager_%.bbappend10
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/state/post-code-manager/0001-Implement-post-code-manager.patch499
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/state/post-code-manager_git.bb34
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/system/callback-manager.bb19
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0005-Added-suport-for-multiple-user-manager-services.patch1648
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend9
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog.bb35
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/.clang-format98
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/CMakeLists.txt52
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/cmake-format.json12
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/frb2-watchdog.cpp258
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0001-Add-redfish-log-support-for-IPMI-watchdog-timeout-ac.patch51
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0002-Add-restart-cause-support.patch82
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0003-Add-redfish-log-support-for-IPMI-watchdog-pre-timeou.patch48
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/obmc-enable-host-watchdog@.service14
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/phosphor-watchdog@.service12
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend9
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb13
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/obmc/system-watchdog/system-watchdog.conf3
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/system-watchdog.service11
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui/0004-Implement-force-boot-to-bios-in-server-power-control.patch199
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui_%.bbappend6
121 files changed, 11463 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager/xyz.openbmc_project.CloseMuxes.service b/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager/xyz.openbmc_project.CloseMuxes.service
new file mode 100644
index 000000000..bc05fa1a1
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager/xyz.openbmc_project.CloseMuxes.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Close Muxes
+ConditionFileNotEmpty=/usr/bin/CloseMuxes.py
+
+[Service]
+ExecStart=/usr/bin/env CloseMuxes.py
+Type=oneshot
+
+[Install]
+WantedBy=basic.target
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend
new file mode 100644
index 000000000..8b9da74f0
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend
@@ -0,0 +1,18 @@
+# this is here just to bump faster than upstream
+SRC_URI = "git://github.com/openbmc/entity-manager.git"
+SRCREV = "15c49902cf030a91a5b4bd325d185ee74b760359"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+RDEPENDS_${PN} += "python"
+SRC_URI += " file://xyz.openbmc_project.CloseMuxes.service"
+SYSTEMD_SERVICE_${PN} += " xyz.openbmc_project.CloseMuxes.service"
+
+EXTRA_OECMAKE = "-DYOCTO=1 -DUSE_OVERLAYS=0"
+
+do_install_prepend() {
+ install -d ${D}${bindir}
+ install -m 0755 ${S}/scripts/CloseMuxes.py ${D}${bindir}
+ install -d ${D}${base_libdir}/systemd/system
+ install -m 0644 ${WORKDIR}/xyz.openbmc_project.CloseMuxes.service ${D}${base_libdir}/systemd/system
+}
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0002-Modify-Dbus-for-IPv6.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0002-Modify-Dbus-for-IPv6.patch
new file mode 100644
index 000000000..3ca81c388
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0002-Modify-Dbus-for-IPv6.patch
@@ -0,0 +1,61 @@
+From 068b816b3c9bf75dcd2a808fc81c67a32fbe29ea Mon Sep 17 00:00:00 2001
+From: David Cobbley <david.j.cobbley@linux.intel.com>
+Date: Wed, 6 Jun 2018 10:11:58 -0700
+Subject: [PATCH] Modify Dbus for IPv6.
+
+Add additional interfaces for IPv6 use.
+---
+ .../Network/EthernetInterface.interface.yaml | 17 ++++++++++++++++-
+ xyz/openbmc_project/Network/IP.interface.yaml | 4 ++++
+ 2 files changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/xyz/openbmc_project/Network/EthernetInterface.interface.yaml b/xyz/openbmc_project/Network/EthernetInterface.interface.yaml
+index 744ac77..6b7cd9a 100644
+--- a/xyz/openbmc_project/Network/EthernetInterface.interface.yaml
++++ b/xyz/openbmc_project/Network/EthernetInterface.interface.yaml
+@@ -42,6 +42,14 @@ properties:
+ description: >
+ This indicates link local auto configuration on this ethernet
+ interface and configured on this ethernet interface.
++ - name: IPv6AcceptRA
++ type: boolean
++ description: >
++ Boolean for accepting router advertisements in IPv6
++ - name: IPAddressEnables
++ type: enum[self.IPAllowed]
++ description: >
++ The type of IP connection is allowed on this channel
+
+ enumerations:
+ - name: LinkLocalConf
+@@ -52,4 +60,11 @@ enumerations:
+ - name: v4
+ - name: v6
+ - name: none
+-
++ - name: IPAllowed
++ description: >
++ Determines whether the system allows both IPv6 & IPv4, or disables on
++ or the other
++ values:
++ - name: IPv4AndIPv6
++ - name: IPv4Only
++ - name: IPv6Only
+diff --git a/xyz/openbmc_project/Network/IP.interface.yaml b/xyz/openbmc_project/Network/IP.interface.yaml
+index 565dcd6..2ffb016 100644
+--- a/xyz/openbmc_project/Network/IP.interface.yaml
++++ b/xyz/openbmc_project/Network/IP.interface.yaml
+@@ -22,6 +22,10 @@ properties:
+ type: string
+ description: >
+ This is the IP gateway for this address.
++ - name: BackupGateway
++ type: string
++ description: >
++ This is the IP address of the backup gateway.
+ - name: Type
+ type: enum[self.Protocol]
+ description: >
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0003-Chassis-Power-Control-are-implemented.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0003-Chassis-Power-Control-are-implemented.patch
new file mode 100644
index 000000000..0e25856ac
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0003-Chassis-Power-Control-are-implemented.patch
@@ -0,0 +1,264 @@
+From a20f9fa9941533b591b6bbfe6b22a74b7c0dfe64 Mon Sep 17 00:00:00 2001
+From: Ed Tanous <ed.tanous@intel.com>
+Date: Thu, 24 Jan 2019 09:29:01 -0800
+Subject: [PATCH] Chassis Power Control are implemented.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Feature level:
+Power on server is ready
+Power off server is ready
+Power cycle server is ready
+Power reset server is ready
+
+Framework level:
+WebUI is enabled.
+IPMI Commands is enabled.
+Restful API is enabled.
+Physical buttons (Power/Reset/ID) are enabled.
+Chassis state manager is enabled.
+Host state manager is enabled.
+
+Enabled IPMI commands:
+ipmitool -H <ip_addr> -P <pass_word> -I lanplus chassis status
+ipmitool -H <ip_addr>  -P <pass_word> -I lanplus chassis power status
+ipmitool -H <ip_addr>  -P <pass_word> -I lanplus chassis power on
+ipmitool -H <ip_addr>  -P <pass_word> -I lanplus chassis power off
+ipmitool -H <ip_addr>  -P <pass_word> -I lanplus chassis power cycle
+ipmitool -H <ip_addr>  -P <pass_word> -I lanplus chassis power reset
+
+Enabled Restful APIs:
+Login: curl --noproxy <ip_addr> -c cjar -b cjar -k -H "Content-Type: application/json" -X POST https://<ip_addr>/login -d "{\"data\": [ \"root\", \"0penBmc\" ] }“
+Host State: curl --noproxy <ip_addr> -b cjar -k https://<ip_addr>/xyz/openbmc_project/state/host0
+Chassis State: curl --noproxy <ip_addr> -b cjar -k https://<ip_addr>/xyz/openbmc_project/state/chassis0
+Power state: curl --noproxy <ip_addr> -b cjar -k https://<ip_addr>/xyz/openbmc_project/Chassis/Control/Power0
+Power on/off: curl --noproxy <ip_addr> -q1c cjar -b cjar -k -H "Content-Type: application/json" -d '{"data": "xyz.openbmc_project.State.Host.Transition.Off"}' -X PUT https://<ip_addr>/xyz/openbmc_project/state/host0/attr/RequestedHostTransition
+
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ .../Chassis/Control/Chassis.interface.yaml | 94 ++++++++++++++++++++++
+ .../Chassis/Control/Power.interface.yaml | 92 ++++++++++++++++++---
+ 2 files changed, 173 insertions(+), 13 deletions(-)
+ create mode 100644 xyz/openbmc_project/Chassis/Control/Chassis.interface.yaml
+
+diff --git a/xyz/openbmc_project/Chassis/Control/Chassis.interface.yaml b/xyz/openbmc_project/Chassis/Control/Chassis.interface.yaml
+new file mode 100644
+index 0000000..c28492a
+--- /dev/null
++++ b/xyz/openbmc_project/Chassis/Control/Chassis.interface.yaml
+@@ -0,0 +1,94 @@
++description: >
++ chassis control service
++methods:
++ - name: powerOn
++ description: >
++ Power on system.
++ returns:
++ - name: state
++ type: int32
++ description: >
++ The result of command.
++ errors:
++ - xyz.openbmc_project.Chassis.Common.Error.UnsupportedCommand
++
++ - xyz.openbmc_project.Chassis.Common.Error.IOError
++
++ - name: powerOff
++ description: >
++ Power Off system.
++ returns:
++ - name: state
++ type: int32
++ description: >
++ The result of command.
++ errors:
++ - xyz.openbmc_project.Chassis.Common.Error.UnsupportedCommand
++
++ - xyz.openbmc_project.Chassis.Common.Error.IOError
++
++ - name: softPowerOff
++ description: >
++ Soft Power off system.
++ returns:
++ - name: state
++ type: int32
++ description: >
++ The result of command.
++ errors:
++ - xyz.openbmc_project.Chassis.Common.Error.UnsupportedCommand
++
++ - xyz.openbmc_project.Chassis.Common.Error.IOError
++
++ - name: reboot
++ description: >
++ reboot system.
++ returns:
++ - name: state
++ type: int32
++ description: >
++ The result of command.
++ errors:
++ - xyz.openbmc_project.Chassis.Common.Error.UnsupportedCommand
++
++ - xyz.openbmc_project.Chassis.Common.Error.IOError
++
++ - name: softReboot
++ description: >
++ Soft Reboot system.
++ returns:
++ - name: state
++ type: int32
++ description: >
++ The result of command.
++ errors:
++ - xyz.openbmc_project.Chassis.Common.Error.UnsupportedCommand
++
++ - xyz.openbmc_project.Chassis.Common.Error.IOError
++
++ - name: quiesce
++ description: >
++ Quiesce system.
++ returns:
++ - name: state
++ type: int32
++ description: >
++ The result of command.
++ errors:
++ - xyz.openbmc_project.Chassis.Common.Error.UnsupportedCommand
++
++ - xyz.openbmc_project.Chassis.Common.Error.IOError
++
++ - name: getPowerState
++ description: >
++ Get system power state.
++ returns:
++ - name: state
++ type: int32
++ description: >
++ The result of command.
++ errors:
++ - xyz.openbmc_project.Chassis.Common.Error.UnsupportedCommand
++
++ - xyz.openbmc_project.Chassis.Common.Error.IOError
++
+diff --git a/xyz/openbmc_project/Chassis/Control/Power.interface.yaml b/xyz/openbmc_project/Chassis/Control/Power.interface.yaml
+index 082586f..368beca 100644
+--- a/xyz/openbmc_project/Chassis/Control/Power.interface.yaml
++++ b/xyz/openbmc_project/Chassis/Control/Power.interface.yaml
+@@ -1,31 +1,97 @@
+ description: >
+- Power control service
++ Chassis control service
+ methods:
++ - name: setPowerState
++ description: >
++ set host power state.
++ parameters:
++ - name: state
++ type: int32
++ description: >
++ 0 for force power off host
++ 1 for power on host
++ returns:
++ - name: status
++ type: int32
++ description: >
++ The result of command.
++ errors:
++ - xyz.openbmc_project.Chassis.Common.Error.UnsupportedCommand
++
++ - xyz.openbmc_project.Chassis.Common.Error.IOError
++
++ - name: getPowerState
++ description: >
++ Get current host power status.
++ returns:
++ - name: status
++ type: int32
++ description: >
++ Current host status,
++ 0 for host power off
++ 1 for host power on
++ errors:
++ - xyz.openbmc_project.Chassis.Common.Error.UnsupportedCommand
++
++ - xyz.openbmc_project.Chassis.Common.Error.IOError
++
+ - name: forcePowerOff
+ description: >
+ Force power off the host.
+ returns:
+ - name: status
+- type: boolean
++ type: int32
+ description: >
+ The result of power off command.
+ errors:
+ - xyz.openbmc_project.Chassis.Common.Error.UnsupportedCommand
++
+ - xyz.openbmc_project.Chassis.Common.Error.IOError
+
+ properties:
+- - name: PGood
+- type: boolean
+- default: false
++ - name: vrd_good
++ type: int32
++ default: 0
++ description: >
++ ACPI status
++ - name: s4s5_state
++ type: int32
++ default: 0
++ description: >
++ ACPI status
++ - name: pgood
++ type: int32
++ default: 0
+ description: >
+- PSU Power good property
+- It is a read-only property.
+- - name: State
++ pgood property
++ - name: state
+ type: int32
+ default: 0
+ description: >
+- System power status
+- 0: power is off
+- 1: power is on
+- Setting its value to change the system state
+- Read its value to get the system state.
+\ No newline at end of file
++ state property
++ - name: pgood_timeout
++ type: int32
++ default: 0
++ description: >
++ pgoodtimeout property
++ - name: post_complete
++ type: boolean
++ default: false
++ description: >
++ The current BIOS POST state,
++ false means not completed or system reset,
++ true means BIOS POST completed.
++ - name: PFail
++ type: boolean
++ default: true
++ description: >
++ The current booting status,
++ true means booting from AC loss,
++ false means not booting from AC loss.
++signals:
++ - name: PowerGood
++ description: >
++ Signal for powergood
++ - name: PowerLost
++ description: >
++ Signal for powerlost
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0005-Add-DBUS-interface-of-CPU-and-Memory-s-properties.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0005-Add-DBUS-interface-of-CPU-and-Memory-s-properties.patch
new file mode 100644
index 000000000..7568f8ce9
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0005-Add-DBUS-interface-of-CPU-and-Memory-s-properties.patch
@@ -0,0 +1,120 @@
+From a30a09f58b9ebfb267c0b9cce9ae25994ea025ca Mon Sep 17 00:00:00 2001
+From: cyang29 <cheng.c.yang@intel.com>
+Date: Tue, 17 Jul 2018 16:04:58 +0800
+Subject: [PATCH] Add DBUS interface of CPU and Memory's properties Feature
+ Support: SMBIOS service interface. CPU DIMM information redfish
+ interface. Base on smbios spec DSP0134_3.0.0
+
+Signed-off-by: cyang29 <cheng.c.yang@intel.com>
+---
+ .../Inventory/Item/Cpu.interface.yaml | 41 +++++++++++++++++++
+ .../Inventory/Item/Dimm.interface.yaml | 46 +++++++++++++++++++++-
+ 2 files changed, 86 insertions(+), 1 deletion(-)
+
+diff --git a/xyz/openbmc_project/Inventory/Item/Cpu.interface.yaml b/xyz/openbmc_project/Inventory/Item/Cpu.interface.yaml
+index ab29cf3..313eada 100644
+--- a/xyz/openbmc_project/Inventory/Item/Cpu.interface.yaml
++++ b/xyz/openbmc_project/Inventory/Item/Cpu.interface.yaml
+@@ -1,4 +1,45 @@
+ description: >
+ Implement to provide CPU attributes.
++properties:
++ - name: ProcessorSocket
++ type: string
++ description: >
++ Processor Socket on MotherBoard
++ - name: ProcessorType
++ type: string
++ description: >
++ Processor Type of CPU
++ - name: ProcessorFamily
++ type: string
++ description: >
++ Processor Family of CPU
++ - name: ProcessorManufacturer
++ type: string
++ description: >
++ Processor Manufacturer of CPU
++ - name: ProcessorId
++ type: uint32
++ description: >
++ Processor ID of CPU
++ - name: ProcessorVersion
++ type: string
++ description: >
++ Processor Version of CPU
++ - name: ProcessorMaxSpeed
++ type: uint16
++ description: >
++ Max Speed CPU Can Support
++ - name: ProcessorCharacteristics
++ type: string
++ description: >
++ The Characteristics CPU Has
++ - name: ProcessorCoreCount
++ type: uint16
++ description: >
++ The Count of Core in CPU
++ - name: ProcessorThreadCount
++ type: uint16
++ description: >
++ The Count of Thread CPU Can Support
+
+ # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
+diff --git a/xyz/openbmc_project/Inventory/Item/Dimm.interface.yaml b/xyz/openbmc_project/Inventory/Item/Dimm.interface.yaml
+index d85326d..b750320 100644
+--- a/xyz/openbmc_project/Inventory/Item/Dimm.interface.yaml
++++ b/xyz/openbmc_project/Inventory/Item/Dimm.interface.yaml
+@@ -1,4 +1,48 @@
+ description: >
+ Implement to provide DIMM attributes.
+-
++properties:
++ - name: MemoryDataWidth
++ type: uint16
++ description: >
++ Data width of Memory.
++ - name: MemorySizeInKB
++ type: uint32
++ description: >
++ Memory size of DIMM in Kilobyte.
++ - name: MemoryDeviceLocator
++ type: string
++ description: >
++ Socket on base board where Memory located.
++ - name: MemoryType
++ type: string
++ description: >
++ Type of memory.
++ - name: MemoryTypeDetail
++ type: string
++ description: >
++ Additional detail on Memory.
++ - name: MemorySpeed
++ type: uint16
++ description: >
++ The maximun capable speed of Memory.
++ - name: MemoryManufacturer
++ type: string
++ description: >
++ Manufacturer of memory.
++ - name: MemorySerialNum
++ type: string
++ description: >
++ Memory Serial Number.
++ - name: MemoryPartNum
++ type: string
++ description: >
++ Memory Part Number.
++ - name: MemoryAttributes
++ type: byte
++ description: >
++ Rank attributes of Memory.
++ - name: MemoryConfClockSpeed
++ type: uint16
++ description: >
++ Configured clock speed to Memory.
+ # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
+--
+2.16.2
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0007-ipmi-set-BIOS-id.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0007-ipmi-set-BIOS-id.patch
new file mode 100644
index 000000000..c87b2d89d
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0007-ipmi-set-BIOS-id.patch
@@ -0,0 +1,32 @@
+From 49debd0955b672d591f35e74119b288bd6df2992 Mon Sep 17 00:00:00 2001
+From: "Jia, Chunhui" <chunhui.jia@intel.com>
+Date: Tue, 24 Jul 2018 11:40:49 +0800
+Subject: [PATCH] [ipmi] set BIOS id
+
+change#2
+add new dbus interface for BIOS attributes
+
+Signed-off-by: Jia, Chunhui <chunhui.jia@intel.com>
+---
+ xyz/openbmc_project/Inventory/Item/Bios.interface.yaml | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+ create mode 100644 xyz/openbmc_project/Inventory/Item/Bios.interface.yaml
+
+diff --git a/xyz/openbmc_project/Inventory/Item/Bios.interface.yaml b/xyz/openbmc_project/Inventory/Item/Bios.interface.yaml
+new file mode 100644
+index 0000000..d7a6b95
+--- /dev/null
++++ b/xyz/openbmc_project/Inventory/Item/Bios.interface.yaml
+@@ -0,0 +1,9 @@
++description: >
++ Implement to provide BIOS attributes.
++properties:
++ - name: BiosId
++ type: string
++ description: >
++ BIOS ID (version) string
++
++# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
+--
+2.16.2
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0009-Add-host-restart-cause-property.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0009-Add-host-restart-cause-property.patch
new file mode 100644
index 000000000..1221a0ab4
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0009-Add-host-restart-cause-property.patch
@@ -0,0 +1,98 @@
+From 72b7b30a5dda56c170ee2ce82c1082c26f4663e3 Mon Sep 17 00:00:00 2001
+From: Kuiying Wang <kuiying.wang@intel.com>
+Date: Tue, 31 Jul 2018 16:55:21 +0800
+Subject: [PATCH] Add host restart cause property.
+
+Add host restart cause property to track the information about what
+action last caused the system to restart.
+According to IPMI Spec, it includes 12 types as following:
+1. Unknown 0x0
+2. IpmiCommand 0x1
+3. ResetButton 0x2
+4. PowerButton 0x3
+5. WatchdogTimer 0x4
+6. OEM 0x5
+7. PowerPolicyAlwaysOn 0x6
+8. PowerPolicyPreviousState 0x7
+9. PEF-Reset 0x8
+10. PEF-PowerCycle 0x9
+11. SoftReset 0xA
+12. RTC-Wakeup 0xB
+
+Change-Id: Id2cc6a18b98e485a978940e5ffc085bf5c4fbed8
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+---
+ xyz/openbmc_project/State/Host.interface.yaml | 52 +++++++++++++++++++
+ 1 file changed, 52 insertions(+)
+
+diff --git a/xyz/openbmc_project/State/Host.interface.yaml b/xyz/openbmc_project/State/Host.interface.yaml
+index 8f481b8..a4d88d0 100644
+--- a/xyz/openbmc_project/State/Host.interface.yaml
++++ b/xyz/openbmc_project/State/Host.interface.yaml
+@@ -17,6 +17,12 @@ properties:
+ comparing the CurrentHostState and the RequestedHostTransition
+ properties.
+
++ - name: HostRestartCause
++ type: enum[self.RestartCause]
++ default: Unknown
++ description: >
++ The information about what action last caused the system to restart.
++
+ enumerations:
+ - name: Transition
+ description: >
+@@ -45,3 +51,49 @@ enumerations:
+ - name: 'Quiesced'
+ description: >
+ Host firmware is quiesced
++
++ - name: RestartCause
++ description: >
++ The information about what action last caused the system to restart.
++ values:
++ - name: Unknown
++ description: >
++ System start/restart detected but the reason is unknown.
++ - name: IpmiCommand
++ description: >
++ System start/restart detected and caused by ipmi command.
++ - name: ResetButton
++ description: >
++ System start/restart detected and caused by reset button.
++ - name: PowerButton
++ description: >
++ System start/restart detected and caused by power button.
++ - name: WatchdogTimer
++ description: >
++ System start/restart detected and casued by watchdog expiration.
++ - name: OEM
++ description: >
++ System start/restart detected and caused by OEM command.
++ - name: PowerPolicyAlwaysOn
++ description: >
++ System start/restart detected and caused by power restore policy
++ "chassis always powers up after AC/mains is applied or returns".
++ - name: PowerPolicyPreviousState
++ description: >
++ System start/restart detected and caused by power restore policy
++ "after AC/mains is applied or returns, power is restored to the
++ state was in effect when AC/mains removed or lost".
++ - name: PEFReset
++ description: >
++ System start/restart detected and caused by PEF(reset).
++ - name: PEFPowerCycle
++ description: >
++ System start/restart detected and caused by PEF(power-cycle).
++ - name: SoftReset
++ description: >
++ System start/restart detected and caused by soft reset like
++ "CTRL-ALT-DEL".
++ - name: RTCWakeup
++ description: >
++ System start/restart detected and caused by system real time
++ clock(RTC) wakeup.
+\ No newline at end of file
+--
+2.17.0
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0010-Increase-the-default-watchdog-timeout-value.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0010-Increase-the-default-watchdog-timeout-value.patch
new file mode 100644
index 000000000..2c9344306
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0010-Increase-the-default-watchdog-timeout-value.patch
@@ -0,0 +1,34 @@
+From 631deef0ca88a77283741edeae8078d2185f414c Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Fri, 10 Aug 2018 16:23:13 +0800
+Subject: [PATCH] Increase the default watchdog timeout value
+
+The default timeout for poweron is 30 seconds,
+but currently the host power on needs 120+ seconds
+due to unimplemented ipmi commands for BIOS.
+
+Increase the value as a workaround,
+to avoid the watchdog timeout during power on.
+Will adjust this value in the future
+
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ xyz/openbmc_project/State/Watchdog.interface.yaml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/xyz/openbmc_project/State/Watchdog.interface.yaml b/xyz/openbmc_project/State/Watchdog.interface.yaml
+index f76dbf2..402e1a8 100644
+--- a/xyz/openbmc_project/State/Watchdog.interface.yaml
++++ b/xyz/openbmc_project/State/Watchdog.interface.yaml
+@@ -37,7 +37,7 @@ properties:
+ type: uint64
+ description: >
+ Time interval to arm the watchdog, in milli-second.
+- default: 30000
++ default: 600000
+ - name: TimeRemaining
+ type: uint64
+ description: >
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0012-Add-RestoreDelay-interface-for-power-restore-delay.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0012-Add-RestoreDelay-interface-for-power-restore-delay.patch
new file mode 100644
index 000000000..9052435ca
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0012-Add-RestoreDelay-interface-for-power-restore-delay.patch
@@ -0,0 +1,34 @@
+From eeac4cf4528994aeb213d549daf4c033ac9d3bbc Mon Sep 17 00:00:00 2001
+From: Kuiying Wang <kuiying.wang@intel.com>
+Date: Fri, 24 Aug 2018 17:55:35 +0800
+Subject: [PATCH] Add RestoreDelay interface for power restore delay
+
+Which provide one property "PowerRestoreDelay"
+
+Change-Id: I4e6d3e45948b1e288301b4aa52cc08cace4f1bc2
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+---
+ .../Control/Power/RestoreDelay.interface.yaml | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+ create mode 100644 xyz/openbmc_project/Control/Power/RestoreDelay.interface.yaml
+
+diff --git a/xyz/openbmc_project/Control/Power/RestoreDelay.interface.yaml b/xyz/openbmc_project/Control/Power/RestoreDelay.interface.yaml
+new file mode 100644
+index 0000000..55ee80a
+--- /dev/null
++++ b/xyz/openbmc_project/Control/Power/RestoreDelay.interface.yaml
+@@ -0,0 +1,11 @@
++description: >
++ Implement to specify power transition behavior on a BMC reset.
++ The implementation based on restore policy and set a delay time
++ for power restore.
++
++properties:
++ - name: PowerRestoreDelay
++ type: uint16
++ description: >
++ The delay time for power restore.
++ Power Restore Delay is NOT applied on power policy is "Always Off"
+--
+2.17.0
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0013-Add-ErrConfig.yaml-interface-for-processor-error-config.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0013-Add-ErrConfig.yaml-interface-for-processor-error-config.patch
new file mode 100644
index 000000000..9471c7ab2
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0013-Add-ErrConfig.yaml-interface-for-processor-error-config.patch
@@ -0,0 +1,86 @@
+From 7260c24b201759f3a5168eebfee215072c13e641 Mon Sep 17 00:00:00 2001
+From: Kuiying Wang <kuiying.wang@intel.com>
+Date: Thu, 30 Aug 2018 16:22:43 +0800
+Subject: [PATCH] Add ErrConfig.yaml interface for processor error
+ configuration.
+
+Which provide 3 properties:
+ ResetCfg
+ type: byte
+ description: >
+ Reset Configuration
+ [0]: CATERR Reset Enabled
+ 0b: Disabled
+ 1b: Enabled
+ [1]: ERR2 Reset Enabled
+ 0b: Disabled
+ 1b: Enabled
+ [7:2]: Reserved
+ ResetErrorOccurrenceCounts
+ type: byte
+ description: >
+ Reset Error Occurrence Counts
+ [0]: Reset CPU Error Counts
+ 0b: Keep CPU Error Counts
+ 1b: Reset all CPU Error Counts to zero
+ [7:1]: Reserved
+ CATERRStatus
+ type: array[byte]
+ description: >
+ For all CPUs including the non-legacy socket CPU
+ CPU CATERR (Core Error) occurrence
+ [5:0]: Error Occurrence Count
+ [7:6]: CPU Status
+ 00b: Disabled
+ 01b: Enabled
+ 11b: Not Present
+
+Change-Id: Ibc5a7a5e15c998e56c04e23b1043d99243a91171
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+---
+ .../Processor/ErrConfig.interface.yaml | 33 +++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+ create mode 100644 xyz/openbmc_project/Control/Processor/ErrConfig.interface.yaml
+
+diff --git a/xyz/openbmc_project/Control/Processor/ErrConfig.interface.yaml b/xyz/openbmc_project/Control/Processor/ErrConfig.interface.yaml
+new file mode 100644
+index 0000000..2304263
+--- /dev/null
++++ b/xyz/openbmc_project/Control/Processor/ErrConfig.interface.yaml
+@@ -0,0 +1,33 @@
++description: >
++ This defines processor error configuration.
++properties:
++ - name: ResetCfg
++ type: byte
++ description: >
++ Reset Configuration
++ [0]: CATERR Reset Enabled
++ 0b: Disabled
++ 1b: Enabled
++ [1]: ERR2 Reset Enabled
++ 0b: Disabled
++ 1b: Enabled
++ [7:2]: Reserved
++
++ - name: ResetErrorOccurrenceCounts
++ type: byte
++ description: >
++ Reset Error Occurrence Counts
++ [0]: Reset CPU Error Counts
++ 0b: Keep CPU Error Counts
++ 1b: Reset all CPU Error Counts to zero
++ [7:1]: Reserved
++ - name: CATERRStatus
++ type: array[byte]
++ description: >
++ For all CPUs including the non-legacy socket CPU
++ CPU CATERR (Core Error) occurrence
++ [5:0]: Error Occurrence Count
++ [7:6]: CPU Status
++ 00b: Disabled
++ 01b: Enabled
++ 11b: Not Present
+--
+2.17.0
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0014-Add-multiple-state-signal-for-host-start-and-stop.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0014-Add-multiple-state-signal-for-host-start-and-stop.patch
new file mode 100644
index 000000000..a8d732dab
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0014-Add-multiple-state-signal-for-host-start-and-stop.patch
@@ -0,0 +1,63 @@
+From 6d0069f4a2b4637c58fd321c9db3034ac9dd17c7 Mon Sep 17 00:00:00 2001
+From: Kuiying Wang <kuiying.wang@intel.com>
+Date: Wed, 12 Sep 2018 15:03:26 +0800
+Subject: [PATCH] Add multiple state signal for host start and stop
+
+Add six host state signals like following:
+ - name: PreHostStart
+ description: >
+ This is the signal to indicate host is at pre start stage.
+ - name: PostHostStart
+ description: >
+ This is the signal to indicate host is at start complete stage.
+ - name: HostStarting
+ description: >
+ This is the signal to indicate host is at starting stage.
+ - name: HostStoping
+ description: >
+ This is the signal to indicate host is at stoping stage.
+ - name: PreHostStop
+ description: >
+ This is the signal to indicate host is at pre stop stage.
+ - name: PostHostStop
+ description: >
+ This is the signal to indicate host is at stop complete stage.
+
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+---
+ xyz/openbmc_project/State/Host.interface.yaml | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/xyz/openbmc_project/State/Host.interface.yaml b/xyz/openbmc_project/State/Host.interface.yaml
+index 8531a27..1ceba13 100644
+--- a/xyz/openbmc_project/State/Host.interface.yaml
++++ b/xyz/openbmc_project/State/Host.interface.yaml
+@@ -96,4 +96,23 @@ enumerations:
+ - name: RTCWakeup
+ description: >
+ System start/restart detected and caused by system real time
+- clock(RTC) wakeup.
+\ No newline at end of file
++ clock(RTC) wakeup.
++signals:
++ - name: PreHostStart
++ description: >
++ This is the signal to indicate host is at pre start stage.
++ - name: PostHostStart
++ description: >
++ This is the signal to indicate host is at start complete stage.
++ - name: HostStarting
++ description: >
++ This is the signal to indicate host is at starting stage.
++ - name: HostStoping
++ description: >
++ This is the signal to indicate host is at stoping stage.
++ - name: PreHostStop
++ description: >
++ This is the signal to indicate host is at pre stop stage.
++ - name: PostHostStop
++ description: >
++ This is the signal to indicate host is at stop complete stage.
+--
+2.16.2
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0016-Add-DBUS-interface-of-SMBIOS-MDR-V2.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0016-Add-DBUS-interface-of-SMBIOS-MDR-V2.patch
new file mode 100644
index 000000000..576bae81a
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0016-Add-DBUS-interface-of-SMBIOS-MDR-V2.patch
@@ -0,0 +1,227 @@
+From 9490574667485cd407193ff9f0d6a96f8c2c87d3 Mon Sep 17 00:00:00 2001
+From: cyang29 <cheng.c.yang@intel.com>
+Date: Wed, 12 Sep 2018 00:27:23 +0800
+Subject: [PATCH] Add DBUS interface of SMBIOS MDR V2
+
+Support:
+ SMBIOS MDR V2 service interface.
+ SMBIOS MDR V2 IPMI Command
+ SMBIOS MDR V2 Redfish interface.
+Base on SMBIOS spec DSP0134_3.0.0 and Managed Data Region
+Specification Revision 4
+---
+ xyz/openbmc_project/Smbios/MDR_V2.errors.yaml | 9 +
+ xyz/openbmc_project/Smbios/MDR_V2.interface.yaml | 158 +++++++++++++++++++++++
+ xyz/openbmc_project/Smbios/README.md | 21 +++
+ 3 files changed, 188 insertions(+)
+ create mode 100644 xyz/openbmc_project/Smbios/MDR_V2.errors.yaml
+ create mode 100644 xyz/openbmc_project/Smbios/MDR_V2.interface.yaml
+ create mode 100644 xyz/openbmc_project/Smbios/README.md
+
+diff --git a/xyz/openbmc_project/Smbios/MDR_V2.errors.yaml b/xyz/openbmc_project/Smbios/MDR_V2.errors.yaml
+new file mode 100644
+index 0000000..88bd6db
+--- /dev/null
++++ b/xyz/openbmc_project/Smbios/MDR_V2.errors.yaml
+@@ -0,0 +1,9 @@
++- name: InvalidParameter
++ description: >
++ An invalid parameter is attempted.
++- name: UpdateInProgress
++ description: >
++ Update is in progress.
++- name: InvalidId
++ description: >
++ An invalid Id is attempted.
+diff --git a/xyz/openbmc_project/Smbios/MDR_V2.interface.yaml b/xyz/openbmc_project/Smbios/MDR_V2.interface.yaml
+new file mode 100644
+index 0000000..f97700a
+--- /dev/null
++++ b/xyz/openbmc_project/Smbios/MDR_V2.interface.yaml
+@@ -0,0 +1,158 @@
++description: >
++ SMBIOS MDR V2 service
++methods:
++ - name: GetDirectoryInformation
++ description: >
++ Get the directory with directory index.
++ parameters:
++ - name: dirIndex
++ type: byte
++ description: >
++ Directory index of SMBIOS.
++ returns:
++ - name: dir
++ type: array[byte]
++ description: >
++ Directory of agent.
++ errors:
++ - self.Error.InvalidParameter
++
++ - name: GetDataInformation
++ description: >
++ Get the data info with id index and data set ID.
++ parameters:
++ - name: idIndex
++ type: byte
++ description: >
++ Index of SMBIOS directory.
++ returns:
++ - name: dataInfo
++ type: array[byte]
++ description: >
++ Data information of SMBIOS.
++ errors:
++ - self.Error.InvalidParameter
++
++ - name: SendDirectoryInformation
++ description: >
++ Send directory information to SMBIOS directory.
++ parameters:
++ - name: dirVersion
++ type: byte
++ description: >
++ A counter which increments each time directory updated.
++ - name: dirIndex
++ type: byte
++ description: >
++ Directory index of SMBIOS.
++ - name: returnedEntries
++ type: byte
++ description: >
++ Indicates number of directory entries.
++ - name: remainingEntries
++ type: byte
++ description: >
++ Remaining entries which are higher than index in this transfer.
++ - name: dirEntry
++ type: array[byte]
++ description: >
++ Data set ID of SMBIOS table.
++ returns:
++ - name: status
++ type: boolean
++ description: >
++ Need to continue directory transmisson or not.
++ errors:
++ - self.Error.InvalidParameter
++
++ - name: GetDataOffer
++ description: >
++ Get data set ID.
++ returns:
++ - name: offer
++ type: array[byte]
++ description: >
++ Data set ID.
++ errors:
++ - self.Error.UpdateInProgress
++
++ - name: SendDataInformation
++ description: >
++ Send data information with directory index.
++ parameters:
++ - name: idIndex
++ type: byte
++ description: >
++ Index of SMBIOS directory.
++ - name: flag
++ type: byte
++ description: >
++ Valid flag to set dir entry status.
++ - name: dataLen
++ type: uint32
++ description: >
++ The length of the data in bytes.
++ - name: dataVer
++ type: uint32
++ description: >
++ The version number of this data.
++ - name: timeStamp
++ type: uint32
++ description: >
++ Timestamp determinded by the agent.
++ returns:
++ - name: status
++ type: boolean
++ description: >
++ Whether data changes.
++ errors:
++ - self.Error.InvalidParameter
++
++ - name: FindIdIndex
++ description: >
++ Find id index by data info.
++ parameters:
++ - name: dataInfo
++ type: array[byte]
++ description: >
++ Data info of data entry.
++ returns:
++ - name: idIndex
++ type: int32
++ description: >
++ Id index of data entry.
++ errors:
++ - self.Error.InvalidId
++
++ - name: AgentSynchronizeData
++ description: >
++ Synchronize SMBIOS data from file.
++ returns:
++ - name: status
++ type: boolean
++ description: >
++ Whether synchronization succeed or not.
++
++ - name: SynchronizeDirectoryCommonData
++ description: >
++ Synchronize directory common data.
++ parameters:
++ - name: idIndex
++ type: byte
++ description: >
++ Index of SMBIOS directory.
++ - name: size
++ type: uint32
++ description: >
++ Size of data that BIOS prepare to transfer.
++ returns:
++ - name: commonData
++ type: array[uint32]
++ description: >
++ Directory common data includes data size, version and timestamp.
++
++properties:
++ - name: DirectoryEntries
++ type: byte
++ description: >
++ Numbers of directory entries.
+diff --git a/xyz/openbmc_project/Smbios/README.md b/xyz/openbmc_project/Smbios/README.md
+new file mode 100644
+index 0000000..415ac52
+--- /dev/null
++++ b/xyz/openbmc_project/Smbios/README.md
+@@ -0,0 +1,22 @@
++# SMBIOS MDR V2
++
++## Overview
++SMBIOS MDR V2 service exposes D-Bus methods for SMBIOS Version 2 operations.
++
++### SMBIOS MDR V2 Interface
++SMBIOS MDR V2 interface `xyz.openbmc_project.Smbios.MDR_V2` provides following
++methods.
++#### methods
++* GetDirectoryInformation - Get the directory with directory index.
++* GetDataInformation - Get the data information with id index and data set ID.
++* SendDirectoryInformation - Send directory information to SMBIOS directory.
++* GetDataOffer - Get data set ID.
++* SendDataInformation - Send data information with directory index.
++* FindIdIndex - Find id index by data info.
++* SynchronizeDirectoryCommonData - Synchronize directory common data before
++SMBIOS data start to transfer.
++* AgentSynchronizeData - Synchronize SMBIOS data from file after data transfer
++complete.
++
++#### properties
++* DirEntries - Numbers of directory entries. Default: 0
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0018-Define-post-code-interfaces-for-post-code-manager.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0018-Define-post-code-interfaces-for-post-code-manager.patch
new file mode 100644
index 000000000..ce23c222b
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0018-Define-post-code-interfaces-for-post-code-manager.patch
@@ -0,0 +1,64 @@
+From f88cac8364d5312e29208018909827d2da4a0f87 Mon Sep 17 00:00:00 2001
+From: Kuiying Wang <kuiying.wang@intel.com>
+Date: Tue, 19 Feb 2019 16:52:51 +0800
+Subject: [PATCH] Define post code interfaces for post code manager
+
+It includes one method and 2 properties.
+properties:
+ - name: CurrentBootCycleIndex
+ description: >
+ It is used to indicate current boot cycle index.
+ - name: MaxBootCycleNum
+ description: >
+ The max cached boot cycles for post code.
+methods:
+ - name: GetPostCodes
+ description: >
+ Method to get the cached post code for each boot cycle.
+TestBy: bitbake build
+
+Signeoff-by: Kuiying Wang <kuiying.wang@intel.com>
+---
+ .../State/Boot/PostCode.interface.yaml | 30 ++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+ create mode 100644 xyz/openbmc_project/State/Boot/PostCode.interface.yaml
+
+diff --git a/xyz/openbmc_project/State/Boot/PostCode.interface.yaml b/xyz/openbmc_project/State/Boot/PostCode.interface.yaml
+new file mode 100644
+index 0000000..711749d
+--- /dev/null
++++ b/xyz/openbmc_project/State/Boot/PostCode.interface.yaml
+@@ -0,0 +1,30 @@
++description: >
++ Monitor Post code coming and buffer all of them based on boot cycle
++ into file system.
++
++properties:
++ - name: CurrentBootCycleIndex
++ type: uint16
++ description: >
++ It is used to indicate current boot cycle index.
++ - name: MaxBootCycleNum
++ type: uint16
++ description: >
++ The max cached boot cycles for post code.
++methods:
++ - name: GetPostCodes
++ description: >
++ Method to get the cached post code for each boot cycle.
++ parameters:
++ - name: Index
++ type: uint16
++ description: >
++ Index indicates which boot cycle of post codes is requested.
++ returns:
++ - name: codes
++ type: array[uint64]
++ description: >
++ An array of post codes of one boot cycle.
++ errors:
++ - xyz.openbmc_project.Common.Error.InternalFailure
++ - xyz.openbmc_project.Common.Error.InvalidArgument
+--
+2.16.2
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0019-Creating-the-Session-interface-for-Host-and-LAN.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0019-Creating-the-Session-interface-for-Host-and-LAN.patch
new file mode 100644
index 000000000..47fab819b
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0019-Creating-the-Session-interface-for-Host-and-LAN.patch
@@ -0,0 +1,116 @@
+From 28fac58dc6ef975e1e9283163d9f1e4c7764c3cc Mon Sep 17 00:00:00 2001
+From: Suryakanth Sekar <suryakanth.sekar@linux.intel.com>
+Date: Sat, 2 Mar 2019 03:31:09 +0530
+Subject: [PATCH] Creating the Session interface- for Host and LAN
+
+Defined all needed session properites to manage the session in
+host and also in LAN
+
+Change-Id: Ic7cccfc3333a602ee07fcd60077ec58fd8f06304
+Signed-off-by: Suryakanth Sekar <suryakanth.sekar@linux.intel.com>
+
+%% original patch: 0019-Creating-the-Session-interface-for-Host-and-LAN.patch
+---
+ xyz/openbmc_project/Ipmi/SESSION_README.md | 25 ++++++++++
+ .../Ipmi/SessionInfo.interface.yaml | 57 ++++++++++++++++++++++
+ 2 files changed, 82 insertions(+)
+ create mode 100644 xyz/openbmc_project/Ipmi/SESSION_README.md
+ create mode 100644 xyz/openbmc_project/Ipmi/SessionInfo.interface.yaml
+
+diff --git a/xyz/openbmc_project/Ipmi/SESSION_README.md b/xyz/openbmc_project/Ipmi/SESSION_README.md
+new file mode 100644
+index 0000000..c59b251
+--- /dev/null
++++ b/xyz/openbmc_project/Ipmi/SESSION_README.md
+@@ -0,0 +1,25 @@
++# Session Management
++
++## Overview
++IPMI RMCP+ sessions are created and maintained by phosphor-ipmi-net daemon,
++whereas we need to provide details about the same using phosphor-ipmi-host.
++Hence IPMI RMCP+ session details has to be exposed through D-Bus interface,
++so that both phosphor-ipmi-host & phosphr-ipmi-net will be in sync.
++
++
++#### xyz.openbmc_project.Ipmi.SessionInfo interface
++##### properties
++* SessionHandle - SessionHandle,unique one-byte number to locate the session.
++* Channel - Session created channel.
++* SessionPrivilege - Privilege of the session.
++* RemoteIPAddr – Remote IP address.
++* RemotePort - Remote port address.
++* RemoteMACAddress -Remote MAC Address.
++* UserID - Session created by given user id.
++
++
++
++#### xyz.openbmc_project.Object.Delete
++#### methods
++* Delete - To delete the session object in the system.
++
+diff --git a/xyz/openbmc_project/Ipmi/SessionInfo.interface.yaml b/xyz/openbmc_project/Ipmi/SessionInfo.interface.yaml
+new file mode 100644
+index 0000000..d461628
+--- /dev/null
++++ b/xyz/openbmc_project/Ipmi/SessionInfo.interface.yaml
+@@ -0,0 +1,57 @@
++description: >
++ Provides properties for IPMI RMCP+ session objects.
++ Provides RMCP+ session information as session objects
++ with Session ID (unique identifier) as path suffix.
++
++properties:
++ - name: SessionHandle
++ type: byte
++ description: >
++ Session Handle,unique number to locate the session.
++ errors:
++ - xyz.openbmc_project.Common.Error.InternalFailure
++ - name: ChannelNum
++ type: byte
++ description: >
++ channelnumber which session is created.
++ errors:
++ - xyz.openbmc_project.Common.Error.InternalFailure
++ - name: CurrentPrivilege
++ type: byte
++ description: >
++ Privilege of the session.
++ errors:
++ - xyz.openbmc_project.Common.Error.InternalFailure
++ - name: RemoteIPAddr
++ type: uint32
++ description: >
++ Remote IP address.
++ errors:
++ - xyz.openbmc_project.Common.Error.InternalFailure
++ - name: RemotePort
++ type: uint16
++ description: >
++ Remote IP Port.
++ errors:
++ - xyz.openbmc_project.Common.Error.InternalFailure
++ - name: RemoteMACAddress
++ type: array[byte]
++ description: >
++ Remote MAC address.
++ errors:
++ - xyz.openbmc_project.Common.Error.InternalFailure
++ - name: UserID
++ type: byte
++ description: >
++ Session created by given user ID.
++ errors:
++ - xyz.openbmc_project.Common.Error.InternalFailure
++ - name: State
++ type: byte
++ default: 0
++ description: >
++ Session state.
++ errors:
++ - xyz.openbmc_project.Common.Error.InternalFailure
++
++# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0020-Create-dbus-interface-for-SOL-commands.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0020-Create-dbus-interface-for-SOL-commands.patch
new file mode 100644
index 000000000..68d2c92b7
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0020-Create-dbus-interface-for-SOL-commands.patch
@@ -0,0 +1,76 @@
+From 2820ca36ab21c52341cdbde477756f960eaeb68b Mon Sep 17 00:00:00 2001
+From: Cheng C Yang <cheng.c.yang@intel.com>
+Date: Wed, 13 Mar 2019 11:19:07 +0800
+Subject: [PATCH] Create dbus interface for SOL commands
+
+Create dbus properties for Set/Get SOL config parameter command.
+Some platforms need to call Set/Get SOL config parameter command
+through KCS, and since sol manager in net-ipmid cannot be accessed
+by commands in host-ipmid, need to create a dbus interface in
+phospher-settings to transfer properties from host-ipmid to
+net-ipmid.
+
+TestedBy:
+With the related code change in net-ipmid, busctl introspect
+xyz.openbmc_project.Ipmi.SOL /xyz/openbmc_project/SOL
+can show all the properties needed.
+
+Signed-off-by: Cheng C Yang <cheng.c.yang@intel.com>
+---
+ xyz/openbmc_project/Ipmi/SOL.interface.yaml | 44 ++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+ create mode 100644 xyz/openbmc_project/Ipmi/SOL.interface.yaml
+
+diff --git a/xyz/openbmc_project/Ipmi/SOL.interface.yaml b/xyz/openbmc_project/Ipmi/SOL.interface.yaml
+new file mode 100644
+index 0000000..94db59f
+--- /dev/null
++++ b/xyz/openbmc_project/Ipmi/SOL.interface.yaml
+@@ -0,0 +1,44 @@
++description: >
++ SOL properties use for Get/Set SOL config parameter command in host-ipmid
++ sending config to SOL process in net-ipmid.
++ Since some platforms need to access Get/Set SOL config parameter command
++ through KCS, and current sol manager is implemented in net-ipmid and
++ cannot be accessed by host-ipmid, add a dbus interface for host-ipmid
++ command to transfer properties to net-ipmid.
++ This interface will be implemented in phosphor-settings.
++properties:
++ - name: Progress
++ type: byte
++ description: >
++ Set In Progress property, indicate when any parameters are being
++ updated.
++ - name: Enable
++ type: boolean
++ description: >
++ SOL Enable property, this controls whether the SOL payload type
++ can be activated.
++ - name: Authentication
++ type: byte
++ description: >
++ If SOL enable Force Payload Encryption and Authenticaton.
++ And the minimun operating privilege level SOL required.
++ - name: AccumulateIntervalMS
++ type: byte
++ description: >
++ Character Accumulate Interval in 5ms increments.
++ BMC will wait this time before transmitting a packet.
++ - name: Threshold
++ type: byte
++ description: >
++ BMC will automatically send an SOL character data packet containing
++ this number of characters as soon as this number of characters
++ (or greater) has been accepted from the baseboard serial controller.
++ - name: RetryCount
++ type: byte
++ description: >
++ Packet will be dropped if no ACK/NACK received by time retries
++ expire.
++ - name: RetryIntervalMS
++ type: byte
++ description: >
++ Retry Interval in 10ms increments.
+--
+2.16.2
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0021-Add-interface-suppot-for-provisioning-modes.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0021-Add-interface-suppot-for-provisioning-modes.patch
new file mode 100644
index 000000000..f6e200cab
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0021-Add-interface-suppot-for-provisioning-modes.patch
@@ -0,0 +1,52 @@
+From 94fb1ac5dd4d54ea5a6d49597e1f15c384be7fd6 Mon Sep 17 00:00:00 2001
+From: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
+Date: Mon, 8 Apr 2019 11:48:22 +0530
+Subject: [PATCH] Add interface suppot for provisioning modes
+
+Support for provisioning modes are added in
+RestrictionMode.interface.yaml
+
+Tested:
+1. Verified build, and verified specified modes are available
+and able to set / get the same using busctl command
+
+Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
+---
+ .../Security/RestrictionMode.interface.yaml | 24 ++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/xyz/openbmc_project/Control/Security/RestrictionMode.interface.yaml b/xyz/openbmc_project/Control/Security/RestrictionMode.interface.yaml
+index 8e4fd8d..d328dac 100644
+--- a/xyz/openbmc_project/Control/Security/RestrictionMode.interface.yaml
++++ b/xyz/openbmc_project/Control/Security/RestrictionMode.interface.yaml
+@@ -21,3 +21,27 @@ enumerations:
+ - name: Blacklist
+ description: >
+ Prevent, if in the blacklist.
++ - name: Provisioning
++ description: >
++ Indicate that system is in provisioning mode
++ and all commands are allowed in KCS inteface
++ in both pre and post BIOS boot.
++ - name: ProvisionedKCSWhiteList
++ description: >
++ Commands in the whitelist will only be executed
++ through KCS interface after BIOS POST complete.
++ All KCS commands are supported before POST complete.
++ - name: ProvisionedKCSDisabled
++ description: >
++ Commands through KCS interface are executed only
++ till BIOS POST complete notification, after
++ which no KCS commands will be executed(other
++ than BIOS SMI based ones).
++ - name: ValidationUnsecure
++ description: >
++ To indicate that BMC is in unsecure mode, and many
++ operations which are not meant for end-user will be
++ allowed in this mode. Interface which sets this
++ property has to make sure due diligence is made
++ as in this mode, many security intrinsic commands
++ can be executed.
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0022-Add-chassis-power-cycle-and-reset-to-Chassis-State.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0022-Add-chassis-power-cycle-and-reset-to-Chassis-State.patch
new file mode 100644
index 000000000..181d12428
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0022-Add-chassis-power-cycle-and-reset-to-Chassis-State.patch
@@ -0,0 +1,40 @@
+From b55c6847b18fdee5a72d601b871d73085481e4d9 Mon Sep 17 00:00:00 2001
+From: "Jason M. Bills" <jason.m.bills@linux.intel.com>
+Date: Mon, 3 Jun 2019 16:31:29 -0700
+Subject: [PATCH] Add chassis power-cycle and reset to Chassis State
+
+This adds chassis PowerCycle and Reset as possible Transition
+values for the Chassis State. These are to support chassis
+power cycle and a chassis reset button, respectively.
+
+Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
+---
+ xyz/openbmc_project/State/Chassis.interface.yaml | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/xyz/openbmc_project/State/Chassis.interface.yaml b/xyz/openbmc_project/State/Chassis.interface.yaml
+index 4ae6274..470a3a2 100644
+--- a/xyz/openbmc_project/State/Chassis.interface.yaml
++++ b/xyz/openbmc_project/State/Chassis.interface.yaml
+@@ -31,10 +31,17 @@ enumerations:
+ values:
+ - name: 'Off'
+ description: >
+- Chassis power should be off
++ Chassis power should be off
+ - name: 'On'
+ description: >
+ Chassis power should be on
++ - name: 'PowerCycle'
++ description: >
++ Chassis power should be cycled
++ - name: 'Reset'
++ description: >
++ Chassis should be reset
++
+
+ - name: PowerState
+ description: >
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0023-Add-host-interrupt-to-the-Host-State.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0023-Add-host-interrupt-to-the-Host-State.patch
new file mode 100644
index 000000000..650fd3bc9
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0023-Add-host-interrupt-to-the-Host-State.patch
@@ -0,0 +1,31 @@
+From 9c94439a5a55efbb72bee10e9cfa0827dbedf511 Mon Sep 17 00:00:00 2001
+From: "Jason M. Bills" <jason.m.bills@linux.intel.com>
+Date: Mon, 3 Jun 2019 16:35:46 -0700
+Subject: [PATCH] Add host interrupt to the Host State
+
+This adds host Interrupt as possible Transition value for the
+Host State. This is to support an interrupt signal to the host
+firmware or software.
+
+Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
+---
+ xyz/openbmc_project/State/Host.interface.yaml | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/xyz/openbmc_project/State/Host.interface.yaml b/xyz/openbmc_project/State/Host.interface.yaml
+index 1ceba13..3d71280 100644
+--- a/xyz/openbmc_project/State/Host.interface.yaml
++++ b/xyz/openbmc_project/State/Host.interface.yaml
+@@ -28,6 +28,9 @@ enumerations:
+ description: >
+ The desired transition for host firmware
+ values:
++ - name: 'Interrupt'
++ description: >
++ Host firmware should be interrupted
+ - name: 'Off'
+ description: >
+ Host firmware should be off
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch
new file mode 100644
index 000000000..67fa59090
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch
@@ -0,0 +1,57 @@
+From 6e9a19c43acac7d4254910906329d98d7b59085a Mon Sep 17 00:00:00 2001
+From: Ren Yu <yux.ren@intel.com>
+Date: Fri, 24 May 2019 14:55:10 +0800
+Subject: [PATCH] Add the pre-timeout interrupt defined in IPMI spec
+
+The IPMI watchdog pre-timeout interrupt is used to set the different
+pre-timeout interrupt source. Add them as a dbus property,
+IPMI set/get watchdog commands will use it.
+
+Signed-off-by: Ren Yu <yux.ren@intel.com>
+---
+ xyz/openbmc_project/State/Watchdog.interface.yaml | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/xyz/openbmc_project/State/Watchdog.interface.yaml b/xyz/openbmc_project/State/Watchdog.interface.yaml
+index 2fc47d8..6dfa9b9 100644
+--- a/xyz/openbmc_project/State/Watchdog.interface.yaml
++++ b/xyz/openbmc_project/State/Watchdog.interface.yaml
+@@ -33,6 +33,11 @@ properties:
+ description: >
+ The action the watchdog should perform when it expires.
+ default: 'HardReset'
++ - name: PreTimeoutInterrupt
++ type: enum[self.PreTimeoutInterruptAction]
++ description: >
++ The BMC generates the selected interrupt before the timer expires.
++ default: 'None'
+ - name: Interval
+ type: uint64
+ description: >
+@@ -73,6 +78,23 @@ enumerations:
+ description: >
+ Perform a power cycle of the system.
+
++ - name: PreTimeoutInterruptAction
++ description: >
++ The type of PreTimeout Interrupt.
++ values:
++ - name: 'None'
++ description: >
++ Do nothing.
++ - name: 'SMI'
++ description: >
++ SMI.
++ - name: 'NMI'
++ description: >
++ NMI / Diagnostic Interrupt.
++ - name: 'MI'
++ description: >
++ Messaging Interrupt.
++
+ - name: TimerUse
+ description: >
+ The type of timer use.
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend
new file mode 100644
index 000000000..89b8da753
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend
@@ -0,0 +1,22 @@
+SRC_URI = "git://github.com/openbmc/phosphor-dbus-interfaces.git"
+SRCREV = "1f0e2ce6e1cb78a59a0015b160816b71156b03c6"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI += "file://0002-Modify-Dbus-for-IPv6.patch \
+ file://0003-Chassis-Power-Control-are-implemented.patch \
+ file://0005-Add-DBUS-interface-of-CPU-and-Memory-s-properties.patch \
+ file://0007-ipmi-set-BIOS-id.patch \
+ file://0009-Add-host-restart-cause-property.patch \
+ file://0010-Increase-the-default-watchdog-timeout-value.patch \
+ file://0012-Add-RestoreDelay-interface-for-power-restore-delay.patch \
+ file://0013-Add-ErrConfig.yaml-interface-for-processor-error-config.patch \
+ file://0014-Add-multiple-state-signal-for-host-start-and-stop.patch \
+ file://0016-Add-DBUS-interface-of-SMBIOS-MDR-V2.patch \
+ file://0018-Define-post-code-interfaces-for-post-code-manager.patch \
+ file://0019-Creating-the-Session-interface-for-Host-and-LAN.patch \
+ file://0021-Add-interface-suppot-for-provisioning-modes.patch \
+ file://0022-Add-chassis-power-cycle-and-reset-to-Chassis-State.patch \
+ file://0023-Add-host-interrupt-to-the-Host-State.patch \
+ file://0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch \
+ "
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper/xyz.openbmc_project.ObjectMapper.service b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper/xyz.openbmc_project.ObjectMapper.service
new file mode 100644
index 000000000..9af9af254
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper/xyz.openbmc_project.ObjectMapper.service
@@ -0,0 +1,20 @@
+[Unit]
+Description=Phosphor DBus Service Discovery Manager
+Before=obmc-mapper.target
+After=dbus.socket
+
+[Service]
+Restart=always
+Type=dbus
+ExecStart=/usr/bin/env mapperx \
+ --service-namespaces="xyz. com. org." \
+ --interface-namespaces="org. com. xyz." \
+ --service-blacklists="org.freedesktop.systemd1"
+SyslogIdentifier=phosphor-mapper
+BusName={BUSNAME}
+TimeoutStartSec=300
+RestartSec=5
+EnvironmentFile={envfiledir}/obmc/mapper
+
+[Install]
+WantedBy={SYSTEMD_DEFAULT_TARGET}
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper_%.bbappend
new file mode 100644
index 000000000..72d991c7e
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper_%.bbappend
@@ -0,0 +1 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control/phosphor-pid-control.service b/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control/phosphor-pid-control.service
new file mode 100644
index 000000000..e8baaa23e
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control/phosphor-pid-control.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Phosphor-Pid-Control Margin-based Fan Control Daemon
+After=xyz.openbmc_project.EntityManager
+After=xyz.openbmc_project.ObjectMapper
+
+[Service]
+Restart=always
+ExecStart={bindir}/swampd
+RestartSec=5
+StartLimitInterval=0
+Type=simple
+
+[Install]
+WantedBy=basic.target
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control_%.bbappend
new file mode 100644
index 000000000..e1ec04ff6
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control_%.bbappend
@@ -0,0 +1,10 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+inherit obmc-phosphor-systemd
+SYSTEMD_SERVICE_${PN} = "phosphor-pid-control.service"
+EXTRA_OECONF = "--enable-configure-dbus=yes"
+
+SRC_URI = "git://github.com/openbmc/phosphor-pid-control.git"
+SRCREV = "1dad21b935b8359806de9a9cc3aa7b7463cc8df3"
+
+FILES_${PN} = "${bindir}/swampd ${bindir}/setsensor"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0002-Redfish-firmware-activation.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0002-Redfish-firmware-activation.patch
new file mode 100644
index 000000000..2a4c7e9b6
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0002-Redfish-firmware-activation.patch
@@ -0,0 +1,44 @@
+From b6b3051c8078267153712ed8cf514373924fd07a Mon Sep 17 00:00:00 2001
+From: Jennifer Lee <jennifer1.lee@intel.com>
+Date: Mon, 16 Jul 2018 19:15:04 -0700
+Subject: [PATCH 2/6] Redfish firmware activation -- Modified flash.cpp to
+ call to customized flash service
+
+Signed-off-by: Jennifer Lee <jennifer1.lee@intel.com>
+Change-Id: I81c3185e9c4c2ee907feeb53620faa22723c04d4
+---
+ ubi/flash.cpp | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/ubi/flash.cpp b/ubi/flash.cpp
+index ffa9348..5af2a17 100644
+--- a/ubi/flash.cpp
++++ b/ubi/flash.cpp
+@@ -15,10 +15,13 @@ void Activation::flashWrite()
+ {
+ auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+ SYSTEMD_INTERFACE, "StartUnit");
+- method.append("obmc-flash-bmc-ubirw.service", "replace");
++ std::string rwServiceFile =
++ "obmc-flash-bmc-ubirw@" + versionId + ".service";
++ method.append(rwServiceFile, "replace");
+ bus.call_noreply(method);
+
+- auto roServiceFile = "obmc-flash-bmc-ubiro@" + versionId + ".service";
++ std::string roServiceFile =
++ "obmc-flash-bmc-ubiro@" + versionId + ".service";
+ method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+ SYSTEMD_INTERFACE, "StartUnit");
+ method.append(roServiceFile, "replace");
+@@ -37,7 +40,7 @@ void Activation::onStateChanges(sdbusplus::message::message& msg)
+ // Read the msg and populate each variable
+ msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
+
+- auto rwServiceFile = "obmc-flash-bmc-ubirw.service";
++ auto rwServiceFile = "obmc-flash-bmc-ubirw@" + versionId + ".service";
+ auto roServiceFile = "obmc-flash-bmc-ubiro@" + versionId + ".service";
+ auto ubootVarsServiceFile =
+ "obmc-flash-bmc-updateubootvars@" + versionId + ".service";
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0004-Changed-the-condition-of-software-version-service-wa.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0004-Changed-the-condition-of-software-version-service-wa.patch
new file mode 100644
index 000000000..3fc3907ba
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0004-Changed-the-condition-of-software-version-service-wa.patch
@@ -0,0 +1,41 @@
+From 1b00440d0c8fabfa2e3eda984a21c0f004ca2150 Mon Sep 17 00:00:00 2001
+From: Jennifer Lee <jennifer1.lee@intel.com>
+Date: Fri, 26 Oct 2018 11:54:05 -0700
+Subject: [PATCH 4/6] Changed the condition of software version service
+ watching deamon
+
+ Originally it watches only files that are "written" into /tmp/images directory.
+This change modified the condition to also watch files that are "moved" into this directory.
+
+Signed-off-by: Jennifer Lee <jennifer1.lee@intel.com>
+Change-Id: I3e9cf1ffc3f5350d4649d32d3d3837991322a65b
+---
+ watch.cpp | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/watch.cpp b/watch.cpp
+index e46b8aa..eee1bc3 100644
+--- a/watch.cpp
++++ b/watch.cpp
+@@ -45,7 +45,7 @@ Watch::Watch(sd_event* loop, std::function<int(std::string&)> imageCallback) :
+ std::strerror(error));
+ }
+
+- wd = inotify_add_watch(fd, IMG_UPLOAD_DIR, IN_CLOSE_WRITE);
++ wd = inotify_add_watch(fd, IMG_UPLOAD_DIR, IN_CLOSE_WRITE | IN_MOVED_TO);
+ if (-1 == wd)
+ {
+ auto error = errno;
+@@ -96,7 +96,8 @@ int Watch::callback(sd_event_source* s, int fd, uint32_t revents,
+ while (offset < bytes)
+ {
+ auto event = reinterpret_cast<inotify_event*>(&buffer[offset]);
+- if ((event->mask & IN_CLOSE_WRITE) && !(event->mask & IN_ISDIR))
++ if ((event->mask & (IN_CLOSE_WRITE | IN_MOVED_TO)) &&
++ !(event->mask & IN_ISDIR))
+ {
+ auto tarballPath = std::string{IMG_UPLOAD_DIR} + '/' + event->name;
+ auto rc = static_cast<Watch*>(userdata)->imageCallback(tarballPath);
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0005-Modified-firmware-activation-to-launch-fwupd.sh-thro.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0005-Modified-firmware-activation-to-launch-fwupd.sh-thro.patch
new file mode 100644
index 000000000..aa5d900e0
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0005-Modified-firmware-activation-to-launch-fwupd.sh-thro.patch
@@ -0,0 +1,188 @@
+From 7f29c255dd2af7fa6d38b02ad63a8b8940fbce84 Mon Sep 17 00:00:00 2001
+From: Jennifer Lee <jennifer1.lee@intel.com>
+Date: Mon, 10 Dec 2018 10:36:44 -0800
+Subject: [PATCH 5/6] Modified firmware activation to launch fwupd.sh through
+ non-ubi fs code path to match more closely to the upstream design -
+ Added option FWUPD_SCRIPT to saperate intel customized code - Adopted
+ ActivationProgress from ubi fs activation code mainly for progress indicator
+ for ipmi update
+
+Signed-off-by: Jennifer Lee <jennifer1.lee@intel.com>
+Change-Id: Id805deea75b21fab86f6bb6edbf50ddb3be42564
+---
+ activation.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ configure.ac | 7 +++++++
+ static/flash.cpp | 41 +++++++++++++++++++++++++++++++++++++++--
+ ubi/flash.cpp | 9 +++------
+ 4 files changed, 93 insertions(+), 8 deletions(-)
+
+diff --git a/activation.cpp b/activation.cpp
+index f918221..f2923ae 100644
+--- a/activation.cpp
++++ b/activation.cpp
+@@ -163,6 +163,50 @@ auto Activation::activation(Activations value) -> Activations
+ softwareServer::Activation::Activations::Active);
+ }
+ }
++#elif defined(FWUPD_SCRIPT)
++ if (!activationProgress)
++ {
++ // Enable systemd signals
++ Activation::subscribeToSystemdSignals();
++ parent.freeSpace(*this);
++
++ activationProgress =
++ std::make_unique<ActivationProgress>(bus, path);
++
++#ifdef WANT_SIGNATURE_VERIFY
++ fs::path uploadDir(IMG_UPLOAD_DIR);
++ if (!verifySignature(uploadDir / versionId, SIGNED_IMAGE_CONF_PATH))
++ {
++ onVerifyFailed();
++ // Stop the activation process, if fieldMode is enabled.
++ if (parent.control::FieldMode::fieldModeEnabled())
++ {
++ return softwareServer::Activation::activation(
++ softwareServer::Activation::Activations::Failed);
++ }
++ }
++#endif
++ flashWrite();
++ activationProgress->progress(10);
++ }
++ else if (activationProgress->progress() == 100)
++ {
++ log<level::ERR>("[Jennifer] progress == 100...");
++ if (!redundancyPriority)
++ {
++ redundancyPriority =
++ std::make_unique<RedundancyPriority>(bus, path, *this, 0);
++ }
++
++ // Remove version object from image manager
++ Activation::deleteImageManagerObject();
++
++ // Create active association
++ parent.createActiveAssociation(path);
++
++ return softwareServer::Activation::activation(
++ softwareServer::Activation::Activations::Active);
++ }
+ #else // !UBIFS_LAYOUT
+
+ #ifdef WANT_SIGNATURE_VERIFY
+diff --git a/configure.ac b/configure.ac
+index 2da97ad..720e704 100755
+--- a/configure.ac
++++ b/configure.ac
+@@ -184,6 +184,13 @@ AS_IF([test "x$enable_ubifs_layout" == "xyes"], \
+ [AC_DEFINE([UBIFS_LAYOUT],[],[Enable ubifs support.])])
+ AM_CONDITIONAL([UBIFS_LAYOUT], [test "x$enable_ubifs_layout" == "xyes"])
+
++# setup fwupd script support
++AC_ARG_ENABLE([fwupd_script],
++ AS_HELP_STRING([--enable-fwupd_script], [Enable fwupd script support.]))
++AS_IF([test "x$enable_fwupd_script" == "xyes"], \
++ [AC_DEFINE([FWUPD_SCRIPT],[],[Enable fwupd script support.])])
++AM_CONDITIONAL([FWUPD_SCRIPT], [test "x$enable_fwupd_script" == "xyes"])
++
+ # Check for header files.
+ AC_CHECK_HEADER(systemd/sd-bus.h, ,[AC_MSG_ERROR([Could not find systemd/sd-bus.h...systemd development package required])])
+ AC_CHECK_HEADER(sdbusplus/server.hpp, ,[AC_MSG_ERROR([Could not find sdbusplus/server.hpp...openbmc/sdbusplus package required])])
+diff --git a/static/flash.cpp b/static/flash.cpp
+index 82c2393..1bf29d5 100644
+--- a/static/flash.cpp
++++ b/static/flash.cpp
+@@ -20,9 +20,11 @@ namespace updater
+ {
+
+ namespace fs = std::experimental::filesystem;
++namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server;
+
+ void Activation::flashWrite()
+ {
++#ifndef FWUPD_SCRIPT
+ // For static layout code update, just put images in /run/initramfs.
+ // It expects user to trigger a reboot and an updater script will program
+ // the image to flash during reboot.
+@@ -33,11 +35,46 @@ void Activation::flashWrite()
+ fs::copy_file(uploadDir / versionId / bmcImage, toPath / bmcImage,
+ fs::copy_options::overwrite_existing);
+ }
++
++#else
++ auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
++ SYSTEMD_INTERFACE, "StartUnit");
++ method.append("fwupd@" + versionId + ".service", "replace");
++ bus.call_noreply(method);
++#endif
+ }
+
+-void Activation::onStateChanges(sdbusplus::message::message& /*msg*/)
++void Activation::onStateChanges(sdbusplus::message::message& msg)
+ {
+- // Empty
++#ifndef FWUPD_SCRIPT
++ uint32_t newStateID{};
++ sdbusplus::message::object_path newStateObjPath;
++ std::string newStateUnit{};
++ std::string newStateResult{};
++
++ msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
++
++ auto rwServiceFile = "fwupdw@" + versionId + ".service";
++
++ if (newStateUnit == rwServiceFile && newStateResult == "done")
++ {
++ activationProgress->progress(100);
++ }
++
++ if (newStateUnit == rwServiceFile)
++ {
++ if (newStateResult == "failed" || newStateResult == "dependency")
++ {
++ Activation::activation(
++ softwareServer::Activation::Activations::Failed);
++ }
++ else
++ {
++ Activation::activation(
++ softwareServer::Activation::Activations::Activating);
++ }
++ }
++#endif
+ }
+
+ } // namespace updater
+diff --git a/ubi/flash.cpp b/ubi/flash.cpp
+index 5af2a17..ffa9348 100644
+--- a/ubi/flash.cpp
++++ b/ubi/flash.cpp
+@@ -15,13 +15,10 @@ void Activation::flashWrite()
+ {
+ auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+ SYSTEMD_INTERFACE, "StartUnit");
+- std::string rwServiceFile =
+- "obmc-flash-bmc-ubirw@" + versionId + ".service";
+- method.append(rwServiceFile, "replace");
++ method.append("obmc-flash-bmc-ubirw.service", "replace");
+ bus.call_noreply(method);
+
+- std::string roServiceFile =
+- "obmc-flash-bmc-ubiro@" + versionId + ".service";
++ auto roServiceFile = "obmc-flash-bmc-ubiro@" + versionId + ".service";
+ method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+ SYSTEMD_INTERFACE, "StartUnit");
+ method.append(roServiceFile, "replace");
+@@ -40,7 +37,7 @@ void Activation::onStateChanges(sdbusplus::message::message& msg)
+ // Read the msg and populate each variable
+ msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
+
+- auto rwServiceFile = "obmc-flash-bmc-ubirw@" + versionId + ".service";
++ auto rwServiceFile = "obmc-flash-bmc-ubirw.service";
+ auto roServiceFile = "obmc-flash-bmc-ubiro@" + versionId + ".service";
+ auto ubootVarsServiceFile =
+ "obmc-flash-bmc-updateubootvars@" + versionId + ".service";
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0006-Modify-the-ID-of-software-image-updater-object-on-DB.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0006-Modify-the-ID-of-software-image-updater-object-on-DB.patch
new file mode 100644
index 000000000..2d2ac2673
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0006-Modify-the-ID-of-software-image-updater-object-on-DB.patch
@@ -0,0 +1,44 @@
+From 9b3c44e9fb3d907c0152f14b967e23ab964c0e0b Mon Sep 17 00:00:00 2001
+From: Jennifer Lee <jennifer1.lee@intel.com>
+Date: Thu, 14 Feb 2019 14:54:45 -0800
+Subject: [PATCH 6/6] Modify the ID of software image updater object on DBus to
+ allow force update onto same version image
+
+In the original design of image update, it does not allow the same version of image to be flashed onto itself.
+But this blocks validation tests and in most of the cases we don't prevent user from doing such update.
+
+This patch appends a random number after the version ID hash string to unblock such limitation.
+
+Signed-off-by: Jennifer Lee <jennifer1.lee@intel.com>
+Change-Id: I16aba4804ae1bc2e8784320f91c0419fb8b23c35
+---
+ image_manager.cpp | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/image_manager.cpp b/image_manager.cpp
+index 5b2ff49..e3d26e3 100644
+--- a/image_manager.cpp
++++ b/image_manager.cpp
+@@ -9,6 +9,7 @@
+ #include <stdlib.h>
+ #include <sys/stat.h>
+ #include <sys/wait.h>
++#include <time.h>
+ #include <unistd.h>
+
+ #include <algorithm>
+@@ -129,6 +130,11 @@ int Manager::processImage(const std::string& tarFilePath)
+ // Compute id
+ auto id = Version::getId(version);
+
++ // Append a random number after the original version hash
++ // This will allow forcing image update onto the same version
++ srand(time(NULL));
++ id = id + "_" + std::to_string(rand());
++
+ fs::path imageDirPath = std::string{IMG_UPLOAD_DIR};
+ imageDirPath /= id;
+
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/fwupd@.service b/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/fwupd@.service
new file mode 100644
index 000000000..d51fee312
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/fwupd@.service
@@ -0,0 +1,8 @@
+[Unit]
+Description=Flash BMC with fwupd script : %I
+
+[Service]
+Type=oneshot
+RemainAfterExit=no
+ExecStart=/usr/bin/fwupd.sh file:////tmp/images/%i/image-runtime
+SyslogIdentifier=fwupd \ No newline at end of file
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager_%.bbappend
new file mode 100644
index 000000000..719c2562a
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager_%.bbappend
@@ -0,0 +1,13 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+EXTRA_OECONF += "--enable-fwupd_script"
+
+SYSTEMD_SERVICE_${PN}-updater += "fwupd@.service"
+
+#Currently enforcing image signature validation only for PFR images
+PACKAGECONFIG_append = "${@bb.utils.contains('IMAGE_TYPE', 'pfr', ' verify_signature', '', d)}"
+
+SRC_URI += "file://0002-Redfish-firmware-activation.patch \
+ file://0004-Changed-the-condition-of-software-version-service-wa.patch \
+ file://0005-Modified-firmware-activation-to-launch-fwupd.sh-thro.patch \
+ file://0006-Modify-the-ID-of-software-image-updater-object-on-DB.patch \
+ "
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/gpiodaemon/gpiodaemon.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/gpiodaemon/gpiodaemon.bb
new file mode 100644
index 000000000..cef2fdcaa
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/gpiodaemon/gpiodaemon.bb
@@ -0,0 +1,18 @@
+SUMMARY = "Gpio daemon service for handling gpio operations"
+DESCRIPTION = "Daemon allows to block gpio access under certain conditions"
+
+PV = "1.0+git${SRCPV}"
+
+S = "${WORKDIR}/git/gpiodaemon"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e"
+
+SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh"
+
+SRCREV = "4373d99e1edcbb4c7233abde3a5e53690693007b"
+
+inherit cmake systemd
+SYSTEMD_SERVICE_${PN} = "gpiodaemon.service"
+
+DEPENDS = "boost systemd sdbusplus phosphor-logging"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/host/obmc-op-control-host%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/host/obmc-op-control-host%.bbappend
new file mode 100644
index 000000000..5326680f6
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/host/obmc-op-control-host%.bbappend
@@ -0,0 +1,6 @@
+SYSTEMD_LINK_${PN}_remove += "../op-start-host@.service:obmc-host-startmin@0.target.requires/op-start-host@0.service"
+SYSTEMD_LINK_${PN}_remove += "../op-init-pnor@.service:obmc-host-startmin@0.target.requires/op-init-pnor@0.service"
+
+FILES_${PN}_remove = "${systemd_unitdir}/system/obmc-host-startmin@0.target.requires"
+FILES_${PN}_remove = "${systemd_unitdir}/system/obmc-host-startmin@0.target.requires/op-start-host@0.service"
+FILES_${PN}_remove = "${systemd_unitdir}/system/obmc-host-startmin@0.target.requires/op-init-pnor@0.service" \ No newline at end of file
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/bmcweb.socket b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/bmcweb.socket
new file mode 100644
index 000000000..8782e4dd3
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/bmcweb.socket
@@ -0,0 +1,9 @@
+[Unit]
+Description=BMC Webserver socket
+
+[Socket]
+ListenStream=443
+ReusePort=true
+
+[Install]
+WantedBy=sockets.target
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend
new file mode 100644
index 000000000..3f870103b
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend
@@ -0,0 +1,17 @@
+SRC_URI = "git://github.com/openbmc/bmcweb.git"
+SRCREV = "fa1a5a38551bd1b9f04ad2d4f9fea2e5ade5cc4c"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+# add a user called bmcweb for the server to assume
+# bmcweb is part of group shadow for non-root pam authentication
+USERADD_PARAM_${PN} = "-r -s /usr/sbin/nologin -d /home/bmcweb -m -G shadow bmcweb"
+
+GROUPADD_PARAM_${PN} = "web; redfish "
+
+# Enable CPU Log and Raw PECI support
+EXTRA_OECMAKE += "-DBMCWEB_ENABLE_REDFISH_CPU_LOG=ON"
+EXTRA_OECMAKE += "-DBMCWEB_ENABLE_REDFISH_RAW_PECI=ON"
+
+# Enable Redfish BMC Journal support
+EXTRA_OECMAKE += "-DBMCWEB_ENABLE_REDFISH_BMC_JOURNAL=ON"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config.bbappend
new file mode 100644
index 000000000..616fb9a75
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config.bbappend
@@ -0,0 +1,21 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+SRC_URI += " file://dev_id.json \
+ file://channel_access.json \
+ file://channel_config.json \
+ file://master_write_read_white_list.json \
+ "
+
+FILES_${PN} += " \
+ ${datadir}/ipmi-providers/channel_access.json \
+ ${datadir}/ipmi-providers/channel_config.json \
+ ${datadir}/ipmi-providers/master_write_read_white_list.json \
+ "
+
+do_install_append() {
+ install -m 0644 -D ${WORKDIR}/channel_access.json \
+ ${D}${datadir}/ipmi-providers/channel_access.json
+ install -m 0644 -D ${WORKDIR}/channel_config.json \
+ ${D}${datadir}/ipmi-providers/channel_config.json
+ install -m 0644 -D ${WORKDIR}/master_write_read_white_list.json \
+ ${D}${datadir}/ipmi-providers/master_write_read_white_list.json
+}
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/channel_access.json b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/channel_access.json
new file mode 100644
index 000000000..299483121
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/channel_access.json
@@ -0,0 +1,23 @@
+{
+ "1" : {
+ "access_mode" : "always_available",
+ "user_auth_disabled" : false,
+ "per_msg_auth_disabled" : false,
+ "alerting_disabled" : false,
+ "priv_limit" : "priv-admin"
+ },
+ "2" : {
+ "access_mode" : "always_available",
+ "user_auth_disabled" : false,
+ "per_msg_auth_disabled" : false,
+ "alerting_disabled" : false,
+ "priv_limit" : "priv-admin"
+ },
+ "3" : {
+ "access_mode" : "always_available",
+ "user_auth_disabled" : false,
+ "per_msg_auth_disabled" : false,
+ "alerting_disabled" : false,
+ "priv_limit" : "priv-admin"
+ }
+}
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/channel_config.json b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/channel_config.json
new file mode 100644
index 000000000..c2f3c9a0e
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/channel_config.json
@@ -0,0 +1,178 @@
+{
+ "0" : {
+ "name" : "IPMB",
+ "is_valid" : true,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "ipmb",
+ "protocol_type" : "ipmb-1.0",
+ "session_supported" : "session-less",
+ "is_ipmi" : true
+ }
+ },
+ "1" : {
+ "name" : "eth1",
+ "is_valid" : true,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "lan-802.3",
+ "protocol_type" : "ipmb-1.0",
+ "session_supported" : "multi-session",
+ "is_ipmi" : true
+ }
+ },
+ "2" : {
+ "name" : "eth2",
+ "is_valid" : true,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "lan-802.3",
+ "protocol_type" : "ipmb-1.0",
+ "session_supported" : "multi-session",
+ "is_ipmi" : true
+ }
+ },
+ "3" : {
+ "name" : "eth0",
+ "is_valid" : true,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "lan-802.3",
+ "protocol_type" : "ipmb-1.0",
+ "session_supported" : "multi-session",
+ "is_ipmi" : true
+ }
+ },
+ "4" : {
+ "name" : "EMP",
+ "is_valid" : true,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "ipmb",
+ "protocol_type" : "ipmb-1.0",
+ "session_supported" : "session-less",
+ "is_ipmi" : true
+ }
+ },
+ "5" : {
+ "name" : "RESERVED",
+ "is_valid" : false,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "reserved",
+ "protocol_type" : "na",
+ "session_supported" : "session-less",
+ "is_ipmi" : true
+ }
+ },
+ "6" : {
+ "name" : "SMLINK",
+ "is_valid" : true,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "ipmb",
+ "protocol_type" : "ipmb-1.0",
+ "session_supported" : "session-less",
+ "is_ipmi" : true
+ }
+ },
+ "7" : {
+ "name" : "ipmi_kcs4",
+ "is_valid" : true,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "system-interface",
+ "protocol_type" : "kcs",
+ "session_supported" : "session-less",
+ "is_ipmi" : true
+ }
+ },
+ "8" : {
+ "name" : "INTRABMC",
+ "is_valid" : true,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "oem",
+ "protocol_type" : "oem",
+ "session_supported" : "session-less",
+ "is_ipmi" : true
+ }
+ },
+ "9" : {
+ "name" : "SIPMB",
+ "is_valid" : true,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "ipmb",
+ "protocol_type" : "ipmb-1.0",
+ "session_supported" : "session-less",
+ "is_ipmi" : true
+ }
+ },
+ "10" : {
+ "name" : "PCIE",
+ "is_valid" : true,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "ipmb",
+ "protocol_type" : "ipmb-1.0",
+ "session_supported" : "session-less",
+ "is_ipmi" : true
+ }
+ },
+ "11" : {
+ "name" : "RESERVED",
+ "is_valid" : false,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "reserved",
+ "protocol_type" : "na",
+ "session_supported" : "session-less",
+ "is_ipmi" : true
+ }
+ },
+ "12" : {
+ "name" : "INTERNAL",
+ "is_valid" : false,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "ipmb",
+ "protocol_type" : "ipmb-1.0",
+ "session_supported" : "session-less",
+ "is_ipmi" : true
+ }
+ },
+ "13" : {
+ "name" : "RESERVED",
+ "is_valid" : false,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "reserved",
+ "protocol_type" : "na",
+ "session_supported" : "session-less",
+ "is_ipmi" : true
+ }
+ },
+ "14" : {
+ "name" : "SELF",
+ "is_valid" : false,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "unknown",
+ "protocol_type" : "na",
+ "session_supported" : "session-less",
+ "is_ipmi" : true
+ }
+ },
+ "15" : {
+ "name" : "ipmi_kcs3",
+ "is_valid" : true,
+ "active_sessions" : 0,
+ "channel_info" : {
+ "medium_type" : "system-interface",
+ "protocol_type" : "kcs",
+ "session_supported" : "session-less",
+ "is_ipmi" : true
+ }
+ }
+}
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/dev_id.json b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/dev_id.json
new file mode 100644
index 000000000..e561569d9
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/dev_id.json
@@ -0,0 +1,2 @@
+{"id": 35, "revision": 0, "addn_dev_support": 191,
+ "manuf_id": 343, "prod_id": 123, "aux": 0}
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/master_write_read_white_list.json b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/master_write_read_white_list.json
new file mode 100644
index 000000000..6fc46f452
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-config/master_write_read_white_list.json
@@ -0,0 +1,76 @@
+{
+ "filters": [
+ {
+ "Description": "Allow full read - ignore first byte write value",
+ "busId": "0x01",
+ "slaveAddr": "0x4d",
+ "slaveAddrMask": "0x00",
+ "command": "0x00",
+ "commandMask": "0xFF"
+ },
+ {
+ "Description": "Allow full read - ignore first byte write value",
+ "busId": "0x01",
+ "slaveAddr": "0x57",
+ "slaveAddrMask": "0x00",
+ "command": "0x00",
+ "commandMask": "0xFF"
+ },
+ {
+ "Description": "Allow full read - ignore first byte write value",
+ "busId": "0x02",
+ "slaveAddr": "0x40",
+ "slaveAddrMask": "0x00",
+ "command": "0x00",
+ "commandMask": "0xFF"
+ },
+ {
+ "Description": "Allow full read - ignore first byte write value",
+ "busId": "0x02",
+ "slaveAddr": "0x49",
+ "slaveAddrMask": "0x00",
+ "command": "0x00",
+ "commandMask": "0xFF"
+ },
+ {
+ "Description": "Allow full read - ignore first byte write value",
+ "busId": "0x02",
+ "slaveAddr": "0x51",
+ "slaveAddrMask": "0x00",
+ "command": "0x00",
+ "commandMask": "0xFF"
+ },
+ {
+ "Description": "Allow full read - ignore first byte write value",
+ "busId": "0x03",
+ "slaveAddr": "0x44",
+ "slaveAddrMask": "0x00",
+ "command": "0x00",
+ "commandMask": "0xFF"
+ },
+ {
+ "Description": "Allow full read - ignore first byte write value",
+ "busId": "0x03",
+ "slaveAddr": "0x68",
+ "slaveAddrMask": "0x00",
+ "command": "0x00",
+ "commandMask": "0xFF"
+ },
+ {
+ "Description": "Allow full read - ignore first byte write value",
+ "busId": "0x06",
+ "slaveAddr": "0x40",
+ "slaveAddrMask": "0x00",
+ "command": "0x00",
+ "commandMask": "0xFF"
+ },
+ {
+ "Description": "Allow full read - ignore first byte write value",
+ "busId": "0x07",
+ "slaveAddr": "0x51",
+ "slaveAddrMask": "0x00",
+ "command": "0x00",
+ "commandMask": "0xFF"
+ }
+ ]
+}
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-fru-merge-config-native.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-fru-merge-config-native.bbappend
new file mode 100644
index 000000000..2d892ad1a
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-fru-merge-config-native.bbappend
@@ -0,0 +1,8 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+SRC_URI += " file://config.yaml"
+
+#override source file before it is used for final FRU file (merged from multiple sources)
+do_install() {
+ cp ${WORKDIR}/config.yaml ${config_datadir}/
+}
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-fru-merge-config-native/config.yaml b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-fru-merge-config-native/config.yaml
new file mode 100644
index 000000000..e9b7a621e
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-fru-merge-config-native/config.yaml
@@ -0,0 +1,31 @@
+# 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/board/WFP_Baseboard:
+ entityID: 23
+ entityInstance: 1
+ interfaces:
+ xyz.openbmc_project.Inventory.Item:
+ name:
+ 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
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0002-Modify-dbus-interface-for-power-control.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0002-Modify-dbus-interface-for-power-control.patch
new file mode 100644
index 000000000..236bd18f4
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0002-Modify-dbus-interface-for-power-control.patch
@@ -0,0 +1,31 @@
+From 39df500f277eca01d6a0538d4db8ec34894d9441 Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Mon, 17 Sep 2018 12:59:12 +0800
+Subject: [PATCH] Modify dbus interface for power control
+
+Switch power control service namespace from "org" to "xyz",
+to compatible with new intel-chassis services
+
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ chassishandler.cpp | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/chassishandler.cpp b/chassishandler.cpp
+index 6002e7a..0e83bba 100644
+--- a/chassishandler.cpp
++++ b/chassishandler.cpp
+@@ -786,8 +786,8 @@ ipmi_ret_t ipmi_get_chassis_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ ipmi_data_len_t data_len,
+ ipmi_context_t context)
+ {
+- const char* objname = "/org/openbmc/control/power0";
+- const char* intf = "org.openbmc.control.Power";
++ const char* objname = "/xyz/openbmc_project/Chassis/Control/Power0";
++ const char* intf = "xyz.openbmc_project.Chassis.Control.Power";
+
+ sd_bus* bus = NULL;
+ sd_bus_message* reply = NULL;
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0009-IPv6-Network-changes.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0009-IPv6-Network-changes.patch
new file mode 100644
index 000000000..b54b22213
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0009-IPv6-Network-changes.patch
@@ -0,0 +1,899 @@
+From c20bc8eb6a08d177d951012eb91b37398b15d81d Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@linux.intel.com>
+Date: Tue, 27 Nov 2018 11:01:15 -0800
+Subject: [PATCH] IPv6 Network changes
+
+Allow IPv6 IPMI set/get commands
+
+Signed-off-by: David Cobbley <david.j.cobbley@linux.intel.com>
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
+
+Change-Id: If5528d3b7294c5f8c17db5919439235d0fad0446
+---
+ include/ipmid/types.hpp | 9 +
+ include/ipmid/utils.hpp | 1 +
+ transporthandler.cpp | 654 +++++++++++++++++++++++++++++++++++++++-
+ transporthandler.hpp | 50 +++
+ 4 files changed, 713 insertions(+), 1 deletion(-)
+
+diff --git a/include/ipmid/types.hpp b/include/ipmid/types.hpp
+index 57c5873..c06fd8c 100644
+--- a/include/ipmid/types.hpp
++++ b/include/ipmid/types.hpp
+@@ -224,6 +224,7 @@ constexpr auto ADDR_TYPE_FORMAT = "%hhx";
+
+ constexpr auto IPV4_ADDRESS_SIZE_BYTE = 4;
+ constexpr auto IPV6_ADDRESS_SIZE_BYTE = 16;
++constexpr auto IPV6_ADDRESS_STATUS_SIZE = 22;
+
+ constexpr auto DEFAULT_MAC_ADDRESS = "00:00:00:00:00:00";
+ constexpr auto DEFAULT_ADDRESS = "0.0.0.0";
+@@ -235,6 +236,7 @@ constexpr auto BITS_32 = 32;
+ constexpr auto MASK_32_BIT = 0xFFFFFFFF;
+ constexpr auto VLAN_ID_MASK = 0x00000FFF;
+ constexpr auto VLAN_ENABLE_MASK = 0x8000;
++constexpr auto IPV6_DUID_SIZE = 18;
+
+ enum class IPOrigin : uint8_t
+ {
+@@ -243,5 +245,12 @@ enum class IPOrigin : uint8_t
+ DHCP = 2,
+ };
+
++enum class AddressingEnables : uint8_t
++{
++ IPv4Only = 0,
++ IPv6Only = 1,
++ IPv4AndIPv6 = 2,
++};
++
+ } // namespace network
+ } // namespace ipmi
+diff --git a/include/ipmid/utils.hpp b/include/ipmid/utils.hpp
+index 9ef1488..8b91b12 100644
+--- a/include/ipmid/utils.hpp
++++ b/include/ipmid/utils.hpp
+@@ -256,6 +256,7 @@ namespace network
+ constexpr auto ROOT = "/xyz/openbmc_project/network";
+ constexpr auto SERVICE = "xyz.openbmc_project.Network";
+ constexpr auto IP_TYPE = "ipv4";
++constexpr auto IPV6_TYPE = "ipv6";
+ constexpr auto IPV4_PREFIX = "169.254";
+ constexpr auto IPV6_PREFIX = "fe80";
+ constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
+diff --git a/transporthandler.cpp b/transporthandler.cpp
+index 8172cc4..12d224a 100644
+--- a/transporthandler.cpp
++++ b/transporthandler.cpp
+@@ -30,6 +30,12 @@ std::unique_ptr<phosphor::Timer> networkTimer = nullptr;
+
+ const int SIZE_MAC = 18; // xx:xx:xx:xx:xx:xx
+ constexpr auto ipv4Protocol = "xyz.openbmc_project.Network.IP.Protocol.IPv4";
++constexpr auto ipv6Protocol = "xyz.openbmc_project.Network.IP.Protocol.IPv6";
++
++static const std::array<std::string, 3> ipAddressEnablesType = {
++ "xyz.openbmc_project.Network.EthernetInterface.IPAllowed.IPv4Only",
++ "xyz.openbmc_project.Network.EthernetInterface.IPAllowed.IPv6Only",
++ "xyz.openbmc_project.Network.EthernetInterface.IPAllowed.IPv4AndIPv6"};
+
+ std::map<int, std::unique_ptr<struct ChannelConfig_t>> channelConfig;
+
+@@ -389,7 +395,6 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ ipmi_context_t context)
+ {
+ ipmi_ret_t rc = IPMI_CC_OK;
+- *data_len = 0;
+
+ using namespace std::chrono_literals;
+
+@@ -403,6 +408,9 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ auto reqptr = reinterpret_cast<const set_lan_t*>(request);
+ sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+
++ size_t reqLen = *data_len;
++ *data_len = 0;
++
+ // channel number is the lower nibble
+ int channel = reqptr->channel & CHANNEL_MASK;
+ auto ethdevice = ipmi::getChannelName(channel);
+@@ -426,6 +434,11 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+
+ case LanParam::IPSRC:
+ {
++ if (reqLen != LAN_PARAM_IPSRC_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
+ uint8_t ipsrc{};
+ std::memcpy(&ipsrc, reqptr->data, ipmi::network::IPSRC_SIZE_BYTE);
+ channelConf->ipsrc = static_cast<ipmi::network::IPOrigin>(ipsrc);
+@@ -434,6 +447,11 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+
+ case LanParam::MAC:
+ {
++ if (reqLen != LAN_PARAM_MAC_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
+ char mac[SIZE_MAC];
+
+ std::snprintf(mac, SIZE_MAC, ipmi::network::MAC_ADDRESS_FORMAT,
+@@ -454,6 +472,11 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+
+ case LanParam::SUBNET:
+ {
++ if (reqLen != LAN_PARAM_SUBNET_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
+ std::snprintf(netmask, INET_ADDRSTRLEN,
+ ipmi::network::IP_ADDRESS_FORMAT, reqptr->data[0],
+ reqptr->data[1], reqptr->data[2], reqptr->data[3]);
+@@ -463,6 +486,11 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+
+ case LanParam::GATEWAY:
+ {
++ if (reqLen != LAN_PARAM_GATEWAY_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
+ std::snprintf(gateway, INET_ADDRSTRLEN,
+ ipmi::network::IP_ADDRESS_FORMAT, reqptr->data[0],
+ reqptr->data[1], reqptr->data[2], reqptr->data[3]);
+@@ -472,6 +500,11 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+
+ case LanParam::VLAN:
+ {
++ if (reqLen != LAN_PARAM_VLAN_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
+ uint16_t vlan{};
+ std::memcpy(&vlan, reqptr->data, ipmi::network::VLAN_SIZE_BYTE);
+ // We are not storing the enable bit
+@@ -484,6 +517,11 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+
+ case LanParam::INPROGRESS:
+ {
++ if (reqLen != LAN_PARAM_INPROGRESS_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
+ if (reqptr->data[0] == SET_COMPLETE)
+ {
+ channelConf->lan_set_in_progress = SET_COMPLETE;
+@@ -512,6 +550,122 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ }
+ break;
+
++ case LanParam::IPV6_AND_IPV4_ENABLES:
++ {
++ if (reqLen != LAN_PARAM_IPV6_AND_IPV4_ENABLES_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
++ channelConf->ipv6AddressingEnables = reqptr->data[0];
++ break;
++ }
++
++ case LanParam::IPV6_STATIC_ADDRESSES:
++ {
++ if (reqLen != LAN_PARAM_IPV6_STATIC_ADDRESSES_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
++ channelConf->ipv6AddressSource =
++ reqptr->data[1] & 0x81; // Looking at bit 0 and bit 7
++ char tmpIPV6[INET6_ADDRSTRLEN];
++ inet_ntop(AF_INET6, &reqptr->data[2], tmpIPV6, INET6_ADDRSTRLEN);
++ channelConf->ipv6Addr.assign(tmpIPV6);
++ channelConf->ipv6Prefix = reqptr->data[19];
++ break;
++ }
++
++ case LanParam::IPV6_ROUTER_ADDRESS_CONF_CTRL:
++ {
++ if (reqLen != LAN_PARAM_IPV6_ROUTER_ADDRESS_CONF_CTRL_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
++ channelConf->ipv6RouterAddressConfigControl = reqptr->data[0];
++ break;
++ }
++
++ case LanParam::IPV6_STATIC_ROUTER_1_IP_ADDR:
++ {
++ if (reqLen != LAN_PARAM_IPV6_STATIC_ROUTER_1_IP_ADDR_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
++ char tmpIPV6[INET6_ADDRSTRLEN];
++ inet_ntop(AF_INET6, reinterpret_cast<const void*>(reqptr->data),
++ tmpIPV6, INET6_ADDRSTRLEN);
++ channelConf->ipv6GatewayAddr.assign(tmpIPV6);
++ break;
++ }
++
++ case LanParam::IPV6_STATIC_ROUTER_1_PREFIX_LEN:
++ {
++ if (reqLen != LAN_PARAM_IPV6_STATIC_ROUTER_1_PREFIX_LEN_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
++ channelConf->ipv6GatewayPrefixLength = reqptr->data[0];
++ break;
++ }
++
++ case LanParam::IPV6_STATIC_ROUTER_1_PREFIX_VAL:
++ {
++ if (reqLen != LAN_PARAM_IPV6_STATIC_ROUTER_1_PREFIX_VAL_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
++ char tmpIPV6[INET6_ADDRSTRLEN];
++ inet_ntop(AF_INET6, reinterpret_cast<const void*>(reqptr->data),
++ tmpIPV6, INET6_ADDRSTRLEN);
++ channelConf->ipv6GatewayPrefixValue.assign(tmpIPV6);
++ break;
++ }
++
++ case LanParam::IPV6_STATIC_ROUTER_2_IP_ADDR:
++ {
++ if (reqLen != LAN_PARAM_IPV6_STATIC_ROUTER_2_IP_ADDR_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
++ char tmpIPV6[INET6_ADDRSTRLEN];
++ inet_ntop(AF_INET6, reinterpret_cast<const void*>(reqptr->data),
++ tmpIPV6, INET6_ADDRSTRLEN);
++ channelConf->ipv6BackupGatewayAddr.assign(tmpIPV6);
++ break;
++ }
++
++ case LanParam::IPV6_STATIC_ROUTER_2_PREFIX_LEN:
++ {
++ if (reqLen != LAN_PARAM_IPV6_STATIC_ROUTER_2_PREFIX_LEN_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
++ channelConf->ipv6BackupGatewayPrefixLength = reqptr->data[0];
++ break;
++ }
++
++ case LanParam::IPV6_STATIC_ROUTER_2_PREFIX_VAL:
++ {
++ if (reqLen != LAN_PARAM_IPV6_STATIC_ROUTER_2_PREFIX_VAL_SIZE)
++ {
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
++ char tmpIPV6[INET6_ADDRSTRLEN];
++ inet_ntop(AF_INET6, reinterpret_cast<const void*>(reqptr->data),
++ tmpIPV6, INET6_ADDRSTRLEN);
++ channelConf->ipv6BackupGatewayPrefixValue.assign(tmpIPV6);
++ break;
++ }
++
+ default:
+ {
+ rc = IPMI_CC_PARM_NOT_SUPPORTED;
+@@ -538,6 +692,7 @@ ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ ipmi_ret_t rc = IPMI_CC_OK;
+ *data_len = 0;
+ const uint8_t current_revision = 0x11; // Current rev per IPMI Spec 2.0
++ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+
+ get_lan_t* reqptr = (get_lan_t*)request;
+ // channel number is the lower nibble
+@@ -676,6 +831,476 @@ ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ static_cast<uint8_t>(cipherList.size());
+ break;
+ }
++ case LanParam::IPV6_AND_IPV4_SUPPORTED:
++ {
++ uint8_t addressSupport =
++ 0x1; // Allow both IPv4 & IPv6 simultaneously
++ std::array<uint8_t, 2> buf = {current_revision, addressSupport};
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_AND_IPV4_ENABLES:
++ {
++ // If DHCP, check if you have an ipv6 and ipv4 address. If static
++ // return not supported
++
++ // 00h check if conf DHCP == ipv4 or off
++ // 01h check if conf DHCP == ipv6
++ // 02h check if DHCP == true
++
++ auto ethIP = ethdevice + "/" + ipmi::network::IPV6_TYPE;
++ std::string networkInterfacePath;
++ uint8_t ipVAddressEnables = 0;
++
++ if (channelConf->lan_set_in_progress == SET_COMPLETE)
++ {
++ try
++ {
++ ipmi::ObjectTree ancestorMap;
++ // if the system has an ip object,then
++ // get the IP object.
++ auto ipObject =
++ ipmi::getDbusObject(bus, ipmi::network::IP_INTERFACE,
++ ipmi::network::ROOT, ethIP);
++ // Get the parent interface of the IP object.
++ try
++ {
++ ipmi::InterfaceList interfaces;
++ interfaces.emplace_back(
++ ipmi::network::ETHERNET_INTERFACE);
++
++ ancestorMap = ipmi::getAllAncestors(
++ bus, ipObject.first, std::move(interfaces));
++ }
++ catch (InternalFailure& e)
++ {
++ // if unable to get the parent interface
++ // then commit the error and return.
++ log<level::ERR>(
++ "Unable to get the parent interface",
++ entry("PATH=%s", ipObject.first.c_str()),
++ entry("INTERFACE=%s",
++ ipmi::network::ETHERNET_INTERFACE));
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ // for an ip object there would be single parent
++ // interface.
++ networkInterfacePath = ancestorMap.begin()->first;
++ }
++ catch (InternalFailure& e)
++ {
++ // if there is no ip configured on the system,then
++ // get the network interface object.
++ auto networkInterfaceObject = ipmi::getDbusObject(
++ bus, ipmi::network::ETHERNET_INTERFACE,
++ ipmi::network::ROOT, ethdevice);
++
++ networkInterfacePath = networkInterfaceObject.first;
++ }
++
++ ipmi::Value ipEnablesProp = ipmi::getDbusProperty(
++ bus, ipmi::network::SERVICE, networkInterfacePath,
++ ipmi::network::ETHERNET_INTERFACE, "IPAddressEnables");
++ std::string ipEnables = std::get<std::string>(ipEnablesProp);
++
++ // check if on off ipv4 ipv6, etc.
++ bool found = false;
++ for (uint8_t ii = 0; ii < ipAddressEnablesType.size(); ii++)
++ {
++ if (ipEnables == ipAddressEnablesType[ii])
++ {
++ ipVAddressEnables = ii;
++ found = true;
++ break;
++ }
++ }
++ if (!found)
++ {
++ return IPMI_CC_PARM_NOT_SUPPORTED;
++ }
++ }
++ else
++ {
++ ipVAddressEnables = channelConf->ipv6AddressingEnables;
++ }
++
++ std::array<uint8_t, 2> buf = {current_revision, ipVAddressEnables};
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_STATUS:
++ {
++ // Number of IPV6 addresses that are supported
++ constexpr std::array<uint8_t, 3> statusData = {1, 1, 3};
++
++ std::array<uint8_t, 4> buf = {current_revision, statusData[0],
++ statusData[1], statusData[2]};
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_STATIC_ADDRESSES:
++ {
++ // Only return set selector 0
++ uint8_t ipv6SetSelector = 0;
++ std::string ipaddress;
++ auto ethIP = ethdevice + "/" + ipmi::network::IPV6_TYPE;
++ uint8_t ipv6AddressSource = 0;
++ uint8_t prefixLength = 0;
++ uint8_t status = 0;
++ if (channelConf->lan_set_in_progress == SET_COMPLETE)
++ {
++ try
++ {
++ auto ipObjectInfo =
++ ipmi::getIPObject(bus, ipmi::network::IP_INTERFACE,
++ ipmi::network::ROOT, ethIP);
++
++ auto properties = ipmi::getAllDbusProperties(
++ bus, ipObjectInfo.second, ipObjectInfo.first,
++ ipmi::network::IP_INTERFACE);
++
++ if (std::get<std::string>(properties["Origin"]) ==
++ "xyz.openbmc_project.Network.IP.AddressOrigin.Static")
++ {
++ ipaddress =
++ std::get<std::string>(properties["Address"]);
++ ipv6AddressSource = 0x81; // Looking at bit 0 and bit 7
++ prefixLength =
++ std::get<uint8_t>(properties["PrefixLength"]);
++ status = 0;
++ }
++ }
++ // ignore the exception, as it is a valid condition that
++ // the system is not configured with any IP.
++ catch (InternalFailure& e)
++ {
++ // nothing to do.
++ }
++ }
++ else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
++ {
++ ipv6AddressSource = channelConf->ipv6AddressSource;
++ ipaddress = channelConf->ipv6Addr.c_str();
++ prefixLength = channelConf->ipv6Prefix;
++ status = 1;
++ }
++
++ std::array<uint8_t, ipmi::network::IPV6_ADDRESS_STATUS_SIZE> buf = {
++ current_revision, ipv6SetSelector, ipv6AddressSource};
++ inet_pton(AF_INET6, ipaddress.c_str(),
++ reinterpret_cast<void*>(&buf[3]));
++ buf[20] = prefixLength;
++ buf[21] = status;
++
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_DHCPV6_STATIC_DUID_STORAGE_LENGTH:
++ {
++ // DHCP unique identified
++ // Only 1 read-only 16-byte Block needed
++ uint8_t duidLength = 1;
++ std::array<uint8_t, 2> buf = {current_revision, duidLength};
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_DHCPV6_STATIC_DUIDS:
++ {
++ std::string macAddress;
++ if (channelConf->lan_set_in_progress == SET_COMPLETE)
++ {
++ auto macObjectInfo =
++ ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE,
++ ipmi::network::ROOT, ethdevice);
++
++ auto variant = ipmi::getDbusProperty(
++ bus, macObjectInfo.second, macObjectInfo.first,
++ ipmi::network::MAC_INTERFACE, "MACAddress");
++
++ macAddress = std::get<std::string>(variant);
++ }
++ else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
++ {
++ macAddress = channelConf->macAddress;
++ }
++
++ std::array<uint8_t,
++ ipmi::network::IPV6_DUID_SIZE + sizeof(current_revision)>
++ buf;
++ buf = {current_revision,
++ reqptr->parameter_set,
++ reqptr->parameter_block,
++ DUID_LEN,
++ 0, // Filler byte
++ DUID_LL_TYPE,
++ 0, // Filler byte
++ DUIC_ETH_HW_TYPE};
++ sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
++ (&buf[8]), (&buf[9]), (&buf[10]), (&buf[11]), (&buf[12]),
++ (&buf[13]));
++
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_DYNAMIC_ADDRESSES:
++ {
++ std::string ipaddress;
++ uint8_t ipv6AddressSource = 0;
++ uint8_t prefixLength = 0;
++ uint8_t status = 0;
++ auto ethIP = ethdevice + "/" + ipmi::network::IPV6_TYPE;
++
++ if (channelConf->lan_set_in_progress == SET_COMPLETE)
++ {
++ try
++ {
++ auto ipObjectInfo =
++ ipmi::getIPObject(bus, ipmi::network::IP_INTERFACE,
++ ipmi::network::ROOT, ethIP);
++
++ auto properties = ipmi::getAllDbusProperties(
++ bus, ipObjectInfo.second, ipObjectInfo.first,
++ ipmi::network::IP_INTERFACE);
++
++ if (std::get<std::string>(properties["Origin"]) ==
++ "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP")
++ {
++ ipaddress =
++ std::get<std::string>(properties["Address"]);
++ ipv6AddressSource = 0x81; // Looking at bit 0 and bit 7
++ prefixLength =
++ std::get<uint8_t>(properties["PrefixLength"]);
++ status = 0;
++ }
++ else
++ {
++ status = 1;
++ }
++ }
++ // ignore the exception, as it is a valid condition that
++ // the system is not configured with any IP.
++ catch (InternalFailure& e)
++ {
++ // nothing to do.
++ }
++ }
++ else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
++ {
++ ipaddress = channelConf->ipv6Addr;
++ ipv6AddressSource = channelConf->ipv6AddressSource;
++ prefixLength = channelConf->ipv6Prefix;
++ status = channelConf->ipv6AddressStatus;
++ }
++
++ uint8_t ipv6SetSelector = 0;
++ std::array<uint8_t, 22> buf = {current_revision, ipv6SetSelector,
++ ipv6AddressSource};
++ inet_pton(AF_INET6, ipaddress.c_str(),
++ reinterpret_cast<void*>(&buf[3]));
++ buf[20] = prefixLength;
++ buf[21] = status;
++
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_DHCPV6_DYNAMIC_DUID_STOR_LEN:
++ {
++ uint8_t duidLength = 0;
++ // Only 1 read-only 16-byte Block needed
++ duidLength = 1;
++
++ std::array<uint8_t, 2> buf = {current_revision, duidLength};
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_DHCPV6_DYNAMIC_DUIDS:
++ {
++ std::string macAddress;
++ if (channelConf->lan_set_in_progress == SET_COMPLETE)
++ {
++ auto macObjectInfo =
++ ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE,
++ ipmi::network::ROOT, ethdevice);
++
++ auto variant = ipmi::getDbusProperty(
++ bus, macObjectInfo.second, macObjectInfo.first,
++ ipmi::network::MAC_INTERFACE, "MACAddress");
++
++ macAddress = std::get<std::string>(variant);
++ }
++ else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
++ {
++ macAddress = channelConf->macAddress;
++ }
++
++ std::array<uint8_t,
++ ipmi::network::IPV6_DUID_SIZE + sizeof(current_revision)>
++ buf;
++ buf = {current_revision,
++ reqptr->parameter_set,
++ reqptr->parameter_block,
++ DUID_LEN,
++ 0, // Filler byte
++ DUID_LL_TYPE,
++ 0, // Filler byte
++ DUIC_ETH_HW_TYPE};
++
++ sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
++ (&buf[8]), (&buf[9]), (&buf[10]), (&buf[11]), (&buf[12]),
++ (&buf[13]));
++
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_ROUTER_ADDRESS_CONF_CTRL:
++ {
++ // Determine if automated router discovery occurs when static
++ // addresses are used for the bmc
++
++ auto ethIP = ethdevice + "/" + ipmi::network::IPV6_TYPE;
++ std::string networkInterfacePath;
++ uint8_t dynamicRA;
++ if (channelConf->lan_set_in_progress == SET_COMPLETE)
++ {
++
++ try
++ {
++ ipmi::ObjectTree ancestorMap;
++ // if the system is having ip object,then
++ // get the IP object.
++ auto ipObject =
++ ipmi::getDbusObject(bus, ipmi::network::IP_INTERFACE,
++ ipmi::network::ROOT, ethIP);
++
++ // Get the parent interface of the IP object.
++ try
++ {
++ ipmi::InterfaceList interfaces;
++ interfaces.emplace_back(
++ ipmi::network::ETHERNET_INTERFACE);
++
++ ancestorMap = ipmi::getAllAncestors(
++ bus, ipObject.first, std::move(interfaces));
++ }
++ catch (InternalFailure& e)
++ {
++ // if unable to get the parent interface
++ // then commit the error and return.
++ log<level::ERR>(
++ "Unable to get the parent interface",
++ entry("PATH=%s", ipObject.first.c_str()),
++ entry("INTERFACE=%s",
++ ipmi::network::ETHERNET_INTERFACE));
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ // for an ip object there would be single parent
++ // interface.
++ networkInterfacePath = ancestorMap.begin()->first;
++ }
++ catch (InternalFailure& e)
++ {
++ // if there is no ip configured on the system,then
++ // get the network interface object.
++ auto networkInterfaceObject = ipmi::getDbusObject(
++ bus, ipmi::network::ETHERNET_INTERFACE,
++ ipmi::network::ROOT, ethdevice);
++
++ networkInterfacePath = networkInterfaceObject.first;
++ }
++
++ auto variant = ipmi::getDbusProperty(
++ bus, ipmi::network::SERVICE, networkInterfacePath,
++ ipmi::network::ETHERNET_INTERFACE, "IPv6AcceptRA");
++ dynamicRA = std::get<bool>(variant);
++ }
++ else
++ {
++ dynamicRA = channelConf->ipv6RouterAddressConfigControl;
++ }
++
++ std::array<uint8_t, 2> buf = {current_revision, dynamicRA};
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_STATIC_ROUTER_1_IP_ADDR:
++ {
++ std::array<uint8_t, ipmi::network::IPV6_ADDRESS_SIZE_BYTE +
++ sizeof(current_revision)>
++ buf = {current_revision};
++ inet_pton(AF_INET6, channelConf->ipv6GatewayAddr.c_str(),
++ reinterpret_cast<void*>(&buf[1]));
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_STATIC_ROUTER_1_PREFIX_LEN:
++ {
++ std::array<uint8_t, 2> buf = {current_revision,
++ channelConf->ipv6GatewayPrefixLength};
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_STATIC_ROUTER_1_PREFIX_VAL:
++ {
++ constexpr uint8_t setSelector = 0;
++ std::array<uint8_t, sizeof(setSelector) +
++ ipmi::network::IPV6_ADDRESS_SIZE_BYTE +
++ sizeof(current_revision)>
++ buf = {current_revision, setSelector};
++
++ inet_pton(AF_INET6, channelConf->ipv6GatewayPrefixValue.c_str(),
++ reinterpret_cast<void*>(&buf[2]));
++
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_STATIC_ROUTER_2_IP_ADDR:
++ {
++ std::array<uint8_t, ipmi::network::IPV6_ADDRESS_SIZE_BYTE +
++ sizeof(current_revision)>
++ buf = {current_revision};
++ inet_pton(AF_INET6, channelConf->ipv6BackupGatewayAddr.c_str(),
++ reinterpret_cast<void*>(&buf[1]));
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_STATIC_ROUTER_2_PREFIX_LEN:
++ {
++ std::array<uint8_t, 2> buf = {
++ current_revision, channelConf->ipv6BackupGatewayPrefixLength};
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
++ case LanParam::IPV6_STATIC_ROUTER_2_PREFIX_VAL:
++ {
++
++ constexpr uint8_t setSelector = 0;
++ std::array<uint8_t, sizeof(setSelector) +
++ ipmi::network::IPV6_ADDRESS_SIZE_BYTE +
++ sizeof(current_revision)>
++ buf = {current_revision, setSelector};
++ inet_pton(AF_INET6,
++ channelConf->ipv6BackupGatewayPrefixValue.c_str(),
++ reinterpret_cast<void*>(&buf[2]));
++
++ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response));
++ *data_len = buf.size();
++ break;
++ }
+ default:
+ log<level::ERR>("Unsupported parameter",
+ entry("PARAMETER=0x%x", reqptr->parameter));
+@@ -921,6 +1546,16 @@ void applyChanges(int channel)
+ ipaddress, prefix);
+ }
+
++ if (!channelConf->ipv6Addr.empty() &&
++ channelConf->ipv6AddressSource ==
++ 0x80) // Check if IPv6 static addresses are enabled
++ {
++ ipmi::network::createIP(bus, ipmi::network::SERVICE,
++ networkInterfacePath, ipv6Protocol,
++ channelConf->ipv6Addr,
++ channelConf->ipv6Prefix);
++ }
++
+ if (!gateway.empty())
+ {
+ ipmi::setDbusProperty(bus, systemObject.second,
+@@ -928,7 +1563,24 @@ void applyChanges(int channel)
+ ipmi::network::SYSTEMCONFIG_INTERFACE,
+ "DefaultGateway", std::string(gateway));
+ }
++ else if (!channelConf->ipv6GatewayAddr.empty())
++ {
++ ipmi::setDbusProperty(
++ bus, systemObject.second, systemObject.first,
++ ipmi::network::SYSTEMCONFIG_INTERFACE, "DefaultGateway",
++ std::string(channelConf->ipv6GatewayAddr));
++ }
+ }
++ // set IPAddress Enables
++ ipmi::setDbusProperty(
++ bus, ipmi::network::SERVICE, networkInterfaceObject.first,
++ ipmi::network::ETHERNET_INTERFACE, "IPAddressEnables",
++ ipAddressEnablesType[channelConf->ipv6AddressingEnables]);
++
++ ipmi::setDbusProperty(
++ bus, ipmi::network::SERVICE, networkInterfaceObject.first,
++ ipmi::network::ETHERNET_INTERFACE, "IPv6AcceptRA",
++ (bool)channelConf->ipv6RouterAddressConfigControl);
+ }
+ catch (InternalFailure& e)
+ {
+diff --git a/transporthandler.hpp b/transporthandler.hpp
+index 04d4673..bd23391 100644
+--- a/transporthandler.hpp
++++ b/transporthandler.hpp
+@@ -79,6 +79,28 @@ enum class LanParam : uint8_t
+ IPV6_NEIGHBOR_TIMING_CONFIGURATION = 80,
+ };
+
++// Data length of parameters
++constexpr size_t LAN_PARAM_INPROGRESS_SIZE = 3;
++constexpr size_t LAN_PARAM_IP_SIZE = 6;
++constexpr size_t LAN_PARAM_IPSRC_SIZE = 3;
++constexpr size_t LAN_PARAM_MAC_SIZE = 8;
++constexpr size_t LAN_PARAM_SUBNET_SIZE = 6;
++constexpr size_t LAN_PARAM_GATEWAY_SIZE = 6;
++constexpr size_t LAN_PARAM_VLAN_SIZE = 4;
++constexpr size_t LAN_PARAM_IPV6_AND_IPV4_ENABLES_SIZE = 3;
++constexpr size_t LAN_PARAM_IPV6_STATIC_ADDRESSES_SIZE = 23;
++constexpr size_t LAN_PARAM_IPV6_ROUTER_ADDRESS_CONF_CTRL_SIZE = 3;
++constexpr size_t LAN_PARAM_IPV6_STATIC_ROUTER_1_IP_ADDR_SIZE = 18;
++constexpr size_t LAN_PARAM_IPV6_STATIC_ROUTER_1_PREFIX_LEN_SIZE = 3;
++constexpr size_t LAN_PARAM_IPV6_STATIC_ROUTER_1_PREFIX_VAL_SIZE = 19;
++constexpr size_t LAN_PARAM_IPV6_STATIC_ROUTER_2_IP_ADDR_SIZE = 18;
++constexpr size_t LAN_PARAM_IPV6_STATIC_ROUTER_2_PREFIX_LEN_SIZE = 3;
++constexpr size_t LAN_PARAM_IPV6_STATIC_ROUTER_2_PREFIX_VAL_SIZE = 19;
++
++constexpr uint8_t DUID_LEN = 10;
++constexpr uint8_t DUID_LL_TYPE = 3;
++constexpr uint8_t DUIC_ETH_HW_TYPE = 1;
++
+ constexpr uint8_t SET_COMPLETE = 0;
+ constexpr uint8_t SET_IN_PROGRESS = 1;
+ constexpr uint8_t SET_COMMIT_WRITE = 2; // Optional
+@@ -101,6 +123,20 @@ struct ChannelConfig_t
+ uint8_t lan_set_in_progress = SET_COMPLETE;
+ bool flush = false;
+
++ // IPV6 parameters
++ uint8_t ipv6AddressSource = 0x0;
++ uint8_t ipv6AddressingEnables = 0x2;
++ std::string ipv6Addr;
++ uint8_t ipv6Prefix = 32;
++ uint8_t ipv6AddressStatus = 0x0;
++ uint8_t ipv6RouterAddressConfigControl = 0x0;
++ std::string ipv6GatewayAddr;
++ std::string ipv6BackupGatewayAddr;
++ uint8_t ipv6GatewayPrefixLength;
++ std::string ipv6GatewayPrefixValue;
++ uint8_t ipv6BackupGatewayPrefixLength = 0x0;
++ std::string ipv6BackupGatewayPrefixValue;
++
+ void clear()
+ {
+ ipaddr.clear();
+@@ -111,6 +147,20 @@ struct ChannelConfig_t
+ ipsrc = ipmi::network::IPOrigin::UNSPECIFIED;
+ lan_set_in_progress = SET_COMPLETE;
+ flush = false;
++
++ // IPv6
++ ipv6Addr.clear();
++ ipv6GatewayAddr.clear();
++ ipv6BackupGatewayAddr.clear();
++ ipv6AddressingEnables = 0x2;
++ ipv6AddressSource = 0x0;
++ ipv6Prefix = 32;
++ ipv6AddressStatus = 0x0;
++ ipv6RouterAddressConfigControl = 0x0;
++ ipv6GatewayPrefixLength = 0x0;
++ ipv6GatewayPrefixValue.clear();
++ ipv6BackupGatewayPrefixLength = 0x0;
++ ipv6BackupGatewayPrefixValue.clear();
+ }
+ };
+
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0010-fix-get-system-GUID-ipmi-command.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0010-fix-get-system-GUID-ipmi-command.patch
new file mode 100644
index 000000000..c1ec6ac6e
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0010-fix-get-system-GUID-ipmi-command.patch
@@ -0,0 +1,56 @@
+From 4953a9f2233fd24a28da84443cea6aebecd14fbc Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Mon, 17 Sep 2018 13:20:54 +0800
+Subject: [PATCH] fix "get system GUID" ipmi command
+
+Change-Id: I15c71607c24ad8b3e2c9065a5470002ecb1761bb
+Signed-off-by: Jia, Chunhui <chunhui.jia@intel.com>
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ apphandler.cpp | 7 ++-----
+ host-ipmid-whitelist.conf | 1 +
+ 2 files changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/apphandler.cpp b/apphandler.cpp
+index f2889c5..9149373 100644
+--- a/apphandler.cpp
++++ b/apphandler.cpp
+@@ -48,7 +48,7 @@ extern sd_bus* bus;
+
+ constexpr auto bmc_state_interface = "xyz.openbmc_project.State.BMC";
+ constexpr auto bmc_state_property = "CurrentBMCState";
+-constexpr auto bmc_interface = "xyz.openbmc_project.Inventory.Item.Bmc";
++// phosphor-setting-manager is the unique service that holds this interface
+ constexpr auto bmc_guid_interface = "xyz.openbmc_project.Common.UUID";
+ constexpr auto bmc_guid_property = "UUID";
+ constexpr auto bmc_guid_len = 16;
+@@ -546,8 +545,7 @@ ipmi_ret_t ipmi_app_get_sys_guid(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ {
+ // Get the Inventory object implementing BMC interface
+ ipmi::DbusObjectInfo bmcObject =
+- ipmi::getDbusObject(bus, bmc_interface);
+-
++ ipmi::getDbusObject(bus, bmc_guid_interface);
+ // Read UUID property value from bmcObject
+ // UUID is in RFC4122 format Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
+ auto variant =
+@@ -591,7 +589,6 @@ ipmi_ret_t ipmi_app_get_sys_guid(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ catch (const InternalFailure& e)
+ {
+ log<level::ERR>("Failed in reading BMC UUID property",
+- entry("INTERFACE=%s", bmc_interface),
+ entry("PROPERTY_INTERFACE=%s", bmc_guid_interface),
+ entry("PROPERTY=%s", bmc_guid_property));
+ return IPMI_CC_UNSPECIFIED_ERROR;
+diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf
+index 2c37ac9..164edbe 100644
+--- a/host-ipmid-whitelist.conf
++++ b/host-ipmid-whitelist.conf
+@@ -40,3 +40,4 @@
+ 0x2C:0x06 //<Group Extension>:<Get Asset Tag>
+ 0x2C:0x07 //<Group Extension>:<Get Sensor Info>
+ 0x2C:0x10 //<Group Extension>:<Get Temperature Readings>
++0x30:0x41 //<OEM>:<Set System GUID>
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0013-ipmi-add-set-bios-id-to-whitelist.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0013-ipmi-add-set-bios-id-to-whitelist.patch
new file mode 100644
index 000000000..ae10ab60a
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0013-ipmi-add-set-bios-id-to-whitelist.patch
@@ -0,0 +1,25 @@
+From ad7276f3aedb6f5aed315db57406c98f2bf71a09 Mon Sep 17 00:00:00 2001
+From: "Jia, Chunhui" <chunhui.jia@intel.com>
+Date: Tue, 24 Jul 2018 13:21:52 +0800
+Subject: [PATCH] [ipmi] add set bios id to whitelist
+
+Add "SetBIOSId" and "GetDeviceInfo" 2 OEM commands into whitelist
+
+Signed-off-by: Jia, Chunhui <chunhui.jia@intel.com>
+---
+ host-ipmid-whitelist.conf | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf
+index 164edbe..db54a49 100644
+--- a/host-ipmid-whitelist.conf
++++ b/host-ipmid-whitelist.conf
+@@ -41,3 +41,5 @@
+ 0x2C:0x07 //<Group Extension>:<Get Sensor Info>
+ 0x2C:0x10 //<Group Extension>:<Get Temperature Readings>
+ 0x30:0x41 //<OEM>:<Set System GUID>
++0x30:0x26 //<OEM>:<Set BIOS ID>
++0x30:0x27 //<OEM>:<Get Device Info>
+--
+2.16.2
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0021-Implement-IPMI-Commmand-Get-Host-Restart-Cause.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0021-Implement-IPMI-Commmand-Get-Host-Restart-Cause.patch
new file mode 100644
index 000000000..cba0cde32
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0021-Implement-IPMI-Commmand-Get-Host-Restart-Cause.patch
@@ -0,0 +1,143 @@
+From 6d5a372e0cf98de4d97a88d2cd42a00b7a8f034f Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Sun, 16 Sep 2018 21:32:38 +0800
+Subject: [PATCH] Implement IPMI Commmand - Get Host Restart Cause.
+
+It supports to track the information about what
+action last caused the system to restart.
+Return value includes: restart_cause and channel_number.
+
+According to IPMI Spec, it includes 12 types as following:
+1. Unknown 0x0
+2. IpmiCommand 0x1
+3. ResetButton 0x2
+4. PowerButton 0x3
+5. WatchdogTimer 0x4
+6. OEM 0x5
+7. PowerPolicyAlwaysOn 0x6
+8. PowerPolicyPreviousState 0x7
+9. PEF-Reset 0x8
+10. PEF-PowerCycle 0x9
+11. SoftReset 0xA
+12. RTC-Wakeup 0xB
+
+Change-Id: Id3b32e271b85b5fc4c69d5ca40227f8f9c08ce48
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ chassishandler.cpp | 54 +++++++++++++++++++++++++++++++++++++++
+ chassishandler.hpp | 1 +
+ host-ipmid-whitelist.conf | 1 +
+ 3 files changed, 56 insertions(+)
+
+diff --git a/chassishandler.cpp b/chassishandler.cpp
+index d20b220..8a8cb26 100644
+--- a/chassishandler.cpp
++++ b/chassishandler.cpp
+@@ -90,6 +90,11 @@ static constexpr auto chassisPOHStateIntf =
+ "xyz.openbmc_project.State.PowerOnHours";
+ static constexpr auto pOHCounterProperty = "POHCounter";
+ static constexpr auto match = "chassis0";
++const static constexpr char* stateHostInterface =
++ "xyz.openbmc_project.State.Host";
++const static constexpr char* hostRestartCauseInterface =
++ "xyz.openbmc_project.State.Host.HostRestartCause";
++const static constexpr char* hostRestartCause = "HostRestartCause";
+ const static constexpr char chassisCapIntf[] =
+ "xyz.openbmc_project.Control.ChassisCapabilities";
+ const static constexpr char chassisCapFlagsProp[] = "CapabilitiesFlags";
+@@ -176,6 +181,13 @@ struct set_sys_boot_options_t
+ uint8_t data[SIZE_BOOT_OPTION];
+ } __attribute__((packed));
+
++struct GetSysRestartCauseResponse
++{
++ uint8_t restartCause;
++ uint8_t channelNum;
++
++} __attribute__((packed));
++
+ int getHostNetworkData(get_sys_boot_options_response_t* respptr)
+ {
+ ipmi::PropertyMap properties;
+@@ -1584,6 +1596,44 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ return rc;
+ }
+
++ipmi_ret_t ipmi_chassis_get_sys_restart_cause(
++ ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
++ ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
++{
++ ipmi_ret_t rc = IPMI_CC_OK;
++
++ GetSysRestartCauseResponse* resp = (GetSysRestartCauseResponse*)response;
++ std::fill(reinterpret_cast<uint8_t*>(resp),
++ reinterpret_cast<uint8_t*>(resp) + sizeof(*resp), 0);
++ if (*data_len != 0)
++ {
++ rc = IPMI_CC_REQ_DATA_LEN_INVALID;
++ return rc;
++ }
++
++ try
++ {
++ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
++ ipmi::DbusObjectInfo hostObject =
++ ipmi::getDbusObject(bus, stateHostInterface);
++ ipmi::Value variant =
++ ipmi::getDbusProperty(bus, hostObject.second, hostObject.first,
++ hostRestartCauseInterface, hostRestartCause);
++ resp->restartCause = variant.get<uint8_t>();
++ }
++
++ catch (std::exception& e)
++ {
++ log<level::ERR>(e.what());
++ rc = IPMI_CC_UNSPECIFIED_ERROR;
++ return rc;
++ }
++ resp->channelNum = 0; // Fix to primary channel.
++ *data_len = sizeof(GetSysRestartCauseResponse);
++
++ return rc;
++}
++
+ /** @brief implements Get POH counter command
+ * @parameter
+ * - none
+@@ -1739,4 +1789,8 @@ void register_netfn_chassis_functions()
+ ipmi::chassis::cmdSetPowerRestorePolicy,
+ ipmi::Privilege::Operator,
+ ipmiChassisSetPowerRestorePolicy);
++
++ // <get Host Restart Cause>
++ ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_RESTART_CAUSE, NULL,
++ ipmi_chassis_get_sys_restart_cause, PRIVILEGE_USER);
+ }
+diff --git a/chassishandler.hpp b/chassishandler.hpp
+index 49b5ef8..2c42b11 100644
+--- a/chassishandler.hpp
++++ b/chassishandler.hpp
+@@ -17,6 +17,7 @@ enum ipmi_netfn_chassis_cmds
+ // Set Power Restore Policy
+ IPMI_CMD_SET_RESTORE_POLICY = 0x06,
+ // Get capability bits
++ IPMI_CMD_GET_SYS_RESTART_CAUSE = 0x07,
+ IPMI_CMD_SET_SYS_BOOT_OPTIONS = 0x08,
+ IPMI_CMD_GET_SYS_BOOT_OPTIONS = 0x09,
+ IPMI_CMD_GET_POH_COUNTER = 0x0F,
+diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf
+index c1fca1d..94232de 100644
+--- a/host-ipmid-whitelist.conf
++++ b/host-ipmid-whitelist.conf
+@@ -4,6 +4,7 @@
+ 0x00:0x02 //<Chassis>:<Chassis Control>
+ 0x00:0x05 //<Chassis>:<Set Chassis Capabilities>
+ 0x00:0x06 //<Chassis>:<Set Power Restore Policy>
++0x00:0x07 //<Chassis>:<Get System Restart Cause>
+ 0x00:0x08 //<Chassis>:<Set System Boot Options>
+ 0x00:0x09 //<Chassis>:<Get System Boot Options>
+ 0x00:0x0F //<Chassis>:<Get POH Counter Command>
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0039-ipmi-add-oem-command-get-AIC-FRU-to-whitelist.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0039-ipmi-add-oem-command-get-AIC-FRU-to-whitelist.patch
new file mode 100644
index 000000000..fdaa91085
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0039-ipmi-add-oem-command-get-AIC-FRU-to-whitelist.patch
@@ -0,0 +1,25 @@
+From cf466ba2c66a95825ae0014d7c378ad63b050d2f Mon Sep 17 00:00:00 2001
+From: "Jia, Chunhui" <chunhui.jia@intel.com>
+Date: Wed, 15 Aug 2018 14:50:04 +0800
+Subject: [PATCH] [ipmi] add oem command "get AIC FRU" to whitelist
+
+Intel BIOS requires this oem command to get addon card FRU info.
+Add to whitelist to unblock.
+
+Signed-off-by: Jia, Chunhui <chunhui.jia@intel.com>
+---
+ host-ipmid-whitelist.conf | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf
+index db54a49..49746a2 100644
+--- a/host-ipmid-whitelist.conf
++++ b/host-ipmid-whitelist.conf
+@@ -43,3 +43,4 @@
+ 0x30:0x41 //<OEM>:<Set System GUID>
+ 0x30:0x26 //<OEM>:<Set BIOS ID>
+ 0x30:0x27 //<OEM>:<Get Device Info>
++0x30:0x31 //<OEM>:<Get AIC card FRU>
+--
+2.16.2
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0049-Fix-Unspecified-error-on-ipmi-restart-cause-command.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0049-Fix-Unspecified-error-on-ipmi-restart-cause-command.patch
new file mode 100644
index 000000000..aba5eb095
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0049-Fix-Unspecified-error-on-ipmi-restart-cause-command.patch
@@ -0,0 +1,71 @@
+From 59287a8869b5253a1b4203e0cc8a92f063dcc7e6 Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Tue, 25 Sep 2018 16:08:22 +0800
+Subject: [PATCH] Fix "Unspecified error" on ipmi restart cause command
+
+Needs to convert the dbus value(enum) into ipmi value(uint8)
+
+Tested by:
+ipmitool chassis restart_cause
+
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ chassishandler.cpp | 28 ++++++++++++++++++++++++++--
+ 1 file changed, 26 insertions(+), 2 deletions(-)
+
+diff --git a/chassishandler.cpp b/chassishandler.cpp
+index 40eb4f5..c3d4931 100644
+--- a/chassishandler.cpp
++++ b/chassishandler.cpp
+@@ -106,7 +106,7 @@ static constexpr auto match = "chassis0";
+ const static constexpr char* stateHostInterface =
+ "xyz.openbmc_project.State.Host";
+ const static constexpr char* hostRestartCauseInterface =
+- "xyz.openbmc_project.State.Host.HostRestartCause";
++ "xyz.openbmc_project.State.Host";
+ const static constexpr char* hostRestartCause = "HostRestartCause";
+ const static constexpr char chassisCapIntf[] =
+ "xyz.openbmc_project.Control.ChassisCapabilities";
+@@ -1764,6 +1764,26 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ return rc;
+ }
+
++namespace restart_cause
++{
++
++using namespace sdbusplus::xyz::openbmc_project::State::server;
++
++std::map<Host::RestartCause, uint8_t> dbusToIpmi = {
++ {Host::RestartCause::Unknown, 0x0},
++ {Host::RestartCause::IpmiCommand, 0x1},
++ {Host::RestartCause::ResetButton, 0x2},
++ {Host::RestartCause::PowerButton, 0x3},
++ {Host::RestartCause::WatchdogTimer, 0x4},
++ {Host::RestartCause::OEM, 0x5},
++ {Host::RestartCause::PowerPolicyAlwaysOn, 0x6},
++ {Host::RestartCause::PowerPolicyPreviousState, 0x7},
++ {Host::RestartCause::PEFReset, 0x8},
++ {Host::RestartCause::PEFPowerCycle, 0x9},
++ {Host::RestartCause::SoftReset, 0xa},
++ {Host::RestartCause::RTCWakeup, 0xb}};
++} // namespace restart_cause
++
+ ipmi_ret_t ipmi_chassis_get_sys_restart_cause(
+ ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
+ ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
+@@ -1787,7 +1807,11 @@ ipmi_ret_t ipmi_chassis_get_sys_restart_cause(
+ ipmi::Value variant =
+ ipmi::getDbusProperty(bus, hostObject.second, hostObject.first,
+ hostRestartCauseInterface, hostRestartCause);
+- resp->restartCause = variant.get<uint8_t>();
++
++ std::string restartCause =
++ sdbusplus::message::variant_ns::get<std::string>(variant);
++ resp->restartCause = restart_cause::dbusToIpmi.at(
++ restart_cause::Host::convertRestartCauseFromString(restartCause));
+ }
+
+ catch (std::exception& e)
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0050-enable-6-oem-commands.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0050-enable-6-oem-commands.patch
new file mode 100644
index 000000000..b800632cc
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0050-enable-6-oem-commands.patch
@@ -0,0 +1,15 @@
+diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf
+index 22a2a3c..5d71698 100644
+--- a/host-ipmid-whitelist.conf
++++ b/host-ipmid-whitelist.conf
+@@ -49,3 +49,10 @@
+ 0x30:0x26 //<OEM>:<Set BIOS ID>
+ 0x30:0x27 //<OEM>:<Get Device Info>
+ 0x30:0x31 //<OEM>:<Get AIC card FRU>
++0x30:0x54 //<OEM>:<Set Power Restore Delay>
++0x30:0x55 //<OEM>:<Get Power Restore Delay>
++0x30:0x9A //<OEM>:<Get Processor Error Config>
++0x30:0x9B //<OEM>:<Set Processor Error Config>
++0x30:0xB0 //<OEM>:<Get LED Status>
++0x30:0xE9 //<OEM>:<Get BIOS Post Codes>
++
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0053-Fix-keep-looping-issue-when-entering-OS.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0053-Fix-keep-looping-issue-when-entering-OS.patch
new file mode 100644
index 000000000..903ae96a7
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0053-Fix-keep-looping-issue-when-entering-OS.patch
@@ -0,0 +1,80 @@
+From ad93a6e17310d92ef07b8d367b23c93793562d0f Mon Sep 17 00:00:00 2001
+From: Cheng C Yang <cheng.c.yang@linux.intel.com>
+Date: Wed, 23 Jan 2019 17:02:40 +0800
+Subject: [PATCH] Fix keep looping issue when entering OS
+
+Sometimes when entering OS, OS will keep continuously sending ipmi command
+"READ EVENT MESSAGE BUFFER" to BMC. This issue is caused by incorrect KCS
+status. If restart the host immediately while OS is still running, SMS_ATN
+will be set, after that KCS come into an incorrect status, and then KCS
+communction between BMC and OS crash. To make KCS go back to correct status
+and fix the issue, clear SMS_ATN after every time power cycle happen.
+
+Unit Test:
+ After entered OS, force reset system, after enter OS again, OS can start
+normally without keep sending READ EVENT MESSAGE BUFFER command.
+ After power on system, enter EFI SHELL, check cmdtool.efi can work
+correctly through KCS channel.
+---
+ host-cmd-manager.cpp | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/host-cmd-manager.cpp b/host-cmd-manager.cpp
+index f3aba7f..465eb81 100644
+--- a/host-cmd-manager.cpp
++++ b/host-cmd-manager.cpp
+@@ -26,6 +26,8 @@ constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
+ constexpr auto HOST_STATE_PATH = "/xyz/openbmc_project/state/host0";
+ constexpr auto HOST_STATE_INTERFACE = "xyz.openbmc_project.State.Host";
+ constexpr auto HOST_TRANS_PROP = "RequestedHostTransition";
++constexpr const char* IPMI_PATH = "/xyz/openbmc_project/Ipmi/Channel/ipmi_kcs3";
++constexpr const char* IPMI_INTERFACE = "xyz.openbmc_project.Ipmi.Channel.SMS";
+
+ // For throwing exceptions
+ using namespace phosphor::logging;
+@@ -106,6 +108,20 @@ void Manager::clearQueue()
+ // `false` indicating Failure
+ std::get<CallBack>(command)(ipmiCmdData, false);
+ }
++
++ auto host = ::ipmi::getService(this->bus, IPMI_INTERFACE, IPMI_PATH);
++ auto method = this->bus.new_method_call(host.c_str(), IPMI_PATH,
++ IPMI_INTERFACE, "clearAttention");
++
++ try
++ {
++ auto reply = this->bus.call(method);
++ }
++ catch (sdbusplus::exception_t&)
++ {
++ log<level::ERR>("Error in clearing SMS attention");
++ elog<InternalFailure>();
++ }
+ }
+
+ // Called for alerting the host
+@@ -115,9 +131,6 @@ void Manager::checkQueueAndAlertHost()
+ {
+ log<level::DEBUG>("Asserting SMS Attention");
+
+- std::string IPMI_PATH("/org/openbmc/HostIpmi/1");
+- std::string IPMI_INTERFACE("org.openbmc.HostIpmi");
+-
+ auto host = ::ipmi::getService(this->bus, IPMI_INTERFACE, IPMI_PATH);
+
+ // Start the timer for this transaction
+@@ -131,9 +144,8 @@ void Manager::checkQueueAndAlertHost()
+ return;
+ }
+
+- auto method =
+- this->bus.new_method_call(host.c_str(), IPMI_PATH.c_str(),
+- IPMI_INTERFACE.c_str(), "setAttention");
++ auto method = this->bus.new_method_call(host.c_str(), IPMI_PATH,
++ IPMI_INTERFACE, "setAttention");
+ auto reply = this->bus.call(method);
+
+ if (reply.is_method_error())
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0054-Fix-User-commands-require-channel-layer-lib.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0054-Fix-User-commands-require-channel-layer-lib.patch
new file mode 100644
index 000000000..bf6f672cf
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0054-Fix-User-commands-require-channel-layer-lib.patch
@@ -0,0 +1,37 @@
+From 5d0c9d2217dbe369daffb8a92d7b5e7d7d34d566 Mon Sep 17 00:00:00 2001
+From: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
+Date: Sat, 2 Mar 2019 20:08:32 +0530
+Subject: [PATCH] Fix: User commands require channel layer lib
+
+As channel layer is separated out from user layer lib, it
+has to be manually included in libusercommands, as user
+command handlers use channel layer API's
+
+Tested-by:
+1. Made sure that libusercommands are loaded on it's own
+without any undefined symbol error.
+2. ipmitool user list 1 works on host interface
+
+Change-Id: I6652ad248e01afc1349e3a9612754dbdb84b96ad
+Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
+---
+ Makefile.am | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index bb7bdbf..4e9101e 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -120,7 +120,8 @@ libipmi20_la_CXXFLAGS = $(COMMON_CXX)
+ providers_LTLIBRARIES += libusercmds.la
+ libusercmds_la_LIBADD = \
+ libipmid/libipmid.la \
+- user_channel/libuserlayer.la
++ user_channel/libuserlayer.la \
++ user_channel/libchannellayer.la
+ libusercmds_la_SOURCES = \
+ user_channel/usercommands.cpp
+ libusercmds_la_LDFLAGS = \
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0055-Implement-set-front-panel-button-enables-command.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0055-Implement-set-front-panel-button-enables-command.patch
new file mode 100644
index 000000000..fd7cf1851
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0055-Implement-set-front-panel-button-enables-command.patch
@@ -0,0 +1,176 @@
+From b8b88a5c0f9e9cb6023cb8d5453e5cfadaa1a375 Mon Sep 17 00:00:00 2001
+From: Kuiying Wang <kuiying.wang@intel.com>
+Date: Fri, 4 Jan 2019 10:50:21 +0800
+Subject: [PATCH] Implement set front panel button enables command
+
+Through modify buttons' property "Enabled" to disable/enable
+corresponding button.
+Currently support power and reset button.
+
+Test-By: ipmitool raw 0x0 0xa 0x2 //disable reset button
+ ipmitool raw 0x0 0xa 0x1 //disable power button
+ ipmitool raw 0x0 0xa 0x0 //enable all buttons
+
+Change-Id: Ice6f58edb898689f7a7fa08ad078d25fccaab27e
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+---
+ chassishandler.cpp | 98 +++++++++++++++++++++++++++++++++++++++
+ chassishandler.hpp | 1 +
+ host-ipmid-whitelist.conf | 1 +
+ 3 files changed, 100 insertions(+)
+
+diff --git a/chassishandler.cpp b/chassishandler.cpp
+index 4b42b3c..1a5b805 100644
+--- a/chassishandler.cpp
++++ b/chassishandler.cpp
+@@ -112,6 +112,8 @@ const static constexpr char chassisSMDevAddrProp[] = "SMDeviceAddress";
+ const static constexpr char chassisBridgeDevAddrProp[] = "BridgeDeviceAddress";
+ static constexpr uint8_t chassisCapFlagMask = 0x0f;
+ static constexpr uint8_t chassisCapAddrMask = 0xfe;
++static constexpr uint8_t disableResetButton = 0x2;
++static constexpr uint8_t disablePowerButton = 0x1;
+ static constexpr const char* powerButtonIntf =
+ "xyz.openbmc_project.Chassis.Buttons.Power";
+ static constexpr const char* powerButtonPath =
+@@ -140,6 +142,19 @@ struct GetPOHCountResponse
+ uint8_t front_panel_button_cap_status;
+ } __attribute__((packed)) ipmi_get_chassis_status_t;
+
++typedef struct
++{
++ uint8_t disables; // Front Panel Button Enables
++ //[7:4] - reserved
++ //[3] - 1b = disable Standby (sleep) button for entering standby (sleep)
++ //(control can still be used to wake the system)
++ //[2] - 1b = disable Diagnostic Interrupt button
++ //[1] - 1b = disable Reset button
++ //[0] - 1b = disable Power off button for power off only (in the case there
++ // is a single combined power/standby (sleep) button, then this also
++ // disables sleep requests via that button)
++} __attribute__((packed)) IPMISetFrontPanelButtonEnablesReq;
++
+ // Phosphor Host State manager
+ namespace State = sdbusplus::xyz::openbmc_project::State::server;
+
+@@ -1721,6 +1738,82 @@ ipmi_ret_t ipmi_chassis_set_power_restore_policy(
+ return ipmi::responseSuccess(power_policy::allSupport);
+ }
+
++ipmi_ret_t ipmiSetFrontPanelButtonEnables(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
++ ipmi_request_t request,
++ ipmi_response_t response,
++ ipmi_data_len_t data_len,
++ ipmi_context_t context)
++{
++ bool enable = false;
++ constexpr const char* powerButtonIntf =
++ "xyz.openbmc_project.Chassis.Buttons.Power";
++ constexpr const char* powerButtonPath =
++ "/xyz/openbmc_project/Chassis/Buttons/Power0";
++ constexpr const char* resetButtonIntf =
++ "xyz.openbmc_project.Chassis.Buttons.Reset";
++ constexpr const char* resetButtonPath =
++ "/xyz/openbmc_project/Chassis/Buttons/Reset0";
++ using namespace chassis::internal;
++
++ IPMISetFrontPanelButtonEnablesReq* req =
++ static_cast<IPMISetFrontPanelButtonEnablesReq*>(request);
++ if (*data_len != 1)
++ {
++ *data_len = 0;
++ log<level::ERR>("IPMI request len is invalid");
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++ *data_len = 0;
++ if (req->disables & disablePowerButton)
++ {
++ // Disable power button
++ enable = false;
++ }
++ else
++ {
++ // Enable power button
++ enable = true;
++ }
++ // set power button Enabled property
++ try
++ {
++ auto service = ipmi::getService(dbus, powerButtonIntf, powerButtonPath);
++ ipmi::setDbusProperty(dbus, service, powerButtonPath, powerButtonIntf,
++ "Enabled", enable);
++ }
++ catch (sdbusplus::exception::SdBusError& e)
++ {
++ log<level::ERR>(e.what());
++ log<level::ERR>("Fail to set power button Enabled property");
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++
++ if (req->disables & disableResetButton)
++ {
++ // disable reset button
++ enable = false;
++ }
++ else
++ {
++ // enable reset button
++ enable = true;
++ }
++ // set reset button Enabled property
++ try
++ {
++ auto service = ipmi::getService(dbus, resetButtonIntf, resetButtonPath);
++ ipmi::setDbusProperty(dbus, service, resetButtonPath, resetButtonIntf,
++ "Enabled", enable);
++ }
++ catch (sdbusplus::exception::SdBusError& e)
++ {
++ log<level::ERR>(e.what());
++ log<level::ERR>("Fail to set reset button Enabled property");
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ return IPMI_CC_OK;
++}
++
+ void register_netfn_chassis_functions()
+ {
+ createIdentifyTimer();
+@@ -1733,6 +1826,11 @@ void register_netfn_chassis_functions()
+ ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP, NULL,
+ ipmi_get_chassis_cap, PRIVILEGE_USER);
+
++ // Set Front Panel Button Enables
++ ipmi_register_callback(NETFUN_CHASSIS,
++ IPMI_CMD_SET_FRONT_PANEL_BUTTON_ENABLES, NULL,
++ ipmiSetFrontPanelButtonEnables, PRIVILEGE_ADMIN);
++
+ // Set Chassis Capabilities
+ ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_CHASSIS_CAP, NULL,
+ ipmi_set_chassis_cap, PRIVILEGE_USER);
+diff --git a/chassishandler.hpp b/chassishandler.hpp
+index 49b5ef8..f4a6bff 100644
+--- a/chassishandler.hpp
++++ b/chassishandler.hpp
+@@ -19,6 +19,7 @@ enum ipmi_netfn_chassis_cmds
+ IPMI_CMD_GET_SYS_RESTART_CAUSE = 0x07,
+ IPMI_CMD_SET_SYS_BOOT_OPTIONS = 0x08,
+ IPMI_CMD_GET_SYS_BOOT_OPTIONS = 0x09,
++ IPMI_CMD_SET_FRONT_PANEL_BUTTON_ENABLES = 0x0A,
+ IPMI_CMD_GET_POH_COUNTER = 0x0F,
+ };
+
+diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf
+index e5cd0b5..d96d9ed 100644
+--- a/host-ipmid-whitelist.conf
++++ b/host-ipmid-whitelist.conf
+@@ -6,6 +6,7 @@
+ 0x00:0x07 //<Chassis>:<Get System Restart Cause>
+ 0x00:0x08 //<Chassis>:<Set System Boot Options>
+ 0x00:0x09 //<Chassis>:<Get System Boot Options>
++0x00:0x0A //<Chassis>:<Set Front Panel Button Enables>
+ 0x00:0x0F //<Chassis>:<Get POH Counter Command>
+ 0x04:0x02 //<Sensor/Event>:<Platform event>
+ 0x04:0x2D //<Sensor/Event>:<Get Sensor Reading>
+--
+2.19.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0056-add-SetInProgress-to-get-set-boot-option-cmd.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0056-add-SetInProgress-to-get-set-boot-option-cmd.patch
new file mode 100644
index 000000000..3a77887a0
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0056-add-SetInProgress-to-get-set-boot-option-cmd.patch
@@ -0,0 +1,102 @@
+From 949db3a985719335d3df77db368eb2b296756749 Mon Sep 17 00:00:00 2001
+From: "Jia, chunhui" <chunhui.jia@linux.intel.com>
+Date: Tue, 19 Mar 2019 16:09:06 +0800
+Subject: [PATCH] add SetInProgress to get/set boot option cmd
+
+It is required by BIOS. BIOS will check setinprogress first.
+If this flag is not supported, BIOS will bypass all boot
+option flow.
+
+Change-Id: Ibb0501ea5bc36c4f1f72339efef03724dd4e613f
+Signed-off-by: Jia, chunhui <chunhui.jia@linux.intel.com>
+---
+ chassishandler.cpp | 26 +++++++++++++++++++++++++-
+ chassishandler.hpp | 3 +++
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/chassishandler.cpp b/chassishandler.cpp
+index 6d14d1b..553afa8 100644
+--- a/chassishandler.cpp
++++ b/chassishandler.cpp
+@@ -1351,6 +1351,10 @@ static ipmi_ret_t setBootMode(const Mode::Modes& mode)
+ return IPMI_CC_OK;
+ }
+
++static constexpr uint8_t setComplete = 0x0;
++static constexpr uint8_t setInProgress = 0x1;
++static uint8_t transferStatus = setComplete;
++
+ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ ipmi_request_t request,
+ ipmi_response_t response,
+@@ -1365,11 +1369,21 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ get_sys_boot_options_t* reqptr = (get_sys_boot_options_t*)request;
+ IpmiValue bootOption = ipmiDefault;
+
++ if (reqptr->parameter ==
++ static_cast<uint8_t>(BootOptionParameter::SET_IN_PROGRESS))
++ {
++ *data_len =
++ static_cast<uint8_t>(BootOptionResponseSize::SET_IN_PROGRESS);
++ resp->version = SET_PARM_VERSION;
++ resp->parm = static_cast<uint8_t>(BootOptionParameter::SET_IN_PROGRESS);
++ resp->data[0] = transferStatus;
++ return IPMI_CC_OK;
++ }
++
+ std::memset(resp, 0, sizeof(*resp));
+ resp->version = SET_PARM_VERSION;
+ resp->parm = 5;
+ resp->data[0] = SET_PARM_BOOT_FLAGS_VALID_ONE_TIME;
+-
+ /*
+ * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
+ * This is the only parameter used by petitboot.
+@@ -1505,6 +1519,16 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ // This IPMI command does not have any resposne data
+ *data_len = 0;
+
++ if (reqptr->parameter ==
++ static_cast<uint8_t>(BootOptionParameter::SET_IN_PROGRESS))
++ {
++ if (transferStatus == setInProgress) {
++ return IPMI_CC_FAIL_SET_IN_PROGRESS;
++ }
++ transferStatus = reqptr->data[0];
++ return IPMI_CC_OK;
++ }
++
+ /* 000101
+ * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
+ * This is the only parameter used by petitboot.
+diff --git a/chassishandler.hpp b/chassishandler.hpp
+index 2c42b11..6a24507 100644
+--- a/chassishandler.hpp
++++ b/chassishandler.hpp
+@@ -28,6 +28,7 @@ enum ipmi_chassis_return_codes
+ {
+ IPMI_OK = 0x0,
+ IPMI_CC_PARM_NOT_SUPPORTED = 0x80,
++ IPMI_CC_FAIL_SET_IN_PROGRESS = 0x81,
+ };
+
+ // Generic completion codes,
+@@ -49,6 +50,7 @@ enum ipmi_chassis_control_cmds : uint8_t
+ };
+ enum class BootOptionParameter : size_t
+ {
++ SET_IN_PROGRESS = 0x0,
+ BOOT_INFO = 0x4,
+ BOOT_FLAGS = 0x5,
+ OPAL_NETWORK_SETTINGS = 0x61
+@@ -56,6 +58,7 @@ enum class BootOptionParameter : size_t
+
+ enum class BootOptionResponseSize : size_t
+ {
++ SET_IN_PROGRESS = 3,
+ BOOT_FLAGS = 5,
+ OPAL_NETWORK_SETTINGS = 50
+ };
+--
+2.16.2
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0057-Add-timer-use-actions-support.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0057-Add-timer-use-actions-support.patch
new file mode 100644
index 000000000..a96707d44
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0057-Add-timer-use-actions-support.patch
@@ -0,0 +1,195 @@
+From 6e37e02a4f200507627a82f6dba00a9c9d877cb2 Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Mon, 18 Mar 2019 23:05:16 +0800
+Subject: [PATCH] Add timer use/actions support
+
+Based on IPMI spec, add timer use/actions support,
+and add input data checking
+
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ app/watchdog.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++-----
+ app/watchdog_service.cpp | 8 +++++++
+ app/watchdog_service.hpp | 8 +++++++
+ 3 files changed, 72 insertions(+), 6 deletions(-)
+
+diff --git a/app/watchdog.cpp b/app/watchdog.cpp
+index 1a5d19c..3b61055 100644
+--- a/app/watchdog.cpp
++++ b/app/watchdog.cpp
+@@ -89,6 +89,13 @@ static constexpr uint8_t wd_dont_stop = 0x1 << 6;
+ static constexpr uint8_t wd_timeout_action_mask = 0x3;
+
+ static constexpr uint8_t wdTimerUseMask = 0x7;
++static constexpr uint8_t wdTimerUseResTimer1 = 0x0;
++static constexpr uint8_t wdTimerUseResTimer2 = 0x6;
++static constexpr uint8_t wdTimerUseResTimer3 = 0x7;
++static constexpr uint8_t wdTimerUseRes = 0x38;
++
++static constexpr uint8_t wdTimerActionMask = 0xcc;
++static constexpr uint8_t wdTimerUseExpMask = 0xc1;
+
+ enum class IpmiAction : uint8_t
+ {
+@@ -186,6 +193,11 @@ static_assert(sizeof(wd_set_req) == 6, "wd_set_req has invalid size.");
+ static_assert(sizeof(wd_set_req) <= MAX_IPMI_BUFFER,
+ "wd_get_res can't fit in request buffer.");
+
++static uint8_t timerLogFlags = 0;
++static uint8_t timerActions = 0;
++
++static uint8_t timerUseExpirationFlags = 0;
++
+ ipmi_ret_t ipmi_app_watchdog_set(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ ipmi_request_t request,
+ ipmi_response_t response,
+@@ -203,6 +215,24 @@ ipmi_ret_t ipmi_app_watchdog_set(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ req.initial_countdown = le16toh(req.initial_countdown);
+ *data_len = 0;
+
++ if (((req.timer_use & wdTimerUseMask) == wdTimerUseResTimer1) ||
++ ((req.timer_use & wdTimerUseMask) == wdTimerUseResTimer2) ||
++ ((req.timer_use & wdTimerUseMask) == wdTimerUseResTimer3) ||
++ (req.timer_use & wdTimerUseRes) ||
++ (req.timer_action & wdTimerActionMask) ||
++ (req.expire_flags & wdTimerUseExpMask))
++ {
++ return IPMI_CC_INVALID_FIELD_REQUEST;
++ }
++
++ if (req.pretimeout > (req.initial_countdown / 10))
++ {
++ return IPMI_CC_INVALID_FIELD_REQUEST;
++ }
++
++ timerLogFlags = req.timer_use & 0x80;
++ timerActions = req.timer_action;
++
+ try
+ {
+ WatchdogService wd_service;
+@@ -221,6 +251,10 @@ ipmi_ret_t ipmi_app_watchdog_set(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ static_cast<IpmiTimerUse>(req.timer_use & wdTimerUseMask);
+ wd_service.setTimerUse(ipmiTimerUseToWdTimerUse(ipmiTimerUse));
+
++ wd_service.setExpiredTimerUse(WatchdogService::TimerUse::Reserved);
++
++ timerUseExpirationFlags &= ~req.expire_flags;
++
+ // Set the new interval and the time remaining deci -> mill seconds
+ const uint64_t interval = req.initial_countdown * 100;
+ wd_service.setInterval(interval);
+@@ -339,7 +373,6 @@ static_assert(sizeof(wd_get_res) == 8, "wd_get_res has invalid size.");
+ static_assert(sizeof(wd_get_res) <= MAX_IPMI_BUFFER,
+ "wd_get_res can't fit in response buffer.");
+
+-static constexpr uint8_t wd_dont_log = 0x1 << 7;
+ static constexpr uint8_t wd_running = 0x1 << 6;
+
+ ipmi_ret_t ipmi_app_watchdog_get(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+@@ -358,20 +391,37 @@ ipmi_ret_t ipmi_app_watchdog_get(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+
+ // Build and return the response
+ wd_get_res res;
+- res.timer_use = wd_dont_log;
+- res.timer_action =
+- static_cast<uint8_t>(wdActionToIpmiAction(wd_prop.expireAction));
++ res.timer_use |= timerLogFlags;
++ res.timer_action = timerActions;
+
+ // Interval and timeRemaining need converted from milli -> deci seconds
+ res.initial_countdown = htole16(wd_prop.interval / 100);
++
++ if (wd_prop.expiredTimerUse != WatchdogService::TimerUse::Reserved)
++ {
++ timerUseExpirationFlags |=
++ 1 << static_cast<uint8_t>(
++ wdTimerUseToIpmiTimerUse(wd_prop.expiredTimerUse));
++ }
++
+ if (wd_prop.enabled)
+ {
+ res.timer_use |= wd_running;
+ res.present_countdown = htole16(wd_prop.timeRemaining / 100);
++ res.expire_flags = 0;
+ }
+ else
+ {
+- res.present_countdown = res.initial_countdown;
++ if (wd_prop.expiredTimerUse == WatchdogService::TimerUse::Reserved)
++ {
++ res.present_countdown = res.initial_countdown;
++ res.expire_flags = 0;
++ }
++ else
++ {
++ res.present_countdown = 0;
++ res.expire_flags = timerUseExpirationFlags;
++ }
+ }
+
+ res.timer_use |=
+@@ -379,7 +429,7 @@ ipmi_ret_t ipmi_app_watchdog_get(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+
+ // TODO: Do something about having pretimeout support
+ res.pretimeout = 0;
+- res.expire_flags = 0;
++
+ memcpy(response, &res, sizeof(res));
+ *data_len = sizeof(res);
+ lastCallSuccessful = true;
+diff --git a/app/watchdog_service.cpp b/app/watchdog_service.cpp
+index e65ea63..8b1aa47 100644
+--- a/app/watchdog_service.cpp
++++ b/app/watchdog_service.cpp
+@@ -83,6 +83,9 @@ WatchdogService::Properties WatchdogService::getProperties()
+ wd_prop.timerUse = Watchdog::convertTimerUseFromString(
+ std::get<std::string>(properties.at("CurrentTimerUse")));
+
++ wd_prop.expiredTimerUse = Watchdog::convertTimerUseFromString(
++ std::get<std::string>(properties.at("ExpiredTimerUse")));
++
+ wd_prop.interval = std::get<uint64_t>(properties.at("Interval"));
+ wd_prop.timeRemaining =
+ std::get<uint64_t>(properties.at("TimeRemaining"));
+@@ -187,6 +190,11 @@ void WatchdogService::setTimerUse(TimerUse timerUse)
+ setProperty("CurrentTimerUse", convertForMessage(timerUse));
+ }
+
++void WatchdogService::setExpiredTimerUse(TimerUse timerUse)
++{
++ setProperty("ExpiredTimerUse", convertForMessage(timerUse));
++}
++
+ void WatchdogService::setInterval(uint64_t interval)
+ {
+ setProperty("Interval", interval);
+diff --git a/app/watchdog_service.hpp b/app/watchdog_service.hpp
+index 75afc1e..d0cc1a8 100644
+--- a/app/watchdog_service.hpp
++++ b/app/watchdog_service.hpp
+@@ -36,6 +36,7 @@ class WatchdogService
+ bool enabled;
+ Action expireAction;
+ TimerUse timerUse;
++ TimerUse expiredTimerUse;
+ uint64_t interval;
+ uint64_t timeRemaining;
+ };
+@@ -79,6 +80,13 @@ class WatchdogService
+ */
+ void setTimerUse(TimerUse timerUse);
+
++ /** @brief Sets the value of the ExpiredTimerUse property on the host
++ * watchdog
++ *
++ * @param[in] timerUse - The new timerUse value
++ */
++ void setExpiredTimerUse(TimerUse timerUse);
++
+ /** @brief Sets the value of the interval property on the host watchdog
+ *
+ * @param[in] interval - The new interval value
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0058-Add-AC-failed-bit-support-for-get-chassis-status-com.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0058-Add-AC-failed-bit-support-for-get-chassis-status-com.patch
new file mode 100644
index 000000000..42bb682c4
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0058-Add-AC-failed-bit-support-for-get-chassis-status-com.patch
@@ -0,0 +1,76 @@
+From f51bef8f7c5785405ee5c83a921efb1bc05e4947 Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Wed, 27 Mar 2019 16:11:25 +0800
+Subject: [PATCH] =?UTF-8?q?Add=20=E2=80=9CAC=20failed=E2=80=9D=20bit=20sup?=
+ =?UTF-8?q?port=20for=20get=20chassis=20status=20command?=
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+PFail property is provided by power control service,
+ture means the booting is from AC loss.
+
+Tested:
+Remove the AC cable and reconnect it
+Ipmitool chassis status to check the status:
+Last Power Event : ac-failed
+
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ chassishandler.cpp | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/chassishandler.cpp b/chassishandler.cpp
+index 7a522ad..40d2018 100644
+--- a/chassishandler.cpp
++++ b/chassishandler.cpp
+@@ -844,6 +844,7 @@ ipmi_ret_t ipmi_get_chassis_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ sd_bus_message* reply = NULL;
+ int r = 0;
+ int pgood = 0;
++ bool pFail = true;
+ char* busname = NULL;
+ ipmi_ret_t rc = IPMI_CC_OK;
+ ipmi_get_chassis_status_t chassis_status{};
+@@ -904,6 +905,26 @@ ipmi_ret_t ipmi_get_chassis_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ goto finish;
+ }
+
++ r = sd_bus_get_property(bus, busname, objname, intf, "PFail", NULL, &reply,
++ "b");
++ if (r < 0)
++ {
++ log<level::ERR>("Failed to call sd_bus_get_property",
++ entry("PROPERTY=%s", "PFail"), entry("ERRNO=0x%X", -r),
++ entry("BUS=%s", busname), entry("PATH=%s", objname),
++ entry("INTERFACE=%s", intf));
++ rc = IPMI_CC_UNSPECIFIED_ERROR;
++ goto finish;
++ }
++
++ r = sd_bus_message_read(reply, "b", &pFail);
++ if (r < 0)
++ {
++ log<level::ERR>("Failed to read PFail:", entry("ERRNO=0x%X", -r));
++ rc = IPMI_CC_UNSPECIFIED_ERROR;
++ goto finish;
++ }
++
+ s = dbusToIpmi.at(powerRestore);
+
+ // Current Power State
+@@ -952,6 +973,11 @@ ipmi_ret_t ipmi_get_chassis_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+
+ chassis_status.last_power_event = 0;
+
++ if (pFail)
++ {
++ chassis_status.last_power_event |= 1;
++ }
++
+ // Misc. Chassis State
+ // [7] – reserved
+ // [6] – 1b = Chassis Identify command and state info supported (Optional)
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0059-Move-Set-SOL-config-parameter-to-host-ipmid.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0059-Move-Set-SOL-config-parameter-to-host-ipmid.patch
new file mode 100644
index 000000000..1dc55e2f4
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0059-Move-Set-SOL-config-parameter-to-host-ipmid.patch
@@ -0,0 +1,415 @@
+From 1c15df9d82254286d0773086836767f23711c5d9 Mon Sep 17 00:00:00 2001
+From: Cheng C Yang <cheng.c.yang@intel.com>
+Date: Tue, 2 Apr 2019 00:34:34 +0800
+Subject: [PATCH] Move Set SOL config parameter to host-ipmid
+
+Move Set SOL config parameter command from net-ipmid to host-ipmid,
+so that BIOS in Intel platform can enable or disable SOL through KCS.
+Get SOL config parameter command will be moved later.
+
+Tested by:
+With the related change in phospher-ipmi-net and phospher-dbus-interface,
+Run commands:
+ipmitool raw 0x0c 0x21 0x0e 0x00 0x01
+ipmitool raw 0x0c 0x21 0x0e 0x01 0x00
+ipmitool raw 0x0c 0x21 0x0e 0x02 0x03
+ipmitool raw 0x0c 0x21 0x0e 0x03 0x5 0x03
+ipmitool raw 0x0c 0x21 0x0e 0x04 0x5 0x03
+All these commands have correct response and all dbus interface for
+sol command change to same value in above commands.
+After reboot BMC, "Progress" property in dbus interface change back
+to 0 and other properties will not reset to default value.
+
+Signed-off-by: Cheng C Yang <cheng.c.yang@intel.com>
+---
+ host-ipmid-whitelist.conf | 1 +
+ include/ipmid/api.h | 1 +
+ transporthandler.cpp | 222 ++++++++++++++++++++++++++++++++++++++
+ transporthandler.hpp | 97 +++++++++++++++++
+ 4 files changed, 321 insertions(+)
+
+diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf
+index 2a83347..544b766 100644
+--- a/host-ipmid-whitelist.conf
++++ b/host-ipmid-whitelist.conf
+@@ -41,6 +41,7 @@
+ 0x0A:0x48 //<Storage>:<Get SEL Time>
+ 0x0A:0x49 //<Storage>:<Set SEL Time>
+ 0x0C:0x02 //<Transport>:<Get LAN Configuration Parameters>
++0x0C:0x21 //<Transport>:<Set SOL Configuration Parameters>
+ 0x2C:0x00 //<Group Extension>:<Group Extension Command>
+ 0x2C:0x01 //<Group Extension>:<Get DCMI Capabilities>
+ 0x2C:0x02 //<Group Extension>:<Get Power Reading>
+diff --git a/include/ipmid/api.h b/include/ipmid/api.h
+index f08ee11..2f366b4 100644
+--- a/include/ipmid/api.h
++++ b/include/ipmid/api.h
+@@ -113,6 +113,7 @@ enum ipmi_return_codes
+ IPMI_DCMI_CC_NO_ACTIVE_POWER_LIMIT = 0x80,
+ IPMI_WDOG_CC_NOT_INIT = 0x80,
+ IPMI_CC_SYSTEM_INFO_PARAMETER_NOT_SUPPORTED = 0x80,
++ IPMI_CC_SET_IN_PROGRESS_ACTIVE = 0x81,
+ IPMI_CC_SYSTEM_INFO_PARAMETER_SET_READ_ONLY = 0x82,
+ IPMI_CC_BUSY = 0xC0,
+ IPMI_CC_INVALID = 0xC1,
+diff --git a/transporthandler.cpp b/transporthandler.cpp
+index 8f18b76..a693279 100644
+--- a/transporthandler.cpp
++++ b/transporthandler.cpp
+@@ -36,6 +36,9 @@ static const std::array<std::string, 3> ipAddressEnablesType = {
+ "xyz.openbmc_project.Network.EthernetInterface.IPAllowed.IPv6Only",
+ "xyz.openbmc_project.Network.EthernetInterface.IPAllowed.IPv4AndIPv6"};
+
++constexpr const char* solInterface = "xyz.openbmc_project.Ipmi.SOL";
++constexpr const char* solPath = "/xyz/openbmc_project/ipmi/sol";
++
+ std::map<int, std::unique_ptr<struct ChannelConfig_t>> channelConfig;
+
+ using namespace phosphor::logging;
+@@ -1633,6 +1636,219 @@ void createNetworkTimer()
+ }
+ }
+
++static int setSOLParameter(std::string property, const ipmi::Value& value)
++{
++ auto dbus = getSdBus();
++
++ static std::string solService{};
++ if (solService.empty())
++ {
++ try
++ {
++ solService = ipmi::getService(*dbus, solInterface, solPath);
++ }
++ catch (const sdbusplus::exception::SdBusError& e)
++ {
++ solService.clear();
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error: get SOL service failed");
++ return -1;
++ }
++ }
++ try
++ {
++ ipmi::setDbusProperty(*dbus, solService, solPath, solInterface,
++ property, value);
++ }
++ catch (sdbusplus::exception_t&)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error setting sol parameter");
++ return -1;
++ }
++
++ return 0;
++}
++
++static int getSOLParameter(std::string property, ipmi::Value& value)
++{
++ auto dbus = getSdBus();
++
++ static std::string solService{};
++ if (solService.empty())
++ {
++ try
++ {
++ solService = ipmi::getService(*dbus, solInterface, solPath);
++ }
++ catch (const sdbusplus::exception::SdBusError& e)
++ {
++ solService.clear();
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error: get SOL service failed");
++ return -1;
++ }
++ }
++ try
++ {
++ value = ipmi::getDbusProperty(*dbus, solService, solPath, solInterface,
++ property);
++ }
++ catch (sdbusplus::exception_t&)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error getting sol parameter");
++ return -1;
++ }
++
++ return 0;
++}
++
++void initializeSOLInProgress()
++{
++ if (setSOLParameter("Progress", static_cast<uint8_t>(0)) < 0)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error initialize sol progress");
++ }
++}
++
++ipmi_ret_t setConfParams(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
++ ipmi_request_t request, ipmi_response_t response,
++ ipmi_data_len_t dataLen, ipmi_context_t context)
++{
++ auto reqData = reinterpret_cast<const SetConfParamsRequest*>(request);
++
++ // Check request length first
++ switch (static_cast<sol::Parameter>(reqData->paramSelector))
++ {
++ case sol::Parameter::progress:
++ case sol::Parameter::enable:
++ case sol::Parameter::authentication:
++ {
++ if (*dataLen != sizeof(SetConfParamsRequest) - 1)
++ {
++ *dataLen = 0;
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++ break;
++ }
++ case sol::Parameter::accumulate:
++ case sol::Parameter::retry:
++ {
++ if (*dataLen != sizeof(SetConfParamsRequest))
++ {
++ *dataLen = 0;
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++ break;
++ }
++ default:
++ break;
++ }
++
++ *dataLen = 0;
++
++ switch (static_cast<sol::Parameter>(reqData->paramSelector))
++ {
++ case sol::Parameter::progress:
++ {
++ uint8_t progress = reqData->value & progressMask;
++ ipmi::Value currentProgress = 0;
++ if (getSOLParameter("Progress", currentProgress) < 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++
++ if ((std::get<uint8_t>(currentProgress) == 1) && (progress == 1))
++ {
++ return IPMI_CC_SET_IN_PROGRESS_ACTIVE;
++ }
++
++ if (setSOLParameter("Progress", progress) < 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ break;
++ }
++ case sol::Parameter::enable:
++ {
++ bool enable = reqData->value & enableMask;
++ if (setSOLParameter("Enable", enable) < 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ break;
++ }
++ case sol::Parameter::authentication:
++ {
++ // if encryption is used authentication must also be used.
++ if (reqData->auth.encrypt && !reqData->auth.auth)
++ {
++ return IPMI_CC_SYSTEM_INFO_PARAMETER_SET_READ_ONLY;
++ }
++ else if (reqData->auth.privilege <
++ static_cast<uint8_t>(sol::Privilege::userPriv) ||
++ reqData->auth.privilege >
++ static_cast<uint8_t>(sol::Privilege::oemPriv))
++ {
++ return IPMI_CC_INVALID_FIELD_REQUEST;
++ }
++
++ if ((setSOLParameter("Privilege", reqData->auth.privilege) < 0) ||
++ (setSOLParameter("ForceEncryption",
++ static_cast<bool>(reqData->auth.encrypt)) <
++ 0) ||
++ (setSOLParameter("ForceAuthentication",
++ static_cast<bool>(reqData->auth.auth)) < 0))
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++
++ break;
++ }
++ case sol::Parameter::accumulate:
++ {
++ if (reqData->acc.threshold == 0)
++ {
++ return IPMI_CC_INVALID_FIELD_REQUEST;
++ }
++ if (setSOLParameter("AccumulateIntervalMS", reqData->acc.interval) <
++ 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ if (setSOLParameter("Threshold", reqData->acc.threshold) < 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ break;
++ }
++ case sol::Parameter::retry:
++ {
++ if ((setSOLParameter("RetryCount", reqData->retry.count) < 0) ||
++ (setSOLParameter("RetryIntervalMS", reqData->retry.interval) <
++ 0))
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++
++ break;
++ }
++ case sol::Parameter::port:
++ {
++ return IPMI_CC_SYSTEM_INFO_PARAMETER_SET_READ_ONLY;
++ }
++ case sol::Parameter::nvbitrate:
++ case sol::Parameter::vbitrate:
++ case sol::Parameter::channel:
++ default:
++ return IPMI_CC_PARM_NOT_SUPPORTED;
++ }
++
++ return IPMI_CC_OK;
++}
++
+ void register_netfn_transport_functions()
+ {
+ // As this timer is only for transport handler
+@@ -1650,5 +1866,11 @@ void register_netfn_transport_functions()
+ ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_GET_LAN, NULL,
+ ipmi_transport_get_lan, PRIVILEGE_OPERATOR);
+
++ ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_SET_SOL_CONF_PARAMS, NULL,
++ setConfParams, PRIVILEGE_ADMIN);
++
++ // Initialize dbus property progress to 0 every time sol manager restart.
++ initializeSOLInProgress();
++
+ return;
+ }
+diff --git a/transporthandler.hpp b/transporthandler.hpp
+index bd23391..3b5e9e1 100644
+--- a/transporthandler.hpp
++++ b/transporthandler.hpp
+@@ -8,6 +8,8 @@ enum ipmi_netfn_storage_cmds
+ // Get capability bits
+ IPMI_CMD_SET_LAN = 0x01,
+ IPMI_CMD_GET_LAN = 0x02,
++ IPMI_CMD_SET_SOL_CONF_PARAMS = 0x21,
++ IPMI_CMD_GET_SOL_CONF_PARAMS = 0x22,
+ };
+
+ // Command specific completion codes
+@@ -186,3 +188,98 @@ void commitNetworkChanges();
+ * @param[in] channel: channel number.
+ */
+ void applyChanges(int channel);
++
++namespace sol
++{
++enum class Parameter
++{
++ progress, //!< Set In Progress.
++ enable, //!< SOL Enable.
++ authentication, //!< SOL Authentication.
++ accumulate, //!< Character Accumulate Interval & Send Threshold.
++ retry, //!< SOL Retry.
++ nvbitrate, //!< SOL non-volatile bit rate.
++ vbitrate, //!< SOL volatile bit rate.
++ channel, //!< SOL payload channel.
++ port, //!< SOL payload port.
++};
++
++enum class Privilege : uint8_t
++{
++ highestPriv,
++ callbackPriv,
++ userPriv,
++ operatorPriv,
++ adminPriv,
++ oemPriv,
++};
++
++} // namespace sol
++
++constexpr uint8_t progressMask = 0x03;
++constexpr uint8_t enableMask = 0x01;
++
++struct Auth
++{
++#if BYTE_ORDER == LITTLE_ENDIAN
++ uint8_t privilege : 4; //!< SOL privilege level.
++ uint8_t reserved : 2; //!< Reserved.
++ uint8_t auth : 1; //!< Force SOL payload Authentication.
++ uint8_t encrypt : 1; //!< Force SOL payload encryption.
++#endif
++
++#if BYTE_ORDER == BIG_ENDIAN
++ uint8_t encrypt : 1; //!< Force SOL payload encryption.
++ uint8_t auth : 1; //!< Force SOL payload Authentication.
++ uint8_t reserved : 2; //!< Reserved.
++ uint8_t privilege : 4; //!< SOL privilege level.
++#endif
++} __attribute__((packed));
++
++struct Accumulate
++{
++ uint8_t interval; //!< Character accumulate interval.
++ uint8_t threshold; //!< Character send threshold.
++} __attribute__((packed));
++
++struct Retry
++{
++#if BYTE_ORDER == LITTLE_ENDIAN
++ uint8_t count : 3; //!< SOL retry count.
++ uint8_t reserved : 5; //!< Reserved.
++#endif
++
++#if BYTE_ORDER == BIG_ENDIAN
++ uint8_t reserved : 5; //!< Reserved.
++ uint8_t count : 3; //!< SOL retry count.
++#endif
++
++ uint8_t interval; //!< SOL retry interval.
++} __attribute__((packed));
++
++struct SetConfParamsRequest
++{
++#if BYTE_ORDER == LITTLE_ENDIAN
++ uint8_t channelNumber : 4; //!< Channel number.
++ uint8_t reserved : 4; //!< Reserved.
++#endif
++
++#if BYTE_ORDER == BIG_ENDIAN
++ uint8_t reserved : 4; //!< Reserved.
++ uint8_t channelNumber : 4; //!< Channel number.
++#endif
++
++ uint8_t paramSelector; //!< Parameter selector.
++ union
++ {
++ uint8_t value; //!< Represents one byte SOL parameters.
++ struct Accumulate acc; //!< Character accumulate values.
++ struct Retry retry; //!< Retry values.
++ struct Auth auth; //!< Authentication parameters.
++ };
++} __attribute__((packed));
++
++struct SetConfParamsResponse
++{
++ uint8_t completionCode; //!< Completion code.
++} __attribute__((packed));
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0060-Move-Get-SOL-config-parameter-to-host-ipmid.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0060-Move-Get-SOL-config-parameter-to-host-ipmid.patch
new file mode 100644
index 000000000..24f355d80
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0060-Move-Get-SOL-config-parameter-to-host-ipmid.patch
@@ -0,0 +1,342 @@
+From 3c95de833eba73b3585941ade42ad1775e723280 Mon Sep 17 00:00:00 2001
+From: Cheng C Yang <cheng.c.yang@intel.com>
+Date: Tue, 7 May 2019 08:03:56 +0800
+Subject: [PATCH] Move Get SOL config parameter to host-ipmid
+
+Move Get SOL config parameter command from net-ipmid to host-ipmid.
+
+Tested:
+Run command ipmitool sol info
+Set in progress : set-complete
+Enabled : true
+Force Encryption : false
+Force Authentication : false
+Privilege Level : ADMINISTRATOR
+Character Accumulate Level (ms) : 60
+Character Send Threshold : 96
+Retry Count : 6
+Retry Interval (ms) : 200
+Volatile Bit Rate (kbps) : IPMI-Over-Serial-Setting
+Non-Volatile Bit Rate (kbps) : 115.2
+Payload Channel : 14 (0x0e)
+Payload Port : 623
+
+Signed-off-by: Cheng C Yang <cheng.c.yang@intel.com>
+---
+ host-ipmid-whitelist.conf | 1 +
+ transporthandler.cpp | 198 ++++++++++++++++++++++++++++++++++++++++++++--
+ transporthandler.hpp | 27 ++++++-
+ 3 files changed, 217 insertions(+), 9 deletions(-)
+
+diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf
+index 2ce44c6..383b412 100644
+--- a/host-ipmid-whitelist.conf
++++ b/host-ipmid-whitelist.conf
+@@ -43,6 +43,7 @@
+ 0x0A:0x49 //<Storage>:<Set SEL Time>
+ 0x0C:0x02 //<Transport>:<Get LAN Configuration Parameters>
+ 0x0C:0x21 //<Transport>:<Set SOL Configuration Parameters>
++0x0C:0x22 //<Transport>:<Get SOL Configuration Parameters>
+ 0x2C:0x00 //<Group Extension>:<Group Extension Command>
+ 0x2C:0x01 //<Group Extension>:<Get DCMI Capabilities>
+ 0x2C:0x02 //<Group Extension>:<Get Power Reading>
+diff --git a/transporthandler.cpp b/transporthandler.cpp
+index 850172d..0c1223a 100644
+--- a/transporthandler.cpp
++++ b/transporthandler.cpp
+@@ -38,6 +38,8 @@ static const std::array<std::string, 3> ipAddressEnablesType = {
+
+ constexpr const char* solInterface = "xyz.openbmc_project.Ipmi.SOL";
+ constexpr const char* solPath = "/xyz/openbmc_project/ipmi/sol";
++constexpr const char* consoleInterface = "xyz.openbmc_project.console";
++constexpr const char* consolePath = "/xyz/openbmc_project/console";
+
+ std::map<int, std::unique_ptr<struct ChannelConfig_t>> channelConfig;
+
+@@ -1668,6 +1670,26 @@ static int setSOLParameter(std::string property, const ipmi::Value& value)
+ return 0;
+ }
+
++static int getSOLBaudRate(ipmi::Value& value)
++{
++ auto dbus = getSdBus();
++
++ try
++ {
++ value =
++ ipmi::getDbusProperty(*dbus, "xyz.openbmc_project.console",
++ consolePath, consoleInterface, "baudrate");
++ }
++ catch (sdbusplus::exception_t&)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error getting sol baud rate");
++ return -1;
++ }
++
++ return 0;
++}
++
+ static int getSOLParameter(std::string property, ipmi::Value& value)
+ {
+ auto dbus = getSdBus();
+@@ -1711,11 +1733,170 @@ void initializeSOLInProgress()
+ }
+ }
+
+-ipmi_ret_t setConfParams(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+- ipmi_request_t request, ipmi_response_t response,
+- ipmi_data_len_t dataLen, ipmi_context_t context)
++static const constexpr uint8_t retryCountMask = 0x07;
++// For getsetSOLConfParams, there are still three tings TODO:
++// 1. session less channel number request has to return error.
++// 2. convert 0xE channel number.
++// 3. have unique object for every session based channel.
++ipmi_ret_t getSOLConfParams(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
++ ipmi_request_t request, ipmi_response_t response,
++ ipmi_data_len_t dataLen, ipmi_context_t context)
++{
++ auto reqData = reinterpret_cast<const GetSOLConfParamsRequest*>(request);
++ std::vector<uint8_t> outPayload;
++
++ if (*dataLen < sizeof(GetSOLConfParamsRequest) - 2)
++ {
++ *dataLen = 0;
++ return IPMI_CC_REQ_DATA_LEN_INVALID;
++ }
++
++ *dataLen = 0;
++
++ outPayload.push_back(solParameterRevision);
++ if (reqData->getParamRev)
++ {
++ std::copy(outPayload.begin(), outPayload.end(),
++ static_cast<uint8_t*>(response));
++ *dataLen = outPayload.size();
++ return IPMI_CC_OK;
++ }
++
++ ipmi::Value value;
++ switch (static_cast<sol::Parameter>(reqData->paramSelector))
++ {
++ case sol::Parameter::progress:
++ {
++ if (getSOLParameter("Progress", value) < 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ outPayload.push_back(std::get<uint8_t>(value));
++ break;
++ }
++ case sol::Parameter::enable:
++ {
++ if (getSOLParameter("Enable", value) < 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ outPayload.push_back(static_cast<uint8_t>(std::get<bool>(value)));
++ break;
++ }
++ case sol::Parameter::authentication:
++ {
++ uint8_t authentication = 0;
++ if (getSOLParameter("Privilege", value) < 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ authentication = (std::get<uint8_t>(value) & 0x0f);
++
++ if (getSOLParameter("ForceAuthentication", value) < 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ authentication |=
++ (static_cast<uint8_t>(std::get<bool>(value)) << 6);
++
++ if (getSOLParameter("ForceEncryption", value) < 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ authentication |=
++ (static_cast<uint8_t>(std::get<bool>(value)) << 7);
++ outPayload.push_back(authentication);
++ break;
++ }
++ case sol::Parameter::accumulate:
++ {
++ if (getSOLParameter("AccumulateIntervalMS", value) < 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ outPayload.push_back(std::get<uint8_t>(value));
++
++ if (getSOLParameter("Threshold", value) < 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ outPayload.push_back(std::get<uint8_t>(value));
++ break;
++ }
++ case sol::Parameter::retry:
++ {
++ if (getSOLParameter("RetryCount", value) < 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ outPayload.push_back(std::get<uint8_t>(value) & retryCountMask);
++
++ if (getSOLParameter("RetryIntervalMS", value) < 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ outPayload.push_back(std::get<uint8_t>(value));
++ break;
++ }
++ case sol::Parameter::port:
++ {
++ uint16_t port = htole16(ipmiStdPort);
++ auto buffer = reinterpret_cast<const uint8_t*>(&port);
++ std::copy(buffer, buffer + sizeof(port),
++ std::back_inserter(outPayload));
++ break;
++ }
++ case sol::Parameter::nvbitrate:
++ {
++ if (getSOLBaudRate(value) < 0)
++ {
++ return IPMI_CC_UNSPECIFIED_ERROR;
++ }
++ uint8_t bitRate = 0;
++ uint32_t* pBaudRate = std::get_if<uint32_t>(&value);
++ if (!pBaudRate)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Failed to get valid baud rate from D-Bus interface");
++ }
++ switch (*pBaudRate)
++ {
++ case 9600:
++ bitRate = 0x06;
++ break;
++ case 19200:
++ bitRate = 0x07;
++ break;
++ case 38400:
++ bitRate = 0x08;
++ break;
++ case 57600:
++ bitRate = 0x09;
++ break;
++ case 115200:
++ bitRate = 0x0a;
++ break;
++ default:
++ break;
++ }
++ outPayload.push_back(bitRate);
++ break;
++ }
++ default:
++ return IPMI_CC_PARM_NOT_SUPPORTED;
++ }
++ std::copy(outPayload.begin(), outPayload.end(),
++ static_cast<uint8_t*>(response));
++ *dataLen = outPayload.size();
++
++ return IPMI_CC_OK;
++}
++
++ipmi_ret_t setSOLConfParams(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
++ ipmi_request_t request, ipmi_response_t response,
++ ipmi_data_len_t dataLen, ipmi_context_t context)
+ {
+- auto reqData = reinterpret_cast<const SetConfParamsRequest*>(request);
++ auto reqData = reinterpret_cast<const SetSOLConfParamsRequest*>(request);
+
+ // Check request length first
+ switch (static_cast<sol::Parameter>(reqData->paramSelector))
+@@ -1724,7 +1905,7 @@ ipmi_ret_t setConfParams(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ case sol::Parameter::enable:
+ case sol::Parameter::authentication:
+ {
+- if (*dataLen != sizeof(SetConfParamsRequest) - 1)
++ if (*dataLen != sizeof(SetSOLConfParamsRequest) - 1)
+ {
+ *dataLen = 0;
+ return IPMI_CC_REQ_DATA_LEN_INVALID;
+@@ -1734,7 +1915,7 @@ ipmi_ret_t setConfParams(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ case sol::Parameter::accumulate:
+ case sol::Parameter::retry:
+ {
+- if (*dataLen != sizeof(SetConfParamsRequest))
++ if (*dataLen != sizeof(SetSOLConfParamsRequest))
+ {
+ *dataLen = 0;
+ return IPMI_CC_REQ_DATA_LEN_INVALID;
+@@ -1865,7 +2046,10 @@ void register_netfn_transport_functions()
+ ipmi_transport_get_lan, PRIVILEGE_OPERATOR);
+
+ ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_SET_SOL_CONF_PARAMS, NULL,
+- setConfParams, PRIVILEGE_ADMIN);
++ setSOLConfParams, PRIVILEGE_ADMIN);
++
++ ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_GET_SOL_CONF_PARAMS, NULL,
++ getSOLConfParams, PRIVILEGE_ADMIN);
+
+ // Initialize dbus property progress to 0 every time sol manager restart.
+ initializeSOLInProgress();
+diff --git a/transporthandler.hpp b/transporthandler.hpp
+index 3b5e9e1..a21862b 100644
+--- a/transporthandler.hpp
++++ b/transporthandler.hpp
+@@ -1,6 +1,7 @@
+ #pragma once
+
+ #include <ipmid/types.hpp>
++#include <map>
+ #include <string>
+ // IPMI commands for Transport net functions.
+ enum ipmi_netfn_storage_cmds
+@@ -257,7 +258,7 @@ struct Retry
+ uint8_t interval; //!< SOL retry interval.
+ } __attribute__((packed));
+
+-struct SetConfParamsRequest
++struct SetSOLConfParamsRequest
+ {
+ #if BYTE_ORDER == LITTLE_ENDIAN
+ uint8_t channelNumber : 4; //!< Channel number.
+@@ -279,7 +280,29 @@ struct SetConfParamsRequest
+ };
+ } __attribute__((packed));
+
+-struct SetConfParamsResponse
++struct SetSOLConfParamsResponse
+ {
+ uint8_t completionCode; //!< Completion code.
+ } __attribute__((packed));
++
++struct GetSOLConfParamsRequest
++{
++#if BYTE_ORDER == LITTLE_ENDIAN
++ uint8_t channelNum : 4; //!< Channel number.
++ uint8_t reserved : 3; //!< Reserved.
++ uint8_t getParamRev : 1; //!< Get parameter or Get parameter revision
++#endif
++
++#if BYTE_ORDER == BIG_ENDIAN
++ uint8_t getParamRev : 1; //!< Get parameter or Get parameter revision
++ uint8_t reserved : 3; //!< Reserved.
++ uint8_t channelNum : 4; //!< Channel number.
++#endif
++
++ uint8_t paramSelector; //!< Parameter selector.
++ uint8_t setSelector; //!< Set selector.
++ uint8_t blockSelector; //!< Block selector.
++} __attribute__((packed));
++
++static constexpr uint16_t ipmiStdPort = 623;
++static constexpr uint8_t solParameterRevision = 0x11;
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0061-Use-xyz.openbmc_project.State.Chassis-for-IPMI-chass.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0061-Use-xyz.openbmc_project.State.Chassis-for-IPMI-chass.patch
new file mode 100644
index 000000000..877c5336a
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0061-Use-xyz.openbmc_project.State.Chassis-for-IPMI-chass.patch
@@ -0,0 +1,127 @@
+From 514b76d1c05d7ed7fb7e1df27833e423e04c9a1c Mon Sep 17 00:00:00 2001
+From: "Jason M. Bills" <jason.m.bills@linux.intel.com>
+Date: Tue, 21 May 2019 09:57:16 -0700
+Subject: [PATCH] Use xyz.openbmc_project.State.Chassis for IPMI chassis status
+
+Instead of directly using pgood on dbus, this change uses the
+xyz.openbmc_project.State.Chassis "CurrentPowerState" property
+for the IPMI chassis status command. This will allow us to
+remove pgood from dbus.
+
+Tested:
+Ran IPMI chassis commands and confirmed that they behave as
+expected:
+ipmitool power status
+Chassis Power is on
+
+ipmitool power off
+Chassis Power Control: Down/Off
+
+ipmitool power status
+Chassis Power is off
+
+ipmitool power on
+Chassis Power Control: Up/On
+
+ipmitool power status
+Chassis Power is on
+
+Change-Id: I7836c16b76c3b309f176186f3e2453082e4cd1af
+Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
+---
+ chassishandler.cpp | 61 ++++++++++++++++++++++++++++++++++++------------------
+ 1 file changed, 41 insertions(+), 20 deletions(-)
+
+diff --git a/chassishandler.cpp b/chassishandler.cpp
+index 1738ccc..e4e842d 100644
+--- a/chassishandler.cpp
++++ b/chassishandler.cpp
+@@ -824,44 +824,65 @@ std::optional<uint2_t> getPowerRestorePolicy()
+ */
+ std::optional<bool> getPowerStatus()
+ {
+- constexpr const char* powerControlObj =
+- "/xyz/openbmc_project/Chassis/Control/Power0";
+- constexpr const char* powerControlIntf =
+- "xyz.openbmc_project.Chassis.Control.Power";
+ bool powerGood = false;
+ std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
+ try
+ {
++ constexpr const char* chassisStatePath =
++ "/xyz/openbmc_project/state/chassis0";
++ constexpr const char* chassisStateIntf =
++ "xyz.openbmc_project.State.Chassis";
+ auto service =
+- ipmi::getService(*busp, powerControlIntf, powerControlObj);
++ ipmi::getService(*busp, chassisStateIntf, chassisStatePath);
+
+- ipmi::Value variant = ipmi::getDbusProperty(
+- *busp, service, powerControlObj, powerControlIntf, "pgood");
+- powerGood = static_cast<bool>(std::get<int>(variant));
++ ipmi::Value variant =
++ ipmi::getDbusProperty(*busp, service, chassisStatePath,
++ chassisStateIntf, "CurrentPowerState");
++ std::string powerState = std::get<std::string>(variant);
++ if (powerState == "xyz.openbmc_project.State.Chassis.PowerState.On")
++ {
++ powerGood = true;
++ }
+ }
+ catch (const std::exception& e)
+ {
+ try
+ {
+- // FIXME: some legacy modules use the older path; try that next
+- constexpr const char* legacyPwrCtrlObj =
+- "/org/openbmc/control/power0";
+- constexpr const char* legacyPwrCtrlIntf =
+- "org.openbmc.control.Power";
++ // FIXME: some modules use pgood; try that next
++ constexpr const char* powerControlObj =
++ "/xyz/openbmc_project/Chassis/Control/Power0";
++ constexpr const char* powerControlIntf =
++ "xyz.openbmc_project.Chassis.Control.Power";
+ auto service =
+- ipmi::getService(*busp, legacyPwrCtrlIntf, legacyPwrCtrlObj);
++ ipmi::getService(*busp, powerControlIntf, powerControlObj);
+
+ ipmi::Value variant = ipmi::getDbusProperty(
+- *busp, service, legacyPwrCtrlObj, legacyPwrCtrlIntf, "pgood");
++ *busp, service, powerControlObj, powerControlIntf, "pgood");
+ powerGood = static_cast<bool>(std::get<int>(variant));
+ }
+ catch (const std::exception& e)
+ {
+- log<level::ERR>("Failed to fetch pgood property",
+- entry("ERROR=%s", e.what()),
+- entry("PATH=%s", powerControlObj),
+- entry("INTERFACE=%s", powerControlIntf));
+- return std::nullopt;
++ try
++ {
++ // FIXME: some legacy modules use the older path; try that next
++ constexpr const char* legacyPwrCtrlObj =
++ "/org/openbmc/control/power0";
++ constexpr const char* legacyPwrCtrlIntf =
++ "org.openbmc.control.Power";
++ auto service = ipmi::getService(*busp, legacyPwrCtrlIntf,
++ legacyPwrCtrlObj);
++
++ ipmi::Value variant =
++ ipmi::getDbusProperty(*busp, service, legacyPwrCtrlObj,
++ legacyPwrCtrlIntf, "pgood");
++ powerGood = static_cast<bool>(std::get<int>(variant));
++ }
++ catch (const std::exception& e)
++ {
++ log<level::ERR>("Failed to fetch pgood property",
++ entry("ERROR=%s", e.what()));
++ return std::nullopt;
++ }
+ }
+ }
+ return std::make_optional(powerGood);
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0062-Update-IPMI-Chassis-Control-command.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0062-Update-IPMI-Chassis-Control-command.patch
new file mode 100644
index 000000000..498233881
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0062-Update-IPMI-Chassis-Control-command.patch
@@ -0,0 +1,214 @@
+From f11928c6b39052c679c9300e9d836837ef60be06 Mon Sep 17 00:00:00 2001
+From: "Jason M. Bills" <jason.m.bills@linux.intel.com>
+Date: Mon, 3 Jun 2019 17:01:47 -0700
+Subject: [PATCH] Update IPMI Chassis Control command
+
+This change updates the IPMI Chassis Control command to use the new
+chassis state transitions. This allows each chassis control action
+to more closely follow the behavior defined in the IPMI spec.
+
+Tested:
+Ran each IPMI chassis control command to confirm the expected
+behavior:
+ipmitool power on: system is powered-on
+ipmitool power off: system is forced off
+ipmitool power cycle: system is forced off then powered-on
+ipmitool power reset: system is hard reset
+ipmitool power soft: soft power-off requested from system software
+
+Change-Id: Ic9fba3ca4abd9a758eb88f1e6ee09f7ca64ff80a
+Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
+---
+ chassishandler.cpp | 138 +++++++++++++++++++++--------------------------------
+ 1 file changed, 54 insertions(+), 84 deletions(-)
+
+diff --git a/chassishandler.cpp b/chassishandler.cpp
+index e4e842d..d71b95f 100644
+--- a/chassishandler.cpp
++++ b/chassishandler.cpp
+@@ -31,6 +31,7 @@
+ #include <xyz/openbmc_project/Control/Boot/Mode/server.hpp>
+ #include <xyz/openbmc_project/Control/Boot/Source/server.hpp>
+ #include <xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp>
++#include <xyz/openbmc_project/State/Chassis/server.hpp>
+ #include <xyz/openbmc_project/State/Host/server.hpp>
+ #include <xyz/openbmc_project/State/PowerOnHours/server.hpp>
+
+@@ -712,59 +713,63 @@ ipmi_ret_t ipmi_set_chassis_cap(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ //------------------------------------------
+ // Calls into Host State Manager Dbus object
+ //------------------------------------------
+-int initiate_state_transition(State::Host::Transition transition)
++int initiateHostStateTransition(State::Host::Transition transition)
+ {
+ // OpenBMC Host State Manager dbus framework
+- constexpr auto HOST_STATE_MANAGER_ROOT = "/xyz/openbmc_project/state/host0";
+- constexpr auto HOST_STATE_MANAGER_IFACE = "xyz.openbmc_project.State.Host";
+- constexpr auto DBUS_PROPERTY_IFACE = "org.freedesktop.DBus.Properties";
+- constexpr auto PROPERTY = "RequestedHostTransition";
++ constexpr auto hostStatePath = "/xyz/openbmc_project/state/host0";
++ constexpr auto hostStateIntf = "xyz.openbmc_project.State.Host";
+
+- // sd_bus error
+- int rc = 0;
+- char* busname = NULL;
++ auto service = ipmi::getService(*getSdBus(), hostStateIntf, hostStatePath);
+
+- // SD Bus error report mechanism.
+- sd_bus_error bus_error = SD_BUS_ERROR_NULL;
++ // Convert to string equivalent of the passed in transition enum.
++ auto request = State::convertForMessage(transition);
+
+- // Gets a hook onto either a SYSTEM or SESSION bus
+- sd_bus* bus_type = ipmid_get_sd_bus_connection();
+- rc = mapper_get_service(bus_type, HOST_STATE_MANAGER_ROOT, &busname);
+- if (rc < 0)
++ try
++ {
++ ipmi::setDbusProperty(*getSdBus(), service, hostStatePath,
++ hostStateIntf, "RequestedHostTransition",
++ request);
++ }
++ catch (std::exception& e)
+ {
+ log<level::ERR>(
+- "Failed to get bus name",
+- entry("ERRNO=0x%X, OBJPATH=%s", -rc, HOST_STATE_MANAGER_ROOT));
+- return rc;
++ "Failed to initiate transition",
++ entry("EXCEPTION=%s, REQUEST=%s", e.what(), request.c_str()));
++ return -1;
+ }
++ return 0;
++}
++
++//------------------------------------------
++// Calls into Chassis State Manager Dbus object
++//------------------------------------------
++int initiateChassisStateTransition(State::Chassis::Transition transition)
++{
++ // OpenBMC Chassis State Manager dbus framework
++ constexpr auto chassisStatePath = "/xyz/openbmc_project/state/chassis0";
++ constexpr auto chassisStateIntf = "xyz.openbmc_project.State.Chassis";
++
++ auto service =
++ ipmi::getService(*getSdBus(), chassisStateIntf, chassisStatePath);
+
+ // Convert to string equivalent of the passed in transition enum.
+ auto request = State::convertForMessage(transition);
+
+- rc = sd_bus_call_method(bus_type, // On the system bus
+- busname, // Service to contact
+- HOST_STATE_MANAGER_ROOT, // Object path
+- DBUS_PROPERTY_IFACE, // Interface name
+- "Set", // Method to be called
+- &bus_error, // object to return error
+- nullptr, // Response buffer if any
+- "ssv", // Takes 3 arguments
+- HOST_STATE_MANAGER_IFACE, PROPERTY, "s",
+- request.c_str());
+- if (rc < 0)
++ try
+ {
+- log<level::ERR>("Failed to initiate transition",
+- entry("ERRNO=0x%X, REQUEST=%s", -rc, request.c_str()));
++ ipmi::setDbusProperty(*getSdBus(), service, chassisStatePath,
++ chassisStateIntf, "RequestedPowerTransition",
++ request);
+ }
+- else
++ catch (std::exception& e)
+ {
+- log<level::INFO>("Transition request initiated successfully");
++ log<level::ERR>(
++ "Failed to initiate transition",
++ entry("EXCEPTION=%s, REQUEST=%s", e.what(), request.c_str()));
++ return -1;
+ }
+
+- sd_bus_error_free(&bus_error);
+- free(busname);
+-
+- return rc;
++ return 0;
+ }
+
+ namespace power_policy
+@@ -1138,61 +1143,26 @@ ipmi::RspType<> ipmiChassisControl(uint8_t chassisControl)
+ switch (chassisControl)
+ {
+ case CMD_POWER_ON:
+- rc = initiate_state_transition(State::Host::Transition::On);
++ rc = initiateHostStateTransition(State::Host::Transition::On);
+ break;
+ case CMD_POWER_OFF:
+- // This path would be hit in 2 conditions.
+- // 1: When user asks for power off using ipmi chassis command 0x04
+- // 2: Host asking for power off post shutting down.
+-
+- // If it's a host requested power off, then need to nudge Softoff
+- // application that it needs to stop the watchdog timer if running.
+- // If it is a user requested power off, then this is not really
+- // needed. But then we need to differentiate between user and host
+- // calling this same command
+-
+- // For now, we are going ahead with trying to nudge the soft off and
+- // interpret the failure to do so as a non softoff case
+- rc = stop_soft_off_timer();
+-
+- // Only request the Off transition if the soft power off
+- // application is not running
+- if (rc < 0)
+- {
+- // First create a file to indicate to the soft off application
+- // that it should not run. Not doing this will result in State
+- // manager doing a default soft power off when asked for power
+- // off.
+- indicate_no_softoff_needed();
+-
+- // Now request the shutdown
+- rc = initiate_state_transition(State::Host::Transition::Off);
+- }
+- else
+- {
+- log<level::INFO>("Soft off is running, so let shutdown target "
+- "stop the host");
+- }
++ rc =
++ initiateChassisStateTransition(State::Chassis::Transition::Off);
+ break;
+-
+ case CMD_HARD_RESET:
++ rc = initiateChassisStateTransition(
++ State::Chassis::Transition::Reset);
++ break;
+ case CMD_POWER_CYCLE:
+- // SPEC has a section that says certain implementations can trigger
+- // PowerOn if power is Off when a command to power cycle is
+- // requested
+-
+- // First create a file to indicate to the soft off application
+- // that it should not run since this is a direct user initiated
+- // power reboot request (i.e. a reboot request that is not
+- // originating via a soft power off SMS request)
+- indicate_no_softoff_needed();
+-
+- rc = initiate_state_transition(State::Host::Transition::Reboot);
++ rc = initiateChassisStateTransition(
++ State::Chassis::Transition::PowerCycle);
+ break;
+-
+ case CMD_SOFT_OFF_VIA_OVER_TEMP:
+- // Request Host State Manager to do a soft power off
+- rc = initiate_state_transition(State::Host::Transition::Off);
++ rc = initiateHostStateTransition(State::Host::Transition::Off);
++ break;
++ case CMD_PULSE_DIAGNOSTIC_INTR:
++ rc =
++ initiateHostStateTransition(State::Host::Transition::Interrupt);
+ break;
+
+ default:
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch
new file mode 100644
index 000000000..685e7c39d
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch
@@ -0,0 +1,140 @@
+From d9c89943d7b0aa00ee99b7c11278ac272a47a790 Mon Sep 17 00:00:00 2001
+From: Ren Yu <yux.ren@intel.com>
+Date: Tue, 28 May 2019 17:11:17 +0800
+Subject: [PATCH] Save the pre-timeout interrupt in dbus property
+
+Get the watchdog pre-timeout interrupt value from ipmi watchdog set command,
+and store it into dbus property.
+
+Tested:
+Config IPMI watchdog: BIOS FRB2 Power Cycle after 1 seconds:
+ipmitool raw 0x06 0x24 0x01 0x13 0x0 0x2 0xa 0x00
+Start watchdog:
+Ipmitool mc watchdog reset
+Check the watchdog pre-timeout interrupt in below:
+https://BMCIP/redfish/v1/Systems/system/LogServices/EventLog/Entries
+
+Signed-off-by: Ren Yu <yux.ren@intel.com>
+---
+ app/watchdog.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++
+ app/watchdog_service.cpp | 6 ++++++
+ app/watchdog_service.hpp | 9 +++++++++
+ 3 files changed, 62 insertions(+)
+
+diff --git a/app/watchdog.cpp b/app/watchdog.cpp
+index 2ffaae3..e9b7a9c 100644
+--- a/app/watchdog.cpp
++++ b/app/watchdog.cpp
+@@ -81,6 +81,7 @@ ipmi::RspType<> ipmiAppResetWatchdogTimer()
+
+ static constexpr uint8_t wd_dont_stop = 0x1 << 6;
+ static constexpr uint8_t wd_timeout_action_mask = 0x3;
++static constexpr uint8_t wdPreTimeoutInterruptMask = 0x3;
+
+ static constexpr uint8_t wdTimerUseMask = 0x7;
+ static constexpr uint8_t wdTimerUseResTimer1 = 0x0;
+@@ -130,6 +131,45 @@ WatchdogService::Action ipmiActionToWdAction(IpmiAction ipmi_action)
+ }
+ }
+
++enum class IpmiPreTimeoutInterrupt : uint8_t
++{
++ None = 0x0,
++ SMI = 0x1,
++ NMI = 0x2,
++ MI = 0x3,
++};
++/** @brief Converts an IPMI Watchdog PreTimeoutInterrupt to DBUS defined action
++ * @param[in] ipmi_action The IPMI Watchdog PreTimeoutInterrupt
++ * @return The Watchdog PreTimeoutInterrupt that the ipmi_action maps to
++ */
++WatchdogService::PreTimeoutInterruptAction ipmiPreTimeoutInterruptToWdAction(
++ IpmiPreTimeoutInterrupt ipmiPreTimeOutInterrupt)
++{
++ switch (ipmiPreTimeOutInterrupt)
++ {
++ case IpmiPreTimeoutInterrupt::None:
++ {
++ return WatchdogService::PreTimeoutInterruptAction::None;
++ }
++ case IpmiPreTimeoutInterrupt::SMI:
++ {
++ return WatchdogService::PreTimeoutInterruptAction::SMI;
++ }
++ case IpmiPreTimeoutInterrupt::NMI:
++ {
++ return WatchdogService::PreTimeoutInterruptAction::NMI;
++ }
++ case IpmiPreTimeoutInterrupt::MI:
++ {
++ return WatchdogService::PreTimeoutInterruptAction::MI;
++ }
++ default:
++ {
++ throw std::domain_error("IPMI PreTimeoutInterrupt is invalid");
++ }
++ }
++}
++
+ enum class IpmiTimerUse : uint8_t
+ {
+ Reserved = 0x0,
+@@ -257,6 +297,13 @@ ipmi_ret_t ipmi_app_watchdog_set(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ // Mark as initialized so that future resets behave correctly
+ wd_service.setInitialized(true);
+
++ // pretimeOutAction
++ const auto ipmiPreTimeoutInterrupt =
++ static_cast<IpmiPreTimeoutInterrupt>((req.timer_action >> 4) &
++ wdPreTimeoutInterruptMask);
++ wd_service.setPreTimeoutInterrupt(
++ ipmiPreTimeoutInterruptToWdAction(ipmiPreTimeoutInterrupt));
++
+ lastCallSuccessful = true;
+ return IPMI_CC_OK;
+ }
+diff --git a/app/watchdog_service.cpp b/app/watchdog_service.cpp
+index 77663b4..0c4ea28 100644
+--- a/app/watchdog_service.cpp
++++ b/app/watchdog_service.cpp
+@@ -203,3 +203,9 @@ void WatchdogService::setTimeRemaining(uint64_t timeRemaining)
+ {
+ setProperty("TimeRemaining", timeRemaining);
+ }
++
++void WatchdogService::setPreTimeoutInterrupt(
++ PreTimeoutInterruptAction preTimeoutInterrupt)
++{
++ setProperty("PreTimeoutInterrupt", convertForMessage(preTimeoutInterrupt));
++}
+\ No newline at end of file
+diff --git a/app/watchdog_service.hpp b/app/watchdog_service.hpp
+index ed64a3c..b550f37 100644
+--- a/app/watchdog_service.hpp
++++ b/app/watchdog_service.hpp
+@@ -15,6 +15,8 @@ class WatchdogService
+
+ using Action =
+ sdbusplus::xyz::openbmc_project::State::server::Watchdog::Action;
++ using PreTimeoutInterruptAction = sdbusplus::xyz::openbmc_project::State::
++ server::Watchdog::PreTimeoutInterruptAction;
+ using TimerUse =
+ sdbusplus::xyz::openbmc_project::State::server::Watchdog::TimerUse;
+
+@@ -99,6 +101,13 @@ class WatchdogService
+ */
+ void setTimeRemaining(uint64_t timeRemaining);
+
++ /** @brief Sets the value of the PreTimeoutInterrupt property on the host
++ * watchdog
++ *
++ * @param[in] PreTimeoutInterrupt - The new PreTimeoutInterrupt value
++ */
++ void setPreTimeoutInterrupt(PreTimeoutInterruptAction preTimeoutInterrupt);
++
+ private:
+ /** @brief sdbusplus handle */
+ sdbusplus::bus::bus bus;
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/phosphor-ipmi-host.service b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/phosphor-ipmi-host.service
new file mode 100644
index 000000000..d855eaa5b
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/phosphor-ipmi-host.service
@@ -0,0 +1,26 @@
+[Unit]
+Description=Phosphor Inband IPMI
+# TODO openbmc/openbmc#2059 - The wants/after below should be based on providers
+Wants=mapper-wait@-xyz-openbmc_project-control-host0-boot.service
+After=mapper-wait@-xyz-openbmc_project-control-host0-boot.service
+Wants=mapper-wait@-xyz-openbmc_project-control-host0-boot-one_time.service
+After=mapper-wait@-xyz-openbmc_project-control-host0-boot-one_time.service
+Wants=mapper-wait@-xyz-openbmc_project-control-host0-power_restore_policy.service
+After=mapper-wait@-xyz-openbmc_project-control-host0-power_restore_policy.service
+Wants=mapper-wait@-xyz-openbmc_project-control-host0-restriction_mode.service
+After=mapper-wait@-xyz-openbmc_project-control-host0-restriction_mode.service
+Wants=clear-once.service
+After=clear-once.service
+
+[Service]
+Restart=always
+RestartSec=5
+StartLimitBurst=10
+ExecStart=/usr/bin/env ipmid
+SyslogIdentifier=ipmid
+RuntimeDirectory = ipmi
+RuntimeDirectoryPreserve = yes
+StateDirectory = ipmi
+
+[Install]
+WantedBy={SYSTEMD_DEFAULT_TARGET}
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend
new file mode 100644
index 000000000..a6a142ec8
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend
@@ -0,0 +1,41 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+# TODO: This should be removed, once up-stream bump up
+# issue is resolved
+#SRC_URI = "git://github.com/openbmc/phosphor-host-ipmid"
+SRCREV = "0b979b61c12ffe6ab8a27acf8ad2a0165d687195"
+
+SRC_URI += "file://phosphor-ipmi-host.service \
+ file://0009-IPv6-Network-changes.patch \
+ file://0010-fix-get-system-GUID-ipmi-command.patch \
+ file://0013-ipmi-add-set-bios-id-to-whitelist.patch \
+ file://0021-Implement-IPMI-Commmand-Get-Host-Restart-Cause.patch \
+ file://0039-ipmi-add-oem-command-get-AIC-FRU-to-whitelist.patch \
+ file://0049-Fix-Unspecified-error-on-ipmi-restart-cause-command.patch \
+ file://0050-enable-6-oem-commands.patch \
+ file://0053-Fix-keep-looping-issue-when-entering-OS.patch \
+ file://0055-Implement-set-front-panel-button-enables-command.patch \
+ file://0056-add-SetInProgress-to-get-set-boot-option-cmd.patch \
+ file://0057-Add-timer-use-actions-support.patch \
+ file://0059-Move-Set-SOL-config-parameter-to-host-ipmid.patch \
+ file://0060-Move-Get-SOL-config-parameter-to-host-ipmid.patch \
+ file://0061-Use-xyz.openbmc_project.State.Chassis-for-IPMI-chass.patch \
+ file://0062-Update-IPMI-Chassis-Control-command.patch \
+ file://0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch \
+ "
+
+# remove the softpoweroff service since we do not need it
+SYSTEMD_SERVICE_${PN}_remove += " \
+ xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service"
+
+SYSTEMD_LINK_${PN}_remove += " \
+ ../xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service:obmc-host-shutdown@0.target.requires/xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service \
+ "
+FILES_${PN}_remove = " \
+ ${systemd_unitdir}/system/obmc-host-shutdown@0.target.requires/ \
+ ${systemd_unitdir}/system/obmc-host-shutdown@0.target.requires/xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service \
+ "
+
+do_install_append(){
+ rm -f ${D}/${bindir}/phosphor-softpoweroff
+}
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-ipmb_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-ipmb_%.bbappend
new file mode 100644
index 000000000..13d908ad1
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-ipmb_%.bbappend
@@ -0,0 +1,2 @@
+SRC_URI = "git://github.com/openbmc/ipmbbridge.git"
+SRCREV = "8188d7651c23502f88f9bf850ab7e549f6463997"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs/99-ipmi-kcs.rules b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs/99-ipmi-kcs.rules
new file mode 100644
index 000000000..0a64b58db
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs/99-ipmi-kcs.rules
@@ -0,0 +1,2 @@
+KERNEL=="ipmi-kcs3", SYMLINK+="ipmi_kcs3"
+KERNEL=="ipmi-kcs4", SYMLINK+="ipmi_kcs4"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs_%.bbappend
new file mode 100644
index 000000000..140d1b302
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs_%.bbappend
@@ -0,0 +1,21 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+#SYSTEMD_SUBSTITUTIONS_remove = "KCS_DEVICE:${KCS_DEVICE}:${DBUS_SERVICE_${PN}}"
+
+# Default kcs device is ipmi-kcs3; this is SMS.
+# Add SMM kcs device instance
+
+# Replace the '-' to '_', since Dbus object/interface names do not allow '-'.
+KCS_DEVICE = "ipmi_kcs3"
+SMM_DEVICE = "ipmi_kcs4"
+SYSTEMD_SERVICE_${PN}_append = " ${PN}@${SMM_DEVICE}.service "
+
+SRC_URI = "git://github.com/openbmc/kcsbridge.git"
+SRCREV = "2cdc49585235a6557c9cbb6c8b75c064fc02681a"
+
+SRC_URI += "file://99-ipmi-kcs.rules"
+
+do_install_append() {
+ install -d ${D}${base_libdir}/udev/rules.d
+ install -m 0644 ${WORKDIR}/99-ipmi-kcs.rules ${D}${base_libdir}/udev/rules.d/
+}
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/00010-Change-Authentication-Parameter.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/00010-Change-Authentication-Parameter.patch
new file mode 100644
index 000000000..867b3aba6
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/00010-Change-Authentication-Parameter.patch
@@ -0,0 +1,40 @@
+From 0fd38eb0a155cb11ff5a5452087f68c46d12111b Mon Sep 17 00:00:00 2001
+From: Cheng C Yang <cheng.c.yang@intel.com>
+Date: Thu, 28 Mar 2019 18:10:40 +0800
+Subject: [PATCH] Change Authentication Parameter
+
+Seprate D-bus interface Authentication to forceAuthentication,
+forceEncryption, Privilege according to the related change in
+sol-dbus-interface.
+
+Tested By:
+ipmitool -I lanplus -H x -U x -P x raw 0x0c 0x21 0x0e 0x02 0x03
+ipmitool -I lanplus -H x -U x -P x raw 0x0c 0x21 0x0e 0x02 0xc2
+The parameters has been changed to the request data in above command.
+
+Signed-off-by: Cheng C Yang <cheng.c.yang@intel.com>
+---
+ sol/sol_manager.cpp | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/sol/sol_manager.cpp b/sol/sol_manager.cpp
+index de36723..0bd837e 100644
+--- a/sol/sol_manager.cpp
++++ b/sol/sol_manager.cpp
+@@ -195,8 +195,12 @@ void Manager::updateSOLParameter()
+
+ enable = std::get<bool>(properties["Enable"]);
+
++ forceEncrypt = std::get<bool>(properties["ForceEncryption"]);
++
++ forceAuth = std::get<bool>(properties["ForceAuthentication"]);
++
+ solMinPrivilege = static_cast<session::Privilege>(
+- std::get<uint8_t>(properties["Authentication"]));
++ std::get<uint8_t>(properties["Privilege"]));
+
+ accumulateInterval =
+ std::get<uint8_t>((properties["AccumulateIntervalMS"])) *
+--
+2.16.2
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0006-Modify-dbus-namespace-of-chassis-control-for-guid.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0006-Modify-dbus-namespace-of-chassis-control-for-guid.patch
new file mode 100644
index 000000000..0ad625a1f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0006-Modify-dbus-namespace-of-chassis-control-for-guid.patch
@@ -0,0 +1,39 @@
+From 6fc55bb689272d34ff6616cdd4b24367ea39c749 Mon Sep 17 00:00:00 2001
+From: Kuiying Wang <kuiying.wang@intel.com>
+Date: Mon, 2 Jul 2018 15:51:52 +0800
+Subject: [PATCH] Modify dbus namespace of chassis control for guid.cpp
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Switch chassis control service namespace for guid.cpp from “org” to “xyz”,
+to compatible with new intel-chassis services
+
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+---
+ command/guid.cpp | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+Index: phosphor-net-ipmid.clean/command/guid.cpp
+===================================================================
+--- phosphor-net-ipmid.clean.orig/command/guid.cpp
++++ phosphor-net-ipmid.clean/command/guid.cpp
+@@ -21,7 +21,8 @@ namespace command
+
+ std::unique_ptr<sdbusplus::bus::match_t> matchPtr(nullptr);
+
+-static constexpr auto guidObjPath = "/org/openbmc/control/chassis0";
++static constexpr auto guidObjPath =
++ "/xyz/openbmc_project/Chassis/Control/Chassis0";
+ static constexpr auto propInterface = "org.freedesktop.DBus.Properties";
+
+ Guid getSystemGUID()
+@@ -31,7 +32,7 @@ Guid getSystemGUID()
+ Guid guid = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10};
+
+- constexpr auto chassisIntf = "org.openbmc.control.Chassis";
++ constexpr auto chassisIntf = "xyz.openbmc_project.Chassis.Control.Chassis";
+
+ sd_bus_message* reply = nullptr;
+ sd_bus_error error = SD_BUS_ERROR_NULL;
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0007-Adding-support-for-GetSessionInfo-command.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0007-Adding-support-for-GetSessionInfo-command.patch
new file mode 100644
index 000000000..bbbe6ae4f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0007-Adding-support-for-GetSessionInfo-command.patch
@@ -0,0 +1,418 @@
+From b05fb3231810865ef1b6e627bb0452ae7a6c61f8 Mon Sep 17 00:00:00 2001
+From: ssekar <suryakanth.sekar@linux.intel.com>
+Date: Wed, 12 Dec 2018 16:04:15 +0530
+Subject: [PATCH 1/2] Adding support for GetSessionInfo command
+
+Description: user can get all session info (remote ip,port,
+session id, priv, etc) using this command.
+
+Verification :we can get all active and non active session
+info by session handle session id.
+Updated the Remote IP addr and Port update for sessioninfo.
+Unit testing are done.
+
+Change-Id: I662ef2b9f0c1d6bda331eb6481d7b9f34534541b
+Signed-off-by: ssekar <suryakanth.sekar@linux.intel.com>
+---
+ comm_module.cpp | 8 +++
+ command/session_cmds.cpp | 147 +++++++++++++++++++++++++++++++++++++++
+ command/session_cmds.hpp | 55 +++++++++++++++
+ message_handler.cpp | 1 +
+ sessions_manager.cpp | 55 +++++++++++++++
+ sessions_manager.hpp | 7 ++
+ socket_channel.hpp | 17 +++++
+ 7 files changed, 290 insertions(+)
+
+diff --git a/comm_module.cpp b/comm_module.cpp
+index acc9089..7a1a17d 100644
+--- a/comm_module.cpp
++++ b/comm_module.cpp
+@@ -53,6 +53,14 @@ void sessionSetupCommands()
+ &closeSession,
+ session::Privilege::CALLBACK,
+ false},
++ // Session Info Command
++ {
++ {
++ (static_cast<uint32_t>(message::PayloadType::IPMI) << 16) |
++ static_cast<uint16_t>(command::NetFns::APP) | 0x3D
++ },
++ &getSessionInfo, session::Privilege::USER, false
++ },
+ };
+
+ for (auto& iter : commands)
+diff --git a/command/session_cmds.cpp b/command/session_cmds.cpp
+index 8606ce5..4beeb6e 100644
+--- a/command/session_cmds.cpp
++++ b/command/session_cmds.cpp
+@@ -8,6 +8,14 @@
+ namespace command
+ {
+
++// Defined as per IPMI sepcification
++static constexpr uint8_t searchCurrentSession = 0x00;
++static constexpr uint8_t searchSessionByHandle = 0xFE;
++static constexpr uint8_t searchSessionByID = 0xFF;
++
++static constexpr uint8_t ipmi15VerSession = 0x00;
++static constexpr uint8_t ipmi20VerSession = 0x01;
++
+ std::vector<uint8_t>
+ setSessionPrivilegeLevel(const std::vector<uint8_t>& inPayload,
+ const message::Handler& handler)
+@@ -92,4 +100,143 @@ std::vector<uint8_t> closeSession(const std::vector<uint8_t>& inPayload,
+ return outPayload;
+ }
+
++std::vector<uint8_t> getSessionInfo(const std::vector<uint8_t>& inPayload,
++ const message::Handler& handler)
++
++{
++ std::vector<uint8_t> outPayload(sizeof(GetSessionInfoResponse));
++ auto request =
++ reinterpret_cast<const GetSessionInfoRequest*>(inPayload.data());
++ auto response =
++ reinterpret_cast<GetSessionInfoResponse*>(outPayload.data());
++ uint32_t reqSessionID = handler.sessionID;
++ response->completionCode = IPMI_CC_OK;
++ if (inPayload.size() == 1 && request->sessionIndex != 0)
++ {
++ if (request->sessionIndex <= session::MAX_SESSION_COUNT)
++ {
++ reqSessionID = std::get<session::Manager&>(singletonPool)
++ .getSessionIDbyHandle(request->sessionIndex);
++ }
++ else
++ {
++ response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
++ outPayload.resize(sizeof(response->completionCode));
++ return std::move(outPayload);
++ }
++ }
++
++ // Here we look for session info according to session index parameter
++ switch (request->sessionIndex)
++ {
++ // Look for current active session which this cmd is received over
++ case searchCurrentSession:
++ // Request data should only contain session index byte
++ if (inPayload.size() != 1)
++ {
++ response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
++ outPayload.resize(sizeof(response->completionCode));
++ return std::move(outPayload);
++ }
++ // To look for current active session which the command came over,
++ // the session ID cannot be 0.
++ if (0 == reqSessionID)
++ {
++ response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
++ outPayload.resize(sizeof(response->completionCode));
++ return std::move(outPayload);
++ }
++ break;
++ case searchSessionByHandle:
++ // Request data should only contain session index byte and Session
++ // handle
++ if (inPayload.size() != 2)
++ {
++ response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
++ outPayload.resize(sizeof(response->completionCode));
++ return std::move(outPayload);
++ }
++
++ // Retrieve session id based on session handle
++ if (request->sessionHandle <= session::MAX_SESSION_COUNT)
++ {
++ reqSessionID =
++ std::get<session::Manager&>(singletonPool)
++ .getSessionIDbyHandle(request->sessionHandle);
++ }
++ else
++ {
++ response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
++ outPayload.resize(sizeof(response->completionCode));
++ return std::move(outPayload);
++ }
++ break;
++ case searchSessionByID:
++ // Request data should only contain session index byte and Session
++ // handle
++ if (inPayload.size() != sizeof(GetSessionInfoRequest))
++ {
++ response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
++ outPayload.resize(sizeof(response->completionCode));
++ return std::move(outPayload);
++ }
++ reqSessionID = endian::from_ipmi(request->sessionID);
++
++ break;
++ default:
++ if (inPayload.size() != 1)
++ {
++ response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
++ outPayload.resize(sizeof(response->completionCode));
++ return std::move(outPayload);
++ }
++ }
++
++ response->totalSessionCount = session::MAX_SESSION_COUNT;
++ response->activeSessioncount =
++ std::get<session::Manager&>(singletonPool).getNoOfActiveSession();
++ response->sessionHandle = 0;
++ if (reqSessionID != 0)
++ {
++
++ std::shared_ptr<session::Session> sessionInfo;
++ try
++ {
++ sessionInfo = std::get<session::Manager&>(singletonPool)
++ .getSession(reqSessionID);
++ }
++ catch (std::exception& e)
++ {
++ response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
++ outPayload.resize(sizeof(response->completionCode));
++ return std::move(outPayload);
++ }
++ response->sessionHandle = std::get<session::Manager&>(singletonPool)
++ .getSessionHandle(reqSessionID);
++ uint8_t userId = ipmi::ipmiUserGetUserId(sessionInfo->userName);
++ if (userId == ipmi::invalidUserId)
++ {
++ response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
++ outPayload.resize(sizeof(response->completionCode));
++ return std::move(outPayload);
++ }
++ response->userID = userId; // userId;
++ response->privLevel = static_cast<uint8_t>(sessionInfo->curPrivLevel);
++ response->chanNum = sessionInfo->chNum; // byte7 3:0
++ response->ipmiVer = ipmi20VerSession; // byte7 7:4
++ response->remoteIpAddr =
++ sessionInfo->channelPtr->getRemoteAddressInbytes();
++ response->remotePort =
++ sessionInfo->channelPtr->getPort(); // remoteSessionPort;
++
++ std::cerr << "\nSessionInfo:" << (int)reqSessionID;
++ // TODO: Filling the Remote MACAddress
++ }
++ else
++ {
++ outPayload.resize(4);
++ }
++ return std::move(outPayload);
++}
++
+ } // namespace command
+diff --git a/command/session_cmds.hpp b/command/session_cmds.hpp
+index 9737fdb..741de23 100644
+--- a/command/session_cmds.hpp
++++ b/command/session_cmds.hpp
+@@ -116,4 +116,59 @@ struct CloseSessionResponse
+ std::vector<uint8_t> closeSession(const std::vector<uint8_t>& inPayload,
+ const message::Handler& handler);
+
++/**
++ * @struct GetSessionInfoRequest
++ *
++ * IPMI Request data for getSession info command
++ */
++struct GetSessionInfoRequest
++{
++ uint8_t sessionIndex;
++ union
++ {
++ uint8_t sessionHandle;
++ uint32_t sessionID;
++ };
++} __attribute__((packed));
++
++/**
++ * @struct getSessionInfoResponse
++ *
++ * IPMI Response data for getSession info command
++ */
++struct GetSessionInfoResponse
++{
++ uint8_t completionCode;
++ uint8_t sessionHandle;
++ uint8_t totalSessionCount;
++ uint8_t activeSessioncount;
++ uint8_t userID;
++ uint8_t privLevel;
++#if BYTE_ORDER == LITTLE_ENDIAN
++ uint8_t chanNum : 4;
++ uint8_t ipmiVer : 4;
++#endif
++#if BYTE_ORDER == BIG_ENDIAN
++ uint8_t ipmiVer : 4;
++ uint8_t chanNum : 4;
++#endif
++ uint32_t remoteIpAddr; // for channel private data
++ uint8_t remoteMACAddr[6];
++ uint16_t remotePort;
++} __attribute__((packed));
++
++/**
++ * @brief GetSessionInfo Command
++ *
++ * This command is used to get the session information based on
++ * session handle or session ID. Retreive all session information.
++
++ * @param[in] inPayload - Request Data for the command
++ * @param[in] handler - Reference to the Message Handler
++ *
++ * @return Response data for the command
++ */
++std::vector<uint8_t> getSessionInfo(const std::vector<uint8_t>& inPayload,
++ const message::Handler& handler);
++
+ } // namespace command
+diff --git a/message_handler.cpp b/message_handler.cpp
+index e2aafb3..b335236 100644
+--- a/message_handler.cpp
++++ b/message_handler.cpp
+@@ -43,6 +43,7 @@ bool Handler::receive()
+ sessionID = inMessage->bmcSessionID;
+ inMessage->rcSessionID = session->getRCSessionID();
+ session->updateLastTransactionTime();
++ session->channelPtr = channel;
+
+ return true;
+ }
+diff --git a/sessions_manager.cpp b/sessions_manager.cpp
+index 95a8a15..9f3210b 100644
+--- a/sessions_manager.cpp
++++ b/sessions_manager.cpp
+@@ -88,6 +88,9 @@ std::shared_ptr<Session>
+ }
+ sessionID = session->getBMCSessionID();
+ sessionsMap.emplace(sessionID, session);
++ storeSessionHandle(sessionID);
++
++
+ return session;
+ }
+
+@@ -149,12 +152,15 @@ std::shared_ptr<Session> Manager::getSession(SessionID sessionID,
+
+ void Manager::cleanStaleEntries()
+ {
++ uint8_t sessionIndex = 0;
+ for (auto iter = sessionsMap.begin(); iter != sessionsMap.end();)
+ {
+ auto session = iter->second;
+ if ((session->getBMCSessionID() != SESSION_ZERO) &&
+ !(session->isSessionActive()))
+ {
++ sessionIndex = getSessionHandle(session->getBMCSessionID());
++ sessionHandleMap[sessionIndex] = 0;
+ iter = sessionsMap.erase(iter);
+ }
+ else
+@@ -164,4 +170,53 @@ void Manager::cleanStaleEntries()
+ }
+ }
+
++uint8_t Manager::storeSessionHandle(SessionID bmcSessionID)
++{
++ // Zero handler is reserved for invalid session.
++ //index starts with 1, for direct usage. Index 0 reserved
++ for (uint8_t i = 1; i <= MAX_SESSION_COUNT; i++)
++ {
++ if (sessionHandleMap[i] == 0)
++ {
++ sessionHandleMap[i] = bmcSessionID;
++ break;
++ }
++ }
++ return 0;
++}
++
++uint32_t Manager::getSessionIDbyHandle(uint8_t sessionHandle) const
++{
++ if (sessionHandle <= MAX_SESSION_COUNT)
++ {
++ return sessionHandleMap[sessionHandle];
++ }
++ return 0;
++}
++
++uint8_t Manager::getSessionHandle(SessionID bmcSessionID) const
++{
++
++ for (uint8_t i = 1; i <= MAX_SESSION_COUNT; i++)
++ {
++ if (sessionHandleMap[i] == bmcSessionID)
++ {
++ return i;
++ }
++ }
++ return 0;
++}
++uint8_t Manager::getNoOfActiveSession() const
++{
++ uint8_t count = 0;
++ for (const auto& it : sessionsMap)
++ {
++ const auto& session = it.second;
++ if (session->state == State::ACTIVE)
++ {
++ count++;
++ }
++ }
++ return count;
++}
+ } // namespace session
+diff --git a/sessions_manager.hpp b/sessions_manager.hpp
+index 9fd38b1..f6ed1c3 100644
+--- a/sessions_manager.hpp
++++ b/sessions_manager.hpp
+@@ -82,8 +82,15 @@ class Manager
+ std::shared_ptr<Session>
+ getSession(SessionID sessionID,
+ RetrieveOption option = RetrieveOption::BMC_SESSION_ID);
++ uint8_t getNoOfActiveSession() const;
++ uint8_t getSessionHandle(SessionID bmcSessionID) const;
++ uint8_t storeSessionHandle(SessionID bmcSessionID);
++ uint32_t getSessionIDbyHandle(uint8_t sessionHandle) const;
+
+ private:
++ //+1 for session, as 0 is reserved for sessionless command
++ std::array<uint32_t, MAX_SESSION_COUNT + 1> sessionHandleMap;
++
+ /**
+ * @brief Session Manager keeps the session objects as a sorted
+ * associative container with Session ID as the unique key
+diff --git a/socket_channel.hpp b/socket_channel.hpp
+index ebe0c8f..349701e 100644
+--- a/socket_channel.hpp
++++ b/socket_channel.hpp
+@@ -64,6 +64,23 @@ class Channel
+ return endpoint.port();
+ }
+
++ /**
++ * @brief Return the binary representation of the remote IPv4 address
++ *
++ * getSessionInfo needs to return the remote IPv4 addresses of each session
++ *
++ * @return A uint32_t representation of the remote IPv4 address
++ */
++ std::uint32_t getRemoteAddressInbytes()
++ {
++ const boost::asio::ip::address& addr = endpoint.address();
++ if (addr.is_v4())
++ {
++ return addr.to_v4().to_uint();
++ }
++ return 0;
++ }
++
+ /**
+ * @brief Read the incoming packet
+ *
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0008-Sync-GetSession-Info-cmd-based-on-Upstream-review.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0008-Sync-GetSession-Info-cmd-based-on-Upstream-review.patch
new file mode 100644
index 000000000..c6b87bf4f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0008-Sync-GetSession-Info-cmd-based-on-Upstream-review.patch
@@ -0,0 +1,282 @@
+From a413e390563205476656a9005ca447f5b626872f Mon Sep 17 00:00:00 2001
+From: Suryakanth Sekar <suryakanth.sekar@linux.intel.com>
+Date: Wed, 6 Mar 2019 10:35:56 +0530
+Subject: [PATCH 2/2] Sync GetSession Info cmd based on Upstream review
+
+Signed-off-by: Suryakanth Sekar <suryakanth.sekar@linux.intel.com>
+---
+ comm_module.cpp | 12 +++----
+ command/session_cmds.cpp | 71 ++++++++++++++++++----------------------
+ sessions_manager.cpp | 10 +++---
+ sessions_manager.hpp | 2 +-
+ socket_channel.hpp | 33 ++++++++++---------
+ 5 files changed, 59 insertions(+), 69 deletions(-)
+
+diff --git a/comm_module.cpp b/comm_module.cpp
+index 7a1a17d..2546583 100644
+--- a/comm_module.cpp
++++ b/comm_module.cpp
+@@ -54,13 +54,11 @@ void sessionSetupCommands()
+ session::Privilege::CALLBACK,
+ false},
+ // Session Info Command
+- {
+- {
+- (static_cast<uint32_t>(message::PayloadType::IPMI) << 16) |
+- static_cast<uint16_t>(command::NetFns::APP) | 0x3D
+- },
+- &getSessionInfo, session::Privilege::USER, false
+- },
++ {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) |
++ static_cast<uint16_t>(command::NetFns::APP) | 0x3D},
++ &getSessionInfo,
++ session::Privilege::USER,
++ false},
+ };
+
+ for (auto& iter : commands)
+diff --git a/command/session_cmds.cpp b/command/session_cmds.cpp
+index 4beeb6e..0c3a4ed 100644
+--- a/command/session_cmds.cpp
++++ b/command/session_cmds.cpp
+@@ -8,7 +8,7 @@
+ namespace command
+ {
+
+-// Defined as per IPMI sepcification
++// Defined as per IPMI specification
+ static constexpr uint8_t searchCurrentSession = 0x00;
+ static constexpr uint8_t searchSessionByHandle = 0xFE;
+ static constexpr uint8_t searchSessionByID = 0xFF;
+@@ -111,20 +111,6 @@ std::vector<uint8_t> getSessionInfo(const std::vector<uint8_t>& inPayload,
+ reinterpret_cast<GetSessionInfoResponse*>(outPayload.data());
+ uint32_t reqSessionID = handler.sessionID;
+ response->completionCode = IPMI_CC_OK;
+- if (inPayload.size() == 1 && request->sessionIndex != 0)
+- {
+- if (request->sessionIndex <= session::MAX_SESSION_COUNT)
+- {
+- reqSessionID = std::get<session::Manager&>(singletonPool)
+- .getSessionIDbyHandle(request->sessionIndex);
+- }
+- else
+- {
+- response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
+- outPayload.resize(sizeof(response->completionCode));
+- return std::move(outPayload);
+- }
+- }
+
+ // Here we look for session info according to session index parameter
+ switch (request->sessionIndex)
+@@ -132,29 +118,22 @@ std::vector<uint8_t> getSessionInfo(const std::vector<uint8_t>& inPayload,
+ // Look for current active session which this cmd is received over
+ case searchCurrentSession:
+ // Request data should only contain session index byte
+- if (inPayload.size() != 1)
++ if (inPayload.size() != sizeof(request->sessionIndex))
+ {
+ response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
+ outPayload.resize(sizeof(response->completionCode));
+- return std::move(outPayload);
+- }
+- // To look for current active session which the command came over,
+- // the session ID cannot be 0.
+- if (0 == reqSessionID)
+- {
+- response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
+- outPayload.resize(sizeof(response->completionCode));
+- return std::move(outPayload);
++ return outPayload;
+ }
+ break;
+ case searchSessionByHandle:
+ // Request data should only contain session index byte and Session
+ // handle
+- if (inPayload.size() != 2)
++ if (inPayload.size() != (sizeof(request->sessionIndex) +
++ sizeof(request->sessionHandle)))
+ {
+ response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
+ outPayload.resize(sizeof(response->completionCode));
+- return std::move(outPayload);
++ return outPayload;
+ }
+
+ // Retrieve session id based on session handle
+@@ -168,7 +147,7 @@ std::vector<uint8_t> getSessionInfo(const std::vector<uint8_t>& inPayload,
+ {
+ response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
+ outPayload.resize(sizeof(response->completionCode));
+- return std::move(outPayload);
++ return outPayload;
+ }
+ break;
+ case searchSessionByID:
+@@ -178,23 +157,38 @@ std::vector<uint8_t> getSessionInfo(const std::vector<uint8_t>& inPayload,
+ {
+ response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
+ outPayload.resize(sizeof(response->completionCode));
+- return std::move(outPayload);
++ return outPayload;
+ }
+ reqSessionID = endian::from_ipmi(request->sessionID);
+
+ break;
+ default:
+- if (inPayload.size() != 1)
++ if (inPayload.size() == sizeof(request->sessionIndex))
++ {
++ if (request->sessionIndex <= session::MAX_SESSION_COUNT)
++ {
++ reqSessionID =
++ std::get<session::Manager&>(singletonPool)
++ .getSessionIDbyHandle(request->sessionIndex);
++ }
++ else
++ {
++ response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
++ outPayload.resize(sizeof(response->completionCode));
++ return outPayload;
++ }
++ }
++ else
+ {
+ response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
+ outPayload.resize(sizeof(response->completionCode));
+- return std::move(outPayload);
++ return outPayload;
+ }
+ }
+
+ response->totalSessionCount = session::MAX_SESSION_COUNT;
+ response->activeSessioncount =
+- std::get<session::Manager&>(singletonPool).getNoOfActiveSession();
++ std::get<session::Manager&>(singletonPool).getActiveSessionCount();
+ response->sessionHandle = 0;
+ if (reqSessionID != 0)
+ {
+@@ -207,9 +201,9 @@ std::vector<uint8_t> getSessionInfo(const std::vector<uint8_t>& inPayload,
+ }
+ catch (std::exception& e)
+ {
+- response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
++ response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
+ outPayload.resize(sizeof(response->completionCode));
+- return std::move(outPayload);
++ return outPayload;
+ }
+ response->sessionHandle = std::get<session::Manager&>(singletonPool)
+ .getSessionHandle(reqSessionID);
+@@ -218,25 +212,24 @@ std::vector<uint8_t> getSessionInfo(const std::vector<uint8_t>& inPayload,
+ {
+ response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
+ outPayload.resize(sizeof(response->completionCode));
+- return std::move(outPayload);
++ return outPayload;
+ }
+ response->userID = userId; // userId;
+ response->privLevel = static_cast<uint8_t>(sessionInfo->curPrivLevel);
+ response->chanNum = sessionInfo->chNum; // byte7 3:0
+ response->ipmiVer = ipmi20VerSession; // byte7 7:4
+- response->remoteIpAddr =
+- sessionInfo->channelPtr->getRemoteAddressInbytes();
+ response->remotePort =
+ sessionInfo->channelPtr->getPort(); // remoteSessionPort;
++ response->remoteIpAddr =
++ sessionInfo->channelPtr->getRemoteAddressInBytes();
+
+- std::cerr << "\nSessionInfo:" << (int)reqSessionID;
+ // TODO: Filling the Remote MACAddress
+ }
+ else
+ {
+ outPayload.resize(4);
+ }
+- return std::move(outPayload);
++ return outPayload;
+ }
+
+ } // namespace command
+diff --git a/sessions_manager.cpp b/sessions_manager.cpp
+index 9f3210b..c6897c6 100644
+--- a/sessions_manager.cpp
++++ b/sessions_manager.cpp
+@@ -152,15 +152,13 @@ std::shared_ptr<Session> Manager::getSession(SessionID sessionID,
+
+ void Manager::cleanStaleEntries()
+ {
+- uint8_t sessionIndex = 0;
+ for (auto iter = sessionsMap.begin(); iter != sessionsMap.end();)
+ {
+ auto session = iter->second;
+ if ((session->getBMCSessionID() != SESSION_ZERO) &&
+ !(session->isSessionActive()))
+ {
+- sessionIndex = getSessionHandle(session->getBMCSessionID());
+- sessionHandleMap[sessionIndex] = 0;
++ sessionHandleMap[getSessionHandle(session->getBMCSessionID())] = 0;
+ iter = sessionsMap.erase(iter);
+ }
+ else
+@@ -172,8 +170,8 @@ void Manager::cleanStaleEntries()
+
+ uint8_t Manager::storeSessionHandle(SessionID bmcSessionID)
+ {
+- // Zero handler is reserved for invalid session.
+- //index starts with 1, for direct usage. Index 0 reserved
++ // Handler index 0 is reserved for invalid session.
++ // index starts with 1, for direct usage. Index 0 reserved
+ for (uint8_t i = 1; i <= MAX_SESSION_COUNT; i++)
+ {
+ if (sessionHandleMap[i] == 0)
+@@ -206,7 +204,7 @@ uint8_t Manager::getSessionHandle(SessionID bmcSessionID) const
+ }
+ return 0;
+ }
+-uint8_t Manager::getNoOfActiveSession() const
++uint8_t Manager::getActiveSessionCount() const
+ {
+ uint8_t count = 0;
+ for (const auto& it : sessionsMap)
+diff --git a/sessions_manager.hpp b/sessions_manager.hpp
+index f6ed1c3..3ff213e 100644
+--- a/sessions_manager.hpp
++++ b/sessions_manager.hpp
+@@ -82,7 +82,7 @@ class Manager
+ std::shared_ptr<Session>
+ getSession(SessionID sessionID,
+ RetrieveOption option = RetrieveOption::BMC_SESSION_ID);
+- uint8_t getNoOfActiveSession() const;
++ uint8_t getActiveSessionCount() const;
+ uint8_t getSessionHandle(SessionID bmcSessionID) const;
+ uint8_t storeSessionHandle(SessionID bmcSessionID);
+ uint32_t getSessionIDbyHandle(uint8_t sessionHandle) const;
+diff --git a/socket_channel.hpp b/socket_channel.hpp
+index 349701e..8b64740 100644
+--- a/socket_channel.hpp
++++ b/socket_channel.hpp
+@@ -107,14 +107,15 @@ class Channel
+ *
+ * @return A uint32_t representation of the remote IPv4 address
+ */
+- std::uint32_t getRemoteAddressInbytes()
++ uint32_t getRemoteAddressInBytes() const
+ {
+- const boost::asio::ip::address& addr = endpoint.address();
+- if (addr.is_v4())
++ uint32_t v4addr = 0;
++ if (sockAddrSize == sizeof(sockaddr_in))
+ {
+- return addr.to_v4().to_uint();
++ auto saddr = reinterpret_cast<const sockaddr_in*>(&remoteSockAddr);
++ v4addr = ntohl(saddr->sin_addr.s_addr);
+ }
+- return 0;
++ return v4addr;
+ }
+
+ /**
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0009-Add-dbus-interface-for-sol-commands.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0009-Add-dbus-interface-for-sol-commands.patch
new file mode 100644
index 000000000..c90cccf34
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0009-Add-dbus-interface-for-sol-commands.patch
@@ -0,0 +1,311 @@
+From 6b9aaf0304aed06e4b5ac53e7c163089568d4171 Mon Sep 17 00:00:00 2001
+From: Cheng C Yang <cheng.c.yang@intel.com>
+Date: Sat, 23 Mar 2019 04:03:07 +0800
+Subject: [PATCH] Add dbus interface for sol commands
+
+Add dbus interface for sol config parameters so that after move set/get
+sol config parameter command from net-ipmid to host-ipmid, the command
+can send config parameters to net-ipmid sol service through the dbus
+interface.
+
+Tested by:
+busctl introspect xyz.openbmc_project.Settings /xyz/openbmc_project
+/network/host0/sol can show correct dbus properties of sol parameters.
+ipmitool -I lanplus -H x -U x -P x raw 0x0c 0x21 0x0e 0x00 0x01
+ipmitool -I lanplus -H x -U x -P x raw 0x0c 0x21 0x0e 0x01 0x00
+ipmitool -I lanplus -H x -U x -P x raw 0x0c 0x21 0x0e 0x02 0x83
+ipmitool -I lanplus -H x -U x -P x raw 0x0c 0x21 0x0e 0x03 0x5 0x03
+ipmitool -I lanplus -H x -U x -P x raw 0x0c 0x21 0x0e 0x04 0x5 0x03
+all these commands can change the dbus properties as the value in
+above commands.
+Before and after run these commands, ipmitool -I lanplus -H x -U x
+-P x sol activate can start sol session correctly.
+After reboot BMC, "Progress" property in dbus interface change back
+to 0 and other properties will not reset to default value.
+
+Signed-off-by: Cheng C Yang <cheng.c.yang@intel.com>
+---
+ command/payload_cmds.cpp | 1 +
+ command/sol_cmds.cpp | 84 ---------------------------------
+ sol/sol_manager.cpp | 119 +++++++++++++++++++++++++++++++++++++++++++++++
+ sol/sol_manager.hpp | 1 +
+ sol_module.cpp | 6 ---
+ 5 files changed, 121 insertions(+), 90 deletions(-)
+
+diff --git a/command/payload_cmds.cpp b/command/payload_cmds.cpp
+index 3b5b4f8..570cdff 100644
+--- a/command/payload_cmds.cpp
++++ b/command/payload_cmds.cpp
+@@ -34,6 +34,7 @@ std::vector<uint8_t> activatePayload(const std::vector<uint8_t>& inPayload,
+ return outPayload;
+ }
+
++ std::get<sol::Manager&>(singletonPool).updateSOLParameter();
+ if (!std::get<sol::Manager&>(singletonPool).enable)
+ {
+ response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
+diff --git a/command/sol_cmds.cpp b/command/sol_cmds.cpp
+index a8fa410..804b5ea 100644
+--- a/command/sol_cmds.cpp
++++ b/command/sol_cmds.cpp
+@@ -65,90 +65,6 @@ void activating(uint8_t payloadInstance, uint32_t sessionID)
+ outPayload);
+ }
+
+-std::vector<uint8_t> setConfParams(const std::vector<uint8_t>& inPayload,
+- const message::Handler& handler)
+-{
+- std::vector<uint8_t> outPayload(sizeof(SetConfParamsResponse));
+- auto request =
+- reinterpret_cast<const SetConfParamsRequest*>(inPayload.data());
+- auto response = reinterpret_cast<SetConfParamsResponse*>(outPayload.data());
+- response->completionCode = IPMI_CC_OK;
+-
+- switch (static_cast<Parameter>(request->paramSelector))
+- {
+- case Parameter::PROGRESS:
+- {
+- uint8_t progress = request->value & progressMask;
+- std::get<sol::Manager&>(singletonPool).progress = progress;
+- break;
+- }
+- case Parameter::ENABLE:
+- {
+- bool enable = request->value & enableMask;
+- std::get<sol::Manager&>(singletonPool).enable = enable;
+- break;
+- }
+- case Parameter::AUTHENTICATION:
+- {
+- if (!request->auth.auth || !request->auth.encrypt)
+- {
+- response->completionCode = ipmiCCWriteReadParameter;
+- }
+- else if (request->auth.privilege <
+- static_cast<uint8_t>(session::Privilege::USER) ||
+- request->auth.privilege >
+- static_cast<uint8_t>(session::Privilege::OEM))
+- {
+- response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
+- }
+- else
+- {
+- std::get<sol::Manager&>(singletonPool).solMinPrivilege =
+- static_cast<session::Privilege>(request->auth.privilege);
+- }
+- break;
+- }
+- case Parameter::ACCUMULATE:
+- {
+- using namespace std::chrono_literals;
+-
+- if (request->acc.threshold == 0)
+- {
+- response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
+- break;
+- }
+-
+- std::get<sol::Manager&>(singletonPool).accumulateInterval =
+- request->acc.interval * sol::accIntervalFactor * 1ms;
+- std::get<sol::Manager&>(singletonPool).sendThreshold =
+- request->acc.threshold;
+- break;
+- }
+- case Parameter::RETRY:
+- {
+- using namespace std::chrono_literals;
+-
+- std::get<sol::Manager&>(singletonPool).retryCount =
+- request->retry.count;
+- std::get<sol::Manager&>(singletonPool).retryInterval =
+- request->retry.interval * sol::retryIntervalFactor * 1ms;
+- break;
+- }
+- case Parameter::PORT:
+- {
+- response->completionCode = ipmiCCWriteReadParameter;
+- break;
+- }
+- case Parameter::NVBITRATE:
+- case Parameter::VBITRATE:
+- case Parameter::CHANNEL:
+- default:
+- response->completionCode = ipmiCCParamNotSupported;
+- }
+-
+- return outPayload;
+-}
+-
+ std::vector<uint8_t> getConfParams(const std::vector<uint8_t>& inPayload,
+ const message::Handler& handler)
+ {
+diff --git a/sol/sol_manager.cpp b/sol/sol_manager.cpp
+index 2046fe4..de36723 100644
+--- a/sol/sol_manager.cpp
++++ b/sol/sol_manager.cpp
+@@ -12,7 +12,13 @@
+ #include <boost/asio/write.hpp>
+ #include <chrono>
+ #include <cmath>
++#include <ipmid/utils.hpp>
+ #include <phosphor-logging/log.hpp>
++#include <sdbusplus/message/types.hpp>
++
++constexpr const char* solInterface = "xyz.openbmc_project.Ipmi.SOL";
++constexpr const char* solPath = "/xyz/openbmc_project/ipmi/sol";
++constexpr const char* PROP_INTF = "org.freedesktop.DBus.Properties";
+
+ namespace sol
+ {
+@@ -93,6 +99,119 @@ void Manager::stopHostConsole()
+ }
+ }
+
++std::string getService(sdbusplus::bus::bus& bus, const std::string& intf,
++ const std::string& path)
++{
++ auto mapperCall =
++ bus.new_method_call("xyz.openbmc_project.ObjectMapper",
++ "/xyz/openbmc_project/object_mapper",
++ "xyz.openbmc_project.ObjectMapper", "GetObject");
++
++ mapperCall.append(path);
++ mapperCall.append(std::vector<std::string>({intf}));
++
++ std::map<std::string, std::vector<std::string>> mapperResponse;
++
++ try
++ {
++ auto mapperResponseMsg = bus.call(mapperCall);
++ mapperResponseMsg.read(mapperResponse);
++ }
++ catch (sdbusplus::exception_t&)
++ {
++ throw std::runtime_error("ERROR in mapper call");
++ }
++
++ if (mapperResponse.begin() == mapperResponse.end())
++ {
++ throw std::runtime_error("ERROR in reading the mapper response");
++ }
++
++ return mapperResponse.begin()->first;
++}
++
++ipmi::PropertyMap getAllDbusProperties(sdbusplus::bus::bus& bus,
++ const std::string& service,
++ const std::string& objPath,
++ const std::string& interface)
++{
++ ipmi::PropertyMap properties;
++
++ sdbusplus::message::message method = bus.new_method_call(
++ service.c_str(), objPath.c_str(), PROP_INTF, "GetAll");
++
++ method.append(interface);
++
++ try
++ {
++ sdbusplus::message::message reply = bus.call(method);
++ reply.read(properties);
++ }
++ catch (sdbusplus::exception_t&)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Failed to get all properties",
++ phosphor::logging::entry("PATH=%s", objPath.c_str()),
++ phosphor::logging::entry("INTERFACE=%s", interface.c_str()));
++ throw std::runtime_error("ERROR in reading proerties");
++ }
++
++ return properties;
++}
++
++void Manager::updateSOLParameter()
++{
++ std::variant<uint8_t, bool> value;
++ sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection());
++ static std::string solService{};
++ ipmi::PropertyMap properties;
++ if (solService.empty())
++ {
++ try
++ {
++ solService = getService(dbus, solInterface, solPath);
++ }
++ catch (const std::runtime_error& e)
++ {
++ solService.clear();
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error: get SOL service failed");
++ return;
++ }
++ }
++ try
++ {
++ properties =
++ getAllDbusProperties(dbus, solService, solPath, solInterface);
++ }
++ catch (const std::runtime_error&)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error setting sol parameter");
++ return;
++ }
++
++ progress = std::get<uint8_t>(properties["Progress"]);
++
++ enable = std::get<bool>(properties["Enable"]);
++
++ solMinPrivilege = static_cast<session::Privilege>(
++ std::get<uint8_t>(properties["Authentication"]));
++
++ accumulateInterval =
++ std::get<uint8_t>((properties["AccumulateIntervalMS"])) *
++ sol::accIntervalFactor * 1ms;
++
++ sendThreshold = std::get<uint8_t>(properties["Threshold"]);
++
++ retryCount = std::get<uint8_t>(properties["RetryCount"]);
++
++ retryInterval = std::get<uint8_t>(properties["RetryIntervalMS"]) *
++ sol::retryIntervalFactor * 1ms;
++
++ return;
++}
++
+ void Manager::startPayloadInstance(uint8_t payloadInstance,
+ session::SessionID sessionID)
+ {
+diff --git a/sol/sol_manager.hpp b/sol/sol_manager.hpp
+index 5d96890..b7eb89e 100644
+--- a/sol/sol_manager.hpp
++++ b/sol/sol_manager.hpp
+@@ -248,6 +248,7 @@ class Manager
+ * @return 0 on success and errno on failure.
+ */
+ int writeConsoleSocket(const std::vector<uint8_t>& input) const;
++ void updateSOLParameter(void);
+
+ private:
+ SOLPayloadMap payloadMap;
+diff --git a/sol_module.cpp b/sol_module.cpp
+index 8200e74..2b1fb46 100644
+--- a/sol_module.cpp
++++ b/sol_module.cpp
+@@ -42,12 +42,6 @@ void registerCommands()
+ &getPayloadInfo,
+ session::Privilege::USER,
+ false},
+- // Set SOL Configuration Parameters
+- {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) |
+- static_cast<uint16_t>(::command::NetFns::TRANSPORT) | 0x21},
+- &setConfParams,
+- session::Privilege::ADMIN,
+- false},
+ // Get SOL Configuration Parameters
+ {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) |
+ static_cast<uint16_t>(::command::NetFns::TRANSPORT) | 0x22},
+--
+2.16.2
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0011-Remove-Get-SOL-Config-Command-from-Netipmid.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0011-Remove-Get-SOL-Config-Command-from-Netipmid.patch
new file mode 100644
index 000000000..da173704b
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/0011-Remove-Get-SOL-Config-Command-from-Netipmid.patch
@@ -0,0 +1,336 @@
+From a36f181163974b2da0a954fc97a89fb2cdbd7287 Mon Sep 17 00:00:00 2001
+From: Cheng C Yang <cheng.c.yang@intel.com>
+Date: Tue, 30 Apr 2019 05:35:31 +0800
+Subject: [PATCH] Remove Get SOL Config Command from Netipmid
+
+Since Get SOL Config Parameter command already exists in host-ipmid, and
+can be shared to net channel, remove this command from net-ipmid.
+
+Tested:
+Run ipmitool -I lanplus -H xxx -U root -P 0penBmc sol info, the command
+returns the same result as ipmitool sol info as below.
+Info: SOL parameter 'Nonvolatile Bitrate (5)' not supported
+Info: SOL parameter 'Volatile Bitrate (6)' not supported
+Info: SOL parameter 'Payload Channel (7)' not supported - defaulting to 0x0e
+Set in progress : set-complete
+Enabled : true
+Force Encryption : true
+Force Authentication : true
+Privilege Level : USER
+Character Accumulate Level (ms) : 100
+Character Send Threshold : 1
+Retry Count : 3
+Retry Interval (ms) : 100
+Volatile Bit Rate (kbps) : IPMI-Over-Serial-Setting
+Non-Volatile Bit Rate (kbps) : IPMI-Over-Serial-Setting
+Payload Channel : 14 (0x0e)
+Payload Port : 623
+
+Signed-off-by: Cheng C Yang <cheng.c.yang@intel.com>
+---
+ command/sol_cmds.cpp | 91 ----------------------------
+ command/sol_cmds.hpp | 168 ---------------------------------------------------
+ sol_module.cpp | 6 --
+ 3 files changed, 265 deletions(-)
+
+diff --git a/command/sol_cmds.cpp b/command/sol_cmds.cpp
+index 804b5ea..8b2d041 100644
+--- a/command/sol_cmds.cpp
++++ b/command/sol_cmds.cpp
+@@ -65,97 +65,6 @@ void activating(uint8_t payloadInstance, uint32_t sessionID)
+ outPayload);
+ }
+
+-std::vector<uint8_t> getConfParams(const std::vector<uint8_t>& inPayload,
+- const message::Handler& handler)
+-{
+- std::vector<uint8_t> outPayload(sizeof(GetConfParamsResponse));
+- auto request =
+- reinterpret_cast<const GetConfParamsRequest*>(inPayload.data());
+- auto response = reinterpret_cast<GetConfParamsResponse*>(outPayload.data());
+- response->completionCode = IPMI_CC_OK;
+- response->paramRev = parameterRevision;
+-
+- if (request->getParamRev)
+- {
+- return outPayload;
+- }
+-
+- switch (static_cast<Parameter>(request->paramSelector))
+- {
+- case Parameter::PROGRESS:
+- {
+- outPayload.push_back(
+- std::get<sol::Manager&>(singletonPool).progress);
+- break;
+- }
+- case Parameter::ENABLE:
+- {
+- outPayload.push_back(std::get<sol::Manager&>(singletonPool).enable);
+- break;
+- }
+- case Parameter::AUTHENTICATION:
+- {
+- Auth value{0};
+-
+- value.encrypt = std::get<sol::Manager&>(singletonPool).forceEncrypt;
+- value.auth = std::get<sol::Manager&>(singletonPool).forceAuth;
+- value.privilege = static_cast<uint8_t>(
+- std::get<sol::Manager&>(singletonPool).solMinPrivilege);
+- auto buffer = reinterpret_cast<const uint8_t*>(&value);
+-
+- std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
+- break;
+- }
+- case Parameter::ACCUMULATE:
+- {
+- Accumulate value{0};
+-
+- value.interval = std::get<sol::Manager&>(singletonPool)
+- .accumulateInterval.count() /
+- sol::accIntervalFactor;
+- value.threshold =
+- std::get<sol::Manager&>(singletonPool).sendThreshold;
+- auto buffer = reinterpret_cast<const uint8_t*>(&value);
+-
+- std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
+- break;
+- }
+- case Parameter::RETRY:
+- {
+- Retry value{0};
+-
+- value.count = std::get<sol::Manager&>(singletonPool).retryCount;
+- value.interval =
+- std::get<sol::Manager&>(singletonPool).retryInterval.count() /
+- sol::retryIntervalFactor;
+- auto buffer = reinterpret_cast<const uint8_t*>(&value);
+-
+- std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
+- break;
+- }
+- case Parameter::PORT:
+- {
+- auto port = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
+- auto buffer = reinterpret_cast<const uint8_t*>(&port);
+-
+- std::copy_n(buffer, sizeof(port), std::back_inserter(outPayload));
+- break;
+- }
+- case Parameter::CHANNEL:
+- {
+- outPayload.push_back(
+- std::get<sol::Manager&>(singletonPool).channel);
+- break;
+- }
+- case Parameter::NVBITRATE:
+- case Parameter::VBITRATE:
+- default:
+- response->completionCode = ipmiCCParamNotSupported;
+- }
+-
+- return outPayload;
+-}
+-
+ } // namespace command
+
+ } // namespace sol
+diff --git a/command/sol_cmds.hpp b/command/sol_cmds.hpp
+index 182b73e..10cbf25 100644
+--- a/command/sol_cmds.hpp
++++ b/command/sol_cmds.hpp
+@@ -62,174 +62,6 @@ struct ActivatingRequest
+ */
+ void activating(uint8_t payloadInstance, uint32_t sessionID);
+
+-/** @enum Parameter
+- *
+- * SOL parameters are volatile, they are initialized by the SOL manager.
+- * They can be read using Get SOL configuration parameters command and updated
+- * using Set SOL configuration parameters command.
+- */
+-enum class Parameter
+-{
+- PROGRESS, //!< Set In Progress.
+- ENABLE, //!< SOL Enable.
+- AUTHENTICATION, //!< SOL Authentication.
+- ACCUMULATE, //!< Character Accumulate Interval & Send Threshold.
+- RETRY, //!< SOL Retry.
+- NVBITRATE, //!< SOL non-volatile bit rate.
+- VBITRATE, //!< SOL volatile bit rate.
+- CHANNEL, //!< SOL payload channel.
+- PORT, //!< SOL payload port.
+-};
+-
+-constexpr uint8_t progressMask = 0x03;
+-constexpr uint8_t enableMask = 0x01;
+-
+-/** @struct Auth
+- *
+- * SOL authentication parameter.
+- */
+-struct Auth
+-{
+-#if BYTE_ORDER == LITTLE_ENDIAN
+- uint8_t privilege : 4; //!< SOL privilege level.
+- uint8_t reserved : 2; //!< Reserved.
+- uint8_t auth : 1; //!< Force SOL payload Authentication.
+- uint8_t encrypt : 1; //!< Force SOL payload encryption.
+-#endif
+-
+-#if BYTE_ORDER == BIG_ENDIAN
+- uint8_t encrypt : 1; //!< Force SOL payload encryption.
+- uint8_t auth : 1; //!< Force SOL payload Authentication.
+- uint8_t reserved : 2; //!< Reserved.
+- uint8_t privilege : 4; //!< SOL privilege level.
+-#endif
+-} __attribute__((packed));
+-
+-/** @struct Accumulate
+- *
+- * Character accumulate interval & Character send threshold.
+- */
+-struct Accumulate
+-{
+- uint8_t interval; //!< Character accumulate interval.
+- uint8_t threshold; //!< Character send threshold.
+-} __attribute__((packed));
+-
+-constexpr uint8_t retryCountMask = 0x07;
+-
+-/** @struct Retry
+- *
+- * SOL retry count and interval.
+- */
+-struct Retry
+-{
+-#if BYTE_ORDER == LITTLE_ENDIAN
+- uint8_t count : 3; //!< SOL retry count.
+- uint8_t reserved : 5; //!< Reserved.
+-#endif
+-
+-#if BYTE_ORDER == BIG_ENDIAN
+- uint8_t reserved : 5; //!< Reserved.
+- uint8_t count : 3; //!< SOL retry count.
+-#endif
+-
+- uint8_t interval; //!< SOL retry interval.
+-} __attribute__((packed));
+-
+-constexpr uint8_t ipmiCCParamNotSupported = 0x80;
+-constexpr uint8_t ipmiCCInvalidSetInProgress = 0x81;
+-constexpr uint8_t ipmiCCWriteReadParameter = 0x82;
+-constexpr uint8_t ipmiCCReadWriteParameter = 0x83;
+-constexpr uint8_t parameterRevision = 0x11;
+-
+-/** @struct SetConfParamsRequest
+- *
+- * IPMI payload for Set SOL configuration parameters command request.
+- */
+-struct SetConfParamsRequest
+-{
+-#if BYTE_ORDER == LITTLE_ENDIAN
+- uint8_t channelNumber : 4; //!< Channel number.
+- uint8_t reserved : 4; //!< Reserved.
+-#endif
+-
+-#if BYTE_ORDER == BIG_ENDIAN
+- uint8_t reserved : 4; //!< Reserved.
+- uint8_t channelNumber : 4; //!< Channel number.
+-#endif
+-
+- uint8_t paramSelector; //!< Parameter selector.
+- union
+- {
+- uint8_t value; //!< Represents one byte SOL parameters.
+- struct Accumulate acc; //!< Character accumulate values.
+- struct Retry retry; //!< Retry values.
+- struct Auth auth; //!< Authentication parameters.
+- };
+-} __attribute__((packed));
+-
+-/** @struct SetConfParamsResponse
+- *
+- * IPMI payload for Set SOL configuration parameters command response.
+- */
+-struct SetConfParamsResponse
+-{
+- uint8_t completionCode; //!< Completion code.
+-} __attribute__((packed));
+-
+-/** @brief Set SOL configuration parameters command.
+- *
+- * @param[in] inPayload - Request data for the command.
+- * @param[in] handler - Reference to the message handler.
+- *
+- * @return Response data for the command.
+- */
+-std::vector<uint8_t> setConfParams(const std::vector<uint8_t>& inPayload,
+- const message::Handler& handler);
+-
+-/** @struct GetConfParamsRequest
+- *
+- * IPMI payload for Get SOL configuration parameters command request.
+- */
+-struct GetConfParamsRequest
+-{
+-#if BYTE_ORDER == LITTLE_ENDIAN
+- uint8_t channelNum : 4; //!< Channel number.
+- uint8_t reserved : 3; //!< Reserved.
+- uint8_t getParamRev : 1; //!< Get parameter or Get parameter revision
+-#endif
+-
+-#if BYTE_ORDER == BIG_ENDIAN
+- uint8_t getParamRev : 1; //!< Get parameter or Get parameter revision
+- uint8_t reserved : 3; //!< Reserved.
+- uint8_t channelNum : 4; //!< Channel number.
+-#endif
+-
+- uint8_t paramSelector; //!< Parameter selector.
+- uint8_t setSelector; //!< Set selector.
+- uint8_t blockSelector; //!< Block selector.
+-} __attribute__((packed));
+-
+-/** @struct GetConfParamsResponse
+- *
+- * IPMI payload for Get SOL configuration parameters command response.
+- */
+-struct GetConfParamsResponse
+-{
+- uint8_t completionCode; //!< Completion code.
+- uint8_t paramRev; //!< Parameter revision.
+-} __attribute__((packed));
+-
+-/** @brief Get SOL configuration parameters command.
+- *
+- * @param[in] inPayload - Request data for the command.
+- * @param[in] handler - Reference to the message handler.
+- *
+- * @return Response data for the command.
+- */
+-std::vector<uint8_t> getConfParams(const std::vector<uint8_t>& inPayload,
+- const message::Handler& handler);
+-
+ } // namespace command
+
+ } // namespace sol
+diff --git a/sol_module.cpp b/sol_module.cpp
+index 2b1fb46..6da82c0 100644
+--- a/sol_module.cpp
++++ b/sol_module.cpp
+@@ -42,12 +42,6 @@ void registerCommands()
+ &getPayloadInfo,
+ session::Privilege::USER,
+ false},
+- // Get SOL Configuration Parameters
+- {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) |
+- static_cast<uint16_t>(::command::NetFns::TRANSPORT) | 0x22},
+- &getConfParams,
+- session::Privilege::USER,
+- false},
+ };
+
+ for (const auto& iter : commands)
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net_%.bbappend
new file mode 100644
index 000000000..214bea189
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net_%.bbappend
@@ -0,0 +1,29 @@
+inherit useradd
+
+# TODO: This should be removed, once up-stream bump up
+# issue is resolved
+#SRC_URI += "git://github.com/openbmc/phosphor-net-ipmid"
+#SRCREV = "b31e969504645f653b58b676d56b01d632dc395c"
+
+USERADD_PACKAGES = "${PN}"
+# add a group called ipmi
+GROUPADD_PARAM_${PN} = "ipmi "
+
+# Default rmcpp iface is eth0; channel 1
+# Add channel 2 instance (eth1)
+RMCPP_EXTRA = "eth1"
+SYSTEMD_SERVICE_${PN} += " \
+ ${PN}@${RMCPP_EXTRA}.service \
+ ${PN}@${RMCPP_EXTRA}.socket \
+ "
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI += " file://0006-Modify-dbus-namespace-of-chassis-control-for-guid.patch \
+ file://0007-Adding-support-for-GetSessionInfo-command.patch \
+ file://0008-Sync-GetSession-Info-cmd-based-on-Upstream-review.patch \
+ file://0009-Add-dbus-interface-for-sol-commands.patch \
+ file://00010-Change-Authentication-Parameter.patch \
+ file://0011-Remove-Get-SOL-Config-Command-from-Netipmid.patch \
+ "
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-sensor-inventory%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-sensor-inventory%.bbappend
new file mode 100644
index 000000000..72d991c7e
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-sensor-inventory%.bbappend
@@ -0,0 +1 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-sensor-inventory%/config.yaml b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-sensor-inventory%/config.yaml
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-sensor-inventory%/config.yaml
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-node-manager-proxy_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-node-manager-proxy_git.bb
new file mode 100644
index 000000000..af83facf6
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-node-manager-proxy_git.bb
@@ -0,0 +1,19 @@
+SUMMARY = "Node Manager Proxy"
+DESCRIPTION = "The Node Manager Proxy provides a simple interface for communicating \
+with Management Engine via IPMB"
+
+SRC_URI = "git://git@github.com/Intel-BMC/node-manager;protocol=ssh"
+SRCREV = "2ab90332828614c95e0ce22c0c95285734b55b65"
+PV = "0.1+git${SRCPV}"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e"
+
+SYSTEMD_SERVICE_${PN} = "node-manager-proxy.service"
+
+DEPENDS = "sdbusplus \
+ phosphor-logging \
+ boost"
+
+S = "${WORKDIR}/git/"
+inherit cmake systemd
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/leds/intel-led-manager-config-native.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/leds/intel-led-manager-config-native.bb
new file mode 100644
index 000000000..dd48df0c6
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/leds/intel-led-manager-config-native.bb
@@ -0,0 +1,21 @@
+SUMMARY = "Phosphor LED Group Management for Intel"
+PR = "r1"
+
+inherit native
+inherit obmc-phosphor-utils
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${INTELBASE}/COPYING.apache-2.0;md5=34400b68072d710fecd0a2940a0d1658"
+
+PROVIDES += "virtual/phosphor-led-manager-config-native"
+
+SRC_URI += "file://led.yaml"
+S = "${WORKDIR}"
+
+# Overwrite the example led layout yaml file prior
+# to building the phosphor-led-manager package
+do_install() {
+ SRC=${S}
+ DEST=${D}${datadir}/phosphor-led-manager
+ install -D ${SRC}/led.yaml ${DEST}/led.yaml
+}
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/leds/intel-led-manager-config/led.yaml b/meta-openbmc-mods/meta-common/recipes-phosphor/leds/intel-led-manager-config/led.yaml
new file mode 100644
index 000000000..533df68a4
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/leds/intel-led-manager-config/led.yaml
@@ -0,0 +1,48 @@
+bmc_booted:
+
+power_on:
+
+status_ok:
+ status_green:
+ Action: 'On'
+ status_amber:
+ Action: 'Off'
+
+status_degraded:
+ status_green:
+ Action: 'Blink'
+ DutyOn: 50
+ Period: 1000
+ status_amber:
+ Action: 'Off'
+
+status_non_critical:
+ status_green:
+ Action: 'Off'
+ status_amber:
+ Action: 'Blink'
+ DutyOn: 50
+ Period: 1000
+
+status_critical:
+ status_green:
+ Action: 'Off'
+ status_amber:
+ Action: 'On'
+
+enclosure_identify:
+ identify:
+ Action: 'On'
+
+enclosure_identify_blink:
+ identify:
+ Action: 'Blink'
+
+cpu0_fault:
+ cpu0fault:
+ Action: 'On'
+
+cpu1_fault:
+ cpu1fault:
+ Action: 'On'
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/logging/phosphor-logging_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/logging/phosphor-logging_%.bbappend
new file mode 100644
index 000000000..b1f4c1ce5
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/logging/phosphor-logging_%.bbappend
@@ -0,0 +1,2 @@
+SRCREV = "30047bf9647215951ba5dfe21ceb3e58a1b405a4"
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/multi-node-manager/multi-node-manager.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/multi-node-manager/multi-node-manager.bb
new file mode 100644
index 000000000..65f578338
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/multi-node-manager/multi-node-manager.bb
@@ -0,0 +1,15 @@
+SUMMARY = "Multi node manager"
+DESCRIPTION = "Daemon to handle chassis level shared resources on multi-node platform"
+
+SRC_URI = "git://git@github.com/Intel-BMC/multi-node-manager.git;protocol=ssh"
+SRCREV = "6a4cd36c0d46df11bdcd3b897bcc9c87e549a076"
+
+PV = "0.1+git${SRCPV}"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e"
+
+SYSTEMD_SERVICE_${PN} = "multi-node-manager.service"
+
+DEPENDS = "boost sdbusplus phosphor-logging i2c-tools"
+inherit cmake systemd
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/preinit-mounts/preinit-mounts.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/preinit-mounts/preinit-mounts.bbappend
new file mode 100644
index 000000000..dc22b3c95
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/preinit-mounts/preinit-mounts.bbappend
@@ -0,0 +1,3 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI = "file://init" \ No newline at end of file
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/preinit-mounts/preinit-mounts/init b/meta-openbmc-mods/meta-common/recipes-phosphor/preinit-mounts/preinit-mounts/init
new file mode 100755
index 000000000..c7f78b1e3
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/preinit-mounts/preinit-mounts/init
@@ -0,0 +1,203 @@
+#!/bin/sh
+
+# Copyright 2017-2019 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+# provide a couple of places in the RO root filesystem
+# that can be made RW with an overlayfs
+
+# start with /proc and /tmp mounted
+[ -e /proc/mounts ] || mount -t proc proc /proc
+grep -q /tmp /proc/mounts || mount -t tmpfs -o rw,nosuid,nodev tmp /tmp
+grep -q /sys /proc/mounts || mount -t sysfs -o rw,nosuid,nodev,noexec sys /sys
+
+# list of things that need to be rw at boot
+NV_OVERLAYS="/etc /var /home"
+
+# place to mount the real ubifs backing store
+RWFS_MNT=/tmp/.rwfs
+
+if grep -q "$RWFS_MNT" /proc/mounts; then
+ # quit - we have already run
+ exit 0
+fi
+mkdir -p "$RWFS_MNT"
+
+mtd_by_name() {
+ local name="$1"
+ local mtd="/dev/$(grep "$name" /proc/mtd | cut -d : -f 1)"
+ echo "$mtd"
+}
+
+mtdnum_by_name() {
+ local name="$1"
+ local mtdnum="$(grep "$name" /proc/mtd | cut -c 4)"
+ echo "$mtdnum"
+}
+
+NV_MTD=rwfs
+NV_MTD_DEV="$(mtd_by_name ${NV_MTD})"
+NV_MTD_NUM="$(mtdnum_by_name ${NV_MTD})"
+
+nvrw() {
+ local p="$1"
+ # Clear the work dir doing overlay mount
+ rm -rf "${RWFS_MNT}${p}.work"
+ mkdir -p "${RWFS_MNT}${p}" "${RWFS_MNT}${p}.work"
+ local mname=$(echo "rwnv${p}" | sed 's,/,,g')
+ local opts="lowerdir=${p},upperdir=${RWFS_MNT}${p},workdir=${RWFS_MNT}${p}.work,sync"
+ mount -t overlay -o "$opts" "$mname" "$p"
+}
+
+targetted_clean() {
+ local LOG_TAG="restore-defaults"
+ # Do not delete server certificates for the web server or ssh
+ echo "removing targetted contents:"
+ cd "${RWFS_MNT}/etc"
+ for file in *; do
+ case $file in
+ # The only files that stay are here:
+ CA|RestoreDefaultConfiguration|dropbear|sdr|server.pem);;
+ # All else get removed.
+ *) echo "remove $file"
+ rm -rf $file;;
+ esac
+ done
+ # nothing should be in the workdir, but clear it just in case
+ rm -rf "${RWFS_MNT}/etc.work"
+
+ # Log files remaining - but not to stdout.
+ echo "Files remaining: $(ls)"
+
+ # clean everything out of /var
+ rm -rf "${RWFS_MNT}/var" "${RWFS_MNT}/var.work"
+}
+
+full_clean() {
+ local OVL=''
+ for OVL in $NV_OVERLAYS; do
+ rm -rf "${RWFS_MNT}${OVL}" "${RWFS_MNT}${OVL}.work"
+ done
+}
+
+# check for full factory reset: if so, ubiformat $NV_MTD_DEV
+bootflags="0x$(sed -n 's/^.*bootflags=\([0-9a-f]*\).*$/\1/p' /proc/cmdline)"
+bootflags=$((bootflags + 0))
+let "restore_op = $bootflags & 0x3"
+if [ $restore_op -eq 3 ]; then
+ ubiformat -y "$NV_MTD_DEV"
+fi
+
+# attach a UBI device to the MTD device
+NV_UBI_DEV="/dev/ubi${NV_MTD_NUM}"
+if [ ! -e $NV_UBI_DEV ]; then
+ if ! ubiattach -m "$NV_MTD_NUM" -d "$NV_MTD_NUM"; then
+ # the attach failed, so format the MTD device and try again
+ echo "Warning! Failed to attach $NV_UBI_DEV to $NV_MTD_DEV."
+ echo "UBI-formatting $NV_MTD_DEV to attach again. Data on this device will be lost."
+ ubiformat -y "$NV_MTD_DEV"
+ ubiattach -m "$NV_MTD_NUM" -d "$NV_MTD_NUM"
+ fi
+fi
+
+# make a UBI volume on the UBI device
+NV_UBI_VOL="${NV_UBI_DEV}_0"
+if [ ! -e $NV_UBI_VOL ]; then
+ ubimkvol "$NV_UBI_DEV" -N "$NV_MTD" -m
+fi
+
+# mount a UBIFS on the UBI volume
+mount -t ubifs "$NV_UBI_VOL" "$RWFS_MNT"
+
+if [ $restore_op -eq 1 ]; then
+ targetted_clean
+elif [ $restore_op -eq 2 ]; then
+ full_clean
+fi
+
+for FS in $NV_OVERLAYS; do
+ nvrw "$FS"
+done
+
+# make sure that /etc/fw_env.config mirrors our current uboot environment
+UENV_MTD_INFO=$(grep UENV /proc/mtd)
+if [ -n "$UENV_MTD_INFO" ]; then
+ UENV_MTD_INFO=$(echo "$UENV_MTD_INFO" | sed 's,^\([^:]*\): \([0-9a-f]*\) \([0-9a-f]*\) .*,/dev/\1 0 0x\2 0x\3,')
+ if ! grep -q "^${UENV_MTD_INFO}$" /etc/fw_env.config; then
+ echo "${UENV_MTD_INFO}" > /etc/fw_env.config
+ echo "Updated fw_env.config"
+ fi
+fi
+
+# work around bug where /etc/machine-id will be mounted with a temporary file
+# if rootfs is read-only and the file is empty
+MACHINE_ID=/etc/machine-id
+generate_machine_id() {
+ systemd-machine-id-setup
+ cp -pf "$MACHINE_ID" "${MACHINE_ID}_bkup"
+}
+
+if [ ! -s "$MACHINE_ID" ]; then
+ # work around - Bug: Overlay fs fails for machine-id due to
+ # origin mismatch. Clean it up, from overlay fs before re-creating
+ # the same.
+ if [ -e "$RWFS_MNT$MACHINE_ID" ]; then
+ umount "/etc"
+ rm -f "$RWFS_MNT$MACHINE_ID"
+ nvrw "/etc"
+ # Restore the machine-id from backup, else generate it.
+ if [ -s "${MACHINE_ID}_bkup" ]; then
+ cp -pf "${MACHINE_ID}_bkup" "${MACHINE_ID}"
+ else
+ generate_machine_id
+ fi
+ echo "Remounted /etc for machine-id origin mismatch"
+ else
+ generate_machine_id
+ fi
+fi
+
+# mount persistent NV filesystem, where immortal settings live
+if ! grep -q sofs /proc/mounts; then
+ mkdir -p /var/sofs
+ SOFS_MTD=sofs
+ SOFS_MTD_DEV="$(mtd_by_name ${SOFS_MTD})"
+ SOFS_MTD_NUM="$(mtdnum_by_name ${SOFS_MTD})"
+ SOFS_UBI_DEV="/dev/ubi${SOFS_MTD_NUM}"
+
+ # attach a UBI device to the MTD device
+ if [ ! -e $SOFS_UBI_DEV ]; then
+ if ! ubiattach -m "$SOFS_MTD_NUM" -d "$SOFS_MTD_NUM"; then
+ # the attach failed, so format the MTD device and try again
+ echo "Warning! Failed to attach $SOFS_UBI_DEV to $SOFS_MTD_DEV."
+ echo "UBI-formatting $SOFS_MTD_DEV to attach again. Data on this device will be lost."
+ ubiformat -y "$SOFS_MTD_DEV"
+ ubiattach -m "$SOFS_MTD_NUM" -d "$SOFS_MTD_NUM"
+ fi
+ fi
+
+ # make a UBI volume on the UBI device
+ SOFS_UBI_VOL="${SOFS_UBI_DEV}_0"
+ if [ ! -e $SOFS_UBI_VOL ]; then
+ ubimkvol "$SOFS_UBI_DEV" -N "$SOFS_MTD" -m
+ fi
+
+ # mount a UBIFS on the UBI volume
+ mount -t ubifs "$SOFS_UBI_VOL" /var/sofs
+fi
+
+echo "Finished mounting non-volatile overlays"
+
+exec /lib/systemd/systemd
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sel-logger/phosphor-sel-logger_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/sel-logger/phosphor-sel-logger_%.bbappend
new file mode 100644
index 000000000..2cdc93e29
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sel-logger/phosphor-sel-logger_%.bbappend
@@ -0,0 +1,7 @@
+# Enable downstream autobump
+SRC_URI = "git://github.com/openbmc/phosphor-sel-logger.git"
+SRCREV = "c4a336fb15464b9f4a7328c02cb43285a6eb1e58"
+
+# Enable threshold monitoring
+EXTRA_OECMAKE += "-DSEL_LOGGER_MONITOR_THRESHOLD_EVENTS=ON"
+EXTRA_OECMAKE += "-DREDFISH_LOG_MONITOR_PULSE_EVENTS=ON"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/selftest/intel-self-test/xyz.openbmc_project.selftest.service b/meta-openbmc-mods/meta-common/recipes-phosphor/selftest/intel-self-test/xyz.openbmc_project.selftest.service
new file mode 100644
index 000000000..b8c3554ae
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/selftest/intel-self-test/xyz.openbmc_project.selftest.service
@@ -0,0 +1,10 @@
+[Unit]
+Description= BMC Self-Test
+
+[Service]
+Restart=always
+ExecStart=/usr/bin/env selftest
+SyslogIdentifier=selftest
+
+[Install]
+WantedBy=multi-user.target
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/selftest/intel-self-test_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/selftest/intel-self-test_git.bb
new file mode 100644
index 000000000..da1d74207
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/selftest/intel-self-test_git.bb
@@ -0,0 +1,38 @@
+SUMMARY = "BMC Self Test service"
+DESCRIPTION = "BMC Self Test service for subsystem diagnosis failure info"
+
+SRC_URI = "git://git@github.com/Intel-BMC/intel-self-test;protocol=ssh"
+
+PV = "1.0+git${SRCPV}"
+SRCREV = "d039998ad2c55aeae4191af30e15bbd3032508c1"
+
+S = "${WORKDIR}/git"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=fa818a259cbed7ce8bc2a22d35a464fc"
+
+inherit cmake
+inherit obmc-phosphor-dbus-service
+inherit obmc-phosphor-systemd
+inherit pkgconfig pythonnative
+
+SYSTEMD_SERVICE_${PN} += "xyz.openbmc_project.selftest.service"
+
+DEPENDS += " \
+ autoconf-archive-native \
+ systemd \
+ sdbusplus \
+ sdbusplus-native \
+ phosphor-logging \
+ phosphor-dbus-interfaces \
+ phosphor-dbus-interfaces-native \
+ "
+
+RDEPENDS_${PN} += " \
+ libsystemd \
+ sdbusplus \
+ phosphor-logging \
+ phosphor-dbus-interfaces \
+ "
+
+EXTRA_OECMAKE = " -DENABLE_GTEST=OFF -DCMAKE_SKIP_RPATH=ON"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend
new file mode 100644
index 000000000..ca3c2eba0
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend
@@ -0,0 +1,7 @@
+SRCREV = "52497fd0fbd8adfe099a99f23515cd0341898e2e"
+SRC_URI = "git://github.com/openbmc/dbus-sensors.git"
+
+DEPENDS_append = " libgpiod"
+
+#todo(cheng) remove this when synced upstream
+SYSTEMD_SERVICE_${PN} += " xyz.openbmc_project.psusensor.service"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-defaults-native.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-defaults-native.bbappend
new file mode 100644
index 000000000..436623234
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-defaults-native.bbappend
@@ -0,0 +1,4 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI += "file://defaults.yaml \
+ "
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-defaults-native/defaults.yaml b/meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-defaults-native/defaults.yaml
new file mode 100644
index 000000000..05d3df07e
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-defaults-native/defaults.yaml
@@ -0,0 +1,209 @@
+/xyz/openbmc_project/control/minimum_ship_level_required:
+ - Interface: xyz.openbmc_project.Control.MinimumShipLevel
+ Properties:
+ MinimumShipLevelRequired:
+ Default: 'true'
+
+/xyz/openbmc_project/control/host0/auto_reboot:
+ - Interface: xyz.openbmc_project.Control.Boot.RebootPolicy
+ Properties:
+ AutoReboot:
+ Default: 'false'
+
+/xyz/openbmc_project/control/host0/boot:
+ - Interface: xyz.openbmc_project.Control.Boot.Source
+ Properties:
+ BootSource:
+ Default: Source::Sources::Default
+ - Interface: xyz.openbmc_project.Control.Boot.Mode
+ Properties:
+ BootMode:
+ Default: Mode::Modes::Regular
+
+/xyz/openbmc_project/control/host0/boot/one_time:
+ - Interface: xyz.openbmc_project.Control.Boot.Source
+ Properties:
+ BootSource:
+ Default: Source::Sources::Default
+ - Interface: xyz.openbmc_project.Control.Boot.Mode
+ Properties:
+ BootMode:
+ Default: Mode::Modes::Regular
+ - Interface: xyz.openbmc_project.Object.Enable
+ Properties:
+ Enabled:
+ Default: 'true'
+
+/xyz/openbmc_project/control/host0/power_cap:
+ - Interface: xyz.openbmc_project.Control.Power.Cap
+ Properties:
+ PowerCap:
+ Default: 0
+ Validation:
+ Type: "range"
+ Validator: "0..1000"
+ Unit: "Watts"
+ PowerCapEnable:
+ Default: 'false'
+
+/xyz/openbmc_project/control/host0/power_restore_policy:
+ - Interface: xyz.openbmc_project.Control.Power.RestorePolicy
+ Properties:
+ PowerRestorePolicy:
+ Default: RestorePolicy::Policy::AlwaysOff
+
+/xyz/openbmc_project/control/power_restore_delay:
+ - Interface: xyz.openbmc_project.Control.Power.RestoreDelay
+ Properties:
+ PowerRestoreDelay:
+ Default: 0
+
+/xyz/openbmc_project/control/host0/acpi_power_state:
+ - Interface: xyz.openbmc_project.Control.Power.ACPIPowerState
+ Properties:
+ SysACPIStatus:
+ Default: ACPIPowerState::ACPI::Unknown
+ DevACPIStatus:
+ Default: ACPIPowerState::ACPI::Unknown
+
+/xyz/openbmc_project/time/owner:
+ - Interface: xyz.openbmc_project.Time.Owner
+ Properties:
+ TimeOwner:
+ Default: Owner::Owners::BMC
+
+/xyz/openbmc_project/time/sync_method:
+ - Interface: xyz.openbmc_project.Time.Synchronization
+ Properties:
+ TimeSyncMethod:
+ Default: Synchronization::Method::NTP
+
+/xyz/openbmc_project/network/host0/intf:
+ - Interface: xyz.openbmc_project.Network.MACAddress
+ Properties:
+ MACAddress:
+ Default: '"00:00:00:00:00:00"'
+ Validation:
+ Type: "regex"
+ Validator: '^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$'
+
+#needs to implement address validation TODO openbmc/issues/2046
+/xyz/openbmc_project/network/host0/intf/addr:
+ - Interface: xyz.openbmc_project.Network.IP
+ Properties:
+ Address:
+ Default: '"0.0.0.0"'
+ PrefixLength:
+ Default: 0
+ Validation:
+ Type: "range"
+ Validator: 0..128
+ Unit: "bits"
+ Origin:
+ Default: IP::AddressOrigin::Static
+ Gateway:
+ Default: '"0.0.0.0"'
+ Type:
+ Default: IP::Protocol::IPv4
+
+/xyz/openbmc_project/control/host0/restriction_mode:
+ - Interface: xyz.openbmc_project.Control.Security.RestrictionMode
+ Properties:
+ RestrictionMode:
+ Default: RestrictionMode::Modes::Provisioning
+
+/xyz/openbmc_project/control/host0/TPMEnable:
+ - Interface: xyz.openbmc_project.Control.TPM.Policy
+ Properties:
+ TPMEnable:
+ Default: 'false'
+
+/xyz/openbmc_project/control/power_supply_redundancy:
+ - Interface: xyz.openbmc_project.Control.PowerSupplyRedundancy
+ Properties:
+ PowerSupplyRedundancyEnabled:
+ Default: 'true'
+
+/xyz/openbmc_project/control/host0/turbo_allowed:
+ - Interface: xyz.openbmc_project.Control.Host.TurboAllowed
+ Properties:
+ TurboAllowed:
+ Default: 'true'
+
+/xyz/openbmc_project/control/host0/systemGUID:
+ - Interface: xyz.openbmc_project.Common.UUID
+ Properties:
+ UUID:
+ Default: '"00000000-0000-0000-0000-000000000000"'
+
+/xyz/openbmc_project/bios:
+ - Interface: xyz.openbmc_project.Inventory.Item.Bios
+ Properties:
+ BiosId:
+ Default: '"NA"'
+
+/xyz/openbmc_project/control/processor_error_config:
+ - Interface: xyz.openbmc_project.Control.Processor.ErrConfig
+ Properties:
+ ResetCfg:
+ Default: 0
+ ResetErrorOccurrenceCounts:
+ Default: 0
+
+/com/intel/control/ocotshutdown_policy_config:
+ - Interface: com.intel.Control.OCOTShutdownPolicy
+ Properties:
+ OCOTPolicy:
+ Default: OCOTShutdownPolicy::Policy::NoShutdownOnOCOT
+
+/xyz/openbmc_project/control/chassis_capabilities_config:
+ - Interface: xyz.openbmc_project.Control.ChassisCapabilities
+ Properties:
+ CapabilitiesFlags:
+ Default: 0
+ FRUDeviceAddress:
+ Default: 0x20
+ SDRDeviceAddress:
+ Default: 0x20
+ SELDeviceAddress:
+ Default: 0x20
+ SMDeviceAddress:
+ Default: 0x20
+ BridgeDeviceAddress:
+ Default: 0x20
+
+/xyz/openbmc_project/control/thermal_mode:
+ - Interface: xyz.openbmc_project.Control.ThermalMode
+ Properties:
+ Current:
+ Default: '"Performance"'
+ Supported:
+ Default: '{"Acoustic", "Performance"}'
+
+/xyz/openbmc_project/control/cfm_limit:
+ - Interface: xyz.openbmc_project.Control.CFMLimit
+ Properties:
+ Limit:
+ Default: 0
+
+/xyz/openbmc_project/ipmi/sol:
+ - Interface: xyz.openbmc_project.Ipmi.SOL
+ Properties:
+ Progress:
+ Default: 0
+ Enable:
+ Default: 'true'
+ ForceEncryption:
+ Default: 'true'
+ ForceAuthentication:
+ Default: 'true'
+ Privilege:
+ Default: 4
+ AccumulateIntervalMS:
+ Default: 12
+ Threshold:
+ Default: 96
+ RetryCount:
+ Default: 6
+ RetryIntervalMS:
+ Default: 20
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-manager/0001-settings-initialize-data-file-with-default-setting.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-manager/0001-settings-initialize-data-file-with-default-setting.patch
new file mode 100644
index 000000000..fcf2415d6
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-manager/0001-settings-initialize-data-file-with-default-setting.patch
@@ -0,0 +1,37 @@
+From 9e99aa4f72f4420e03ec2e4a29816eae43c5e748 Mon Sep 17 00:00:00 2001
+From: "Jia, Chunhui" <chunhui.jia@intel.com>
+Date: Tue, 29 May 2018 16:16:06 +0800
+Subject: [PATCH] [settings] initialize data file with default setting
+
+Current code trys to load settings from file at startup. When file
+does not exist, it will just use default setting. However, it will
+still load default on next reboot because no one create files.
+
+This change creates file as well when daemon loads default so next
+time daemon could load/save from file.
+
+Signed-off-by: Jia, Chunhui <chunhui.jia@intel.com>
+---
+ settings_manager.mako.hpp | 3 +++
+ 1 file changed, 3 insertions(+)
+ mode change 100644 => 100755 settings_manager.mako.hpp
+
+diff --git a/settings_manager.mako.hpp b/settings_manager.mako.hpp
+old mode 100644
+new mode 100755
+index 09a5a1f..cd592a0
+--- a/settings_manager.mako.hpp
++++ b/settings_manager.mako.hpp
+@@ -323,6 +323,9 @@ class Manager
+ else
+ {
+ initSetting${index}();
++ std::ofstream ostr(path.c_str(), std::ios::out);
++ cereal::JSONOutputArchive oarchive(ostr);
++ oarchive(*std::get<${index}>(settings)); //create file with default
+ }
+ }
+ catch (cereal::Exception& e)
+--
+2.16.2
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-manager_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-manager_%.bbappend
new file mode 100644
index 000000000..f5c924b31
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/settings/phosphor-settings-manager_%.bbappend
@@ -0,0 +1,9 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI += "file://0001-settings-initialize-data-file-with-default-setting.patch \
+ "
+
+DEPENDS += "intel-dbus-interfaces intel-dbus-interfaces-native"
+RDEPENDS_${PN} += "intel-dbus-interfaces"
+
+EXTRA_OEMAKE += "LDFLAGS='${LDFLAGS} -lintel_dbus'"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/settings/settings_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/settings/settings_git.bb
new file mode 100644
index 000000000..aadb48fbf
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/settings/settings_git.bb
@@ -0,0 +1,20 @@
+SUMMARY = "Settings"
+
+SRC_URI = "git://git-amr-2.devtools.intel.com:29418/openbmc-provingground.git;protocol=ssh"
+SRCREV = "4373d99e1edcbb4c7233abde3a5e53690693007b"
+PV = "0.1+git${SRCPV}"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${INTELBASE}/COPYING.apache-2.0;md5=34400b68072d710fecd0a2940a0d1658"
+
+SYSTEMD_SERVICE_${PN} = "settings.service"
+
+DEPENDS = "boost \
+ nlohmann-json \
+ sdbusplus"
+
+S = "${WORKDIR}/git/settings"
+inherit cmake systemd
+
+EXTRA_OECMAKE = "-DYOCTO=1"
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/special-mode-mgr/special-mode-mgr_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/special-mode-mgr/special-mode-mgr_git.bb
new file mode 100644
index 000000000..99cac7931
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/special-mode-mgr/special-mode-mgr_git.bb
@@ -0,0 +1,28 @@
+SUMMARY = "Special mode manager daemon to handle manufacturing modes"
+DESCRIPTION = "Daemon exposes the manufacturing mode property"
+
+PV = "1.0+git${SRCPV}"
+
+S = "${WORKDIR}/git/special-mode-mgr"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e"
+
+SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh"
+SRCREV = "4373d99e1edcbb4c7233abde3a5e53690693007b"
+
+inherit cmake systemd
+SYSTEMD_SERVICE_${PN} = "specialmodemgr.service"
+
+DEPENDS += " \
+ systemd \
+ sdbusplus \
+ sdbusplus-native \
+ phosphor-logging \
+ boost \
+ "
+RDEPENDS_${PN} += " \
+ libsystemd \
+ sdbusplus \
+ phosphor-logging \
+ "
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/srvcfg-manager/srvcfg-manager_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/srvcfg-manager/srvcfg-manager_git.bb
new file mode 100644
index 000000000..52ebdfd88
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/srvcfg-manager/srvcfg-manager_git.bb
@@ -0,0 +1,28 @@
+SUMMARY = "Service configuration manager daemon to control service properties"
+DESCRIPTION = "Daemon controls service properies like port, channels, state etc.."
+
+PV = "1.0+git${SRCPV}"
+
+S = "${WORKDIR}/git/srvcfg-manager"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e"
+
+SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh"
+SRCREV = "4373d99e1edcbb4c7233abde3a5e53690693007b"
+
+inherit cmake systemd
+SYSTEMD_SERVICE_${PN} = "srvcfg-manager.service"
+
+DEPENDS += " \
+ systemd \
+ sdbusplus \
+ sdbusplus-native \
+ phosphor-logging \
+ boost \
+ "
+RDEPENDS_${PN} += " \
+ libsystemd \
+ sdbusplus \
+ phosphor-logging \
+ "
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0001-Modify-dbus-interface-for-power-control.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0001-Modify-dbus-interface-for-power-control.patch
new file mode 100644
index 000000000..fac9b52f1
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0001-Modify-dbus-interface-for-power-control.patch
@@ -0,0 +1,38 @@
+From d34a2a5f6ca0564275ed0e2664624525cad64585 Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Fri, 13 Jul 2018 09:08:52 +0800
+Subject: [PATCH] Modify dbus interface for power control
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Switch power control service namespace from “org” to “xyz”,
+to compatible with new intel-chassis services
+
+Change-Id: I1bf5e218f72eb9fd4fb6f203c35479818d12b1fa
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ chassis_state_manager.cpp | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/chassis_state_manager.cpp b/chassis_state_manager.cpp
+index 03dd176..05e2440 100644
+--- a/chassis_state_manager.cpp
++++ b/chassis_state_manager.cpp
+@@ -63,10 +63,11 @@ void Chassis::determineInitialState()
+ {
+ sdbusplus::message::variant<int> pgood = -1;
+ auto method = this->bus.new_method_call(
+- "org.openbmc.control.Power", "/org/openbmc/control/power0",
++ "xyz.openbmc_project.Chassis.Control.Power",
++ "/xyz/openbmc_project/Chassis/Control/Power0",
+ "org.freedesktop.DBus.Properties", "Get");
+
+- method.append("org.openbmc.control.Power", "pgood");
++ method.append("xyz.openbmc_project.Chassis.Control.Power", "pgood");
+ try
+ {
+ auto reply = this->bus.call(method);
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0002-Capture-host-restart-cause.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0002-Capture-host-restart-cause.patch
new file mode 100644
index 000000000..2adff372e
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0002-Capture-host-restart-cause.patch
@@ -0,0 +1,338 @@
+From ed64fe7379a259a822aca69e70426a2b07aad25d Mon Sep 17 00:00:00 2001
+From: Kuiying Wang <kuiying.wang@intel.com>
+Date: Tue, 7 Aug 2018 16:43:00 +0800
+Subject: [PATCH] Capture host restart cause
+
+Capture host restart cause on power/reset button pressed,
+ipmi command/webui, host OS reboot(Ctrl-Alt-Del),
+and power restore policy settings.
+Save the restart cause into file system,
+and restore it when BMC boot up.
+
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ configure.ac | 4 +-
+ discover_system_state.cpp | 14 +++++
+ host_state_manager.cpp | 17 ++++++
+ host_state_manager.hpp | 148 +++++++++++++++++++++++++++++++++++++++++++++-
+ 4 files changed, 178 insertions(+), 5 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 7919ec5..051a0c0 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -52,9 +52,9 @@ AC_ARG_VAR(HOST_RUNNING_FILE, [File to create if host is running])
+ AS_IF([test "x$HOST_RUNNING_FILE" == "x"], [HOST_RUNNING_FILE="/run/openbmc/host@%u-on"])
+ AC_DEFINE_UNQUOTED([HOST_RUNNING_FILE], ["$HOST_RUNNING_FILE"], [File to create if host is running])
+
+-AC_ARG_VAR(HOST_STATE_PERSIST_PATH, [Path of file for storing requested host state.])
++AC_ARG_VAR(HOST_STATE_PERSIST_PATH, [Path of file for storing host state.])
+ AS_IF([test "x$HOST_STATE_PERSIST_PATH" == "x"], \
+- [HOST_STATE_PERSIST_PATH="/var/lib/phosphor-state-manager/requestedHostTransition"])
++ [HOST_STATE_PERSIST_PATH="/var/lib/phosphor-state-manager/hostState"])
+ AC_DEFINE_UNQUOTED([HOST_STATE_PERSIST_PATH], ["$HOST_STATE_PERSIST_PATH"], \
+ [Path of file for storing requested host state.])
+
+diff --git a/discover_system_state.cpp b/discover_system_state.cpp
+index 3a38152..0b5798a 100644
+--- a/discover_system_state.cpp
++++ b/discover_system_state.cpp
+@@ -12,6 +12,7 @@
+ #include "settings.hpp"
+ #include "xyz/openbmc_project/Common/error.hpp"
+ #include "xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp"
++#include <xyz/openbmc_project/State/Host/server.hpp>
+
+ namespace phosphor
+ {
+@@ -181,6 +182,10 @@ int main(int argc, char** argv)
+ log<level::INFO>("power_policy=ALWAYS_POWER_ON, powering host on");
+ setProperty(bus, hostPath, HOST_BUSNAME, "RequestedHostTransition",
+ convertForMessage(server::Host::Transition::On));
++
++ setProperty(
++ bus, hostPath, HOST_BUSNAME, "HostRestartCause",
++ convertForMessage(server::Host::RestartCause::PowerPolicyAlwaysOn));
+ }
+ else if (RestorePolicy::Policy::Restore ==
+ RestorePolicy::convertPolicyFromString(powerPolicy))
+@@ -192,6 +197,15 @@ int main(int argc, char** argv)
+ getProperty(bus, hostPath, HOST_BUSNAME, "RequestedHostTransition");
+ setProperty(bus, hostPath, HOST_BUSNAME, "RequestedHostTransition",
+ hostReqState);
++
++ if (server::Host::convertTransitionFromString(hostReqState) ==
++ server::Host::Transition::On)
++ {
++ setProperty(
++ bus, hostPath, HOST_BUSNAME, "HostRestartCause",
++ convertForMessage(
++ server::Host::RestartCause::PowerPolicyPreviousState));
++ }
+ }
+
+ return 0;
+diff --git a/host_state_manager.cpp b/host_state_manager.cpp
+index 7d661dd..0e00e78 100644
+--- a/host_state_manager.cpp
++++ b/host_state_manager.cpp
+@@ -308,6 +308,15 @@ bool Host::deserialize(const fs::path& path)
+ }
+ }
+
++void Host::restoreHostRestartCause()
++{
++ if (!deserialize(HOST_STATE_PERSIST_PATH))
++ {
++ // set to default value
++ server::Host::hostRestartCause(server::Host::RestartCause::Unknown);
++ }
++}
++
+ Host::Transition Host::requestedHostTransition(Transition value)
+ {
+ log<level::INFO>("Host State transaction request",
+@@ -321,6 +330,7 @@ Host::Transition Host::requestedHostTransition(Transition value)
+ // check of this count will occur
+ if (value != server::Host::Transition::Off)
+ {
++ hostRestartCause(RestartCause::IpmiCommand);
+ decrementRebootCount();
+ }
+
+@@ -353,6 +363,13 @@ Host::HostState Host::currentHostState(HostState value)
+ return server::Host::currentHostState(value);
+ }
+
++Host::RestartCause Host::hostRestartCause(RestartCause value)
++{
++ auto retVal = server::Host::hostRestartCause(value);
++ serialize();
++ return retVal;
++}
++
+ } // namespace manager
+ } // namespace state
+ } // namespace phosphor
+diff --git a/host_state_manager.hpp b/host_state_manager.hpp
+index 2b00777..afd8aa3 100644
+--- a/host_state_manager.hpp
++++ b/host_state_manager.hpp
+@@ -32,6 +32,22 @@ using namespace phosphor::logging;
+ namespace sdbusRule = sdbusplus::bus::match::rules;
+ namespace fs = std::experimental::filesystem;
+
++const static constexpr char* powerButtonPath =
++ "/xyz/openbmc_project/Chassis/Buttons/Power0";
++const static constexpr char* powerButtonIntf =
++ "xyz.openbmc_project.Chassis.Buttons.Power";
++const static constexpr char* resetButtonPath =
++ "/xyz/openbmc_project/Chassis/Buttons/Reset0";
++const static constexpr char* resetButtonIntf =
++ "xyz.openbmc_project.Chassis.Buttons.Reset";
++
++const static constexpr char* powerControlService =
++ "xyz.openbmc_project.Chassis.Control.Power";
++const static constexpr char* powerControlPath =
++ "/xyz/openbmc_project/Chassis/Control/Power0";
++const static constexpr char* powerControlInterface =
++ "xyz.openbmc_project.Chassis.Control.Power";
++
+ /** @class Host
+ * @brief OpenBMC host state management implementation.
+ * @details A concrete implementation for xyz.openbmc_project.State.Host
+@@ -59,8 +75,93 @@ class Host : public HostInherit
+ sdbusRule::interface("org.freedesktop.systemd1.Manager"),
+ std::bind(std::mem_fn(&Host::sysStateChange), this,
+ std::placeholders::_1)),
+- settings(bus)
++ settings(bus),
++ powerButtonPressedSignal(
++ bus,
++ sdbusRule::type::signal() + sdbusRule::member("Pressed") +
++ sdbusRule::path(powerButtonPath) +
++ sdbusRule::interface(powerButtonIntf),
++ [this](sdbusplus::message::message& msg) {
++ phosphor::logging::log<phosphor::logging::level::INFO>(
++ "powerButtonPressedSignal callback function is called...");
++ this->hostRestartCause(this->RestartCause::PowerButton);
++ this->powerButtonPressed = true;
++ return;
++ }),
++ resetButtonPressedSignal(
++ bus,
++ sdbusRule::type::signal() + sdbusRule::member("Pressed") +
++ sdbusRule::path(resetButtonPath) +
++ sdbusRule::interface(resetButtonIntf),
++ [this](sdbusplus::message::message& msg) {
++ phosphor::logging::log<phosphor::logging::level::INFO>(
++ "resetButtonPressedSignal callback function is called...");
++ this->hostRestartCause(this->RestartCause::ResetButton);
++ this->resetButtonPressed = true;
++ return;
++ }),
++ postCompletePropSignal(
++ bus,
++ sdbusplus::bus::match::rules::propertiesChanged(
++ powerControlPath, powerControlInterface),
++ [this](sdbusplus::message::message& msg) {
++ phosphor::logging::log<phosphor::logging::level::INFO>(
++ "postCompletePropSignal callback function is called...");
++
++ using DbusVariant = sdbusplus::message::variant<
++ std::string, bool, uint8_t, uint16_t, int16_t, uint32_t,
++ int32_t, uint64_t, int64_t, double>;
++
++ std::map<std::string, DbusVariant> props;
++ std::vector<std::string> inval;
++ std::string iface;
++ msg.read(iface, props, inval);
++
++ for (const auto& t : props)
++ {
++ auto key = t.first;
++ auto value = t.second;
++
++ if (key == "state")
++ {
++ this->powerStateChanged = true;
++ }
++
++ else if (key == "pgood")
++ {
++ this->pgood =
++ sdbusplus::message::variant_ns::get<int32_t>(value);
++ }
++
++ else if (key == "post_complete")
++ {
++ bool postState =
++ sdbusplus::message::variant_ns::get<bool>(value);
++
++ if (!postState && this->pgood)
++ {
++ if (!this->resetButtonPressed &&
++ !this->powerButtonPressed &&
++ !this->powerStateChanged)
++ {
++ phosphor::logging::log<
++ phosphor::logging::level::INFO>(
++ "OEM Reset");
++ this->hostRestartCause(this->RestartCause::OEM);
++ }
++ this->powerButtonPressed = false;
++ this->powerStateChanged = false;
++ this->resetButtonPressed = false;
++ }
++ }
++ }
++ })
+ {
++ powerButtonPressed = false;
++ powerStateChanged = false;
++ resetButtonPressed = false;
++ pgood = 0;
++
+ // Enable systemd signals
+ subscribeToSystemdSignals();
+
+@@ -69,8 +170,29 @@ class Host : public HostInherit
+
+ attemptsLeft(BOOT_COUNT_MAX_ALLOWED);
+
++ restoreHostRestartCause(); // restore host restart cause from persisted
++ // file
++
+ // We deferred this until we could get our property correct
+ this->emit_object_added();
++ sdbusplus::message::variant<int32_t> pgoodProp = -1;
++ auto method =
++ this->bus.new_method_call(powerControlService, powerControlPath,
++ "org.freedesktop.DBus.Properties", "Get");
++
++ method.append(powerControlInterface, "pgood");
++ try
++ {
++ auto reply = this->bus.call(method);
++ reply.read(pgoodProp);
++ pgood = sdbusplus::message::variant_ns::get<int>(pgoodProp);
++ }
++ catch (const sdbusplus::exception::SdBusError& e)
++ {
++ log<level::ERR>("Error performing call to get pgood",
++ entry("NAME=%s", e.name()),
++ entry("ERROR=%s", e.what()));
++ }
+ }
+
+ /** @brief Set value of HostTransition */
+@@ -85,6 +207,9 @@ class Host : public HostInherit
+ /** @brief Set value of CurrentHostState */
+ HostState currentHostState(HostState value) override;
+
++ /** @brief Set value of HostRestartCause */
++ RestartCause hostRestartCause(RestartCause value) override;
++
+ /**
+ * @brief Set host reboot count to default
+ *
+@@ -192,7 +317,9 @@ class Host : public HostInherit
+ server::Progress::bootProgress()),
+ convertForMessage(
+ sdbusplus::xyz::openbmc_project::State::OperatingSystem::
+- server::Status::operatingSystemState()));
++ server::Status::operatingSystemState()),
++ convertForMessage(sdbusplus::xyz::openbmc_project::State::
++ server::Host::hostRestartCause()));
+ }
+
+ /** @brief Function required by Cereal to perform deserialization.
+@@ -208,7 +335,8 @@ class Host : public HostInherit
+ std::string reqTranState;
+ std::string bootProgress;
+ std::string osState;
+- archive(reqTranState, bootProgress, osState);
++ std::string restartCause;
++ archive(reqTranState, bootProgress, osState, restartCause);
+ auto reqTran = Host::convertTransitionFromString(reqTranState);
+ // When restoring, set the requested state with persistent value
+ // but don't call the override which would execute it
+@@ -219,6 +347,8 @@ class Host : public HostInherit
+ sdbusplus::xyz::openbmc_project::State::OperatingSystem::server::
+ Status::operatingSystemState(
+ Host::convertOSStatusFromString(osState));
++ sdbusplus::xyz::openbmc_project::State::server::Host::hostRestartCause(
++ Host::convertRestartCauseFromString(restartCause));
+ }
+
+ /** @brief Serialize and persist requested host state
+@@ -239,6 +369,9 @@ class Host : public HostInherit
+ */
+ bool deserialize(const fs::path& path);
+
++ /** @brief Used to restore HostRestartCause value from persisted file */
++ void restoreHostRestartCause();
++
+ /** @brief Persistent sdbusplus DBus bus connection. */
+ sdbusplus::bus::bus& bus;
+
+@@ -247,6 +380,15 @@ class Host : public HostInherit
+
+ // Settings objects of interest
+ settings::Objects settings;
++
++ bool resetButtonPressed;
++ bool powerButtonPressed;
++ bool powerStateChanged;
++ int32_t pgood;
++
++ sdbusplus::bus::match_t powerButtonPressedSignal;
++ sdbusplus::bus::match_t resetButtonPressedSignal;
++ sdbusplus::bus::match_t postCompletePropSignal;
+ };
+
+ } // namespace manager
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0003-Use-warm-reboot-for-the-Reboot-host-state-transition.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0003-Use-warm-reboot-for-the-Reboot-host-state-transition.patch
new file mode 100644
index 000000000..40722c3c9
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0003-Use-warm-reboot-for-the-Reboot-host-state-transition.patch
@@ -0,0 +1,71 @@
+From 8a7f73a0688524c71023da89e8cb5578dac16f5d Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Fri, 8 Mar 2019 17:21:49 +0800
+Subject: [PATCH] Use warm-reboot for the Reboot host state transition
+
+The same as reset button pressing, the pgood signal will keep on during the reboot
+
+Tested By:
+ipmitool chassis power reset
+The pgood(gpio219) will be keep high during the reset process
+
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ host_state_manager.cpp | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/host_state_manager.cpp b/host_state_manager.cpp
+index 03d210d..8fac348 100644
+--- a/host_state_manager.cpp
++++ b/host_state_manager.cpp
+@@ -44,8 +44,9 @@ constexpr auto HOST_STATE_SOFT_POWEROFF_TGT = "obmc-host-shutdown@0.target";
+ constexpr auto HOST_STATE_POWEROFF_TGT = "obmc-host-stop@0.target";
+ constexpr auto HOST_STATE_POWERON_TGT = "obmc-host-start@0.target";
+ constexpr auto HOST_STATE_POWERON_MIN_TGT = "obmc-host-startmin@0.target";
+-constexpr auto HOST_STATE_REBOOT_TGT = "obmc-host-reboot@0.target";
++constexpr auto HOST_STATE_REBOOT_TGT = "obmc-host-warm-reset@0.target";
+ constexpr auto HOST_STATE_QUIESCE_TGT = "obmc-host-quiesce@0.target";
++constexpr auto hostStateRebootService = "intel-power-warm-reset@0.service";
+
+ constexpr auto ACTIVE_STATE = "active";
+ constexpr auto ACTIVATING_STATE = "activating";
+@@ -168,6 +169,7 @@ bool Host::stateActive(const std::string& target)
+
+ const auto& currentStateStr =
+ sdbusplus::message::variant_ns::get<std::string>(currentState);
++
+ return currentStateStr == ACTIVE_STATE ||
+ currentStateStr == ACTIVATING_STATE;
+ }
+@@ -236,18 +238,22 @@ void Host::sysStateChange(sdbusplus::message::message& msg)
+ // Read the msg and populate each variable
+ msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
+
+- if ((newStateUnit == HOST_STATE_POWEROFF_TGT) &&
+- (newStateResult == "done") &&
+- (!stateActive(HOST_STATE_POWERON_MIN_TGT)))
++ if (((newStateUnit == HOST_STATE_POWEROFF_TGT) &&
++ (newStateResult == "done") &&
++ (!stateActive(HOST_STATE_POWERON_MIN_TGT))) ||
++ ((newStateUnit == hostStateRebootService) &&
++ (newStateResult == "done")))
+ {
+ log<level::INFO>("Received signal that host is off");
+ this->currentHostState(server::Host::HostState::Off);
+ this->bootProgress(bootprogress::Progress::ProgressStages::Unspecified);
+ this->operatingSystemState(osstatus::Status::OSStatus::Inactive);
+ }
+- else if ((newStateUnit == HOST_STATE_POWERON_MIN_TGT) &&
+- (newStateResult == "done") &&
+- (stateActive(HOST_STATE_POWERON_MIN_TGT)))
++ else if (((newStateUnit == HOST_STATE_POWERON_MIN_TGT) &&
++ (newStateResult == "done") &&
++ (stateActive(HOST_STATE_POWERON_MIN_TGT))) ||
++ ((newStateUnit == HOST_STATE_REBOOT_TGT) &&
++ (newStateResult == "done")))
+ {
+ log<level::INFO>("Received signal that host is running");
+ this->currentHostState(server::Host::HostState::Running);
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0004-Add-Power-Restore-delay-support.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0004-Add-Power-Restore-delay-support.patch
new file mode 100644
index 000000000..31cb31079
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0004-Add-Power-Restore-delay-support.patch
@@ -0,0 +1,141 @@
+From 0edff651156ae63b6a73d9cb81e5e76cc6ae501a Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Fri, 12 Apr 2019 18:43:06 +0800
+Subject: [PATCH] Add Power Restore delay support
+
+That takes effect whenever the BMC
+automatically turns on the system due
+to the Power Restore Policy setting
+
+Tested:
+Set power restore delay:
+ipmitool raw 0x30 0x54 0 7
+Set restore policy as always-on:
+ipmitool chassis policy always-on
+AC off/on, check the journal log, the host will start boot after 7 seconds delay
+
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ discover_system_state.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 68 insertions(+), 3 deletions(-)
+
+diff --git a/discover_system_state.cpp b/discover_system_state.cpp
+index 0b5798a..298ae5b 100644
+--- a/discover_system_state.cpp
++++ b/discover_system_state.cpp
+@@ -1,5 +1,4 @@
+ #include <getopt.h>
+-#include <iostream>
+ #include <map>
+ #include <string>
+ #include <config.h>
+@@ -114,6 +113,49 @@ void setProperty(sdbusplus::bus::bus& bus, const std::string& path,
+ return;
+ }
+
++int getPowerRestoreDelay(sdbusplus::bus::bus& bus, uint16_t& delay)
++{
++ static constexpr const char* powerRestoreDelayObjPath =
++ "/xyz/openbmc_project/control/power_restore_delay";
++ static constexpr const char* powerRestoreDelayIntf =
++ "xyz.openbmc_project.Control.Power.RestoreDelay";
++ static constexpr const char* powerRestoreDelayProp = "PowerRestoreDelay";
++
++ std::string service =
++ getService(bus, powerRestoreDelayObjPath, powerRestoreDelayIntf);
++
++ sdbusplus::message::message method = bus.new_method_call(
++ service.c_str(), powerRestoreDelayObjPath, PROPERTY_INTERFACE, "Get");
++
++ method.append(powerRestoreDelayIntf, powerRestoreDelayProp);
++
++ try
++ {
++ auto reply = bus.call(method);
++ sdbusplus::message::variant<uint16_t> variant;
++ reply.read(variant);
++ delay = sdbusplus::message::variant_ns::get<uint16_t>(variant);
++ }
++ catch (sdbusplus::exception_t&)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Failed to get property",
++ phosphor::logging::entry("PROPERTY=%s", powerRestoreDelayProp),
++ phosphor::logging::entry("PATH=%s", powerRestoreDelayObjPath),
++ phosphor::logging::entry("INTERFACE=%s", powerRestoreDelayIntf));
++ return -1;
++ }
++ return 0;
++}
++
++void applyPowerRestoreDelay(uint16_t delay)
++{
++ if (delay > 0)
++ {
++ log<level::INFO>("Apply Power Restore Delay", entry("DELAY=%d", delay));
++ std::this_thread::sleep_for(std::chrono::milliseconds(1000 * delay));
++ }
++}
+ } // namespace manager
+ } // namespace state
+ } // namespace phosphor
+@@ -176,13 +218,27 @@ int main(int argc, char** argv)
+ log<level::INFO>("Host power is off, checking power policy",
+ entry("POWER_POLICY=%s", powerPolicy.c_str()));
+
++ uint16_t delay = 0;
++ int ret = getPowerRestoreDelay(bus, delay);
++
++ if (ret != 0)
++ {
++ log<level::WARNING>("getPowerRestoreDelay failed!");
++ delay = 0;
++ }
++
+ if (RestorePolicy::Policy::AlwaysOn ==
+ RestorePolicy::convertPolicyFromString(powerPolicy))
+ {
++ applyPowerRestoreDelay(delay);
++
+ log<level::INFO>("power_policy=ALWAYS_POWER_ON, powering host on");
++
+ setProperty(bus, hostPath, HOST_BUSNAME, "RequestedHostTransition",
+ convertForMessage(server::Host::Transition::On));
+
++ // Host on, needs to set the restart cause after host transition
++ // since host transition will change the restart cause
+ setProperty(
+ bus, hostPath, HOST_BUSNAME, "HostRestartCause",
+ convertForMessage(server::Host::RestartCause::PowerPolicyAlwaysOn));
+@@ -195,17 +251,26 @@ int main(int argc, char** argv)
+ // Read last requested state and re-request it to execute it
+ auto hostReqState =
+ getProperty(bus, hostPath, HOST_BUSNAME, "RequestedHostTransition");
+- setProperty(bus, hostPath, HOST_BUSNAME, "RequestedHostTransition",
+- hostReqState);
+
+ if (server::Host::convertTransitionFromString(hostReqState) ==
+ server::Host::Transition::On)
+ {
++ applyPowerRestoreDelay(delay);
++ setProperty(bus, hostPath, HOST_BUSNAME, "RequestedHostTransition",
++ hostReqState);
++
++ // Host on, needs to set the restart cause after host transition
++ // since host transition will change the restart cause
+ setProperty(
+ bus, hostPath, HOST_BUSNAME, "HostRestartCause",
+ convertForMessage(
+ server::Host::RestartCause::PowerPolicyPreviousState));
+ }
++ else
++ {
++ setProperty(bus, hostPath, HOST_BUSNAME, "RequestedHostTransition",
++ hostReqState);
++ }
+ }
+
+ return 0;
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/phosphor-reboot-host@.service b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/phosphor-reboot-host@.service
new file mode 100644
index 000000000..ffde01ca3
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/phosphor-reboot-host@.service
@@ -0,0 +1,18 @@
+[Unit]
+Description=Reboot host%i
+Wants=obmc-host-stop@%i.target
+After=obmc-host-stop@%i.target
+
+[Service]
+#ExecStart={base_bindir}/systemctl start obmc-host-start@%i.target
+# This service is starting another target that conflicts with the
+# target this service is running in. OpenBMC needs a refactor of
+# how it does its host reset path. Until then, this short term
+# solution does the job.
+# Since this is a part of the reboot target, call the startmin
+# target which does the minimum required to start the host.
+ExecStart=/bin/sh -c "sleep 10 && systemctl start obmc-host-startmin@%i.target"
+
+
+[Install]
+WantedBy=obmc-host-reboot@%i.target
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/phosphor-reset-host-check@.service b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/phosphor-reset-host-check@.service
new file mode 100644
index 000000000..13b8f0fca
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/phosphor-reset-host-check@.service
@@ -0,0 +1,19 @@
+[Unit]
+Description=Check Host%i status on BMC reset
+Wants=mapper-wait@-xyz-openbmc_project-control-host%i.service
+After=mapper-wait@-xyz-openbmc_project-control-host%i.service
+Wants=obmc-host-reset-running@%i.target
+Before=obmc-host-reset-running@%i.target
+Wants=op-reset-chassis-on@%i.service
+After=op-reset-chassis-on@%i.service
+Conflicts=obmc-host-stop@%i.target
+ConditionPathExists=/run/openbmc/chassis@%i-on
+
+[Service]
+RemainAfterExit=yes
+Type=oneshot
+ExecStart=/bin/sh -c "if [ $(busctl get-property `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power vrd_good | sed 's/i\s*[1]/on/' | grep on | wc -l) != 0 ]; then mkdir -p /run/openbmc/ && touch /run/openbmc/host@%i-on; fi"
+SyslogIdentifier=phosphor-host-check
+
+[Install]
+WantedBy=obmc-host-reset@%i.target
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/phosphor-reset-host-reboot-attempts@.service b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/phosphor-reset-host-reboot-attempts@.service
new file mode 100644
index 000000000..87c750c57
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/phosphor-reset-host-reboot-attempts@.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Reset host reboot counter
+Wants=mapper-wait@-xyz-openbmc_project-state-host%i.service
+After=mapper-wait@-xyz-openbmc_project-state-host%i.service
+ConditionPathExists=!/run/openbmc/host@%i-on
+
+[Service]
+Restart=no
+Type=oneshot
+ExecStart=/bin/sh -c "busctl set-property `mapper get-service /xyz/openbmc_project/state/host%i` /xyz/openbmc_project/state/host%i xyz.openbmc_project.Control.Boot.RebootAttempts AttemptsLeft u 3"
+StartLimitInterval=0
+
+[Install]
+WantedBy=obmc-host-start@%i.target
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager_%.bbappend
new file mode 100644
index 000000000..63155ce0d
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager_%.bbappend
@@ -0,0 +1,10 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI += "file://0001-Modify-dbus-interface-for-power-control.patch \
+ file://phosphor-reboot-host@.service \
+ file://phosphor-reset-host-reboot-attempts@.service \
+ file://phosphor-reset-host-check@.service \
+ file://0002-Capture-host-restart-cause.patch \
+ file://0003-Use-warm-reboot-for-the-Reboot-host-state-transition.patch \
+ file://0004-Add-Power-Restore-delay-support.patch \
+ "
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/state/post-code-manager/0001-Implement-post-code-manager.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/state/post-code-manager/0001-Implement-post-code-manager.patch
new file mode 100644
index 000000000..8915484cd
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/state/post-code-manager/0001-Implement-post-code-manager.patch
@@ -0,0 +1,499 @@
+From 7d78e70735e1bce51ef34cfe128be68758de3447 Mon Sep 17 00:00:00 2001
+From: Kuiying Wang <kuiying.wang@intel.com>
+Date: Tue, 19 Feb 2019 15:00:11 +0800
+Subject: [PATCH] Implement post code manager
+
+Implement method and properties defined in PostCode.interface.yaml
+under phosphor-dbus-interfaces/xyz/openbmc_project/State/Boot
+1. Method: std::vector<uint64_t> PostCode::getPostCodes(uint16_t index)
+2. Properties: CurrentBootCycleIndex/MaxBootCycleNum
+
+Test-By:
+ Every cycle post codes is saved in "/var/lib/phosphor-post-code-manager"
+ "1" file is saved all post codes for cycle 1
+ "2" file is saved all post codes for cycle 2
+ "CurrentBootCycleIndex" file is saved the current boot cycle number.
+ root@wolfpass:/var/lib/phosphor-post-code-manager# ls
+ 1 2 CurrentBootCycleIndex
+
+Change-Id: Ia89b9121983261fef5573092d890beb84626ceeb
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+---
+ CMakeLists.txt | 45 ++++++
+ MAINTAINERS | 45 ++++++
+ inc/post_code.hpp | 152 ++++++++++++++++++
+ ...penbmc_project.State.Boot.PostCode.service | 11 ++
+ src/main.cpp | 61 +++++++
+ src/post_code.cpp | 109 +++++++++++++
+ 6 files changed, 423 insertions(+)
+ create mode 100644 CMakeLists.txt
+ create mode 100644 MAINTAINERS
+ create mode 100644 inc/post_code.hpp
+ create mode 100644 service_files/xyz.openbmc_project.State.Boot.PostCode.service
+ create mode 100644 src/main.cpp
+ create mode 100644 src/post_code.cpp
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+new file mode 100644
+index 0000000..594d839
+--- /dev/null
++++ b/CMakeLists.txt
+@@ -0,0 +1,45 @@
++cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR)
++project(post-code-manager CXX)
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
++include(GNUInstallDirs)
++include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
++include_directories(${CMAKE_CURRENT_BINARY_DIR})
++
++set(DBUS_OBJECT_NAME "xyz/openbmc_project/State/Boot/PostCode")
++set(DBUS_INTF_NAME "xyz.openbmc_project.State.Boot.PostCode")
++
++add_definitions(-DDBUS_OBJECT_NAME="/${DBUS_OBJECT_NAME}")
++add_definitions(-DDBUS_INTF_NAME="${DBUS_INTF_NAME}")
++set(SRC_FILES src/post_code.cpp
++ src/main.cpp )
++set ( SERVICE_FILES
++ service_files/xyz.openbmc_project.State.Boot.PostCode.service )
++
++# import sdbusplus
++find_package(PkgConfig REQUIRED)
++pkg_check_modules(SDBUSPLUSPLUS sdbusplus REQUIRED)
++include_directories(${SDBUSPLUSPLUS_INCLUDE_DIRS})
++link_directories(${SDBUSPLUSPLUS_LIBRARY_DIRS})
++find_program(SDBUSPLUSPLUS sdbus++)
++
++# import phosphor-logging
++find_package(PkgConfig REQUIRED)
++pkg_check_modules(LOGGING phosphor-logging REQUIRED)
++include_directories(${LOGGING_INCLUDE_DIRS})
++link_directories(${LOGGING_LIBRARY_DIRS})
++
++# phosphor-dbus-interfaces
++find_package(PkgConfig REQUIRED)
++pkg_check_modules(DBUSINTERFACE phosphor-dbus-interfaces REQUIRED)
++include_directories(${DBUSINTERFACE_INCLUDE_DIRS})
++link_directories(${DBUSINTERFACE_LIBRARY_DIRS})
++
++add_executable(${PROJECT_NAME} ${SRC_FILES})
++target_link_libraries(${PROJECT_NAME} ${DBUSINTERFACE_LIBRARIES} )
++target_link_libraries(${PROJECT_NAME} "${SDBUSPLUSPLUS_LIBRARIES} -lstdc++fs -lphosphor_dbus")
++
++install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
++install (FILES ${SERVICE_FILES} DESTINATION /lib/systemd/system/)
+\ No newline at end of file
+diff --git a/MAINTAINERS b/MAINTAINERS
+new file mode 100644
+index 0000000..de6cc54
+--- /dev/null
++++ b/MAINTAINERS
+@@ -0,0 +1,45 @@
++How to use this list:
++ Find the most specific section entry (described below) that matches where
++ your change lives and add the reviewers (R) and maintainers (M) as
++ reviewers. You can use the same method to track down who knows a particular
++ code base best.
++
++ Your change/query may span multiple entries; that is okay.
++
++ If you do not find an entry that describes your request at all, someone
++ forgot to update this list; please at least file an issue or send an email
++ to a maintainer, but preferably you should just update this document.
++
++Description of section entries:
++
++ Section entries are structured according to the following scheme:
++
++ X: NAME <EMAIL_USERNAME@DOMAIN> <IRC_USERNAME!>
++ X: ...
++ .
++ .
++ .
++
++ Where REPO_NAME is the name of the repository within the OpenBMC GitHub
++ organization; FILE_PATH is a file path within the repository, possibly with
++ wildcards; X is a tag of one of the following types:
++
++ M: Denotes maintainer; has fields NAME <EMAIL_USERNAME@DOMAIN> <IRC_USERNAME!>;
++ if omitted from an entry, assume one of the maintainers from the
++ MAINTAINERS entry.
++ R: Denotes reviewer; has fields NAME <EMAIL_USERNAME@DOMAIN> <IRC_USERNAME!>;
++ these people are to be added as reviewers for a change matching the repo
++ path.
++ F: Denotes forked from an external repository; has fields URL.
++
++ Line comments are to be denoted "# SOME COMMENT" (typical shell style
++ comment); it is important to follow the correct syntax and semantics as we
++ may want to use automated tools with this file in the future.
++
++ A change cannot be added to an OpenBMC repository without a MAINTAINER's
++ approval; thus, a MAINTAINER should always be listed as a reviewer.
++
++START OF MAINTAINERS LIST
++-------------------------
++
++M: Kuiying Wang <kuiying.wang@intel.com> <kuiyingw>
+\ No newline at end of file
+diff --git a/inc/post_code.hpp b/inc/post_code.hpp
+new file mode 100644
+index 0000000..84c8b3e
+--- /dev/null
++++ b/inc/post_code.hpp
+@@ -0,0 +1,152 @@
++/*
++// Copyright (c) 2019 Intel Corporation
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++*/
++#pragma once
++#include <fcntl.h>
++#include <unistd.h>
++#include <cereal/cereal.hpp>
++#include <experimental/filesystem>
++#include <cereal/access.hpp>
++#include <cereal/archives/json.hpp>
++#include <iostream>
++#include <fstream>
++#include <cereal/types/vector.hpp>
++
++#include <xyz/openbmc_project/State/Boot/PostCode/server.hpp>
++#include <xyz/openbmc_project/Common/error.hpp>
++#include <phosphor-logging/elog-errors.hpp>
++#include <xyz/openbmc_project/State/Host/server.hpp>
++
++#define MaxPostCodeCycles 100
++
++const static constexpr char *PostCodePath =
++ "/xyz/openbmc_project/state/boot/raw";
++const static constexpr char *PropertiesIntf =
++ "org.freedesktop.DBus.Properties";
++const static constexpr char *PostCodeListPath =
++ "/var/lib/phosphor-post-code-manager/";
++const static constexpr char *CurrentBootCycleIndexName =
++ "CurrentBootCycleIndex";
++const static constexpr char *HostStatePath =
++ "/xyz/openbmc_project/state/host0";
++
++
++struct EventDeleter
++{
++ void operator()(sd_event *event) const
++ {
++ event = sd_event_unref(event);
++ }
++};
++using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
++namespace fs = std::experimental::filesystem;
++namespace StateServer = sdbusplus::xyz::openbmc_project::State::server;
++
++using post_code =
++ sdbusplus::xyz::openbmc_project::State::Boot::server::PostCode;
++
++struct PostCode : sdbusplus::server::object_t<post_code>
++{
++ PostCode(sdbusplus::bus::bus& bus, const char* path,
++ EventPtr &event) :
++ sdbusplus::server::object_t<post_code>(bus, path),
++ bus(bus),
++ propertiesChangedSignalRaw(
++ bus,
++ sdbusplus::bus::match::rules::type::signal() +
++ sdbusplus::bus::match::rules::member("PropertiesChanged") +
++ sdbusplus::bus::match::rules::path(PostCodePath) +
++ sdbusplus::bus::match::rules::interface(PropertiesIntf),
++ [this](sdbusplus::message::message &msg) {
++ std::string objectName;
++ std::map<std::string, sdbusplus::message::variant<uint64_t>> msgData;
++ msg.read(objectName, msgData);
++ // Check if it was the Value property that changed.
++ auto valPropMap = msgData.find("Value");
++ {
++ if (valPropMap != msgData.end())
++ {
++ this->savePostCodes(sdbusplus::message::variant_ns::get<uint64_t>(valPropMap->second));
++ }
++ }
++ }),
++ propertiesChangedSignalCurrentHostState(
++ bus,
++ sdbusplus::bus::match::rules::type::signal() +
++ sdbusplus::bus::match::rules::member("PropertiesChanged") +
++ sdbusplus::bus::match::rules::path(HostStatePath) +
++ sdbusplus::bus::match::rules::interface(PropertiesIntf),
++ [this](sdbusplus::message::message &msg) {
++ std::string objectName;
++ std::map<std::string, sdbusplus::message::variant<std::string>> msgData;
++ msg.read(objectName, msgData);
++ // Check if it was the Value property that changed.
++ auto valPropMap = msgData.find("CurrentHostState");
++ {
++ if (valPropMap != msgData.end())
++ {
++ StateServer::Host::HostState currentHostState =
++ StateServer::Host::convertHostStateFromString(
++ sdbusplus::message::variant_ns::get<std::string>(valPropMap->second));
++ if (currentHostState == StateServer::Host::HostState::Off)
++ {
++ if (this->currentBootCycleIndex() >= this->maxBootCycleNum())
++ {
++ this->currentBootCycleIndex(1);
++ } else{
++ this->currentBootCycleIndex(this->currentBootCycleIndex() + 1);
++ }
++ this->postCodes.clear();
++ }
++ }
++ }
++ })
++ {
++ phosphor::logging::log<phosphor::logging::level::INFO>(
++ "PostCode is created");
++ auto dir = fs::path(PostCodeListPath);
++ fs::create_directories(dir);
++ strPostCodeListPath = PostCodeListPath;
++ strCurrentBootCycleIndexName = CurrentBootCycleIndexName;
++ uint16_t index = 0;
++ deserialize(fs::path(strPostCodeListPath + strCurrentBootCycleIndexName), index);
++ currentBootCycleIndex(index);
++ maxBootCycleNum(MaxPostCodeCycles);
++ if (currentBootCycleIndex() >= maxBootCycleNum())
++ {
++ currentBootCycleIndex(1);
++ } else{
++ currentBootCycleIndex(currentBootCycleIndex() + 1);
++ }
++ }
++ ~PostCode()
++ {
++
++ }
++
++ std::vector<uint64_t> getPostCodes(uint16_t index) override;
++
++ private:
++ sdbusplus::bus::bus& bus;
++ std::vector<uint64_t> postCodes;
++ std::string strPostCodeListPath;
++ std::string strCurrentBootCycleIndexName;
++ void savePostCodes(uint64_t code);
++ sdbusplus::bus::match_t propertiesChangedSignalRaw;
++ sdbusplus::bus::match_t propertiesChangedSignalCurrentHostState;
++ fs::path serialize(const std::string& path);
++ bool deserialize(const fs::path& path, uint16_t& index);
++ bool deserializePostCodes(const fs::path& path, std::vector<uint64_t> &codes);
++};
+diff --git a/service_files/xyz.openbmc_project.State.Boot.PostCode.service b/service_files/xyz.openbmc_project.State.Boot.PostCode.service
+new file mode 100644
+index 0000000..67bc43f
+--- /dev/null
++++ b/service_files/xyz.openbmc_project.State.Boot.PostCode.service
+@@ -0,0 +1,11 @@
++[Unit]
++Description=Post code manager
++
++[Service]
++ExecStart=/usr/bin/env post-code-manager
++SyslogIdentifier=post-code-manager
++Type=dbus
++BusName=xyz.openbmc_project.State.Boot.PostCode
++
++[Install]
++WantedBy=obmc-standby.target
+diff --git a/src/main.cpp b/src/main.cpp
+new file mode 100644
+index 0000000..4a74b29
+--- /dev/null
++++ b/src/main.cpp
+@@ -0,0 +1,61 @@
++/*
++// Copyright (c) 2019 Intel Corporation
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++*/
++#include "post_code.hpp"
++
++int main(int argc, char* argv[])
++{
++ int ret = 0;
++
++ phosphor::logging::log<phosphor::logging::level::INFO>(
++ "Start post code manager service...");
++
++ sd_event* event = nullptr;
++ ret = sd_event_default(&event);
++ if (ret < 0)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error creating a default sd_event handler");
++ return ret;
++ }
++ EventPtr eventP{event};
++ event = nullptr;
++
++ sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
++ sdbusplus::server::manager_t m{bus, DBUS_OBJECT_NAME};
++
++ bus.request_name(DBUS_INTF_NAME);
++
++ PostCode postCode{bus, DBUS_OBJECT_NAME, eventP};
++
++ try
++ {
++ bus.attach_event(eventP.get(), SD_EVENT_PRIORITY_NORMAL);
++ ret = sd_event_loop(eventP.get());
++ if (ret < 0)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error occurred during the sd_event_loop",
++ phosphor::logging::entry("RET=%d", ret));
++ }
++ }
++ catch (std::exception& e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
++ return -1;
++ }
++ return 0;
++
++}
+diff --git a/src/post_code.cpp b/src/post_code.cpp
+new file mode 100644
+index 0000000..983eeee
+--- /dev/null
++++ b/src/post_code.cpp
+@@ -0,0 +1,109 @@
++/*
++// Copyright (c) 2019 Intel Corporation
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++*/
++#include "post_code.hpp"
++std::vector<uint64_t> PostCode::getPostCodes(uint16_t index)
++{
++ std::vector<uint64_t> codes;
++
++ if (currentBootCycleIndex() == index)
++ return postCodes;
++ deserializePostCodes(fs::path(strPostCodeListPath + std::to_string(index)), codes);
++ return codes;
++}
++void PostCode::savePostCodes(uint64_t code)
++{
++ postCodes.push_back(code);
++ serialize(fs::path(PostCodeListPath));
++ return;
++}
++
++fs::path PostCode::serialize(const std::string& path)
++{
++ try
++ {
++ uint16_t index = currentBootCycleIndex();
++ fs::path fullPath(path + strCurrentBootCycleIndexName);
++ std::ofstream os(fullPath.c_str(), std::ios::binary);
++ cereal::JSONOutputArchive oarchive(os);
++ oarchive(index);
++
++ std::ofstream osPostCodes((path + std::to_string(currentBootCycleIndex())).c_str(), std::ios::binary);
++ cereal::JSONOutputArchive oarchivePostCodes(osPostCodes);
++ oarchivePostCodes(postCodes);
++
++ return path;
++ }
++ catch (cereal::Exception& e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
++ }
++ catch (const fs::filesystem_error& e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
++ }
++}
++
++bool PostCode::deserialize(const fs::path& path, uint16_t& index)
++{
++ try
++ {
++ if (fs::exists(path))
++ {
++ std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
++ cereal::JSONInputArchive iarchive(is);
++ iarchive(index);
++ return true;
++ }
++ return false;
++ }
++ catch (cereal::Exception& e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
++ return false;
++ }
++ catch (const fs::filesystem_error& e)
++ {
++ return false;
++ }
++
++ return false;
++}
++
++bool PostCode::deserializePostCodes(const fs::path& path, std::vector<uint64_t> &codes)
++{
++ try
++ {
++ if (fs::exists(path))
++ {
++ std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
++ cereal::JSONInputArchive iarchive(is);
++ iarchive(codes);
++ return true;
++ }
++ return false;
++ }
++ catch (cereal::Exception& e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
++ return false;
++ }
++ catch (const fs::filesystem_error& e)
++ {
++ return false;
++ }
++
++ return false;
++}
+--
+2.19.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/state/post-code-manager_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/state/post-code-manager_git.bb
new file mode 100644
index 000000000..8f2ead18a
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/state/post-code-manager_git.bb
@@ -0,0 +1,34 @@
+SUMMARY = "Phosphor post code manager"
+DESCRIPTION = "Post Code Manager"
+
+SRC_URI = "git://github.com/openbmc/phosphor-post-code-manager.git"
+SRCREV = "7f50dcaa6feb66cf5307b8a0e4742a36a50eed29"
+
+S = "${WORKDIR}/git"
+
+PV = "1.0+git${SRCPV}"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327"
+
+inherit cmake pkgconfig systemd
+
+SYSTEMD_SERVICE_${PN} += "xyz.openbmc_project.State.Boot.PostCode.service"
+
+DEPENDS += " \
+ autoconf-archive-native \
+ systemd \
+ sdbusplus \
+ sdbusplus-native \
+ phosphor-dbus-interfaces \
+ phosphor-dbus-interfaces-native \
+ phosphor-logging \
+ "
+RDEPENDS_${PN} += " \
+ libsystemd \
+ sdbusplus \
+ phosphor-dbus-interfaces \
+ phosphor-logging \
+ "
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+SRC_URI += "file://0001-Implement-post-code-manager.patch"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/system/callback-manager.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/system/callback-manager.bb
new file mode 100644
index 000000000..e272fdc96
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/system/callback-manager.bb
@@ -0,0 +1,19 @@
+SUMMARY = "Callback Manager"
+DESCRIPTION = "D-Bus daemon that registers matches that trigger method calls"
+
+SRC_URI = "git://git@github.com/Intel-BMC/provingground;protocol=ssh"
+
+inherit cmake systemd
+DEPENDS = "boost sdbusplus"
+
+PV = "0.1+git${SRCPV}"
+SRCREV = "4373d99e1edcbb4c7233abde3a5e53690693007b"
+
+S = "${WORKDIR}/git/callback-manager"
+
+SYSTEMD_SERVICE_${PN} += "callback-manager.service"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://LICENCE;md5=7becf906c8f8d03c237bad13bc3dac53"
+
+EXTRA_OECMAKE = "-DYOCTO=1"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0005-Added-suport-for-multiple-user-manager-services.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0005-Added-suport-for-multiple-user-manager-services.patch
new file mode 100644
index 000000000..5c2879d8f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0005-Added-suport-for-multiple-user-manager-services.patch
@@ -0,0 +1,1648 @@
+From 726be648df955f5ae94f34391adc0e88f6956345 Mon Sep 17 00:00:00 2001
+From: Radivoje Jovanovic <radivoje.jovanovic@intel.com>
+Date: Mon, 2 Jul 2018 19:23:25 -0700
+Subject: [PATCH] Added suport for multiple user manager services
+
+Support added for SSSD service implementation
+
+Signed-off-by: Alberto Salazar Perez <alberto.salazar.perez@intel.com>
+Signed-off-by: Radivoje Jovanovic <radivoje.jovanovic@intel.com>
+Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
+---
+ Makefile.am | 5 +-
+ mainapp.cpp | 89 ++++++-
+ user_mgr.cpp | 293 +++------------------
+ user_mgr.hpp | 9 +-
+ user_service.cpp | 781 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ user_service.hpp | 233 +++++++++++++++++
+ 6 files changed, 1141 insertions(+), 269 deletions(-)
+ create mode 100644 user_service.cpp
+ create mode 100644 user_service.hpp
+
+diff --git a/Makefile.am b/Makefile.am
+index b138aea..288b780 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,11 +1,12 @@
+ sbin_PROGRAMS = phosphor-user-manager
+
+-noinst_HEADERS = user_mgr.hpp users.hpp
++noinst_HEADERS = user_mgr.hpp users.hpp user_service.hpp
+
+ phosphor_user_manager_SOURCES = \
+ mainapp.cpp \
+ user_mgr.cpp \
+- users.cpp
++ users.cpp \
++ user_service.cpp
+
+ phosphor_user_manager_LDFLAGS = $(SDBUSPLUS_LIBS) \
+ $(PHOSPHOR_DBUS_INTERFACES_LIBS) \
+diff --git a/mainapp.cpp b/mainapp.cpp
+index c9da030..03c406a 100644
+--- a/mainapp.cpp
++++ b/mainapp.cpp
+@@ -14,18 +14,105 @@
+ * limitations under the License.
+ */
+ #include <string>
++#include <iostream>
++#include <getopt.h>
+ #include "user_mgr.hpp"
++#include "user_service.hpp"
+ #include "config.h"
+
+ // D-Bus root for user manager
+ constexpr auto USER_MANAGER_ROOT = "/xyz/openbmc_project/user";
+
++void printUsage()
++{
++ std::string usage =
++ R"(Usage:
++ phosphor-user-manager [OPTIONS]
++
++Backend DBUS service for OpenBMC User Management.
++If no OPTIONS are specified, shadow file will be used.
++
++Options:
++ -s, --service={shadow|sssd}
++ Specify the authentication service to use:
++ 'shadow' will use the /etc/shadow file.
++ 'sssd' will use the sssd service domains.
++ -h, --help Displays this help message.
++)";
++ std::cerr << usage;
++}
++
++void parseArgs(int argc, char** argv,
++ phosphor::user::UserService::ServiceType& srvc)
++{
++ const std::string shortOpts{"s:h"};
++ const struct option longOpts[] = {{"service", 1, nullptr, 's'},
++ {"help", 0, nullptr, 'h'},
++ {nullptr, 0, nullptr, 0}};
++
++ while (true)
++ {
++ const auto opt =
++ getopt_long(argc, argv, shortOpts.c_str(), longOpts, nullptr);
++
++ if (opt == -1)
++ {
++ if (srvc == phosphor::user::UserService::ServiceType::none)
++ {
++ srvc = phosphor::user::UserService::ServiceType::shadow;
++ }
++ break;
++ }
++
++ switch (opt)
++ {
++ case 's':
++ {
++ std::string srvcStr{optarg};
++ if (!srvcStr.compare("shadow"))
++ {
++ srvc = phosphor::user::UserService::ServiceType::shadow;
++ }
++ else if (!srvcStr.compare("sssd"))
++ {
++ srvc = phosphor::user::UserService::ServiceType::sssd;
++ }
++ else
++ {
++ std::cerr << "Error. '" << srvcStr << "' is not a valid"
++ << " authentication service." << std::endl;
++ printUsage();
++ exit(1);
++ }
++ }
++ break;
++
++ case 'h':
++ {
++ printUsage();
++ exit(0);
++ }
++
++ default:
++ {
++ printUsage();
++ exit(1);
++ }
++ }
++ }
++}
++
+ int main(int argc, char** argv)
+ {
++ // Check command line options. Exit if error.
++ phosphor::user::UserService::ServiceType srvc =
++ phosphor::user::UserService::ServiceType::none;
++ parseArgs(argc, argv, srvc);
++
+ auto bus = sdbusplus::bus::new_default();
+ sdbusplus::server::manager::manager objManager(bus, USER_MANAGER_ROOT);
+
+- phosphor::user::UserMgr userMgr(bus, USER_MANAGER_ROOT);
++ phosphor::user::UserMgr userMgr(bus, USER_MANAGER_ROOT, srvc);
+
+ // Claim the bus now
+ bus.request_name(USER_MANAGER_BUSNAME);
+diff --git a/user_mgr.cpp b/user_mgr.cpp
+index 47edf7d..32f3f4c 100644
+--- a/user_mgr.cpp
++++ b/user_mgr.cpp
+@@ -14,26 +14,20 @@
+ // limitations under the License.
+ */
+
+-#include <shadow.h>
+-#include <unistd.h>
+-#include <sys/types.h>
+-#include <sys/wait.h>
++#include <cstdio>
++
+ #include <fstream>
+ #include <grp.h>
+ #include <pwd.h>
+ #include <regex>
+-#include <algorithm>
+-#include <numeric>
+-#include <boost/process/child.hpp>
+-#include <boost/process/io.hpp>
+ #include <boost/algorithm/string/split.hpp>
+ #include <xyz/openbmc_project/Common/error.hpp>
+ #include <xyz/openbmc_project/User/Common/error.hpp>
+ #include <phosphor-logging/log.hpp>
+ #include <phosphor-logging/elog.hpp>
+ #include <phosphor-logging/elog-errors.hpp>
++#include <stdexcept>
+ #include "shadowlock.hpp"
+-#include "file.hpp"
+ #include "user_mgr.hpp"
+ #include "users.hpp"
+ #include "config.h"
+@@ -43,12 +37,10 @@ namespace phosphor
+ namespace user
+ {
+
+-static constexpr const char *passwdFileName = "/etc/passwd";
+ static constexpr size_t ipmiMaxUsers = 15;
+ static constexpr size_t ipmiMaxUserNameLen = 16;
+ static constexpr size_t systemMaxUserNameLen = 30;
+ static constexpr size_t maxSystemUsers = 30;
+-static constexpr const char *grpSsh = "ssh";
+ static constexpr uint8_t minPasswdLength = 8;
+ static constexpr int success = 0;
+ static constexpr int failure = -1;
+@@ -94,79 +86,6 @@ using NoResource =
+
+ using Argument = xyz::openbmc_project::Common::InvalidArgument;
+
+-template <typename... ArgTypes>
+-static std::vector<std::string> executeCmd(const char *path,
+- ArgTypes &&... tArgs)
+-{
+- std::vector<std::string> stdOutput;
+- boost::process::ipstream stdOutStream;
+- boost::process::child execProg(path, const_cast<char *>(tArgs)...,
+- boost::process::std_out > stdOutStream);
+- std::string stdOutLine;
+-
+- while (stdOutStream && std::getline(stdOutStream, stdOutLine) &&
+- !stdOutLine.empty())
+- {
+- stdOutput.emplace_back(stdOutLine);
+- }
+-
+- execProg.wait();
+-
+- int retCode = execProg.exit_code();
+- if (retCode)
+- {
+- log<level::ERR>("Command execution failed", entry("PATH=%d", path),
+- entry("RETURN_CODE:%d", retCode));
+- elog<InternalFailure>();
+- }
+-
+- return stdOutput;
+-}
+-
+-static std::string getCSVFromVector(std::vector<std::string> vec)
+-{
+- switch (vec.size())
+- {
+- case 0:
+- {
+- return "";
+- }
+- break;
+-
+- case 1:
+- {
+- return std::string{vec[0]};
+- }
+- break;
+-
+- default:
+- {
+- return std::accumulate(
+- std::next(vec.begin()), vec.end(), vec[0],
+- [](std::string a, std::string b) { return a + ',' + b; });
+- }
+- }
+-}
+-
+-static bool removeStringFromCSV(std::string &csvStr, const std::string &delStr)
+-{
+- std::string::size_type delStrPos = csvStr.find(delStr);
+- if (delStrPos != std::string::npos)
+- {
+- // need to also delete the comma char
+- if (delStrPos == 0)
+- {
+- csvStr.erase(delStrPos, delStr.size() + 1);
+- }
+- else
+- {
+- csvStr.erase(delStrPos - 1, delStr.size() + 1);
+- }
+- return true;
+- }
+- return false;
+-}
+-
+ bool UserMgr::isUserExist(const std::string &userName)
+ {
+ if (userName.empty())
+@@ -293,39 +212,14 @@ void UserMgr::createUser(std::string userName,
+ {
+ throwForInvalidPrivilege(priv);
+ throwForInvalidGroups(groupNames);
+- // All user management lock has to be based on /etc/shadow
+- phosphor::user::shadow::Lock lock();
+ throwForUserExists(userName);
+ throwForUserNameConstraints(userName, groupNames);
+ throwForMaxGrpUserCount(groupNames);
+
+- std::string groups = getCSVFromVector(groupNames);
+- bool sshRequested = removeStringFromCSV(groups, grpSsh);
+-
+- // treat privilege as a group - This is to avoid using different file to
+- // store the same.
+- if (!priv.empty())
+- {
+- if (groups.size() != 0)
+- {
+- groups += ",";
+- }
+- groups += priv;
+- }
+- try
+- {
+- executeCmd("/usr/sbin/useradd", userName.c_str(), "-G", groups.c_str(),
+- "-m", "-N", "-s",
+- (sshRequested ? "/bin/sh" : "/bin/nologin"), "-e",
+- (enabled ? "" : "1970-01-02"));
+- }
+- catch (const InternalFailure &e)
+- {
+- log<level::ERR>("Unable to create new user");
+- elog<InternalFailure>();
+- }
++ // Tell the User Service to create a new user with the info provided.
++ userSrvc->createUser(userName, groupNames, priv, enabled);
+
+- // Add the users object before sending out the signal
++ // Add the users to the local list before sending out the signal
+ std::string userObj = std::string(usersObjPath) + "/" + userName;
+ std::sort(groupNames.begin(), groupNames.end());
+ usersList.emplace(
+@@ -339,19 +233,11 @@ void UserMgr::createUser(std::string userName,
+
+ void UserMgr::deleteUser(std::string userName)
+ {
+- // All user management lock has to be based on /etc/shadow
+- phosphor::user::shadow::Lock lock();
+ throwForUserDoesNotExist(userName);
+- try
+- {
+- executeCmd("/usr/sbin/userdel", userName.c_str(), "-r");
+- }
+- catch (const InternalFailure &e)
+- {
+- log<level::ERR>("User delete failed",
+- entry("USER_NAME=%s", userName.c_str()));
+- elog<InternalFailure>();
+- }
++
++ // Tell the User Service to delete user
++ userSrvc->deleteUser(userName);
++ // Then delete user from local list
+
+ usersList.erase(userName);
+
+@@ -362,24 +248,13 @@ void UserMgr::deleteUser(std::string userName)
+
+ void UserMgr::renameUser(std::string userName, std::string newUserName)
+ {
+- // All user management lock has to be based on /etc/shadow
+- phosphor::user::shadow::Lock lock();
+ throwForUserDoesNotExist(userName);
+ throwForUserExists(newUserName);
+ throwForUserNameConstraints(newUserName,
+ usersList[userName].get()->userGroups());
+- try
+- {
+- std::string newHomeDir = "/home/" + newUserName;
+- executeCmd("/usr/sbin/usermod", "-l", newUserName.c_str(),
+- userName.c_str(), "-d", newHomeDir.c_str(), "-m");
+- }
+- catch (const InternalFailure &e)
+- {
+- log<level::ERR>("User rename failed",
+- entry("USER_NAME=%s", userName.c_str()));
+- elog<InternalFailure>();
+- }
++ // Call The User Service to rename user on the system
++ userSrvc->renameUser(userName, newUserName);
++ // Update local list to reflect the name change
+ const auto &user = usersList[userName];
+ std::string priv = user.get()->userPrivilege();
+ std::vector<std::string> groupNames = user.get()->userGroups();
+@@ -403,8 +278,6 @@ void UserMgr::updateGroupsAndPriv(const std::string &userName,
+ {
+ throwForInvalidPrivilege(priv);
+ throwForInvalidGroups(groupNames);
+- // All user management lock has to be based on /etc/shadow
+- phosphor::user::shadow::Lock lock();
+ throwForUserDoesNotExist(userName);
+ const std::vector<std::string> &oldGroupNames =
+ usersList[userName].get()->userGroups();
+@@ -420,29 +293,8 @@ void UserMgr::updateGroupsAndPriv(const std::string &userName,
+ throwForMaxGrpUserCount(groupNames);
+ }
+
+- std::string groups = getCSVFromVector(groupNames);
+- bool sshRequested = removeStringFromCSV(groups, grpSsh);
+-
+- // treat privilege as a group - This is to avoid using different file to
+- // store the same.
+- if (!priv.empty())
+- {
+- if (groups.size() != 0)
+- {
+- groups += ",";
+- }
+- groups += priv;
+- }
+- try
+- {
+- executeCmd("/usr/sbin/usermod", userName.c_str(), "-G", groups.c_str(),
+- "-s", (sshRequested ? "/bin/sh" : "/bin/nologin"));
+- }
+- catch (const InternalFailure &e)
+- {
+- log<level::ERR>("Unable to modify user privilege / groups");
+- elog<InternalFailure>();
+- }
++ // Call The User Service to update user groups and priv on the system
++ userSrvc->updateGroupsAndPriv(userName, groupNames, priv);
+
+ log<level::INFO>("User groups / privilege updated successfully",
+ entry("USER_NAME=%s", userName.c_str()));
+@@ -638,19 +490,9 @@ int UserMgr::setPamModuleArgValue(const std::string &moduleName,
+
+ void UserMgr::userEnable(const std::string &userName, bool enabled)
+ {
+- // All user management lock has to be based on /etc/shadow
+- phosphor::user::shadow::Lock lock();
+ throwForUserDoesNotExist(userName);
+- try
+- {
+- executeCmd("/usr/sbin/usermod", userName.c_str(), "-e",
+- (enabled ? "" : "1970-01-02"));
+- }
+- catch (const InternalFailure &e)
+- {
+- log<level::ERR>("Unable to modify user enabled state");
+- elog<InternalFailure>();
+- }
++ // Call The User Service to update user groups and priv on the system
++ userSrvc->updateUserStatus(userName, enabled);
+
+ log<level::INFO>("User enabled/disabled state updated successfully",
+ entry("USER_NAME=%s", userName.c_str()),
+@@ -728,49 +570,8 @@ bool UserMgr::userLockedForFailedAttempt(const std::string &userName,
+
+ UserSSHLists UserMgr::getUserAndSshGrpList()
+ {
+- // All user management lock has to be based on /etc/shadow
+- phosphor::user::shadow::Lock lock();
+-
+- std::vector<std::string> userList;
+- std::vector<std::string> sshUsersList;
+- struct passwd pw, *pwp = nullptr;
+- std::array<char, 1024> buffer{};
+-
+- phosphor::user::File passwd(passwdFileName, "r");
+- if ((passwd)() == NULL)
+- {
+- log<level::ERR>("Error opening the passwd file");
+- elog<InternalFailure>();
+- }
+-
+- while (true)
+- {
+- auto r = fgetpwent_r((passwd)(), &pw, buffer.data(), buffer.max_size(),
+- &pwp);
+- if ((r != 0) || (pwp == NULL))
+- {
+- // Any error, break the loop.
+- break;
+- }
+- // Add all users whose UID >= 1000 and < 65534
+- // and special UID 0.
+- if ((pwp->pw_uid == 0) ||
+- ((pwp->pw_uid >= 1000) && (pwp->pw_uid < 65534)))
+- {
+- std::string userName(pwp->pw_name);
+- userList.emplace_back(userName);
+-
+- // ssh doesn't have separate group. Check login shell entry to
+- // get all users list which are member of ssh group.
+- std::string loginShell(pwp->pw_shell);
+- if (loginShell == "/bin/sh")
+- {
+- sshUsersList.emplace_back(userName);
+- }
+- }
+- }
+- endpwent();
+- return std::make_pair(std::move(userList), std::move(sshUsersList));
++ // Call The User Service to get the User and SSUsers lists
++ return std::move(userSrvc->getUserAndSshGrpList());
+ }
+
+ size_t UserMgr::getIpmiUsersCount()
+@@ -781,49 +582,14 @@ size_t UserMgr::getIpmiUsersCount()
+
+ bool UserMgr::isUserEnabled(const std::string &userName)
+ {
+- // All user management lock has to be based on /etc/shadow
+- phosphor::user::shadow::Lock lock();
+- std::array<char, 4096> buffer{};
+- struct spwd spwd;
+- struct spwd *resultPtr = nullptr;
+- int status = getspnam_r(userName.c_str(), &spwd, buffer.data(),
+- buffer.max_size(), &resultPtr);
+- if (!status && (&spwd == resultPtr))
+- {
+- if (resultPtr->sp_expire >= 0)
+- {
+- return false; // user locked out
+- }
+- return true;
+- }
+- return false; // assume user is disabled for any error.
++ // Call The User Service to verify if user is enabled
++ return userSrvc->isUserEnabled(userName);
+ }
+
+ std::vector<std::string> UserMgr::getUsersInGroup(const std::string &groupName)
+ {
+- std::vector<std::string> usersInGroup;
+- // Should be more than enough to get the pwd structure.
+- std::array<char, 4096> buffer{};
+- struct group grp;
+- struct group *resultPtr = nullptr;
+-
+- int status = getgrnam_r(groupName.c_str(), &grp, buffer.data(),
+- buffer.max_size(), &resultPtr);
+-
+- if (!status && (&grp == resultPtr))
+- {
+- for (; *(grp.gr_mem) != NULL; ++(grp.gr_mem))
+- {
+- usersInGroup.emplace_back(*(grp.gr_mem));
+- }
+- }
+- else
+- {
+- log<level::ERR>("Group not found",
+- entry("GROUP=%s", groupName.c_str()));
+- // Don't throw error, just return empty userList - fallback
+- }
+- return usersInGroup;
++ // Call The User Service to get the users that belong to a group
++ return std::move(userSrvc->getUsersInGroup(groupName));
+ }
+
+ DbusUserObj UserMgr::getPrivilegeMapperObject(void)
+@@ -1018,11 +784,9 @@ void UserMgr::initUserObjects(void)
+ {
+ // All user management lock has to be based on /etc/shadow
+ phosphor::user::shadow::Lock lock();
+- std::vector<std::string> userNameList;
+- std::vector<std::string> sshGrpUsersList;
+ UserSSHLists userSSHLists = getUserAndSshGrpList();
+- userNameList = std::move(userSSHLists.first);
+- sshGrpUsersList = std::move(userSSHLists.second);
++ std::vector<std::string> userNameList = std::move(userSSHLists.first);
++ std::vector<std::string> sshGrpUsersList = std::move(userSSHLists.second);
+
+ if (!userNameList.empty())
+ {
+@@ -1077,8 +841,10 @@ void UserMgr::initUserObjects(void)
+ }
+ }
+
+-UserMgr::UserMgr(sdbusplus::bus::bus &bus, const char *path) :
+- UserMgrIface(bus, path), AccountPolicyIface(bus, path), bus(bus), path(path)
++UserMgr::UserMgr(sdbusplus::bus::bus &bus, const char *path,
++ UserService::ServiceType srvc) :
++ UserMgrIface(bus, path),
++ AccountPolicyIface(bus, path), bus(bus), path(path)
+ {
+ UserMgrIface::allPrivileges(privMgr);
+ std::sort(groupsMgr.begin(), groupsMgr.end());
+@@ -1186,6 +952,7 @@ UserMgr::UserMgr(sdbusplus::bus::bus &bus, const char *path) :
+ }
+ AccountPolicyIface::accountUnlockTimeout(value32);
+ }
++ userSrvc = std::make_unique<UserService>(srvc, groupsMgr, privMgr);
+ initUserObjects();
+ }
+
+diff --git a/user_mgr.hpp b/user_mgr.hpp
+index c78174d..9d9c842 100644
+--- a/user_mgr.hpp
++++ b/user_mgr.hpp
+@@ -21,6 +21,7 @@
+ #include <unordered_map>
+ #include <variant>
+ #include "users.hpp"
++#include "user_service.hpp"
+
+ namespace phosphor
+ {
+@@ -28,8 +29,6 @@ namespace user
+ {
+
+ using UserMgrIface = sdbusplus::xyz::openbmc_project::User::server::Manager;
+-using UserSSHLists =
+- std::pair<std::vector<std::string>, std::vector<std::string>>;
+ using AccountPolicyIface =
+ sdbusplus::xyz::openbmc_project::User::server::AccountPolicy;
+
+@@ -71,8 +70,10 @@ class UserMgr : public UserMgrIface, AccountPolicyIface
+ *
+ * @param[in] bus - sdbusplus handler
+ * @param[in] path - D-Bus path
++ * @param[in] srvc - User service to be used
+ */
+- UserMgr(sdbusplus::bus::bus &bus, const char *path);
++ UserMgr(sdbusplus::bus::bus &bus, const char *path,
++ UserService::ServiceType srvc);
+
+ /** @brief create user method.
+ * This method creates a new user as requested
+@@ -181,6 +182,8 @@ class UserMgr : public UserMgrIface, AccountPolicyIface
+ /** @brief object path */
+ const std::string path;
+
++ /** @brief user service to be used */
++ std::unique_ptr<UserService> userSrvc;
+ /** @brief privilege manager container */
+ std::vector<std::string> privMgr = {"priv-admin", "priv-operator",
+ "priv-user", "priv-callback"};
+diff --git a/user_service.cpp b/user_service.cpp
+new file mode 100644
+index 0000000..9bb602c
+--- /dev/null
++++ b/user_service.cpp
+@@ -0,0 +1,781 @@
++/*
++// Copyright (c) 2018 Intel Corporation
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++*/
++
++#include <grp.h>
++#include <pwd.h>
++#include <numeric>
++#include <boost/process/child.hpp>
++#include <boost/process/io.hpp>
++#include <boost/algorithm/string/split.hpp>
++#include "shadowlock.hpp"
++#include "file.hpp"
++#include "user_service.hpp"
++
++/* anonymous namespace for User Service interface implementations.
++// Each class inside this namespace implements a special service
++// to be used for the User Manager class. This can be extended to use
++// other user management services and it should be as simple as
++// adding a new class which inherits from phosphor::user::UserServiceInterface
++*/
++
++namespace
++{
++
++std::string getCSVFromVector(std::vector<std::string> vec)
++{
++ switch (vec.size())
++ {
++ case 0:
++ {
++ return "";
++ }
++ break;
++
++ case 1:
++ {
++ return std::string{vec[0]};
++ }
++ break;
++
++ default:
++ {
++ return std::accumulate(
++ std::next(vec.begin()), vec.end(), vec[0],
++ [](std::string a, std::string b) { return a + ',' + b; });
++ }
++ }
++}
++
++bool removeStringFromCSV(std::string &csvStr, const std::string &delStr)
++{
++ std::string::size_type delStrPos = csvStr.find(delStr);
++ if (delStrPos != std::string::npos)
++ {
++ // need to also delete the comma char
++ if (delStrPos == 0)
++ {
++ csvStr.erase(delStrPos, delStr.size() + 1);
++ }
++ else
++ {
++ csvStr.erase(delStrPos - 1, delStr.size() + 1);
++ }
++ return true;
++ }
++ return false;
++}
++
++class ShadowService : public phosphor::user::UserServiceInterface
++{
++ public:
++ ShadowService() = default;
++
++ ~ShadowService() = default;
++
++ phosphor::user::UserSSHLists getUserAndSshGrpList() const override
++ {
++ // All user management lock has to be based on /etc/shadow
++ phosphor::user::shadow::Lock lock();
++
++ std::vector<std::string> userList;
++ std::vector<std::string> sshUsersList;
++
++ struct passwd pw, *pwp = nullptr;
++ std::array<char, 1024> buffer{};
++
++ phosphor::user::File passwd(passwdFileName, "r");
++ if ((passwd)() == NULL)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error opening the passwd file");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++
++ while (true)
++ {
++ auto r = fgetpwent_r((passwd)(), &pw, buffer.data(),
++ buffer.max_size(), &pwp);
++ if ((r != 0) || (pwp == NULL))
++ {
++ // Any error, break the loop.
++ break;
++ }
++ // Add all users whose UID >= 1000 and < 65534
++ // and special UID 0.
++ if ((pwp->pw_uid == 0) ||
++ ((pwp->pw_uid >= 1000) && (pwp->pw_uid < 65534)))
++ {
++ std::string userName(pwp->pw_name);
++ userList.emplace_back(userName);
++
++ // ssh doesn't have separate group. Check login shell entry to
++ // get all users list which are member of ssh group.
++ std::string loginShell(pwp->pw_shell);
++ if (loginShell == "/bin/sh")
++ {
++ sshUsersList.emplace_back(userName);
++ }
++ }
++ }
++ endpwent();
++ return std::make_pair(std::move(userList), std::move(sshUsersList));
++ }
++
++ std::vector<std::string>
++ getUsersInGroup(const std::string &groupName) const override
++ {
++ std::vector<std::string> usersInGroup;
++ // Should be more than enough to get the pwd structure.
++ std::array<char, 4096> buffer{};
++ struct group grp;
++ struct group *grpPtr = &grp;
++ struct group *resultPtr;
++
++ int status = getgrnam_r(groupName.c_str(), grpPtr, buffer.data(),
++ buffer.max_size(), &resultPtr);
++
++ if (!status && (grpPtr == resultPtr))
++ {
++ for (; *(grp.gr_mem) != NULL; ++(grp.gr_mem))
++ {
++ usersInGroup.emplace_back(*(grp.gr_mem));
++ }
++ }
++ else
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Group not found",
++ phosphor::logging::entry("GROUP=%s", groupName.c_str()));
++ // Don't throw error, just return empty usersInGroup - fallback
++ }
++ return usersInGroup;
++ }
++
++ void createUser(const std::string &userName,
++ const std::vector<std::string> &groupNames,
++ const std::string &priv, const bool &enabled) const override
++ {
++ // All user management lock has to be based on /etc/shadow
++ phosphor::user::shadow::Lock lock();
++
++ std::string groups = getCSVFromVector(groupNames);
++ bool sshRequested = removeStringFromCSV(groups, phosphor::user::grpSsh);
++
++ // treat privilege as a group - This is to avoid using different file to
++ // store the same
++ if (!priv.empty())
++ {
++ if (groups.size() != 0)
++ {
++ groups.append(",");
++ }
++ groups.append(priv);
++ }
++
++ try
++ {
++ phosphor::user::executeCmd(
++ "/usr/sbin/useradd", userName.c_str(), "-G", groups.c_str(),
++ "-m", "-N", "-s", (sshRequested ? "/bin/sh" : "/bin/nologin"),
++ "-e", (enabled ? "" : "1970-01-02"));
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Unable to create new user");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++ }
++
++ void renameUser(const std::string &userName,
++ const std::string &newUserName) const override
++ {
++ // All user management lock has to be based on /etc/shadow
++ phosphor::user::shadow::Lock lock();
++ try
++ {
++ std::string newHomeDir = "/home/" + newUserName;
++ phosphor::user::executeCmd("/usr/sbin/usermod", "-l",
++ newUserName.c_str(), userName.c_str(),
++ "-d", newHomeDir.c_str(), "-m");
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ phosphor::logging::log<phosphor::logging::level::INFO>(
++ "User rename failed",
++ phosphor::logging::entry("USER_NAME=%s", userName.c_str()));
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++ }
++
++ void deleteUser(const std::string &userName) const override
++ {
++ // All user management lock has to be based on /etc/shadow
++ phosphor::user::shadow::Lock lock();
++
++ try
++ {
++ phosphor::user::executeCmd("/usr/sbin/userdel", userName.c_str(),
++ "-r");
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ phosphor::logging::log<phosphor::logging::level::INFO>(
++ "User delete failed",
++ phosphor::logging::entry("USER_NAME=%s", userName.c_str()));
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++ }
++
++ void updateGroupsAndPriv(const std::string &userName,
++ const std::vector<std::string> &groupNames,
++ const std::string &priv) const override
++ {
++ // All user management lock has to be based on /etc/shadow
++ phosphor::user::shadow::Lock lock();
++
++ std::string groups = getCSVFromVector(groupNames);
++ bool sshRequested = removeStringFromCSV(groups, phosphor::user::grpSsh);
++
++ // treat privilege as a group - This is to avoid using different file to
++ // store the same.
++ if (!priv.empty())
++ {
++ if (groups.size() != 0)
++ {
++ groups += ",";
++ }
++ groups += priv;
++ }
++
++ try
++ {
++ phosphor::user::executeCmd(
++ "/usr/sbin/usermod", userName.c_str(), "-G", groups.c_str(),
++ "-s", (sshRequested ? "/bin/sh" : "/bin/nologin"));
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Unable to modify user privilege / groups");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++ }
++
++ void updateUserStatus(const std::string &userName,
++ const bool &enabled) const override
++ {
++ // All user management lock has to be based on /etc/shadow
++ phosphor::user::shadow::Lock lock();
++ try
++ {
++ phosphor::user::executeCmd("/usr/sbin/usermod", userName.c_str(),
++ "-e", (enabled ? "" : "1970-01-02"));
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Unable to modify user enabled state");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++ }
++
++ bool isUserEnabled(const std::string &userName) const override
++ {
++ // All user management lock has to be based on /etc/shadow
++ phosphor::user::shadow::Lock lock();
++ std::array<char, 4096> buffer{};
++ struct spwd spwd;
++ struct spwd *resultPtr = nullptr;
++ int status = getspnam_r(userName.c_str(), &spwd, buffer.data(),
++ buffer.max_size(), &resultPtr);
++ if (!status && (&spwd == resultPtr))
++ {
++ if (resultPtr->sp_expire >= 0)
++ {
++ return false; // user locked out
++ }
++ return true;
++ }
++ return false; // assume user is disabled for any error.
++ }
++
++ std::vector<std::string>
++ getUserGroups(const std::string &userName) const override
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "ShadowService::getUserGroups not implemented!");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ return std::vector<std::string>();
++ }
++
++ void createGroup(const std::string &groupName) const override
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "ShadowService::createGroup not implemented!");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++
++ private:
++ static constexpr const char *passwdFileName = "/etc/passwd";
++};
++
++class SSSDService : public phosphor::user::UserServiceInterface
++{
++ public:
++ SSSDService(const std::vector<std::string> &groups,
++ const std::vector<std::string> &privs)
++ {
++
++ createGroup(lockedGrp);
++ for (const auto &g : groups)
++ {
++ createGroup(g);
++ }
++ for (const auto &p : privs)
++ {
++ createGroup(p);
++ }
++ }
++
++ ~SSSDService() = default;
++
++ phosphor::user::UserSSHLists getUserAndSshGrpList() const override
++ {
++ std::vector<std::string> users;
++ std::vector<std::string> sshGroup;
++ std::vector<std::string> exeOutput;
++
++ try
++ {
++ exeOutput = phosphor::user::executeCmd("/usr/bin/getent", "-s",
++ "sss", "passwd");
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Unable to get users information "
++ "from sssd service");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++
++ for (const auto &userLine : exeOutput)
++ {
++ std::vector<std::string> userInfo;
++ boost::algorithm::split(userInfo, userLine,
++ boost::algorithm::is_any_of(":"));
++ // At this point userInfo is a vector containing the passwd
++ // info for the user, so we know the correct positions:
++ // 0: User name.
++ // 1: Encrypted password.
++ // 2: User ID number (UID)
++ // 3: User's group ID number (GID)
++ // 4: Full name of the user (GECOS)
++ // 5: User home directory.
++ // 6: Login shell.
++ users.emplace_back(userInfo[0]);
++
++ // ssh doesn't have separate group. Check login shell entry to
++ // get all users list which are member of ssh group.
++ if (userInfo[6] == "/bin/sh")
++ {
++ sshGroup.emplace_back(userInfo[0]);
++ }
++ }
++
++ return std::make_pair(std::move(users), std::move(sshGroup));
++ }
++
++ std::vector<std::string>
++ getUsersInGroup(const std::string &groupName) const override
++ {
++ std::vector<std::string> userList;
++ std::vector<std::string> exeOutput;
++
++ try
++ {
++ exeOutput = phosphor::user::executeCmd("/usr/sbin/sss_groupshow",
++ groupName.c_str());
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Unable to get group users from sssd service");
++ // Don't throw error, just return empty usersInGroup - return
++ return userList;
++ }
++ // exeOutput should have 5 entries
++ // 0: Group
++ // 1: GID number
++ // 2: Member users
++ // 3: Is a member of
++ // 4: Member groups
++ exeOutput[2].erase(
++ exeOutput[2].begin(),
++ std::find(exeOutput[2].begin(), exeOutput[2].end(), ':'));
++ boost::algorithm::trim_left(exeOutput[2]);
++ boost::algorithm::split(userList, exeOutput[2],
++ boost::algorithm::is_any_of(","));
++ return userList;
++ }
++
++ void createUser(const std::string &userName,
++ const std::vector<std::string> &groupNames,
++ const std::string &priv, const bool &enabled) const override
++ {
++ std::string groups = getCSVFromVector(groupNames);
++ bool sshRequested = removeStringFromCSV(groups, phosphor::user::grpSsh);
++ // treat privilege as a group - This is to avoid using different file to
++ // store the same
++ if (!priv.empty())
++ {
++ if (groups.size() != 0)
++ {
++ groups += ",";
++ }
++ groups += priv;
++ }
++
++ try
++ {
++ phosphor::user::executeCmd(
++ "/usr/sbin/sss_useradd", "-m", "-G", groups.c_str(), "-s",
++ (sshRequested ? "/bin/sh" : "/bin/nologin"), userName.c_str());
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Unable to create new user in sssd service");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++
++ // Sometimes the SSSD service needs some time to actually
++ // reflect the changes to the local DB to the NSS service,
++ // that is why we have this sleep here ...
++ std::this_thread::sleep_for(std::chrono::seconds(1));
++ // update user status (locked/unlocked)
++ updateUserStatus(userName, enabled);
++ }
++
++ void renameUser(const std::string &userName,
++ const std::string &newUserName) const override
++ {
++ std::vector<std::string> exeOutput;
++ // Local Domain for sssd doesn't have a rename feature
++ // so we need to first create a new user and then delete
++ // the old one.
++ // The only issue with this is that the password for the
++ // user will have to be reseted since it is a new user being created.
++
++ // Get original user groups
++ std::vector<std::string> groups = getUserGroups(userName);
++ // Check if it has a "ssh" group by looking for the shell login
++ try
++ {
++ exeOutput = phosphor::user::executeCmd(
++ "/usr/bin/getent", "-s", "sss", "passwd", userName.c_str());
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Unable to get information for user");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++ if (exeOutput[0].find("/bin/sh"))
++ {
++ groups.emplace_back(phosphor::user::grpSsh);
++ }
++ // Call create user with the new user names and previous groups
++ // Priv is already part of the groups so that can be empty.
++ createUser(newUserName, groups, "", isUserEnabled(userName));
++
++ // Now delete original user
++ deleteUser(userName);
++ }
++
++ void deleteUser(const std::string &userName) const override
++ {
++ try
++ {
++ phosphor::user::executeCmd("/usr/sbin/sss_userdel", "-r",
++ userName.c_str());
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Unable to delete user from sssd service");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++ }
++
++ void updateGroupsAndPriv(const std::string &userName,
++ const std::vector<std::string> &groupNames,
++ const std::string &priv) const override
++ {
++ // local domain sssd do not allow to update all list of groups,
++ // so we will remove all groups first (except for the user one)
++ // and then all all the ones that were passed
++ std::string oldGroups = getCSVFromVector(getUserGroups(userName));
++ std::string groups = getCSVFromVector(groupNames);
++ bool sshRequested = removeStringFromCSV(groups, phosphor::user::grpSsh);
++ // treat privilege as a group - This is to avoid using different file to
++ // store the same
++ if (!priv.empty())
++ {
++ if (groups.size() != 0)
++ {
++ groups += ",";
++ }
++ groups += priv;
++ }
++ try
++ {
++ phosphor::user::executeCmd(
++ "/usr/sbin/sss_usermod", "-r", oldGroups.c_str(), "-a",
++ groups.c_str(), "-s",
++ (sshRequested ? "/bin/sh" : "/bin/nologin"), userName.c_str());
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Unable to update user groups and "
++ "priv from sssd service");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++ }
++
++ void updateUserStatus(const std::string &userName,
++ const bool &enabled) const override
++ {
++ std::string enabledStr;
++ std::string lockedStr;
++ if (isUserEnabled(userName) == enabled)
++ {
++ return;
++ }
++ if (enabled)
++ {
++ enabledStr = "-r";
++ lockedStr = "-U";
++ }
++ else
++ {
++ enabledStr = "-a";
++ lockedStr = "-L";
++ }
++ try
++ {
++ // We will add a special locked group to identify the users
++ // that have been locked out of the system.
++ // TODO: sss_usermod is not locking user accounts for the
++ // LOCAL domain, need to find the correct PAM configuration
++ // to actually lockout users for SSSD.
++ // As a workaround we are using the pam module pam_listfile.so
++ // to lockout all users that belong to the locked group.
++ phosphor::user::executeCmd("/usr/sbin/sss_usermod",
++ enabledStr.c_str(), lockedGrp.c_str(),
++ lockedStr.c_str(), userName.c_str());
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Unable to update user status from sssd service");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++ }
++
++ bool isUserEnabled(const std::string &userName) const override
++ {
++ std::vector<std::string> userGrps = getUserGroups(userName);
++ return std::find(userGrps.begin(), userGrps.end(), lockedGrp) ==
++ userGrps.end();
++ }
++
++ std::vector<std::string>
++ getUserGroups(const std::string &userName) const override
++ {
++ std::vector<std::string> exeOutput;
++ try
++ {
++ exeOutput =
++ phosphor::user::executeCmd("/usr/bin/groups", userName.c_str());
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Unable to get groups for user");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++
++ std::vector<std::string> groups;
++ boost::algorithm::split(groups, exeOutput[0],
++ boost::algorithm::is_any_of(" "));
++ // Delete group that equals user name if it exists
++ auto userNameGroup = std::find(groups.begin(), groups.end(), userName);
++ if (userNameGroup != groups.end())
++ {
++ groups.erase(userNameGroup);
++ }
++ return groups;
++ }
++
++ void createGroup(const std::string &groupName) const override
++ {
++ try
++ {
++ if (!groupExists(groupName))
++ {
++ phosphor::user::executeCmd("/usr/sbin/sss_groupadd",
++ groupName.c_str());
++ }
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Unable to create group");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++ }
++
++ private:
++ static const std::string lockedGrp;
++
++ bool groupExists(const std::string &groupName) const
++ {
++ try
++ {
++ phosphor::user::executeCmd("/usr/sbin/sss_groupshow",
++ groupName.c_str());
++ }
++ catch (const phosphor::user::InternalFailure &e)
++ {
++ return false;
++ }
++ return true;
++ }
++};
++
++const std::string SSSDService::lockedGrp = "sssd_locked";
++} // anonymous namespace
++
++namespace phosphor
++{
++namespace user
++{
++
++UserService::UserService(const ServiceType &srvcType,
++ const std::vector<std::string> &groups,
++ const std::vector<std::string> &privs)
++{
++ setServiceImpl(srvcType, groups, privs);
++}
++
++void UserService::updateServiceType(const ServiceType &srvcType,
++ const std::vector<std::string> &groups,
++ const std::vector<std::string> &privs)
++{
++ usrSrvcImpl.reset();
++ setServiceImpl(srvcType, groups, privs);
++}
++
++void UserService::setServiceImpl(const ServiceType &srvcType,
++ const std::vector<std::string> &groups,
++ const std::vector<std::string> &privs)
++{
++ switch (srvcType)
++ {
++ case ServiceType::shadow:
++ {
++ usrSrvcImpl = std::make_unique<ShadowService>();
++ }
++ break;
++
++ case ServiceType::sssd:
++ {
++ usrSrvcImpl = std::make_unique<SSSDService>(groups, privs);
++ }
++ break;
++
++ case ServiceType::none:
++ default:
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Invalid service type initialization!");
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++ break;
++ }
++}
++
++UserService::~UserService()
++{
++}
++
++phosphor::user::UserSSHLists UserService::getUserAndSshGrpList() const
++{
++ return usrSrvcImpl->getUserAndSshGrpList();
++}
++
++std::vector<std::string>
++ UserService::getUsersInGroup(const std::string &groupName) const
++{
++ return usrSrvcImpl->getUsersInGroup(groupName);
++}
++
++void UserService::createUser(const std::string &userName,
++ const std::vector<std::string> &groupNames,
++ const std::string &priv, const bool &enabled) const
++{
++ usrSrvcImpl->createUser(userName, groupNames, priv, enabled);
++}
++
++void UserService::renameUser(const std::string &userName,
++ const std::string &newUserName) const
++{
++ usrSrvcImpl->renameUser(userName, newUserName);
++}
++
++void UserService::deleteUser(const std::string &userName) const
++{
++ usrSrvcImpl->deleteUser(userName);
++}
++
++void UserService::updateGroupsAndPriv(
++ const std::string &userName, const std::vector<std::string> &groupNames,
++ const std::string &priv) const
++{
++ usrSrvcImpl->updateGroupsAndPriv(userName, groupNames, priv);
++}
++
++void UserService::updateUserStatus(const std::string &userName,
++ const bool &enabled) const
++{
++ usrSrvcImpl->updateUserStatus(userName, enabled);
++}
++
++bool UserService::isUserEnabled(const std::string &userName) const
++{
++ return usrSrvcImpl->isUserEnabled(userName);
++}
++
++std::vector<std::string>
++ UserService::getUserGroups(const std::string &userName) const
++{
++ return usrSrvcImpl->getUserGroups(userName);
++}
++
++} // namespace user
++} // namespace phosphor
+diff --git a/user_service.hpp b/user_service.hpp
+new file mode 100644
+index 0000000..97a049b
+--- /dev/null
++++ b/user_service.hpp
+@@ -0,0 +1,233 @@
++/*
++// Copyright (c) 2018 Intel Corporation
++//
++// Licensed under the Apache License, Version 2.0 (the "License");
++// you may not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++*/
++
++#pragma once
++#include <xyz/openbmc_project/Common/error.hpp>
++#include <xyz/openbmc_project/User/Common/error.hpp>
++#include <phosphor-logging/log.hpp>
++#include <phosphor-logging/elog.hpp>
++#include <boost/process/child.hpp>
++#include <boost/process/io.hpp>
++
++namespace phosphor
++{
++namespace user
++{
++
++using UserSSHLists =
++ std::pair<std::vector<std::string>, std::vector<std::string>>;
++using InternalFailure =
++ sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
++using InsufficientPermission =
++ sdbusplus::xyz::openbmc_project::Common::Error::InsufficientPermission;
++
++const std::string grpSsh = "ssh";
++
++template <typename... ArgTypes>
++std::vector<std::string> executeCmd(const char *path, ArgTypes &&... tArgs)
++{
++ std::vector<std::string> stdOutput;
++ boost::process::ipstream stdOutStream;
++ boost::process::child execProg(path, const_cast<char *>(tArgs)...,
++ boost::process::std_out > stdOutStream);
++ std::string stdOutLine;
++
++ while (stdOutStream && std::getline(stdOutStream, stdOutLine) &&
++ !stdOutLine.empty())
++ {
++ stdOutput.emplace_back(stdOutLine);
++ }
++
++ execProg.wait();
++
++ int retCode = execProg.exit_code();
++ if (retCode)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Command execution failed",
++ phosphor::logging::entry("PATH=%d", path),
++ phosphor::logging::entry("RETURN_CODE:%d", retCode));
++ phosphor::logging::elog<phosphor::user::InternalFailure>();
++ }
++
++ return stdOutput;
++}
++
++/** @class UserServiceInterface
++ * @brief Interface class for methods provided by the implemmentations
++ * of the user service. Provides the same methods as the UserService
++ * class.
++ */
++class UserServiceInterface
++{
++ public:
++ UserServiceInterface() = default;
++ virtual ~UserServiceInterface() = default;
++ virtual UserSSHLists getUserAndSshGrpList() const = 0;
++ virtual std::vector<std::string>
++ getUsersInGroup(const std::string &groupName) const = 0;
++ virtual void createUser(const std::string &userName,
++ const std::vector<std::string> &groupNames,
++ const std::string &priv,
++ const bool &enabled) const = 0;
++ virtual void renameUser(const std::string &userName,
++ const std::string &newUserName) const = 0;
++ virtual void deleteUser(const std::string &userName) const = 0;
++ virtual void updateGroupsAndPriv(const std::string &userName,
++ const std::vector<std::string> &groupNames,
++ const std::string &priv) const = 0;
++ virtual void updateUserStatus(const std::string &userName,
++ const bool &enabled) const = 0;
++ virtual bool isUserEnabled(const std::string &userName) const = 0;
++ virtual std::vector<std::string>
++ getUserGroups(const std::string &userName) const = 0;
++ virtual void createGroup(const std::string &groupName) const = 0;
++};
++
++/** @class UserService
++ * @brief Responsible for managing the user service for the user manager.
++ * This service is the one responsible to actually change the user information
++ * of the application. It can support sevaral services, currently the ones
++ * supported are:
++ *
++ * 1) Shadow: Which uses the /etc/shadow file for updating the users
++ * 2) SSSD: Which uses the sssd service for a LOCAL domain only right now.
++ */
++class UserService
++{
++ public:
++ UserService() = delete;
++ UserService(const UserService &) = delete;
++ UserService &operator=(const UserService &) = delete;
++ UserService(UserService &&) = delete;
++ UserService &operator=(UserService &&) = delete;
++
++ // Service Types implemented. None is used to validate.
++ enum class ServiceType
++ {
++ none,
++ shadow,
++ sssd
++ };
++
++ UserService(const ServiceType &srvcType,
++ const std::vector<std::string> &groups,
++ const std::vector<std::string> &privs);
++ ~UserService();
++
++ /** @brief update the current Service type of the instance.
++ * This function is used to update in real time the service
++ * being used for the user management without restarting the
++ * whole service.
++ *
++ * @param[in] srvcType
++ * @param[in] groups
++ * @param[in] privs
++ */
++ void updateServiceType(const ServiceType &srvcType,
++ const std::vector<std::string> &groups,
++ const std::vector<std::string> &privs);
++
++ /** @brief get user list and SSH group members list
++ * This method gets the list of users from the service.
++ * If the userlist reference is empty, all the users will be added
++ * and DBus notified about them. If the list is not empty, the function
++ * will only update list adding the missing ones to it. It will not remove
++ * any extra users on the list that are not part of the service!
++ *
++ */
++ UserSSHLists getUserAndSshGrpList() const;
++
++ /** @brief Get users in group.
++ * This method creates a new user as requested
++ *
++ * @param[in] groupName - Name of the group which has to be queried
++ */
++ std::vector<std::string>
++ getUsersInGroup(const std::string &groupName) const;
++
++ /** @brief create user method.
++ * This method creates a new user as requested
++ *
++ * @param[in] userName - Name of the user which has to be created
++ * @param[in] groupNames - Group names list, to which user has to be added.
++ * @param[in] priv - Privilege of the user.
++ * @param[in] enabled - State of the user enabled / disabled.
++ */
++ void createUser(const std::string &userName,
++ const std::vector<std::string> &groupNames,
++ const std::string &priv, const bool &enabled) const;
++
++ /** @brief rename user method.
++ * This method renames the user as requested
++ *
++ * @param[in] userName - current name of the user
++ * @param[in] userName - user name to which it has to be renamed.
++ */
++ void renameUser(const std::string &userName,
++ const std::string &newUserName) const;
++
++ /** @brief delete user method.
++ * This method deletes the user as requested
++ *
++ * @param[in] userName - Name of the user which has to be deleted
++ */
++ void deleteUser(const std::string &userName) const;
++
++ /** @brief Updates user Groups and Privilege.
++ *
++ * @param[in] userName - Name of the user which has to be modified
++ * @param[in] groupNames - Group names list for user.
++ * @param[in] priv - Privilege of the user.
++ */
++ void updateGroupsAndPriv(const std::string &userName,
++ const std::vector<std::string> &groupNames,
++ const std::string &priv) const;
++
++ /** @brief Updates user status
++ * If enabled = false: User will be disabled
++ * If enabled = true : User will be enabled
++ *
++ * @param[in] userName - Name of the user
++ * @param[in] enabled - Status of the user: enabled / disabled?
++ */
++ void updateUserStatus(const std::string &userName,
++ const bool &enabled) const;
++
++ /** @brief Verify if user is enabled or not
++ * If enabled returns true
++ * If not enabled returns false
++ *
++ * @param[in] userName - Name of the user
++ */
++ bool isUserEnabled(const std::string &userName) const;
++
++ /** @brief Get the list of groups a user belongs to
++ *
++ * @param[in] userName - Name of the user
++ */
++ std::vector<std::string> getUserGroups(const std::string &userName) const;
++
++ private:
++ // User service implementation.
++ void setServiceImpl(const ServiceType &srvcType,
++ const std::vector<std::string> &groups,
++ const std::vector<std::string> &privs);
++ std::unique_ptr<UserServiceInterface> usrSrvcImpl;
++};
++
++} // namespace user
++} // namespace phosphor
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend
new file mode 100644
index 000000000..2cc081433
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend
@@ -0,0 +1,9 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+#SRC_URI = "git://github.com/openbmc/phosphor-user-manager"
+SRCREV = "75b5a6fc4c0c06f43623fe0e746fd55e667dceb3"
+
+
+SRC_URI += " \
+ file://0005-Added-suport-for-multiple-user-manager-services.patch \
+ "
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog.bb
new file mode 100644
index 000000000..950f4932d
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog.bb
@@ -0,0 +1,35 @@
+
+SUMMARY = "FRB2 timer service"
+DESCRIPTION = "The FRB2 timer service will monitor the mailbox register 0\
+and start a watchdog for FRB2 if the data is 1(BIOS will write this value)"
+
+SRC_URI = "\
+ file://CMakeLists.txt \
+ file://frb2-watchdog.cpp \
+ "
+PV = "0.1"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${PHOSPHORBASE}/LICENSE;md5=19407077e42b1ba3d653da313f1f5b4e"
+
+S = "${WORKDIR}"
+
+inherit cmake
+inherit pkgconfig pythonnative
+
+DEPENDS += " \
+ systemd \
+ sdbusplus \
+ sdbusplus-native \
+ phosphor-logging \
+ phosphor-dbus-interfaces \
+ phosphor-dbus-interfaces-native \
+ boost \
+ "
+
+RDEPENDS_${PN} += " \
+ libsystemd \
+ sdbusplus \
+ phosphor-logging \
+ phosphor-dbus-interfaces \
+ "
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/.clang-format b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/.clang-format
new file mode 100644
index 000000000..dd2770837
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/.clang-format
@@ -0,0 +1,98 @@
+---
+Language: Cpp
+# BasedOnStyle: LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: false
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterClass: true
+ AfterControlStatement: true
+ AfterEnum: true
+ AfterFunction: true
+ AfterNamespace: true
+ AfterObjCDeclaration: true
+ AfterStruct: true
+ AfterUnion: true
+ BeforeCatch: true
+ BeforeElse: true
+ IndentBraces: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: AfterColon
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: true
+PointerAlignment: Left
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IncludeBlocks: Regroup
+IncludeCategories:
+ - Regex: '^[<"](gtest|gmock)'
+ Priority: 5
+ - Regex: '^"config.h"'
+ Priority: -1
+ - Regex: '^".*\.hpp"'
+ Priority: 1
+ - Regex: '^<.*\.h>'
+ Priority: 2
+ - Regex: '^<.*'
+ Priority: 3
+ - Regex: '.*'
+ Priority: 4
+IndentCaseLabels: true
+IndentWidth: 4
+IndentWrappedFunctionNames: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Right
+ReflowComments: true
+SortIncludes: true
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp11
+TabWidth: 4
+UseTab: Never
+...
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/CMakeLists.txt b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/CMakeLists.txt
new file mode 100644
index 000000000..bd5567d31
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/CMakeLists.txt
@@ -0,0 +1,52 @@
+cmake_minimum_required (VERSION 3.5 FATAL_ERROR)
+project (frb2-watchdog CXX)
+set (CMAKE_CXX_STANDARD 17)
+set (CMAKE_CXX_STANDARD_REQUIRED ON)
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti")
+
+include_directories (${CMAKE_CURRENT_SOURCE_DIR})
+
+# boost support
+find_package (Boost REQUIRED)
+# pkg_check_modules(Boost boost REQUIRED)
+include_directories (${Boost_INCLUDE_DIRS})
+add_definitions (-DBOOST_ERROR_CODE_HEADER_ONLY)
+add_definitions (-DBOOST_SYSTEM_NO_DEPRECATED)
+add_definitions (-DBOOST_ALL_NO_LIB)
+add_definitions (-DBOOST_NO_RTTI)
+add_definitions (-DBOOST_NO_TYPEID)
+add_definitions (-DBOOST_ASIO_DISABLE_THREADS)
+
+# import libsystemd
+find_package (PkgConfig REQUIRED)
+pkg_check_modules (SYSTEMD libsystemd REQUIRED)
+include_directories (${SYSTEMD_INCLUDE_DIRS})
+link_directories (${SYSTEMD_LIBRARY_DIRS})
+
+# import sdbusplus
+find_package (PkgConfig REQUIRED)
+pkg_check_modules (SDBUSPLUSPLUS sdbusplus REQUIRED)
+include_directories (${SDBUSPLUSPLUS_INCLUDE_DIRS})
+link_directories (${SDBUSPLUSPLUS_LIBRARY_DIRS})
+
+# import phosphor-logging
+find_package (PkgConfig REQUIRED)
+pkg_check_modules (LOGGING phosphor-logging REQUIRED)
+include_directories (${LOGGING_INCLUDE_DIRS})
+link_directories (${LOGGING_LIBRARY_DIRS})
+
+# import phosphor-dbus-interfaces
+find_package (PkgConfig REQUIRED)
+pkg_check_modules (DBUSINTERFACE phosphor-dbus-interfaces REQUIRED)
+include_directories (${DBUSINTERFACE_INCLUDE_DIRS})
+link_directories (${DBUSINTERFACE_LIBRARY_DIRS})
+
+add_executable (frb2-watchdog frb2-watchdog.cpp)
+
+target_link_libraries (${PROJECT_NAME} systemd)
+target_link_libraries (${PROJECT_NAME} ${Boost_LIBRARIES})
+target_link_libraries (${PROJECT_NAME} ${SDBUSPLUSPLUS_LIBRARIES})
+target_link_libraries (${PROJECT_NAME} ${DBUSINTERFACE_LIBRARIES}
+ phosphor_logging)
+install (TARGETS frb2-watchdog DESTINATION bin)
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/cmake-format.json b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/cmake-format.json
new file mode 100644
index 000000000..583c255a3
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/cmake-format.json
@@ -0,0 +1,12 @@
+{
+ "enum_char": ".",
+ "line_ending": "unix",
+ "bullet_char": "*",
+ "max_subargs_per_line": 99,
+ "command_case": "lower",
+ "tab_size": 4,
+ "line_width": 80,
+ "separate_fn_name_with_space": true,
+ "dangle_parens": true,
+ "separate_ctrl_name_with_space": true
+} \ No newline at end of file
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/frb2-watchdog.cpp b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/frb2-watchdog.cpp
new file mode 100644
index 000000000..5356e95db
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog/frb2-watchdog.cpp
@@ -0,0 +1,258 @@
+/* Copyright 2018 Intel
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <boost/container/flat_set.hpp>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+#include <iostream>
+#include <memory>
+#include <optional>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/timer.hpp>
+#include <vector>
+#include <xyz/openbmc_project/State/Watchdog/server.hpp>
+
+void handleResponse(const boost::system::error_code &err,
+ std::size_t bytes_transferred);
+
+static int mailboxDevFd = -1;
+
+static boost::asio::io_service io;
+static auto conn = std::make_shared<sdbusplus::asio::connection>(io);
+boost::asio::ip::tcp::socket mailBoxDevSocket(io);
+boost::asio::deadline_timer pollTimer(io);
+boost::asio::posix::stream_descriptor inputDevice(io);
+
+// mailbox registre data[0:0] for FRB2 enable bit
+boost::asio::streambuf readBuf(1);
+std::string dataRead;
+
+// FRB2 watchdog timeout is 6 minutes
+static constexpr unsigned int frb2TimerIntervalMs = 360 * 1000;
+
+// mailbox device polling time interval is 2 seconds
+static constexpr unsigned int pollMs = 2000;
+
+static constexpr unsigned int frb2Started = 1;
+static constexpr unsigned int frb2Stopped = 0;
+
+// FRB2 status
+static uint8_t frb2Status = frb2Stopped;
+
+static constexpr const char *mailboxDevName = "/dev/aspeed-mbox";
+
+static constexpr const char frb2Bus[] = "xyz.openbmc_project.FRB2";
+static constexpr const char frb2Obj[] = "/xyz/openbmc_project/FRB2";
+static constexpr const char frb2Intf[] = "xyz.openbmc_project.FRB2";
+
+static constexpr char powerBus[] = "xyz.openbmc_project.Chassis.Control.Power";
+static constexpr char powerPath[] =
+ "/xyz/openbmc_project/Chassis/Control/Power0";
+static constexpr char powerIntf[] = "xyz.openbmc_project.Chassis.Control.Power";
+
+static constexpr char wdBus[] = "xyz.openbmc_project.Watchdog";
+static constexpr char wdPath[] = "/xyz/openbmc_project/watchdog/host0";
+static constexpr char wdIntf[] = "xyz.openbmc_project.State.Watchdog";
+static constexpr char propIntf[] = "org.freedesktop.DBus.Properties";
+
+typedef boost::asio::buffers_iterator<boost::asio::const_buffers_1> iterator;
+
+// check if FRB2 bit is 0x1
+std::pair<iterator, bool> matchFRB2(iterator begin, iterator end)
+{
+ unsigned char ch = 0;
+ iterator i = begin;
+
+ while (i != end)
+ {
+ ch = static_cast<unsigned char>(*i);
+ if (ch & 0x1)
+ {
+ return std::make_pair(i, true);
+ }
+ i++;
+ }
+
+ return std::make_pair(i, false);
+}
+
+static void startRead()
+{
+ boost::asio::async_read_until(inputDevice, readBuf, matchFRB2,
+ [&](const boost::system::error_code &ec,
+ std::size_t bytes_transferred) {
+ handleResponse(ec, bytes_transferred);
+ });
+}
+
+template <typename T> void setProperty(const std::string &key, const T &val)
+{
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ "setProperty", phosphor::logging::entry("KEY=%s", key.c_str()));
+
+ try
+ {
+ conn->async_method_call(
+ [](const boost::system::error_code &err) {
+ if (err)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "async_method_call error!",
+ phosphor::logging::entry(
+ "ERROR=%s",
+ boost::system::system_error(err).what()));
+ }
+ },
+ wdBus, wdPath, propIntf, "Set", wdIntf, key,
+ sdbusplus::message::variant_ns::variant<T>(val));
+ }
+ catch (sdbusplus::exception::SdBusError &e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Dbus error!", phosphor::logging::entry("ERROR=%s", e.what()));
+ }
+}
+void handleResponse(const boost::system::error_code &err,
+ std::size_t bytes_transferred)
+{
+ std::istream responseStream(&readBuf);
+ std::string response;
+ int n = 0;
+ uint64_t interval = frb2TimerIntervalMs;
+
+ std::getline(responseStream, response);
+ responseStream.clear();
+
+ if (err == boost::system::errc::bad_file_descriptor)
+ {
+
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ "bad file descriptor");
+ return; // we're being destroyed
+ }
+
+ if (!err)
+ {
+ // FRB2 is set by BIOS
+ if (frb2Stopped == frb2Status)
+ {
+ // start FRB2 watchdog
+ frb2Status = frb2Started;
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ "FRB2 enable, start FRB2 watchdog");
+ setProperty(
+ "ExpireAction",
+ std::string(
+ "xyz.openbmc_project.State.Watchdog.Action.HardReset"));
+ setProperty("Interval", interval);
+ setProperty("TimeRemaining", interval);
+ setProperty("Initialized", true);
+ setProperty("Enabled", true);
+ }
+ }
+ else if (err == boost::asio::error::misc_errors::not_found)
+ {
+ // FRB2 is clear, stop FRB2 watchdog if it is started
+ if (frb2Started == frb2Status)
+ {
+ frb2Status = frb2Stopped;
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ "FRB2 is unset, stop FRB2 watchdog");
+ setProperty("Enabled", false);
+ }
+ }
+ else
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "handleResponse error!",
+ phosphor::logging::entry("ERROR=%s",
+ boost::system::system_error(err).what()));
+ }
+
+ pollTimer.expires_from_now(boost::posix_time::milliseconds(pollMs));
+ pollTimer.async_wait(
+ [](const boost::system::error_code &ec) { startRead(); });
+}
+
+int main(int argc, char **argv)
+{
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ "Monitor FRB2 signal");
+
+ sdbusplus::bus::match_t biosPostSignal(
+ static_cast<sdbusplus::bus::bus &>(*conn),
+ sdbusplus::bus::match::rules::type::signal() +
+ sdbusplus::bus::match::rules::member("PostCompleted") +
+ sdbusplus::bus::match::rules::path(powerPath) +
+ sdbusplus::bus::match::rules::interface(powerIntf),
+ [](sdbusplus::message::message &msg) {
+ uint8_t value = 0;
+ ssize_t rc = 0;
+ phosphor::logging::log<phosphor::logging::level::INFO>(
+ "BIOS post completed signal");
+ // stop FRB2 and clean mailbox
+ value = 0;
+ rc = ::pwrite(mailboxDevFd, &value, 1, 0);
+ if (rc != 1)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "mailbox write error!");
+ }
+ setProperty("Enabled", false);
+ frb2Status = frb2Stopped;
+ return;
+ });
+
+ conn->request_name(frb2Bus);
+
+ auto server = sdbusplus::asio::object_server(conn);
+
+ std::shared_ptr<sdbusplus::asio::dbus_interface> frb2Iface =
+ server.add_interface(frb2Obj, frb2Intf);
+
+ frb2Iface->register_property("frb2Status", frb2Status);
+
+ frb2Iface->initialize();
+
+ mailboxDevFd = ::open(mailboxDevName, O_RDWR | O_CLOEXEC);
+ if (mailboxDevFd < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "mailbox device open fail!");
+ return -1;
+ }
+
+ inputDevice.assign(mailboxDevFd);
+
+ startRead();
+
+ io.run();
+
+ ::close(mailboxDevFd);
+
+ return 0;
+}
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0001-Add-redfish-log-support-for-IPMI-watchdog-timeout-ac.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0001-Add-redfish-log-support-for-IPMI-watchdog-timeout-ac.patch
new file mode 100644
index 000000000..28995d14b
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0001-Add-redfish-log-support-for-IPMI-watchdog-timeout-ac.patch
@@ -0,0 +1,51 @@
+From 38faf5c040660e752741dcf7f03e4bb1e9f3411b Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Thu, 4 Apr 2019 18:24:54 +0800
+Subject: [PATCH] Add redfish log support for IPMI watchdog timeout actions
+
+The current plan is that only threshold sensor events
+will be logged to the IPMI SEL,
+and all other events will be logged to the Redfish Event Log.
+
+Tested:
+Config IPMI watchdog: OEM hard reset after 10 seconds:
+ipmitool raw 0x06 0x24 0x5 0x1 0x0 0x0 0x64 0x00
+Start watchdog:
+Ipmitool mc watchdog reset
+Check the redfish logs in 10 seconds:
+https://BMCIP/redfish/v1/Systems/system/LogServices/EventLog/Entries
+
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ watchdog.cpp | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/watchdog.cpp b/watchdog.cpp
+index bc3ba95..4774fd8 100644
+--- a/watchdog.cpp
++++ b/watchdog.cpp
+@@ -1,5 +1,7 @@
+ #include "watchdog.hpp"
+
++#include <systemd/sd-journal.h>
++
+ #include <chrono>
+ #include <phosphor-logging/elog.hpp>
+ #include <phosphor-logging/log.hpp>
+@@ -101,6 +103,13 @@ void Watchdog::timeOutHandler()
+ action = fallback->action;
+ }
+
++ // Log into redfish event log
++ sd_journal_send("MESSAGE=IPMIWatchdog: Timed out ACTION=%s",
++ convertForMessage(action).c_str(), "PRIORITY=%i", LOG_INFO,
++ "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.IPMIWatchdog",
++ "REDFISH_MESSAGE_ARGS=%s",
++ convertForMessage(action).c_str(), NULL);
++
+ expiredTimerUse(currentTimerUse());
+
+ auto target = actionTargetMap.find(action);
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0002-Add-restart-cause-support.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0002-Add-restart-cause-support.patch
new file mode 100644
index 000000000..05374e9db
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0002-Add-restart-cause-support.patch
@@ -0,0 +1,82 @@
+From af3a7d07b801c22a03350897c2186b1ee9507ff2 Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Sun, 14 Apr 2019 11:14:09 +0800
+Subject: [PATCH] Add restart cause support
+
+Add restart cause support for watchdog expiration, to support
+Get system restart cause command defined in IPMI spec
+
+Tested:
+Set a hard reset watchdog:
+ipmitool raw 0x06 0x24 0x5 0x1 0x0 0x0 0x64 0x00
+
+Start the timer:
+ipmitool mc watchdog reset
+
+Wait for 10 seconds, host will be restart, query the restart cause:
+Ipmitool chassis restart_cause
+System restart cause: watchdog expired
+
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ watchdog.cpp | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/watchdog.cpp b/watchdog.cpp
+index 008cde5..7f1ec05 100644
+--- a/watchdog.cpp
++++ b/watchdog.cpp
+@@ -7,6 +7,7 @@
+ #include <phosphor-logging/log.hpp>
+ #include <sdbusplus/exception.hpp>
+ #include <xyz/openbmc_project/Common/error.hpp>
++#include <xyz/openbmc_project/State/Host/server.hpp>
+
+ namespace phosphor
+ {
+@@ -24,6 +25,12 @@ constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
+ constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1";
+ constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
+
++// host state manager service
++static constexpr const char* hostService = "xyz.openbmc_project.State.Host";
++static constexpr const char* hostPath = "/xyz/openbmc_project/state/host0";
++static constexpr const char* hostInterface = "xyz.openbmc_project.State.Host";
++static constexpr const char* dbusPropIf = "org.freedesktop.DBus.Properties";
++
+ void Watchdog::resetTimeRemaining(bool enableWatchdog)
+ {
+ timeRemaining(interval());
+@@ -139,6 +146,29 @@ void Watchdog::timeOutHandler()
+ entry("ERROR=%s", e.what()));
+ commit<InternalFailure>();
+ }
++
++ // set restart cause for watchdog HardReset & PowerCycle actions
++ if ((action == Watchdog::Action::HardReset) ||
++ (action == Watchdog::Action::PowerCycle))
++ {
++ sdbusplus::message::variant<std::string> property =
++ convertForMessage(
++ (sdbusplus::xyz::openbmc_project::State::server::Host::
++ RestartCause::WatchdogTimer));
++ try
++ {
++ auto method = bus.new_method_call(hostService, hostPath,
++ dbusPropIf, "Set");
++ method.append(hostInterface, "HostRestartCause", property);
++ bus.call(method);
++ }
++ catch (sdbusplus::exception_t& e)
++ {
++ log<level::ERR>("Failed to set HostRestartCause property",
++ entry("ERROR=%s", e.what()));
++ commit<InternalFailure>();
++ }
++ }
+ }
+
+ tryFallbackOrDisable();
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0003-Add-redfish-log-support-for-IPMI-watchdog-pre-timeou.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0003-Add-redfish-log-support-for-IPMI-watchdog-pre-timeou.patch
new file mode 100644
index 000000000..309a8c646
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0003-Add-redfish-log-support-for-IPMI-watchdog-pre-timeou.patch
@@ -0,0 +1,48 @@
+From 46e8e4fe6cb48145152e37380a4064c8957d2ff7 Mon Sep 17 00:00:00 2001
+From: Ren Yu <yux.ren@intel.com>
+Date: Tue, 28 May 2019 17:04:10 +0800
+Subject: [PATCH] Add redfish log support for IPMI watchdog pre-timeout
+ interrupt
+
+Tested:
+Config IPMI watchdog: BIOS FRB2 Power Cycle after 1 seconds:
+ipmitool raw 0x06 0x24 0x01 0x13 0x0 0x2 0xa 0x00
+Start watchdog:
+Ipmitool mc watchdog reset
+Check the redfish logs in 1 seconds:
+https://BMCIP/redfish/v1/Systems/system/LogServices/EventLog/Entries
+
+Signed-off-by: Ren Yu <yux.ren@intel.com>
+---
+ watchdog.cpp | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/watchdog.cpp b/watchdog.cpp
+index d893237..5062049 100644
+--- a/watchdog.cpp
++++ b/watchdog.cpp
+@@ -104,6 +104,8 @@ uint64_t Watchdog::timeRemaining(uint64_t value)
+ // Optional callback function on timer expiration
+ void Watchdog::timeOutHandler()
+ {
++ PreTimeoutInterruptAction preTimeoutInterruptAction = preTimeoutInterrupt();
++
+ Action action = expireAction();
+ if (!this->enabled())
+ {
+@@ -117,6 +119,12 @@ void Watchdog::timeOutHandler()
+ "REDFISH_MESSAGE_ARGS=%s",
+ convertForMessage(action).c_str(), NULL);
+
++ sd_journal_send("MESSAGE=IPMIWatchdog: Pre Timed out Interrupt=%s",
++ convertForMessage(preTimeoutInterruptAction).c_str(),
++ "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
++ "OpenBMC.0.1.IPMIWatchdog", "REDFISH_MESSAGE_ARGS=%s",
++ convertForMessage(preTimeoutInterruptAction).c_str(), NULL);
++
+ expiredTimerUse(currentTimerUse());
+
+ auto target = actionTargetMap.find(action);
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/obmc-enable-host-watchdog@.service b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/obmc-enable-host-watchdog@.service
new file mode 100644
index 000000000..87a662f7c
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/obmc-enable-host-watchdog@.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Start FRB2 Watchdog%i
+Wants=obmc-host-started@%i.target
+After=obmc-host-started@%i.target
+Wants=mapper-wait@-xyz-openbmc_project-watchdog-host%i.service
+After=mapper-wait@-xyz-openbmc_project-watchdog-host%i.service
+Conflicts=obmc-host-stop@%i.target
+ConditionPathExists=!/run/openbmc/host@%i-on
+
+[Service]
+Restart=always
+ExecStart=/usr/bin/env frb2-watchdog
+ExecStopPost=/bin/sh -c "busctl call `mapper get-service /xyz/openbmc_project/watchdog/host%i` /xyz/openbmc_project/watchdog/host%i org.freedesktop.DBus.Properties Set ssv xyz.openbmc_project.State.Watchdog Enabled b false"
+SyslogIdentifier=obmc-enable-host-watchdog
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/phosphor-watchdog@.service b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/phosphor-watchdog@.service
new file mode 100644
index 000000000..251c2257b
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/phosphor-watchdog@.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Phosphor %I watchdog
+
+[Service]
+Restart=no
+EnvironmentFile={envfiledir}/obmc/watchdog/%I
+ExecStart=/usr/bin/env phosphor-watchdog --continue --service=${{SERVICE}} --path=${{DEVPATH}} \
+ --action_target=xyz.openbmc_project.State.Watchdog.Action.HardReset=obmc-host-warm-reset@0.target \
+ --action_target=xyz.openbmc_project.State.Watchdog.Action.PowerOff=obmc-host-shutdown@0.target \
+ --action_target=xyz.openbmc_project.State.Watchdog.Action.PowerCycle=obmc-host-reboot@0.target
+
+SyslogIdentifier=phosphor-watchdog
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend
new file mode 100644
index 000000000..c117102ee
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend
@@ -0,0 +1,9 @@
+FILESEXTRAPATHS_append := ":${THISDIR}/${PN}"
+
+SRC_URI += "file://0001-Add-redfish-log-support-for-IPMI-watchdog-timeout-ac.patch \
+ file://0002-Add-restart-cause-support.patch \
+ file://0003-Add-redfish-log-support-for-IPMI-watchdog-pre-timeou.patch \
+ "
+
+# Remove the override to keep service running after DC cycle
+SYSTEMD_OVERRIDE_${PN}_remove = "poweron.conf:phosphor-watchdog@poweron.service.d/poweron.conf"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb
new file mode 100644
index 000000000..5da053f1d
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb
@@ -0,0 +1,13 @@
+SUMMARY = "System watchdog"
+DESCRIPTION = "BMC hardware watchdog service that is used to reset BMC \
+ when unrecoverable events occurs"
+
+inherit allarch
+inherit obmc-phosphor-systemd
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${INTELBASE}/COPYING.apache-2.0;md5=34400b68072d710fecd0a2940a0d1658"
+
+SYSTEMD_SERVICE_${PN} += "system-watchdog.service"
+SYSTEMD_ENVIRONMENT_FILE_${PN} += "obmc/system-watchdog/system-watchdog.conf"
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/obmc/system-watchdog/system-watchdog.conf b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/obmc/system-watchdog/system-watchdog.conf
new file mode 100644
index 000000000..defe830a1
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/obmc/system-watchdog/system-watchdog.conf
@@ -0,0 +1,3 @@
+TIMEOUT=60
+INTERVAL=10
+DEVICE=/dev/watchdog1
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/system-watchdog.service b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/system-watchdog.service
new file mode 100644
index 000000000..1564fda20
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/system-watchdog.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=BMC Hardware Watchdog Daemon
+
+[Service]
+EnvironmentFile=/etc/default/obmc/system-watchdog/system-watchdog.conf
+ExecStart=/sbin/watchdog -T ${{TIMEOUT}} -t ${{INTERVAL}} -F ${{DEVICE}}
+KillSignal=SIGKILL
+
+[Install]
+WantedBy=basic.target
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui/0004-Implement-force-boot-to-bios-in-server-power-control.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui/0004-Implement-force-boot-to-bios-in-server-power-control.patch
new file mode 100644
index 000000000..0e2d400a3
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui/0004-Implement-force-boot-to-bios-in-server-power-control.patch
@@ -0,0 +1,199 @@
+From a4f948f98e9bfd8b019699b4e23281448f7b7313 Mon Sep 17 00:00:00 2001
+From: Kuiying Wang <kuiying.wang@intel.com>
+Date: Wed, 27 Mar 2019 19:35:12 +0800
+Subject: [PATCH] Implement force to BIOS
+
+UI page review use below link:
+https://projects.invisionapp.com/share/UER87D98GPM#/screens
+
+Tested:
+ Switch on "Boot To BIOS", could enter BIOS setup page directly
+ when power on system.
+
+Change-Id: Ib46dc5d84df51d31cc5ff8635fa0c0f52de0e194
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+---
+ app/common/services/api-utils.js | 49 +++++++++++++++++++
+ app/common/services/constants.js | 4 ++
+ app/common/services/dataService.js | 1 +
+ .../power-operations-controller.html | 12 +++++
+ .../power-operations-controller.js | 32 ++++++++++++
+ 5 files changed, 98 insertions(+)
+
+diff --git a/app/common/services/api-utils.js b/app/common/services/api-utils.js
+index 840db8e..193c172 100644
+--- a/app/common/services/api-utils.js
++++ b/app/common/services/api-utils.js
+@@ -31,6 +31,7 @@ window.angular && (function(angular) {
+ HOST_STATE: Constants.HOST_STATE,
+ LED_STATE: Constants.LED_STATE,
+ LED_STATE_TEXT: Constants.LED_STATE_TEXT,
++ FORCE_TO_BIOS_STATE_TEXT: Constants.FORCE_TO_BIOS_STATE_TEXT,
+ HOST_SESSION_STORAGE_KEY: Constants.API_CREDENTIALS.host_storage_key,
+ getChassisState: function() {
+ var deferred = $q.defer();
+@@ -451,6 +452,32 @@ window.angular && (function(angular) {
+ });
+ return deferred.promise;
+ },
++ getForceToBIOSState: function() {
++ var deferred = $q.defer();
++
++ if (DataService.configJson.redfishSupportEnabled == true) {
++ $http({
++ method: 'GET',
++ url:
++ DataService.getHost() + '/redfish/v1/Systems/system',
++ withCredentials: true
++ }).then(
++ function(response) {
++ var json = JSON.stringify(response.data);
++ var content = JSON.parse(json);
++ deferred.resolve(content.Boot.BootSourceOverrideTarget);
++ },
++ function(error) {
++ console.log(error);
++ deferred.reject(error);
++ });
++ } else {
++ var err = "Redfish is not enabled!";
++ console.log(err);
++ deferred.reject(err);
++ }
++ return deferred.promise;
++ },
+ login: function(username, password, callback) {
+ $http({
+ method: 'POST',
+@@ -872,6 +899,28 @@ window.angular && (function(angular) {
+ }
+ });
+ },
++ setForceToBIOSState: function(state) {
++ if (DataService.configJson.redfishSupportEnabled == true) {
++ var data = JSON.stringify({'Boot':
++ {
++ 'BootSourceOverrideTarget': state
++ }
++ });
++ return $http({
++ method: 'PATCH',
++ url:
++ DataService.getHost() + '/redfish/v1/Systems/system',
++ withCredentials: true,
++ data: data
++ });
++ } else {
++ var deferred = $q.defer();
++ var err = "Redfish is not enabled!";
++ console.log(err);
++ deferred.reject(err);
++ return deferred.promise;
++ }
++ },
+ getLastRebootTime: function() {
+ return $http({
+ method: 'GET',
+diff --git a/app/common/services/constants.js b/app/common/services/constants.js
+index 9931f01..8da0b12 100644
+--- a/app/common/services/constants.js
++++ b/app/common/services/constants.js
+@@ -38,6 +38,10 @@ window.angular && (function(angular) {
+ HOST_STATE: {on: 1, off: -1, error: 0, unreachable: -2},
+ LED_STATE: {on: true, off: false},
+ LED_STATE_TEXT: {on: 'on', off: 'off'},
++ FORCE_TO_BIOS_STATE_TEXT: {
++ on: 'BiosSetup',
++ off: 'None'
++ },
+ SEVERITY_TO_PRIORITY_MAP: {
+ Emergency: 'High',
+ Alert: 'High',
+diff --git a/app/common/services/dataService.js b/app/common/services/dataService.js
+index 76ab381..bcd7142 100644
+--- a/app/common/services/dataService.js
++++ b/app/common/services/dataService.js
+@@ -18,6 +18,7 @@ window.angular && (function(angular) {
+ this.server_status = -2;
+ this.chassis_state = 'On';
+ this.LED_state = Constants.LED_STATE_TEXT.off;
++ this.ForceToBIOS_state = Constants.FORCE_TO_BIOS_STATE_TEXT.off;
+ this.last_updated = new Date();
+
+ this.loading = false;
+diff --git a/app/server-control/controllers/power-operations-controller.html b/app/server-control/controllers/power-operations-controller.html
+index 3dc69d2..1f00f4a 100644
+--- a/app/server-control/controllers/power-operations-controller.html
++++ b/app/server-control/controllers/power-operations-controller.html
+@@ -10,6 +10,18 @@
+ <div class="row column">
+ <div id="power-indicator-bar" class="power__indicator-bar" ng-class="{'power__state-on': dataService.server_state == 'Running', 'power__state-off': dataService.server_state == 'Off', 'power__state-indet': dataService.server_state == 'Standby', 'power__state-error': dataService.server_state == 'Quiesced'}">
+ <p class="inline">{{dataService.hostname}} - {{dataService.server_id}}</p>
++ <div class="toggle float-right">
++ <input id="toggle__switch-round"
++ class="toggle-switch toggle-switch__round-flat"
++ type="checkbox"
++ tabindex="0"
++ ng-click="toggleForceToBIOS()"
++ ng-checked="dataService.ForceToBIOS_state == 'BiosSetup'"
++ ng-disabled="dataService.server_unreachable">
++ <label for="toggle__switch-round" tabindex="0"> </label>
++ <h3 class="inline">Boot to BIOS</h3>
++ </div>
++
+ <h3 class="power__state inline no-margin h3"><span>{{dataService.server_state | quiescedToError}}</span></h3>
+ </div>
+ </div>
+diff --git a/app/server-control/controllers/power-operations-controller.js b/app/server-control/controllers/power-operations-controller.js
+index 1a1f355..9a832e8 100644
+--- a/app/server-control/controllers/power-operations-controller.js
++++ b/app/server-control/controllers/power-operations-controller.js
+@@ -26,6 +26,17 @@ window.angular && (function(angular) {
+
+ var pollChassisStatusTimer = undefined;
+ var pollStartTime = null;
++ APIUtils.getForceToBIOSState().then(
++ function(data) {
++ if (data == APIUtils.FORCE_TO_BIOS_STATE_TEXT.on) {
++ dataService.ForceToBIOS_state = APIUtils.FORCE_TO_BIOS_STATE_TEXT.on;
++ } else {
++ dataService.ForceToBIOS_state = APIUtils.FORCE_TO_BIOS_STATE_TEXT.off;
++ }
++ },
++ function(error) {
++ console.log(JSON.stringify(error));
++ });
+
+ //@TODO: call api and get proper state
+
+@@ -50,6 +61,27 @@ window.angular && (function(angular) {
+ (dataService.server_state == 'Running') ? 'Off' : 'Running';
+ };
+
++ $scope.toggleForceToBIOS = function() {
++ var toggleState =
++ (dataService.ForceToBIOS_state == APIUtils.FORCE_TO_BIOS_STATE_TEXT.on) ?
++ APIUtils.FORCE_TO_BIOS_STATE_TEXT.off :
++ APIUtils.FORCE_TO_BIOS_STATE_TEXT.on;
++ dataService.ForceToBIOS_state =
++ (dataService.ForceToBIOS_state == APIUtils.FORCE_TO_BIOS_STATE_TEXT.on) ?
++ APIUtils.FORCE_TO_BIOS_STATE_TEXT.off :
++ APIUtils.FORCE_TO_BIOS_STATE_TEXT.on;
++ APIUtils.setForceToBIOSState(toggleState)
++ .then(
++ function(response) {},
++ function(errors) {
++ toastService.error(
++ 'Failed to set Boot to BIOS ');
++ console.log(JSON.stringify(errors));
++ // Reload to get correct current state
++ $route.reload();
++ })
++ };
++
+ $scope.powerOn = function() {
+ $scope.loading = true;
+ dataService.setUnreachableState();
+--
+2.19.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui_%.bbappend
new file mode 100644
index 000000000..f4b054acf
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui_%.bbappend
@@ -0,0 +1,6 @@
+FILESEXTRAPATHS_append := ":${THISDIR}/${PN}"
+
+#SRC_URI = "git://github.com/openbmc/phosphor-webui.git"
+SRCREV = "e4ae854c217344b4f35717e922083a253f43bfa0"
+
+SRC_URI += "file://0004-Implement-force-boot-to-bios-in-server-power-control.patch"