summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohnny Lin <johnny_lin@wiwynn.com>2019-10-21 10:04:24 +0800
committerPatrick Georgi <pgeorgi@google.com>2019-10-24 15:47:51 +0000
commit241f0a559347a9ee5325b94c0a021dd404da4030 (patch)
tree0abec5993444b554361b4af671fec98fcabb83e9
parentf4abe51b74a593962c72bbecd3ff1d95a81c82d6 (diff)
downloadcoreboot-241f0a559347a9ee5325b94c0a021dd404da4030.tar.xz
mb/ocp/monolake: Configure IPMI BMC FRB2 watchdog timer via VPD variables
Add VPD variables for enabling/disabling FRB2 watchdog timer and setting the timer countdown value. By default it would start the timer and trigger hard reset when it's expired. The timer is expected to be stopped later by payload or OS. Right now the timer is started after FSP-M. Ideally it should be before FSP-M (to detect memory training error). Tested on OCP Mono Lake. Change-Id: I82b244d08380a0461c92662e025d8b95b3133e23 Signed-off-by: Johnny Lin <johnny_lin@wiwynn.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/36180 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Patrick Rudolph <siro@das-labor.org>
-rw-r--r--src/mainboard/ocp/monolake/Kconfig1
-rw-r--r--src/mainboard/ocp/monolake/ipmi.c2
-rw-r--r--src/mainboard/ocp/monolake/ipmi.h2
-rw-r--r--src/mainboard/ocp/monolake/mainboard.c40
4 files changed, 42 insertions, 3 deletions
diff --git a/src/mainboard/ocp/monolake/Kconfig b/src/mainboard/ocp/monolake/Kconfig
index ad4e9c7208..7d85bbba70 100644
--- a/src/mainboard/ocp/monolake/Kconfig
+++ b/src/mainboard/ocp/monolake/Kconfig
@@ -13,6 +13,7 @@ config BOARD_SPECIFIC_OPTIONS
select MAINBOARD_HAS_LPC_TPM
select MAINBOARD_HAS_TPM1
select IPMI_KCS
+ select VPD
config VBOOT
select VBOOT_VBNV_CMOS
diff --git a/src/mainboard/ocp/monolake/ipmi.c b/src/mainboard/ocp/monolake/ipmi.c
index 37aacc842e..3f178dc2cc 100644
--- a/src/mainboard/ocp/monolake/ipmi.c
+++ b/src/mainboard/ocp/monolake/ipmi.c
@@ -17,8 +17,6 @@
#include <console/console.h>
#include "ipmi.h"
-#define BMC_KCS_BASE 0xca2
-
int is_ipmi_clear_cmos_set(ipmi_oem_rsp_t *rsp)
{
int ret;
diff --git a/src/mainboard/ocp/monolake/ipmi.h b/src/mainboard/ocp/monolake/ipmi.h
index 5863eb5082..04649111c2 100644
--- a/src/mainboard/ocp/monolake/ipmi.h
+++ b/src/mainboard/ocp/monolake/ipmi.h
@@ -23,7 +23,7 @@
#define GET_CMOS_BIT(x) ((x) & (1 << 1))
#define GET_VALID_BIT(x) ((x) & (1 << 7))
#define CLEAR_CMOS_AND_VALID_BIT(x) ((x) &= 0x7d)
-
+#define BMC_KCS_BASE 0xca2
typedef struct {
u8 BootMode; /* Bit 1:CMOS clear, bit 7:valid bit. */
u8 Boot0000;
diff --git a/src/mainboard/ocp/monolake/mainboard.c b/src/mainboard/ocp/monolake/mainboard.c
index 010e064c35..dffd19f0f0 100644
--- a/src/mainboard/ocp/monolake/mainboard.c
+++ b/src/mainboard/ocp/monolake/mainboard.c
@@ -19,7 +19,46 @@
#include <cf9_reset.h>
#include <smbios.h>
#include <string.h>
+#include <drivers/vpd/vpd.h>
+#include <console/console.h>
+#include <drivers/ipmi/ipmi_ops.h>
#include "ipmi.h"
+/* VPD variable for enabling/disabling FRB2 timer. */
+#define FRB2_TIMER "FRB2_TIMER"
+/* VPD variable for setting FRB2 timer countdown value. */
+#define FRB2_COUNTDOWN "FRB2_COUNTDOWN"
+#define VPD_LEN 10
+/* Default countdown is 15 minutes. */
+#define DEFAULT_COUNTDOWN 9000
+
+static void init_frb2_wdt(void)
+{
+
+ char val[VPD_LEN];
+ /* Enable FRB2 timer by default. */
+ u8 enable = 1;
+ uint16_t countdown;
+
+ if (vpd_get_bool(FRB2_TIMER, VPD_RW, &enable)) {
+ if (!enable) {
+ printk(BIOS_DEBUG, "Disable FRB2 timer\n");
+ ipmi_stop_bmc_wdt(BMC_KCS_BASE);
+ }
+ }
+ if (enable) {
+ if (vpd_gets(FRB2_COUNTDOWN, val, VPD_LEN, VPD_RW)) {
+ countdown = (uint16_t)atol(val);
+ printk(BIOS_DEBUG, "FRB2 timer countdown set to: %d\n",
+ countdown);
+ } else {
+ printk(BIOS_DEBUG, "FRB2 timer use default value: %d\n",
+ DEFAULT_COUNTDOWN);
+ countdown = DEFAULT_COUNTDOWN;
+ }
+ ipmi_init_and_start_bmc_wdt(BMC_KCS_BASE, countdown,
+ TIMEOUT_HARD_RESET);
+ }
+}
/*
* mainboard_enable is executed as first thing after enumerate_buses().
@@ -29,6 +68,7 @@ static void mainboard_enable(struct device *dev)
{
ipmi_oem_rsp_t rsp;
+ init_frb2_wdt();
if (is_ipmi_clear_cmos_set(&rsp)) {
/* TODO: Should also try to restore CMOS to cmos.default
* if USE_OPTION_TABLE is set */