summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0029-FFUJ-FW-IPMI-commands-and-flash-support-in-u-boot.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0029-FFUJ-FW-IPMI-commands-and-flash-support-in-u-boot.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0029-FFUJ-FW-IPMI-commands-and-flash-support-in-u-boot.patch1273
1 files changed, 0 insertions, 1273 deletions
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
deleted file mode 100644
index 3c21a7c0a..000000000
--- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0029-FFUJ-FW-IPMI-commands-and-flash-support-in-u-boot.patch
+++ /dev/null
@@ -1,1273 +0,0 @@
-From 0f64b0e0c0a122ce23b5ccc518f514ec296bc7f5 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 | 13 +
- configs/ast_g5_phy_defconfig | 1 +
- 10 files changed, 1093 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..3647d5f 100644
---- a/common/autoboot.c
-+++ b/common/autoboot.c
-@@ -349,6 +349,19 @@ 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()) {
-+ printf("#### Force firmware update mode is enabled, "
-+ "Serial console is disabled. ####\n");
-+ 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 1b96ab7..5965a9b 100644
---- a/configs/ast_g5_phy_defconfig
-+++ b/configs/ast_g5_phy_defconfig
-@@ -15,3 +15,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
-