diff options
author | Ed Tanous <ed.tanous@intel.com> | 2019-06-20 19:46:38 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-20 19:46:38 +0300 |
commit | 43a183cc0926da36e3a218efa02ab4838ace316f (patch) | |
tree | 9ea192b408585fc2a19b54d196c3d56eaddc4acb /meta-openbmc-mods/meta-common | |
parent | 5575b1d27fc222f973d96dc06af0f21ba7656f28 (diff) | |
parent | 2c7e8f4ce61f2e0407c37e98e22bbb13e562b414 (diff) | |
download | openbmc-43a183cc0926da36e3a218efa02ab4838ace316f.tar.xz |
Merge pull request #12 from Intel-BMC/update
Update
Diffstat (limited to 'meta-openbmc-mods/meta-common')
52 files changed, 2711 insertions, 501 deletions
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 1520cb7b9..4ad3b2b92 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 @@ -8,7 +8,6 @@ IMAGE_INSTALL_append = " \ dtoverlay \ entity-manager \ ipmitool \ - ipmi-providers \ intel-ipmi-oem \ phosphor-ipmi-ipmb \ phosphor-node-manager-proxy \ diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0016-Add-support-for-128MB-Macronix-spi-flash-MX66L1G45G.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0016-Add-support-for-128MB-Macronix-spi-flash-MX66L1G45G.patch deleted file mode 100644 index cc1e56fdb..000000000 --- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0016-Add-support-for-128MB-Macronix-spi-flash-MX66L1G45G.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 8992df8f3a0f5fc16ec41ad6dd7a5a13e6f94d32 Mon Sep 17 00:00:00 2001 -From: Vernon Mauery <vernon.mauery@linux.intel.com> -Date: Wed, 5 Dec 2018 16:13:15 -0800 -Subject: [PATCH] Add support for 128MB Macronix spi flash MX66L1G45G - -This will enable u-boot support for the Macronix MX66L1G45G part. - -Change-Id: I5edc69357a8b1607c5c44e53bed3eddf38fdc0be -Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com> ---- - drivers/mtd/spi/sf_params.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/mtd/spi/sf_params.c b/drivers/mtd/spi/sf_params.c -index c577d9ed6c..d2a96efe48 100644 ---- a/drivers/mtd/spi/sf_params.c -+++ b/drivers/mtd/spi/sf_params.c -@@ -50,6 +50,7 @@ const struct spi_flash_params spi_flash_params_table[] = { - {"MX25L12805", 0xc22018, 0x0, 64 * 1024, 256, RD_FULL, WR_QPP}, - {"MX25L25635F", 0xc22019, 0x0, 64 * 1024, 512, RD_FULL, WR_QPP}, - {"MX25L51235F", 0xc2201a, 0x0, 64 * 1024, 1024, RD_FULL, WR_QPP}, -+ {"MX66L1G45G", 0xc2201b, 0x0, 64 * 1024, 2048, RD_FULL, SECT_4K|WR_QPP}, - {"MX25L12855E", 0xc22618, 0x0, 64 * 1024, 256, RD_FULL, WR_QPP}, - #endif - #ifdef CONFIG_SPI_FLASH_SPANSION /* SPANSION */ --- -2.17.1 - diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0017-Enable-Macronix-and-Micron-SPI-support.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0017-Enable-Macronix-and-Micron-SPI-support.patch deleted file mode 100644 index b26803c95..000000000 --- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0017-Enable-Macronix-and-Micron-SPI-support.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 8415002a2e77a41831b3064dae264f60996ac88a Mon Sep 17 00:00:00 2001 -From: Jae Hyun Yoo <jae.hyun.yoo@intel.com> -Date: Thu, 6 Dec 2018 15:07:09 -0800 -Subject: [PATCH] Enable Macronix and Micron SPI support - -This commit enables Macronix and Micron SPI support. - -Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com> ---- - configs/ast_g5_ncsi_2boot_defconfig | 2 ++ - configs/ast_g5_ncsi_defconfig | 2 ++ - configs/ast_g5_phy_defconfig | 2 ++ - 3 files changed, 6 insertions(+) - -diff --git a/configs/ast_g5_ncsi_2boot_defconfig b/configs/ast_g5_ncsi_2boot_defconfig -index d5b7894a9e00..abceed817615 100644 ---- a/configs/ast_g5_ncsi_2boot_defconfig -+++ b/configs/ast_g5_ncsi_2boot_defconfig -@@ -10,6 +10,8 @@ CONFIG_FIT_VERBOSE=y - CONFIG_HUSH_PARSER=y - CONFIG_OF_LIBFDT=y - CONFIG_SPI_FLASH=y -+CONFIG_SPI_FLASH_MACRONIX=y -+CONFIG_SPI_FLASH_STMICRO=y - CONFIG_SYS_NS16550=y - CONFIG_FIRMWARE_2ND_BOOT=y - CONFIG_AUTOBOOT=y -diff --git a/configs/ast_g5_ncsi_defconfig b/configs/ast_g5_ncsi_defconfig -index 9481e5fb6e9d..3f504a325649 100644 ---- a/configs/ast_g5_ncsi_defconfig -+++ b/configs/ast_g5_ncsi_defconfig -@@ -10,5 +10,7 @@ CONFIG_FIT_VERBOSE=y - CONFIG_HUSH_PARSER=y - CONFIG_OF_LIBFDT=y - CONFIG_SPI_FLASH=y -+CONFIG_SPI_FLASH_MACRONIX=y -+CONFIG_SPI_FLASH_STMICRO=y - CONFIG_SYS_NS16550=y - CONFIG_USE_IRQ=y -diff --git a/configs/ast_g5_phy_defconfig b/configs/ast_g5_phy_defconfig -index 4aefcf49e880..8f0919043376 100644 ---- a/configs/ast_g5_phy_defconfig -+++ b/configs/ast_g5_phy_defconfig -@@ -11,5 +11,7 @@ CONFIG_FIT_VERBOSE=y - CONFIG_HUSH_PARSER=y - CONFIG_OF_LIBFDT=y - CONFIG_SPI_FLASH=y -+CONFIG_SPI_FLASH_MACRONIX=y -+CONFIG_SPI_FLASH_STMICRO=y - CONFIG_SYS_NS16550=y - CONFIG_USE_IRQ=y --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0018-Add-support-for-Macronix-and-Micron-1Gbits-SPI-flash.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0018-Add-support-for-Macronix-and-Micron-1Gbits-SPI-flash.patch deleted file mode 100644 index 2ed297a96..000000000 --- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0018-Add-support-for-Macronix-and-Micron-1Gbits-SPI-flash.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0039c15251a7fcf60154d59933a11d9e17b04d5c Mon Sep 17 00:00:00 2001 -From: Jae Hyun Yoo <jae.hyun.yoo@intel.com> -Date: Thu, 6 Dec 2018 18:49:04 -0800 -Subject: [PATCH] Add support for Macronix and Micron 1Gbits SPI flash - -Quick fix to support Macronix and Micron 1Gbits SPI. - -Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com> ---- - arch/arm/mach-aspeed/flash.c | 33 ++++++++++++++++++++++++++++++++- - 1 file changed, 32 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/mach-aspeed/flash.c b/arch/arm/mach-aspeed/flash.c -index dece4315d755..2a31b6503a22 100644 ---- a/arch/arm/mach-aspeed/flash.c -+++ b/arch/arm/mach-aspeed/flash.c -@@ -79,6 +79,7 @@ flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* FLASH chips info */ - #define MX25L12805D 0x1820C2 - #define MX25L25635E 0x1920C2 - #define MX66L51235F 0x1A20C2 -+#define MX66L1G45G 0x1B20C2 - #define SST25VF016B 0x4125bf - #define SST25VF064C 0x4b25bf - #define SST25VF040B 0x8d25bf -@@ -978,6 +979,35 @@ static ulong flash_get_size (ulong base, flash_info_t *info) - #endif - break; - -+ case MX66L1G45G: -+ erase_region_size = 0x10000; -+ info->readcmd = 0x0b; -+ info->dualport = 0; -+ info->dummybyte = 1; -+ info->buffersize = 256; -+ WriteClk = 50; -+ EraseClk = 20; -+ ReadClk = 50; -+#if 1 -+ info->sector_count = 2048; -+ info->size = 0x4000000; -+ info->address32 = 1; -+#if defined(CONFIG_FLASH_SPIx2_Dummy) -+ info->readcmd = 0xbb; -+ info->dummybyte = 1; -+ info->dualport = 1; -+ info->iomode = IOMODEx2_dummy; -+#elif defined(CONFIG_FLASH_SPIx4_Dummy) -+ info->readcmd = 0xeb; -+ info->dummybyte = 3; -+ info->dualport = 0; -+ info->iomode = IOMODEx4_dummy; -+ info->quadport = 1; -+ info->dummydata = 0xaa; -+#endif -+#endif -+ break; -+ - case MX25L12805D: - info->sector_count = 256; - info->size = 0x1000000; -@@ -1093,7 +1123,8 @@ static ulong flash_get_size (ulong base, flash_info_t *info) - info->readcmd = 0x0b; - info->dualport = 0; - info->dummybyte = 1; -- info->buffersize = 1; -+ info->buffersize = 256; -+ info->address32 = 1; - WriteClk = 50; - EraseClk = 25; - ReadClk = 50; --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-KCS-driver-support-in-uBoot.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-KCS-driver-support-in-uBoot.patch index 79028d2a1..c79b2f2dc 100644 --- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-KCS-driver-support-in-uBoot.patch +++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-KCS-driver-support-in-uBoot.patch @@ -1,4 +1,4 @@ -From 16209364c27a0cb7e2b7fdd445942f68e9180263 Mon Sep 17 00:00:00 2001 +From b11377c73c85bdee1975402084c3760b70cc99c4 Mon Sep 17 00:00:00 2001 From: AppaRao Puli <apparao.puli@linux.intel.com> Date: Wed, 13 Mar 2019 14:28:05 +0530 Subject: [PATCH] KCS driver support in uBoot @@ -28,9 +28,9 @@ Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com> --- board/aspeed/ast-g5/Makefile | 1 + board/aspeed/ast-g5/ast-g5-intel.c | 3 + - board/aspeed/ast-g5/ast-g5-kcs.c | 425 +++++++++++++++++++++++++++++++++++++ - board/aspeed/ast-g5/ast-g5-kcs.h | 114 ++++++++++ - 4 files changed, 543 insertions(+) + board/aspeed/ast-g5/ast-g5-kcs.c | 420 +++++++++++++++++++++++++++++++++++++ + board/aspeed/ast-g5/ast-g5-kcs.h | 112 ++++++++++ + 4 files changed, 536 insertions(+) create mode 100644 board/aspeed/ast-g5/ast-g5-kcs.c create mode 100644 board/aspeed/ast-g5/ast-g5-kcs.h @@ -44,7 +44,7 @@ index 9022433..05972b9 100644 obj-y += ast-g5-timer.o +obj-y += ast-g5-kcs.o diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c -index f810a40..f9955c7 100644 +index 409b1a7..41d41ea 100644 --- a/board/aspeed/ast-g5/ast-g5-intel.c +++ b/board/aspeed/ast-g5/ast-g5-intel.c @@ -437,6 +437,7 @@ static void pwm_init(void) @@ -66,16 +66,15 @@ index f810a40..f9955c7 100644 } diff --git a/board/aspeed/ast-g5/ast-g5-kcs.c b/board/aspeed/ast-g5/ast-g5-kcs.c new file mode 100644 -index 0000000..f983b4a +index 0000000..7bff26f --- /dev/null +++ b/board/aspeed/ast-g5/ast-g5-kcs.c -@@ -0,0 +1,425 @@ +@@ -0,0 +1,420 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018-2019 Intel Corporation + +#include "ast-g5-kcs.h" + -+#define DEBUG_KCS_ENABLED 0 +#ifdef DEBUG_KCS_ENABLED +#define DBG_KCS printf +#else @@ -139,7 +138,7 @@ index 0000000..f983b4a + } + + /* very unlike code hits here. */ -+ printf("ERROR: %s error. ChannelNo: %d\n", __func__, channel_num); ++ DBG_KCS("ERROR: %s error. ChannelNo: %d\n", __func__, channel_num); + BUG(); +} + @@ -148,7 +147,7 @@ index 0000000..f983b4a + struct kcs_packet *kcs_pkt = NULL; + + kcs_pkt = get_kcs_packet(channel_num); -+ printf("ERROR: KCS communication aborted (Channel:%d, Error:%d)\n", ++ DBG_KCS("ERROR: KCS communication aborted (Channel:%d, Error:%d)\n", + channel_num, kcs_pkt->error); + set_kcs_state(channel_num, KCS_STATE_ERROR); + read_data(channel_num); @@ -176,6 +175,7 @@ index 0000000..f983b4a +static void process_kcs_request(u16 channel_num) +{ + struct kcs_packet *kcs_pkt = NULL; ++ int i; + + kcs_pkt = get_kcs_packet(channel_num); + if (!kcs_pkt->read_req_done) @@ -184,8 +184,6 @@ index 0000000..f983b4a + DBG_KCS("%s:- chan:%d\n", __func__, channel_num); + +#ifdef DEBUG_KCS_ENABLED -+ int i; -+ + DBG_KCS("Request data(Len:%d): ", kcs_pkt->data_in_idx); + for (i = 0; i < kcs_pkt->data_in_idx; i++) + DBG_KCS(" 0x%02x", kcs_pkt->data_in[i]); @@ -240,8 +238,6 @@ index 0000000..f983b4a + struct kcs_packet *kcs_pkt = NULL; + + kcs_pkt = get_kcs_packet(channel_num); -+ DBG_KCS("%s:- chan:%d, kcs_pkt->phase:%d\n", __func__, channel_num, -+ kcs_pkt->phase); + + switch (kcs_pkt->phase) { + case KCS_PHASE_WRITE_START: @@ -326,7 +322,6 @@ index 0000000..f983b4a + write_data(channel_num, ZERO_DATA); + + u16 cmd = read_data(channel_num); -+ DBG_KCS("%s:- chan:%d, cmd:0x%02x\n", __func__, channel_num, cmd); + switch (cmd) { + case KCS_CTRL_CODE_WRITE_START: + init_kcs_packet(channel_num); @@ -497,10 +492,10 @@ index 0000000..f983b4a +} diff --git a/board/aspeed/ast-g5/ast-g5-kcs.h b/board/aspeed/ast-g5/ast-g5-kcs.h new file mode 100644 -index 0000000..52b5097 +index 0000000..bb697c4 --- /dev/null +++ b/board/aspeed/ast-g5/ast-g5-kcs.h -@@ -0,0 +1,114 @@ +@@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2018-2019 Intel Corporation */ + @@ -515,8 +510,8 @@ index 0000000..52b5097 +/* KCS channel addresses */ +#define KCS_CHANNEL1_ADDR 0xCA0 +#define KCS_CHANNEL2_ADDR 0xCA8 -+#define KCS_CHANNEL3_ADDR 0xCA2 -+#define KCS_CHANNEL4_ADDR 0xCB2 ++#define KCS_CHANNEL3_ADDR 0xCA2 /* KCS SMS */ ++#define KCS_CHANNEL4_ADDR 0xCA4 /* KCS SMM */ + +#define ZERO_DATA 0x00 + @@ -539,6 +534,11 @@ index 0000000..52b5097 +#define LPC_STR1 0x3C /* Status Register 1 */ +#define LPC_STR2 0x40 /* Status Register 2 */ +#define LPC_STR3 0x44 /* Status Register 3 */ ++#define LPC_HICRB 0x100 /* Host Interface Control Register B */ ++#define LPC_LADR4 0x110 /* LPC channel #4 Address Register */ ++#define LPC_IDR4 0x114 /* Input Data Register 4 */ ++#define LPC_ODR4 0x118 /* Output Data Register 4 */ ++#define LPC_STR4 0x11C /* Status Data Register 4 */ + +/* LPC Bits */ +#define BIT_LADR12AS BIT(7) /* Channel Address selection */ @@ -549,15 +549,8 @@ index 0000000..52b5097 +#define BIT_LPC2E BIT(6) /* Enable LPC channel #2 */ +#define BIT_LPC3E BIT(7) /* Enable LPC channel #2 */ +#define BIT_KCSENBL BIT(2) /* Enable KCS interface in Channel #3 */ -+ -+/* mapped to lpc-host@80 IO space */ -+#define LPC_HICRB 0x080 +#define BIT_IBFIE4 BIT(1) +#define BIT_LPC4E BIT(0) -+#define LPC_LADR4 0x090 -+#define LPC_IDR4 0x094 /* Input Data Register 4 */ -+#define LPC_ODR4 0x098 /* Output Data Register 4 */ -+#define LPC_STR4 0x09c /* Status Data Register 4 */ + +#define BIT_STATUS_OBF BIT(0) /* Output Data Register full #1/#2/#3 */ +#define BIT_STATUS_IBF BIT(1) /* Input Data Register full #1/#2/#3 */ diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0024-IPMI-command-handler-implementation-in-uboot.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0024-IPMI-command-handler-implementation-in-uboot.patch index 47cb56062..9096b09b2 100644 --- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0024-IPMI-command-handler-implementation-in-uboot.patch +++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0024-IPMI-command-handler-implementation-in-uboot.patch @@ -1,6 +1,6 @@ -From d770ea7a30742339b0692858847838dd2a738aeb Mon Sep 17 00:00:00 2001 +From 50d3a7264fc0ecdd61ae1686839b19091b124e8d Mon Sep 17 00:00:00 2001 From: AppaRao Puli <apparao.puli@linux.intel.com> -Date: Fri, 5 Apr 2019 17:53:21 +0530 +Date: Tue, 21 May 2019 00:19:16 +0530 Subject: [PATCH] IPMI command handler implementation in uboot IPMI command handler implemtation in uBoot. @@ -22,10 +22,10 @@ Change-Id: I18b205bc45c34f7c4ef16adc29fa5bd494624ceb Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com> --- board/aspeed/ast-g5/Makefile | 1 + - board/aspeed/ast-g5/ast-g5-kcs.c | 78 +++++++++++++----------- + board/aspeed/ast-g5/ast-g5-kcs.c | 77 +++++++++++++----------- board/aspeed/ast-g5/ipmi-handler.c | 118 +++++++++++++++++++++++++++++++++++++ board/aspeed/ast-g5/ipmi-handler.h | 40 +++++++++++++ - 4 files changed, 202 insertions(+), 35 deletions(-) + 4 files changed, 202 insertions(+), 34 deletions(-) create mode 100644 board/aspeed/ast-g5/ipmi-handler.c create mode 100644 board/aspeed/ast-g5/ipmi-handler.h @@ -39,7 +39,7 @@ index 05972b9..f28fcfe 100644 obj-y += ast-g5-kcs.o +obj-y += ipmi-handler.o diff --git a/board/aspeed/ast-g5/ast-g5-kcs.c b/board/aspeed/ast-g5/ast-g5-kcs.c -index f983b4a..05b1cc2 100644 +index 7bff26f..98bf69b 100644 --- a/board/aspeed/ast-g5/ast-g5-kcs.c +++ b/board/aspeed/ast-g5/ast-g5-kcs.c @@ -1,7 +1,7 @@ @@ -49,9 +49,9 @@ index f983b4a..05b1cc2 100644 -#include "ast-g5-kcs.h" +#include "ipmi-handler.h" - #define DEBUG_KCS_ENABLED 0 #ifdef DEBUG_KCS_ENABLED -@@ -10,11 +10,6 @@ + #define DBG_KCS printf +@@ -9,11 +9,6 @@ #define DBG_KCS(...) #endif @@ -63,22 +63,15 @@ index f983b4a..05b1cc2 100644 #define KCS_CHANNEL_NO_3 3 static const u16 enabled_kcs_channel[] = { KCS_CHANNEL_NO_3 }; -@@ -104,13 +99,13 @@ static void init_kcs_packet(u16 channel_num) +@@ -103,6 +98,7 @@ static void init_kcs_packet(u16 channel_num) static void process_kcs_request(u16 channel_num) { struct kcs_packet *kcs_pkt = NULL; + struct ipmi_cmd_data ipmi_data; - - kcs_pkt = get_kcs_packet(channel_num); - if (!kcs_pkt->read_req_done) - return; - - DBG_KCS("%s:- chan:%d\n", __func__, channel_num); -- - #ifdef DEBUG_KCS_ENABLED int i; -@@ -119,37 +114,49 @@ static void process_kcs_request(u16 channel_num) + kcs_pkt = get_kcs_packet(channel_num); +@@ -117,37 +113,49 @@ static void process_kcs_request(u16 channel_num) DBG_KCS(" 0x%02x", kcs_pkt->data_in[i]); DBG_KCS("\n"); #endif @@ -156,7 +149,7 @@ index f983b4a..05b1cc2 100644 #ifdef DEBUG_KCS_ENABLED DBG_KCS("Response data(Len:%d): ", kcs_pkt->data_out_len); -@@ -158,6 +165,7 @@ static void process_kcs_request(u16 channel_num) +@@ -156,6 +164,7 @@ static void process_kcs_request(u16 channel_num) DBG_KCS("\n"); #endif diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0029-FFUJ-FW-IPMI-commands-and-flash-support-in-u-boot.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0029-FFUJ-FW-IPMI-commands-and-flash-support-in-u-boot.patch new file mode 100644 index 000000000..00dbd68da --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0029-FFUJ-FW-IPMI-commands-and-flash-support-in-u-boot.patch @@ -0,0 +1,1271 @@ +From bd4a64d7ea394d0b418d491699853112229f098e Mon Sep 17 00:00:00 2001 +From: AppaRao Puli <apparao.puli@linux.intel.com> +Date: Tue, 21 May 2019 00:53:04 +0530 +Subject: [PATCH] FFUJ: FW IPMI commands and flash support in u-boot + +Firmware update and OEM ipmi commands implementation +for supporting Force Firmware Update Jumper(FFUJ) +mode. Also added support to update the fit images +in FFUJ mode. + +Firmware update commands: +1) Get BMC Execution Context(0x23) +2) Get Firmware Update Random Number(0x26) +3) Set Firmware Update Mode(0x27) +4) Exit Firmware Update Mode(0x28) +5) Set/Get Firmware Update Control(0x29) +6) Get Firmware Update status(0x2A) +7) Set Firmware Update Options(0x2B) +8) Firmware Image Write(0x2C) + +OEM Commands: +1) Get Buffer Size(0x66) + +Tested: + - Used cmdtool.efi to test the individual commands + implementation and negative cases. + - Used debug fwpiaupd.efi tool for validating Firmware + image transfer via KCS and flashing. + +Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com> +--- + arch/arm/include/asm/arch-aspeed/ast-g5-intel.h | 1 + + board/aspeed/ast-g5/Makefile | 2 + + board/aspeed/ast-g5/fw-update.c | 486 ++++++++++++++++++++++++ + board/aspeed/ast-g5/fw-update.h | 50 +++ + board/aspeed/ast-g5/ipmi-fwupd.c | 402 ++++++++++++++++++++ + board/aspeed/ast-g5/ipmi-fwupd.h | 81 ++++ + board/aspeed/ast-g5/ipmi-handler.c | 66 +++- + board/aspeed/ast-g5/ipmi-handler.h | 3 +- + common/autoboot.c | 11 + + configs/ast_g5_phy_defconfig | 1 + + 10 files changed, 1091 insertions(+), 12 deletions(-) + create mode 100644 board/aspeed/ast-g5/fw-update.c + create mode 100644 board/aspeed/ast-g5/fw-update.h + create mode 100644 board/aspeed/ast-g5/ipmi-fwupd.c + create mode 100644 board/aspeed/ast-g5/ipmi-fwupd.h + +diff --git a/arch/arm/include/asm/arch-aspeed/ast-g5-intel.h b/arch/arm/include/asm/arch-aspeed/ast-g5-intel.h +index cd9a099..a88521a 100644 +--- a/arch/arm/include/asm/arch-aspeed/ast-g5-intel.h ++++ b/arch/arm/include/asm/arch-aspeed/ast-g5-intel.h +@@ -14,6 +14,7 @@ + + #ifndef __ASSEMBLY__ + int intel_force_firmware_jumper_enabled(void); ++void start_fw_update_loop(void); + #endif + + #endif /* __AST_INTEL_G5_H__ */ +diff --git a/board/aspeed/ast-g5/Makefile b/board/aspeed/ast-g5/Makefile +index f28fcfe..0b2d936 100644 +--- a/board/aspeed/ast-g5/Makefile ++++ b/board/aspeed/ast-g5/Makefile +@@ -6,3 +6,5 @@ obj-y += ast-g5-gpio.o + obj-y += ast-g5-timer.o + obj-y += ast-g5-kcs.o + obj-y += ipmi-handler.o ++obj-y += ipmi-fwupd.o ++obj-y += fw-update.o +diff --git a/board/aspeed/ast-g5/fw-update.c b/board/aspeed/ast-g5/fw-update.c +new file mode 100644 +index 0000000..9923993 +--- /dev/null ++++ b/board/aspeed/ast-g5/fw-update.c +@@ -0,0 +1,486 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++// Copyright (c) 2018-2019 Intel Corporation ++ ++#include <common.h> ++#include <cli.h> ++#include <flash.h> ++ ++#include "fw-update.h" ++ ++#define BOOTCMD_BOOTM_STR "bootm " ++#define RANDOM_NUM_TIMEOUT 30 /* in seconds */ ++#define WAIT_STATE_TIMEOUT 10000 /* 10 seconds */ ++ ++#define PROTECT_OFF 0 ++#define PROTECT_ON 1 ++ ++extern struct fwupd_global_setting g_fwupd_settings; ++extern u32 g_write_addr; ++ ++bool g_fwupd_settings_lock = false; ++unsigned long long etime; ++ ++bool fwupd_settings_trylock(void) ++{ ++ if (g_fwupd_settings_lock) ++ return false; ++ ++ g_fwupd_settings_lock = true; ++ return g_fwupd_settings_lock; ++} ++ ++void fwupd_settings_unlock(void) ++{ ++ g_fwupd_settings_lock = false; ++} ++ ++u8 get_active_boot_image(void) ++{ ++ char *bootcmd = getenv("bootcmd"); ++ char *start = strstr(bootcmd, BOOTCMD_BOOTM_STR); ++ u8 boot_image = PRIMARY_IMAGE; ++ ++ if (start) { ++ ulong boot_addr = simple_strtoul( ++ (start + strlen(BOOTCMD_BOOTM_STR)), NULL, 16); ++ if (boot_addr == SECONDARY_FITIMAGE_START_ADDR) ++ return SECONDARY_IMAGE; ++ } ++ return boot_image; ++} ++ ++static ulong get_flash_image_address(void) ++{ ++ char *bootcmd = getenv("bootcmd"); ++ char *start = strstr(bootcmd, BOOTCMD_BOOTM_STR); ++ ulong boot_addr = PRIMARY_FITIMAGE_START_ADDR; ++ ++ if (start) { ++ boot_addr = simple_strtoul((start + strlen(BOOTCMD_BOOTM_STR)), ++ NULL, 16); ++ /* We update in backup region and set the bootcmd accordingly */ ++ if (boot_addr == PRIMARY_FITIMAGE_START_ADDR) ++ boot_addr = SECONDARY_FITIMAGE_START_ADDR; ++ else ++ boot_addr = PRIMARY_FITIMAGE_START_ADDR; ++ } ++ ++ return boot_addr; ++} ++ ++static void update_processing_status(u8 status, u8 percent) ++{ ++ if (!fwupd_settings_trylock()) ++ return; ++ ++ g_fwupd_settings.processing_status = status; ++ g_fwupd_settings.percentage_completion = percent; ++ ++ fwupd_settings_unlock(); ++ return; ++} ++ ++static void reset_all_settings(void) ++{ ++ if (!fwupd_settings_trylock()) ++ return; ++ ++ memset(&g_fwupd_settings, 0, sizeof(g_fwupd_settings)); ++ g_fwupd_settings.fwupd_mode_active = false; ++ g_fwupd_settings.start_update = false; ++ ++ fwupd_settings_unlock(); ++} ++ ++unsigned int get_seed(void) ++{ ++ char seed_str[] = { "INTEL" }; ++ unsigned int seed; ++ ++ for (int i = 0; i < strlen(seed_str); i++) ++ seed += (seed_str[i] << (i * 8)); ++ ++ return seed; ++} ++ ++int generate_random_number(void) ++{ ++ srand(get_seed()); ++ ++ if (!fwupd_settings_trylock()) { ++ printf("%s(): Lock failed\n", __func__); ++ return -1; ++ } ++ for (int i = 0; i < RAND_NUMBER_SIZE; i++) ++ g_fwupd_settings.rand_num[i] = (u8)(rand() & 0xFF); ++ ++ g_fwupd_settings.random_number_valid = true; ++ ++ fwupd_settings_unlock(); ++ ++ /* Random number should be cleared after 30sec timeout */ ++ etime = endtick(RANDOM_NUM_TIMEOUT); ++ ++ return 0; ++} ++ ++static int sect_roundb(ulong *addr) ++{ ++ flash_info_t *info; ++ ulong bank, sector_end_addr; ++ char found; ++ int i; ++ ++ /* find the end addr of the sector where the *addr is */ ++ found = 0; ++ for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS && !found; ++bank) { ++ info = &flash_info[bank]; ++ for (i = 0; i < info->sector_count && !found; ++i) { ++ /* get the end address of the sector */ ++ if (i == info->sector_count - 1) { ++ sector_end_addr = ++ info->start[0] + info->size - 1; ++ } else { ++ sector_end_addr = info->start[i + 1] - 1; ++ } ++ ++ if (*addr <= sector_end_addr && ++ *addr >= info->start[i]) { ++ found = 1; ++ /* adjust *addr if necessary */ ++ if (*addr < sector_end_addr) ++ *addr = sector_end_addr; ++ } /* sector */ ++ } /* bank */ ++ } ++ if (!found) { ++ /* error, address not in flash */ ++ printf("Error: end address (0x%08lx) not in flash!\n", *addr); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static int fill_flash_sect_ranges(ulong addr_first, ulong addr_last, ++ int *s_first, int *s_last, int *s_count) ++{ ++ flash_info_t *info; ++ ulong bank; ++ int rcode = 0; ++ ++ *s_count = 0; ++ ++ for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) { ++ s_first[bank] = -1; /* first sector to erase */ ++ s_last[bank] = -1; /* last sector to erase */ ++ } ++ ++ for (bank = 0, info = &flash_info[0]; ++ (bank < CONFIG_SYS_MAX_FLASH_BANKS) && (addr_first <= addr_last); ++ ++bank, ++info) { ++ ulong b_end; ++ int sect; ++ short s_end; ++ ++ if (info->flash_id == FLASH_UNKNOWN) ++ continue; ++ ++ b_end = info->start[0] + info->size - 1; /* bank end addr */ ++ s_end = info->sector_count - 1; /* last sector */ ++ ++ for (sect = 0; sect < info->sector_count; ++sect) { ++ ulong end; /* last address in current sect */ ++ ++ end = (sect == s_end) ? b_end : ++ info->start[sect + 1] - 1; ++ ++ if (addr_first > end) ++ continue; ++ if (addr_last < info->start[sect]) ++ continue; ++ ++ if (addr_first == info->start[sect]) ++ s_first[bank] = sect; ++ if (addr_last == end) ++ s_last[bank] = sect; ++ } ++ if (s_first[bank] >= 0) { ++ if (s_last[bank] < 0) { ++ if (addr_last > b_end) { ++ s_last[bank] = s_end; ++ } else { ++ printf("Error: end address not on sector boundary\n"); ++ rcode = 1; ++ break; ++ } ++ } ++ if (s_last[bank] < s_first[bank]) { ++ printf("Error: end sector precedes start sector\n"); ++ rcode = 1; ++ break; ++ } ++ sect = s_last[bank]; ++ addr_first = (sect == s_end) ? b_end + 1 : ++ info->start[sect + 1]; ++ (*s_count) += s_last[bank] - s_first[bank] + 1; ++ } else if (addr_first >= info->start[0] && addr_first < b_end) { ++ printf("Error: start address not on sector boundary\n"); ++ rcode = 1; ++ break; ++ } else if (s_last[bank] >= 0) { ++ printf("Error: cannot span across banks when they are mapped in reverse order\n"); ++ rcode = 1; ++ break; ++ } ++ } ++ ++ return rcode; ++} ++ ++static int protect_flash_sector(int state, ulong addr_first, ulong addr_last) ++{ ++ flash_info_t *info; ++ ulong bank; ++ int s_first[CONFIG_SYS_MAX_FLASH_BANKS], ++ s_last[CONFIG_SYS_MAX_FLASH_BANKS]; ++ int protected = 0; ++ int planned; ++ int rcode, i; ++ ++ rcode = fill_flash_sect_ranges(addr_first, addr_last, s_first, s_last, ++ &planned); ++ ++ if (planned && (rcode == 0)) { ++ for (bank = 0, info = &flash_info[0]; ++ bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank, ++info) { ++ if (info->flash_id == FLASH_UNKNOWN) ++ continue; ++ ++ if (s_first[bank] >= 0 && ++ s_first[bank] <= s_last[bank]) { ++ debug("%sProtecting sectors %d..%d in bank %ld\n", ++ state ? "" : "Un-", s_first[bank], ++ s_last[bank], bank + 1); ++ protected ++ += s_last[bank] - s_first[bank] + 1; ++ for (i = s_first[bank]; i <= s_last[bank]; ++i) ++ info->protect[i] = state; ++ } ++ } ++ printf("%sProtected %d sectors\n", state ? "" : "Un-", ++ protected); ++ } else if (rcode == 0) { ++ printf("Error: start and/or end address not on sector boundary\n"); ++ rcode = 1; ++ } ++ ++ return rcode; ++} ++ ++static int erase_flash_sector(ulong addr_first, ulong addr_last) ++{ ++ flash_info_t *info; ++ ulong bank; ++ int s_first[CONFIG_SYS_MAX_FLASH_BANKS]; ++ int s_last[CONFIG_SYS_MAX_FLASH_BANKS]; ++ int erased = 0; ++ int planned; ++ int rcode = 0; ++ ++ rcode = fill_flash_sect_ranges(addr_first, addr_last, s_first, s_last, ++ &planned); ++ ++ if (planned && (rcode == 0)) { ++ for (bank = 0, info = &flash_info[0]; ++ (bank < CONFIG_SYS_MAX_FLASH_BANKS) && (rcode == 0); ++ ++bank, ++info) { ++ if (s_first[bank] >= 0) { ++ erased += s_last[bank] - s_first[bank] + 1; ++ debug("Erase Flash from 0x%08lx to 0x%08lx " ++ "in Bank # %ld ", ++ info->start[s_first[bank]], ++ (s_last[bank] == info->sector_count) ? ++ info->start[0] + info->size - 1 : ++ info->start[s_last[bank] + 1] - 1, ++ bank + 1); ++ rcode = flash_erase(info, s_first[bank], ++ s_last[bank]); ++ } ++ } ++ if (rcode == 0) ++ printf("Erased %d sectors\n", erased); ++ } else if (rcode == 0) { ++ printf("Error: start and/or end address not on sector boundary\n"); ++ rcode = 1; ++ } ++ ++ return rcode; ++} ++ ++static int verify_image(void) ++{ ++ ulong src_addr = IMAGE_LOAD_RAM_ADDR; ++ void *hdr = (void *)src_addr; ++ ++ printf("\n## Checking Image at 0x%08lx ...\n", src_addr); ++ /* AT the moment, we only support FIT image flash */ ++ switch (genimg_get_format(hdr)) { ++ case IMAGE_FORMAT_FIT: ++ printf(" FIT image found\n"); ++ if (!fit_check_format(hdr)) { ++ printf("Bad FIT image format!\n"); ++ return -1; ++ } ++ ++ if (!fit_all_image_verify(hdr)) { ++ printf("Bad hash in FIT image!\n"); ++ return -1; ++ } ++ break; ++ default: ++ printf("Unknown image format!\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int flash_image(void) ++{ ++ int rcode; ++ ulong max_size = MAX_FITIMAGE_SIZE; ++ ulong src_addr = IMAGE_LOAD_RAM_ADDR; ++ ulong addr_first = get_flash_image_address(); ++ ulong addr_last = addr_first + max_size - 1; ++ ++ if ((g_write_addr > max_size) || (g_write_addr == 0)) { ++ printf("ERROR: %s(): Invalid file uploaded. filesize(0x%08x)\n", ++ __func__, g_write_addr); ++ return -1; ++ } ++ ++ if (sect_roundb(&addr_last) > 0) { ++ printf("ERROR: %s(): sect_roundb failed\n", __func__); ++ return -1; ++ } ++ ++ if (addr_first >= addr_last) { ++ printf("ERROR: %s(): addr_first(0x%08lx) >= addr_last(0x%08lx)\n", ++ __func__, addr_first, addr_last); ++ return -1; ++ } ++ ++ /* Hack: To update the percentage update, ++ * treat logical division as below. ++ * Image verify - 10% ++ * Unprotecting flash sectors - 10% ++ * Erase flash sectors - 40% ++ * Copy to flash - 40% */ ++ ++ /* Unprotect the flash sectors */ ++ rcode = protect_flash_sector(PROTECT_OFF, addr_first, addr_last); ++ if (rcode != 0) { ++ printf("%s(): Protecting flash sector failed(%d).\n", __func__, ++ rcode); ++ return -1; ++ } ++ update_processing_status(IMG_PROGRAMMING, 20); ++ ++ /* erase flash sectors */ ++ rcode = erase_flash_sector(addr_first, addr_last); ++ if (rcode != 0) { ++ printf("%s(): Erasing flash sector failed(%d).\n", __func__, ++ rcode); ++ return -1; ++ } ++ update_processing_status(IMG_PROGRAMMING, 60); ++ ++ /* write to flash area */ ++ printf("Copy to Flash... "); ++ rcode = flash_write((char *)src_addr, addr_first, g_write_addr * 1); ++ if (rcode != 0) { ++ printf("%s(): Flash copy failed(%d).\n", __func__, rcode); ++ flash_perror(rcode); ++ return -1; ++ } ++ printf("done\n"); ++ return 0; ++} ++ ++void start_fw_update_loop(void) ++{ ++ int rc; ++ ulong boot_addr; ++ char boot_cmd[20]; ++ ++ while (1) { ++ if (g_fwupd_settings.random_number_valid) { ++ /* Random number should be cleared after 30seconds */ ++ if (get_ticks() >= etime) { ++ printf("Clearing random number\n"); ++ ++ if (!fwupd_settings_trylock()) ++ continue; ++ memcpy(g_fwupd_settings.rand_num, 0, ++ RAND_NUMBER_SIZE); ++ g_fwupd_settings.random_number_valid = false; ++ fwupd_settings_unlock(); ++ } ++ } ++ ++ if (g_fwupd_settings.start_update) { ++ update_processing_status(IMG_VALIDATING, 0); ++ ++ rc = verify_image(); ++ if (rc != 0) { ++ update_processing_status(UPDATE_ERROR, 100); ++ /* Adding delay to make consumer gets status */ ++ mdelay(WAIT_STATE_TIMEOUT); ++ ++ reset_all_settings(); ++ continue; ++ } ++ ++ update_processing_status(IMG_PROGRAMMING, 10); ++ ++ rc = flash_image(); ++ if (rc == 0) { ++ /* Update successful, change the boot command */ ++ boot_addr = get_flash_image_address(); ++ snprintf(boot_cmd, sizeof(boot_cmd), ++ "bootm %08x", boot_addr); ++ setenv("bootcmd", boot_cmd); ++ saveenv(); ++ ++ update_processing_status(UPDATE_SUCCESSFUL, ++ 100); ++ } else { ++ update_processing_status(UPDATE_ERROR, 100); ++ } ++ ++ /* Adding delay to make sure consumer gets status */ ++ mdelay(WAIT_STATE_TIMEOUT); ++ ++ reset_all_settings(); ++ ++ /* Reset BMC */ ++ do_reset(NULL, 0, 0, NULL); ++ } ++ mdelay(WAIT_STATE_TIMEOUT); ++ } ++ ++ return; ++} ++ ++#if 1 /* Debug purpose */ ++int do_fwupd(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) ++{ ++ if (argc != 1) ++ return 1; ++ ++ start_fw_update_loop(); ++ return 0; ++} ++U_BOOT_CMD(fwupd, 1, 0, do_fwupd, "Start Firmware update process", ""); ++#endif +diff --git a/board/aspeed/ast-g5/fw-update.h b/board/aspeed/ast-g5/fw-update.h +new file mode 100644 +index 0000000..ed033ad +--- /dev/null ++++ b/board/aspeed/ast-g5/fw-update.h +@@ -0,0 +1,50 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// Copyright (c) 2018-2019 Intel Corporation ++ ++#include <common.h> ++ ++/* SPI flash map */ ++#define MAX_FITIMAGE_SIZE 0x1B80000 ++#define PRIMARY_FITIMAGE_START_ADDR 0x20080000 ++#define SECONDARY_FITIMAGE_START_ADDR 0x22480000 ++#define IMAGE_LOAD_RAM_ADDR 0x83000000 ++ ++#define MAX_FILENAME_LENGTH 256 ++#define RAND_NUMBER_SIZE 8 ++ ++enum boot_image { ++ PRIMARY_IMAGE = 0x01, ++ SECONDARY_IMAGE = 0x02 ++}; ++ ++enum update_status { ++ INITIALIZING = 0, ++ IDLE, ++ IMG_DOWNLOADING, ++ IMG_VALIDATING, ++ IMG_PROGRAMMING, ++ UPDATE_SUCCESSFUL, ++ UPDATE_ERROR = 0x0F, ++ UPDATE_FORBIDDEN = 0x80, ++ AC_CYCLE_REQUIRED = 0x83 ++}; ++ ++struct fwupd_global_setting { ++ bool fwupd_mode_active; ++ bool start_update; ++ bool random_number_valid; ++ u8 ctrl_state; ++ u8 options_mask; ++ u8 options_value; ++ u8 processing_status; ++ u8 percentage_completion; ++ u8 integrity_check_status; ++ u8 filename_len; ++ u8 filename[MAX_FILENAME_LENGTH]; ++ u8 rand_num[RAND_NUMBER_SIZE]; ++}; ++ ++bool fwupd_settings_trylock(void); ++void fwupd_settings_unlock(void); ++u8 get_active_boot_image(void); ++int generate_random_number(void); +diff --git a/board/aspeed/ast-g5/ipmi-fwupd.c b/board/aspeed/ast-g5/ipmi-fwupd.c +new file mode 100644 +index 0000000..3eba056 +--- /dev/null ++++ b/board/aspeed/ast-g5/ipmi-fwupd.c +@@ -0,0 +1,402 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// Copyright (c) 2018-2019 Intel Corporation ++ ++#include "ipmi-fwupd.h" ++ ++struct fwupd_global_setting g_fwupd_settings; ++u32 g_write_addr = 0; ++ ++u16 fwupd_get_execution_ctx(u8 *req, u16 req_len, u8 *res) ++{ ++ int booting_image = 0x01; ++ struct fwupd_get_exe_ctx_res *result = ++ (struct fwupd_get_exe_ctx_res *)res; ++ ++ /* Get active image location(primary/secondary) */ ++ booting_image = get_active_boot_image(); ++ result->patition_ptr = booting_image; ++ result->exection_ctx = 0x11; /* Forced Firmware Update mode */ ++ ++ result->completion_code = IPMI_CC_OK; ++ return sizeof(struct fwupd_get_exe_ctx_res); ++} ++u16 fwupd_get_rand_number(u8 *req, u16 req_len, u8 *res) ++{ ++ struct fwupd_rand_num_res *result = (struct fwupd_rand_num_res *)res; ++ ++ if (req_len != 0) { ++ printf("%s(): Invalid request length\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH; ++ return sizeof(result->completion_code); ++ } ++ ++ /* Check is critical operation is going on */ ++ if (g_fwupd_settings.start_update) { ++ printf("%s(): Update in progress.\n", __func__); ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ ++ /* Check is it already in fwupdate mode */ ++ if (g_fwupd_settings.fwupd_mode_active) { ++ printf("%s(): Already in firmware update mode\n", __func__); ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ ++ if (generate_random_number() != 0) { ++ printf("%s(): Random number generation failed\n", __func__); ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ ++ result->completion_code = IPMI_CC_OK; ++ memcpy(result->rand_num, g_fwupd_settings.rand_num, RAND_NUMBER_SIZE); ++ ++ return sizeof(struct fwupd_rand_num_res); ++} ++ ++u16 fwupd_enter_update_mode(u8 *req, u16 req_len, u8 *res) ++{ ++ struct fwupd_set_update_mode_res *result = ++ (struct fwupd_set_update_mode_res *)res; ++ ++ if (req_len != RAND_NUMBER_SIZE) { ++ printf("%s(): Invalid request length\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH; ++ return sizeof(result->completion_code); ++ } ++ ++ /* Check is critical operation is going on */ ++ if (g_fwupd_settings.start_update) { ++ printf("%s(): Update in progress.\n", __func__); ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ ++ /* Check is it already in fwupdate mode */ ++ if (g_fwupd_settings.fwupd_mode_active) { ++ printf("%s(): Already in firmware update mode\n", __func__); ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ ++ /* This command should excute within 30 seconds ++ * after random number generation. */ ++ if (!g_fwupd_settings.random_number_valid) { ++ printf("%s(): No valid random number exist.\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_CODE; ++ return sizeof(result->completion_code); ++ } ++ ++ /* Validate the key to enter this mode */ ++ for (int i = 0; i < RAND_NUMBER_SIZE; i++) { ++ if (req[i] != g_fwupd_settings.rand_num[i]) { ++ printf("%s(): Invalid key entered\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_CODE; ++ return sizeof(result->completion_code); ++ } ++ } ++ ++ if (!fwupd_settings_trylock()) { ++ printf("%s(): Lock failed\n", __func__); ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ /* Reset all the settings */ ++ memset(&g_fwupd_settings, 0, sizeof(g_fwupd_settings)); ++ g_fwupd_settings.fwupd_mode_active = true; ++ fwupd_settings_unlock(); ++ ++ result->completion_code = IPMI_CC_OK; ++ ++ return sizeof(struct fwupd_set_update_mode_res); ++} ++ ++u16 fwupd_exit_update_mode(u8 *req, u16 req_len, u8 *res) ++{ ++ struct fwupd_exit_update_mode_res *result = ++ (struct fwupd_exit_update_mode_res *)res; ++ ++ if (req_len != 0) { ++ printf("%s(): Invalid request length\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH; ++ return sizeof(result->completion_code); ++ } ++ ++ if (!g_fwupd_settings.fwupd_mode_active) { ++ printf("%s(): Invalid command entered\n", __func__); ++ result->completion_code = IPMI_CC_NOT_SUPPORTED_IN_STATE; ++ return sizeof(result->completion_code); ++ } ++ ++ if (!fwupd_settings_trylock()) { ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ g_fwupd_settings.fwupd_mode_active = false; ++ fwupd_settings_unlock(); ++ ++ result->completion_code = IPMI_CC_OK; ++ ++ return sizeof(struct fwupd_exit_update_mode_res); ++} ++u16 fwupd_set_options(u8 *req, u16 req_len, u8 *res) ++{ ++ struct fwupd_options_req *options_req = (struct fwupd_options_req *)req; ++ struct fwupd_options_res *result = (struct fwupd_options_res *)res; ++ ++ if (req_len < 2) { ++ printf("%s(): Invalid request length\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH; ++ return sizeof(result->completion_code); ++ } ++ ++ /* Check is critical operation is going on */ ++ if (g_fwupd_settings.start_update) { ++ printf("%s(): Update in progress.\n", __func__); ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ ++ /* Setting any reserved bits will result the command being rejected */ ++ if (((options_req->options_mask & 0xF0) != 0) || ++ ((options_req->options_value & 0xF0) != 0)) { ++ printf("%s(): Invalid request\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_DATA_FIELD; ++ return sizeof(result->completion_code); ++ } ++ ++ if (!fwupd_settings_trylock()) { ++ printf("%s(): Lock failed\n", __func__); ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ g_fwupd_settings.options_mask = options_req->options_mask; ++ g_fwupd_settings.options_value = options_req->options_value; ++ fwupd_settings_unlock(); ++ ++ result->completion_code = IPMI_CC_OK; ++ result->options_value = (g_fwupd_settings.options_mask & ++ g_fwupd_settings.options_value); ++ ++ return sizeof(struct fwupd_options_res); ++} ++ ++u16 fwupd_set_get_control(u8 *req, u16 req_len, u8 *res) ++{ ++ struct fwupd_control_req *ctrl_req = (struct fwupd_control_req *)req; ++ struct fwupd_control_res *result = (struct fwupd_control_res *)res; ++ ++ if (req_len < 1) { ++ printf("%s(): Invalid request length\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH; ++ return sizeof(result->completion_code); ++ } ++ ++ /* Check is critical operation is going on */ ++ if (g_fwupd_settings.start_update) { ++ printf("%s(): Update in progress.\n", __func__); ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ ++ if ((ctrl_req->ctrl_state == SET_FW_FILENAME) && (req_len < 3)) { ++ printf("%s(): Invalid request data\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH; ++ return sizeof(result->completion_code); ++ } else if ((ctrl_req->ctrl_state != SET_FW_FILENAME) && ++ (req_len != 1)) { ++ printf("%s(): Invalid request data\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH; ++ return sizeof(result->completion_code); ++ } ++ ++ if ((!g_fwupd_settings.fwupd_mode_active) && ++ (ctrl_req->ctrl_state != GET_CTRL_STATE)) { ++ printf("%s(): Invalid request. Control State: %d.\n", __func__, ++ ctrl_req->ctrl_state); ++ result->completion_code = IPMI_CC_NOT_SUPPORTED_IN_STATE; ++ return sizeof(result->completion_code); ++ } ++ ++ switch (ctrl_req->ctrl_state) { ++ case GET_CTRL_STATE: ++ break; ++ case IMG_TRANSFER_START: ++ if ((g_fwupd_settings.ctrl_state & ++ IMG_TRANSFER_CTRL_BIT_START)) { ++ printf("%s(): Invalid request\n", __func__); ++ result->completion_code = ++ IPMI_CC_NOT_SUPPORTED_IN_STATE; ++ return sizeof(result->completion_code); ++ } ++ ++ if (!fwupd_settings_trylock()) { ++ printf("%s(): Lock failed\n", __func__); ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ g_fwupd_settings.processing_status = IMG_DOWNLOADING; ++ /* Reset control state during start */ ++ g_fwupd_settings.ctrl_state = 0x00; ++ g_fwupd_settings.ctrl_state |= IMG_TRANSFER_CTRL_BIT_START; ++ /* Set current write address to ZERO */ ++ g_write_addr = 0x00; ++ fwupd_settings_unlock(); ++ break; ++ case IMG_TRANSFER_END: ++ if (!(g_fwupd_settings.ctrl_state & ++ IMG_TRANSFER_CTRL_BIT_START)) { ++ printf("%s(): Invalid request\n", __func__); ++ result->completion_code = ++ IPMI_CC_NOT_SUPPORTED_IN_STATE; ++ return sizeof(result->completion_code); ++ } ++ ++ if (!fwupd_settings_trylock()) { ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ g_fwupd_settings.start_update = true; ++ g_fwupd_settings.ctrl_state |= IMG_TRANSFER_CTRL_BIT_END; ++ ++ g_fwupd_settings.ctrl_state &= ~(IMG_TRANSFER_CTRL_BIT_START | ++ IMG_TRANSFER_CTRL_BIT_ABORT); ++ fwupd_settings_unlock(); ++ break; ++ case IMG_TRANSFER_ABORT: ++ if (!(g_fwupd_settings.ctrl_state & ++ IMG_TRANSFER_CTRL_BIT_START)) { ++ printf("%s(): Invalid request\n", __func__); ++ result->completion_code = ++ IPMI_CC_NOT_SUPPORTED_IN_STATE; ++ return sizeof(result->completion_code); ++ } ++ ++ if (!fwupd_settings_trylock()) { ++ printf("%s(): Lock failed\n", __func__); ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ g_fwupd_settings.processing_status = UPDATE_ERROR; ++ g_fwupd_settings.ctrl_state |= IMG_TRANSFER_CTRL_BIT_ABORT; ++ g_fwupd_settings.ctrl_state &= ~(IMG_TRANSFER_CTRL_BIT_START | ++ IMG_TRANSFER_CTRL_BIT_END); ++ fwupd_settings_unlock(); ++ break; ++ case SET_FW_FILENAME: ++ /* Not supporting now */ ++ if (ctrl_req->filename_len > sizeof(ctrl_req->filename)) { ++ printf("%s(): Invalid request\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_DATA_FIELD; ++ return sizeof(result->completion_code); ++ } ++ ++ if (!(g_fwupd_settings.ctrl_state & ++ IMG_TRANSFER_CTRL_BIT_START)) { ++ printf("%s(): Invalid request\n", __func__); ++ result->completion_code = ++ IPMI_CC_NOT_SUPPORTED_IN_STATE; ++ return sizeof(result->completion_code); ++ } ++ ++ if (!fwupd_settings_trylock()) { ++ printf("%s(): Lock failed\n", __func__); ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ g_fwupd_settings.filename_len = ctrl_req->filename_len; ++ strncpy(g_fwupd_settings.filename, ctrl_req->filename, ++ ctrl_req->filename_len); ++ fwupd_settings_unlock(); ++ /* TODO: Used for TFTP update but not implemented yet. */ ++ /* TODO: Verify image and write to flash */ ++ break; ++ case USB_DEV_ATTACH: ++ /* Not supporting now */ ++ result->completion_code = IPMI_CC_NOT_SUPPORTED_IN_STATE; ++ return sizeof(result->completion_code); ++ case USB_DEV_DETACH: ++ /* Not supporting now */ ++ result->completion_code = IPMI_CC_NOT_SUPPORTED_IN_STATE; ++ return sizeof(result->completion_code); ++ break; ++ default: ++ printf("%s(): Invalid request\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_DATA_FIELD; ++ return sizeof(result->completion_code); ++ } ++ ++ result->completion_code = IPMI_CC_OK; ++ result->curr_state = g_fwupd_settings.ctrl_state; ++ return sizeof(struct fwupd_control_res); ++} ++u16 fwupd_get_update_status(u8 *req, u16 req_len, u8 *res) ++{ ++ struct fwupd_get_update_status_res *result = ++ (struct fwupd_get_update_status_res *)res; ++ ++ if (req_len != 0) { ++ printf("%s(): Invalid request length\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH; ++ return sizeof(result->completion_code); ++ } ++ ++ result->processing_status = g_fwupd_settings.processing_status; ++ result->percent_completion = g_fwupd_settings.percentage_completion; ++ result->check_status = 0; ++ /* We don't support error code messages cmd(0x0EH) in uboot.*/ ++ result->error_code = 0; ++ ++ result->completion_code = IPMI_CC_OK; ++ ++ return sizeof(struct fwupd_get_update_status_res); ++} ++ ++u16 fwupd_image_write(u8 *req, u16 req_len, u8 *res) ++{ ++ struct fwupd_image_write_res *result = ++ (struct fwupd_image_write_res *)res; ++ ++ if (req_len < 1) { ++ printf("%s(): Invalid request length\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH; ++ return sizeof(result->completion_code); ++ } ++ ++ /* Check is critical operation is going on */ ++ if (g_fwupd_settings.start_update) { ++ printf("%s(): Update in progress.\n", __func__); ++ result->completion_code = IPMI_CC_NODE_BUSY; ++ return sizeof(result->completion_code); ++ } ++ ++ if (!g_fwupd_settings.fwupd_mode_active) { ++ printf("%s(): Invalid request\n", __func__); ++ result->completion_code = IPMI_CC_NOT_SUPPORTED_IN_STATE; ++ return sizeof(result->completion_code); ++ } ++ ++ if (!(g_fwupd_settings.ctrl_state & IMG_TRANSFER_CTRL_BIT_START)) { ++ printf("%s(): Invalid request\n", __func__); ++ result->completion_code = IPMI_CC_NOT_SUPPORTED_IN_STATE; ++ return sizeof(result->completion_code); ++ } ++ ++ if ((g_write_addr + req_len) > MAX_FITIMAGE_SIZE) { ++ printf("%s(): Request length exceeded max size\n", __func__); ++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH; ++ return sizeof(result->completion_code); ++ } ++ ++ u8 *mem_addr = (u8 *)((u32)IMAGE_LOAD_RAM_ADDR + g_write_addr); ++ ++ memcpy(mem_addr, req, req_len); ++ g_write_addr += req_len; ++ ++ result->completion_code = IPMI_CC_OK; ++ result->no_of_bytes_written = (u8)req_len; ++ ++ return sizeof(struct fwupd_image_write_res); ++} +diff --git a/board/aspeed/ast-g5/ipmi-fwupd.h b/board/aspeed/ast-g5/ipmi-fwupd.h +new file mode 100644 +index 0000000..e490f6b +--- /dev/null ++++ b/board/aspeed/ast-g5/ipmi-fwupd.h +@@ -0,0 +1,81 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// Copyright (c) 2018-2019 Intel Corporation ++ ++#include "ipmi-handler.h" ++#include "fw-update.h" ++ ++enum control_state { ++ GET_CTRL_STATE = 0, ++ IMG_TRANSFER_START, ++ IMG_TRANSFER_END, ++ IMG_TRANSFER_ABORT, ++ SET_FW_FILENAME, ++ USB_DEV_ATTACH, ++ USB_DEV_DETACH ++}; ++enum control_state_bit { ++ IMG_TRANSFER_CTRL_BIT_START = (0x01 << 0), ++ IMG_TRANSFER_CTRL_BIT_END = (0x01 << 1), ++ IMG_TRANSFER_CTRL_BIT_ABORT = (0x01 << 2), ++ USB_CTRL_BIT_ATTACH = (0x01 << 3) ++}; ++enum update_options_bit { ++ NO_DOWN_REVISION = 0, ++ DEFER_BMC_RESET = 1, ++ SHA32_INTEGRITY_CHECK = 2, ++ CRC32_INTEGRITY_CHECK = 3 ++}; ++ ++struct fwupd_get_exe_ctx_res { ++ u8 completion_code; ++ u8 exection_ctx; ++ u8 patition_ptr; ++}; ++struct fwupd_rand_num_res { ++ u8 completion_code; ++ u8 rand_num[RAND_NUMBER_SIZE]; ++}; ++struct fwupd_set_update_mode_res { ++ u8 completion_code; ++}; ++struct fwupd_exit_update_mode_res { ++ u8 completion_code; ++}; ++struct fwupd_options_req { ++ u8 options_mask; ++ u8 options_value; ++ u8 integrity_check_value[32]; ++}; ++struct fwupd_options_res { ++ u8 completion_code; ++ u8 options_value; ++}; ++struct fwupd_control_req { ++ u8 ctrl_state; ++ u8 filename_len; ++ u8 filename[MAX_FILENAME_LENGTH]; ++}; ++struct fwupd_control_res { ++ u8 completion_code; ++ u8 curr_state; ++}; ++struct fwupd_get_update_status_res { ++ u8 completion_code; ++ u8 processing_status; ++ u8 percent_completion; ++ u8 check_status; ++ u8 error_code; ++}; ++struct fwupd_image_write_res { ++ u8 completion_code; ++ u8 no_of_bytes_written; ++}; ++ ++u16 fwupd_get_execution_ctx(u8 *req, u16 req_len, u8 *res); ++u16 fwupd_get_rand_number(u8 *req, u16 req_len, u8 *res); ++u16 fwupd_enter_update_mode(u8 *req, u16 req_len, u8 *res); ++u16 fwupd_exit_update_mode(u8 *req, u16 req_len, u8 *res); ++u16 fwupd_set_options(u8 *req, u16 req_len, u8 *res); ++u16 fwupd_set_get_control(u8 *req, u16 req_len, u8 *res); ++u16 fwupd_get_update_status(u8 *req, u16 req_len, u8 *res); ++u16 fwupd_image_write(u8 *req, u16 req_len, u8 *res); +diff --git a/board/aspeed/ast-g5/ipmi-handler.c b/board/aspeed/ast-g5/ipmi-handler.c +index 9cccee9..5e78546 100644 +--- a/board/aspeed/ast-g5/ipmi-handler.c ++++ b/board/aspeed/ast-g5/ipmi-handler.c +@@ -1,18 +1,37 @@ +- + // SPDX-License-Identifier: GPL-2.0 + // Copyright (c) 2018-2019 Intel Corporation + +-#include "ipmi-handler.h" ++#include "ipmi-fwupd.h" + + /* IPMI network function codes */ + #define NETFN_APP 0x06 ++#define NETFN_FIRMWARE 0x08 ++#define NETFN_INTEL_OEM 0x30 + + /* IPMI command codes */ +-#define CMD_GET_DEV_ID 0x01 +-#define CMD_GET_SELF_TEST_RESULTS 0x04 ++#define CMD_APP_GET_DEV_ID 0x01 ++#define CMD_APP_GET_SELF_TEST_RESULTS 0x04 ++#define CMD_FWUPD_GET_EXECUTION_CTX 0x23 ++#define CMD_FWUPD_GET_RANDOM_NUMBER 0x26 ++#define CMD_FWUPD_SET_UPDATE_MODE 0x27 ++#define CMD_FWUPD_EXIT_UPDATE_MODE 0x28 ++#define CMD_FWUPD_CONTROL_GET_SET 0x29 ++#define CMD_FWUPD_GET_UPDATE_STATUS 0x2A ++#define CMD_FWUPD_SET_OPTIONS 0x2B ++#define CMD_FWUPD_IMAGE_WRITE 0x2C ++#define CMD_INTL_OEM_GET_BUFFER_SIZE 0x66 ++ ++#define MAX_KCS_BUF_SIZE 1020 /* (0xFF * 4) */ ++#define MAX_IPMB_BUF_SIZE 1020 /* (0xFF * 4) */ + + typedef u16 (*fun_handler)(u8 *req, u16 req_len, u8 *res); + ++struct ipmi_cmd_table { ++ u8 net_fun; ++ u8 cmd; ++ fun_handler process_cmd; ++}; ++ + struct get_dev_id { + u8 completion_code; + u8 dev_id; +@@ -29,11 +48,10 @@ struct self_test_res { + u8 completion_code; + u8 res_byte[2]; + }; +- +-struct ipmi_cmd_table { +- u8 net_fun; +- u8 cmd; +- fun_handler process_cmd; ++struct intc_get_buf_size_res { ++ u8 completion_code; ++ u8 kcs_size; ++ u8 ipmb_size; + }; + + static u16 get_device_id(u8 *req, u16 req_len, u8 *res) +@@ -84,10 +102,36 @@ static u16 get_self_test_result(u8 *req, u16 req_len, u8 *res) + + return sizeof(struct self_test_res); + } ++static u16 intel_get_buffer_size(u8 *req, u16 req_len, u8 *res) ++{ ++ struct intc_get_buf_size_res *result = ++ (struct intc_get_buf_size_res *)res; ++ ++ if (req_len != 0) { ++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH; ++ return sizeof(result->completion_code); ++ } ++ ++ /* Size is multiples of four bytes */ ++ result->completion_code = IPMI_CC_OK; ++ result->kcs_size = MAX_KCS_BUF_SIZE / 4; ++ result->ipmb_size = MAX_IPMB_BUF_SIZE / 4; ++ ++ return sizeof(struct intc_get_buf_size_res); ++} + + const struct ipmi_cmd_table cmd_info[] = { +- { NETFN_APP, CMD_GET_DEV_ID, get_device_id }, +- { NETFN_APP, CMD_GET_SELF_TEST_RESULTS, get_self_test_result } ++ { NETFN_APP, CMD_APP_GET_DEV_ID, get_device_id }, ++ { NETFN_APP, CMD_APP_GET_SELF_TEST_RESULTS, get_self_test_result }, ++ { NETFN_FIRMWARE, CMD_FWUPD_GET_EXECUTION_CTX, fwupd_get_execution_ctx }, ++ { NETFN_FIRMWARE, CMD_FWUPD_GET_RANDOM_NUMBER, fwupd_get_rand_number }, ++ { NETFN_FIRMWARE, CMD_FWUPD_SET_UPDATE_MODE, fwupd_enter_update_mode }, ++ { NETFN_FIRMWARE, CMD_FWUPD_EXIT_UPDATE_MODE, fwupd_exit_update_mode }, ++ { NETFN_FIRMWARE, CMD_FWUPD_CONTROL_GET_SET, fwupd_set_get_control }, ++ { NETFN_FIRMWARE, CMD_FWUPD_GET_UPDATE_STATUS, fwupd_get_update_status }, ++ { NETFN_FIRMWARE, CMD_FWUPD_SET_OPTIONS, fwupd_set_options }, ++ { NETFN_FIRMWARE, CMD_FWUPD_IMAGE_WRITE, fwupd_image_write }, ++ { NETFN_INTEL_OEM, CMD_INTL_OEM_GET_BUFFER_SIZE, intel_get_buffer_size } + }; + + #define CMD_TABLE_SIZE ARRAY_SIZE(cmd_info) +diff --git a/board/aspeed/ast-g5/ipmi-handler.h b/board/aspeed/ast-g5/ipmi-handler.h +index 9d46d9b..8eea930 100644 +--- a/board/aspeed/ast-g5/ipmi-handler.h ++++ b/board/aspeed/ast-g5/ipmi-handler.h +@@ -1,4 +1,3 @@ +- + /* SPDX-License-Identifier: GPL-2.0 */ + /* Copyright (c) 2018-2019 Intel Corporation */ + +@@ -6,12 +5,14 @@ + + /* IPMI completion codes */ + #define IPMI_CC_OK 0x00 ++#define IPMI_CC_INVALID_CODE 0x80 + #define IPMI_CC_NODE_BUSY 0xC0 + #define IPMI_CC_INVALID_CMD 0xC1 + #define IPMI_CC_INVALID_CMD_LUN 0xC2 + #define IPMI_CC_OUT_OF_SPACE 0xC4 + #define IPMI_CC_INVALID_DATA_LENGTH 0xC7 + #define IPMI_CC_INVALID_DATA_FIELD 0xCC ++#define IPMI_CC_NOT_SUPPORTED_IN_STATE 0xD5 + #define IPMI_CC_UNSPECIFIED 0xFF + + /* BMC IPMB LUNs */ +diff --git a/common/autoboot.c b/common/autoboot.c +index d66c0fa..45a600e 100644 +--- a/common/autoboot.c ++++ b/common/autoboot.c +@@ -349,6 +349,17 @@ void autoboot_command(const char *s) + { + debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>"); + ++#ifdef AST_G5_INTEL ++ /* TODO: Make run_command_list as non-blocking(blocked by getc()) ++ * and make main u-boot loop to check both keyboard inputs as well ++ * as start_update firmware flags during FFUJ. ++ * This will make sure debug mode intact during FFUJ. ++ */ ++ if (intel_force_firmware_jumper_enabled()) { ++ start_fw_update_loop(); ++ } ++#endif ++ + if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) { + #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) + int prev = disable_ctrlc(1); /* disable Control C checking */ +diff --git a/configs/ast_g5_phy_defconfig b/configs/ast_g5_phy_defconfig +index 47d9563..f070494 100644 +--- a/configs/ast_g5_phy_defconfig ++++ b/configs/ast_g5_phy_defconfig +@@ -17,3 +17,4 @@ CONFIG_SYS_NS16550=y + CONFIG_USE_IRQ=y + CONFIG_CMD_I2C=y + CONFIG_SYS_I2C_AST=y ++CONFIG_LIB_RAND=y +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend index 798e43295..acac46d70 100644 --- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend @@ -19,9 +19,6 @@ SRC_URI_append_intel-ast2500 = " \ file://0013-aspeed-Add-Pwm-Driver.patch \ file://0014-Keep-interrupts-enabled-until-last-second.patch \ file://0015-Rewrite-memmove-to-optimize-on-word-transfers.patch \ - file://0016-Add-support-for-128MB-Macronix-spi-flash-MX66L1G45G.patch \ - file://0017-Enable-Macronix-and-Micron-SPI-support.patch \ - file://0018-Add-support-for-Macronix-and-Micron-1Gbits-SPI-flash.patch \ file://0019-u-boot-full-platform-reset-espi-oob-ready.patch \ file://0020-Enable-PCIe-L1-support.patch \ file://0020-Add-system-reset-status-support.patch \ @@ -33,11 +30,21 @@ SRC_URI_append_intel-ast2500 = " \ file://0026-Aspeed-I2C-support-in-U-Boot.patch \ file://0027-CPLD-u-boot-commands-support-for-PFR.patch \ file://0028-Enabling-uart1-uart2-in-u-boot-for-BIOS-messages.patch \ + file://0029-FFUJ-FW-IPMI-commands-and-flash-support-in-u-boot.patch \ " SRC_URI_append_intel-ast2500 += "${@bb.utils.contains('IMAGE_TYPE', 'pfr', 'file://0022-u-boot-env-change-for-PFR-image.patch', '', d)}" require recipes-core/os-release/version-vars.inc -BUILD_CFLAGS_append = " -DVER_MAJOR=${IPMI_MAJOR} -DVER_MINOR=${IPMI_MINOR}" -BUILD_CFLAGS_append += " -DVER_AUX13=${IPMI_AUX13} -DVER_AUX14=${IPMI_AUX14}" -BUILD_CFLAGS_append += " -DVER_AUX15=${IPMI_AUX15} -DVER_AUX16=${IPMI_AUX16}" +python do_version () { + with open(d.expand('${S}/board/aspeed/ast-g5/intel-version.h'), 'w') as f: + f.write(d.expand('#define VER_MAJOR ${IPMI_MAJOR}\n')) + f.write(d.expand('#define VER_MINOR ${IPMI_MINOR}\n')) + f.write(d.expand('#define VER_AUX13 ${IPMI_AUX13}\n')) + f.write(d.expand('#define VER_AUX14 ${IPMI_AUX14}\n')) + f.write(d.expand('#define VER_AUX15 ${IPMI_AUX15}\n')) + f.write(d.expand('#define VER_AUX16 ${IPMI_AUX16}\n')) +} + +do_version[vardepsexclude] = "IPMI_MAJOR IPMI_MINOR IPMI_AUX13 IPMI_AUX14 IPMI_AUX15 IPMI_AUX16 PRODUCT_GENERATION VERSION VERSION_ID BUILD_ID" +addtask do_version after do_configure before do_compile diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-fw-utils-aspeed_%.bbappend b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-fw-utils-aspeed_%.bbappend index 742334ade..acac46d70 120000..100644 --- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-fw-utils-aspeed_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-fw-utils-aspeed_%.bbappend @@ -1 +1,50 @@ -u-boot-aspeed_%.bbappend
\ No newline at end of file +FILESEXTRAPATHS_append_intel-ast2500:= "${THISDIR}/files:" + +# the meta-phosphor layer adds this patch, which conflicts +# with the intel layout for environment +SRC_URI_remove_intel-ast2500 = " file://0001-configs-ast-Add-redundnant-env.patch" + +SRC_URI_append_intel-ast2500 = " \ + file://0001-flash-use-readX-writeX-not-udelay.patch \ + file://0002-intel-layout-environment-addr.patch \ + file://0004-Make-sure-debug-uart-is-using-24MHz-clock-source.patch \ + file://0005-enable-passthrough-in-uboot.patch \ + file://0006-Add-Aspeed-g5-interrupt-support.patch \ + file://0007-Add-espi-support.patch \ + file://0008-add-sgio-support-for-port80-snoop-post-LEDs.patch \ + file://0009-Add-basic-GPIO-support.patch \ + file://0010-Update-Force-Firmware-Update-Jumper-to-use-new-gpio.patch \ + file://0011-Add-basic-timer-support-for-Aspeed-g5-in-U-Boot.patch \ + file://0012-Add-status-and-ID-LED-support.patch \ + file://0013-aspeed-Add-Pwm-Driver.patch \ + file://0014-Keep-interrupts-enabled-until-last-second.patch \ + file://0015-Rewrite-memmove-to-optimize-on-word-transfers.patch \ + file://0019-u-boot-full-platform-reset-espi-oob-ready.patch \ + file://0020-Enable-PCIe-L1-support.patch \ + file://0020-Add-system-reset-status-support.patch \ + file://0021-Config-host-uart-clock-source-using-environment-vari.patch \ + file://0022-KCS-driver-support-in-uBoot.patch \ + file://0023-Add-TPM-enable-pulse-triggering.patch \ + file://0024-IPMI-command-handler-implementation-in-uboot.patch \ + file://0025-Manufacturing-mode-physical-presence-detection.patch \ + file://0026-Aspeed-I2C-support-in-U-Boot.patch \ + file://0027-CPLD-u-boot-commands-support-for-PFR.patch \ + file://0028-Enabling-uart1-uart2-in-u-boot-for-BIOS-messages.patch \ + file://0029-FFUJ-FW-IPMI-commands-and-flash-support-in-u-boot.patch \ + " +SRC_URI_append_intel-ast2500 += "${@bb.utils.contains('IMAGE_TYPE', 'pfr', 'file://0022-u-boot-env-change-for-PFR-image.patch', '', d)}" + +require recipes-core/os-release/version-vars.inc + +python do_version () { + with open(d.expand('${S}/board/aspeed/ast-g5/intel-version.h'), 'w') as f: + f.write(d.expand('#define VER_MAJOR ${IPMI_MAJOR}\n')) + f.write(d.expand('#define VER_MINOR ${IPMI_MINOR}\n')) + f.write(d.expand('#define VER_AUX13 ${IPMI_AUX13}\n')) + f.write(d.expand('#define VER_AUX14 ${IPMI_AUX14}\n')) + f.write(d.expand('#define VER_AUX15 ${IPMI_AUX15}\n')) + f.write(d.expand('#define VER_AUX16 ${IPMI_AUX16}\n')) +} + +do_version[vardepsexclude] = "IPMI_MAJOR IPMI_MINOR IPMI_AUX13 IPMI_AUX14 IPMI_AUX15 IPMI_AUX16 PRODUCT_GENERATION VERSION VERSION_ID BUILD_ID" +addtask do_version after do_configure before do_compile diff --git a/meta-openbmc-mods/meta-common/recipes-core/at-scale-debug/at-scale-debug.bb b/meta-openbmc-mods/meta-common/recipes-core/at-scale-debug/at-scale-debug.bb index fda0716c5..37ad5667f 100644 --- a/meta-openbmc-mods/meta-common/recipes-core/at-scale-debug/at-scale-debug.bb +++ b/meta-openbmc-mods/meta-common/recipes-core/at-scale-debug/at-scale-debug.bb @@ -14,7 +14,7 @@ do_configure[depends] += "virtual/kernel:do_shared_workdir" SRC_URI = "git://git@github.com/Intel-BMC/at-scale-debug;protocol=ssh" -SRCREV = "0536b8cc3591a310ab36d145540811c728f8ef60" +SRCREV = "3369d2e81f7e5e4bcb5d9e14bcecea7ae5da07fb" S = "${WORKDIR}/git" SYSTEMD_SERVICE_${PN} += "com.intel.AtScaleDebug.service" diff --git a/meta-openbmc-mods/meta-common/recipes-core/at-scale-debug/files/com.intel.AtScaleDebug.service b/meta-openbmc-mods/meta-common/recipes-core/at-scale-debug/files/com.intel.AtScaleDebug.service index 65d83b4c4..744982703 100644 --- a/meta-openbmc-mods/meta-common/recipes-core/at-scale-debug/files/com.intel.AtScaleDebug.service +++ b/meta-openbmc-mods/meta-common/recipes-core/at-scale-debug/files/com.intel.AtScaleDebug.service @@ -1,6 +1,6 @@ [Unit] Description=Intel BMC At Scale Debug -Requires=com.intel.AtScaleDebugJtagTest.service network-online.target +Requires=network-online.target [Service] Restart=always @@ -10,4 +10,4 @@ Type=simple SyslogIdentifier=asd [Install] -WantedBy=obmc-host-start@0.target +WantedBy=multi-user.target 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 a1c53389d..8f876cc9c 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 @@ -11,7 +11,7 @@ LICENSE = "CLOSED" LIC_FILES_CHKSUM = "" SRC_URI = "git://git@github.com/Intel-BMC/at-scale-debug;protocol=ssh" -SRCREV = "0536b8cc3591a310ab36d145540811c728f8ef60" +SRCREV = "3369d2e81f7e5e4bcb5d9e14bcecea7ae5da07fb" S = "${WORKDIR}/git/crashdump" PACKAGES += "libpeci" 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 22568dba2..70533e540 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 @@ -1,2 +1,2 @@ SRC_URI = "git://github.com/openbmc/intel-ipmi-oem.git" -SRCREV = "53870d7308e374df0c0382e3208ff1567a160947" +SRCREV = "ba9c1765f5edc2f0891e012f33b3059a0dbd7ff1" diff --git a/meta-openbmc-mods/meta-common/recipes-core/os-release/os-release.bbappend b/meta-openbmc-mods/meta-common/recipes-core/os-release/os-release.bbappend index 059931ed2..a47d923f8 100644 --- a/meta-openbmc-mods/meta-common/recipes-core/os-release/os-release.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-core/os-release/os-release.bbappend @@ -29,7 +29,6 @@ python do_compile_append () { # Ensure the git commands run every time bitbake is invoked. BB_DONT_CACHE = "1" -do_compile[nostamp]="1" # Make os-release available to other recipes. SYSROOT_DIRS_append = " ${sysconfdir}" diff --git a/meta-openbmc-mods/meta-common/recipes-core/peci-pcie/peci-pcie_git.bb b/meta-openbmc-mods/meta-common/recipes-core/peci-pcie/peci-pcie_git.bb index d66a14281..5061e1e56 100644 --- a/meta-openbmc-mods/meta-common/recipes-core/peci-pcie/peci-pcie_git.bb +++ b/meta-openbmc-mods/meta-common/recipes-core/peci-pcie/peci-pcie_git.bb @@ -10,7 +10,7 @@ SRC_URI = "git://git@github.com/Intel-BMC/at-scale-debug;protocol=ssh" DEPENDS = "boost sdbusplus crashdump" PV = "0.1+git${SRCPV}" -SRCREV = "0536b8cc3591a310ab36d145540811c728f8ef60" +SRCREV = "3369d2e81f7e5e4bcb5d9e14bcecea7ae5da07fb" S = "${WORKDIR}/git/peci_pcie" diff --git a/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd/systemd-time-wait-sync.service b/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd/systemd-time-wait-sync.service new file mode 100644 index 000000000..f71aea39d --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd/systemd-time-wait-sync.service @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: LGPL-2.1+ +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Wait Until Kernel Time Synchronized +Documentation=man:systemd-time-wait-sync.service(8) + +# Note that this tool doesn't need CAP_SYS_TIME itself, but it's primary +# usecase is to run in conjunction with a local NTP service such as +# systemd-timesyncd.service, which is conditioned this way. There might be +# niche usecases where running this service independently is desired, but let's +# make this all "just work" for the general case, and leave it to local +# modifications to make it work in the remaining cases. + +ConditionCapability=CAP_SYS_TIME +ConditionVirtualization=!container + +DefaultDependencies=no +Before=time-sync.target shutdown.target +Wants=time-sync.target +Conflicts=shutdown.target + +[Service] +Type=oneshot +ExecStart=/lib/systemd/systemd-time-wait-sync +TimeoutStartSec=10 +RemainAfterExit=yes + +[Install] +WantedBy=sysinit.target diff --git a/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd/systemd-timesyncd.service b/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd/systemd-timesyncd.service new file mode 100644 index 000000000..9a5fffbb3 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd/systemd-timesyncd.service @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: LGPL-2.1+ +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Network Time Synchronization +Documentation=man:systemd-timesyncd.service(8) +ConditionCapability=CAP_SYS_TIME +ConditionVirtualization=!container +DefaultDependencies=no +After=systemd-remount-fs.service systemd-sysusers.service var.mount +Before=time-set.target sysinit.target shutdown.target +Conflicts=shutdown.target +Wants=time-set.target time-sync.target + +[Service] +AmbientCapabilities=CAP_SYS_TIME +CapabilityBoundingSet=CAP_SYS_TIME +ExecStart=!!/lib/systemd/systemd-timesyncd +LockPersonality=yes +MemoryDenyWriteExecute=yes +NoNewPrivileges=yes +PrivateDevices=yes +PrivateTmp=yes +ProtectControlGroups=yes +ProtectHome=yes +ProtectHostname=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +ProtectSystem=strict +Restart=always +RestartSec=0 +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 +RestrictNamespaces=yes +RestrictRealtime=yes +RestrictSUIDSGID=yes +RuntimeDirectory=systemd/timesync +StateDirectory=systemd/timesync +SystemCallArchitectures=native +SystemCallErrorNumber=EPERM +SystemCallFilter=@system-service @clock +Type=notify +User=systemd-timesync +WatchdogSec=3min + +[Install] +WantedBy=sysinit.target +Alias=dbus-org.freedesktop.timesync1.service diff --git a/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd_%.bbappend b/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd_%.bbappend index ef7ac20e2..3e5adf7ce 100644 --- a/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd_%.bbappend @@ -6,6 +6,11 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" SRC_URI += "file://000-ro-rootfs-tmpfile-defaults.patch \ file://0001-Modfiy-system.conf-DefaultTimeoutStopSec.patch \ + file://systemd-time-wait-sync.service \ " USERADD_PACKAGES_remove = "${PN}-journal-gateway ${PN}-journal-upload ${PN}-journal-remote" + +do_install_append(){ + cp -f ${WORKDIR}/systemd-time-wait-sync.service ${D}/lib/systemd/system/ +} diff --git a/meta-openbmc-mods/meta-common/recipes-extended/sdbusplus/sdbusplus_%.bbappend b/meta-openbmc-mods/meta-common/recipes-extended/sdbusplus/sdbusplus_%.bbappend index b174f271e..af5fa8b05 100644 --- a/meta-openbmc-mods/meta-common/recipes-extended/sdbusplus/sdbusplus_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-extended/sdbusplus/sdbusplus_%.bbappend @@ -1,4 +1,4 @@ #SRC_URI += "git://github.com/openbmc/sdbusplus" -SRCREV = "c14699f63e909ed6d8599e65503ee9c1e3a104d6" +SRCREV = "f8bbf17c3db879359b0984b40250e4db3d274be1" diff --git a/meta-openbmc-mods/meta-common/recipes-intel/psu-manager/psu-manager.bb b/meta-openbmc-mods/meta-common/recipes-intel/psu-manager/psu-manager.bb new file mode 100644 index 000000000..24a8c668b --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-intel/psu-manager/psu-manager.bb @@ -0,0 +1,26 @@ +SUMMARY = "Power supply manager for Intel based platform" +DESCRIPTION = "Power supply manager which include PSU Cold Redundancy service" + +SRC_URI = "git://git-amr-2.devtools.intel.com:29418/openbmc-provingground.git;protocol=ssh;nobranch=1" +SRCREV = "fe33964c744f871f3e024dd8d0b6ffba67394c30" + +S = "${WORKDIR}/git/psu-manager/" + +PV = "1.0+git${SRCPV}" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${S}/LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" + +inherit cmake +inherit systemd + +SYSTEMD_SERVICE_${PN} += "cold-redundancy.service" + +DEPENDS += " \ + systemd \ + sdbusplus \ + phosphor-dbus-interfaces \ + phosphor-logging \ + boost \ + i2c-tools \ + " diff --git a/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv1.bb b/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv1.bb index 64645da2b..c37ea66e1 100644 --- a/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv1.bb +++ b/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv1.bb @@ -2,7 +2,7 @@ SUMMARY = "SMBIOS MDR version 1 service for Intel based platform" DESCRIPTION = "SMBIOS MDR version 1 service for Intel based platfrom" SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh" -SRCREV = "9d2d365a79591ec21b54ecde957263f1ba1d8391" +SRCREV = "4373d99e1edcbb4c7233abde3a5e53690693007b" S = "${WORKDIR}/git/services/smbios/" 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 175d5edf9..a41cdb50b 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 @@ -2,7 +2,7 @@ SUMMARY = "SMBIOS MDR version 2 service for Intel based platform" DESCRIPTION = "SMBIOS MDR version 2 service for Intel based platfrom" SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh" -SRCREV = "9d2d365a79591ec21b54ecde957263f1ba1d8391" +SRCREV = "4373d99e1edcbb4c7233abde3a5e53690693007b" S = "${WORKDIR}/git/services/smbios-mdrv2/" diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0052-drivers-jtag-Add-JTAG-core-driver.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0052-drivers-jtag-Add-JTAG-core-driver.patch index 7ba94a7bc..6c9d46d9d 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0052-drivers-jtag-Add-JTAG-core-driver.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0052-drivers-jtag-Add-JTAG-core-driver.patch @@ -1,6 +1,6 @@ From 0b8b93851bb79e70e91159f310afd4b56084977f Mon Sep 17 00:00:00 2001 From: "Corona, Ernesto" <ernesto.corona@intel.com> -Date: Mon, 6 May 2019 10:05:51 -0800 +Date: Fri, 7 Jun 2019 07:37:39 -0800 Subject: [PATCH v29 1/6] drivers: jtag: Add JTAG core driver JTAG class driver provide infrastructure to support hardware/software @@ -58,6 +58,9 @@ Comments pointed by Steven Filary <steven.a.filary@intel.com> the driver is not in use to allow other HW to own the JTAG bus. Remove SCU register accesses. This register controls the JTAG controller mode (master/slave). +- Fix static analysis issues +- Add support for multichain. Set tap state and xfer operations now include + two tap state arguments: current state and end state. v27->v28 Comments pointed by Steven Filary <steven.a.filary@intel.com> @@ -253,10 +256,10 @@ Comments pointed by Tobias Klauser <tklauser@distanz.ch> drivers/Makefile | 1 + drivers/jtag/Kconfig | 17 +++ drivers/jtag/Makefile | 1 + - drivers/jtag/jtag.c | 314 ++++++++++++++++++++++++++++++++++++++++++++++ + drivers/jtag/jtag.c | 321 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/jtag.h | 47 +++++++ - include/uapi/linux/jtag.h | 208 ++++++++++++++++++++++++++++++ - 7 files changed, 589 insertions(+) + include/uapi/linux/jtag.h | 214 ++++++++++++++++++++++++++++++ + 7 files changed, 602 insertions(+) create mode 100644 drivers/jtag/Kconfig create mode 100644 drivers/jtag/Makefile create mode 100644 drivers/jtag/jtag.c @@ -317,7 +320,7 @@ new file mode 100644 index 0000000..47503a1 --- /dev/null +++ b/drivers/jtag/jtag.c -@@ -0,0 +1,314 @@ +@@ -0,0 +1,321 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2018 Mellanox Technologies. All rights reserved. +// Copyright (c) 2018 Oleksandr Shamray <oleksandrs@mellanox.com> @@ -353,7 +356,7 @@ index 0000000..47503a1 +static long jtag_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct jtag *jtag = file->private_data; -+ struct jtag_end_tap_state endstate; ++ struct jtag_tap_state tapstate; + struct jtag_xfer xfer; + struct bitbang_packet bitbang; + struct tck_bitbang *bitbang_data; @@ -392,17 +395,20 @@ index 0000000..47503a1 + break; + + case JTAG_SIOCSTATE: -+ if (copy_from_user(&endstate, (const void __user *)arg, -+ sizeof(struct jtag_end_tap_state))) ++ if (copy_from_user(&tapstate, (const void __user *)arg, ++ sizeof(struct jtag_tap_state))) + return -EFAULT; + -+ if (endstate.endstate > JTAG_STATE_UPDATEIR) ++ if (tapstate.from > JTAG_STATE_CURRENT) + return -EINVAL; + -+ if (endstate.reset > JTAG_FORCE_RESET) ++ if (tapstate.endstate > JTAG_STATE_CURRENT) + return -EINVAL; + -+ err = jtag->ops->status_set(jtag, &endstate); ++ if (tapstate.reset > JTAG_FORCE_RESET) ++ return -EINVAL; ++ ++ err = jtag->ops->status_set(jtag, &tapstate); + break; + + case JTAG_IOCXFER: @@ -419,7 +425,10 @@ index 0000000..47503a1 + if (xfer.direction > JTAG_READ_WRITE_XFER) + return -EINVAL; + -+ if (xfer.endstate > JTAG_STATE_UPDATEIR) ++ if (xfer.from > JTAG_STATE_CURRENT) ++ return -EINVAL; ++ ++ if (xfer.endstate > JTAG_STATE_CURRENT) + return -EINVAL; + + data_size = DIV_ROUND_UP(xfer.length, BITS_PER_BYTE); @@ -607,7 +616,8 @@ index 0000000..47503a1 + struct jtag **ptr; + int ret; + -+ ptr = devres_alloc(devm_jtag_unregister, sizeof(*ptr), GFP_KERNEL); ++ ptr = devres_alloc(devm_jtag_unregister, sizeof(struct jtag *), ++ GFP_KERNEL); + if (!ptr) + return -ENOMEM; + @@ -669,7 +679,7 @@ index 0000000..4153c90 + int (*freq_get)(struct jtag *jtag, u32 *freq); + int (*freq_set)(struct jtag *jtag, u32 freq); + int (*status_get)(struct jtag *jtag, u32 *state); -+ int (*status_set)(struct jtag *jtag, struct jtag_end_tap_state *endst); ++ int (*status_set)(struct jtag *jtag, struct jtag_tap_state *endst); + int (*xfer)(struct jtag *jtag, struct jtag_xfer *xfer, u8 *xfer_data); + int (*mode_set)(struct jtag *jtag, struct jtag_mode *jtag_mode); + int (*bitbang)(struct jtag *jtag, struct bitbang_packet *bitbang, @@ -690,7 +700,7 @@ new file mode 100644 index 0000000..3f9e195 --- /dev/null +++ b/include/uapi/linux/jtag.h -@@ -0,0 +1,208 @@ +@@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2018 Mellanox Technologies. All rights reserved. */ +/* Copyright (c) 2018 Oleksandr Shamray <oleksandrs@mellanox.com> */ @@ -732,7 +742,7 @@ index 0000000..3f9e195 +#define JTAG_XFER_SW_MODE 0 + +/** -+ * enum jtag_endstate: ++ * enum jtag_tapstate: + * + * @JTAG_STATE_TLRESET: JTAG state machine Test Logic Reset state + * @JTAG_STATE_IDLE: JTAG state machine IDLE state @@ -750,8 +760,9 @@ index 0000000..3f9e195 + * @JTAG_STATE_PAUSEIR: JTAG state machine PAUSE_IR state + * @JTAG_STATE_EXIT2IR: JTAG state machine EXIT-2 IR state + * @JTAG_STATE_UPDATEIR: JTAG state machine UPDATE IR state ++ * @JTAG_STATE_CURRENT: JTAG current state, saved by driver + */ -+enum jtag_endstate { ++enum jtag_tapstate { + JTAG_STATE_TLRESET, + JTAG_STATE_IDLE, + JTAG_STATE_SELECTDR, @@ -767,7 +778,8 @@ index 0000000..3f9e195 + JTAG_STATE_EXIT1IR, + JTAG_STATE_PAUSEIR, + JTAG_STATE_EXIT2IR, -+ JTAG_STATE_UPDATEIR ++ JTAG_STATE_UPDATEIR, ++ JTAG_STATE_CURRENT +}; + +/** @@ -806,7 +818,7 @@ index 0000000..3f9e195 +}; + +/** -+ * struct jtag_end_tap_state - forces JTAG state machine to go into a TAPC ++ * struct jtag_tap_state - forces JTAG state machine to go into a TAPC + * state + * + * @reset: 0 - run IDLE/PAUSE from current state @@ -816,8 +828,9 @@ index 0000000..3f9e195 + * + * Structure provide interface to JTAG device for JTAG set state execution. + */ -+struct jtag_end_tap_state { ++struct jtag_tap_state { + __u8 reset; ++ __u8 from; + __u8 endstate; + __u8 tck; +}; @@ -827,15 +840,18 @@ index 0000000..3f9e195 + * + * @type: transfer type + * @direction: xfer direction -+ * @length: xfer bits len ++ * @from: xfer current state ++ * @endstate: xfer end state ++ * @padding: xfer padding ++ * @length: xfer bits length + * @tdio : xfer data array -+ * @endir: xfer end state + * + * Structure provide interface to JTAG device for JTAG SDR/SIR xfer execution. + */ +struct jtag_xfer { + __u8 type; + __u8 direction; ++ __u8 from; + __u8 endstate; + __u8 padding; + __u32 length; @@ -890,11 +906,11 @@ index 0000000..3f9e195 +/* ioctl interface */ +#define __JTAG_IOCTL_MAGIC 0xb2 + -+#define JTAG_SIOCSTATE _IOW(__JTAG_IOCTL_MAGIC, 0, struct jtag_end_tap_state) ++#define JTAG_SIOCSTATE _IOW(__JTAG_IOCTL_MAGIC, 0, struct jtag_tap_state) +#define JTAG_SIOCFREQ _IOW(__JTAG_IOCTL_MAGIC, 1, unsigned int) +#define JTAG_GIOCFREQ _IOR(__JTAG_IOCTL_MAGIC, 2, unsigned int) +#define JTAG_IOCXFER _IOWR(__JTAG_IOCTL_MAGIC, 3, struct jtag_xfer) -+#define JTAG_GIOCSTATUS _IOWR(__JTAG_IOCTL_MAGIC, 4, enum jtag_endstate) ++#define JTAG_GIOCSTATUS _IOWR(__JTAG_IOCTL_MAGIC, 4, enum jtag_tapstate) +#define JTAG_SIOCMODE _IOW(__JTAG_IOCTL_MAGIC, 5, unsigned int) +#define JTAG_IOCBITBANG _IOW(__JTAG_IOCTL_MAGIC, 6, unsigned int) + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0053-Add-Aspeed-SoC-24xx-and-25xx-families-JTAG.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0053-Add-Aspeed-SoC-24xx-and-25xx-families-JTAG.patch index d5d43f31b..94722d6c4 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0053-Add-Aspeed-SoC-24xx-and-25xx-families-JTAG.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0053-Add-Aspeed-SoC-24xx-and-25xx-families-JTAG.patch @@ -1,6 +1,6 @@ From 817a43d1b1e197e7eff43492599469bbc23bf0fd Mon Sep 17 00:00:00 2001 From: "Corona, Ernesto" <ernesto.corona@intel.com> -Date: Fri, 17 May 2019 11:18:13 -0800 +Date: Mon, 3 Jun 2019 08:22:09 -0800 Subject: [PATCH v29 2/6] Add Aspeed SoC 24xx and 25xx families JTAG master driver @@ -46,6 +46,8 @@ Comments pointed by Steven Filary <steven.a.filary@intel.com> (master/slave). - Encansulate dev_dgb message into DEBUG_JTAG macros to improve driver's JTAG performace. +- Add support for multichain. Set tap state and xfer operations now include + two tap state arguments: current state and end state. v27->v28 Comments pointed by Steven Filary <steven.a.filary@intel.com> @@ -198,8 +200,8 @@ Comments pointed by kbuild test robot <lkp@intel.com> --- drivers/jtag/Kconfig | 14 + drivers/jtag/Makefile | 1 + - drivers/jtag/jtag-aspeed.c | 1040 ++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 1055 insertions(+) + drivers/jtag/jtag-aspeed.c | 1050 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 1065 insertions(+) create mode 100644 drivers/jtag/jtag-aspeed.c diff --git a/drivers/jtag/Kconfig b/drivers/jtag/Kconfig @@ -236,7 +238,7 @@ new file mode 100644 index 0000000..1d41a66 --- /dev/null +++ b/drivers/jtag/jtag-aspeed.c -@@ -0,0 +1,1040 @@ +@@ -0,0 +1,1050 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018 Mellanox Technologies. All rights reserved. +// Copyright (c) 2018 Oleksandr Shamray <oleksandrs@mellanox.com> @@ -327,6 +329,7 @@ index 0000000..1d41a66 +#define WAIT_ITERATIONS 75 + +/*#define USE_INTERRUPTS*/ ++/*#define DEBUG_JTAG*/ + +static const char * const regnames[] = { + [ASPEED_JTAG_DATA] = "ASPEED_JTAG_DATA", @@ -344,7 +347,7 @@ index 0000000..1d41a66 + void __iomem *reg_base; + struct device *dev; + struct clk *pclk; -+ enum jtag_endstate status; ++ enum jtag_tapstate status; + int irq; + struct reset_control *rst; + u32 flag; @@ -480,10 +483,12 @@ index 0000000..1d41a66 + {0x0b, 4}, {0x0b, 5}, {0x2b, 6}, {0x00, 0} }, +}; + ++#ifdef DEBUG_JTAG +static char *end_status_str[] = { + "tlr", "idle", "selDR", "capDR", "sDR", "ex1DR", "pDR", "ex2DR", + "updDR", "selIR", "capIR", "sIR", "ex1IR", "pIR", "ex2IR", "updIR" +}; ++#endif + +static u32 aspeed_jtag_read(struct aspeed_jtag *aspeed_jtag, u32 reg) +{ @@ -776,24 +781,29 @@ index 0000000..1d41a66 +} + +static void aspeed_jtag_set_tap_state(struct aspeed_jtag *aspeed_jtag, -+ enum jtag_endstate endstate) ++ enum jtag_tapstate from_state, ++ enum jtag_tapstate end_state) +{ + int i = 0; -+ enum jtag_endstate from, to; ++ enum jtag_tapstate from, to; ++ ++ from = from_state; ++ to = end_state; ++ ++ if (from == JTAG_STATE_CURRENT) ++ from = aspeed_jtag->status; + -+ from = aspeed_jtag->status; -+ to = endstate; + for (i = 0; i < _tms_cycle_lookup[from][to].count; i++) + aspeed_jtag_tck_cycle(aspeed_jtag, + ((_tms_cycle_lookup[from][to].tmsbits >> i) & 0x1), 0); -+ aspeed_jtag->status = endstate; ++ aspeed_jtag->status = end_state; +} + -+static void aspeed_jtag_end_tap_state_sw(struct aspeed_jtag *aspeed_jtag, -+ struct jtag_end_tap_state *endstate) ++static void aspeed_jtag_set_tap_state_sw(struct aspeed_jtag *aspeed_jtag, ++ struct jtag_tap_state *tapstate) +{ + /* SW mode from curent tap state -> to end_state */ -+ if (endstate->reset) { ++ if (tapstate->reset) { + int i = 0; + + for (i = 0; i < ASPEED_JTAG_RESET_CNTR; i++) @@ -801,26 +811,27 @@ index 0000000..1d41a66 + aspeed_jtag->status = JTAG_STATE_TLRESET; + } + -+ aspeed_jtag_set_tap_state(aspeed_jtag, endstate->endstate); ++ aspeed_jtag_set_tap_state(aspeed_jtag, tapstate->from, ++ tapstate->endstate); +} + +static int aspeed_jtag_status_set(struct jtag *jtag, -+ struct jtag_end_tap_state *endstate) ++ struct jtag_tap_state *tapstate) +{ + struct aspeed_jtag *aspeed_jtag = jtag_priv(jtag); + +#ifdef DEBUG_JTAG + dev_dbg(aspeed_jtag->dev, "Set TAP state: %s\n", -+ end_status_str[endstate->endstate]); ++ end_status_str[tapstate->endstate]); +#endif + + if (!(aspeed_jtag->mode & JTAG_XFER_HW_MODE)) { -+ aspeed_jtag_end_tap_state_sw(aspeed_jtag, endstate); ++ aspeed_jtag_set_tap_state_sw(aspeed_jtag, tapstate); + return 0; + } + + /* x TMS high + 1 TMS low */ -+ if (endstate->reset) { ++ if (tapstate->reset) { + /* Disable sw mode */ + aspeed_jtag_write(aspeed_jtag, 0, ASPEED_JTAG_SW); + mdelay(1); @@ -851,9 +862,11 @@ index 0000000..1d41a66 +#endif + + if (xfer->type == JTAG_SIR_XFER) -+ aspeed_jtag_set_tap_state(aspeed_jtag, JTAG_STATE_SHIFTIR); ++ aspeed_jtag_set_tap_state(aspeed_jtag, xfer->from, ++ JTAG_STATE_SHIFTIR); + else -+ aspeed_jtag_set_tap_state(aspeed_jtag, JTAG_STATE_SHIFTDR); ++ aspeed_jtag_set_tap_state(aspeed_jtag, xfer->from, ++ JTAG_STATE_SHIFTDR); + + tdi = ASPEED_JTAG_GET_TDI(xfer->direction, data[index]); + data[index] = 0; @@ -889,7 +902,8 @@ index 0000000..1d41a66 + ASPEED_JTAG_DATA_CHUNK_SIZE); + aspeed_jtag->status = (xfer->type == JTAG_SIR_XFER) ? + JTAG_STATE_EXIT1IR : JTAG_STATE_EXIT1DR; -+ aspeed_jtag_set_tap_state(aspeed_jtag, xfer->endstate); ++ aspeed_jtag_set_tap_state(aspeed_jtag, aspeed_jtag->status, ++ xfer->endstate); + } +} + @@ -916,8 +930,7 @@ index 0000000..1d41a66 + +static int aspeed_jtag_xfer_push_data_last(struct aspeed_jtag *aspeed_jtag, + enum jtag_xfer_type type, -+ u32 shift_bits, -+ enum jtag_endstate endstate) ++ u32 shift_bits) +{ + int res = 0; + @@ -1014,8 +1027,7 @@ index 0000000..1d41a66 + if (aspeed_jtag_xfer_push_data_last( + aspeed_jtag, + xfer->type, -+ shift_bits, -+ xfer->endstate) != 0) { ++ shift_bits) != 0) { + return -EFAULT; + } + } else { diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0055-Documentation-jtag-Add-ABI-documentation.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0055-Documentation-jtag-Add-ABI-documentation.patch index af641ffe2..b91311d94 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0055-Documentation-jtag-Add-ABI-documentation.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0055-Documentation-jtag-Add-ABI-documentation.patch @@ -86,8 +86,8 @@ Comments pointed by Pavel Machek <pavel@ucw.cz> --- Documentation/ABI/testing/jtag-dev | 23 +++++++ Documentation/jtag/overview | 27 ++++++++ - Documentation/jtag/transactions | 138 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 188 insertions(+) + Documentation/jtag/transactions | 145 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 195 insertions(+) create mode 100644 Documentation/ABI/testing/jtag-dev create mode 100644 Documentation/jtag/overview create mode 100644 Documentation/jtag/transactions @@ -159,7 +159,7 @@ new file mode 100644 index 0000000..76fd0b1 --- /dev/null +++ b/Documentation/jtag/transactions -@@ -0,0 +1,138 @@ +@@ -0,0 +1,145 @@ +The JTAG API +============= + @@ -204,8 +204,9 @@ index 0000000..76fd0b1 +------ +Force JTAG state machine to go into a TAPC state + -+struct jtag_end_tap_state { ++struct jtag_tap_state { + __u8 reset; ++ __u8 from; + __u8 endstate; + __u8 tck; +}; @@ -217,21 +218,22 @@ index 0000000..76fd0b1 +tck: clock counter + +Example: -+ struct jtag_end_tap_state end_state; ++ struct jtag_tap_state tap_state; + -+ end_state.endstate = JTAG_STATE_IDLE; -+ end_state.reset = 0; -+ end_state.tck = data_p->tck; ++ tap_state.from = JTAG_STATE_TLRESET; ++ tap_state.endstate = JTAG_STATE_IDLE; ++ tap_state.reset = 0; ++ tap_state.tck = data_p->tck; + usleep(25 * 1000); -+ ioctl(jtag_fd, JTAG_SIOCSTATE, &end_state); ++ ioctl(jtag_fd, JTAG_SIOCSTATE, &tap_state); + +JTAG_GIOCSTATUS +------ +Get JTAG TAPC machine state + + unsigned int jtag_fd; -+ jtag_endstate endstate; -+ ioctl(jtag_fd, JTAG_GIOCSTATUS, &endstate); ++ jtag_tapstate tapstate; ++ ioctl(jtag_fd, JTAG_GIOCSTATUS, &tapstate); + +JTAG_IOCXFER +------ @@ -240,6 +242,7 @@ index 0000000..76fd0b1 +struct jtag_xfer { + __u8 type; + __u8 direction; ++ __u8 from; + __u8 endstate; + __u8 padding; + __u32 length; @@ -250,8 +253,11 @@ index 0000000..76fd0b1 +direction: xfer direction - JTAG_READ_XFER/JTAG_WRITE_XFER/JTAG_READ_WRITE_XFER +length: xfer data length in bits +tdio : xfer data array ++from: xfer from state can be current JTAG tap state saved by the driver ++ JTAG_STATE_CURRENT or in a multichain environment any state listed in ++ jtag_tapstate struct saved by your multichain controller software. +endstate: xfer end state after transaction finish -+ can be: any state listed in jtag_endstate struct ++ can be: any state listed in jtag_tapstate struct + +Example: + struct jtag_xfer xfer; @@ -261,6 +267,7 @@ index 0000000..76fd0b1 + xfer.type = JTAG_SDR_XFER; + xfer.tdio = (__u64)buf; + xfer.length = buf_len; ++ xfer.from = JTAG_STATE_TLRESET; + xfer.endstate = JTAG_STATE_IDLE; + + if (is_read) @@ -300,4 +307,3 @@ index 0000000..76fd0b1 + tdo1 = bitbang_data[1].tdo; -- 2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0059-media-aspeed-remove-source-buffer-allocation-before-.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0059-media-aspeed-remove-source-buffer-allocation-before-.patch deleted file mode 100644 index 41bf4fb55..000000000 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0059-media-aspeed-remove-source-buffer-allocation-before-.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 28aa61a720d2db812d66b2b59681ba184771ff3e Mon Sep 17 00:00:00 2001 -From: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> -Date: Tue, 21 May 2019 16:00:28 -0700 -Subject: [PATCH] media: aspeed: remove source buffer allocation before mode - detection - -Mode detection doesn't require source buffer allocation so this -commit removes that. - -Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> ---- - drivers/media/platform/aspeed-video.c | 37 +++++------------------------------ - 1 file changed, 5 insertions(+), 32 deletions(-) - -diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c -index 1bb863b32836..fed51fd22ce2 100644 ---- a/drivers/media/platform/aspeed-video.c -+++ b/drivers/media/platform/aspeed-video.c -@@ -733,27 +733,6 @@ static void aspeed_video_get_resolution(struct aspeed_video *video) - det->height = MIN_HEIGHT; - video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL; - -- /* -- * Since we need max buffer size for detection, free the second source -- * buffer first. -- */ -- if (video->srcs[1].size) -- aspeed_video_free_buf(video, &video->srcs[1]); -- -- if (video->srcs[0].size < VE_MAX_SRC_BUFFER_SIZE) { -- if (video->srcs[0].size) -- aspeed_video_free_buf(video, &video->srcs[0]); -- -- if (!aspeed_video_alloc_buf(video, &video->srcs[0], -- VE_MAX_SRC_BUFFER_SIZE)) { -- dev_err(video->dev, -- "Failed to allocate source buffers\n"); -- return; -- } -- } -- -- aspeed_video_write(video, VE_SRC0_ADDR, video->srcs[0].dma); -- - do { - if (tries) { - set_current_state(TASK_INTERRUPTIBLE); -@@ -873,20 +852,14 @@ static void aspeed_video_set_resolution(struct aspeed_video *video) - - size *= 4; - -- if (size == video->srcs[0].size / 2) { -- aspeed_video_write(video, VE_SRC1_ADDR, -- video->srcs[0].dma + size); -- } else if (size == video->srcs[0].size) { -- if (!aspeed_video_alloc_buf(video, &video->srcs[1], size)) -- goto err_mem; -- -- aspeed_video_write(video, VE_SRC1_ADDR, video->srcs[1].dma); -- } else { -- aspeed_video_free_buf(video, &video->srcs[0]); -+ if (size != video->srcs[0].size) { -+ if (video->srcs[0].size) -+ aspeed_video_free_buf(video, &video->srcs[0]); -+ if (video->srcs[1].size) -+ aspeed_video_free_buf(video, &video->srcs[1]); - - if (!aspeed_video_alloc_buf(video, &video->srcs[0], size)) - goto err_mem; -- - if (!aspeed_video_alloc_buf(video, &video->srcs[1], size)) - goto err_mem; - --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0060-media-aspeed-use-different-delays-for-triggering-VE-.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0060-media-aspeed-use-different-delays-for-triggering-VE-.patch deleted file mode 100644 index 3e158c628..000000000 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0060-media-aspeed-use-different-delays-for-triggering-VE-.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 431c7974302fad5ae835adb46d3c8fa4034c845a Mon Sep 17 00:00:00 2001 -From: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> -Date: Tue, 21 May 2019 16:06:56 -0700 -Subject: [PATCH 2/4] media: aspeed: use different delays for triggering VE H/W - reset - -In case of watchdog timeout detected while doing mode detection, -it's better triggering video engine hardware reset immediately so -this commit fixes code for the case. Other than the case, it will -trigger video engine hardware reset after RESOLUTION_CHANGE_DELAY. - -Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> ---- - drivers/media/platform/aspeed-video.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c -index ee1f87a08c7c..b8540cc7848d 100644 ---- a/drivers/media/platform/aspeed-video.c -+++ b/drivers/media/platform/aspeed-video.c -@@ -522,7 +522,7 @@ static void aspeed_video_bufs_done(struct aspeed_video *video, - spin_unlock_irqrestore(&video->lock, flags); - } - --static void aspeed_video_irq_res_change(struct aspeed_video *video) -+static void aspeed_video_irq_res_change(struct aspeed_video *video, ulong delay) - { - spin_lock(&video->lock); - dev_dbg(video->dev, "Resolution changed; resetting\n"); -@@ -534,7 +534,7 @@ static void aspeed_video_irq_res_change(struct aspeed_video *video) - spin_unlock(&video->lock); - aspeed_video_bufs_done(video, VB2_BUF_STATE_ERROR); - -- schedule_delayed_work(&video->res_work, RESOLUTION_CHANGE_DELAY); -+ schedule_delayed_work(&video->res_work, delay); - } - - static irqreturn_t aspeed_video_irq(int irq, void *arg) -@@ -547,7 +547,7 @@ static irqreturn_t aspeed_video_irq(int irq, void *arg) - * re-initialize - */ - if (sts & VE_INTERRUPT_MODE_DETECT_WD) { -- aspeed_video_irq_res_change(video); -+ aspeed_video_irq_res_change(video, 0); - return IRQ_HANDLED; - } - -@@ -565,7 +565,8 @@ static irqreturn_t aspeed_video_irq(int irq, void *arg) - * Signal acquired while NOT doing resolution - * detection; reset the engine and re-initialize - */ -- aspeed_video_irq_res_change(video); -+ aspeed_video_irq_res_change(video, -+ RESOLUTION_CHANGE_DELAY); - return IRQ_HANDLED; - } - } --- -2.21.0 - diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0062-media-aspeed-add-a-workaround-to-fix-a-silicon-bug.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0062-media-aspeed-add-a-workaround-to-fix-a-silicon-bug.patch deleted file mode 100644 index a10963572..000000000 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0062-media-aspeed-add-a-workaround-to-fix-a-silicon-bug.patch +++ /dev/null @@ -1,68 +0,0 @@ -From fa386f96691ed8501949daf5129667b72723a55e Mon Sep 17 00:00:00 2001 -From: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> -Date: Thu, 23 May 2019 14:33:03 -0700 -Subject: [PATCH] media: aspeed: add a workaround to fix a silicon bug - -AST2500 silicon revision A1 and A2 have a silicon bug which causes -extremly long capturing time on specific resolutions (1680 width). -To fix the bug, this commit adjusts the capturing window register -setting to 1728 if detected width is 1680. The compression window -register setting will be kept as the original width so output -result will be the same. - -Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> ---- - drivers/media/platform/aspeed-video.c | 28 +++++++++++++++++++++------- - 1 file changed, 21 insertions(+), 7 deletions(-) - -diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c -index 67d6380d4ef3..f58f44eab588 100644 ---- a/drivers/media/platform/aspeed-video.c -+++ b/drivers/media/platform/aspeed-video.c -@@ -826,8 +826,29 @@ static void aspeed_video_set_resolution(struct aspeed_video *video) - struct v4l2_bt_timings *act = &video->active_timings; - unsigned int size = act->width * act->height; - -+ /* Set capture/compression frame sizes */ - aspeed_video_calc_compressed_size(video, size); - -+ if (video->active_timings.width == 1680) { -+ /* -+ * This is a workaround to fix a silicon bug on A1 and A2 -+ * revisions. Since it doesn't break capturing operation of -+ * other revisions, use it for all revisions without checking -+ * the revision ID. It picked 1728 which is a very next -+ * 64-pixels aligned value to 1680 to minimize memory bandwidth -+ * and to get better access speed from video engine. -+ */ -+ aspeed_video_write(video, VE_CAP_WINDOW, -+ 1728 << 16 | act->height); -+ size += (1728 - 1680) * video->active_timings.height; -+ } else { -+ aspeed_video_write(video, VE_CAP_WINDOW, -+ act->width << 16 | act->height); -+ } -+ aspeed_video_write(video, VE_COMP_WINDOW, -+ act->width << 16 | act->height); -+ aspeed_video_write(video, VE_SRC_SCANLINE_OFFSET, act->width * 4); -+ - /* Don't use direct mode below 1024 x 768 (irqs don't fire) */ - if (size < DIRECT_FETCH_THRESHOLD) { - aspeed_video_write(video, VE_TGS_0, -@@ -844,13 +865,6 @@ static void aspeed_video_set_resolution(struct aspeed_video *video) - aspeed_video_update(video, VE_CTRL, 0, VE_CTRL_DIRECT_FETCH); - } - -- /* Set capture/compression frame sizes */ -- aspeed_video_write(video, VE_CAP_WINDOW, -- act->width << 16 | act->height); -- aspeed_video_write(video, VE_COMP_WINDOW, -- act->width << 16 | act->height); -- aspeed_video_write(video, VE_SRC_SCANLINE_OFFSET, act->width * 4); -- - size *= 4; - - if (size != video->srcs[0].size) { --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0065-i2c-aspeed-fix-master-pending-state-handling.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0065-i2c-aspeed-fix-master-pending-state-handling.patch new file mode 100644 index 000000000..3a86d5b25 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0065-i2c-aspeed-fix-master-pending-state-handling.patch @@ -0,0 +1,55 @@ +From 50221ac92816333efcf961c5f22f8b9ffdccb31b Mon Sep 17 00:00:00 2001 +From: Jae Hyun Yoo <jae.hyun.yoo@intel.com> +Date: Tue, 11 Jun 2019 14:59:53 -0700 +Subject: [PATCH] i2c: aspeed: fix master pending state handling + +In case of a master pending state, it should not trigger the master +command because this H/W is sharing the same byte buffer for slave +and master operation, so this commit fixes the issue with making +the master command triggering happens when the state goes to active +state. + +Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com> +--- + drivers/i2c/busses/i2c-aspeed.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c +index f96160e01a69..64bc68eaa88f 100644 +--- a/drivers/i2c/busses/i2c-aspeed.c ++++ b/drivers/i2c/busses/i2c-aspeed.c +@@ -384,18 +384,19 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) + struct i2c_msg *msg = &bus->msgs[bus->msgs_index]; + u8 slave_addr = i2c_8bit_addr_from_msg(msg); + +- bus->master_state = ASPEED_I2C_MASTER_START; +- + #if IS_ENABLED(CONFIG_I2C_SLAVE) + /* + * If it's requested in the middle of a slave session, set the master + * state to 'pending' then H/W will continue handling this master + * command when the bus comes back to the idle state. + */ +- if (bus->slave_state != ASPEED_I2C_SLAVE_INACTIVE) ++ if (bus->slave_state != ASPEED_I2C_SLAVE_INACTIVE) { + bus->master_state = ASPEED_I2C_MASTER_PENDING; ++ return; ++ } + #endif /* CONFIG_I2C_SLAVE */ + ++ bus->master_state = ASPEED_I2C_MASTER_START; + bus->buf_index = 0; + + if (msg->flags & I2C_M_RD) { +@@ -480,7 +481,7 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + if (bus->slave_state != ASPEED_I2C_SLAVE_INACTIVE) + goto out_no_complete; + +- bus->master_state = ASPEED_I2C_MASTER_START; ++ aspeed_i2c_do_start(bus); + } + #endif /* CONFIG_I2C_SLAVE */ + +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0066-i2c-aspeed-add-buffer-mode-transfer-support.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0066-i2c-aspeed-add-buffer-mode-transfer-support.patch new file mode 100644 index 000000000..9480daeff --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0066-i2c-aspeed-add-buffer-mode-transfer-support.patch @@ -0,0 +1,770 @@ +From efb710a6b3a39f28b988af717eefc1b72c4c43bd Mon Sep 17 00:00:00 2001 +From: Jae Hyun Yoo <jae.hyun.yoo@intel.com> +Date: Tue, 11 Jun 2019 15:07:08 -0700 +Subject: [PATCH] i2c: aspeed: add buffer mode transfer support + +Byte mode currently this driver uses makes lots of interrupt call +which isn't good for performance and it makes the driver very +timing sensitive. To improve performance of the driver, this commit +adds buffer mode transfer support which uses I2C SRAM buffer +instead of using a single byte buffer. + +AST2400: +It has 2 KBytes (256 Bytes x 8 pages) of I2C SRAM buffer pool from +0x1e78a800 to 0x1e78afff that can be used for all busses with +buffer pool manipulation. To simplify implementation for supporting +both AST2400 and AST2500, it assigns each 128 Bytes per bus without +using buffer pool manipulation so total 1792 Bytes of I2C SRAM +buffer will used. + +AST2500: +It has 16 Bytes of individual I2C SRAM buffer per each bus and its +range is from 0x1e78a200 to 0x1e78a2df, so it doesn't have 'buffer +page selection' bit field in the Function control register, and +neither 'base address pointer' bit field in the Pool buffer control +register it has. To simplify implementation for supporting both +AST2400 and AST2500, it writes zeros on those register bit fields +but it's okay because it does nothing in AST2500. + +It provides buffer based master and slave data transfer. + +Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com> +--- + arch/arm/boot/dts/aspeed-g4.dtsi | 42 ++++-- + arch/arm/boot/dts/aspeed-g5.dtsi | 42 ++++-- + drivers/i2c/busses/i2c-aspeed.c | 262 ++++++++++++++++++++++++++++++++---- + drivers/irqchip/irq-aspeed-i2c-ic.c | 8 ++ + 4 files changed, 301 insertions(+), 53 deletions(-) + +diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi +index 47a5029f5bdb..c1c125add9fa 100644 +--- a/arch/arm/boot/dts/aspeed-g4.dtsi ++++ b/arch/arm/boot/dts/aspeed-g4.dtsi +@@ -482,7 +482,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x40 0x40>; ++ reg = <0x40 0x40>, <0x800 0x80>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2400-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -498,7 +499,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x80 0x40>; ++ reg = <0x80 0x40>, <0x880 0x80>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2400-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -514,7 +516,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0xc0 0x40>; ++ reg = <0xc0 0x40>, <0x900 0x80>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2400-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -531,7 +534,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x100 0x40>; ++ reg = <0x100 0x40>, <0x980 0x80>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2400-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -548,7 +552,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x140 0x40>; ++ reg = <0x140 0x40>, <0xa00 0x80>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2400-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -565,7 +570,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x180 0x40>; ++ reg = <0x180 0x40>, <0xa80 0x80>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2400-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -582,7 +588,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x1c0 0x40>; ++ reg = <0x1c0 0x40>, <0xb00 0x80>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2400-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -599,7 +606,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x300 0x40>; ++ reg = <0x300 0x40>, <0xb80 0x80>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2400-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -616,7 +624,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x340 0x40>; ++ reg = <0x340 0x40>, <0xc00 0x80>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2400-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -633,7 +642,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x380 0x40>; ++ reg = <0x380 0x40>, <0xc80 0x80>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2400-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -650,7 +660,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x3c0 0x40>; ++ reg = <0x3c0 0x40>, <0xd00 0x80>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2400-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -667,7 +678,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x400 0x40>; ++ reg = <0x400 0x40>, <0xd80 0x80>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2400-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -684,7 +696,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x440 0x40>; ++ reg = <0x440 0x40>, <0xe00 0x80>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2400-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -701,7 +714,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x480 0x40>; ++ reg = <0x480 0x40>, <0xe80 0x80>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2400-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi +index 9d5ed9499b1f..662249bc15f9 100644 +--- a/arch/arm/boot/dts/aspeed-g5.dtsi ++++ b/arch/arm/boot/dts/aspeed-g5.dtsi +@@ -599,7 +599,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x40 0x40>; ++ reg = <0x40 0x40>, <0x200 0x10>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2500-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -615,7 +616,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x80 0x40>; ++ reg = <0x80 0x40>, <0x210 0x10>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2500-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -631,7 +633,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0xc0 0x40>; ++ reg = <0xc0 0x40>, <0x220 0x10>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2500-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -648,7 +651,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x100 0x40>; ++ reg = <0x100 0x40>, <0x230 0x10>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2500-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -665,7 +669,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x140 0x40>; ++ reg = <0x140 0x40>, <0x240 0x10>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2500-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -682,7 +687,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x180 0x40>; ++ reg = <0x180 0x40>, <0x250 0x10>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2500-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -699,7 +705,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x1c0 0x40>; ++ reg = <0x1c0 0x40>, <0x260 0x10>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2500-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -716,7 +723,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x300 0x40>; ++ reg = <0x300 0x40>, <0x270 0x10>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2500-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -733,7 +741,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x340 0x40>; ++ reg = <0x340 0x40>, <0x280 0x10>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2500-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -750,7 +759,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x380 0x40>; ++ reg = <0x380 0x40>, <0x290 0x10>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2500-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -767,7 +777,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x3c0 0x40>; ++ reg = <0x3c0 0x40>, <0x2a0 0x10>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2500-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -784,7 +795,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x400 0x40>; ++ reg = <0x400 0x40>, <0x2b0 0x10>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2500-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -801,7 +813,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x440 0x40>; ++ reg = <0x440 0x40>, <0x2c0 0x10>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2500-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +@@ -818,7 +831,8 @@ + #size-cells = <0>; + #interrupt-cells = <1>; + +- reg = <0x480 0x40>; ++ reg = <0x480 0x40>, <0x2d0 0x10>; ++ reg-names = "bus-regs", "buf"; + compatible = "aspeed,ast2500-i2c-bus"; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_I2C>; +diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c +index 64bc68eaa88f..b21a4c87853e 100644 +--- a/drivers/i2c/busses/i2c-aspeed.c ++++ b/drivers/i2c/busses/i2c-aspeed.c +@@ -10,6 +10,7 @@ + * published by the Free Software Foundation. + */ + ++#include <linux/bitfield.h> + #include <linux/clk.h> + #include <linux/completion.h> + #include <linux/err.h> +@@ -38,6 +39,7 @@ + #define ASPEED_I2C_INTR_STS_REG 0x10 + #define ASPEED_I2C_CMD_REG 0x14 + #define ASPEED_I2C_DEV_ADDR_REG 0x18 ++#define ASPEED_I2C_BUF_CTRL_REG 0x1c + #define ASPEED_I2C_BYTE_BUF_REG 0x20 + + /* Global Register Definition */ +@@ -46,6 +48,7 @@ + + /* Device Register Definition */ + /* 0x00 : I2CD Function Control Register */ ++#define ASPEED_I2CD_BUFFER_PAGE_SEL_MASK GENMASK(22, 20) + #define ASPEED_I2CD_MULTI_MASTER_DIS BIT(15) + #define ASPEED_I2CD_SDA_DRIVE_1T_EN BIT(8) + #define ASPEED_I2CD_M_SDA_DRIVE_1T_EN BIT(7) +@@ -107,6 +110,8 @@ + #define ASPEED_I2CD_BUS_RECOVER_CMD BIT(11) + + /* Command Bit */ ++#define ASPEED_I2CD_RX_BUFF_ENABLE BIT(7) ++#define ASPEED_I2CD_TX_BUFF_ENABLE BIT(6) + #define ASPEED_I2CD_M_STOP_CMD BIT(5) + #define ASPEED_I2CD_M_S_RX_CMD_LAST BIT(4) + #define ASPEED_I2CD_M_RX_CMD BIT(3) +@@ -117,6 +122,13 @@ + /* 0x18 : I2CD Slave Device Address Register */ + #define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0) + ++/* 0x1c : I2CD Buffer Control Register */ ++/* Use 8-bits or 6-bits wide bit fileds to support both AST2400 and AST2500 */ ++#define ASPEED_I2CD_BUF_RX_COUNT_MASK GENMASK(31, 24) ++#define ASPEED_I2CD_BUF_RX_SIZE_MASK GENMASK(23, 16) ++#define ASPEED_I2CD_BUF_TX_COUNT_MASK GENMASK(15, 8) ++#define ASPEED_I2CD_BUF_OFFSET_MASK GENMASK(5, 0) ++ + enum aspeed_i2c_master_state { + ASPEED_I2C_MASTER_INACTIVE, + ASPEED_I2C_MASTER_PENDING, +@@ -164,6 +176,11 @@ struct aspeed_i2c_bus { + int master_xfer_result; + /* Multi-master */ + bool multi_master; ++ /* Buffer/DMA mode */ ++ void __iomem *buf_base; ++ size_t buf_size; ++ u8 buf_offset; ++ u8 buf_page; + #if IS_ENABLED(CONFIG_I2C_SLAVE) + struct i2c_client *slave; + enum aspeed_i2c_slave_state slave_state; +@@ -260,6 +277,7 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + { + u32 command, irq_handled = 0; + struct i2c_client *slave = bus->slave; ++ int i, len; + u8 value; + + if (!slave) +@@ -288,7 +306,11 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + + /* Slave was sent something. */ + if (irq_status & ASPEED_I2CD_INTR_RX_DONE) { +- value = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) >> 8; ++ if (bus->buf_base && ++ bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED) ++ value = readb(bus->buf_base); ++ else ++ value = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) >> 8; + /* Handle address frame. */ + if (bus->slave_state == ASPEED_I2C_SLAVE_START) { + if (value & 0x1) +@@ -318,6 +340,18 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + + /* Slave was asked to stop. */ + if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) { ++ if (bus->buf_base && ++ bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED) { ++ len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, ++ readl(bus->base + ++ ASPEED_I2C_BUF_CTRL_REG)); ++ for (i = 0; i < len; i++) { ++ value = readb(bus->buf_base + i); ++ i2c_slave_event(slave, ++ I2C_SLAVE_WRITE_RECEIVED, ++ &value); ++ } ++ } + irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP; + bus->slave_state = ASPEED_I2C_SLAVE_STOP; + } +@@ -350,6 +384,15 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + case ASPEED_I2C_SLAVE_WRITE_REQUESTED: + bus->slave_state = ASPEED_I2C_SLAVE_WRITE_RECEIVED; + i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value); ++ if (bus->buf_base) { ++ writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, ++ bus->buf_size - 1) | ++ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, ++ bus->buf_offset), ++ bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ writel(ASPEED_I2CD_RX_BUFF_ENABLE, ++ bus->base + ASPEED_I2C_CMD_REG); ++ } + break; + case ASPEED_I2C_SLAVE_GCALL_REQUESTED: + bus->slave_state = ASPEED_I2C_SLAVE_WRITE_RECEIVED; +@@ -357,6 +400,24 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + break; + case ASPEED_I2C_SLAVE_WRITE_RECEIVED: + i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED, &value); ++ if (bus->buf_base) { ++ len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, ++ readl(bus->base + ++ ASPEED_I2C_BUF_CTRL_REG)); ++ for (i = 1; i < len; i++) { ++ value = readb(bus->buf_base + i); ++ i2c_slave_event(slave, ++ I2C_SLAVE_WRITE_RECEIVED, ++ &value); ++ } ++ writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, ++ bus->buf_size - 1) | ++ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, ++ bus->buf_offset), ++ bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ writel(ASPEED_I2CD_RX_BUFF_ENABLE, ++ bus->base + ASPEED_I2C_CMD_REG); ++ } + break; + case ASPEED_I2C_SLAVE_STOP: + i2c_slave_event(slave, I2C_SLAVE_STOP, &value); +@@ -383,6 +444,8 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) + u32 command = ASPEED_I2CD_M_START_CMD | ASPEED_I2CD_M_TX_CMD; + struct i2c_msg *msg = &bus->msgs[bus->msgs_index]; + u8 slave_addr = i2c_8bit_addr_from_msg(msg); ++ u8 wbuf[4]; ++ int len; + + #if IS_ENABLED(CONFIG_I2C_SLAVE) + /* +@@ -401,12 +464,66 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) + + if (msg->flags & I2C_M_RD) { + command |= ASPEED_I2CD_M_RX_CMD; +- /* Need to let the hardware know to NACK after RX. */ +- if (msg->len == 1 && !(msg->flags & I2C_M_RECV_LEN)) +- command |= ASPEED_I2CD_M_S_RX_CMD_LAST; ++ ++ if (bus->buf_base && !(msg->flags & I2C_M_RECV_LEN)) { ++ command |= ASPEED_I2CD_TX_BUFF_ENABLE | ++ ASPEED_I2CD_RX_BUFF_ENABLE; ++ ++ wbuf[0] = slave_addr; ++ writel(*(u32 *)wbuf, bus->buf_base); ++ ++ if (msg->len > bus->buf_size) { ++ len = bus->buf_size; ++ } else { ++ len = msg->len; ++ command |= ASPEED_I2CD_M_S_RX_CMD_LAST; ++ } ++ ++ writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, ++ len - 1) | ++ FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, 0) | ++ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, ++ bus->buf_offset), ++ bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ } else { ++ /* Need to let the hardware know to NACK after RX. */ ++ if (msg->len == 1 && !(msg->flags & I2C_M_RECV_LEN)) ++ command |= ASPEED_I2CD_M_S_RX_CMD_LAST; ++ } ++ } else { ++ if (bus->buf_base) { ++ int i; ++ ++ command |= ASPEED_I2CD_TX_BUFF_ENABLE; ++ ++ if (msg->len + 1 > bus->buf_size) ++ len = bus->buf_size; ++ else ++ len = msg->len + 1; ++ ++ wbuf[0] = slave_addr; ++ for (i = 1; i < len; i++) { ++ wbuf[i % 4] = msg->buf[i - 1]; ++ if (i % 4 == 3) ++ writel(*(u32 *)wbuf, ++ bus->buf_base + i - 3); ++ } ++ if (--i % 4 != 3) ++ writel(*(u32 *)wbuf, ++ bus->buf_base + i - (i % 4)); ++ ++ bus->buf_index = len - 1; ++ ++ writel(FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, ++ len - 1) | ++ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, ++ bus->buf_offset), ++ bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ } + } + +- writel(slave_addr, bus->base + ASPEED_I2C_BYTE_BUF_REG); ++ if (!(command & ASPEED_I2CD_TX_BUFF_ENABLE)) ++ writel(slave_addr, bus->base + ASPEED_I2C_BYTE_BUF_REG); + writel(command, bus->base + ASPEED_I2C_CMD_REG); + } + +@@ -441,12 +558,22 @@ static int aspeed_i2c_is_irq_error(u32 irq_status) + return 0; + } + ++static inline int aspeed_i2c_is_tx_error(struct aspeed_i2c_bus *bus) ++{ ++ if (FIELD_GET(ASPEED_I2CD_BUF_TX_COUNT_MASK, ++ readl(bus->base + ASPEED_I2C_BUF_CTRL_REG)) != ++ bus->buf_size - 1) ++ return -EIO; ++ ++ return 0; ++} ++ + static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + { + u32 irq_handled = 0, command = 0; + struct i2c_msg *msg; + u8 recv_byte; +- int ret; ++ int ret, len; + + if (irq_status & ASPEED_I2CD_INTR_BUS_RECOVER_DONE) { + bus->master_state = ASPEED_I2C_MASTER_INACTIVE; +@@ -559,11 +686,46 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + /* fall through */ + case ASPEED_I2C_MASTER_TX_FIRST: + if (bus->buf_index < msg->len) { ++ if (bus->buf_base) { ++ u8 wbuf[4]; ++ int i; ++ ++ if (unlikely(aspeed_i2c_is_tx_error(bus))) ++ goto error_and_stop; ++ ++ if (msg->len - bus->buf_index > bus->buf_size) ++ len = bus->buf_size; ++ else ++ len = msg->len - bus->buf_index; ++ ++ for (i = 0; i < len; i++) { ++ wbuf[i % 4] = msg->buf[bus->buf_index ++ + i]; ++ if (i % 4 == 3) ++ writel(*(u32 *)wbuf, ++ bus->buf_base + i - 3); ++ } ++ if (--i % 4 != 3) ++ writel(*(u32 *)wbuf, ++ bus->buf_base + i - (i % 4)); ++ ++ bus->buf_index += len; ++ ++ writel(FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, ++ len - 1) | ++ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, ++ bus->buf_offset), ++ bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ writel(ASPEED_I2CD_TX_BUFF_ENABLE | ++ ASPEED_I2CD_M_TX_CMD, ++ bus->base + ASPEED_I2C_CMD_REG); ++ } else { ++ writel(msg->buf[bus->buf_index++], ++ bus->base + ASPEED_I2C_BYTE_BUF_REG); ++ writel(ASPEED_I2CD_M_TX_CMD, ++ bus->base + ASPEED_I2C_CMD_REG); ++ } + bus->master_state = ASPEED_I2C_MASTER_TX; +- writel(msg->buf[bus->buf_index++], +- bus->base + ASPEED_I2C_BYTE_BUF_REG); +- writel(ASPEED_I2CD_M_TX_CMD, +- bus->base + ASPEED_I2C_CMD_REG); + } else { + aspeed_i2c_next_msg_or_stop(bus); + } +@@ -580,25 +742,57 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + } + irq_handled |= ASPEED_I2CD_INTR_RX_DONE; + +- recv_byte = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) >> 8; +- msg->buf[bus->buf_index++] = recv_byte; +- +- if (msg->flags & I2C_M_RECV_LEN) { +- if (unlikely(recv_byte > I2C_SMBUS_BLOCK_MAX)) { +- bus->cmd_err = -EPROTO; +- aspeed_i2c_do_stop(bus); +- goto out_no_complete; ++ if (bus->buf_base && !(msg->flags & I2C_M_RECV_LEN)) { ++ len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, ++ readl(bus->base + ++ ASPEED_I2C_BUF_CTRL_REG)); ++ memcpy_fromio(msg->buf + bus->buf_index, ++ bus->buf_base, len); ++ bus->buf_index += len; ++ } else { ++ recv_byte = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) ++ >> 8; ++ msg->buf[bus->buf_index++] = recv_byte; ++ ++ if (msg->flags & I2C_M_RECV_LEN) { ++ if (unlikely(recv_byte > I2C_SMBUS_BLOCK_MAX)) { ++ bus->cmd_err = -EPROTO; ++ aspeed_i2c_do_stop(bus); ++ goto out_no_complete; ++ } ++ msg->len = recv_byte + ++ ((msg->flags & I2C_CLIENT_PEC) ? ++ 2 : 1); ++ msg->flags &= ~I2C_M_RECV_LEN; + } +- msg->len = recv_byte + +- ((msg->flags & I2C_CLIENT_PEC) ? 2 : 1); +- msg->flags &= ~I2C_M_RECV_LEN; + } + + if (bus->buf_index < msg->len) { +- bus->master_state = ASPEED_I2C_MASTER_RX; + command = ASPEED_I2CD_M_RX_CMD; +- if (bus->buf_index + 1 == msg->len) +- command |= ASPEED_I2CD_M_S_RX_CMD_LAST; ++ bus->master_state = ASPEED_I2C_MASTER_RX; ++ if (bus->buf_base) { ++ command |= ASPEED_I2CD_RX_BUFF_ENABLE; ++ ++ if (msg->len - bus->buf_index > ++ bus->buf_size) { ++ len = bus->buf_size; ++ } else { ++ len = msg->len - bus->buf_index; ++ command |= ASPEED_I2CD_M_S_RX_CMD_LAST; ++ } ++ ++ writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, ++ len - 1) | ++ FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, ++ 0) | ++ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, ++ bus->buf_offset), ++ bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ ++ } else { ++ if (bus->buf_index + 1 == msg->len) ++ command |= ASPEED_I2CD_M_S_RX_CMD_LAST; ++ } + writel(command, bus->base + ASPEED_I2C_CMD_REG); + } else { + aspeed_i2c_next_msg_or_stop(bus); +@@ -948,6 +1142,9 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus, + if (ret < 0) + return ret; + ++ fun_ctrl_reg |= FIELD_PREP(ASPEED_I2CD_BUFFER_PAGE_SEL_MASK, ++ bus->buf_page); ++ + if (of_property_read_bool(pdev->dev.of_node, "multi-master")) + bus->multi_master = true; + else +@@ -1010,17 +1207,32 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) + struct aspeed_i2c_bus *bus; + struct clk *parent_clk; + struct resource *res; ++ void __iomem *gc_reg; + int irq, ret; + + bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL); + if (!bus) + return -ENOMEM; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bus-regs"); + bus->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(bus->base)) + return PTR_ERR(bus->base); + ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "buf"); ++ bus->buf_base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(bus->buf_base) || resource_size(res) < 2) { ++ bus->buf_base = NULL; ++ } else { ++ bus->buf_size = resource_size(res); ++ if (of_device_is_compatible(pdev->dev.of_node, ++ "aspeed,ast2400-i2c-bus")) { ++ bus->buf_page = (res->start >> 8) & GENMASK(3, 0) - 8; ++ bus->buf_offset = (res->start >> 2) & ++ ASPEED_I2CD_BUF_OFFSET_MASK; ++ } ++ } ++ + parent_clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(parent_clk)) + return PTR_ERR(parent_clk); +diff --git a/drivers/irqchip/irq-aspeed-i2c-ic.c b/drivers/irqchip/irq-aspeed-i2c-ic.c +index f20200af0992..99985b22a9fa 100644 +--- a/drivers/irqchip/irq-aspeed-i2c-ic.c ++++ b/drivers/irqchip/irq-aspeed-i2c-ic.c +@@ -18,6 +18,9 @@ + #include <linux/of_irq.h> + #include <linux/io.h> + ++/* I2C Global Control Register (AST2500) */ ++#define ASPEED_I2C_GLOBAL_CTRL_REG 0xc ++#define ASPEED_I2C_SRAM_BUFFER_EN BIT(0) + + #define ASPEED_I2C_IC_NUM_BUS 14 + +@@ -100,6 +103,11 @@ static int __init aspeed_i2c_ic_of_init(struct device_node *node, + irq_set_chained_handler_and_data(i2c_ic->parent_irq, + aspeed_i2c_ic_irq_handler, i2c_ic); + ++ /* Enable I2C SRAM buffer in case of AST2500 */ ++ if (of_device_is_compatible(node, "aspeed,ast2500-i2c-ic")) ++ writel(ASPEED_I2C_SRAM_BUFFER_EN, ++ i2c_ic->base + ASPEED_I2C_GLOBAL_CTRL_REG); ++ + pr_info("i2c controller registered, irq %d\n", i2c_ic->parent_irq); + + return 0; +-- +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 7ae4b5e64..ed5be3455 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 @@ -41,7 +41,6 @@ SRC_URI += " \ file://0056-Documentation-jtag-Add-JTAG-core-driver-ioctl-number.patch \ file://0057-drivers-jtag-Add-JTAG-core-driver-Maintainers.patch \ file://0058-i2c-aspeed-add-general-call-support.patch \ - file://0059-media-aspeed-remove-source-buffer-allocation-before-.patch \ - file://0060-media-aspeed-use-different-delays-for-triggering-VE-.patch \ - file://0062-media-aspeed-add-a-workaround-to-fix-a-silicon-bug.patch \ + file://0065-i2c-aspeed-fix-master-pending-state-handling.patch \ + file://0066-i2c-aspeed-add-buffer-mode-transfer-support.patch \ " 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 e773da3cd..8b9da74f0 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 = "683ff83b9cfe0ec3d9683f7220bd40ef77dbfe96" +SRCREV = "15c49902cf030a91a5b4bd325d185ee74b760359" FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch new file mode 100644 index 000000000..67fa59090 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch @@ -0,0 +1,57 @@ +From 6e9a19c43acac7d4254910906329d98d7b59085a Mon Sep 17 00:00:00 2001 +From: Ren Yu <yux.ren@intel.com> +Date: Fri, 24 May 2019 14:55:10 +0800 +Subject: [PATCH] Add the pre-timeout interrupt defined in IPMI spec + +The IPMI watchdog pre-timeout interrupt is used to set the different +pre-timeout interrupt source. Add them as a dbus property, +IPMI set/get watchdog commands will use it. + +Signed-off-by: Ren Yu <yux.ren@intel.com> +--- + xyz/openbmc_project/State/Watchdog.interface.yaml | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/xyz/openbmc_project/State/Watchdog.interface.yaml b/xyz/openbmc_project/State/Watchdog.interface.yaml +index 2fc47d8..6dfa9b9 100644 +--- a/xyz/openbmc_project/State/Watchdog.interface.yaml ++++ b/xyz/openbmc_project/State/Watchdog.interface.yaml +@@ -33,6 +33,11 @@ properties: + description: > + The action the watchdog should perform when it expires. + default: 'HardReset' ++ - name: PreTimeoutInterrupt ++ type: enum[self.PreTimeoutInterruptAction] ++ description: > ++ The BMC generates the selected interrupt before the timer expires. ++ default: 'None' + - name: Interval + type: uint64 + description: > +@@ -73,6 +78,23 @@ enumerations: + description: > + Perform a power cycle of the system. + ++ - name: PreTimeoutInterruptAction ++ description: > ++ The type of PreTimeout Interrupt. ++ values: ++ - name: 'None' ++ description: > ++ Do nothing. ++ - name: 'SMI' ++ description: > ++ SMI. ++ - name: 'NMI' ++ description: > ++ NMI / Diagnostic Interrupt. ++ - name: 'MI' ++ description: > ++ Messaging Interrupt. ++ + - name: TimerUse + description: > + The type of timer use. +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend index 94eff8ac7..89b8da753 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 = "57b878d048f929643276f1bf7fdf750abc4bde8b" +SRCREV = "1f0e2ce6e1cb78a59a0015b160816b71156b03c6" FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" @@ -18,4 +18,5 @@ SRC_URI += "file://0002-Modify-Dbus-for-IPv6.patch \ file://0021-Add-interface-suppot-for-provisioning-modes.patch \ file://0022-Add-chassis-power-cycle-and-reset-to-Chassis-State.patch \ file://0023-Add-host-interrupt-to-the-Host-State.patch \ + file://0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch \ " diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control_%.bbappend index 1ce94dca4..e1ec04ff6 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control_%.bbappend @@ -5,6 +5,6 @@ SYSTEMD_SERVICE_${PN} = "phosphor-pid-control.service" EXTRA_OECONF = "--enable-configure-dbus=yes" SRC_URI = "git://github.com/openbmc/phosphor-pid-control.git" -SRCREV = "98b704e179f12d987179fe6b0ea6234d1bace48f" +SRCREV = "1dad21b935b8359806de9a9cc3aa7b7463cc8df3" FILES_${PN} = "${bindir}/swampd ${bindir}/setsensor" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/gpiodaemon/gpiodaemon.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/gpiodaemon/gpiodaemon.bb index e24245525..cef2fdcaa 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/gpiodaemon/gpiodaemon.bb +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/gpiodaemon/gpiodaemon.bb @@ -10,7 +10,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh" -SRCREV = "9d2d365a79591ec21b54ecde957263f1ba1d8391" +SRCREV = "4373d99e1edcbb4c7233abde3a5e53690693007b" inherit cmake systemd SYSTEMD_SERVICE_${PN} = "gpiodaemon.service" 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 6ac05b61d..3f870103b 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend @@ -1,5 +1,5 @@ SRC_URI = "git://github.com/openbmc/bmcweb.git" -SRCREV = "d62cec731dcb533b3fecb08ba115dbf713539681" +SRCREV = "fa1a5a38551bd1b9f04ad2d4f9fea2e5ade5cc4c" FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch new file mode 100644 index 000000000..685e7c39d --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch @@ -0,0 +1,140 @@ +From d9c89943d7b0aa00ee99b7c11278ac272a47a790 Mon Sep 17 00:00:00 2001 +From: Ren Yu <yux.ren@intel.com> +Date: Tue, 28 May 2019 17:11:17 +0800 +Subject: [PATCH] Save the pre-timeout interrupt in dbus property + +Get the watchdog pre-timeout interrupt value from ipmi watchdog set command, +and store it into dbus property. + +Tested: +Config IPMI watchdog: BIOS FRB2 Power Cycle after 1 seconds: +ipmitool raw 0x06 0x24 0x01 0x13 0x0 0x2 0xa 0x00 +Start watchdog: +Ipmitool mc watchdog reset +Check the watchdog pre-timeout interrupt in below: +https://BMCIP/redfish/v1/Systems/system/LogServices/EventLog/Entries + +Signed-off-by: Ren Yu <yux.ren@intel.com> +--- + app/watchdog.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ + app/watchdog_service.cpp | 6 ++++++ + app/watchdog_service.hpp | 9 +++++++++ + 3 files changed, 62 insertions(+) + +diff --git a/app/watchdog.cpp b/app/watchdog.cpp +index 2ffaae3..e9b7a9c 100644 +--- a/app/watchdog.cpp ++++ b/app/watchdog.cpp +@@ -81,6 +81,7 @@ ipmi::RspType<> ipmiAppResetWatchdogTimer() + + static constexpr uint8_t wd_dont_stop = 0x1 << 6; + static constexpr uint8_t wd_timeout_action_mask = 0x3; ++static constexpr uint8_t wdPreTimeoutInterruptMask = 0x3; + + static constexpr uint8_t wdTimerUseMask = 0x7; + static constexpr uint8_t wdTimerUseResTimer1 = 0x0; +@@ -130,6 +131,45 @@ WatchdogService::Action ipmiActionToWdAction(IpmiAction ipmi_action) + } + } + ++enum class IpmiPreTimeoutInterrupt : uint8_t ++{ ++ None = 0x0, ++ SMI = 0x1, ++ NMI = 0x2, ++ MI = 0x3, ++}; ++/** @brief Converts an IPMI Watchdog PreTimeoutInterrupt to DBUS defined action ++ * @param[in] ipmi_action The IPMI Watchdog PreTimeoutInterrupt ++ * @return The Watchdog PreTimeoutInterrupt that the ipmi_action maps to ++ */ ++WatchdogService::PreTimeoutInterruptAction ipmiPreTimeoutInterruptToWdAction( ++ IpmiPreTimeoutInterrupt ipmiPreTimeOutInterrupt) ++{ ++ switch (ipmiPreTimeOutInterrupt) ++ { ++ case IpmiPreTimeoutInterrupt::None: ++ { ++ return WatchdogService::PreTimeoutInterruptAction::None; ++ } ++ case IpmiPreTimeoutInterrupt::SMI: ++ { ++ return WatchdogService::PreTimeoutInterruptAction::SMI; ++ } ++ case IpmiPreTimeoutInterrupt::NMI: ++ { ++ return WatchdogService::PreTimeoutInterruptAction::NMI; ++ } ++ case IpmiPreTimeoutInterrupt::MI: ++ { ++ return WatchdogService::PreTimeoutInterruptAction::MI; ++ } ++ default: ++ { ++ throw std::domain_error("IPMI PreTimeoutInterrupt is invalid"); ++ } ++ } ++} ++ + enum class IpmiTimerUse : uint8_t + { + Reserved = 0x0, +@@ -257,6 +297,13 @@ ipmi_ret_t ipmi_app_watchdog_set(ipmi_netfn_t netfn, ipmi_cmd_t cmd, + // Mark as initialized so that future resets behave correctly + wd_service.setInitialized(true); + ++ // pretimeOutAction ++ const auto ipmiPreTimeoutInterrupt = ++ static_cast<IpmiPreTimeoutInterrupt>((req.timer_action >> 4) & ++ wdPreTimeoutInterruptMask); ++ wd_service.setPreTimeoutInterrupt( ++ ipmiPreTimeoutInterruptToWdAction(ipmiPreTimeoutInterrupt)); ++ + lastCallSuccessful = true; + return IPMI_CC_OK; + } +diff --git a/app/watchdog_service.cpp b/app/watchdog_service.cpp +index 77663b4..0c4ea28 100644 +--- a/app/watchdog_service.cpp ++++ b/app/watchdog_service.cpp +@@ -203,3 +203,9 @@ void WatchdogService::setTimeRemaining(uint64_t timeRemaining) + { + setProperty("TimeRemaining", timeRemaining); + } ++ ++void WatchdogService::setPreTimeoutInterrupt( ++ PreTimeoutInterruptAction preTimeoutInterrupt) ++{ ++ setProperty("PreTimeoutInterrupt", convertForMessage(preTimeoutInterrupt)); ++} +\ No newline at end of file +diff --git a/app/watchdog_service.hpp b/app/watchdog_service.hpp +index ed64a3c..b550f37 100644 +--- a/app/watchdog_service.hpp ++++ b/app/watchdog_service.hpp +@@ -15,6 +15,8 @@ class WatchdogService + + using Action = + sdbusplus::xyz::openbmc_project::State::server::Watchdog::Action; ++ using PreTimeoutInterruptAction = sdbusplus::xyz::openbmc_project::State:: ++ server::Watchdog::PreTimeoutInterruptAction; + using TimerUse = + sdbusplus::xyz::openbmc_project::State::server::Watchdog::TimerUse; + +@@ -99,6 +101,13 @@ class WatchdogService + */ + void setTimeRemaining(uint64_t timeRemaining); + ++ /** @brief Sets the value of the PreTimeoutInterrupt property on the host ++ * watchdog ++ * ++ * @param[in] PreTimeoutInterrupt - The new PreTimeoutInterrupt value ++ */ ++ void setPreTimeoutInterrupt(PreTimeoutInterruptAction preTimeoutInterrupt); ++ + private: + /** @brief sdbusplus handle */ + sdbusplus::bus::bus bus; +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend index 3509ebfd6..a6a142ec8 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend @@ -3,7 +3,7 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" # TODO: This should be removed, once up-stream bump up # issue is resolved #SRC_URI = "git://github.com/openbmc/phosphor-host-ipmid" -SRCREV = "ea1c401c4bac43d6070bf7d515df08f8bf57c0a2" +SRCREV = "0b979b61c12ffe6ab8a27acf8ad2a0165d687195" SRC_URI += "file://phosphor-ipmi-host.service \ file://0009-IPv6-Network-changes.patch \ @@ -21,6 +21,7 @@ SRC_URI += "file://phosphor-ipmi-host.service \ file://0060-Move-Get-SOL-config-parameter-to-host-ipmid.patch \ file://0061-Use-xyz.openbmc_project.State.Chassis-for-IPMI-chass.patch \ file://0062-Update-IPMI-Chassis-Control-command.patch \ + file://0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch \ " # remove the softpoweroff service since we do not need it diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs/99-ipmi-kcs.rules b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs/99-ipmi-kcs.rules new file mode 100644 index 000000000..0a64b58db --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs/99-ipmi-kcs.rules @@ -0,0 +1,2 @@ +KERNEL=="ipmi-kcs3", SYMLINK+="ipmi_kcs3" +KERNEL=="ipmi-kcs4", SYMLINK+="ipmi_kcs4" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs_%.bbappend index e3d397f06..140d1b302 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-kcs_%.bbappend @@ -4,9 +4,18 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" # Default kcs device is ipmi-kcs3; this is SMS. # Add SMM kcs device instance -SMM_DEVICE = "ipmi-kcs4" + +# Replace the '-' to '_', since Dbus object/interface names do not allow '-'. +KCS_DEVICE = "ipmi_kcs3" +SMM_DEVICE = "ipmi_kcs4" SYSTEMD_SERVICE_${PN}_append = " ${PN}@${SMM_DEVICE}.service " SRC_URI = "git://github.com/openbmc/kcsbridge.git" SRCREV = "2cdc49585235a6557c9cbb6c8b75c064fc02681a" +SRC_URI += "file://99-ipmi-kcs.rules" + +do_install_append() { + install -d ${D}${base_libdir}/udev/rules.d + install -m 0644 ${WORKDIR}/99-ipmi-kcs.rules ${D}${base_libdir}/udev/rules.d/ +} diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net_%.bbappend index 9f5e3fa6f..214bea189 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 = "052b7cf37411a1bb69af1e6ce541a16021fffa9f" +#SRCREV = "b31e969504645f653b58b676d56b01d632dc395c" USERADD_PACKAGES = "${PN}" # add a group called ipmi diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/multi-node-manager/multi-node-manager.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/multi-node-manager/multi-node-manager.bb index 31b9e9338..65f578338 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/multi-node-manager/multi-node-manager.bb +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/multi-node-manager/multi-node-manager.bb @@ -2,7 +2,7 @@ SUMMARY = "Multi node manager" DESCRIPTION = "Daemon to handle chassis level shared resources on multi-node platform" SRC_URI = "git://git@github.com/Intel-BMC/multi-node-manager.git;protocol=ssh" -SRCREV = "8a34c017e04dd8f327aff127f64855f6132bd318" +SRCREV = "6a4cd36c0d46df11bdcd3b897bcc9c87e549a076" PV = "0.1+git${SRCPV}" 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 996f11b42..ca3c2eba0 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 = "930fcde3c8776c02f2a3d969d05608e2155eb159" +SRCREV = "52497fd0fbd8adfe099a99f23515cd0341898e2e" SRC_URI = "git://github.com/openbmc/dbus-sensors.git" DEPENDS_append = " libgpiod" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/settings/settings_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/settings/settings_git.bb new file mode 100644 index 000000000..aadb48fbf --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/settings/settings_git.bb @@ -0,0 +1,20 @@ +SUMMARY = "Settings" + +SRC_URI = "git://git-amr-2.devtools.intel.com:29418/openbmc-provingground.git;protocol=ssh" +SRCREV = "4373d99e1edcbb4c7233abde3a5e53690693007b" +PV = "0.1+git${SRCPV}" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${INTELBASE}/COPYING.apache-2.0;md5=34400b68072d710fecd0a2940a0d1658" + +SYSTEMD_SERVICE_${PN} = "settings.service" + +DEPENDS = "boost \ + nlohmann-json \ + sdbusplus" + +S = "${WORKDIR}/git/settings" +inherit cmake systemd + +EXTRA_OECMAKE = "-DYOCTO=1" + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/special-mode-mgr/special-mode-mgr_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/special-mode-mgr/special-mode-mgr_git.bb index 503f3875a..99cac7931 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/special-mode-mgr/special-mode-mgr_git.bb +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/special-mode-mgr/special-mode-mgr_git.bb @@ -8,8 +8,8 @@ S = "${WORKDIR}/git/special-mode-mgr" LICENSE = "Apache-2.0" LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" -SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh;nobranch=1" -SRCREV = "ec8f1c06be71d6059c82fd442475420286f5dbcd" +SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh" +SRCREV = "4373d99e1edcbb4c7233abde3a5e53690693007b" inherit cmake systemd SYSTEMD_SERVICE_${PN} = "specialmodemgr.service" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/srvcfg-manager/srvcfg-manager_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/srvcfg-manager/srvcfg-manager_git.bb index 878de75bb..52ebdfd88 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/srvcfg-manager/srvcfg-manager_git.bb +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/srvcfg-manager/srvcfg-manager_git.bb @@ -9,7 +9,7 @@ LICENSE = "Apache-2.0" LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh" -SRCREV = "9d2d365a79591ec21b54ecde957263f1ba1d8391" +SRCREV = "4373d99e1edcbb4c7233abde3a5e53690693007b" inherit cmake systemd SYSTEMD_SERVICE_${PN} = "srvcfg-manager.service" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/system/callback-manager.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/system/callback-manager.bb index 4bef0fd0e..e272fdc96 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/system/callback-manager.bb +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/system/callback-manager.bb @@ -7,7 +7,7 @@ inherit cmake systemd DEPENDS = "boost sdbusplus" PV = "0.1+git${SRCPV}" -SRCREV = "9d2d365a79591ec21b54ecde957263f1ba1d8391" +SRCREV = "4373d99e1edcbb4c7233abde3a5e53690693007b" S = "${WORKDIR}/git/callback-manager" 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 0cb531e60..2cc081433 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,7 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" #SRC_URI = "git://github.com/openbmc/phosphor-user-manager" -SRCREV = "59dba4435d0d553369790e8936d7eb43251ff302" +SRCREV = "75b5a6fc4c0c06f43623fe0e746fd55e667dceb3" SRC_URI += " \ diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0003-Add-redfish-log-support-for-IPMI-watchdog-pre-timeou.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0003-Add-redfish-log-support-for-IPMI-watchdog-pre-timeou.patch new file mode 100644 index 000000000..309a8c646 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0003-Add-redfish-log-support-for-IPMI-watchdog-pre-timeou.patch @@ -0,0 +1,48 @@ +From 46e8e4fe6cb48145152e37380a4064c8957d2ff7 Mon Sep 17 00:00:00 2001 +From: Ren Yu <yux.ren@intel.com> +Date: Tue, 28 May 2019 17:04:10 +0800 +Subject: [PATCH] Add redfish log support for IPMI watchdog pre-timeout + interrupt + +Tested: +Config IPMI watchdog: BIOS FRB2 Power Cycle after 1 seconds: +ipmitool raw 0x06 0x24 0x01 0x13 0x0 0x2 0xa 0x00 +Start watchdog: +Ipmitool mc watchdog reset +Check the redfish logs in 1 seconds: +https://BMCIP/redfish/v1/Systems/system/LogServices/EventLog/Entries + +Signed-off-by: Ren Yu <yux.ren@intel.com> +--- + watchdog.cpp | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/watchdog.cpp b/watchdog.cpp +index d893237..5062049 100644 +--- a/watchdog.cpp ++++ b/watchdog.cpp +@@ -104,6 +104,8 @@ uint64_t Watchdog::timeRemaining(uint64_t value) + // Optional callback function on timer expiration + void Watchdog::timeOutHandler() + { ++ PreTimeoutInterruptAction preTimeoutInterruptAction = preTimeoutInterrupt(); ++ + Action action = expireAction(); + if (!this->enabled()) + { +@@ -117,6 +119,12 @@ void Watchdog::timeOutHandler() + "REDFISH_MESSAGE_ARGS=%s", + convertForMessage(action).c_str(), NULL); + ++ sd_journal_send("MESSAGE=IPMIWatchdog: Pre Timed out Interrupt=%s", ++ convertForMessage(preTimeoutInterruptAction).c_str(), ++ "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s", ++ "OpenBMC.0.1.IPMIWatchdog", "REDFISH_MESSAGE_ARGS=%s", ++ convertForMessage(preTimeoutInterruptAction).c_str(), NULL); ++ + expiredTimerUse(currentTimerUse()); + + auto target = actionTargetMap.find(action); +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend index d9c047461..c117102ee 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend @@ -2,6 +2,7 @@ FILESEXTRAPATHS_append := ":${THISDIR}/${PN}" SRC_URI += "file://0001-Add-redfish-log-support-for-IPMI-watchdog-timeout-ac.patch \ file://0002-Add-restart-cause-support.patch \ + file://0003-Add-redfish-log-support-for-IPMI-watchdog-pre-timeou.patch \ " # Remove the override to keep service running after DC cycle 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 e6e329d06..f4b054acf 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,6 +1,6 @@ FILESEXTRAPATHS_append := ":${THISDIR}/${PN}" #SRC_URI = "git://github.com/openbmc/phosphor-webui.git" -SRCREV = "5bd1dec7fdc8f6a3a20e6c23dc491b3d31392bc5" +SRCREV = "e4ae854c217344b4f35717e922083a253f43bfa0" SRC_URI += "file://0004-Implement-force-boot-to-bios-in-server-power-control.patch" |