summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods
diff options
context:
space:
mode:
authorJason M. Bills <jason.m.bills@linux.intel.com>2020-06-15 21:00:52 +0300
committerJason M. Bills <jason.m.bills@linux.intel.com>2020-06-15 21:34:52 +0300
commit057594a8bb8d062d72244196170c2d78947d318a (patch)
treebd0ce34dac9b401ce5ac6919f1cd85239c526b82 /meta-openbmc-mods
parent0ccb93d91de41b7db333efccc1aa8d03db1ef63f (diff)
downloadopenbmc-057594a8bb8d062d72244196170c2d78947d318a.tar.xz
Update to internal 0.59
Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
Diffstat (limited to 'meta-openbmc-mods')
-rw-r--r--meta-openbmc-mods/meta-ast2500/recipes-phosphor/configuration/entity-manager/CPC-Baseboard.json7
-rw-r--r--meta-openbmc-mods/meta-ast2600/recipes-kernel/linux/linux-aspeed/intel-ast2600.cfg5
-rw-r--r--meta-openbmc-mods/meta-ast2600/recipes-kernel/linux/linux-aspeed_%.bbappend5
-rw-r--r--meta-openbmc-mods/meta-common/classes/image_types_intel_pfr.bbclass8
-rw-r--r--meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass2
-rw-r--r--meta-openbmc-mods/meta-common/classes/systemd-watchdog.bbclass2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-connectivity/openssl/files/environment.d-openssl.sh1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0001-buildinfo-strip-sysroot-and-debug-prefix-map-from-co.patch76
-rw-r--r--meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0001-skip-test_symbol_presence.patch46
-rw-r--r--meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/afalg.patch31
-rw-r--r--meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/reproducible.patch32
-rw-r--r--meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/run-ptest12
-rw-r--r--meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl_1.1.1g.bb211
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/crashdump/crashdump_git.bb2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp_git.bb2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem_%.bbappend2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/libpeci/libpeci_%.bbappend2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog/rotate-event-logs.service9
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog/rotate-event-logs.sh10
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog_%.bbappend13
-rw-r--r--meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/intel-blocksign-native.bb2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2.bb2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2600-platforms.patch44
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0092-SPI-Quad-IO-driver-support-AST2600.patch8
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0106-enable-AST2600-I3C.patch922
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0107-arm-dts-aspeed-g6-Add-ast2600-mctp-node.patch79
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0108-soc-aspeed-mctp-Add-initial-driver-for-ast2600-mctp.patch1265
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0109-signal-Extend-exec_id-to-64bits.patch88
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0110-USB-gadget-fix-illegal-array-access-in-binding-with-.patch75
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend5
-rw-r--r--meta-openbmc-mods/meta-common/recipes-network/network/static-mac-addr/mac-check60
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0005-Modified-firmware-activation-to-launch-fwupd.sh-thro.patch24
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-ipmb/0001-Add-dbus-method-SlotIpmbRequest.patch536
-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-net/10-nice-rules.conf2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net_%.bbappend9
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/pmci/libmctp-intel_git.bb2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/pmci/mctp-emulator.bb30
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/pmci/mctpd.bb2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sel-logger/phosphor-sel-logger_%.bbappend2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend2
-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/users/phosphor-user-manager/0005-Added-suport-for-multiple-user-manager-services.patch49
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0006-Use-groupmems-instead-of-getgrnam_r-due-to-overlay.patch4
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend3
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.sh9
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset@.service (renamed from meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.service)2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui_%.bbappend2
52 files changed, 3613 insertions, 137 deletions
diff --git a/meta-openbmc-mods/meta-ast2500/recipes-phosphor/configuration/entity-manager/CPC-Baseboard.json b/meta-openbmc-mods/meta-ast2500/recipes-phosphor/configuration/entity-manager/CPC-Baseboard.json
index 80d4606bb..793c790c8 100644
--- a/meta-openbmc-mods/meta-ast2500/recipes-phosphor/configuration/entity-manager/CPC-Baseboard.json
+++ b/meta-openbmc-mods/meta-ast2500/recipes-phosphor/configuration/entity-manager/CPC-Baseboard.json
@@ -1877,6 +1877,13 @@
"CpuID": 8,
"Name": "CPU 8",
"Type": "XeonCPU"
+ },
+ {
+ "Name": "ASD",
+ "BMC_XDP_PRST_IN": {
+ "PinType": "PIN_NONE"
+ },
+ "Type": "ASD"
}
],
"Name": "CPC Baseboard",
diff --git a/meta-openbmc-mods/meta-ast2600/recipes-kernel/linux/linux-aspeed/intel-ast2600.cfg b/meta-openbmc-mods/meta-ast2600/recipes-kernel/linux/linux-aspeed/intel-ast2600.cfg
index a044ce6cd..7992be527 100644
--- a/meta-openbmc-mods/meta-ast2600/recipes-kernel/linux/linux-aspeed/intel-ast2600.cfg
+++ b/meta-openbmc-mods/meta-ast2600/recipes-kernel/linux/linux-aspeed/intel-ast2600.cfg
@@ -4,6 +4,8 @@ CONFIG_SPI_ASPEED_SMC=y
CONFIG_SPI_FMC=y
CONFIG_I3C=y
CONFIG_DW_I3C_MASTER=y
+CONFIG_ASPEED_I3C_GLOBAL=y
+CONFIG_I3CDEV=y
CONFIG_JTAG_ASPEED=n
CONFIG_U_SERIAL_CONSOLE=n
CONFIG_KERNEL_LZO=y
@@ -14,5 +16,6 @@ CONFIG_DEBUG_LL=n
CONFIG_DEBUG_LL_UART_8250=n
CONFIG_EARLY_PRINTK=n
CONFIG_LOG_BUF_SHIFT=21
-CONFIG_DEBUG_PINCTRL=y
+CONFIG_DEBUG_PINCTRL=n
CONFIG_SUSPEND=n
+CONFIG_ASPEED_MCTP=y
diff --git a/meta-openbmc-mods/meta-ast2600/recipes-kernel/linux/linux-aspeed_%.bbappend b/meta-openbmc-mods/meta-ast2600/recipes-kernel/linux/linux-aspeed_%.bbappend
index d32f38611..07cafe94e 100644
--- a/meta-openbmc-mods/meta-ast2600/recipes-kernel/linux/linux-aspeed_%.bbappend
+++ b/meta-openbmc-mods/meta-ast2600/recipes-kernel/linux/linux-aspeed_%.bbappend
@@ -1,9 +1,6 @@
COMPATIBLE_MACHINE = "intel-ast2600"
-FILESEXTRAPATHS_prepend := "${THISDIR}/linux-aspeed:"
-#SRCREV="f9e04c3157234671b9d5e27bf9b7025b8b21e0d4"
-#LINUX_VERSION="5.2.11"
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
-# TODO: the base kernel dtsi fixups patch should be pushed upstream
SRC_URI += " \
file://intel-ast2600.cfg \
file://0001-Add-a-workaround-to-cover-UART-interrupt-bug-in-AST2.patch \
diff --git a/meta-openbmc-mods/meta-common/classes/image_types_intel_pfr.bbclass b/meta-openbmc-mods/meta-common/classes/image_types_intel_pfr.bbclass
index abbb0d2dc..344dddd3d 100644
--- a/meta-openbmc-mods/meta-common/classes/image_types_intel_pfr.bbclass
+++ b/meta-openbmc-mods/meta-common/classes/image_types_intel_pfr.bbclass
@@ -72,8 +72,12 @@ do_image_pfr () {
mv ${PFR_IMAGES_DIR}/bmc_unsigned_cap.bin ${PFR_IMAGES_DIR}/bmc_unsigned_cap-${DATETIME}.bin
mv ${PFR_IMAGES_DIR}/bmc_signed_cap.bin ${PFR_IMAGES_DIR}/bmc_signed_cap-${DATETIME}.bin
mv ${PFR_IMAGES_DIR}/image-mtd-pfr ${PFR_IMAGES_DIR}/image-mtd-pfr-${DATETIME}.bin
- ln -sf ${PFR_IMAGES_DIR}/image-mtd-pfr-${DATETIME}.bin ${PFR_IMAGES_DIR}/image-mtd-pfr.bin
- ln -sf ${PFR_IMAGES_DIR}/bmc_signed_cap-${DATETIME}.bin ${PFR_IMAGES_DIR}/bmc_signed_cap.bin
+
+ # Use relative links. The build process removes some of the build
+ # artifacts and that makes fully qualified pathes break. Relative links
+ # work because of the 'cd "${PFR_IMAGES_DIR}"' at the start of this section.
+ ln -sf image-mtd-pfr-${DATETIME}.bin ${PFR_IMAGES_DIR}/image-mtd-pfr.bin
+ ln -sf bmc_signed_cap-${DATETIME}.bin ${PFR_IMAGES_DIR}/bmc_signed_cap.bin
}
do_image_pfr[vardepsexclude] += "DATE DATETIME"
diff --git a/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass b/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass
index 4d50fbc52..1e6bc05af 100644
--- a/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass
+++ b/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass
@@ -22,7 +22,7 @@ IMAGE_INSTALL_append = " \
frb2-watchdog \
srvcfg-manager \
callback-manager \
- post-code-manager \
+ phosphor-post-code-manager \
preinit-mounts \
mtd-utils-ubifs \
special-mode-mgr \
diff --git a/meta-openbmc-mods/meta-common/classes/systemd-watchdog.bbclass b/meta-openbmc-mods/meta-common/classes/systemd-watchdog.bbclass
index 66fecb8a9..c088fec34 100644
--- a/meta-openbmc-mods/meta-common/classes/systemd-watchdog.bbclass
+++ b/meta-openbmc-mods/meta-common/classes/systemd-watchdog.bbclass
@@ -24,7 +24,7 @@ add_watchdog_confs() {
mkdir -p "${folder}"
fname="${folder}/watchdog.conf"
echo "[Unit]" > ${fname}
- echo "OnFailure=watchdog-reset.service" >> ${fname}
+ echo "OnFailure=watchdog-reset@${service}.service" >> ${fname}
echo "[Service]" >> "${fname}"
echo "StartLimitInterval=${interval}min" >> "${fname}"
echo "StartLimitBurst=${count}" >> "${fname}"
diff --git a/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/files/environment.d-openssl.sh b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/files/environment.d-openssl.sh
new file mode 100644
index 000000000..b9cc24a7a
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/files/environment.d-openssl.sh
@@ -0,0 +1 @@
+export OPENSSL_CONF="$OECORE_NATIVE_SYSROOT/usr/lib/ssl/openssl.cnf"
diff --git a/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0001-buildinfo-strip-sysroot-and-debug-prefix-map-from-co.patch b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0001-buildinfo-strip-sysroot-and-debug-prefix-map-from-co.patch
new file mode 100644
index 000000000..949c78834
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0001-buildinfo-strip-sysroot-and-debug-prefix-map-from-co.patch
@@ -0,0 +1,76 @@
+From 3e1d00481093e10775eaf69d619c45b32a4aa7dc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Martin=20Hundeb=C3=B8ll?= <martin@geanix.com>
+Date: Tue, 6 Nov 2018 14:50:47 +0100
+Subject: [PATCH] buildinfo: strip sysroot and debug-prefix-map from compiler
+ info
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The openssl build system generates buildinf.h containing the full
+compiler command line used to compile objects. This breaks
+reproducibility, as the compile command is baked into libcrypto, where
+it is used when running `openssl version -f`.
+
+Add stripped build variables for the compiler and cflags lines, and use
+those when generating buildinfo.h.
+
+This is based on a similar patch for older openssl versions:
+https://patchwork.openembedded.org/patch/147229/
+
+Upstream-Status: Inappropriate [OE specific]
+Signed-off-by: Martin Hundebøll <martin@geanix.com>
+
+
+Update to fix buildpaths qa issue for '-fmacro-prefix-map'.
+
+Signed-off-by: Kai Kang <kai.kang@windriver.com>
+---
+ Configurations/unix-Makefile.tmpl | 10 +++++++++-
+ crypto/build.info | 2 +-
+ 2 files changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl
+index 16af4d2087..54c162784c 100644
+--- a/Configurations/unix-Makefile.tmpl
++++ b/Configurations/unix-Makefile.tmpl
+@@ -317,13 +317,22 @@ BIN_LDFLAGS={- join(' ', $target{bin_lflags} || (),
+ '$(CNF_LDFLAGS)', '$(LDFLAGS)') -}
+ BIN_EX_LIBS=$(CNF_EX_LIBS) $(EX_LIBS)
+
+-# CPPFLAGS_Q is used for one thing only: to build up buildinf.h
++# *_Q variables are used for one thing only: to build up buildinf.h
+ CPPFLAGS_Q={- $cppflags1 =~ s|([\\"])|\\$1|g;
+ $cppflags2 =~ s|([\\"])|\\$1|g;
+ $lib_cppflags =~ s|([\\"])|\\$1|g;
+ join(' ', $lib_cppflags || (), $cppflags2 || (),
+ $cppflags1 || ()) -}
+
++CFLAGS_Q={- for (@{$config{CFLAGS}}) {
++ s|-fdebug-prefix-map=[^ ]+|-fdebug-prefix-map=|g;
++ s|-fmacro-prefix-map=[^ ]+|-fmacro-prefix-map=|g;
++ }
++ join(' ', @{$config{CFLAGS}}) -}
++
++CC_Q={- $config{CC} =~ s|--sysroot=[^ ]+|--sysroot=recipe-sysroot|g;
++ join(' ', $config{CC}) -}
++
+ PERLASM_SCHEME= {- $target{perlasm_scheme} -}
+
+ # For x86 assembler: Set PROCESSOR to 386 if you want to support
+diff --git a/crypto/build.info b/crypto/build.info
+index b515b7318e..8c9cee2a09 100644
+--- a/crypto/build.info
++++ b/crypto/build.info
+@@ -10,7 +10,7 @@ EXTRA= ../ms/uplink-x86.pl ../ms/uplink.c ../ms/applink.c \
+ ppccpuid.pl pariscid.pl alphacpuid.pl arm64cpuid.pl armv4cpuid.pl
+
+ DEPEND[cversion.o]=buildinf.h
+-GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(CC) $(LIB_CFLAGS) $(CPPFLAGS_Q)" "$(PLATFORM)"
++GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(CC_Q) $(CFLAGS_Q) $(CPPFLAGS_Q)" "$(PLATFORM)"
+ DEPEND[buildinf.h]=../configdata.pm
+
+ GENERATE[uplink-x86.s]=../ms/uplink-x86.pl $(PERLASM_SCHEME)
+--
+2.19.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0001-skip-test_symbol_presence.patch b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0001-skip-test_symbol_presence.patch
new file mode 100644
index 000000000..d8d9651b6
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0001-skip-test_symbol_presence.patch
@@ -0,0 +1,46 @@
+From a9401b2289656c5a36dd1b0ecebf0d23e291ce70 Mon Sep 17 00:00:00 2001
+From: Hongxu Jia <hongxu.jia@windriver.com>
+Date: Tue, 2 Oct 2018 23:58:24 +0800
+Subject: [PATCH] skip test_symbol_presence
+
+We cannot skip `01-test_symbol_presence.t' by configuring option `no-shared'
+as INSTALL told us the shared libraries will not be built.
+
+[INSTALL snip]
+ Notes on shared libraries
+ -------------------------
+
+ For most systems the OpenSSL Configure script knows what is needed to
+ build shared libraries for libcrypto and libssl. On these systems
+ the shared libraries will be created by default. This can be suppressed and
+ only static libraries created by using the "no-shared" option. On systems
+ where OpenSSL does not know how to build shared libraries the "no-shared"
+ option will be forced and only static libraries will be created.
+[INSTALL snip]
+
+Hence directly modification the case to skip it.
+
+Upstream-Status: Inappropriate [OE Specific]
+
+Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
+---
+ test/recipes/01-test_symbol_presence.t | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/test/recipes/01-test_symbol_presence.t b/test/recipes/01-test_symbol_presence.t
+index 7f2a2d7..0b93745 100644
+--- a/test/recipes/01-test_symbol_presence.t
++++ b/test/recipes/01-test_symbol_presence.t
+@@ -14,8 +14,7 @@ use OpenSSL::Test::Utils;
+
+ setup("test_symbol_presence");
+
+-plan skip_all => "Only useful when building shared libraries"
+- if disabled("shared");
++plan skip_all => "The case needs debug symbols then we just disable it";
+
+ my @libnames = ("crypto", "ssl");
+ my $testcount = scalar @libnames;
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/afalg.patch b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/afalg.patch
new file mode 100644
index 000000000..b7c0e9697
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/afalg.patch
@@ -0,0 +1,31 @@
+Don't refuse to build afalgeng if cross-compiling or the host kernel is too old.
+
+Upstream-Status: Submitted [hhttps://github.com/openssl/openssl/pull/7688]
+Signed-off-by: Ross Burton <ross.burton@intel.com>
+
+diff --git a/Configure b/Configure
+index 3baa8ce..9ef52ed 100755
+--- a/Configure
++++ b/Configure
+@@ -1550,20 +1550,7 @@ unless ($disabled{"crypto-mdebug-backtrace"})
+ unless ($disabled{afalgeng}) {
+ $config{afalgeng}="";
+ if (grep { $_ eq 'afalgeng' } @{$target{enable}}) {
+- my $minver = 4*10000 + 1*100 + 0;
+- if ($config{CROSS_COMPILE} eq "") {
+- my $verstr = `uname -r`;
+- my ($ma, $mi1, $mi2) = split("\\.", $verstr);
+- ($mi2) = $mi2 =~ /(\d+)/;
+- my $ver = $ma*10000 + $mi1*100 + $mi2;
+- if ($ver < $minver) {
+- disable('too-old-kernel', 'afalgeng');
+- } else {
+- push @{$config{engdirs}}, "afalg";
+- }
+- } else {
+- disable('cross-compiling', 'afalgeng');
+- }
++ push @{$config{engdirs}}, "afalg";
+ } else {
+ disable('not-linux', 'afalgeng');
+ }
diff --git a/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/reproducible.patch b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/reproducible.patch
new file mode 100644
index 000000000..a24260c95
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/reproducible.patch
@@ -0,0 +1,32 @@
+The value for perl_archname can vary depending on the host, e.g.
+x86_64-linux-gnu-thread-multi or x86_64-linux-thread-multi which
+makes the ptest package non-reproducible. Its unused other than
+these references so drop it.
+
+RP 2020/2/6
+
+Upstream-Status: Pending
+Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
+
+Index: openssl-1.1.1d/Configure
+===================================================================
+--- openssl-1.1.1d.orig/Configure
++++ openssl-1.1.1d/Configure
+@@ -286,7 +286,7 @@ if (defined env($local_config_envname))
+ # Save away perl command information
+ $config{perl_cmd} = $^X;
+ $config{perl_version} = $Config{version};
+-$config{perl_archname} = $Config{archname};
++#$config{perl_archname} = $Config{archname};
+
+ $config{prefix}="";
+ $config{openssldir}="";
+@@ -2517,7 +2517,7 @@ _____
+ @{$config{perlargv}}), "\n";
+ print "\nPerl information:\n\n";
+ print ' ',$config{perl_cmd},"\n";
+- print ' ',$config{perl_version},' for ',$config{perl_archname},"\n";
++ print ' ',$config{perl_version},"\n";
+ }
+ if ($dump || $options) {
+ my $longest = 0;
diff --git a/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/run-ptest b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/run-ptest
new file mode 100644
index 000000000..3fb22471f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/run-ptest
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+set -e
+
+# Optional arguments are 'list' to lists all tests, or the test name (base name
+# ie test_evp, not 03_test_evp.t).
+
+export TOP=.
+# OPENSSL_ENGINES is relative from the test binaries
+export OPENSSL_ENGINES=../engines
+
+perl ./test/run_tests.pl $* | perl -0pe 's#(.*) \.*.ok#PASS: \1#g; s#(.*) \.*.skipped: (.*)#SKIP: \1 (\2)#g; s#(.*) \.*.\nDubious#FAIL: \1#;'
diff --git a/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl_1.1.1g.bb b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl_1.1.1g.bb
new file mode 100644
index 000000000..66fa8f7d0
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl_1.1.1g.bb
@@ -0,0 +1,211 @@
+SUMMARY = "Secure Socket Layer"
+DESCRIPTION = "Secure Socket Layer (SSL) binary and related cryptographic tools."
+HOMEPAGE = "http://www.openssl.org/"
+BUGTRACKER = "http://www.openssl.org/news/vulnerabilities.html"
+SECTION = "libs/network"
+
+# "openssl" here actually means both OpenSSL and SSLeay licenses apply
+# (see meta/files/common-licenses/OpenSSL to which "openssl" is SPDXLICENSEMAPped)
+LICENSE = "openssl"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=d343e62fc9c833710bbbed25f27364c8"
+
+DEPENDS = "hostperl-runtime-native"
+
+SRC_URI = "http://www.openssl.org/source/openssl-${PV}.tar.gz \
+ file://run-ptest \
+ file://0001-skip-test_symbol_presence.patch \
+ file://0001-buildinfo-strip-sysroot-and-debug-prefix-map-from-co.patch \
+ file://afalg.patch \
+ file://reproducible.patch \
+ "
+
+SRC_URI_append_class-nativesdk = " \
+ file://environment.d-openssl.sh \
+ "
+
+SRC_URI[sha256sum] = "ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46"
+
+inherit lib_package multilib_header multilib_script ptest
+MULTILIB_SCRIPTS = "${PN}-bin:${bindir}/c_rehash"
+
+PACKAGECONFIG ?= ""
+PACKAGECONFIG_class-native = ""
+PACKAGECONFIG_class-nativesdk = ""
+
+PACKAGECONFIG[cryptodev-linux] = "enable-devcryptoeng,disable-devcryptoeng,cryptodev-linux,,cryptodev-module"
+
+B = "${WORKDIR}/build"
+do_configure[cleandirs] = "${B}"
+
+#| ./libcrypto.so: undefined reference to `getcontext'
+#| ./libcrypto.so: undefined reference to `setcontext'
+#| ./libcrypto.so: undefined reference to `makecontext'
+EXTRA_OECONF_append_libc-musl = " no-async"
+EXTRA_OECONF_append_libc-musl_powerpc64 = " no-asm"
+
+# adding devrandom prevents openssl from using getrandom() which is not available on older glibc versions
+# (native versions can be built with newer glibc, but then relocated onto a system with older glibc)
+EXTRA_OECONF_class-native = "--with-rand-seed=os,devrandom"
+EXTRA_OECONF_class-nativesdk = "--with-rand-seed=os,devrandom"
+
+# Relying on hardcoded built-in paths causes openssl-native to not be relocateable from sstate.
+CFLAGS_append_class-native = " -DOPENSSLDIR=/not/builtin -DENGINESDIR=/not/builtin"
+CFLAGS_append_class-nativesdk = " -DOPENSSLDIR=/not/builtin -DENGINESDIR=/not/builtin"
+
+do_configure () {
+ os=${HOST_OS}
+ case $os in
+ linux-gnueabi |\
+ linux-gnuspe |\
+ linux-musleabi |\
+ linux-muslspe |\
+ linux-musl )
+ os=linux
+ ;;
+ *)
+ ;;
+ esac
+ target="$os-${HOST_ARCH}"
+ case $target in
+ linux-arm*)
+ target=linux-armv4
+ ;;
+ linux-aarch64*)
+ target=linux-aarch64
+ ;;
+ linux-i?86 | linux-viac3)
+ target=linux-x86
+ ;;
+ linux-gnux32-x86_64 | linux-muslx32-x86_64 )
+ target=linux-x32
+ ;;
+ linux-gnu64-x86_64)
+ target=linux-x86_64
+ ;;
+ linux-mips | linux-mipsel)
+ # specifying TARGET_CC_ARCH prevents openssl from (incorrectly) adding target architecture flags
+ target="linux-mips32 ${TARGET_CC_ARCH}"
+ ;;
+ linux-gnun32-mips*)
+ target=linux-mips64
+ ;;
+ linux-*-mips64 | linux-mips64 | linux-*-mips64el | linux-mips64el)
+ target=linux64-mips64
+ ;;
+ linux-microblaze* | linux-nios2* | linux-sh3 | linux-sh4 | linux-arc*)
+ target=linux-generic32
+ ;;
+ linux-powerpc)
+ target=linux-ppc
+ ;;
+ linux-powerpc64)
+ target=linux-ppc64
+ ;;
+ linux-powerpc64le)
+ target=linux-ppc64le
+ ;;
+ linux-riscv32)
+ target=linux-generic32
+ ;;
+ linux-riscv64)
+ target=linux-generic64
+ ;;
+ linux-sparc | linux-supersparc)
+ target=linux-sparcv9
+ ;;
+ esac
+
+ useprefix=${prefix}
+ if [ "x$useprefix" = "x" ]; then
+ useprefix=/
+ fi
+ # WARNING: do not set compiler/linker flags (-I/-D etc.) in EXTRA_OECONF, as they will fully replace the
+ # environment variables set by bitbake. Adjust the environment variables instead.
+ HASHBANGPERL="/usr/bin/env perl" PERL=perl PERL5LIB="${S}/external/perl/Text-Template-1.46/lib/" \
+ perl ${S}/Configure ${EXTRA_OECONF} ${PACKAGECONFIG_CONFARGS} --prefix=$useprefix --openssldir=${libdir}/ssl-1.1 --libdir=${libdir} $target
+ perl ${B}/configdata.pm --dump
+}
+
+do_install () {
+ oe_runmake DESTDIR="${D}" MANDIR="${mandir}" MANSUFFIX=ssl install
+
+ oe_multilib_header openssl/opensslconf.h
+
+ # Create SSL structure for packages such as ca-certificates which
+ # contain hard-coded paths to /etc/ssl. Debian does the same.
+ install -d ${D}${sysconfdir}/ssl
+ mv ${D}${libdir}/ssl-1.1/certs \
+ ${D}${libdir}/ssl-1.1/private \
+ ${D}${libdir}/ssl-1.1/openssl.cnf \
+ ${D}${sysconfdir}/ssl/
+
+ # Although absolute symlinks would be OK for the target, they become
+ # invalid if native or nativesdk are relocated from sstate.
+ ln -sf ${@oe.path.relative('${libdir}/ssl-1.1', '${sysconfdir}/ssl/certs')} ${D}${libdir}/ssl-1.1/certs
+ ln -sf ${@oe.path.relative('${libdir}/ssl-1.1', '${sysconfdir}/ssl/private')} ${D}${libdir}/ssl-1.1/private
+ ln -sf ${@oe.path.relative('${libdir}/ssl-1.1', '${sysconfdir}/ssl/openssl.cnf')} ${D}${libdir}/ssl-1.1/openssl.cnf
+}
+
+do_install_append_class-native () {
+ create_wrapper ${D}${bindir}/openssl \
+ OPENSSL_CONF=${libdir}/ssl-1.1/openssl.cnf \
+ SSL_CERT_DIR=${libdir}/ssl-1.1/certs \
+ SSL_CERT_FILE=${libdir}/ssl-1.1/cert.pem \
+ OPENSSL_ENGINES=${libdir}/engines-1.1
+}
+
+do_install_append_class-nativesdk () {
+ mkdir -p ${D}${SDKPATHNATIVE}/environment-setup.d
+ install -m 644 ${WORKDIR}/environment.d-openssl.sh ${D}${SDKPATHNATIVE}/environment-setup.d/openssl.sh
+ sed 's|/usr/lib/ssl/|/usr/lib/ssl-1.1/|g' -i ${D}${SDKPATHNATIVE}/environment-setup.d/openssl.sh
+}
+
+PTEST_BUILD_HOST_FILES += "configdata.pm"
+PTEST_BUILD_HOST_PATTERN = "perl_version ="
+do_install_ptest () {
+ # Prune the build tree
+ rm -f ${B}/fuzz/*.* ${B}/test/*.*
+
+ cp ${S}/Configure ${B}/configdata.pm ${D}${PTEST_PATH}
+ cp -r ${S}/external ${B}/test ${S}/test ${B}/fuzz ${S}/util ${B}/util ${D}${PTEST_PATH}
+
+ # For test_shlibload
+ ln -s ${libdir}/libcrypto.so.1.1 ${D}${PTEST_PATH}/
+ ln -s ${libdir}/libssl.so.1.1 ${D}${PTEST_PATH}/
+
+ install -d ${D}${PTEST_PATH}/apps
+ ln -s ${bindir}/openssl ${D}${PTEST_PATH}/apps
+ install -m644 ${S}/apps/*.pem ${S}/apps/*.srl ${S}/apps/openssl.cnf ${D}${PTEST_PATH}/apps
+ install -m755 ${B}/apps/CA.pl ${D}${PTEST_PATH}/apps
+
+ install -d ${D}${PTEST_PATH}/engines
+ install -m755 ${B}/engines/ossltest.so ${D}${PTEST_PATH}/engines
+}
+
+# Add the openssl.cnf file to the openssl-conf package. Make the libcrypto
+# package RRECOMMENDS on this package. This will enable the configuration
+# file to be installed for both the openssl-bin package and the libcrypto
+# package since the openssl-bin package depends on the libcrypto package.
+
+PACKAGES =+ "libcrypto libssl openssl-conf ${PN}-engines ${PN}-misc"
+
+FILES_libcrypto = "${libdir}/libcrypto${SOLIBS}"
+FILES_libssl = "${libdir}/libssl${SOLIBS}"
+FILES_openssl-conf = "${sysconfdir}/ssl/openssl.cnf"
+FILES_${PN}-engines = "${libdir}/engines-1.1"
+FILES_${PN}-misc = "${libdir}/ssl-1.1/misc"
+FILES_${PN} =+ "${libdir}/ssl-1.1/*"
+FILES_${PN}_append_class-nativesdk = " ${SDKPATHNATIVE}/environment-setup.d/openssl.sh"
+
+CONFFILES_openssl-conf = "${sysconfdir}/ssl/openssl.cnf"
+
+RRECOMMENDS_libcrypto += "openssl-conf"
+RDEPENDS_${PN}-ptest += "openssl-bin perl perl-modules bash"
+
+BBCLASSEXTEND = "native nativesdk"
+
+CVE_PRODUCT = "openssl:openssl"
+
+# Only affects OpenSSL >= 1.1.1 in combination with Apache < 2.4.37
+# Apache in meta-webserver is already recent enough
+CVE_CHECK_WHITELIST += "CVE-2019-0190"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/crashdump/crashdump_git.bb b/meta-openbmc-mods/meta-common/recipes-core/crashdump/crashdump_git.bb
index b80282743..b4875c332 100644
--- a/meta-openbmc-mods/meta-common/recipes-core/crashdump/crashdump_git.bb
+++ b/meta-openbmc-mods/meta-common/recipes-core/crashdump/crashdump_git.bb
@@ -13,7 +13,7 @@ LICENSE = "Proprietary"
LIC_FILES_CHKSUM = "file://LICENSE;md5=43c09494f6b77f344027eea0a1c22830"
SRC_URI = "git://github.com/Intel-BMC/crashdump;protocol=git"
-SRCREV = "0.5"
+SRCREV = "wht-0.65"
S = "${WORKDIR}/git"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp_git.bb b/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp_git.bb
index edbcce6f3..2f3b48cb3 100644
--- a/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp_git.bb
+++ b/meta-openbmc-mods/meta-common/recipes-core/interfaces/libmctp_git.bb
@@ -2,7 +2,7 @@ SUMMARY = "libmctp"
DESCRIPTION = "Implementation of MCTP (DTMF DSP0236)"
SRC_URI = "git://github.com/openbmc/libmctp.git"
-SRCREV = "6a18582ba2f47f677846dc68f608effc60bbb9e7"
+SRCREV = "f5afcd7e6597dcdeaa475aa7194ecfae2e82d114"
PV = "0.1+git${SRCPV}"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem_%.bbappend b/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem_%.bbappend
index 5fda8788e..de57d5e19 100644
--- a/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem_%.bbappend
@@ -2,4 +2,4 @@ EXTRA_OECMAKE += "${@bb.utils.contains('IMAGE_FSTYPES', 'intel-pfr', '-DINTEL_PF
EXTRA_OECMAKE += "${@bb.utils.contains('EXTRA_IMAGE_FEATURES', 'validation-unsecure', '-DBMC_VALIDATION_UNSECURE_FEATURE=ON', '', d)}"
EXTRA_OECMAKE += "-DUSING_ENTITY_MANAGER_DECORATORS=OFF"
SRC_URI = "git://github.com/openbmc/intel-ipmi-oem.git"
-SRCREV = "899bfd15e7230b5da0b2b16c814f4e3bdf6c824c"
+SRCREV = "358e7dfa41d4f297d33670c5caceda3629748cfe"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/libpeci/libpeci_%.bbappend b/meta-openbmc-mods/meta-common/recipes-core/libpeci/libpeci_%.bbappend
index fd56781d7..ba549b324 100644
--- a/meta-openbmc-mods/meta-common/recipes-core/libpeci/libpeci_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-core/libpeci/libpeci_%.bbappend
@@ -1,3 +1,3 @@
# Enable downstream autobump
SRC_URI = "git://github.com/openbmc/libpeci"
-SRCREV = "7ef5a55777bb4d0c403a4eca98c487fa4e9c7bd1"
+SRCREV = "a2ceec2aa139277cebb62e1eda449ef60fa4c962"
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog/rotate-event-logs.service b/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog/rotate-event-logs.service
new file mode 100644
index 000000000..8f3a2bc31
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog/rotate-event-logs.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=Rotate the event logs
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/rotate-event-logs.sh
+
+[Install]
+WantedBy=multi-user.target
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog/rotate-event-logs.sh b/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog/rotate-event-logs.sh
new file mode 100644
index 000000000..5a8c5cc10
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog/rotate-event-logs.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+while true; do
+ sleep 60
+ /usr/sbin/logrotate /etc/logrotate.d/logrotate.rsyslog
+ ec=$?
+ if [ $ec -ne 0 ] ; then
+ echo "logrotate failed ($ec)"
+ fi
+done
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog_%.bbappend b/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog_%.bbappend
new file mode 100644
index 000000000..78c3b31af
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog_%.bbappend
@@ -0,0 +1,13 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI += "file://rotate-event-logs.service \
+ file://rotate-event-logs.sh \
+"
+
+do_install_append() {
+ install -d ${D}${bindir}
+ install -m 0755 ${WORKDIR}/rotate-event-logs.sh ${D}/${bindir}/rotate-event-logs.sh
+ rm ${D}${systemd_system_unitdir}/rotate-event-logs.timer
+}
+
+SYSTEMD_SERVICE_${PN}_remove = "rotate-event-logs.timer"
diff --git a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/intel-blocksign-native.bb b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/intel-blocksign-native.bb
index 4f72dbe2b..7acc19f46 100644
--- a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/intel-blocksign-native.bb
+++ b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/intel-blocksign-native.bb
@@ -10,7 +10,7 @@ DEPENDS = "openssl-native libxml2-native "
SRC_URI = "git://git@github.com/Intel-BMC/blocksign;protocol=ssh"
-SRCREV = "852d88a1cbf4dc5856ff88e823a38d2872a86ffe"
+SRCREV = "966d16f680c1b14c338640d35a12d5e2f9a6937a"
S = "${WORKDIR}/git/"
diff --git a/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2.bb b/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2.bb
index 7a5cc7d3e..f921704f6 100644
--- a/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2.bb
+++ b/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2.bb
@@ -26,3 +26,5 @@ DEPENDS += " \
phosphor-dbus-interfaces-native \
phosphor-logging \
"
+
+EXTRA_OECMAKE += "-DDIMM_DBUS=OFF"
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2600-platforms.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2600-platforms.patch
index e77f744ff..8ad7b3c0a 100644
--- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2600-platforms.patch
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2600-platforms.patch
@@ -1,4 +1,4 @@
-From 297e22a00a71d386c93b1e0d587a01c0386b31f3 Mon Sep 17 00:00:00 2001
+From 498b7829800ec27c7787b3ae77ee59e7b10ec40e Mon Sep 17 00:00:00 2001
From: Vernon Mauery <vernon.mauery@linux.intel.com>
Date: Tue, 19 Sep 2017 15:55:39 +0800
Subject: [PATCH] arm: dts: add DTS for Intel ast2600 platforms
@@ -12,17 +12,18 @@ Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
Signed-off-by: arun-pm <arun.p.m@linux.intel.com>
Signed-off-by: Ayushi Smriti <smriti.ayushi@intel.com>
Signed-off-by: Arun P. Mohanan <arun.p.m@linux.intel.com>
+Signed-off-by: Iwona Winiarska <iwona.winiarska@intel.com>
---
- .../arm/boot/dts/aspeed-bmc-intel-ast2600.dts | 519 ++++++++++++++++++
- 1 file changed, 519 insertions(+)
+ arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts | 528 +++++++++++++++++++++++++
+ 1 file changed, 528 insertions(+)
create mode 100644 arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts
diff --git a/arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts b/arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts
new file mode 100644
-index 000000000000..a95b5ac828b3
+index 000000000000..c68314d3901b
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts
-@@ -0,0 +1,519 @@
+@@ -0,0 +1,528 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
@@ -111,12 +112,9 @@ index 000000000000..a95b5ac828b3
+
+&fmc {
+ status = "okay";
-+ flash: m25p80@0 {
-+ compatible = "m25p80", "jedec,spi-nor";
-+ reg = <0x0>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ spi-max-frequency = <40000000>;
++ flash@0 {
++ status = "okay";
++ spi-max-frequency = <50000000>;
+ spi-tx-bus-width = <4>;
+ m25p,fast-read;
+#include "openbmc-flash-layout-intel-64MB.dtsi"
@@ -127,6 +125,10 @@ index 000000000000..a95b5ac828b3
+ status = "okay";
+};
+
++&mctp {
++ status = "okay";
++};
++
+&peci0 {
+ status = "okay";
+ gpios = <&gpio0 ASPEED_GPIO(F, 6) 0>;
@@ -449,24 +451,28 @@ index 000000000000..a95b5ac828b3
+ status = "okay";
+};
+
++&i3cglobal {
++ status = "okay";
++};
++
+&i3c0 {
-+ /* I3C_SPD_DDRABCD_CPU0_BMC ; FIXME: i3c driver hangs kernel on probe...*/
-+ status = "disabled";
++ /* I3C_SPD_DDRABCD_CPU0_BMC */
++ status = "okay";
+};
+
+&i3c1 {
+ /* I3C_SPD_DDREFGH_CPU0_BMC */
-+ status = "disabled";
++ status = "okay";
+};
+
+&i3c2 {
+ /* I3C_SPD_DDRABCD_CPU1_BMC */
-+ status = "disabled";
++ status = "okay";
+};
+
+&i3c3 {
+ /* I3C_SPD_DDREFGH_CPU1_BMC */
-+ status = "disabled";
++ status = "okay";
+};
+
+&gfx {
@@ -474,6 +480,10 @@ index 000000000000..a95b5ac828b3
+ memory-region = <&gfx_memory>;
+};
+
++&pcieh {
++ status = "okay";
++};
++
+&pwm_tacho {
+ status = "disabled";
+ pinctrl-names = "default";
@@ -543,5 +553,5 @@ index 000000000000..a95b5ac828b3
+ status = "okay";
+};
--
-2.17.1
+2.7.4
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0092-SPI-Quad-IO-driver-support-AST2600.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0092-SPI-Quad-IO-driver-support-AST2600.patch
index 2717d367f..f8a05fd7c 100644
--- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0092-SPI-Quad-IO-driver-support-AST2600.patch
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0092-SPI-Quad-IO-driver-support-AST2600.patch
@@ -1,4 +1,4 @@
-From 9f1eea1fb639a0554195e29c488cefb36a04910e Mon Sep 17 00:00:00 2001
+From f231c8d6babe5ac1b74ab4eb09901b864020a83f Mon Sep 17 00:00:00 2001
From: arun-pm <arun.p.m@linux.intel.com>
Date: Tue, 3 Dec 2019 17:22:28 +0530
Subject: [PATCH] SPI Quad IO driver support AST2600
@@ -15,7 +15,7 @@ Signed-off-by: arun-pm <arun.p.m@linux.intel.com>
2 files changed, 48 insertions(+), 8 deletions(-)
diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
-index 0805dcab8cb1..305c1940e822 100644
+index 0805dcab8cb1..6e2f3802d162 100644
--- a/drivers/mtd/spi-nor/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/aspeed-smc.c
@@ -21,6 +21,11 @@
@@ -62,8 +62,8 @@ index 0805dcab8cb1..305c1940e822 100644
+ /*Limit max spi frequency less than 50MHz on AST2600-A0 due
+ * to FWSPICLK signal quality issue.
+ */
-+ if(rev_id == AST2600A0 && chip->clk_rate >= AST2600A0_MAX_FREQ)
-+ chip->clk_rate = AST2600A0_SAFE_FREQ;
++ if(rev_id == AST2600A0 && chip->clk_rate > AST2600A0_MAX_FREQ)
++ chip->clk_rate = AST2600A0_MAX_FREQ;
+}
+
+static u32 get_hwcaps(unsigned int tx_width){
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0106-enable-AST2600-I3C.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0106-enable-AST2600-I3C.patch
new file mode 100644
index 000000000..7eac39e5b
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0106-enable-AST2600-I3C.patch
@@ -0,0 +1,922 @@
+From ec463c332c3b954a5a0ef4ceb253701b8190bbb9 Mon Sep 17 00:00:00 2001
+From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+Date: Wed, 6 May 2020 18:11:29 -0700
+Subject: [PATCH] enable AST2600 I3C
+
+This commit ports I3C related changes from Aspeed SDK v00.05.05.
+It also includes Vitor's I3C cdev implementation which isn't
+upstreamed yet so it should be refined later.
+
+Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
+Signed-off-by: Vitor Soares <soares@synopsys.com>
+Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+---
+ arch/arm/boot/dts/aspeed-g6.dtsi | 19 +-
+ drivers/clk/clk-ast2600.c | 30 ++-
+ drivers/i3c/Kconfig | 15 ++
+ drivers/i3c/Makefile | 1 +
+ drivers/i3c/i3cdev.c | 428 ++++++++++++++++++++++++++++++
+ drivers/i3c/internals.h | 2 +
+ drivers/i3c/master.c | 39 ++-
+ drivers/i3c/master/Kconfig | 5 +
+ drivers/i3c/master/Makefile | 1 +
+ drivers/i3c/master/aspeed-i3c-global.c | 89 +++++++
+ include/dt-bindings/clock/ast2600-clock.h | 3 +-
+ include/uapi/linux/i3c/i3cdev.h | 38 +++
+ 12 files changed, 646 insertions(+), 24 deletions(-)
+ create mode 100644 drivers/i3c/i3cdev.c
+ create mode 100644 drivers/i3c/master/aspeed-i3c-global.c
+ create mode 100644 include/uapi/linux/i3c/i3cdev.h
+
+diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
+index 91f431e419d9..33e1b0ef24f0 100644
+--- a/arch/arm/boot/dts/aspeed-g6.dtsi
++++ b/arch/arm/boot/dts/aspeed-g6.dtsi
+@@ -1091,13 +1091,20 @@
+ };
+
+ &i3c {
++ i3cglobal: i3cg@0 {
++ reg = <0x0 0x1000>;
++ compatible = "aspeed,ast2600-i3c-global";
++ resets = <&syscon ASPEED_RESET_I3C_DMA>;
++ status = "disabled";
++ };
++
+ i3c0: i3c0@2000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x2000 0x1000>;
+ compatible = "snps,dw-i3c-master-1.00a";
+- clocks = <&syscon ASPEED_CLK_APB2>;
++ clocks = <&syscon ASPEED_CLK_GATE_I3C0CLK>;
+ resets = <&syscon ASPEED_RESET_I3C0>;
+ bus-frequency = <100000>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+@@ -1110,7 +1117,7 @@
+ #interrupt-cells = <1>;
+ reg = <0x3000 0x1000>;
+ compatible = "snps,dw-i3c-master-1.00a";
+- clocks = <&syscon ASPEED_CLK_APB2>;
++ clocks = <&syscon ASPEED_CLK_GATE_I3C1CLK>;
+ resets = <&syscon ASPEED_RESET_I3C1>;
+ bus-frequency = <100000>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+@@ -1123,7 +1130,7 @@
+ #interrupt-cells = <1>;
+ reg = <0x4000 0x1000>;
+ compatible = "snps,dw-i3c-master-1.00a";
+- clocks = <&syscon ASPEED_CLK_APB2>;
++ clocks = <&syscon ASPEED_CLK_GATE_I3C2CLK>;
+ resets = <&syscon ASPEED_RESET_I3C2>;
+ bus-frequency = <100000>;
+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+@@ -1138,7 +1145,7 @@
+ #interrupt-cells = <1>;
+ reg = <0x5000 0x1000>;
+ compatible = "snps,dw-i3c-master-1.00a";
+- clocks = <&syscon ASPEED_CLK_APB2>;
++ clocks = <&syscon ASPEED_CLK_GATE_I3C3CLK>;
+ resets = <&syscon ASPEED_RESET_I3C3>;
+ bus-frequency = <100000>;
+ interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+@@ -1153,7 +1160,7 @@
+ #interrupt-cells = <1>;
+ reg = <0x6000 0x1000>;
+ compatible = "snps,dw-i3c-master-1.00a";
+- clocks = <&syscon ASPEED_CLK_APB2>;
++ clocks = <&syscon ASPEED_CLK_GATE_I3C4CLK>;
+ resets = <&syscon ASPEED_RESET_I3C4>;
+ bus-frequency = <100000>;
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+@@ -1168,7 +1175,7 @@
+ #interrupt-cells = <1>;
+ reg = <0x7000 0x1000>;
+ compatible = "snps,dw-i3c-master-1.00a";
+- clocks = <&syscon ASPEED_CLK_APB2>;
++ clocks = <&syscon ASPEED_CLK_GATE_I3C5CLK>;
+ resets = <&syscon ASPEED_RESET_I3C5>;
+ bus-frequency = <100000>;
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c
+index e07326544fdc..a30dcbb1a3fd 100644
+--- a/drivers/clk/clk-ast2600.c
++++ b/drivers/clk/clk-ast2600.c
+@@ -112,14 +112,14 @@ static const struct aspeed_gate_data aspeed_g6_gates[] = {
+ [ASPEED_CLK_GATE_LHCCLK] = { 37, -1, "lhclk-gate", "lhclk", 0 }, /* LPC master/LPC+ */
+ /* Reserved 38 RSA: no longer used */
+ /* Reserved 39 */
+- [ASPEED_CLK_GATE_I3C0CLK] = { 40, 40, "i3c0clk-gate", NULL, 0 }, /* I3C0 */
+- [ASPEED_CLK_GATE_I3C1CLK] = { 41, 41, "i3c1clk-gate", NULL, 0 }, /* I3C1 */
+- [ASPEED_CLK_GATE_I3C2CLK] = { 42, 42, "i3c2clk-gate", NULL, 0 }, /* I3C2 */
+- [ASPEED_CLK_GATE_I3C3CLK] = { 43, 43, "i3c3clk-gate", NULL, 0 }, /* I3C3 */
+- [ASPEED_CLK_GATE_I3C4CLK] = { 44, 44, "i3c4clk-gate", NULL, 0 }, /* I3C4 */
+- [ASPEED_CLK_GATE_I3C5CLK] = { 45, 45, "i3c5clk-gate", NULL, 0 }, /* I3C5 */
+- [ASPEED_CLK_GATE_I3C6CLK] = { 46, 46, "i3c6clk-gate", NULL, 0 }, /* I3C6 */
+- [ASPEED_CLK_GATE_I3C7CLK] = { 47, 47, "i3c7clk-gate", NULL, 0 }, /* I3C7 */
++ [ASPEED_CLK_GATE_I3C0CLK] = { 40, 40, "i3c0clk-gate", "i3cclk", 0 }, /* I3C0 */
++ [ASPEED_CLK_GATE_I3C1CLK] = { 41, 41, "i3c1clk-gate", "i3cclk", 0 }, /* I3C1 */
++ [ASPEED_CLK_GATE_I3C2CLK] = { 42, 42, "i3c2clk-gate", "i3cclk", 0 }, /* I3C2 */
++ [ASPEED_CLK_GATE_I3C3CLK] = { 43, 43, "i3c3clk-gate", "i3cclk", 0 }, /* I3C3 */
++ [ASPEED_CLK_GATE_I3C4CLK] = { 44, 44, "i3c4clk-gate", "i3cclk", 0 }, /* I3C4 */
++ [ASPEED_CLK_GATE_I3C5CLK] = { 45, 45, "i3c5clk-gate", "i3cclk", 0 }, /* I3C5 */
++ [ASPEED_CLK_GATE_I3C6CLK] = { 46, 46, "i3c6clk-gate", "i3cclk", 0 }, /* I3C6 */
++ [ASPEED_CLK_GATE_I3C7CLK] = { 47, 47, "i3c7clk-gate", "i3cclk", 0 }, /* I3C7 */
+ [ASPEED_CLK_GATE_UART1CLK] = { 48, -1, "uart1clk-gate", "uart", 0 }, /* UART1 */
+ [ASPEED_CLK_GATE_UART2CLK] = { 49, -1, "uart2clk-gate", "uart", 0 }, /* UART2 */
+ [ASPEED_CLK_GATE_UART3CLK] = { 50, -1, "uart3clk-gate", "uart", 0 }, /* UART3 */
+@@ -749,6 +749,20 @@ static void __init aspeed_g6_cc(struct regmap *map)
+ /* USB 2.0 port1 phy 40MHz clock */
+ hw = clk_hw_register_fixed_rate(NULL, "usb-phy-40m", NULL, 0, 40000000);
+ aspeed_g6_clk_data->hws[ASPEED_CLK_USBPHY_40M] = hw;
++
++ /* i3c clock source */
++ regmap_read(map, ASPEED_G6_CLK_SELECTION5, &val);
++ if(val & BIT(31)) {
++ val = (val >> 28) & 0x7;
++ if(val)
++ div = val + 1;
++ else
++ div = val + 2;
++ hw = clk_hw_register_fixed_factor(NULL, "i3cclk", "apll", 0, 1, div);
++ } else {
++ hw = clk_hw_register_fixed_factor(NULL, "i3cclk", "ahb", 0, 1, 1);
++ }
++ aspeed_g6_clk_data->hws[ASPEED_CLK_I3C] = hw;
+ };
+
+ static void __init aspeed_g6_cc_init(struct device_node *np)
+diff --git a/drivers/i3c/Kconfig b/drivers/i3c/Kconfig
+index 30a441506f61..01642768ab5f 100644
+--- a/drivers/i3c/Kconfig
++++ b/drivers/i3c/Kconfig
+@@ -20,5 +20,20 @@ menuconfig I3C
+ will be called i3c.
+
+ if I3C
++
++config I3CDEV
++ tristate "I3C device interface"
++ depends on I3C
++ help
++ Say Y here to use i3c-* device files, usually found in the /dev
++ directory on your system. They make it possible to have user-space
++ programs use the I3C devices.
++
++ This support is also available as a module. If so, the module
++ will be called i3cdev.
++
++ Note that this application programming interface is EXPERIMENTAL
++ and hence SUBJECT TO CHANGE WITHOUT NOTICE while it stabilizes.
++
+ source "drivers/i3c/master/Kconfig"
+ endif # I3C
+diff --git a/drivers/i3c/Makefile b/drivers/i3c/Makefile
+index 11982efbc6d9..606d422841b2 100644
+--- a/drivers/i3c/Makefile
++++ b/drivers/i3c/Makefile
+@@ -1,4 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0
+ i3c-y := device.o master.o
+ obj-$(CONFIG_I3C) += i3c.o
++obj-$(CONFIG_I3CDEV) += i3cdev.o
+ obj-$(CONFIG_I3C) += master/
+diff --git a/drivers/i3c/i3cdev.c b/drivers/i3c/i3cdev.c
+new file mode 100644
+index 000000000000..07f5641a902d
+--- /dev/null
++++ b/drivers/i3c/i3cdev.c
+@@ -0,0 +1,428 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2019 Synopsys, Inc. and/or its affiliates.
++ *
++ * Author: Vitor Soares <soares@synopsys.com>
++ */
++
++#include <linux/cdev.h>
++#include <linux/compat.h>
++#include <linux/device.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/jiffies.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/module.h>
++#include <linux/notifier.h>
++#include <linux/slab.h>
++#include <linux/uaccess.h>
++
++#include <linux/i3c/i3cdev.h>
++
++#include "internals.h"
++
++struct i3cdev_data {
++ struct list_head list;
++ struct i3c_device *i3c;
++ struct cdev cdev;
++ struct device *dev;
++ int id;
++};
++
++static DEFINE_IDA(i3cdev_ida);
++static dev_t i3cdev_number;
++#define I3C_MINORS 16 /* 16 I3C devices supported for now */
++
++static LIST_HEAD(i3cdev_list);
++static DEFINE_SPINLOCK(i3cdev_list_lock);
++
++static struct i3cdev_data *i3cdev_get_by_i3c(struct i3c_device *i3c)
++{
++ struct i3cdev_data *i3cdev;
++
++ spin_lock(&i3cdev_list_lock);
++ list_for_each_entry(i3cdev, &i3cdev_list, list) {
++ if (i3cdev->i3c == i3c)
++ goto found;
++ }
++
++ i3cdev = NULL;
++
++found:
++ spin_unlock(&i3cdev_list_lock);
++ return i3cdev;
++}
++
++static struct i3cdev_data *get_free_i3cdev(struct i3c_device *i3c)
++{
++ struct i3cdev_data *i3cdev;
++ int id;
++
++ id = ida_simple_get(&i3cdev_ida, 0, I3C_MINORS, GFP_KERNEL);
++ if (id < 0) {
++ pr_err("i3cdev: no minor number available!\n");
++ return ERR_PTR(id);
++ }
++
++ i3cdev = kzalloc(sizeof(*i3cdev), GFP_KERNEL);
++ if (!i3cdev) {
++ ida_simple_remove(&i3cdev_ida, id);
++ return ERR_PTR(-ENOMEM);
++ }
++
++ i3cdev->i3c = i3c;
++ i3cdev->id = id;
++
++ spin_lock(&i3cdev_list_lock);
++ list_add_tail(&i3cdev->list, &i3cdev_list);
++ spin_unlock(&i3cdev_list_lock);
++
++ return i3cdev;
++}
++
++static void put_i3cdev(struct i3cdev_data *i3cdev)
++{
++ spin_lock(&i3cdev_list_lock);
++ list_del(&i3cdev->list);
++ spin_unlock(&i3cdev_list_lock);
++ kfree(i3cdev);
++}
++
++static ssize_t
++i3cdev_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos)
++{
++ struct i3c_device *i3c = file->private_data;
++ struct i3c_priv_xfer xfers = {
++ .rnw = true,
++ .len = count,
++ };
++ char *tmp;
++ int ret;
++
++ tmp = kzalloc(count, GFP_KERNEL);
++ if (!tmp)
++ return -ENOMEM;
++
++ xfers.data.in = tmp;
++
++ dev_dbg(&i3c->dev, "Reading %zu bytes.\n", count);
++
++ ret = i3c_device_do_priv_xfers(i3c, &xfers, 1);
++ if (!ret)
++ ret = copy_to_user(buf, tmp, count) ? -EFAULT : ret;
++
++ kfree(tmp);
++ return ret;
++}
++
++static ssize_t
++i3cdev_write(struct file *file, const char __user *buf, size_t count,
++ loff_t *f_pos)
++{
++ struct i3c_device *i3c = file->private_data;
++ struct i3c_priv_xfer xfers = {
++ .rnw = false,
++ .len = count,
++ };
++ char *tmp;
++ int ret;
++
++ tmp = memdup_user(buf, count);
++ if (IS_ERR(tmp))
++ return PTR_ERR(tmp);
++
++ xfers.data.out = tmp;
++
++ dev_dbg(&i3c->dev, "Writing %zu bytes.\n", count);
++
++ ret = i3c_device_do_priv_xfers(i3c, &xfers, 1);
++ kfree(tmp);
++ return (!ret) ? count : ret;
++}
++
++static int
++i3cdev_do_priv_xfer(struct i3c_device *dev, struct i3c_ioc_priv_xfer *xfers,
++ unsigned int nxfers)
++{
++ struct i3c_priv_xfer *k_xfers;
++ u8 **data_ptrs;
++ int i, ret = 0;
++
++ k_xfers = kcalloc(nxfers, sizeof(*k_xfers), GFP_KERNEL);
++ if (!k_xfers)
++ return -ENOMEM;
++
++ data_ptrs = kcalloc(nxfers, sizeof(*data_ptrs), GFP_KERNEL);
++ if (!data_ptrs) {
++ ret = -ENOMEM;
++ goto err_free_k_xfer;
++ }
++
++ for (i = 0; i < nxfers; i++) {
++ data_ptrs[i] = memdup_user((const u8 __user *)
++ (uintptr_t)xfers[i].data,
++ xfers[i].len);
++ if (IS_ERR(data_ptrs[i])) {
++ ret = PTR_ERR(data_ptrs[i]);
++ break;
++ }
++
++ k_xfers[i].len = xfers[i].len;
++ if (xfers[i].rnw) {
++ k_xfers[i].rnw = true;
++ k_xfers[i].data.in = data_ptrs[i];
++ } else {
++ k_xfers[i].rnw = false;
++ k_xfers[i].data.out = data_ptrs[i];
++ }
++ }
++
++ if (ret < 0) {
++ i--;
++ goto err_free_mem;
++ }
++
++ ret = i3c_device_do_priv_xfers(dev, k_xfers, nxfers);
++ if (ret)
++ goto err_free_mem;
++
++ for (i = 0; i < nxfers; i++) {
++ if (xfers[i].rnw) {
++ if (copy_to_user((void __user *)(uintptr_t)xfers[i].data,
++ data_ptrs[i], xfers[i].len))
++ ret = -EFAULT;
++ }
++ }
++
++err_free_mem:
++ for (; i >= 0; i--)
++ kfree(data_ptrs[i]);
++ kfree(data_ptrs);
++err_free_k_xfer:
++ kfree(k_xfers);
++ return ret;
++}
++
++static struct i3c_ioc_priv_xfer *
++i3cdev_get_ioc_priv_xfer(unsigned int cmd, struct i3c_ioc_priv_xfer *u_xfers,
++ unsigned int *nxfers)
++{
++ u32 tmp = _IOC_SIZE(cmd);
++
++ if ((tmp % sizeof(struct i3c_ioc_priv_xfer)) != 0)
++ return ERR_PTR(-EINVAL);
++
++ *nxfers = tmp / sizeof(struct i3c_ioc_priv_xfer);
++ if (*nxfers == 0)
++ return NULL;
++
++ return memdup_user(u_xfers, tmp);
++}
++
++static int
++i3cdev_ioc_priv_xfer(struct i3c_device *i3c, unsigned int cmd,
++ struct i3c_ioc_priv_xfer *u_xfers)
++{
++ struct i3c_ioc_priv_xfer *k_xfers;
++ unsigned int nxfers;
++ int ret;
++
++ k_xfers = i3cdev_get_ioc_priv_xfer(cmd, u_xfers, &nxfers);
++ if (IS_ERR_OR_NULL(k_xfers))
++ return PTR_ERR(k_xfers);
++
++ ret = i3cdev_do_priv_xfer(i3c, k_xfers, nxfers);
++
++ kfree(k_xfers);
++
++ return ret;
++}
++
++static long
++i3cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
++{
++ struct i3c_device *i3c = file->private_data;
++
++ dev_dbg(&i3c->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n", cmd, arg);
++
++ if (_IOC_TYPE(cmd) != I3C_DEV_IOC_MAGIC)
++ return -ENOTTY;
++
++ /* Check command number and direction */
++ if (_IOC_NR(cmd) == _IOC_NR(I3C_IOC_PRIV_XFER(0)) &&
++ _IOC_DIR(cmd) == (_IOC_READ | _IOC_WRITE))
++ return i3cdev_ioc_priv_xfer(i3c, cmd,
++ (struct i3c_ioc_priv_xfer __user *)arg);
++
++ return 0;
++}
++
++static int i3cdev_open(struct inode *inode, struct file *file)
++{
++ struct i3cdev_data *i3cdev = container_of(inode->i_cdev,
++ struct i3cdev_data,
++ cdev);
++
++ file->private_data = i3cdev->i3c;
++
++ return 0;
++}
++
++static int i3cdev_release(struct inode *inode, struct file *file)
++{
++ file->private_data = NULL;
++
++ return 0;
++}
++
++static const struct file_operations i3cdev_fops = {
++ .owner = THIS_MODULE,
++ .read = i3cdev_read,
++ .write = i3cdev_write,
++ .unlocked_ioctl = i3cdev_ioctl,
++ .open = i3cdev_open,
++ .release = i3cdev_release,
++};
++
++/* ------------------------------------------------------------------------- */
++
++static struct class *i3cdev_class;
++
++static int i3cdev_attach(struct device *dev, void *dummy)
++{
++ struct i3cdev_data *i3cdev;
++ struct i3c_device *i3c;
++ int res;
++
++ if (dev->type == &i3c_masterdev_type || dev->driver)
++ return 0;
++
++ i3c = dev_to_i3cdev(dev);
++
++ /* Get a device */
++ i3cdev = get_free_i3cdev(i3c);
++ if (IS_ERR(i3cdev))
++ return PTR_ERR(i3cdev);
++
++ cdev_init(&i3cdev->cdev, &i3cdev_fops);
++ i3cdev->cdev.owner = THIS_MODULE;
++ res = cdev_add(&i3cdev->cdev,
++ MKDEV(MAJOR(i3cdev_number), i3cdev->id), 1);
++ if (res)
++ goto error_cdev;
++
++ /* register this i3c device with the driver core */
++ i3cdev->dev = device_create(i3cdev_class, &i3c->dev,
++ MKDEV(MAJOR(i3cdev_number), i3cdev->id),
++ NULL, "i3c-%s", dev_name(&i3c->dev));
++ if (IS_ERR(i3cdev->dev)) {
++ res = PTR_ERR(i3cdev->dev);
++ goto error;
++ }
++ pr_debug("i3cdev: I3C device [%s] registered as minor %d\n",
++ dev_name(&i3c->dev), i3cdev->id);
++ return 0;
++
++error:
++ cdev_del(&i3cdev->cdev);
++error_cdev:
++ put_i3cdev(i3cdev);
++ return res;
++}
++
++static int i3cdev_detach(struct device *dev, void *dummy)
++{
++ struct i3cdev_data *i3cdev;
++ struct i3c_device *i3c;
++
++ if (dev->type == &i3c_masterdev_type)
++ return 0;
++
++ i3c = dev_to_i3cdev(dev);
++
++ i3cdev = i3cdev_get_by_i3c(i3c);
++ if (!i3cdev)
++ return 0;
++
++ cdev_del(&i3cdev->cdev);
++ device_destroy(i3cdev_class, MKDEV(MAJOR(i3cdev_number), i3cdev->id));
++ ida_simple_remove(&i3cdev_ida, i3cdev->id);
++ put_i3cdev(i3cdev);
++
++ pr_debug("i3cdev: device [%s] unregistered\n", dev_name(&i3c->dev));
++
++ return 0;
++}
++
++static int i3cdev_notifier_call(struct notifier_block *nb,
++ unsigned long action,
++ void *data)
++{
++ struct device *dev = data;
++
++ switch (action) {
++ case BUS_NOTIFY_ADD_DEVICE:
++ case BUS_NOTIFY_UNBOUND_DRIVER:
++ return i3cdev_attach(dev, NULL);
++ case BUS_NOTIFY_DEL_DEVICE:
++ case BUS_NOTIFY_BOUND_DRIVER:
++ return i3cdev_detach(dev, NULL);
++ }
++
++ return 0;
++}
++
++static struct notifier_block i3c_notifier = {
++ .notifier_call = i3cdev_notifier_call,
++};
++
++static int __init i3cdev_init(void)
++{
++ int res;
++
++ /* Dynamically request unused major number */
++ res = alloc_chrdev_region(&i3cdev_number, 0, I3C_MINORS, "i3c");
++ if (res)
++ goto out;
++
++ /* Create a classe to populate sysfs entries*/
++ i3cdev_class = class_create(THIS_MODULE, "i3cdev");
++ if (IS_ERR(i3cdev_class)) {
++ res = PTR_ERR(i3cdev_class);
++ goto out_unreg_chrdev;
++ }
++
++ /* Keep track of busses which have devices to add or remove later */
++ res = bus_register_notifier(&i3c_bus_type, &i3c_notifier);
++ if (res)
++ goto out_unreg_class;
++
++ /* Bind to already existing device without driver right away */
++ i3c_for_each_dev(NULL, i3cdev_attach);
++
++ return 0;
++
++out_unreg_class:
++ class_destroy(i3cdev_class);
++out_unreg_chrdev:
++ unregister_chrdev_region(i3cdev_number, I3C_MINORS);
++out:
++ pr_err("%s: Driver Initialisation failed\n", __FILE__);
++ return res;
++}
++
++static void __exit i3cdev_exit(void)
++{
++ bus_unregister_notifier(&i3c_bus_type, &i3c_notifier);
++ i3c_for_each_dev(NULL, i3cdev_detach);
++ class_destroy(i3cdev_class);
++ unregister_chrdev_region(i3cdev_number, I3C_MINORS);
++}
++
++MODULE_AUTHOR("Vitor Soares <soares@synopsys.com>");
++MODULE_DESCRIPTION("I3C /dev entries driver");
++MODULE_LICENSE("GPL");
++
++module_init(i3cdev_init);
++module_exit(i3cdev_exit);
+diff --git a/drivers/i3c/internals.h b/drivers/i3c/internals.h
+index 86b7b44cfca2..a6deedf5ce06 100644
+--- a/drivers/i3c/internals.h
++++ b/drivers/i3c/internals.h
+@@ -11,6 +11,7 @@
+ #include <linux/i3c/master.h>
+
+ extern struct bus_type i3c_bus_type;
++extern const struct device_type i3c_masterdev_type;
+
+ void i3c_bus_normaluse_lock(struct i3c_bus *bus);
+ void i3c_bus_normaluse_unlock(struct i3c_bus *bus);
+@@ -23,4 +24,5 @@ int i3c_dev_enable_ibi_locked(struct i3c_dev_desc *dev);
+ int i3c_dev_request_ibi_locked(struct i3c_dev_desc *dev,
+ const struct i3c_ibi_setup *req);
+ void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev);
++int i3c_for_each_dev(void *data, int (*fn)(struct device *, void *));
+ #endif /* I3C_INTERNAL_H */
+diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
+index 5c051dba32a5..53910fb6702e 100644
+--- a/drivers/i3c/master.c
++++ b/drivers/i3c/master.c
+@@ -321,6 +321,7 @@ struct bus_type i3c_bus_type = {
+ .probe = i3c_device_probe,
+ .remove = i3c_device_remove,
+ };
++EXPORT_SYMBOL_GPL(i3c_bus_type);
+
+ static enum i3c_addr_slot_status
+ i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr)
+@@ -523,11 +524,12 @@ static void i3c_masterdev_release(struct device *dev)
+ of_node_put(dev->of_node);
+ }
+
+-static const struct device_type i3c_masterdev_type = {
++const struct device_type i3c_masterdev_type = {
+ .groups = i3c_masterdev_groups,
+ };
++EXPORT_SYMBOL_GPL(i3c_masterdev_type);
+
+-int i3c_bus_set_mode(struct i3c_bus *i3cbus, enum i3c_bus_mode mode,
++static int i3c_bus_set_mode(struct i3c_bus *i3cbus, enum i3c_bus_mode mode,
+ unsigned long max_i2c_scl_rate)
+ {
+ struct i3c_master_controller *master = i3c_bus_to_i3c_master(i3cbus);
+@@ -1410,19 +1412,19 @@ static void i3c_master_detach_i2c_dev(struct i2c_dev_desc *dev)
+ master->ops->detach_i2c_dev(dev);
+ }
+
+-static void i3c_master_pre_assign_dyn_addr(struct i3c_dev_desc *dev)
++static int i3c_master_pre_assign_dyn_addr(struct i3c_dev_desc *dev)
+ {
+ struct i3c_master_controller *master = i3c_dev_get_master(dev);
+ int ret;
+
+ if (!dev->boardinfo || !dev->boardinfo->init_dyn_addr ||
+ !dev->boardinfo->static_addr)
+- return;
++ return -1;
+
+ ret = i3c_master_setdasa_locked(master, dev->info.static_addr,
+ dev->boardinfo->init_dyn_addr);
+ if (ret)
+- return;
++ return ret;
+
+ dev->info.dyn_addr = dev->boardinfo->init_dyn_addr;
+ ret = i3c_master_reattach_i3c_dev(dev, 0);
+@@ -1433,10 +1435,11 @@ static void i3c_master_pre_assign_dyn_addr(struct i3c_dev_desc *dev)
+ if (ret)
+ goto err_rstdaa;
+
+- return;
++ return 0;
+
+ err_rstdaa:
+ i3c_master_rstdaa_locked(master, dev->boardinfo->init_dyn_addr);
++ return ret;
+ }
+
+ static void
+@@ -1631,7 +1634,7 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
+ enum i3c_addr_slot_status status;
+ struct i2c_dev_boardinfo *i2cboardinfo;
+ struct i3c_dev_boardinfo *i3cboardinfo;
+- struct i3c_dev_desc *i3cdev;
++ struct i3c_dev_desc *i3cdev, *i3ctmp;
+ struct i2c_dev_desc *i2cdev;
+ int ret;
+
+@@ -1730,8 +1733,14 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
+ * Pre-assign dynamic address and retrieve device information if
+ * needed.
+ */
+- i3c_bus_for_each_i3cdev(&master->bus, i3cdev)
+- i3c_master_pre_assign_dyn_addr(i3cdev);
++ list_for_each_entry_safe(i3cdev, i3ctmp, &master->bus.devs.i3c,
++ common.node) {
++ ret = i3c_master_pre_assign_dyn_addr(i3cdev);
++ if (ret) {
++ i3c_master_detach_i3c_dev(i3cdev);
++ i3c_master_free_i3c_dev(i3cdev);
++ }
++ }
+
+ ret = i3c_master_do_daa(master);
+ if (ret)
+@@ -2638,6 +2647,18 @@ void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev)
+ dev->ibi = NULL;
+ }
+
++int i3c_for_each_dev(void *data, int (*fn)(struct device *, void *))
++{
++ int res;
++
++ mutex_lock(&i3c_core_lock);
++ res = bus_for_each_dev(&i3c_bus_type, NULL, data, fn);
++ mutex_unlock(&i3c_core_lock);
++
++ return res;
++}
++EXPORT_SYMBOL_GPL(i3c_for_each_dev);
++
+ static int __init i3c_init(void)
+ {
+ return bus_register(&i3c_bus_type);
+diff --git a/drivers/i3c/master/Kconfig b/drivers/i3c/master/Kconfig
+index 4e80a1fcbf91..693f9aba2b17 100644
+--- a/drivers/i3c/master/Kconfig
++++ b/drivers/i3c/master/Kconfig
+@@ -21,3 +21,8 @@ config DW_I3C_MASTER
+
+ This driver can also be built as a module. If so, the module
+ will be called dw-i3c-master.
++
++config ASPEED_I3C_GLOBAL
++ tristate "ASPEED I3C global driver"
++ depends on I3C
++ depends on MACH_ASPEED_G6
+diff --git a/drivers/i3c/master/Makefile b/drivers/i3c/master/Makefile
+index 7eea9e086144..09057d1432cc 100644
+--- a/drivers/i3c/master/Makefile
++++ b/drivers/i3c/master/Makefile
+@@ -1,3 +1,4 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ obj-$(CONFIG_CDNS_I3C_MASTER) += i3c-master-cdns.o
+ obj-$(CONFIG_DW_I3C_MASTER) += dw-i3c-master.o
++obj-$(CONFIG_ASPEED_I3C_GLOBAL) += aspeed-i3c-global.o
+diff --git a/drivers/i3c/master/aspeed-i3c-global.c b/drivers/i3c/master/aspeed-i3c-global.c
+new file mode 100644
+index 000000000000..9c3e58794a3e
+--- /dev/null
++++ b/drivers/i3c/master/aspeed-i3c-global.c
+@@ -0,0 +1,89 @@
++/*
++ * Aspeed I2C Interrupt Controller.
++ *
++ * Copyright (C) 2012-2017 ASPEED Technology Inc.
++ * Copyright 2017 IBM Corporation
++ * Copyright 2017 Google, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/clk.h>
++#include <linux/irq.h>
++#include <linux/irqchip.h>
++#include <linux/irqchip/chained_irq.h>
++#include <linux/irqdomain.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/platform_device.h>
++#include <linux/of_address.h>
++#include <linux/of_irq.h>
++#include <linux/io.h>
++#include <linux/reset.h>
++#include <linux/delay.h>
++
++#define ASPEED_I3CG_CTRL(x) (0x10 + (x*0x10))
++#define ASPEED_I3CG_SET(x) (0x14 + (x*0x10))
++
++struct aspeed_i3c_global {
++ void __iomem *base;
++ struct reset_control *rst;
++};
++
++static const struct of_device_id aspeed_i3c_of_match[] = {
++ { .compatible = "aspeed,ast2600-i3c-global", },
++ {},
++};
++
++static int aspeed_i3c_global_probe(struct platform_device *pdev)
++{
++ struct aspeed_i3c_global *i3c_global;
++ struct device_node *node = pdev->dev.of_node;
++ int i = 0;
++
++ i3c_global = kzalloc(sizeof(*i3c_global), GFP_KERNEL);
++ if (!i3c_global)
++ return -ENOMEM;
++
++ i3c_global->base = of_iomap(node, 0);
++ if (!i3c_global->base) {
++ return -ENOMEM;
++ }
++
++ i3c_global->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
++
++ if (IS_ERR(i3c_global->rst)) {
++ dev_err(&pdev->dev,
++ "missing or invalid reset controller device tree entry");
++ return PTR_ERR(i3c_global->rst);
++ }
++
++ reset_control_assert(i3c_global->rst);
++ udelay(3);
++ reset_control_deassert(i3c_global->rst);
++
++ /* init */
++ for(i = 0; i < 5; i++)
++ writel(0x000474c4, i3c_global->base + ASPEED_I3CG_SET(i));
++
++ return 0;
++}
++
++static struct platform_driver aspeed_i3c_driver = {
++ .probe = aspeed_i3c_global_probe,
++ .driver = {
++ .name = KBUILD_MODNAME,
++ .of_match_table = aspeed_i3c_of_match,
++ },
++};
++
++static int __init aspeed_i3c_global_init(void)
++{
++ return platform_driver_register(&aspeed_i3c_driver);
++}
++postcore_initcall(aspeed_i3c_global_init);
++
++MODULE_AUTHOR("Ryan Chen");
++MODULE_DESCRIPTION("ASPEED I3C Global Driver");
++MODULE_LICENSE("GPL v2");
+diff --git a/include/dt-bindings/clock/ast2600-clock.h b/include/dt-bindings/clock/ast2600-clock.h
+index 26f84584a821..6cc47373cc97 100644
+--- a/include/dt-bindings/clock/ast2600-clock.h
++++ b/include/dt-bindings/clock/ast2600-clock.h
+@@ -88,7 +88,8 @@
+ #define ASPEED_CLK_MAC3RCLK 69
+ #define ASPEED_CLK_MAC4RCLK 70
+ #define ASPEED_CLK_UART5 71
+-#define ASPEED_CLK_MAX 72
++#define ASPEED_CLK_I3C 72
++#define ASPEED_CLK_MAX 73
+
+ /* Only list resets here that are not part of a gate */
+ #define ASPEED_RESET_ADC 55
+diff --git a/include/uapi/linux/i3c/i3cdev.h b/include/uapi/linux/i3c/i3cdev.h
+new file mode 100644
+index 000000000000..0897313f5516
+--- /dev/null
++++ b/include/uapi/linux/i3c/i3cdev.h
+@@ -0,0 +1,38 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
++/*
++ * Copyright (c) 2019 Synopsys, Inc. and/or its affiliates.
++ *
++ * Author: Vitor Soares <vitor.soares@synopsys.com>
++ */
++
++#ifndef _UAPI_I3C_DEV_H_
++#define _UAPI_I3C_DEV_H_
++
++#include <linux/types.h>
++#include <linux/ioctl.h>
++
++/* IOCTL commands */
++#define I3C_DEV_IOC_MAGIC 0x07
++
++/**
++ * struct i3c_ioc_priv_xfer - I3C SDR ioctl private transfer
++ * @data: Holds pointer to userspace buffer with transmit data.
++ * @len: Length of data buffer buffers, in bytes.
++ * @rnw: encodes the transfer direction. true for a read, false for a write
++ */
++struct i3c_ioc_priv_xfer {
++ __u64 data;
++ __u16 len;
++ __u8 rnw;
++ __u8 pad[5];
++};
++
++
++#define I3C_PRIV_XFER_SIZE(N) \
++ ((((sizeof(struct i3c_ioc_priv_xfer)) * (N)) < (1 << _IOC_SIZEBITS)) \
++ ? ((sizeof(struct i3c_ioc_priv_xfer)) * (N)) : 0)
++
++#define I3C_IOC_PRIV_XFER(N) \
++ _IOC(_IOC_READ|_IOC_WRITE, I3C_DEV_IOC_MAGIC, 30, I3C_PRIV_XFER_SIZE(N))
++
++#endif
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0107-arm-dts-aspeed-g6-Add-ast2600-mctp-node.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0107-arm-dts-aspeed-g6-Add-ast2600-mctp-node.patch
new file mode 100644
index 000000000..fc72c7537
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0107-arm-dts-aspeed-g6-Add-ast2600-mctp-node.patch
@@ -0,0 +1,79 @@
+From 7f4dc6aee65d9badf841099806ae6b85a86320ce Mon Sep 17 00:00:00 2001
+From: Iwona Winiarska <iwona.winiarska@intel.com>
+Date: Thu, 27 Feb 2020 00:53:38 +0100
+Subject: [PATCH 107/108] arm: dts: aspeed-g6: Add ast2600-mctp node
+
+AST2600 provides MCTP over PCIe controller allowing BMC to communicate
+with devices on host PCIe bus.
+
+We are also adding syscon node describing PCIe Host controller device
+which can be used to gather information on PCIe enumeration (and
+assigned address).
+
+Signed-off-by: Iwona Winiarska <iwona.winiarska@intel.com>
+---
+ .../bindings/soc/aspeed/aspeed-mctp.txt | 25 +++++++++++++++++++
+ arch/arm/boot/dts/aspeed-g6.dtsi | 15 +++++++++++
+ 2 files changed, 40 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/soc/aspeed/aspeed-mctp.txt
+
+diff --git a/Documentation/devicetree/bindings/soc/aspeed/aspeed-mctp.txt b/Documentation/devicetree/bindings/soc/aspeed/aspeed-mctp.txt
+new file mode 100644
+index 000000000000..5dc30fdfc53a
+--- /dev/null
++++ b/Documentation/devicetree/bindings/soc/aspeed/aspeed-mctp.txt
+@@ -0,0 +1,25 @@
++* Aspeed AST2600 MCTP PCIe VDM Controller
++
++Required properties:
++- compatible : must be "aspeed,ast2600-mctp"
++- reg : contains the address and size of the memory region
++ associated with the MCTP controller
++- resets : reset specifier for the syscon reset associated with
++ the MCTP controller
++- interrupts-extended : two interrupt cells; the first specifies the global
++ interrupt for MCTP controller and the second
++ specifies the PCIe reset or PERST interrupt
++- aspeed,pcieh : a phandle to the PCIe Host Controller node to be
++ used in conjunction with the PCIe reset or PERST
++ interrupt
++Example:
++
++mctp: mctp@1e6e8000 {
++ compatible = "aspeed,ast2600-mctp";
++ reg = <0x1e6e8000 0x1000>;
++ interrupts-extended = <&gic GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
++ <&scu_ic0 ASPEED_AST2600_SCU_IC0_PCIE_PERST_LO_TO_HI>;
++ resets = <&syscon ASPEED_RESET_DEV_MCTP>;
++ aspeed,pcieh = <&pcieh>;
++ status = "disabled";
++};
+diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
+index 33e1b0ef24f0..90a060db20c7 100644
+--- a/arch/arm/boot/dts/aspeed-g6.dtsi
++++ b/arch/arm/boot/dts/aspeed-g6.dtsi
+@@ -407,6 +407,21 @@
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
++ pcieh: pcieh@1e6ed000 {
++ compatible = "aspeed,ast2600-pcieh", "syscon";
++ reg = <0x1e6ed000 0x100>;
++ };
++
++ mctp: mctp@1e6e8000 {
++ compatible = "aspeed,ast2600-mctp";
++ reg = <0x1e6e8000 0x1000>;
++ interrupts-extended = <&gic GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
++ <&scu_ic0 ASPEED_AST2600_SCU_IC0_PCIE_PERST_LO_TO_HI>;
++ resets = <&syscon ASPEED_RESET_DEV_MCTP>;
++ aspeed,pcieh = <&pcieh>;
++ status = "disabled";
++ };
++
+ adc0: adc@1e6e9000 {
+ compatible = "aspeed,ast2600-adc";
+ reg = <0x1e6e9000 0x100>;
+--
+2.21.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0108-soc-aspeed-mctp-Add-initial-driver-for-ast2600-mctp.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0108-soc-aspeed-mctp-Add-initial-driver-for-ast2600-mctp.patch
new file mode 100644
index 000000000..bff271bfe
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0108-soc-aspeed-mctp-Add-initial-driver-for-ast2600-mctp.patch
@@ -0,0 +1,1265 @@
+From cafc578414a664ecde96598838a3907a5d915416 Mon Sep 17 00:00:00 2001
+From: Iwona Winiarska <iwona.winiarska@intel.com>
+Date: Mon, 6 Apr 2020 22:00:46 +0200
+Subject: [PATCH 108/108] soc: aspeed: mctp: Add initial driver for
+ ast2600-mctp
+
+Currently, there is no proper MCTP networking subsystem in Linux.
+Until we are able to work out the details of that, we are going to
+expose HW to userspace using raw read/write interface.
+Because of that, this driver is not intended to be submitted upstream.
+
+Here we are providing a simple device driver for AST2600 MCTP
+controller.
+
+Signed-off-by: Iwona Winiarska <iwona.winiarska@intel.com>
+---
+ drivers/soc/aspeed/Kconfig | 8 +
+ drivers/soc/aspeed/Makefile | 1 +
+ drivers/soc/aspeed/aspeed-mctp.c | 1126 ++++++++++++++++++++++++++++++
+ include/uapi/linux/aspeed-mctp.h | 72 ++
+ 4 files changed, 1207 insertions(+)
+ create mode 100644 drivers/soc/aspeed/aspeed-mctp.c
+ create mode 100644 include/uapi/linux/aspeed-mctp.h
+
+diff --git a/drivers/soc/aspeed/Kconfig b/drivers/soc/aspeed/Kconfig
+index 13cd9fbabbf1..78d9140d822b 100644
+--- a/drivers/soc/aspeed/Kconfig
++++ b/drivers/soc/aspeed/Kconfig
+@@ -43,6 +43,14 @@ config ASPEED_LPC_SNOOP
+ allows the BMC to listen on and save the data written by
+ the host to an arbitrary LPC I/O port.
+
++config ASPEED_MCTP
++ tristate "Aspeed ast2600 MCTP Controller support"
++ depends on SOC_ASPEED && REGMAP && MFD_SYSCON
++ help
++ Enable support for ast2600 MCTP Controller.
++ The MCTP controller allows the BMC to communicate with devices on
++ the host PCIe network.
++
+ config ASPEED_P2A_CTRL
+ depends on SOC_ASPEED && REGMAP && MFD_SYSCON
+ tristate "Aspeed ast2400/2500 HOST P2A VGA MMIO to BMC bridge control"
+diff --git a/drivers/soc/aspeed/Makefile b/drivers/soc/aspeed/Makefile
+index 875f0d9e7866..b3c143f9e24c 100644
+--- a/drivers/soc/aspeed/Makefile
++++ b/drivers/soc/aspeed/Makefile
+@@ -7,3 +7,4 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o
+ obj-$(CONFIG_ASPEED_P2A_CTRL) += aspeed-p2a-ctrl.o
+ obj-$(CONFIG_ASPEED_XDMA) += aspeed-xdma.o
+ obj-$(CONFIG_ASPEED_VGA_SHAREDMEM) += aspeed-vga-sharedmem.o
++obj-$(CONFIG_ASPEED_MCTP) += aspeed-mctp.o
+diff --git a/drivers/soc/aspeed/aspeed-mctp.c b/drivers/soc/aspeed/aspeed-mctp.c
+new file mode 100644
+index 000000000000..addf96133abf
+--- /dev/null
++++ b/drivers/soc/aspeed/aspeed-mctp.c
+@@ -0,0 +1,1126 @@
++// SPDX-License-Identifier: GPL-2.0
++// Copyright (c) 2020, Intel Corporation.
++
++#include <linux/dma-mapping.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/mfd/syscon.h>
++#include <linux/miscdevice.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/pci.h>
++#include <linux/poll.h>
++#include <linux/ptr_ring.h>
++#include <linux/regmap.h>
++#include <linux/reset.h>
++#include <linux/slab.h>
++#include <linux/uaccess.h>
++#include <linux/workqueue.h>
++#include <uapi/linux/aspeed-mctp.h>
++
++/* AST2600 MCTP Controller registers */
++#define ASPEED_MCTP_CTRL 0x000
++#define TX_CMD_TRIGGER BIT(0)
++#define RX_CMD_READY BIT(4)
++#define MATCHING_EID BIT(9)
++
++#define ASPEED_MCTP_TX_CMD 0x004
++#define ASPEED_MCTP_RX_CMD 0x008
++
++#define ASPEED_MCTP_INT_STS 0x00c
++#define ASPEED_MCTP_INT_EN 0x010
++#define TX_CMD_SENT_INT BIT(0)
++#define TX_CMD_LAST_INT BIT(1)
++#define TX_CMD_WRONG_INT BIT(2)
++#define RX_CMD_RECEIVE_INT BIT(8)
++#define RX_CMD_NO_MORE_INT BIT(9)
++
++#define ASPEED_MCTP_EID 0x014
++#define ASPEED_MCTP_OBFF_CTRL 0x018
++
++#define ASPEED_MCTP_ENGINE_CTRL 0x01c
++#define TX_MAX_PAYLOAD_SIZE_SHIFT 0
++#define TX_MAX_PAYLOAD_SIZE_MASK GENMASK(1, TX_MAX_PAYLOAD_SIZE_SHIFT)
++#define TX_MAX_PAYLOAD_SIZE(x) \
++ (((x) << TX_MAX_PAYLOAD_SIZE_SHIFT) & TX_MAX_PAYLOAD_SIZE_MASK)
++#define RX_MAX_PAYLOAD_SIZE_SHIFT 4
++#define RX_MAX_PAYLOAD_SIZE_MASK GENMASK(5, RX_MAX_PAYLOAD_SIZE_SHIFT)
++#define RX_MAX_PAYLOAD_SIZE(x) \
++ (((x) << RX_MAX_PAYLOAD_SIZE_SHIFT) & RX_MAX_PAYLOAD_SIZE_MASK)
++#define FIFO_LAYOUT_SHIFT 8
++#define FIFO_LAYOUT_MASK GENMASK(9, FIFO_LAYOUT_SHIFT)
++#define FIFO_LAYOUT(x) \
++ (((x) << FIFO_LAYOUT_SHIFT) & FIFO_LAYOUT_MASK)
++
++#define ASPEED_MCTP_RX_BUF_ADDR 0x020
++#define ASPEED_MCTP_RX_BUF_SIZE 0x024
++#define ASPEED_MCTP_RX_BUF_RD_PTR 0x028
++#define UPDATE_RX_RD_PTR BIT(31)
++#define RX_BUFFER_RD_PTR GENMASK(11, 0)
++#define ASPEED_MCTP_RX_BUF_WR_PTR 0x02c
++#define RX_BUFFER_WR_PTR GENMASK(11, 0)
++
++#define ASPEED_MCTP_TX_BUF_ADDR 0x004
++#define ASPEED_MCTP_TX_BUF_SIZE 0x034
++#define ASPEED_MCTP_TX_BUF_RD_PTR 0x038
++#define UPDATE_TX_RD_PTR BIT(31)
++#define TX_BUFFER_RD_PTR GENMASK(11, 0)
++#define ASPEED_MCTP_TX_BUF_WR_PTR 0x03c
++#define TX_BUFFER_WR_PTR GENMASK(11, 0)
++
++#define ADDR_LEN (BIT(26) - 1)
++#define DATA_ADDR(x) (((x) >> 4) & ADDR_LEN)
++
++/* TX command */
++#define TX_LAST_CMD BIT(31)
++#define TX_DATA_ADDR_SHIFT 4
++#define TX_DATA_ADDR_MASK GENMASK(30, TX_DATA_ADDR_SHIFT)
++#define TX_DATA_ADDR(x) \
++ ((DATA_ADDR(x) << TX_DATA_ADDR_SHIFT) & TX_DATA_ADDR_MASK)
++#define TX_RESERVED_1_MASK GENMASK(1, 0) /* must be 1 */
++#define TX_RESERVED_1 1
++#define TX_STOP_AFTER_CMD BIT(16)
++#define TX_INTERRUPT_AFTER_CMD BIT(15)
++#define TX_PACKET_SIZE_SHIFT 2
++#define TX_PACKET_SIZE_MASK GENMASK(12, TX_PACKET_SIZE_SHIFT)
++#define TX_PACKET_SIZE(x) \
++ (((x) << TX_PACKET_SIZE_SHIFT) & TX_PACKET_SIZE_MASK)
++#define TX_RESERVED_0_MASK GENMASK(1, 0) /* MBZ */
++#define TX_RESERVED_0 0
++
++/* RX command */
++#define RX_INTERRUPT_AFTER_CMD BIT(2)
++#define RX_DATA_ADDR_SHIFT 4
++#define RX_DATA_ADDR_MASK GENMASK(30, RX_DATA_ADDR_SHIFT)
++#define RX_DATA_ADDR(x) \
++ ((DATA_ADDR(x) << RX_DATA_ADDR_SHIFT) & RX_DATA_ADDR_MASK)
++
++/* Buffer sizes */
++#define TX_CMD_COUNT 4
++#define RX_CMD_COUNT 4
++#define TX_MAX_CMD_COUNT SZ_4K
++#define RX_MAX_CMD_COUNT SZ_4K
++
++/* PCIe Host Controller registers */
++#define ASPEED_PCIE_MISC_STS_1 0x0c4
++
++/* PCI address definitions */
++#define PCI_DEV_NUM_MASK GENMASK(4, 0)
++#define PCI_BUS_NUM_SHIFT 5
++#define PCI_BUS_NUM_MASK GENMASK(12, PCI_BUS_NUM_SHIFT)
++#define GET_PCI_DEV_NUM(x) ((x) & PCI_DEV_NUM_MASK)
++#define GET_PCI_BUS_NUM(x) (((x) & PCI_BUS_NUM_MASK) >> PCI_BUS_NUM_SHIFT)
++
++/* FIXME: ast2600 supports variable max transmission unit */
++#define ASPEED_MCTP_MTU 64
++
++struct mctp_pcie_packet {
++ struct {
++ u32 hdr[4];
++ u32 payload[16];
++ } data;
++ u32 size;
++};
++
++struct aspeed_mctp_tx_cmd {
++ u32 tx_lo;
++ u32 tx_hi;
++};
++
++struct mctp_buffer {
++ void *vaddr;
++ dma_addr_t dma_handle;
++};
++
++struct mctp_channel {
++ struct mctp_buffer data;
++ struct mctp_buffer cmd;
++ struct tasklet_struct tasklet;
++ u32 rd_ptr;
++ u32 wr_ptr;
++};
++
++struct aspeed_mctp {
++ struct device *dev;
++ struct regmap *map;
++ struct reset_control *reset;
++ struct mctp_channel tx;
++ struct mctp_channel rx;
++ struct list_head clients;
++ spinlock_t clients_lock; /* to protect clients list operations */
++ wait_queue_head_t wait_queue;
++ struct {
++ struct regmap *map;
++ struct delayed_work rst_dwork;
++ bool need_uevent;
++ u16 bdf;
++ } pcie;
++};
++
++struct mctp_client {
++ struct kref ref;
++ struct aspeed_mctp *priv;
++ struct ptr_ring tx_queue;
++ struct ptr_ring rx_queue;
++ struct list_head link;
++ bool disconnected;
++};
++
++#define TX_CMD_BUF_SIZE \
++ PAGE_ALIGN(TX_CMD_COUNT * sizeof(struct aspeed_mctp_tx_cmd))
++#define TX_DATA_BUF_SIZE \
++ PAGE_ALIGN(TX_CMD_COUNT * sizeof(struct mctp_pcie_packet))
++#define RX_CMD_BUF_SIZE PAGE_ALIGN(RX_CMD_COUNT * sizeof(u32))
++#define RX_DATA_BUF_SIZE \
++ PAGE_ALIGN(RX_CMD_COUNT * sizeof(struct mctp_pcie_packet))
++
++struct kmem_cache *packet_cache;
++
++static void *packet_alloc(gfp_t flags)
++{
++ return kmem_cache_alloc(packet_cache, flags);
++}
++
++static void packet_free(void *packet)
++{
++ kmem_cache_free(packet_cache, packet);
++}
++
++static void aspeed_mctp_rx_trigger(struct mctp_channel *rx)
++{
++ struct aspeed_mctp *priv = container_of(rx, typeof(*priv), rx);
++
++ /*
++ * Even though rx_buf_addr doesn't change, if we don't do the write
++ * here, the HW doesn't trigger RX.
++ * Also, note that we're writing 0 as wr_ptr. If we're writing other
++ * value, the HW behaves in a bizzare way that's hard to explain...
++ */
++ regmap_write(priv->map, ASPEED_MCTP_RX_BUF_ADDR, rx->cmd.dma_handle);
++ regmap_write(priv->map, ASPEED_MCTP_RX_BUF_WR_PTR, 0);
++ regmap_update_bits(priv->map, ASPEED_MCTP_CTRL, RX_CMD_READY,
++ RX_CMD_READY);
++}
++
++static void aspeed_mctp_tx_trigger(struct mctp_channel *tx)
++{
++ struct aspeed_mctp *priv = container_of(tx, typeof(*priv), tx);
++
++ regmap_write(priv->map, ASPEED_MCTP_TX_BUF_ADDR,
++ tx->cmd.dma_handle);
++ regmap_write(priv->map, ASPEED_MCTP_TX_BUF_WR_PTR, tx->wr_ptr);
++ regmap_update_bits(priv->map, ASPEED_MCTP_CTRL, TX_CMD_TRIGGER,
++ TX_CMD_TRIGGER);
++}
++
++static void aspeed_mctp_emit_tx_cmd(struct mctp_channel *tx,
++ struct mctp_pcie_packet *packet, bool last)
++{
++ struct aspeed_mctp_tx_cmd *tx_cmd =
++ (struct aspeed_mctp_tx_cmd *)tx->cmd.vaddr + tx->wr_ptr;
++ u32 packet_sz_dw = packet->size / sizeof(u32) -
++ sizeof(packet->data.hdr) / sizeof(u32);
++ u32 offset = tx->wr_ptr * sizeof(packet->data);
++
++ memcpy(tx->data.vaddr + offset, &packet->data,
++ sizeof(packet->data));
++
++ tx_cmd->tx_lo |= TX_PACKET_SIZE(packet_sz_dw);
++ tx_cmd->tx_lo |= TX_STOP_AFTER_CMD;
++ tx_cmd->tx_lo |= TX_INTERRUPT_AFTER_CMD;
++ tx_cmd->tx_hi |= TX_RESERVED_1;
++ tx_cmd->tx_hi |= TX_DATA_ADDR(tx->data.dma_handle + offset);
++ if (last)
++ tx_cmd->tx_hi |= TX_LAST_CMD;
++
++ tx->wr_ptr++;
++}
++
++static struct mctp_client *aspeed_mctp_client_alloc(struct aspeed_mctp *priv)
++{
++ struct mctp_client *client;
++
++ client = kzalloc(sizeof(*client), GFP_KERNEL);
++ if (!client)
++ goto out;
++
++ kref_init(&client->ref);
++ client->priv = priv;
++ ptr_ring_init(&client->tx_queue, TX_CMD_COUNT, GFP_KERNEL);
++ ptr_ring_init(&client->rx_queue, RX_CMD_COUNT, GFP_ATOMIC);
++
++out:
++ return client;
++}
++
++static void aspeed_mctp_client_free(struct kref *ref)
++{
++ struct mctp_client *client = container_of(ref, typeof(*client), ref);
++
++ ptr_ring_cleanup(&client->rx_queue, &packet_free);
++ ptr_ring_cleanup(&client->tx_queue, &packet_free);
++
++ kfree(client);
++}
++
++static void aspeed_mctp_client_get(struct mctp_client *client)
++{
++ lockdep_assert_held(&client->priv->clients_lock);
++
++ kref_get(&client->ref);
++}
++
++static void aspeed_mctp_client_put(struct mctp_client *client)
++{
++ kref_put(&client->ref, &aspeed_mctp_client_free);
++}
++
++static void aspeed_mctp_tx_tasklet(unsigned long data)
++{
++ struct mctp_channel *tx = (struct mctp_channel *)data;
++ struct aspeed_mctp *priv = container_of(tx, typeof(*priv), tx);
++ u32 rd_ptr = READ_ONCE(tx->rd_ptr);
++ struct mctp_pcie_packet *packet;
++ struct mctp_client *client;
++ bool last, trigger = false;
++
++ /* we're called while there's still TX in progress */
++ if (rd_ptr == 0 && tx->wr_ptr != 0)
++ return;
++
++ spin_lock(&priv->clients_lock);
++ client = list_first_entry_or_null(&priv->clients, typeof(*client),
++ link);
++ if (!client) {
++ spin_unlock(&priv->clients_lock);
++ return;
++ }
++ aspeed_mctp_client_get(client);
++ spin_unlock(&priv->clients_lock);
++
++ /* last tx ended up with buffer size, meaning we now restart from 0 */
++ if (rd_ptr == TX_CMD_COUNT) {
++ WRITE_ONCE(tx->rd_ptr, 0);
++ tx->wr_ptr = 0;
++ }
++
++ while (tx->wr_ptr < TX_CMD_COUNT) {
++ packet = ptr_ring_consume(&client->tx_queue);
++ if (!packet)
++ break;
++
++ last = !__ptr_ring_peek(&client->tx_queue);
++
++ aspeed_mctp_emit_tx_cmd(tx, packet, last);
++ packet_free(packet);
++
++ trigger = true;
++
++ if (last)
++ break;
++ }
++
++ aspeed_mctp_client_put(client);
++
++ if (trigger)
++ aspeed_mctp_tx_trigger(tx);
++}
++
++static void aspeed_mctp_rx_tasklet(unsigned long data)
++{
++ struct mctp_channel *rx = (struct mctp_channel *)data;
++ struct aspeed_mctp *priv = container_of(rx, typeof(*priv), rx);
++ u32 rd_ptr = READ_ONCE(priv->rx.rd_ptr);
++ struct mctp_pcie_packet *rx_packet;
++ struct mctp_client *client;
++ int ret;
++
++ spin_lock(&priv->clients_lock);
++ client = list_first_entry_or_null(&priv->clients, typeof(*client),
++ link);
++ if (!client) {
++ rx->wr_ptr = rd_ptr;
++ spin_unlock(&priv->clients_lock);
++ goto out_skip;
++ }
++ aspeed_mctp_client_get(client);
++ spin_unlock(&priv->clients_lock);
++
++ while (rx->wr_ptr < rd_ptr) {
++ rx_packet = packet_alloc(GFP_ATOMIC);
++ if (!rx_packet) {
++ dev_err(priv->dev, "Failed to allocate RX packet\n");
++ goto out_put;
++ }
++
++ memcpy(&rx_packet->data,
++ rx->data.vaddr + rx->wr_ptr * sizeof(rx_packet->data),
++ sizeof(rx_packet->data));
++ rx->wr_ptr++;
++
++ ret = ptr_ring_produce(&client->rx_queue, rx_packet);
++ if (ret) {
++ dev_warn(priv->dev, "Failed to produce RX packet: %d\n",
++ ret);
++ packet_free(rx_packet);
++ continue;
++ }
++ }
++out_skip:
++ if (rx->wr_ptr == RX_CMD_COUNT || (rx->wr_ptr == 0 && rd_ptr == 0)) {
++ rx->wr_ptr = 0;
++ if (client)
++ aspeed_mctp_rx_trigger(rx);
++ else
++ WRITE_ONCE(rx->rd_ptr, 0);
++ }
++ wake_up_all(&priv->wait_queue);
++
++out_put:
++ if (client)
++ aspeed_mctp_client_put(client);
++}
++
++static void aspeed_mctp_rx_chan_init(struct mctp_channel *rx)
++{
++ struct aspeed_mctp *priv = container_of(rx, typeof(*priv), rx);
++ u32 *rx_cmd = (u32 *)rx->cmd.vaddr;
++ u32 rx_data_addr = rx->data.dma_handle;
++ struct mctp_pcie_packet packet;
++ u32 data_size = sizeof(packet.data);
++ u32 i;
++
++ for (i = 0; i < RX_CMD_COUNT; i++) {
++ *rx_cmd |= RX_DATA_ADDR(rx_data_addr);
++ *rx_cmd |= RX_INTERRUPT_AFTER_CMD;
++ rx_data_addr += data_size;
++ rx_cmd++;
++ }
++ regmap_write(priv->map, ASPEED_MCTP_RX_BUF_SIZE, RX_CMD_COUNT);
++}
++
++static void aspeed_mctp_tx_chan_init(struct mctp_channel *tx)
++{
++ struct aspeed_mctp *priv = container_of(tx, typeof(*priv), tx);
++
++ regmap_write(priv->map, ASPEED_MCTP_TX_BUF_SIZE, TX_CMD_COUNT);
++ regmap_write(priv->map, ASPEED_MCTP_TX_BUF_WR_PTR, 0);
++}
++
++static int aspeed_mctp_open(struct inode *inode, struct file *file)
++{
++ struct miscdevice *misc = file->private_data;
++ struct platform_device *pdev = to_platform_device(misc->parent);
++ struct aspeed_mctp *priv = platform_get_drvdata(pdev);
++ struct mctp_client *client;
++ int ret;
++
++ if (priv->pcie.bdf == 0) {
++ ret = -ENODEV;
++ goto out;
++ }
++
++ client = aspeed_mctp_client_alloc(priv);
++ if (!client) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ spin_lock_bh(&priv->clients_lock);
++ /* TODO: Add support for multiple clients */
++ if (!list_empty(&priv->clients)) {
++ ret = -EBUSY;
++ goto out_unlock;
++ }
++ list_add_tail(&client->link, &priv->clients);
++ spin_unlock_bh(&priv->clients_lock);
++
++ /*
++ * kick the tasklet to trigger rx
++ * bh_disable/enable is just to make sure that the tasklet gets
++ * scheduled immediately in process context without any unnecessary
++ * delay
++ */
++ local_bh_disable();
++ tasklet_hi_schedule(&priv->rx.tasklet);
++ local_bh_enable();
++
++ file->private_data = client;
++
++ return 0;
++out_unlock:
++ spin_unlock_bh(&priv->clients_lock);
++ aspeed_mctp_client_put(client);
++out:
++ return ret;
++}
++
++static int aspeed_mctp_release(struct inode *inode, struct file *file)
++{
++ struct mctp_client *client = file->private_data;
++ struct aspeed_mctp *priv = client->priv;
++
++ spin_lock_bh(&priv->clients_lock);
++ list_del(&client->link);
++ spin_unlock_bh(&priv->clients_lock);
++
++ /* Disable the tasklet to appease lockdep */
++ local_bh_disable();
++ aspeed_mctp_client_put(client);
++ local_bh_enable();
++
++ return 0;
++}
++
++static ssize_t aspeed_mctp_read(struct file *file, char __user *buf,
++ size_t count, loff_t *ppos)
++{
++ struct mctp_client *client = file->private_data;
++ struct aspeed_mctp *priv = client->priv;
++ struct mctp_pcie_packet *rx_packet;
++ size_t packet_sz = sizeof(rx_packet->data);
++
++ if (READ_ONCE(client->disconnected))
++ return -EIO;
++
++ if (buf && count > 0) {
++ if (count > packet_sz)
++ count = packet_sz;
++
++ rx_packet = ptr_ring_consume_bh(&client->rx_queue);
++ if (!rx_packet)
++ return -EAGAIN;
++
++ if (copy_to_user(buf, &rx_packet->data, count)) {
++ dev_err(priv->dev, "copy to user failed\n");
++ packet_free(rx_packet);
++ return -EFAULT;
++ }
++
++ packet_free(rx_packet);
++ }
++
++ return count;
++}
++
++static ssize_t aspeed_mctp_write(struct file *file, const char __user *buf,
++ size_t count, loff_t *ppos)
++{
++ struct mctp_client *client = file->private_data;
++ struct aspeed_mctp *priv = client->priv;
++ struct mctp_pcie_packet *tx_packet;
++ int ret;
++
++ if (READ_ONCE(client->disconnected))
++ return -EIO;
++
++ tx_packet = packet_alloc(GFP_KERNEL);
++ if (!tx_packet) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ if (buf && count > 0) {
++ if (count > sizeof(tx_packet->data)) {
++ ret = -ENOSPC;
++ goto out_packet;
++ }
++
++ if (copy_from_user(&tx_packet->data, buf, count)) {
++ dev_err(priv->dev, "copy from user failed\n");
++ ret = -EFAULT;
++ goto out_packet;
++ }
++ tx_packet->size = count;
++
++ ret = ptr_ring_produce_bh(&client->tx_queue, tx_packet);
++ if (ret)
++ goto out_packet;
++
++ tasklet_hi_schedule(&priv->tx.tasklet);
++ }
++
++ return count;
++
++out_packet:
++ packet_free(tx_packet);
++out:
++ return ret;
++}
++
++static int
++aspeed_mctp_filter_eid(struct aspeed_mctp *priv, void __user *userbuf)
++{
++ struct aspeed_mctp_filter_eid eid;
++
++ if (copy_from_user(&eid, userbuf, sizeof(eid))) {
++ dev_err(priv->dev, "copy from user failed\n");
++ return -EFAULT;
++ }
++
++ if (eid.enable) {
++ regmap_write(priv->map, ASPEED_MCTP_EID, eid.eid);
++ regmap_update_bits(priv->map, ASPEED_MCTP_CTRL,
++ MATCHING_EID, MATCHING_EID);
++ } else {
++ regmap_update_bits(priv->map, ASPEED_MCTP_CTRL,
++ MATCHING_EID, 0);
++ }
++ return 0;
++}
++
++static int aspeed_mctp_get_bdf(struct aspeed_mctp *priv, void __user *userbuf)
++{
++ struct aspeed_mctp_get_bdf bdf = { priv->pcie.bdf };
++
++ if (copy_to_user(userbuf, &bdf, sizeof(bdf))) {
++ dev_err(priv->dev, "copy to user failed\n");
++ return -EFAULT;
++ }
++ return 0;
++}
++
++static int
++aspeed_mctp_get_medium_id(struct aspeed_mctp *priv, void __user *userbuf)
++{
++ struct aspeed_mctp_get_medium_id id = { 0x09 }; /* PCIe revision 2.0 */
++
++ if (copy_to_user(userbuf, &id, sizeof(id))) {
++ dev_err(priv->dev, "copy to user failed\n");
++ return -EFAULT;
++ }
++ return 0;
++}
++
++static int
++aspeed_mctp_get_mtu(struct aspeed_mctp *priv, void __user *userbuf)
++{
++ struct aspeed_mctp_get_mtu id = { ASPEED_MCTP_MTU };
++
++ if (copy_to_user(userbuf, &id, sizeof(id))) {
++ dev_err(priv->dev, "copy to user failed\n");
++ return -EFAULT;
++ }
++ return 0;
++}
++
++static long
++aspeed_mctp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
++{
++ struct mctp_client *client = file->private_data;
++ struct aspeed_mctp *priv = client->priv;
++ void __user *userbuf = (void __user *)arg;
++ int ret;
++
++ switch (cmd) {
++ case ASPEED_MCTP_IOCTL_FILTER_EID:
++ ret = aspeed_mctp_filter_eid(priv, userbuf);
++ break;
++
++ case ASPEED_MCTP_IOCTL_GET_BDF:
++ ret = aspeed_mctp_get_bdf(priv, userbuf);
++ break;
++
++ case ASPEED_MCTP_IOCTL_GET_MEDIUM_ID:
++ ret = aspeed_mctp_get_medium_id(priv, userbuf);
++ break;
++
++ case ASPEED_MCTP_IOCTL_GET_MTU:
++ ret = aspeed_mctp_get_mtu(priv, userbuf);
++ break;
++
++ default:
++ dev_err(priv->dev, "Command not found\n");
++ ret = -EINVAL;
++ }
++
++ return ret;
++}
++
++static __poll_t aspeed_mctp_poll(struct file *file,
++ struct poll_table_struct *pt)
++{
++ struct mctp_client *client = file->private_data;
++ struct aspeed_mctp *priv = client->priv;
++ __poll_t ret = 0;
++
++ poll_wait(file, &priv->wait_queue, pt);
++
++ if (!ptr_ring_full_bh(&client->tx_queue))
++ ret |= EPOLLOUT;
++
++ if (__ptr_ring_peek(&client->rx_queue))
++ ret |= EPOLLIN;
++
++ return ret;
++}
++
++static const struct file_operations aspeed_mctp_fops = {
++ .owner = THIS_MODULE,
++ .open = aspeed_mctp_open,
++ .release = aspeed_mctp_release,
++ .read = aspeed_mctp_read,
++ .write = aspeed_mctp_write,
++ .unlocked_ioctl = aspeed_mctp_ioctl,
++ .poll = aspeed_mctp_poll,
++};
++
++static const struct regmap_config aspeed_mctp_regmap_cfg = {
++ .reg_bits = 32,
++ .reg_stride = 4,
++ .val_bits = 32,
++ .max_register = ASPEED_MCTP_TX_BUF_WR_PTR,
++};
++
++struct device_type aspeed_mctp_type = {
++ .name = "aspeed-mctp",
++};
++
++static struct miscdevice aspeed_mctp_miscdev = {
++ .minor = MISC_DYNAMIC_MINOR,
++ .name = "aspeed-mctp",
++ .fops = &aspeed_mctp_fops,
++};
++
++static void aspeed_mctp_send_pcie_uevent(struct kobject *kobj, bool ready)
++{
++ char *pcie_not_ready_event[] = { ASPEED_MCTP_READY "=0", NULL };
++ char *pcie_ready_event[] = { ASPEED_MCTP_READY "=1", NULL };
++
++ kobject_uevent_env(kobj, KOBJ_CHANGE,
++ ready ? pcie_ready_event : pcie_not_ready_event);
++}
++
++static void aspeed_mctp_pcie_setup(struct aspeed_mctp *priv)
++{
++ u32 reg;
++
++ regmap_read(priv->pcie.map, ASPEED_PCIE_MISC_STS_1, &reg);
++
++ priv->pcie.bdf = PCI_DEVID(GET_PCI_BUS_NUM(reg), GET_PCI_DEV_NUM(reg));
++ if (priv->pcie.bdf != 0)
++ cancel_delayed_work(&priv->pcie.rst_dwork);
++ else
++ schedule_delayed_work(&priv->pcie.rst_dwork,
++ msecs_to_jiffies(1000));
++}
++
++static void aspeed_mctp_irq_enable(struct aspeed_mctp *priv)
++{
++ u32 enable = TX_CMD_LAST_INT | TX_CMD_WRONG_INT |
++ RX_CMD_RECEIVE_INT;
++
++ regmap_write(priv->map, ASPEED_MCTP_INT_EN, enable);
++}
++
++static void aspeed_mctp_irq_disable(struct aspeed_mctp *priv)
++{
++ regmap_write(priv->map, ASPEED_MCTP_INT_EN, 0);
++}
++
++static void aspeed_mctp_reset_work(struct work_struct *work)
++{
++ struct aspeed_mctp *priv = container_of(work, typeof(*priv),
++ pcie.rst_dwork.work);
++
++ /*
++ * Client "disconnection" is permanent to avoid forcing the user to use
++ * uevents in order to monitor for reset. Even if no reads/writes are
++ * issued during pci reset, userspace will still get -EIO afterwards,
++ * forcing it to reopen and check the BDF (which may have potentially
++ * changed after reset). Uevents can be used to avoid looping in open()
++ */
++ if (priv->pcie.need_uevent) {
++ struct kobject *kobj = &aspeed_mctp_miscdev.this_device->kobj;
++ struct mctp_client *client;
++
++ spin_lock_bh(&priv->clients_lock);
++ client = list_first_entry_or_null(&priv->clients,
++ typeof(*client), link);
++ /*
++ * Here, we're only updating the "disconnected" flag under
++ * spinlock, meaning that we can skip taking the refcount
++ */
++ if (client)
++ WRITE_ONCE(client->disconnected, true);
++ spin_unlock_bh(&priv->clients_lock);
++
++ aspeed_mctp_send_pcie_uevent(kobj, false);
++ priv->pcie.need_uevent = false;
++ }
++
++ aspeed_mctp_pcie_setup(priv);
++
++ if (priv->pcie.bdf) {
++ aspeed_mctp_send_pcie_uevent(&priv->dev->kobj, true);
++ aspeed_mctp_irq_enable(priv);
++ }
++}
++
++static void aspeed_mctp_channels_init(struct aspeed_mctp *priv)
++{
++ aspeed_mctp_rx_chan_init(&priv->rx);
++ aspeed_mctp_tx_chan_init(&priv->tx);
++}
++
++static irqreturn_t aspeed_mctp_irq_handler(int irq, void *arg)
++{
++ struct aspeed_mctp *priv = arg;
++ u32 handled = 0;
++ u32 status;
++
++ regmap_read(priv->map, ASPEED_MCTP_INT_STS, &status);
++ regmap_write(priv->map, ASPEED_MCTP_INT_STS, status);
++
++ if (status & TX_CMD_LAST_INT) {
++ u32 rd_ptr;
++
++ regmap_write(priv->map, ASPEED_MCTP_TX_BUF_RD_PTR,
++ UPDATE_RX_RD_PTR);
++ regmap_read(priv->map, ASPEED_MCTP_TX_BUF_RD_PTR, &rd_ptr);
++ rd_ptr &= TX_BUFFER_RD_PTR;
++
++ /*
++ * rd_ptr on TX side seems to be busted...
++ * Since we're always reading zeroes, let's trust that when
++ * we're getting LAST_CMD irq, everything we previously
++ * submitted was transmitted and start from 0
++ */
++ WRITE_ONCE(priv->tx.rd_ptr, TX_CMD_COUNT);
++
++ tasklet_hi_schedule(&priv->tx.tasklet);
++
++ wake_up_all(&priv->wait_queue);
++
++ handled |= TX_CMD_LAST_INT;
++ }
++
++ if (status & TX_CMD_WRONG_INT) {
++ /* TODO: print the actual command */
++ dev_warn(priv->dev, "TX wrong");
++
++ handled |= TX_CMD_WRONG_INT;
++ }
++
++ if (status & RX_CMD_RECEIVE_INT) {
++ u32 rd_ptr;
++
++ regmap_write(priv->map, ASPEED_MCTP_RX_BUF_RD_PTR,
++ UPDATE_RX_RD_PTR);
++ regmap_read(priv->map, ASPEED_MCTP_RX_BUF_RD_PTR, &rd_ptr);
++ rd_ptr &= RX_BUFFER_RD_PTR;
++
++ WRITE_ONCE(priv->rx.rd_ptr, rd_ptr > 0 ? rd_ptr : RX_CMD_COUNT);
++
++ tasklet_hi_schedule(&priv->rx.tasklet);
++
++ handled |= RX_CMD_RECEIVE_INT;
++ }
++
++ if (!handled)
++ return IRQ_NONE;
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t aspeed_mctp_pcie_rst_irq_handler(int irq, void *arg)
++{
++ struct aspeed_mctp *priv = arg;
++
++ aspeed_mctp_channels_init(priv);
++
++ priv->pcie.need_uevent = true;
++ priv->pcie.bdf = 0;
++
++ schedule_delayed_work(&priv->pcie.rst_dwork, 0);
++
++ return IRQ_HANDLED;
++}
++
++static void aspeed_mctp_drv_init(struct aspeed_mctp *priv)
++{
++ init_waitqueue_head(&priv->wait_queue);
++ INIT_LIST_HEAD(&priv->clients);
++
++ spin_lock_init(&priv->clients_lock);
++
++ INIT_DELAYED_WORK(&priv->pcie.rst_dwork, aspeed_mctp_reset_work);
++
++ tasklet_init(&priv->tx.tasklet, aspeed_mctp_tx_tasklet,
++ (unsigned long)&priv->tx);
++ tasklet_init(&priv->rx.tasklet, aspeed_mctp_rx_tasklet,
++ (unsigned long)&priv->rx);
++}
++
++static void aspeed_mctp_drv_fini(struct aspeed_mctp *priv)
++{
++ tasklet_disable(&priv->tx.tasklet);
++ tasklet_kill(&priv->tx.tasklet);
++ tasklet_disable(&priv->rx.tasklet);
++ tasklet_kill(&priv->rx.tasklet);
++
++ cancel_delayed_work_sync(&priv->pcie.rst_dwork);
++}
++
++static int aspeed_mctp_resources_init(struct aspeed_mctp *priv)
++{
++ struct platform_device *pdev = to_platform_device(priv->dev);
++ void __iomem *regs;
++
++ regs = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(regs)) {
++ dev_err(priv->dev, "Failed to get regmap!\n");
++ return PTR_ERR(regs);
++ }
++
++ priv->map = devm_regmap_init_mmio(priv->dev, regs,
++ &aspeed_mctp_regmap_cfg);
++ if (IS_ERR(priv->map))
++ return PTR_ERR(priv->map);
++
++ priv->reset = devm_reset_control_get(priv->dev, 0);
++ if (IS_ERR(priv->reset)) {
++ dev_err(priv->dev, "Failed to get reset!\n");
++ return PTR_ERR(priv->reset);
++ }
++
++ priv->pcie.map =
++ syscon_regmap_lookup_by_phandle(priv->dev->of_node,
++ "aspeed,pcieh");
++ if (IS_ERR(priv->pcie.map)) {
++ dev_err(priv->dev, "Failed to find PCIe Host regmap!\n");
++ return PTR_ERR(priv->pcie.map);
++ }
++
++ platform_set_drvdata(pdev, priv);
++
++ return 0;
++}
++
++static int aspeed_mctp_dma_init(struct aspeed_mctp *priv)
++{
++ struct mctp_channel *tx = &priv->tx;
++ struct mctp_channel *rx = &priv->rx;
++ int ret = -ENOMEM;
++
++ BUILD_BUG_ON(TX_CMD_COUNT >= TX_MAX_CMD_COUNT);
++ BUILD_BUG_ON(RX_CMD_COUNT >= RX_MAX_CMD_COUNT);
++
++ tx->cmd.vaddr = dma_alloc_coherent(priv->dev, TX_CMD_BUF_SIZE,
++ &tx->cmd.dma_handle, GFP_KERNEL);
++
++ if (!tx->cmd.vaddr)
++ return ret;
++
++ tx->data.vaddr = dma_alloc_coherent(priv->dev, TX_DATA_BUF_SIZE,
++ &tx->data.dma_handle, GFP_KERNEL);
++
++ if (!tx->data.vaddr)
++ goto out_tx_data;
++
++ rx->cmd.vaddr = dma_alloc_coherent(priv->dev, RX_CMD_BUF_SIZE,
++ &rx->cmd.dma_handle, GFP_KERNEL);
++
++ if (!rx->cmd.vaddr)
++ goto out_tx_cmd;
++
++ rx->data.vaddr = dma_alloc_coherent(priv->dev, RX_DATA_BUF_SIZE,
++ &rx->data.dma_handle, GFP_KERNEL);
++
++ if (!rx->data.vaddr)
++ goto out_rx_data;
++
++ return 0;
++out_rx_data:
++ dma_free_coherent(priv->dev, RX_CMD_BUF_SIZE, rx->cmd.vaddr,
++ rx->cmd.dma_handle);
++
++out_tx_cmd:
++ dma_free_coherent(priv->dev, TX_DATA_BUF_SIZE, tx->data.vaddr,
++ tx->data.dma_handle);
++
++out_tx_data:
++ dma_free_coherent(priv->dev, TX_CMD_BUF_SIZE, tx->cmd.vaddr,
++ tx->cmd.dma_handle);
++ return ret;
++}
++
++static void aspeed_mctp_dma_fini(struct aspeed_mctp *priv)
++{
++ struct mctp_channel *tx = &priv->tx;
++ struct mctp_channel *rx = &priv->rx;
++
++ dma_free_coherent(priv->dev, TX_CMD_BUF_SIZE, tx->cmd.vaddr,
++ tx->cmd.dma_handle);
++
++ dma_free_coherent(priv->dev, RX_CMD_BUF_SIZE, rx->cmd.vaddr,
++ rx->cmd.dma_handle);
++
++ dma_free_coherent(priv->dev, TX_DATA_BUF_SIZE, tx->data.vaddr,
++ tx->data.dma_handle);
++
++ dma_free_coherent(priv->dev, RX_DATA_BUF_SIZE, rx->data.vaddr,
++ rx->data.dma_handle);
++}
++
++static int aspeed_mctp_irq_init(struct aspeed_mctp *priv)
++{
++ struct platform_device *pdev = to_platform_device(priv->dev);
++ int irq, ret;
++
++ irq = platform_get_irq(pdev, 0);
++ if (!irq)
++ return -ENODEV;
++
++ ret = devm_request_irq(priv->dev, irq, aspeed_mctp_irq_handler,
++ IRQF_SHARED, "aspeed-mctp", priv);
++ if (ret)
++ return ret;
++
++ irq = platform_get_irq(pdev, 1);
++ if (!irq)
++ return -ENODEV;
++
++ ret = devm_request_irq(priv->dev, irq,
++ aspeed_mctp_pcie_rst_irq_handler,
++ IRQF_SHARED, "aspeed-mctp", priv);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
++static void aspeed_mctp_hw_reset(struct aspeed_mctp *priv)
++{
++ if (reset_control_assert(priv->reset) != 0)
++ dev_warn(priv->dev, "Failed to assert reset\n");
++
++ if (reset_control_deassert(priv->reset) != 0)
++ dev_warn(priv->dev, "Failed to deassert reset\n");
++}
++
++static int aspeed_mctp_probe(struct platform_device *pdev)
++{
++ struct aspeed_mctp *priv;
++ int ret;
++
++ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ priv->dev = &pdev->dev;
++
++ aspeed_mctp_drv_init(priv);
++
++ ret = aspeed_mctp_resources_init(priv);
++ if (ret) {
++ dev_err(priv->dev, "Failed to init resources\n");
++ goto out_drv;
++ }
++
++ ret = aspeed_mctp_dma_init(priv);
++ if (ret) {
++ dev_err(priv->dev, "Failed to init DMA\n");
++ goto out_drv;
++ }
++
++ /*
++ * FIXME: We need to verify how to make the reset work when we probe
++ * multiple times. Currently calling reset more than once seems to make
++ * the HW upset, however, we do need to reset after boot before we're
++ * able to use the HW.
++ */
++ aspeed_mctp_hw_reset(priv);
++
++ aspeed_mctp_channels_init(priv);
++
++ aspeed_mctp_miscdev.parent = priv->dev;
++ ret = misc_register(&aspeed_mctp_miscdev);
++ if (ret) {
++ dev_err(priv->dev, "Failed to register miscdev\n");
++ goto out_dma;
++ }
++ aspeed_mctp_miscdev.this_device->type = &aspeed_mctp_type;
++
++ ret = aspeed_mctp_irq_init(priv);
++ if (ret) {
++ dev_err(priv->dev, "Failed to init IRQ!\n");
++ goto out_dma;
++ }
++
++ aspeed_mctp_irq_enable(priv);
++
++ aspeed_mctp_pcie_setup(priv);
++
++ return 0;
++
++out_dma:
++ aspeed_mctp_dma_fini(priv);
++out_drv:
++ aspeed_mctp_drv_fini(priv);
++out:
++ dev_err(priv->dev, "Failed to probe Aspeed MCTP: %d\n", ret);
++ return ret;
++}
++
++static int aspeed_mctp_remove(struct platform_device *pdev)
++{
++ struct aspeed_mctp *priv = platform_get_drvdata(pdev);
++
++ misc_deregister(&aspeed_mctp_miscdev);
++
++ aspeed_mctp_irq_disable(priv);
++
++ aspeed_mctp_dma_fini(priv);
++
++ aspeed_mctp_drv_fini(priv);
++
++ return 0;
++}
++
++static const struct of_device_id aspeed_mctp_match_table[] = {
++ { .compatible = "aspeed,ast2600-mctp" },
++ { }
++};
++
++static struct platform_driver aspeed_mctp_driver = {
++ .driver = {
++ .name = "aspeed-mctp",
++ .of_match_table = of_match_ptr(aspeed_mctp_match_table),
++ },
++ .probe = aspeed_mctp_probe,
++ .remove = aspeed_mctp_remove,
++};
++
++static int __init aspeed_mctp_init(void)
++{
++ packet_cache =
++ kmem_cache_create_usercopy("mctp-packet",
++ sizeof(struct mctp_pcie_packet),
++ 0, 0, 0,
++ sizeof(struct mctp_pcie_packet),
++ NULL);
++ if (!packet_cache)
++ return -ENOMEM;
++
++ return platform_driver_register(&aspeed_mctp_driver);
++}
++
++static void __exit aspeed_mctp_exit(void)
++{
++ platform_driver_unregister(&aspeed_mctp_driver);
++ kmem_cache_destroy(packet_cache);
++}
++
++module_init(aspeed_mctp_init)
++module_exit(aspeed_mctp_exit)
++
++MODULE_DEVICE_TABLE(of, aspeed_mctp_match_table);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska@intel.com>");
++MODULE_DESCRIPTION("Aspeed AST2600 MCTP driver");
+diff --git a/include/uapi/linux/aspeed-mctp.h b/include/uapi/linux/aspeed-mctp.h
+new file mode 100644
+index 000000000000..e37fa3afde9d
+--- /dev/null
++++ b/include/uapi/linux/aspeed-mctp.h
+@@ -0,0 +1,72 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/* Copyright (c) 2020 Intel Corporation */
++
++#ifndef _UAPI_LINUX_ASPEED_MCTP_H
++#define _UAPI_LINUX_ASPEED_MCTP_H
++
++#include <linux/ioctl.h>
++#include <linux/types.h>
++
++/*
++ * aspeed-mctp is a simple device driver exposing a read/write interface:
++ * +----------------------+
++ * | PCIe VDM Header | 16 bytes (Big Endian)
++ * +----------------------+
++ * | MCTP Message Payload | 64/128/256/512 bytes (Little Endian)
++ * +----------------------+
++ *
++ * MCTP packet description can be found in DMTF DSP0238,
++ * MCTP PCIe VDM Transport Specification.
++ *
++ * Note: AST2600 hardware follows MCTP Message Payload rules from earlier
++ * hardware and we've decided to copy the packets directly, without swapping.
++ * This means that it's userspace responsibility to provide the data in
++ * a format that the hardware expects.
++ */
++
++#define ASPEED_MCTP_PCIE_VDM_HDR_SIZE 16
++
++/*
++ * uevents generated by aspeed-mctp driver
++ */
++#define ASPEED_MCTP_READY "PCIE_READY"
++
++/*
++ * MCTP operations
++ * @ASPEED_MCTP_IOCTL_FILTER_EID: enable/disable filter incoming packets based
++ * on Endpoint ID (BROKEN)
++ * @ASPEED_MCTP_IOCTL_GET_BDF: read PCI bus/device/function of MCTP Controller
++ * @ASPEED_MCTP_IOCTL_GET_MEDIUM_ID: read MCTP physical medium identifier
++ * related to PCIe revision
++ * @ASPEED_MCTP_IOCTL_GET_MTU: read max transmission unit (in bytes)
++ */
++
++struct aspeed_mctp_filter_eid {
++ __u8 eid;
++ bool enable;
++};
++
++struct aspeed_mctp_get_bdf {
++ __u16 bdf;
++};
++
++struct aspeed_mctp_get_medium_id {
++ __u8 medium_id;
++};
++
++struct aspeed_mctp_get_mtu {
++ __u8 mtu;
++};
++
++#define ASPEED_MCTP_IOCTL_BASE 0x4d
++
++#define ASPEED_MCTP_IOCTL_FILTER_EID \
++ _IOW(ASPEED_MCTP_IOCTL_BASE, 0, struct aspeed_mctp_filter_eid)
++#define ASPEED_MCTP_IOCTL_GET_BDF \
++ _IOR(ASPEED_MCTP_IOCTL_BASE, 1, struct aspeed_mctp_get_bdf)
++#define ASPEED_MCTP_IOCTL_GET_MEDIUM_ID \
++ _IOR(ASPEED_MCTP_IOCTL_BASE, 2, struct aspeed_mctp_get_medium_id)
++#define ASPEED_MCTP_IOCTL_GET_MTU \
++ _IOR(ASPEED_MCTP_IOCTL_BASE, 3, struct aspeed_mctp_get_mtu)
++
++#endif /* _UAPI_LINUX_ASPEED_MCTP_H */
+--
+2.21.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0109-signal-Extend-exec_id-to-64bits.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0109-signal-Extend-exec_id-to-64bits.patch
new file mode 100644
index 000000000..7d879ab82
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0109-signal-Extend-exec_id-to-64bits.patch
@@ -0,0 +1,88 @@
+From 5f2d04139aa5ed04eab54b84e8a25bab87a2449c Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Mon, 30 Mar 2020 19:01:04 -0500
+Subject: [PATCH] signal: Extend exec_id to 64bits
+
+commit d1e7fd6462ca9fc76650fbe6ca800e35b24267da upstream.
+
+Replace the 32bit exec_id with a 64bit exec_id to make it impossible
+to wrap the exec_id counter. With care an attacker can cause exec_id
+wrap and send arbitrary signals to a newly exec'd parent. This
+bypasses the signal sending checks if the parent changes their
+credentials during exec.
+
+The severity of this problem can been seen that in my limited testing
+of a 32bit exec_id it can take as little as 19s to exec 65536 times.
+Which means that it can take as little as 14 days to wrap a 32bit
+exec_id. Adam Zabrocki has succeeded wrapping the self_exe_id in 7
+days. Even my slower timing is in the uptime of a typical server.
+Which means self_exec_id is simply a speed bump today, and if exec
+gets noticably faster self_exec_id won't even be a speed bump.
+
+Extending self_exec_id to 64bits introduces a problem on 32bit
+architectures where reading self_exec_id is no longer atomic and can
+take two read instructions. Which means that is is possible to hit
+a window where the read value of exec_id does not match the written
+value. So with very lucky timing after this change this still
+remains expoiltable.
+
+I have updated the update of exec_id on exec to use WRITE_ONCE
+and the read of exec_id in do_notify_parent to use READ_ONCE
+to make it clear that there is no locking between these two
+locations.
+
+Link: https://lore.kernel.org/kernel-hardening/20200324215049.GA3710@pi3.com.pl
+Fixes: 2.3.23pre2
+Cc: stable@vger.kernel.org
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/exec.c | 2 +-
+ include/linux/sched.h | 4 ++--
+ kernel/signal.c | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/fs/exec.c b/fs/exec.c
+index c27231234764..fc2870f2aca9 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -1383,7 +1383,7 @@ void setup_new_exec(struct linux_binprm * bprm)
+
+ /* An exec changes our domain. We are no longer part of the thread
+ group */
+- current->self_exec_id++;
++ WRITE_ONCE(current->self_exec_id, current->self_exec_id + 1);
+ flush_signal_handlers(current, 0);
+ }
+ EXPORT_SYMBOL(setup_new_exec);
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index b968d736833b..5710b80f8050 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -934,8 +934,8 @@ struct task_struct {
+ struct seccomp seccomp;
+
+ /* Thread group tracking: */
+- u32 parent_exec_id;
+- u32 self_exec_id;
++ u64 parent_exec_id;
++ u64 self_exec_id;
+
+ /* Protection against (de-)allocation: mm, files, fs, tty, keyrings, mems_allowed, mempolicy: */
+ spinlock_t alloc_lock;
+diff --git a/kernel/signal.c b/kernel/signal.c
+index eea748174ade..7d3d35eb7a0b 100644
+--- a/kernel/signal.c
++++ b/kernel/signal.c
+@@ -1931,7 +1931,7 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
+ * This is only possible if parent == real_parent.
+ * Check if it has changed security domain.
+ */
+- if (tsk->parent_exec_id != tsk->parent->self_exec_id)
++ if (tsk->parent_exec_id != READ_ONCE(tsk->parent->self_exec_id))
+ sig = SIGCHLD;
+ }
+
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0110-USB-gadget-fix-illegal-array-access-in-binding-with-.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0110-USB-gadget-fix-illegal-array-access-in-binding-with-.patch
new file mode 100644
index 000000000..542d80e16
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0110-USB-gadget-fix-illegal-array-access-in-binding-with-.patch
@@ -0,0 +1,75 @@
+From 15753588bcd4bbffae1cca33c8ced5722477fe1f Mon Sep 17 00:00:00 2001
+From: Kyungtae Kim <kt0755@gmail.com>
+Date: Sun, 10 May 2020 05:43:34 +0000
+Subject: [PATCH] USB: gadget: fix illegal array access in binding with UDC
+
+FuzzUSB (a variant of syzkaller) found an illegal array access
+using an incorrect index while binding a gadget with UDC.
+
+Reference: https://www.spinics.net/lists/linux-usb/msg194331.html
+
+This bug occurs when a size variable used for a buffer
+is misused to access its strcpy-ed buffer.
+Given a buffer along with its size variable (taken from user input),
+from which, a new buffer is created using kstrdup().
+Due to the original buffer containing 0 value in the middle,
+the size of the kstrdup-ed buffer becomes smaller than that of the original.
+So accessing the kstrdup-ed buffer with the same size variable
+triggers memory access violation.
+
+The fix makes sure no zero value in the buffer,
+by comparing the strlen() of the orignal buffer with the size variable,
+so that the access to the kstrdup-ed buffer is safe.
+
+BUG: KASAN: slab-out-of-bounds in gadget_dev_desc_UDC_store+0x1ba/0x200
+drivers/usb/gadget/configfs.c:266
+Read of size 1 at addr ffff88806a55dd7e by task syz-executor.0/17208
+
+CPU: 2 PID: 17208 Comm: syz-executor.0 Not tainted 5.6.8 #1
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0xce/0x128 lib/dump_stack.c:118
+ print_address_description.constprop.4+0x21/0x3c0 mm/kasan/report.c:374
+ __kasan_report+0x131/0x1b0 mm/kasan/report.c:506
+ kasan_report+0x12/0x20 mm/kasan/common.c:641
+ __asan_report_load1_noabort+0x14/0x20 mm/kasan/generic_report.c:132
+ gadget_dev_desc_UDC_store+0x1ba/0x200 drivers/usb/gadget/configfs.c:266
+ flush_write_buffer fs/configfs/file.c:251 [inline]
+ configfs_write_file+0x2f1/0x4c0 fs/configfs/file.c:283
+ __vfs_write+0x85/0x110 fs/read_write.c:494
+ vfs_write+0x1cd/0x510 fs/read_write.c:558
+ ksys_write+0x18a/0x220 fs/read_write.c:611
+ __do_sys_write fs/read_write.c:623 [inline]
+ __se_sys_write fs/read_write.c:620 [inline]
+ __x64_sys_write+0x73/0xb0 fs/read_write.c:620
+ do_syscall_64+0x9e/0x510 arch/x86/entry/common.c:294
+ entry_SYSCALL_64_after_hwframe+0x49/0xbe
+
+Signed-off-by: Kyungtae Kim <kt0755@gmail.com>
+Reported-and-tested-by: Kyungtae Kim <kt0755@gmail.com>
+Cc: Felipe Balbi <balbi@kernel.org>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200510054326.GA19198@pizza01
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/configfs.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
+index 32b637e3e1fa..6a9aa4413d64 100644
+--- a/drivers/usb/gadget/configfs.c
++++ b/drivers/usb/gadget/configfs.c
+@@ -260,6 +260,9 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item,
+ char *name;
+ int ret;
+
++ if (strlen(page) < len)
++ return -EOVERFLOW;
++
+ name = kstrdup(page, GFP_KERNEL);
+ if (!name)
+ return -ENOMEM;
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend
index 1f3085503..f1d781f6f 100644
--- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend
@@ -76,6 +76,11 @@ SRC_URI += " \
file://0103-Refine-clock-settings.patch \
file://0104-Add-chip-unique-id-reading-interface.patch \
file://0105-i2c-aspeed-fix-arbitration-loss-handling-logic.patch \
+ file://0106-enable-AST2600-I3C.patch \
+ file://0107-arm-dts-aspeed-g6-Add-ast2600-mctp-node.patch \
+ file://0108-soc-aspeed-mctp-Add-initial-driver-for-ast2600-mctp.patch \
+ file://0109-signal-Extend-exec_id-to-64bits.patch \
+ file://0110-USB-gadget-fix-illegal-array-access-in-binding-with-.patch \
"
SRC_URI += "${@bb.utils.contains('IMAGE_FSTYPES', 'intel-pfr', 'file://0005-128MB-flashmap-for-PFR.patch', '', d)}"
diff --git a/meta-openbmc-mods/meta-common/recipes-network/network/static-mac-addr/mac-check b/meta-openbmc-mods/meta-common/recipes-network/network/static-mac-addr/mac-check
index 639b6c5ee..7e81ad63a 100644
--- a/meta-openbmc-mods/meta-common/recipes-network/network/static-mac-addr/mac-check
+++ b/meta-openbmc-mods/meta-common/recipes-network/network/static-mac-addr/mac-check
@@ -13,9 +13,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+SOFS_MNT=/var/sofs
+SOFS_MACDIR=${SOFS_MNT}/factory-settings/network/mac
+
read_hw_mac() {
local iface="$1"
- cat /sys/class/net/"$iface"/address
+ cat /sys/class/net/"$iface"/address 2>/dev/null
}
set_hw_mac() {
@@ -28,10 +31,9 @@ set_hw_mac() {
[[ $up -eq 0 ]] && ip link set dev "$iface" up
}
-SOFS_MNT=/var/sofs
read_sofs_mac() {
local iface="$1"
- cat "${SOFS_MNT}/factory-settings/network/mac/${iface}" 2>/dev/null
+ cat "${SOFS_MACDIR}/${iface}" 2>/dev/null
}
read_fw_env_mac() {
@@ -45,35 +47,63 @@ set_fw_env_mac() {
fw_setenv "$envname" "$mac"
}
+create_macdir() {
+if [ -a ${SOFS_MACDIR} ]; then
+ if [ ! -d ${SOFS_MACDIR} ]; then
+ rm -rf ${SOFS_MACDIR}
+ mkdir -p ${SOFS_MACDIR}
+ fi
+else
+ mkdir -p ${SOFS_MACDIR}
+fi
+return 0
+}
+
mac_check() {
local iface="$1"
local envname="$2"
- # read current HW MAC addr
+ # Read the MAC address in use by the NIC
local hw_mac=$(read_hw_mac "$iface")
- # read saved sofs MAC addr
+ # Read the MAC address stored in the non-volatile file provisioned in
+ # manufacturing.
local sofs_mac=$(read_sofs_mac "$iface")
- # if set and not the same as HW addr, set HW addr
if [ -n "$sofs_mac" ] && [ "$hw_mac" != "$sofs_mac" ]; then
+ # A factory assigned address was found, and it is newly assigned.
+ # Update the active interface and save the new value to the u-boot
+ # environment.
set_hw_mac "$iface" "$sofs_mac"
- hw_mac="$sofs_mac"
+ set_fw_env_mac "$envname" "$sofs_mac"
+ return $?
+ elif [ -n "$hw_mac" ]; then
+ # Read the MAC address stored by U-Boot
+ local fw_env_mac=$(read_fw_env_mac "$envname")
+ if [ -z "$fw_env_mac" ] || [ "$fw_env_mac" != "$hw_mac" ]; then
+ set_fw_env_mac "$envname" "$hw_mac"
+ return $?
+ fi
+ else
+ # Could not identify a MAC address
+ return 255
fi
+ return 0
+}
- # read saved fw_env MAC addr
- local fw_env_mac=$(read_fw_env_mac "$envname")
+create_macdir
- # save to fw_env if not the same as HW addr
- if [ -z "$fw_env_mac" ] || [ "$fw_env_mac" != "$hw_mac" ]; then
- set_fw_env_mac "$envname" "$hw_mac"
- fi
-}
+error=0
+first_error_seen=0
-mkdir -p ${SOFS_MNT}/factory-settings/network/mac
while read IFACE UBDEV; do
mac_check "$IFACE" "$UBDEV"
+ error=$?
+ if [ $error -ne 0 ] && [ $first_error_seen -eq 0 ]; then
+ first_error_seen=$error
+ fi
done <<-END_CONF
eth0 eth1addr
eth1 ethaddr
END_CONF
+exit $first_error_seen
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
index 01c9ead9f..577e5aaaa 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend
@@ -1,6 +1,6 @@
# this is here just to bump faster than upstream
SRC_URI = "git://github.com/openbmc/entity-manager.git"
-SRCREV = "2539ccd113174d37feb1b0c036f97ada68f541e7"
+SRCREV = "fa8d322d08743b3ca0e6f575011814058e18f011"
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
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
index 91f3d8311..762efe2b4 100644
--- 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
@@ -1,5 +1,5 @@
SRC_URI = "git://github.com/openbmc/phosphor-dbus-interfaces.git"
-SRCREV = "00c8527a40650650d2826d77b6e4e6d48f68f622"
+SRCREV = "fdd88281dd243b3b9e6140b3f7b59aaaa188f37e"
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
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
index aa5d900e0..355261e8f 100644
--- 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
@@ -1,26 +1,27 @@
-From 7f29c255dd2af7fa6d38b02ad63a8b8940fbce84 Mon Sep 17 00:00:00 2001
+From 32d90301c494c1b43f8e1d74ac9e7c1dc2fe486a 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
+Subject: [PATCH 1/1] 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
+Signed-off-by: James Feist <james.feist@linux.intel.com>
---
- activation.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ activation.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++
configure.ac | 7 +++++++
static/flash.cpp | 41 +++++++++++++++++++++++++++++++++++++++--
ubi/flash.cpp | 9 +++------
- 4 files changed, 93 insertions(+), 8 deletions(-)
+ 4 files changed, 92 insertions(+), 8 deletions(-)
diff --git a/activation.cpp b/activation.cpp
-index f918221..f2923ae 100644
+index ab76420..91e3a10 100644
--- a/activation.cpp
+++ b/activation.cpp
-@@ -163,6 +163,50 @@ auto Activation::activation(Activations value) -> Activations
+@@ -200,6 +200,49 @@ auto Activation::activation(Activations value) -> Activations
softwareServer::Activation::Activations::Active);
}
}
@@ -48,7 +49,6 @@ index f918221..f2923ae 100644
+ }
+#endif
+ flashWrite();
-+ activationProgress->progress(10);
+ }
+ else if (activationProgress->progress() == 100)
+ {
@@ -72,12 +72,12 @@ index f918221..f2923ae 100644
#ifdef WANT_SIGNATURE_VERIFY
diff --git a/configure.ac b/configure.ac
-index 2da97ad..720e704 100755
+index 5fba420..3b5fdab 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"])
+@@ -194,6 +194,13 @@ AS_IF([test "x$enable_host_bios_upgrade" == "xyes"], \
+ [AC_DEFINE([HOST_BIOS_UPGRADE],[],[Enable host bios upgrade support.])])
+ AM_CONDITIONAL([HOST_BIOS_UPGRADE], [test "x$enable_host_bios_upgrade" == "xyes"])
+# setup fwupd script support
+AC_ARG_ENABLE([fwupd_script],
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend
index c9f95121f..9824210cd 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend
@@ -1,6 +1,6 @@
# todo(james) remove nobranch
SRC_URI = "git://github.com/openbmc/bmcweb.git"
-SRCREV = "8a3bb71ebcdf14dafd5967192f73bf2416e8bb6e"
+SRCREV = "7d1cc387d312e2a8e4844f9d69ab39b042acd5ce"
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-ipmb/0001-Add-dbus-method-SlotIpmbRequest.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-ipmb/0001-Add-dbus-method-SlotIpmbRequest.patch
new file mode 100644
index 000000000..3f01cd2c8
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-ipmb/0001-Add-dbus-method-SlotIpmbRequest.patch
@@ -0,0 +1,536 @@
+From 644165bf32fd6e757c261881987d127a865cbf2b Mon Sep 17 00:00:00 2001
+From: Rajashekar Gade Reddy <raja.sekhar.reddy.gade@linux.intel.com>
+Date: Mon, 23 Mar 2020 22:19:07 +0530
+Subject: [PATCH] Add dbus method SlotIpmbRequest
+
+Added dbus method SlotIpmbRequest which enables the applications to
+communicate with add-in cards.
+
+This is submitted in down stream because SlotIpmbRequest uses hold and
+unhold mux kernel patches which are downstream only patches.
+
+Tested:
+
+busctl call xyz.openbmc_project.Ipmi.Channel.Ipmb
+/xyz/openbmc_project/Ipmi/Channel/Ipmb org.openbmc.Ipmb SlotIpmbRequest
+"yyyyyay" <valid_addressType> <valid_slot> <valid_slaveAddr> <valid_netFun> <valid_cmd> <data> // method call
+(iyyyyay) 0 7 0 1 0 15 0 0 0 0 2 12 87 1 0 0 0 0 0 0 0 // success
+
+busctl call xyz.openbmc_project.Ipmi.Channel.Ipmb
+/xyz/openbmc_project/Ipmi/Channel/Ipmb org.openbmc.Ipmb SlotIpmbRequest
+"yyyyyay" <valid_addressType> <invalid_slot> <valid_slaveAddr> <valid_netFun> <valid_cmd> <data> // method call
+(iyyyyay) 4 0 0 0 0 0 // failure
+
+busctl call xyz.openbmc_project.Ipmi.Channel.Ipmb
+/xyz/openbmc_project/Ipmi/Channel/Ipmb org.openbmc.Ipmb SlotIpmbRequest
+"yyyyyay" <valid_addressType> <valid_slot> <invalid_slaveAddr> <valid_netFun> <valid_cmd> <data> // method call
+(iyyyyay) 4 0 0 0 0 0 // failure
+
+//This ipmi command internally calls the dbus method SlotIpmbRequest.
+ipmitool raw 0x3e 0x51 0 0x01 0xb0 0x6 1
+00 00 00 00 00 02 0c 57 01 00 00 00 00 00 00 00 //success
+
+Note: Tested for all possible negative test cases and it works fine.
+
+Signed-off-by: Rajashekar Gade Reddy <raja.sekhar.reddy.gade@intel.com>
+
+%% original patch: 0001-Add-dbus-method-SlotIpmbRequest.patch
+---
+ CMakeLists.txt | 2 +-
+ include/linux/i2c.h | 159 ++++++++++++++++++++++++++++++++
+ ipmb-channels.json | 6 ++
+ ipmbbridged.cpp | 220 +++++++++++++++++++++++++++++++++++++++++++-
+ ipmbbridged.hpp | 8 +-
+ 5 files changed, 391 insertions(+), 4 deletions(-)
+ create mode 100644 include/linux/i2c.h
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 80377f5..1436d5e 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -5,7 +5,7 @@ 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})
++include_directories (${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include)
+ find_package (Boost REQUIRED)
+ include_directories (${Boost_INCLUDE_DIRS})
+ add_definitions (-DBOOST_ERROR_CODE_HEADER_ONLY)
+diff --git a/include/linux/i2c.h b/include/linux/i2c.h
+new file mode 100644
+index 0000000..a1db9b1
+--- /dev/null
++++ b/include/linux/i2c.h
+@@ -0,0 +1,159 @@
++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
++/* ------------------------------------------------------------------------- */
++/* */
++/* i2c.h - definitions for the i2c-bus interface */
++/* */
++/* ------------------------------------------------------------------------- */
++/* Copyright (C) 1995-2000 Simon G. Vogl
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
++ MA 02110-1301 USA. */
++/* ------------------------------------------------------------------------- */
++
++/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
++ Frodo Looijaard <frodol@dds.nl> */
++
++#ifndef _UAPI_LINUX_I2C_H
++#define _UAPI_LINUX_I2C_H
++
++#include <linux/types.h>
++
++/**
++ * struct i2c_msg - an I2C transaction segment beginning with START
++ * @addr: Slave address, either seven or ten bits. When this is a ten
++ * bit address, I2C_M_TEN must be set in @flags and the adapter
++ * must support I2C_FUNC_10BIT_ADDR.
++ * @flags: I2C_M_RD is handled by all adapters. No other flags may be
++ * provided unless the adapter exported the relevant I2C_FUNC_*
++ * flags through i2c_check_functionality().
++ * @len: Number of data bytes in @buf being read from or written to the
++ * I2C slave address. For read transactions where I2C_M_RECV_LEN
++ * is set, the caller guarantees that this buffer can hold up to
++ * 32 bytes in addition to the initial length byte sent by the
++ * slave (plus, if used, the SMBus PEC); and this value will be
++ * incremented by the number of block data bytes received.
++ * @buf: The buffer into which data is read, or from which it's written.
++ *
++ * An i2c_msg is the low level representation of one segment of an I2C
++ * transaction. It is visible to drivers in the @i2c_transfer() procedure,
++ * to userspace from i2c-dev, and to I2C adapter drivers through the
++ * @i2c_adapter.@master_xfer() method.
++ *
++ * Except when I2C "protocol mangling" is used, all I2C adapters implement
++ * the standard rules for I2C transactions. Each transaction begins with a
++ * START. That is followed by the slave address, and a bit encoding read
++ * versus write. Then follow all the data bytes, possibly including a byte
++ * with SMBus PEC. The transfer terminates with a NAK, or when all those
++ * bytes have been transferred and ACKed. If this is the last message in a
++ * group, it is followed by a STOP. Otherwise it is followed by the next
++ * @i2c_msg transaction segment, beginning with a (repeated) START.
++ *
++ * Alternatively, when the adapter supports I2C_FUNC_PROTOCOL_MANGLING then
++ * passing certain @flags may have changed those standard protocol behaviors.
++ * Those flags are only for use with broken/nonconforming slaves, and with
++ * adapters which are known to support the specific mangling options they
++ * need (one or more of IGNORE_NAK, NO_RD_ACK, NOSTART, and REV_DIR_ADDR).
++ */
++struct i2c_msg {
++ __u16 addr; /* slave address */
++ __u16 flags;
++#define I2C_M_RD 0x0001 /* read data, from slave to master */
++ /* I2C_M_RD is guaranteed to be 0x0001! */
++#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
++#define I2C_M_HOLD 0x0100 /* for holding a mux path */
++#define I2C_M_DMA_SAFE 0x0200 /* the buffer of this message is DMA safe */
++ /* makes only sense in kernelspace */
++ /* userspace buffers are copied anyway */
++#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
++#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
++#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
++#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
++#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */
++#define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */
++ __u16 len; /* msg length */
++ __u8 *buf; /* pointer to msg data */
++};
++
++/* To determine what functionality is present */
++
++#define I2C_FUNC_I2C 0x00000001
++#define I2C_FUNC_10BIT_ADDR 0x00000002
++#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_IGNORE_NAK etc. */
++#define I2C_FUNC_SMBUS_PEC 0x00000008
++#define I2C_FUNC_NOSTART 0x00000010 /* I2C_M_NOSTART */
++#define I2C_FUNC_SLAVE 0x00000020
++#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
++#define I2C_FUNC_SMBUS_QUICK 0x00010000
++#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000
++#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000
++#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000
++#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
++#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000
++#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
++#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000
++#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
++#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
++#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */
++#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
++#define I2C_FUNC_SMBUS_HOST_NOTIFY 0x10000000
++
++#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
++ I2C_FUNC_SMBUS_WRITE_BYTE)
++#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
++ I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
++#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \
++ I2C_FUNC_SMBUS_WRITE_WORD_DATA)
++#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
++ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
++#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
++ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
++
++#define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \
++ I2C_FUNC_SMBUS_BYTE | \
++ I2C_FUNC_SMBUS_BYTE_DATA | \
++ I2C_FUNC_SMBUS_WORD_DATA | \
++ I2C_FUNC_SMBUS_PROC_CALL | \
++ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
++ I2C_FUNC_SMBUS_I2C_BLOCK | \
++ I2C_FUNC_SMBUS_PEC)
++
++/*
++ * Data for SMBus Messages
++ */
++#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */
++union i2c_smbus_data {
++ __u8 byte;
++ __u16 word;
++ __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
++ /* and one more for user-space compatibility */
++};
++
++/* i2c_smbus_xfer read or write markers */
++#define I2C_SMBUS_READ 1
++#define I2C_SMBUS_WRITE 0
++
++/* SMBus transaction types (size parameter in the above functions)
++ Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
++#define I2C_SMBUS_QUICK 0
++#define I2C_SMBUS_BYTE 1
++#define I2C_SMBUS_BYTE_DATA 2
++#define I2C_SMBUS_WORD_DATA 3
++#define I2C_SMBUS_PROC_CALL 4
++#define I2C_SMBUS_BLOCK_DATA 5
++#define I2C_SMBUS_I2C_BLOCK_BROKEN 6
++#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
++#define I2C_SMBUS_I2C_BLOCK_DATA 8
++
++#endif /* _UAPI_LINUX_I2C_H */
+diff --git a/ipmb-channels.json b/ipmb-channels.json
+index 0876db7..ff570c6 100644
+--- a/ipmb-channels.json
++++ b/ipmb-channels.json
+@@ -11,6 +11,12 @@
+ "slave-path": "/dev/ipmb-0",
+ "bmc-addr": 32,
+ "remote-addr": 88
++ },
++ {
++ "type": "slot-ipmb",
++ "slave-path": "/dev/ipmb-6",
++ "bmc-addr": 18,
++ "remote-addr": 176
+ }
+ ]
+ }
+diff --git a/ipmbbridged.cpp b/ipmbbridged.cpp
+index e0eadfc..72ede8c 100644
+--- a/ipmbbridged.cpp
++++ b/ipmbbridged.cpp
+@@ -18,6 +18,11 @@
+ #include "ipmbdefines.hpp"
+ #include "ipmbutils.hpp"
+
++#include <i2c/smbus.h>
++#include <linux/i2c-dev.h>
++#include <linux/i2c.h>
++#include <sys/ioctl.h>
++
+ #include <boost/algorithm/string/replace.hpp>
+ #include <filesystem>
+ #include <fstream>
+@@ -39,7 +44,8 @@ auto conn = std::make_shared<sdbusplus::asio::connection>(io);
+ static std::list<IpmbChannel> ipmbChannels;
+ static const std::unordered_map<std::string, ipmbChannelType>
+ ipmbChannelTypeMap = {{"me", ipmbChannelType::me},
+- {"ipmb", ipmbChannelType::ipmb}};
++ {"ipmb", ipmbChannelType::ipmb},
++ {"slot-ipmb", ipmbChannelType::slot_ipmb}};
+
+ /**
+ * @brief Ipmb request class methods
+@@ -551,7 +557,10 @@ int IpmbChannel::ipmbChannelInit(const char *ipmbI2cSlave)
+ {
+ std::string deviceFileName =
+ "/sys/bus/i2c/devices/i2c-" + busStr + "/new_device";
+- std::string para = "ipmb-dev 0x1010"; // init with BMC addr 0x20
++ std::ostringstream param;
++ param << "ipmb-dev 0x" << std::hex
++ << static_cast<uint16_t>(0x1000 | (ipmbBmcSlaveAddress >> 1));
++ std::string para(param.str());
+ std::fstream deviceFile;
+ deviceFile.open(deviceFileName, std::ios::out);
+ if (!deviceFile.good())
+@@ -697,6 +706,171 @@ void IpmbChannel::addFilter(const uint8_t respNetFn, const uint8_t cmd)
+ }
+ }
+
++class Mux
++{
++ public:
++ Mux(const std::string &path) : heldMux(false)
++ {
++ fd = open(path.c_str(), O_RDWR | O_NONBLOCK);
++ }
++ ~Mux()
++ {
++ if (heldMux)
++ {
++ if (unholdMux() < 0)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error while unholding the bus");
++ }
++ }
++ if (!(fd < 0))
++ {
++ close(fd);
++ }
++ }
++
++ int transferAndHoldMux(const uint8_t slaveAddr, uint8_t *buffer,
++ const uint8_t len, uint16_t timeout)
++ {
++ if (!isMuxFdOpen())
++ {
++ return -1;
++ }
++ struct i2c_msg holdmsg[2] = {
++ {slaveAddr, 0, len, buffer},
++ {0, I2C_M_HOLD, sizeof(timeout), (uint8_t *)&timeout}};
++
++ struct i2c_rdwr_ioctl_data msgrdwr = {&holdmsg[0], 2};
++
++ int retVal = ioctl(fd, I2C_RDWR, &msgrdwr);
++ if (retVal >= 0)
++ {
++ heldMux = true;
++ }
++ return retVal;
++ }
++
++ bool isMuxFdOpen()
++ {
++ if (fd < 0)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error while opening the mux device file");
++ return false;
++ }
++ return true;
++ }
++
++ private:
++ int unholdMux()
++ {
++ if (!isMuxFdOpen())
++ {
++ return -1;
++ }
++ uint16_t holdtimeout = 0; // unhold the bus
++
++ struct i2c_msg holdmsg = {0, I2C_M_HOLD, sizeof(holdtimeout),
++ (uint8_t *)&holdtimeout};
++
++ struct i2c_rdwr_ioctl_data msgrdwr = {&holdmsg, 1};
++
++ return ioctl(fd, I2C_RDWR, &msgrdwr);
++ }
++
++ int fd;
++ bool heldMux;
++};
++
++std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>
++ IpmbChannel::slotRequestAdd(boost::asio::yield_context &yield,
++ std::shared_ptr<IpmbRequest> request,
++ const uint8_t pcieSlot)
++{
++ makeRequestValid(request);
++ std::filesystem::path p =
++ "/dev/i2c-mux/PCIE_Mux/Pcie_Slot_" + std::to_string(pcieSlot);
++
++ if (!std::filesystem::exists(p) || !std::filesystem::is_symlink(p))
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "does not exist or not a symlink ",
++ phosphor::logging::entry("File:%s", p.c_str()));
++ return returnStatus(ipmbResponseStatus::error);
++ }
++
++ Mux mux(p);
++ if (!mux.isMuxFdOpen())
++ {
++ return returnStatus(ipmbResponseStatus::error);
++ }
++
++ std::vector<uint8_t> buffer(0);
++ if (request->ipmbToi2cConstruct(buffer) != 0)
++ {
++ return returnStatus(ipmbResponseStatus::error);
++ }
++
++ uint8_t size = buffer.size();
++
++ const uint8_t slaveAddrIndex = 1;
++ const uint8_t slotIpmbHeader = 2;
++
++ for (int i = 0; i < ipmbNumberOfTries; i++)
++ {
++ boost::system::error_code ec;
++ int i2cRetryCnt = 0;
++ do
++ {
++ if (mux.transferAndHoldMux(
++ buffer[slaveAddrIndex] >> 1, buffer.data() + slotIpmbHeader,
++ size - slotIpmbHeader, ipmbRequestRetryTimeout) >= 0)
++ {
++ break;
++ }
++
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error sending slot IPMB command");
++ i2cRetryCnt++;
++ } while (i2cRetryCnt < ipmbI2cNumberOfRetries);
++
++ if (i2cRetryCnt == ipmbI2cNumberOfRetries)
++ {
++ std::string msgToLog =
++ "slotRequestAdd: Sent to I2C failed after retries."
++ " busId=" +
++ std::to_string(ipmbBusId) + ", error=" + ec.message();
++ phosphor::logging::log<phosphor::logging::level::INFO>(
++ msgToLog.c_str());
++ makeRequestInvalid(*request);
++ return returnStatus(ipmbResponseStatus::error);
++ }
++
++ request->timer->expires_after(
++ std::chrono::milliseconds(ipmbRequestRetryTimeout));
++ request->timer->async_wait(yield[ec]);
++
++ if (ec && ec != boost::asio::error::operation_aborted)
++ {
++ // unexpected error - invalidate request and return generic error
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "requestAdd: async_wait error");
++ makeRequestInvalid(*request);
++ return returnStatus(ipmbResponseStatus::error);
++ }
++
++ if (request->state == ipmbRequestState::matched)
++ {
++ // matched response, send it to client application
++ makeRequestInvalid(*request);
++ return request->returnMatchedResponse();
++ }
++ }
++
++ makeRequestInvalid(*request);
++ return returnStatus(ipmbResponseStatus::timeout);
++}
++
+ std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>
+ IpmbChannel::requestAdd(boost::asio::yield_context &yield,
+ std::shared_ptr<IpmbRequest> request)
+@@ -826,6 +1000,46 @@ static int initializeChannels()
+ return 0;
+ }
+
++auto slotIpmbHandleRequest =
++ [](boost::asio::yield_context yield, uint8_t addressType,
++ uint8_t slotNumber, uint8_t targetSlaveAddr, uint8_t netfn, uint8_t cmd,
++ std::vector<uint8_t> dataReceived) {
++ uint8_t lun = 0; // No support for lun in slot IPMB
++ IpmbChannel *channel = getChannel(ipmbChannelType::slot_ipmb);
++ if (channel == nullptr)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "slotIpmbHandleRequest: Slot IPMB channel does not exist");
++ return returnStatus(ipmbResponseStatus::error);
++ }
++
++ // check outstanding request list for valid sequence number
++ uint8_t seqNum = 0;
++ bool seqValid = channel->seqNumGet(seqNum);
++ if (!seqValid)
++ {
++ phosphor::logging::log<phosphor::logging::level::WARNING>(
++ "slotIpmbHandleRequest: cannot add more requests to the list");
++ return returnStatus(ipmbResponseStatus::busy);
++ }
++
++ uint8_t bmcSlaveAddress = channel->getBmcSlaveAddress();
++ uint8_t rqSlaveAddress = targetSlaveAddr;
++
++ // construct the request to add it to outstanding request list
++ std::shared_ptr<IpmbRequest> request = std::make_shared<IpmbRequest>(
++ rqSlaveAddress, netfn, ipmbRsLun, bmcSlaveAddress, seqNum, lun, cmd,
++ dataReceived);
++
++ if (!request->timer)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "slotIpmbHandleRequest: timer object does not exist");
++ return returnStatus(ipmbResponseStatus::error);
++ }
++ return channel->slotRequestAdd(yield, request, slotNumber);
++ };
++
+ auto ipmbHandleRequest = [](boost::asio::yield_context yield,
+ uint8_t reqChannel, uint8_t netfn, uint8_t lun,
+ uint8_t cmd, std::vector<uint8_t> dataReceived) {
+@@ -971,6 +1185,8 @@ int main(int argc, char *argv[])
+ server.add_interface(ipmbObj, ipmbDbusIntf);
+
+ ipmbIface->register_method("sendRequest", std::move(ipmbHandleRequest));
++ ipmbIface->register_method("SlotIpmbRequest",
++ std::move(slotIpmbHandleRequest));
+ ipmbIface->initialize();
+
+ if (initializeChannels() < 0)
+diff --git a/ipmbbridged.hpp b/ipmbbridged.hpp
+index e264195..167f613 100644
+--- a/ipmbbridged.hpp
++++ b/ipmbbridged.hpp
+@@ -153,7 +153,8 @@ enum class ipmbRequestState
+ enum class ipmbChannelType
+ {
+ ipmb = 0,
+- me = 1
++ me = 1,
++ slot_ipmb = 2
+ };
+
+ /**
+@@ -287,6 +288,11 @@ class IpmbChannel
+ void ipmbSendI2cFrame(std::shared_ptr<std::vector<uint8_t>> buffer,
+ size_t retriesAttempted);
+
++ std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>
++ slotRequestAdd(boost::asio::yield_context &yield,
++ std::shared_ptr<IpmbRequest> requestToSend,
++ const uint8_t pcieSlot);
++
+ std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>
+ requestAdd(boost::asio::yield_context &yield,
+ std::shared_ptr<IpmbRequest> requestToSend);
+--
+2.17.1
+
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
index 69b730221..dcbba98e7 100644
--- 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
@@ -1,2 +1,4 @@
SRC_URI = "git://github.com/openbmc/ipmbbridge.git"
SRCREV = "a86059348fe133725f4616f3e46ff0d555db4039"
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+SRC_URI += "file://0001-Add-dbus-method-SlotIpmbRequest.patch"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/10-nice-rules.conf b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/10-nice-rules.conf
new file mode 100644
index 000000000..d2fb5ba04
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net/10-nice-rules.conf
@@ -0,0 +1,2 @@
+[Service]
+Nice=-18
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
index 15a0041c2..0a9a6ba57 100644
--- 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
@@ -3,7 +3,7 @@ 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 = "a6ad5e161e5e5db4258b04254b19796f154b8533"
+SRCREV = "9d9b7638cb1e95989329680730ec272da786615f"
USERADD_PACKAGES = "${PN}"
# add a group called ipmi
@@ -19,8 +19,13 @@ SYSTEMD_SERVICE_${PN} += " \
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
-SRC_URI += " file://0006-Modify-dbus-namespace-of-chassis-control-for-guid.patch \
+SRC_URI += " file://10-nice-rules.conf \
+ file://0006-Modify-dbus-namespace-of-chassis-control-for-guid.patch \
file://0009-Add-dbus-interface-for-sol-commands.patch \
file://0011-Remove-Get-SOL-Config-Command-from-Netipmid.patch \
"
+do_install_append() {
+ mkdir -p ${D}${sysconfdir}/systemd/system/phosphor-ipmi-net@.service.d/
+ install -m 0644 ${WORKDIR}/10-nice-rules.conf ${D}${sysconfdir}/systemd/system/phosphor-ipmi-net@.service.d/
+}
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/libmctp-intel_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/libmctp-intel_git.bb
index 82305938d..2ffa151f4 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/libmctp-intel_git.bb
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/libmctp-intel_git.bb
@@ -2,7 +2,7 @@ SUMMARY = "libmctp_intel"
DESCRIPTION = "Implementation of MCTP(DMTF DSP0236)"
SRC_URI = "git://github.com/Intel-BMC/libmctp.git;protocol=ssh"
-SRCREV = "a077c8ca846574509983d10aaa33de943ab6388a"
+SRCREV = "1f22461796e1f95a9b0d32f95cb8e871aab820c7"
S = "${WORKDIR}/git/"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/mctp-emulator.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/mctp-emulator.bb
new file mode 100644
index 000000000..3b048b4fd
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/mctp-emulator.bb
@@ -0,0 +1,30 @@
+SUMMARY = "MCTP Daemon"
+DESCRIPTION = "Implementation of MCTP (DTMF DSP0236)"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=bcd9ada3a943f58551867d72893cc9ab"
+
+SRC_URI = "git://github.com/Intel-BMC/pmci.git;protocol=ssh"
+SRCREV = "5cecf9c8b1ab2ff819221f002b67010a6260c9a3"
+
+S = "${WORKDIR}/git/mctp_emulator/"
+
+PV = "1.0+git${SRCPV}"
+
+inherit cmake systemd
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+DEPENDS += " \
+ libmctp-intel \
+ systemd \
+ sdbusplus \
+ phosphor-logging \
+ boost \
+ i2c-tools \
+ cli11 \
+ nlohmann-json \
+ gtest \
+ "
+
+SYSTEMD_SERVICE_${PN} = "xyz.openbmc_project.mctp-emulator.service"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/mctpd.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/mctpd.bb
index d0a03636d..6335440a2 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/mctpd.bb
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/mctpd.bb
@@ -5,7 +5,7 @@ LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e"
SRC_URI = "git://github.com/Intel-BMC/pmci.git;protocol=ssh"
-SRCREV = "626ae6b67b1e2c53e25c0be0b42561c6776be1c7"
+SRCREV = "5cecf9c8b1ab2ff819221f002b67010a6260c9a3"
S = "${WORKDIR}/git/mctpd/"
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
index e80464274..67d8854d2 100644
--- 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
@@ -1,4 +1,4 @@
# Enable downstream autobump
SRC_URI = "git://github.com/openbmc/phosphor-sel-logger.git"
-SRCREV = "151b7c1fc62971b7d319146e5ea129d44eadd9d7"
+SRCREV = "761bf202ba9db9fe644f8f400a5e768abe1a70cf"
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
index 69b721779..c78b00bc1 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend
@@ -1,4 +1,4 @@
-SRCREV = "10306bd5032fda014628487665d8000c0db49177"
+SRCREV = "3840d0ad45134597455f6d70fe1ae76f3cac0e7d"
#SRC_URI = "git://github.com/openbmc/dbus-sensors.git"
DEPENDS_append = " libgpiod libmctp"
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
deleted file mode 100644
index 484d6f80d..000000000
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/state/post-code-manager_git.bb
+++ /dev/null
@@ -1,34 +0,0 @@
-SUMMARY = "Phosphor post code manager"
-DESCRIPTION = "Post Code Manager"
-
-SRC_URI = "git://github.com/openbmc/phosphor-post-code-manager.git"
-SRCREV = "993d4dd9dc583e62a84c6056edffad957d7b7b5d"
-
-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 \
- boost \
- 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}:"
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
index c19f33da2..2182201cf 100644
--- 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
@@ -1,4 +1,4 @@
-From b8a8e561d7dba48f3f0a0eb34662b2450dcad35d Mon Sep 17 00:00:00 2001
+From ab2ff3d715b00a13b0a670fb010793dc626352e0 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
@@ -11,11 +11,11 @@ Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.co
---
Makefile.am | 5 +-
mainapp.cpp | 89 ++++++-
- user_mgr.cpp | 295 ++-------------------
+ user_mgr.cpp | 297 ++-------------------
user_mgr.hpp | 9 +-
user_service.cpp | 786 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
user_service.hpp | 233 +++++++++++++++++
- 6 files changed, 1144 insertions(+), 273 deletions(-)
+ 6 files changed, 1145 insertions(+), 274 deletions(-)
create mode 100644 user_service.cpp
create mode 100644 user_service.hpp
@@ -150,10 +150,10 @@ index c9da030..03c406a 100644
// Claim the bus now
bus.request_name(USER_MANAGER_BUSNAME);
diff --git a/user_mgr.cpp b/user_mgr.cpp
-index 2f22323..db6e7d5 100644
+index 9694fd1..c48196a 100644
--- a/user_mgr.cpp
+++ b/user_mgr.cpp
-@@ -14,26 +14,20 @@
+@@ -14,27 +14,20 @@
// limitations under the License.
*/
@@ -161,8 +161,8 @@ index 2f22323..db6e7d5 100644
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
+ #include <time.h>
+#include <cstdio>
-+
#include <fstream>
#include <grp.h>
#include <pwd.h>
@@ -183,7 +183,7 @@ index 2f22323..db6e7d5 100644
#include "user_mgr.hpp"
#include "users.hpp"
#include "config.h"
-@@ -43,12 +37,10 @@ namespace phosphor
+@@ -44,12 +37,10 @@ namespace phosphor
namespace user
{
@@ -196,7 +196,7 @@ index 2f22323..db6e7d5 100644
static constexpr uint8_t minPasswdLength = 8;
static constexpr int success = 0;
static constexpr int failure = -1;
-@@ -94,79 +86,6 @@ using NoResource =
+@@ -95,79 +86,6 @@ using NoResource =
using Argument = xyz::openbmc_project::Common::InvalidArgument;
@@ -276,7 +276,7 @@ index 2f22323..db6e7d5 100644
bool UserMgr::isUserExist(const std::string &userName)
{
if (userName.empty())
-@@ -293,39 +212,14 @@ void UserMgr::createUser(std::string userName,
+@@ -294,39 +212,14 @@ void UserMgr::createUser(std::string userName,
{
throwForInvalidPrivilege(priv);
throwForInvalidGroups(groupNames);
@@ -319,7 +319,7 @@ index 2f22323..db6e7d5 100644
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,
+@@ -340,19 +233,11 @@ void UserMgr::createUser(std::string userName,
void UserMgr::deleteUser(std::string userName)
{
@@ -343,7 +343,7 @@ index 2f22323..db6e7d5 100644
usersList.erase(userName);
-@@ -362,24 +248,13 @@ void UserMgr::deleteUser(std::string userName)
+@@ -363,24 +248,13 @@ void UserMgr::deleteUser(std::string userName)
void UserMgr::renameUser(std::string userName, std::string newUserName)
{
@@ -371,7 +371,7 @@ index 2f22323..db6e7d5 100644
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,
+@@ -404,8 +278,6 @@ void UserMgr::updateGroupsAndPriv(const std::string &userName,
{
throwForInvalidPrivilege(priv);
throwForInvalidGroups(groupNames);
@@ -380,7 +380,7 @@ index 2f22323..db6e7d5 100644
throwForUserDoesNotExist(userName);
const std::vector<std::string> &oldGroupNames =
usersList[userName].get()->userGroups();
-@@ -420,29 +293,8 @@ void UserMgr::updateGroupsAndPriv(const std::string &userName,
+@@ -421,29 +293,8 @@ void UserMgr::updateGroupsAndPriv(const std::string &userName,
throwForMaxGrpUserCount(groupNames);
}
@@ -412,7 +412,7 @@ index 2f22323..db6e7d5 100644
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,
+@@ -639,19 +490,9 @@ int UserMgr::setPamModuleArgValue(const std::string &moduleName,
void UserMgr::userEnable(const std::string &userName, bool enabled)
{
@@ -434,7 +434,7 @@ index 2f22323..db6e7d5 100644
log<level::INFO>("User enabled/disabled state updated successfully",
entry("USER_NAME=%s", userName.c_str()),
-@@ -728,54 +570,8 @@ bool UserMgr::userLockedForFailedAttempt(const std::string &userName,
+@@ -773,54 +614,8 @@ bool UserMgr::userPasswordExpired(const std::string &userName)
UserSSHLists UserMgr::getUserAndSshGrpList()
{
@@ -491,7 +491,7 @@ index 2f22323..db6e7d5 100644
}
size_t UserMgr::getIpmiUsersCount()
-@@ -786,49 +582,14 @@ size_t UserMgr::getIpmiUsersCount()
+@@ -831,49 +626,14 @@ size_t UserMgr::getIpmiUsersCount()
bool UserMgr::isUserEnabled(const std::string &userName)
{
@@ -545,7 +545,7 @@ index 2f22323..db6e7d5 100644
}
DbusUserObj UserMgr::getPrivilegeMapperObject(void)
-@@ -1057,11 +818,9 @@ void UserMgr::initUserObjects(void)
+@@ -1104,11 +864,9 @@ void UserMgr::initUserObjects(void)
{
// All user management lock has to be based on /etc/shadow
phosphor::user::shadow::Lock lock();
@@ -559,17 +559,20 @@ index 2f22323..db6e7d5 100644
if (!userNameList.empty())
{
-@@ -1116,7 +875,8 @@ void UserMgr::initUserObjects(void)
+@@ -1163,8 +921,10 @@ void UserMgr::initUserObjects(void)
}
}
-UserMgr::UserMgr(sdbusplus::bus::bus &bus, const char *path) :
+- Ifaces(bus, path, true), bus(bus), path(path)
+UserMgr::UserMgr(sdbusplus::bus::bus &bus, const char *path,
+ UserService::ServiceType srvc) :
- Ifaces(bus, path, true), bus(bus), path(path)
++ Ifaces(bus, path, true),
++ bus(bus), path(path)
{
UserMgrIface::allPrivileges(privMgr);
-@@ -1225,6 +985,7 @@ UserMgr::UserMgr(sdbusplus::bus::bus &bus, const char *path) :
+ std::sort(groupsMgr.begin(), groupsMgr.end());
+@@ -1272,6 +1032,7 @@ UserMgr::UserMgr(sdbusplus::bus::bus &bus, const char *path) :
}
AccountPolicyIface::accountUnlockTimeout(value32);
}
@@ -578,7 +581,7 @@ index 2f22323..db6e7d5 100644
// emit the signal
diff --git a/user_mgr.hpp b/user_mgr.hpp
-index b25e9f2..c24733b 100644
+index e25ca87..262aaf9 100644
--- a/user_mgr.hpp
+++ b/user_mgr.hpp
@@ -21,6 +21,7 @@
@@ -610,7 +613,7 @@ index b25e9f2..c24733b 100644
/** @brief create user method.
* This method creates a new user as requested
-@@ -186,6 +187,8 @@ class UserMgr : public Ifaces
+@@ -193,6 +194,8 @@ class UserMgr : public Ifaces
/** @brief object path */
const std::string path;
@@ -618,7 +621,7 @@ index b25e9f2..c24733b 100644
+ std::unique_ptr<UserService> userSrvc;
/** @brief privilege manager container */
std::vector<std::string> privMgr = {"priv-admin", "priv-operator",
- "priv-user", "priv-callback"};
+ "priv-user", "priv-noaccess"};
diff --git a/user_service.cpp b/user_service.cpp
new file mode 100644
index 0000000..c3c45bd
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0006-Use-groupmems-instead-of-getgrnam_r-due-to-overlay.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0006-Use-groupmems-instead-of-getgrnam_r-due-to-overlay.patch
index 91087a155..2abfeb78c 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0006-Use-groupmems-instead-of-getgrnam_r-due-to-overlay.patch
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0006-Use-groupmems-instead-of-getgrnam_r-due-to-overlay.patch
@@ -1,4 +1,4 @@
-From c0bf911cbc33659adddebde767029ffc23251c61 Mon Sep 17 00:00:00 2001
+From a78bad158bca59dadb93c9c52d6daefa1c52b9cf Mon Sep 17 00:00:00 2001
From: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
Date: Mon, 24 Feb 2020 13:37:12 +0530
Subject: [PATCH] Use groupmems instead of getgrnam_r due to overlay
@@ -72,5 +72,5 @@ index c3c45bd..0a6b171 100644
return usersInGroup;
}
--
-2.17.1
+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
index 238511ed5..162f5210c 100644
--- 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
@@ -1,7 +1,6 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
-#SRC_URI = "git://github.com/openbmc/phosphor-user-manager;nobranch=1"
-SRCREV = "d4d655006c6179d47008d9b374debcedcc03a1c4"
+SRCREV = "3ab6cc280e71c1fffe53a4f3f14ea683f0e2e87e"
EXTRA_OECONF += "${@bb.utils.contains_any("IMAGE_FEATURES", [ 'debug-tweaks', 'allow-root-login' ], '', '--disable-root_user_mgmt', d)}"
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
index 45c2c5364..fc6e1034a 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb
@@ -13,7 +13,7 @@ LIC_FILES_CHKSUM = "file://${INTELBASE}/COPYING.apache-2.0;md5=34400b68072d710fe
SYSTEMD_SERVICE_${PN} += "system-watchdog.service"
SYSTEMD_ENVIRONMENT_FILE_${PN} += "obmc/system-watchdog/system-watchdog.conf"
-SYSTEMD_SERVICE_${PN} += "watchdog-reset.service"
+SYSTEMD_SERVICE_${PN} += "watchdog-reset@.service"
SYSTEMD_SERVICE_${PN} += "watchdog-clear-failures.service"
SYSTEMD_SERVICE_${PN} += "watchdog-clear-failures.timer"
SRC_URI += "file://watchdog-reset.sh"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.sh b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.sh
index b3afd73d3..3413fdb9f 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.sh
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.sh
@@ -1,11 +1,16 @@
#!/bin/bash
+echo "Watchdog being started by $1" > /dev/kmsg
+
if /sbin/fw_printenv bootfailures -n | grep -q 3; then
exit 0 # passed boot limit, user started again on purpose
fi
-echo "Watchdog Failure Limit Reached, Failed Processes:" > /dev/kmsg
-systemctl --failed --no-pager | grep failed > /dev/kmsg
+if test -f "/tmp/nowatchdog"; then
+ echo "Not resetting due to nowatchdog file" > /dev/kmsg
+ exit 0
+fi
+
echo "Log as follows:" > /dev/kmsg
journalctl -r -n 100 | while read line; do echo $line > /dev/kmsg; done
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.service b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset@.service
index 6a5ffb4ba..6b1ebc544 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.service
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset@.service
@@ -2,6 +2,6 @@
Description=Reset BMC Using Hardware Watchdog
[Service]
-ExecStart=/usr/bin/watchdog-reset.sh
+ExecStart=/usr/bin/watchdog-reset.sh %i
Type=oneshot
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
index 2382b20e7..be02d5fd9 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui_%.bbappend
@@ -1,4 +1,4 @@
SRC_URI = "git://github.com/Intel-BMC/phosphor-webui;protocol=ssh;branch=intel2"
FILESEXTRAPATHS_prepend_intel := "${THISDIR}/${PN}:"
-SRCREV = "3d8dcffe2bbbdbb0212507bec60eb4e9f91c1d18"
+SRCREV = "34a4a702870e33a5612d2c4a84385eae2edbf477"