summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-bsp
diff options
context:
space:
mode:
authorEd Tanous <ed.tanous@intel.com>2019-04-15 23:42:44 +0300
committerEd Tanous <ed.tanous@intel.com>2019-04-17 19:13:25 +0300
commit816d793003e93c1e5eec0a2e90fbd8b9dde9f7a5 (patch)
tree341534fed9a2de460ded7f8231ca1cbb178bb2ca /meta-openbmc-mods/meta-common/recipes-bsp
parenta75bff085ba9443315222231c42692745e5781e9 (diff)
downloadopenbmc-816d793003e93c1e5eec0a2e90fbd8b9dde9f7a5.tar.xz
Update 4-15-19
Signed-off-by: Ed Tanous <ed.tanous@intel.com>
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-bsp')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0018-Add-support-for-Macronix-and-Micron-1Gbits-SPI-flash.patch24
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0020-Add-system-reset-status-support.patch103
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-KCS-driver-support-in-uBoot.patch620
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-u-boot-env-change-for-PFR-image.patch35
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0023-Add-TPM-enable-pulse-triggering.patch52
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0024-IPMI-command-handler-implementation-in-uboot.patch339
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend49
7 files changed, 1098 insertions, 124 deletions
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
index b96211118..2ed297a96 100644
--- 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
@@ -1,4 +1,4 @@
-From 5f2a7c03c877454eb78a406934abf6b7d05e40a6 Mon Sep 17 00:00:00 2001
+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
@@ -7,27 +7,25 @@ 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 | 32 ++++++++++++++++++++++++++++++++
- 1 file changed, 32 insertions(+)
+ 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 f9f1345523d4..abc0420176a6 100644
+index dece4315d755..2a31b6503a22 100644
--- a/arch/arm/mach-aspeed/flash.c
+++ b/arch/arm/mach-aspeed/flash.c
-@@ -79,6 +79,8 @@ flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* FLASH chips info */
+@@ -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 MT25QL01GB 0x21BA20
#define SST25VF016B 0x4125bf
#define SST25VF064C 0x4b25bf
#define SST25VF040B 0x8d25bf
-@@ -977,6 +979,36 @@ static ulong flash_get_size (ulong base, flash_info_t *info)
+@@ -978,6 +979,35 @@ static ulong flash_get_size (ulong base, flash_info_t *info)
#endif
break;
-+ case MT25QL01GB:
+ case MX66L1G45G:
+ erase_region_size = 0x10000;
+ info->readcmd = 0x0b;
@@ -60,6 +58,16 @@ index f9f1345523d4..abc0420176a6 100644
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/0020-Add-system-reset-status-support.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0020-Add-system-reset-status-support.patch
index 814a7dc2a..2e541561a 100644
--- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0020-Add-system-reset-status-support.patch
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0020-Add-system-reset-status-support.patch
@@ -1,6 +1,6 @@
-From d0338f68edb7f818b45ee43765cf124c14ccae03 Mon Sep 17 00:00:00 2001
+From 06445210bfda7f9bbbb36133e6818575bd6a0cc1 Mon Sep 17 00:00:00 2001
From: Yong Li <yong.b.li@linux.intel.com>
-Date: Tue, 22 Jan 2019 16:15:36 +0800
+Date: Tue, 9 Apr 2019 14:42:05 +0800
Subject: [PATCH] Add system reset status support
Will display the reset reasons and other CPU information in u-boot,
@@ -9,25 +9,12 @@ for applications to query.
Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
---
- arch/arm/include/asm/arch-aspeed/ast_scu.h | 1 +
arch/arm/include/asm/arch-aspeed/platform.h | 2 ++
- arch/arm/mach-aspeed/ast-scu.c | 55 +++++++++++++++++++++++++++++
- board/aspeed/ast-g5/ast-g5-intel.c | 30 ++++++++++++++++
- board/aspeed/ast-g5/ast-g5.c | 7 ++++
- 5 files changed, 95 insertions(+)
+ arch/arm/mach-aspeed/ast-scu.c | 4 ++++
+ board/aspeed/ast-g5/ast-g5-intel.c | 30 +++++++++++++++++++++++++++++
+ board/aspeed/ast-g5/ast-g5.c | 7 +++++++
+ 4 files changed, 43 insertions(+)
-diff --git a/arch/arm/include/asm/arch-aspeed/ast_scu.h b/arch/arm/include/asm/arch-aspeed/ast_scu.h
-index c10e6a9..369c4e3 100644
---- a/arch/arm/include/asm/arch-aspeed/ast_scu.h
-+++ b/arch/arm/include/asm/arch-aspeed/ast_scu.h
-@@ -37,6 +37,7 @@ extern void ast_scu_get_who_init_dram(void);
-
- extern u32 ast_get_clk_source(void);
- extern u32 ast_get_h_pll_clk(void);
-+extern u32 ast_get_m_pll_clk(void);
- extern u32 ast_get_ahbclk(void);
-
- extern u32 ast_scu_get_vga_memsize(void);
diff --git a/arch/arm/include/asm/arch-aspeed/platform.h b/arch/arm/include/asm/arch-aspeed/platform.h
index 3b06e52..4e4140d 100644
--- a/arch/arm/include/asm/arch-aspeed/platform.h
@@ -42,82 +29,10 @@ index 3b06e52..4e4140d 100644
#err "No define for platform.h"
#endif
diff --git a/arch/arm/mach-aspeed/ast-scu.c b/arch/arm/mach-aspeed/ast-scu.c
-index 63e9c7c..f4268f3 100644
+index 3a9ba05..976c59b 100644
--- a/arch/arm/mach-aspeed/ast-scu.c
+++ b/arch/arm/mach-aspeed/ast-scu.c
-@@ -100,6 +100,7 @@ static struct soc_id soc_map_table[] = {
- SOC_ID("AST2510-A1", 0x04010103),
- SOC_ID("AST2520-A1", 0x04010203),
- SOC_ID("AST2530-A1", 0x04010403),
-+ SOC_ID("AST2500-A2", 0x04030303),
- };
-
- void ast_scu_init_eth(u8 num)
-@@ -235,6 +236,29 @@ u32 ast_get_h_pll_clk(void)
- return clk;
- }
-
-+u32 ast_get_m_pll_clk(void)
-+{
-+ u32 clk=0;
-+ u32 m_pll_set = ast_scu_read(AST_SCU_M_PLL);
-+
-+ if(m_pll_set & SCU_M_PLL_OFF)
-+ return 0;
-+
-+ // Programming
-+ clk = ast_get_clk_source();
-+ if(m_pll_set & SCU_M_PLL_BYPASS) {
-+ return clk;
-+ } else {
-+ //PD == SCU20[13:18]
-+ //M == SCU20[5:12]
-+ //N == SCU20[0:4]
-+ //mpll = 24MHz * [(M+1) /(N+1)] / (P+1)
-+ clk = ((clk * (SCU_M_PLL_GET_MNUM(m_pll_set) + 1)) / (SCU_M_PLL_GET_NNUM(m_pll_set) + 1))/(SCU_M_PLL_GET_PDNUM(m_pll_set) + 1);
-+ }
-+ debug("m_pll = %d\n",clk);
-+ return clk;
-+}
-+
- u32 ast_get_ahbclk(void)
- {
- unsigned int axi_div, ahb_div, hpll;
-@@ -304,6 +328,33 @@ u32 ast_get_h_pll_clk(void)
- return clk;
- }
-
-+u32 ast_get_m_pll_clk(void)
-+{
-+ u32 clk=0;
-+ u32 m_pll_set = ast_scu_read(AST_SCU_M_PLL);
-+
-+ if(m_pll_set & SCU_M_PLL_OFF)
-+ return 0;
-+
-+ // Programming
-+ clk = ast_get_clk_source();
-+ if(m_pll_set & SCU_M_PLL_BYPASS) {
-+ return clk;
-+ } else {
-+ //OD == SCU24[4]
-+ //OD = SCU_M_PLL_GET_DIV(h_pll_set);
-+ //Numerator == SCU24[10:5]
-+ //num = SCU_M_PLL_GET_NUM(h_pll_set);
-+ //Denumerator == SCU24[3:0]
-+ //denum = SCU_M_PLL_GET_DENUM(h_pll_set);
-+
-+ //hpll = 24MHz * (2-OD) * ((Numerator+2)/(Denumerator+1))
-+ clk = (clk * (2-SCU_M_PLL_GET_DIV(m_pll_set)) * ((SCU_M_PLL_GET_NUM(m_pll_set)+2)/(SCU_M_PLL_GET_DENUM(m_pll_set)+1)));
-+ }
-+ debug("m_pll = %d\n",clk);
-+ return clk;
-+}
-+
- u32 ast_get_ahbclk(void)
- {
- unsigned int div, hpll;
-@@ -452,6 +503,9 @@ void ast_scu_sys_rest_info(void)
+@@ -494,6 +494,9 @@ void ast_scu_sys_rest_info(void)
{
u32 rest = ast_scu_read(AST_SCU_SYS_CTRL);
@@ -127,7 +42,7 @@ index 63e9c7c..f4268f3 100644
if (rest & SCU_SYS_EXT_RESET_FLAG) {
printf("RST : External\n");
ast_scu_write(SCU_SYS_EXT_RESET_FLAG, AST_SCU_SYS_CTRL);
-@@ -464,6 +518,7 @@ void ast_scu_sys_rest_info(void)
+@@ -506,6 +509,7 @@ void ast_scu_sys_rest_info(void)
} else {
printf("RST : CLK en\n");
}
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
new file mode 100644
index 000000000..79028d2a1
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-KCS-driver-support-in-uBoot.patch
@@ -0,0 +1,620 @@
+From 16209364c27a0cb7e2b7fdd445942f68e9180263 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
+
+Added KCS support in uBoot. This will enable
+KCS channels and set the specified registers
+to do KCS communication in uBoot. It also
+consist of read and write KCS message transations
+work flow implementation( As specified in IPMI
+specification Section 9.15). It is enabled
+only when Force Firmware Update Jumper is ON.
+
+Tested By:
+Stopped booting in uBoot and sent IPMI commands
+via KCS interfaces using cmdtool.efi.
+ - Get Device ID:
+ Req: cmdtool.efi 20 18 1
+ Res: 00 23 00 12 03 02 BF 57 01 00 7B 00 00 00 00 00
+ - Get Self Test Results
+ Req: cmdtool.efi 20 18 4
+ Res: 00 56 00
+ - All other commands
+ Req: cmdtool.efi 20 18 2
+ Res: C1 (Invalid).
+
+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(+)
+ create mode 100644 board/aspeed/ast-g5/ast-g5-kcs.c
+ create mode 100644 board/aspeed/ast-g5/ast-g5-kcs.h
+
+diff --git a/board/aspeed/ast-g5/Makefile b/board/aspeed/ast-g5/Makefile
+index 9022433..05972b9 100644
+--- a/board/aspeed/ast-g5/Makefile
++++ b/board/aspeed/ast-g5/Makefile
+@@ -4,3 +4,4 @@ obj-y += ast-g5-espi.o
+ obj-y += ast-g5-irq.o
+ obj-y += ast-g5-gpio.o
+ 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
+--- 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)
+ }
+
+ extern void espi_init(void);
++extern void kcs_init(void);
+ void ast_g5_intel(void)
+ {
+ pwm_init();
+@@ -446,6 +447,8 @@ void ast_g5_intel(void)
+ timer8_init();
+ if (intel_force_firmware_jumper_enabled()) {
+ id_led_control(GPIO_AMBER_LED, EIDLED_On);
++ kcs_init();
++ /* TODO: need to stop the booting here. */
+ } else {
+ id_led_control(GPIO_GREEN_LED, EIDLED_On);
+ }
+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
+--- /dev/null
++++ b/board/aspeed/ast-g5/ast-g5-kcs.c
+@@ -0,0 +1,425 @@
++// 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
++#define DBG_KCS(...)
++#endif
++
++/* TODO: Move to IPMI file. */
++#define IPMI_CC_OK 0x00
++#define IPMI_CC_INVALID 0xC1
++#define IPMI_CC_UNSPECIFIED 0xFF
++
++#define KCS_CHANNEL_NO_3 3
++
++static const u16 enabled_kcs_channel[] = { KCS_CHANNEL_NO_3 };
++
++static const struct kcs_io_reg ast_kcs_bmc_ioregs[KCS_CHANNEL_MAX] = {
++ { .idr = LPC_IDR1, .odr = LPC_ODR1, .str = LPC_STR1 },
++ { .idr = LPC_IDR2, .odr = LPC_ODR2, .str = LPC_STR2 },
++ { .idr = LPC_IDR3, .odr = LPC_ODR3, .str = LPC_STR3 },
++ { .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 }
++};
++
++#define NO_OF_ENABLED_KCS_CHANNELS ARRAY_SIZE(enabled_kcs_channel)
++
++static struct kcs_packet m_kcs_pkt[NO_OF_ENABLED_KCS_CHANNELS];
++
++static u16 read_status(u16 channel_num)
++{
++ return readl(AST_LPC_BASE + ast_kcs_bmc_ioregs[channel_num - 1].str);
++}
++
++static void write_status(u16 channel_num, u16 value)
++{
++ writel(value, AST_LPC_BASE + ast_kcs_bmc_ioregs[channel_num - 1].str);
++}
++
++static u16 read_data(u16 channel_num)
++{
++ return readl(AST_LPC_BASE + ast_kcs_bmc_ioregs[channel_num - 1].idr);
++}
++
++static void write_data(u16 channel_num, u16 value)
++{
++ writel(value, AST_LPC_BASE + ast_kcs_bmc_ioregs[channel_num - 1].odr);
++}
++
++static void set_kcs_state(u16 channel_num, u16 state)
++{
++ u16 status = read_status(channel_num);
++
++ status &= ~KCS_STATE_MASK;
++ status |= KCS_STATE(state) & KCS_STATE_MASK;
++ write_status(channel_num, status);
++}
++
++static struct kcs_packet *get_kcs_packet(u16 channel_num)
++{
++ for (u16 idx = 0; idx < NO_OF_ENABLED_KCS_CHANNELS; idx++) {
++ if (channel_num == enabled_kcs_channel[idx])
++ return &m_kcs_pkt[idx];
++ }
++
++ /* very unlike code hits here. */
++ printf("ERROR: %s error. ChannelNo: %d\n", __func__, channel_num);
++ BUG();
++}
++
++static void kcs_force_abort(u16 channel_num)
++{
++ struct kcs_packet *kcs_pkt = NULL;
++
++ kcs_pkt = get_kcs_packet(channel_num);
++ printf("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);
++ write_data(channel_num, ZERO_DATA);
++
++ kcs_pkt->phase = KCS_PHASE_ERROR;
++ kcs_pkt->read_req_done = false;
++ kcs_pkt->data_in_idx = 0;
++}
++
++static void init_kcs_packet(u16 channel_num)
++{
++ struct kcs_packet *kcs_pkt = NULL;
++
++ kcs_pkt = get_kcs_packet(channel_num);
++ kcs_pkt->channel = channel_num;
++ kcs_pkt->read_req_done = false;
++ kcs_pkt->phase = KCS_PHASE_IDLE;
++ kcs_pkt->error = KCS_NO_ERROR;
++ kcs_pkt->data_in_idx = 0;
++ kcs_pkt->data_out_idx = 0;
++ kcs_pkt->data_out_len = 0;
++}
++
++static void process_kcs_request(u16 channel_num)
++{
++ struct kcs_packet *kcs_pkt = NULL;
++
++ 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;
++
++ 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]);
++ DBG_KCS("\n");
++#endif
++
++ /*
++ * TODO: Move it to IPMI Command Handler
++ * Below code is added for timebeing till
++ * we implement the IPMI command handler.
++ */
++ kcs_pkt->data_out[0] = kcs_pkt->data_in[0]; /* netfn */
++ kcs_pkt->data_out[1] = kcs_pkt->data_in[1]; /* cmd */
++ kcs_pkt->data_out[2] = IPMI_CC_OK; /* cc */
++
++ if (((kcs_pkt->data_in[0] >> 2) == 0x06) &&
++ (kcs_pkt->data_in[1] == 0x01)) {
++ /* Get Device ID */
++ u8 device_id[15] = { 0x23, 0x00, 0x12, 0x03, 0x02,
++ 0xBF, 0x57, 0x01, 0x00, 0x7B,
++ 0x00, 0x00, 0x00, 0x00, 0x00 };
++ for (i = 0; i < 15; i++)
++ kcs_pkt->data_out[i + 3] = device_id[i];
++ kcs_pkt->data_out_len = 18;
++ } else if (((kcs_pkt->data_in[0] >> 2) == 0x06) &&
++ (kcs_pkt->data_in[1] == 0x04)) {
++ /* Get Self Test Results */
++ kcs_pkt->data_out[3] = 0x56;
++ kcs_pkt->data_out[4] = 0x00;
++ kcs_pkt->data_out_len = 5;
++ } else {
++ kcs_pkt->data_out[2] =
++ IPMI_CC_INVALID; /* Invalid or not supported. */
++ kcs_pkt->data_out_len = 3;
++ }
++ /* END: TODO */
++
++#ifdef DEBUG_KCS_ENABLED
++ DBG_KCS("Response data(Len:%d): ", kcs_pkt->data_out_len);
++ for (i = 0; i < kcs_pkt->data_out_len; i++)
++ DBG_KCS(" 0x%02x", kcs_pkt->data_out[i]);
++ DBG_KCS("\n");
++#endif
++
++ kcs_pkt->phase = KCS_PHASE_READ;
++ write_data(channel_num, kcs_pkt->data_out[kcs_pkt->data_out_idx++]);
++ kcs_pkt->read_req_done = false;
++}
++
++static void read_kcs_data(u16 channel_num)
++{
++ 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:
++ kcs_pkt->phase = KCS_PHASE_WRITE_DATA;
++ /* fall through */
++
++ case KCS_PHASE_WRITE_DATA:
++ if (kcs_pkt->data_in_idx >= MAX_KCS_PKT_SIZE) {
++ kcs_pkt->error = KCS_LENGTH_ERROR;
++ kcs_force_abort(channel_num);
++ return;
++ }
++ set_kcs_state(channel_num, KCS_STATE_WRITE);
++ write_data(channel_num, ZERO_DATA);
++ kcs_pkt->data_in[kcs_pkt->data_in_idx++] =
++ read_data(channel_num);
++ break;
++
++ case KCS_PHASE_WRITE_END:
++ if (kcs_pkt->data_in_idx >= MAX_KCS_PKT_SIZE) {
++ kcs_pkt->error = KCS_LENGTH_ERROR;
++ kcs_force_abort(channel_num);
++ return;
++ }
++ set_kcs_state(channel_num, KCS_STATE_READ);
++ kcs_pkt->data_in[kcs_pkt->data_in_idx++] =
++ read_data(channel_num);
++ kcs_pkt->phase = KCS_PHASE_READ_WAIT;
++ kcs_pkt->read_req_done = true;
++
++ process_kcs_request(channel_num);
++ break;
++
++ case KCS_PHASE_READ:
++ if (kcs_pkt->data_out_idx == kcs_pkt->data_out_len)
++ set_kcs_state(channel_num, KCS_STATE_IDLE);
++
++ u8 data = read_data(channel_num);
++ if (data != KCS_CTRL_CODE_READ) {
++ DBG_KCS("Invalid Read data. Phase:%d, Data:0x%02x\n",
++ kcs_pkt->phase, data);
++ set_kcs_state(channel_num, KCS_STATE_ERROR);
++ write_data(channel_num, ZERO_DATA);
++ break;
++ }
++
++ if (kcs_pkt->data_out_idx == kcs_pkt->data_out_len) {
++ write_data(channel_num, ZERO_DATA);
++ kcs_pkt->phase = KCS_PHASE_IDLE;
++ break;
++ }
++ write_data(channel_num,
++ kcs_pkt->data_out[kcs_pkt->data_out_idx++]);
++ break;
++
++ case KCS_PHASE_ABORT_1:
++ set_kcs_state(channel_num, KCS_STATE_READ);
++ read_data(channel_num);
++ write_data(channel_num, kcs_pkt->error);
++ kcs_pkt->phase = KCS_PHASE_ABORT_2;
++ break;
++
++ case KCS_PHASE_ABORT_2:
++ set_kcs_state(channel_num, KCS_STATE_IDLE);
++ read_data(channel_num);
++ write_data(channel_num, ZERO_DATA);
++ kcs_pkt->phase = KCS_PHASE_IDLE;
++ break;
++
++ default:
++ kcs_force_abort(channel_num);
++ }
++}
++
++static void read_kcs_cmd(u16 channel_num)
++{
++ struct kcs_packet *kcs_pkt = NULL;
++
++ kcs_pkt = get_kcs_packet(channel_num);
++
++ set_kcs_state(channel_num, KCS_STATE_WRITE);
++ 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);
++ kcs_pkt->phase = KCS_PHASE_WRITE_START;
++ break;
++
++ case KCS_CTRL_CODE_WRITE_END:
++ if (kcs_pkt->error != KCS_NO_ERROR) {
++ kcs_force_abort(channel_num);
++ return;
++ }
++
++ kcs_pkt->phase = KCS_PHASE_WRITE_END;
++ break;
++
++ case KCS_CTRL_CODE_GET_STATUS_ABORT:
++ kcs_pkt->phase = KCS_PHASE_ABORT_1;
++ kcs_pkt->error = KCS_ABORT_BY_CMD;
++ break;
++
++ default:
++ kcs_pkt->error = KCS_ILLEGAL_CTRL_CMD;
++ kcs_force_abort(channel_num);
++ }
++}
++
++static u16 kcs_irq_handler(struct pt_regs *regs)
++{
++ for (u16 idx = 0; idx < NO_OF_ENABLED_KCS_CHANNELS; idx++) {
++ u16 channel_num = enabled_kcs_channel[idx];
++ /* Look-up the interrupted KCS channel */
++ u16 status = read_status(channel_num);
++ if (status & BIT_STATUS_IBF) {
++ if (status & BIT_STATUS_COD)
++ read_kcs_cmd(channel_num);
++ else
++ read_kcs_data(channel_num);
++ }
++ }
++
++ return 0;
++}
++
++static void set_kcs_channel_addr(u16 channel_num)
++{
++ u32 val;
++
++ switch (channel_num) {
++ case 1:
++ val = readl(AST_LPC_BASE + LPC_HICR4) & ~BIT_LADR12AS;
++ writel(val, AST_LPC_BASE + LPC_HICR4);
++ val = (KCS_CHANNEL1_ADDR >> 8);
++ writel(val, AST_LPC_BASE + LPC_LADR12H);
++ val = (KCS_CHANNEL1_ADDR & 0xFF);
++ writel(val, AST_LPC_BASE + LPC_LADR12L);
++ break;
++
++ case 2:
++ val = readl(AST_LPC_BASE + LPC_HICR4) | BIT_LADR12AS;
++ writel(val, AST_LPC_BASE + LPC_HICR4);
++ val = (KCS_CHANNEL2_ADDR >> 8);
++ writel(val, AST_LPC_BASE + LPC_LADR12H);
++ val = (KCS_CHANNEL2_ADDR & 0xFF);
++ writel(val, AST_LPC_BASE + LPC_LADR12L);
++ break;
++
++ case 3:
++ val = (KCS_CHANNEL3_ADDR >> 8);
++ writel(val, AST_LPC_BASE + LPC_LADR3H);
++ val = (KCS_CHANNEL3_ADDR & 0xFF);
++ writel(val, AST_LPC_BASE + LPC_LADR3L);
++ break;
++
++ case 4:
++ val = (((KCS_CHANNEL4_ADDR + 1) << 16) | KCS_CHANNEL4_ADDR);
++ writel(val, AST_LPC_BASE + LPC_LADR4);
++ break;
++
++ default:
++ DBG_KCS("Invalid channel (%d) specified\n", channel_num);
++ break;
++ }
++}
++
++static void enable_kcs_channel(u16 channel_num, u16 enable)
++{
++ u32 val;
++
++ switch (channel_num) {
++ case 1:
++ if (enable) {
++ val = readl(AST_LPC_BASE + LPC_HICR2) | BIT_IBFIE1;
++ writel(val, AST_LPC_BASE + LPC_HICR2);
++ val = readl(AST_LPC_BASE + LPC_HICR0) | BIT_LPC1E;
++ writel(val, AST_LPC_BASE + LPC_HICR0);
++ } else {
++ val = readl(AST_LPC_BASE + LPC_HICR0) & ~BIT_LPC1E;
++ writel(val, AST_LPC_BASE + LPC_HICR0);
++ val = readl(AST_LPC_BASE + LPC_HICR2) & ~BIT_IBFIE1;
++ writel(val, AST_LPC_BASE + LPC_HICR2);
++ }
++ break;
++
++ case 2:
++ if (enable) {
++ val = readl(AST_LPC_BASE + LPC_HICR2) | BIT_IBFIE2;
++ writel(val, AST_LPC_BASE + LPC_HICR2);
++ val = readl(AST_LPC_BASE + LPC_HICR0) | BIT_LPC2E;
++ writel(val, AST_LPC_BASE + LPC_HICR0);
++ } else {
++ val = readl(AST_LPC_BASE + LPC_HICR0) & ~BIT_LPC2E;
++ writel(val, AST_LPC_BASE + LPC_HICR0);
++ val = readl(AST_LPC_BASE + LPC_HICR2) & ~BIT_IBFIE2;
++ writel(val, AST_LPC_BASE + LPC_HICR2);
++ }
++ break;
++
++ case 3:
++ if (enable) {
++ val = readl(AST_LPC_BASE + LPC_HICR2) | BIT_IBFIE3;
++ writel(val, AST_LPC_BASE + LPC_HICR2);
++ val = readl(AST_LPC_BASE + LPC_HICR0) | BIT_LPC3E;
++ writel(val, AST_LPC_BASE + LPC_HICR0);
++ val = readl(AST_LPC_BASE + LPC_HICR4) | BIT_KCSENBL;
++ writel(val, AST_LPC_BASE + LPC_HICR4);
++ } else {
++ val = readl(AST_LPC_BASE + LPC_HICR0) & ~BIT_LPC3E;
++ writel(val, AST_LPC_BASE + LPC_HICR0);
++ val = readl(AST_LPC_BASE + LPC_HICR4) & ~BIT_KCSENBL;
++ writel(val, AST_LPC_BASE + LPC_HICR4);
++ val = readl(AST_LPC_BASE + LPC_HICR2) & ~BIT_IBFIE3;
++ writel(val, AST_LPC_BASE + LPC_HICR2);
++ }
++ break;
++
++ case 4:
++ if (enable) {
++ val = readl(AST_LPC_BASE + LPC_HICRB) | BIT_IBFIE4 |
++ BIT_LPC4E;
++ writel(val, AST_LPC_BASE + LPC_HICRB);
++ } else {
++ val = readl(AST_LPC_BASE + LPC_HICRB) &
++ ~(BIT_IBFIE4 | BIT_LPC4E);
++ writel(val, AST_LPC_BASE + LPC_HICRB);
++ }
++ break;
++
++ default:
++ DBG_KCS("Invalid channel (%d) specified\n", channel_num);
++ }
++}
++
++void kcs_init(void)
++{
++ /* Initialize the KCS channels. */
++ for (u16 idx = 0; idx < NO_OF_ENABLED_KCS_CHANNELS; idx++) {
++ u16 channel_num = enabled_kcs_channel[idx];
++ DBG_KCS("%s Channel: %d\n", __func__, channel_num);
++ set_kcs_channel_addr(channel_num);
++ enable_kcs_channel(channel_num, 1);
++
++ /* Set KCS channel state to idle */
++ set_kcs_state(channel_num, KCS_STATE_IDLE);
++ }
++
++ /* KCS interrupt */
++ request_irq(IRQ_SRC_LPC, kcs_irq_handler);
++}
+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
+--- /dev/null
++++ b/board/aspeed/ast-g5/ast-g5-kcs.h
+@@ -0,0 +1,114 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/* Copyright (c) 2018-2019 Intel Corporation */
++
++#include <asm/io.h>
++#include <common.h>
++
++#include "ast-g5.h"
++
++#define KCS_CHANNEL_MAX 4
++#define IRQ_SRC_LPC 8 /* IRQ 8 */
++#define MAX_KCS_PKT_SIZE (64 * 1024)
++/* KCS channel addresses */
++#define KCS_CHANNEL1_ADDR 0xCA0
++#define KCS_CHANNEL2_ADDR 0xCA8
++#define KCS_CHANNEL3_ADDR 0xCA2
++#define KCS_CHANNEL4_ADDR 0xCB2
++
++#define ZERO_DATA 0x00
++
++/* Aspeed KCS control registers */
++#define LPC_HICR0 0x00 /* Host Interface Control Register 0 */
++#define LPC_HICR1 0x04 /* Host Interface Control Register 1 */
++#define LPC_HICR2 0x08 /* Host Interface Control Register 2 */
++#define LPC_HICR3 0x0C /* Host Interface Control Register 3 */
++#define LPC_HICR4 0x10 /* Host Interface Control Register 4 */
++#define LPC_LADR3H 0x14 /* LPC channel #3 Address Register H */
++#define LPC_LADR3L 0x18 /* LPC channel #3 Address Register H */
++#define LPC_LADR12H 0x1C /* LPC channel #1#2 Address Register H */
++#define LPC_LADR12L 0x20 /* LPC channel #1#2 Address Register L */
++#define LPC_IDR1 0x24 /* Input Data Register 1 */
++#define LPC_IDR2 0x28 /* Input Data Register 2 */
++#define LPC_IDR3 0x2C /* Input Data Register 3 */
++#define LPC_ODR1 0x30 /* Output Data Register 1 */
++#define LPC_ODR2 0x34 /* Output Data Register 2 */
++#define LPC_ODR3 0x38 /* Output Data Register 3 */
++#define LPC_STR1 0x3C /* Status Register 1 */
++#define LPC_STR2 0x40 /* Status Register 2 */
++#define LPC_STR3 0x44 /* Status Register 3 */
++
++/* LPC Bits */
++#define BIT_LADR12AS BIT(7) /* Channel Address selection */
++#define BIT_IBFIE1 BIT(1) /* Enable IDR1 Recv completion interrupt */
++#define BIT_IBFIE2 BIT(2) /* Enable IDR2 Recv completion interrupt */
++#define BIT_IBFIE3 BIT(3) /* Enable IBF13 interrupt */
++#define BIT_LPC1E BIT(5) /* Enable LPC channel #1 */
++#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 */
++#define BIT_STATUS_COD BIT(3) /* Command/Data - (1=command,0=data) */
++
++#define KCS_STATE_MASK 0xC0 /* BIT[6:7] of status register */
++#define KCS_STATE(state) ((state) << 6)
++
++/* IPMI2.0(section 9.7) - KCS interface State Bits */
++#define KCS_STATE_IDLE 0x00
++#define KCS_STATE_READ 0x01
++#define KCS_STATE_WRITE 0x02
++#define KCS_STATE_ERROR 0x03
++
++/* IPMI2.0(section 9.10) - KCS interface control codes */
++#define KCS_CTRL_CODE_GET_STATUS_ABORT 0x60
++#define KCS_CTRL_CODE_WRITE_START 0x61
++#define KCS_CTRL_CODE_WRITE_END 0x62
++#define KCS_CTRL_CODE_READ 0x68
++
++struct kcs_io_reg {
++ u32 idr;
++ u32 odr;
++ u32 str;
++};
++
++enum kcs_phase {
++ KCS_PHASE_IDLE = 0,
++ KCS_PHASE_WRITE_START = 1,
++ KCS_PHASE_WRITE_DATA = 2,
++ KCS_PHASE_WRITE_END = 3,
++ KCS_PHASE_READ_WAIT = 4,
++ KCS_PHASE_READ = 5,
++ KCS_PHASE_ABORT_1 = 6,
++ KCS_PHASE_ABORT_2 = 7,
++ KCS_PHASE_ERROR = 8
++};
++
++enum kcs_error {
++ KCS_NO_ERROR = 0x00,
++ KCS_ABORT_BY_CMD = 0x01,
++ KCS_ILLEGAL_CTRL_CMD = 0x02,
++ KCS_LENGTH_ERROR = 0x06,
++ KCS_UNSPECIFIED_ERROR = 0xFF,
++};
++
++struct kcs_packet {
++ enum kcs_phase phase;
++ enum kcs_error error;
++ u16 channel;
++ bool read_req_done;
++ u16 data_in_idx;
++ u8 data_in[MAX_KCS_PKT_SIZE];
++ u16 data_out_len;
++ u16 data_out_idx;
++ u8 data_out[MAX_KCS_PKT_SIZE];
++};
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-u-boot-env-change-for-PFR-image.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-u-boot-env-change-for-PFR-image.patch
new file mode 100644
index 000000000..746063a56
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-u-boot-env-change-for-PFR-image.patch
@@ -0,0 +1,35 @@
+From 6651a2663ee3e9f02c6ed8377097456528a2ee1a Mon Sep 17 00:00:00 2001
+From: Vikram Bodireddy <vikram.bodireddy@intel.com>
+Date: Tue, 26 Mar 2019 20:34:51 +0530
+Subject: [PATCH] u-boot env change for PFR image
+
+Signed-off-by: Vikram Bodireddy <vikram.bodireddy@intel.com>
+---
+ include/configs/ast-common.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/configs/ast-common.h b/include/configs/ast-common.h
+index b7d7192..dd89d91 100644
+--- a/include/configs/ast-common.h
++++ b/include/configs/ast-common.h
+@@ -103,7 +103,7 @@
+ #define CONFIG_SYS_MAX_FLASH_BANKS (CONFIG_FMC_CS)
+ #define CONFIG_SYS_MAX_FLASH_SECT (8192) /* max number of sectors on one chip */
+ #define CONFIG_ENV_IS_IN_FLASH 1
+-#define CONFIG_ENV_OFFSET 0x2400000 /* environment starts here */
++#define CONFIG_ENV_OFFSET 0xa0000 /* environment starts here */
+ #define CONFIG_ENV_ADDR (AST_FMC_CS0_BASE + CONFIG_ENV_OFFSET)
+ #define CONFIG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
+
+@@ -111,7 +111,7 @@
+ #define CONFIG_ENV_ADDR_REDUND (AST_FMC_CS0_BASE + CONFIG_ENV_OFFSET_REDUND)
+ #define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
+
+-#define CONFIG_BOOTCOMMAND "bootm 20080000"
++#define CONFIG_BOOTCOMMAND "bootm 21100000"
+ #define CONFIG_ENV_OVERWRITE
+
+ #define ASPEED_ENV_SETTINGS \
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0023-Add-TPM-enable-pulse-triggering.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0023-Add-TPM-enable-pulse-triggering.patch
new file mode 100644
index 000000000..5e8cd103d
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0023-Add-TPM-enable-pulse-triggering.patch
@@ -0,0 +1,52 @@
+From f762526077a7af02fc93bacc74fb9d49481d664f Mon Sep 17 00:00:00 2001
+From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+Date: Fri, 29 Mar 2019 12:30:20 -0700
+Subject: [PATCH] Add TPM enable pulse triggering
+
+This commit adds onboard TPM enable pulse triggering.
+
+Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+---
+ board/aspeed/ast-g5/ast-g5-intel.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
+index f9955c70d2f2..d9ba4a47a413 100644
+--- a/board/aspeed/ast-g5/ast-g5-intel.c
++++ b/board/aspeed/ast-g5/ast-g5-intel.c
+@@ -53,8 +53,8 @@ static const GPIOValue gpio_table[] = {
+ GPIO_DEBOUNCE_8MS},
+
+ /* Enable Pulse -- pin D6 */
+- [GPIO_ENABLE_TPM_PULSE] = {PORT_PIN(GPIO_PORT_D, GPIO_PIN_6),
+- GPIO_CFG_DEFAULT, 0, GPIO_DEBOUNCE_8MS},
++ [GPIO_ENABLE_TPM_PULSE] = {TPM_EN_PULSE_PORT_PIN, GPCFG_OUTPUT_EN, 0,
++ GPIO_DEBOUNCE_NONE},
+ };
+
+ #define LPC_SNOOP_ADDR 0x80
+@@ -232,6 +232,13 @@ void id_led_control(int id, int action)
+ gpio_set_value(s_led_info[id].gpio, s_led_info[id].state);
+ }
+
++static void enable_onboard_tpm(void)
++{
++ gpio_set_value(GPIO_ENABLE_TPM_PULSE, 1);
++ mdelay(50);
++ gpio_set_value(GPIO_ENABLE_TPM_PULSE, 0);
++}
++
+ static void timer8_irq_handler(void *regs)
+ {
+ int i;
+@@ -445,6 +452,7 @@ void ast_g5_intel(void)
+ espi_init();
+ sgpio_init();
+ timer8_init();
++ enable_onboard_tpm();
+ if (intel_force_firmware_jumper_enabled()) {
+ id_led_control(GPIO_AMBER_LED, EIDLED_On);
+ kcs_init();
+--
+2.7.4
+
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
new file mode 100644
index 000000000..47cb56062
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0024-IPMI-command-handler-implementation-in-uboot.patch
@@ -0,0 +1,339 @@
+From d770ea7a30742339b0692858847838dd2a738aeb Mon Sep 17 00:00:00 2001
+From: AppaRao Puli <apparao.puli@linux.intel.com>
+Date: Fri, 5 Apr 2019 17:53:21 +0530
+Subject: [PATCH] IPMI command handler implementation in uboot
+
+IPMI command handler implemtation in uBoot.
+Implemented IPMI commands:
+ 1) Get Device ID
+ 2) Get Self Test Result
+
+Tested By:
+Ran the above IPMI command Via KCS channel
+and got proper response.
+- Get Device ID
+ Req: cmdtool.efi 20 18 1
+ Res: 0x00 0x23 0x00 0x82 0x03 0x02 0x00 0x57 0x01 0x00 0x7b 0x00 0x00 0x00 0x00 0x00
+- Get Self Test Results
+ Req: cmdtool.efi 20 18 4
+ Res: 00 56 00
+
+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/ipmi-handler.c | 118 +++++++++++++++++++++++++++++++++++++
+ board/aspeed/ast-g5/ipmi-handler.h | 40 +++++++++++++
+ 4 files changed, 202 insertions(+), 35 deletions(-)
+ create mode 100644 board/aspeed/ast-g5/ipmi-handler.c
+ create mode 100644 board/aspeed/ast-g5/ipmi-handler.h
+
+diff --git a/board/aspeed/ast-g5/Makefile b/board/aspeed/ast-g5/Makefile
+index 05972b9..f28fcfe 100644
+--- a/board/aspeed/ast-g5/Makefile
++++ b/board/aspeed/ast-g5/Makefile
+@@ -5,3 +5,4 @@ obj-y += ast-g5-irq.o
+ obj-y += ast-g5-gpio.o
+ obj-y += ast-g5-timer.o
+ 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
+--- a/board/aspeed/ast-g5/ast-g5-kcs.c
++++ b/board/aspeed/ast-g5/ast-g5-kcs.c
+@@ -1,7 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0
+ // Copyright (c) 2018-2019 Intel Corporation
+
+-#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(...)
+ #endif
+
+-/* TODO: Move to IPMI file. */
+-#define IPMI_CC_OK 0x00
+-#define IPMI_CC_INVALID 0xC1
+-#define IPMI_CC_UNSPECIFIED 0xFF
+-
+ #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)
+ 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)
+ DBG_KCS(" 0x%02x", kcs_pkt->data_in[i]);
+ DBG_KCS("\n");
+ #endif
++ u8 req_lun = kcs_pkt->data_in[0] & 0x03; /* LUN[1:0] */
++ ipmi_data.net_fun = (kcs_pkt->data_in[0] >> 2); /* netfn[7:2] */
++ ipmi_data.cmd = kcs_pkt->data_in[1]; /* cmd */
++ /* We support only BMC LUN 00h */
++ if (req_lun != LUN_BMC) {
++ kcs_pkt->data_out[0] =
++ GET_RESP_NETFN_LUN(req_lun, ipmi_data.net_fun);
++ kcs_pkt->data_out[1] = ipmi_data.cmd; /* cmd */
++ kcs_pkt->data_out[2] = IPMI_CC_INVALID_CMD_LUN; /* CC code */
++ kcs_pkt->data_out_len = 3;
++ goto done;
++ }
+
+- /*
+- * TODO: Move it to IPMI Command Handler
+- * Below code is added for timebeing till
+- * we implement the IPMI command handler.
+- */
+- kcs_pkt->data_out[0] = kcs_pkt->data_in[0]; /* netfn */
+- kcs_pkt->data_out[1] = kcs_pkt->data_in[1]; /* cmd */
+- kcs_pkt->data_out[2] = IPMI_CC_OK; /* cc */
+-
+- if (((kcs_pkt->data_in[0] >> 2) == 0x06) &&
+- (kcs_pkt->data_in[1] == 0x01)) {
+- /* Get Device ID */
+- u8 device_id[15] = { 0x23, 0x00, 0x12, 0x03, 0x02,
+- 0xBF, 0x57, 0x01, 0x00, 0x7B,
+- 0x00, 0x00, 0x00, 0x00, 0x00 };
+- for (i = 0; i < 15; i++)
+- kcs_pkt->data_out[i + 3] = device_id[i];
+- kcs_pkt->data_out_len = 18;
+- } else if (((kcs_pkt->data_in[0] >> 2) == 0x06) &&
+- (kcs_pkt->data_in[1] == 0x04)) {
+- /* Get Self Test Results */
+- kcs_pkt->data_out[3] = 0x56;
+- kcs_pkt->data_out[4] = 0x00;
+- kcs_pkt->data_out_len = 5;
+- } else {
+- kcs_pkt->data_out[2] =
+- IPMI_CC_INVALID; /* Invalid or not supported. */
++ /* Boundary check */
++ if ((kcs_pkt->data_in_idx - 2) > sizeof(ipmi_data.req_data)) {
++ kcs_pkt->data_out[0] =
++ GET_RESP_NETFN_LUN(req_lun, ipmi_data.net_fun);
++ kcs_pkt->data_out[1] = ipmi_data.cmd; /* cmd */
++ kcs_pkt->data_out[2] = IPMI_CC_OUT_OF_SPACE; /* CC code */
+ kcs_pkt->data_out_len = 3;
++ goto done;
+ }
+- /* END: TODO */
++ /* Fill in IPMI request data */
++ ipmi_data.req_len = kcs_pkt->data_in_idx - 2;
++ for (i = 0; i < kcs_pkt->data_in_idx - 2; i++)
++ ipmi_data.req_data[i] = kcs_pkt->data_in[i + 2];
++
++ /* Call IPMI command handler */
++ ipmi_cmd_handler(&ipmi_data);
++
++ /* Get IPMI response and fill KCS out data */
++ /* First 2 bytes in KCS response are netFn, Cmd */
++ kcs_pkt->data_out[0] = GET_RESP_NETFN_LUN(req_lun, ipmi_data.net_fun);
++ kcs_pkt->data_out[1] = ipmi_data.cmd;
++ if ((ipmi_data.res_len + 2) > sizeof(kcs_pkt->data_out)) {
++ kcs_pkt->data_out[2] = IPMI_CC_UNSPECIFIED; /* CC code */
++ kcs_pkt->data_out_len = 3;
++ goto done;
++ }
++ for (i = 0; i < ipmi_data.res_len; i++)
++ kcs_pkt->data_out[i + 2] = ipmi_data.res_data[i];
++
++ kcs_pkt->data_out_len = ipmi_data.res_len + 2;
+
+ #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)
+ DBG_KCS("\n");
+ #endif
+
++done:
+ kcs_pkt->phase = KCS_PHASE_READ;
+ write_data(channel_num, kcs_pkt->data_out[kcs_pkt->data_out_idx++]);
+ kcs_pkt->read_req_done = false;
+diff --git a/board/aspeed/ast-g5/ipmi-handler.c b/board/aspeed/ast-g5/ipmi-handler.c
+new file mode 100644
+index 0000000..9cccee9
+--- /dev/null
++++ b/board/aspeed/ast-g5/ipmi-handler.c
+@@ -0,0 +1,118 @@
++
++// SPDX-License-Identifier: GPL-2.0
++// Copyright (c) 2018-2019 Intel Corporation
++
++#include "ipmi-handler.h"
++
++/* IPMI network function codes */
++#define NETFN_APP 0x06
++
++/* IPMI command codes */
++#define CMD_GET_DEV_ID 0x01
++#define CMD_GET_SELF_TEST_RESULTS 0x04
++
++typedef u16 (*fun_handler)(u8 *req, u16 req_len, u8 *res);
++
++struct get_dev_id {
++ u8 completion_code;
++ u8 dev_id;
++ u8 dev_rev;
++ u8 fw_rev1;
++ u8 fw_rev2;
++ u8 ipmi_ver;
++ u8 dev_support;
++ u8 mfg_id[3];
++ u8 product_id[2];
++ u8 aux_fw_rev[4];
++};
++struct self_test_res {
++ u8 completion_code;
++ u8 res_byte[2];
++};
++
++struct ipmi_cmd_table {
++ u8 net_fun;
++ u8 cmd;
++ fun_handler process_cmd;
++};
++
++static u16 get_device_id(u8 *req, u16 req_len, u8 *res)
++{
++ /* Get Device ID */
++ bool operation = 1; /* Firmware operation */
++ u8 intel_mfg_id[3] = { 0x57, 0x01, 0x00 };
++ u8 platform_id[2] = { 0x7B, 0x00 };
++ u8 aux_fw_rev[4] = { 0x00, 0x00, 0x00, 0x00 };
++ struct get_dev_id *result = (struct get_dev_id *)res;
++
++ if (req_len != 0) {
++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH;
++ return sizeof(result->completion_code);
++ }
++
++ result->completion_code = IPMI_CC_OK;
++ result->dev_id = 0x23;
++ result->dev_rev = 0x00; /* Not provides dev SDR */
++
++ result->ipmi_ver = 0x02; /* IPMI 2.0 */
++ result->dev_support = 0x00; /* No dev support in this mode */
++ memcpy(result->mfg_id, intel_mfg_id, sizeof(result->mfg_id));
++ memcpy(result->aux_fw_rev, aux_fw_rev, sizeof(result->aux_fw_rev));
++
++ /* TODO: Get Firmware version from flash(PFM Header) */
++ result->fw_rev1 = ((operation << 7) | (0x02 & 0x7F));
++ result->fw_rev2 = 0x03;
++ /* TODO: Read Platform ID from GPIO */
++ memcpy(result->product_id, platform_id, sizeof(result->product_id));
++
++ return sizeof(struct get_dev_id);
++}
++
++static u16 get_self_test_result(u8 *req, u16 req_len, u8 *res)
++{
++ /* Get Self Test Results */
++ struct self_test_res *result = (struct self_test_res *)res;
++
++ if (req_len != 0) {
++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH;
++ return sizeof(result->completion_code);
++ }
++
++ result->completion_code = IPMI_CC_OK;
++ result->res_byte[0] = 0x56; /* Self test function not implemented. */
++ result->res_byte[1] = 0x00;
++
++ return sizeof(struct self_test_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 }
++};
++
++#define CMD_TABLE_SIZE ARRAY_SIZE(cmd_info)
++
++void ipmi_cmd_handler(struct ipmi_cmd_data *ipmi_data)
++{
++ int i = 0;
++ for (i = 0; i < CMD_TABLE_SIZE; i++) {
++ if ((cmd_info[i].net_fun == ipmi_data->net_fun) &&
++ (cmd_info[i].cmd == ipmi_data->cmd)) {
++ break;
++ }
++ }
++
++ if (i == CMD_TABLE_SIZE) {
++ /* Invalid or not supported. */
++ ipmi_data->res_data[0] = IPMI_CC_INVALID_CMD;
++ ipmi_data->res_len = 1;
++ return;
++ }
++
++ /* Call the appropriate function handler */
++ ipmi_data->res_len =
++ cmd_info[i].process_cmd(ipmi_data->req_data, ipmi_data->req_len,
++ &ipmi_data->res_data[0]);
++
++ return;
++}
+diff --git a/board/aspeed/ast-g5/ipmi-handler.h b/board/aspeed/ast-g5/ipmi-handler.h
+new file mode 100644
+index 0000000..9d46d9b
+--- /dev/null
++++ b/board/aspeed/ast-g5/ipmi-handler.h
+@@ -0,0 +1,40 @@
++
++/* SPDX-License-Identifier: GPL-2.0 */
++/* Copyright (c) 2018-2019 Intel Corporation */
++
++#include "ast-g5-kcs.h"
++
++/* IPMI completion codes */
++#define IPMI_CC_OK 0x00
++#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_UNSPECIFIED 0xFF
++
++/* BMC IPMB LUNs */
++#define LUN_BMC 0x00
++#define LUN_OEM1 0x01
++#define LUN_SMS 0x02
++#define LUN_OEM2 0x01
++
++
++#define MAX_IPMI_REQ_DATA_SIZE MAX_KCS_PKT_SIZE
++#define MAX_IPMI_RES_DATA_SIZE 64
++
++/* Response netFn[7:2], Lun[1:0] */
++#define GET_RESP_NETFN_LUN(lun, netfn) \
++ ((lun & 0x03) | (((netfn + 1) << 2) & 0xFD))
++
++struct ipmi_cmd_data {
++ u8 net_fun;
++ u8 cmd;
++ u16 req_len;
++ u16 res_len;
++ u8 req_data[MAX_IPMI_REQ_DATA_SIZE];
++ u8 res_data[MAX_IPMI_RES_DATA_SIZE];
++};
++
++void ipmi_cmd_handler(struct ipmi_cmd_data *ipmi_data);
+--
+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 9494c823e..8eb06b622 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
@@ -4,25 +4,30 @@ FILESEXTRAPATHS_append_wolfpass:= "${THISDIR}/files:"
# with the intel layout for environment
SRC_URI_remove_wolfpass = " file://0001-configs-ast-Add-redundnant-env.patch"
-SRC_URI_append_wolfpass = " 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://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 \
- file://0021-Config-host-uart-clock-source-using-environment-vari.patch \
- "
+SRC_URI_append_wolfpass = " \
+ 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://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 \
+ 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 \
+ "
+SRC_URI_append_wolfpass += "${@bb.utils.contains('IMAGE_TYPE', 'pfr', 'file://0022-u-boot-env-change-for-PFR-image.patch', '', d)}"