summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-bsp/u-boot
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-bsp/u-boot')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0016-Add-support-for-128MB-Macronix-spi-flash-MX66L1G45G.patch28
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0017-Enable-Macronix-and-Micron-SPI-support.patch54
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0018-Add-support-for-Macronix-and-Micron-1Gbits-SPI-flash.patch73
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-KCS-driver-support-in-uBoot.patch45
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0024-IPMI-command-handler-implementation-in-uboot.patch29
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0029-FFUJ-FW-IPMI-commands-and-flash-support-in-u-boot.patch1271
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend19
-rw-r--r--[l---------]meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-fw-utils-aspeed_%.bbappend51
8 files changed, 1364 insertions, 206 deletions
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