summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/skylake/Makefile.inc1
-rw-r--r--src/soc/intel/skylake/fsp_reset.c62
-rw-r--r--src/vendorcode/google/chromeos/chromeos.h1
-rw-r--r--src/vendorcode/google/chromeos/vbnv_cmos.c16
-rw-r--r--src/vendorcode/google/chromeos/vboot_common.c15
-rw-r--r--src/vendorcode/google/chromeos/vboot_common.h2
6 files changed, 97 insertions, 0 deletions
diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc
index d6c2212310..9c578c56c1 100644
--- a/src/soc/intel/skylake/Makefile.inc
+++ b/src/soc/intel/skylake/Makefile.inc
@@ -37,6 +37,7 @@ ramstage-y += cpu_info.c
ramstage-y += elog.c
ramstage-y += finalize.c
ramstage-y += flash_controller.c
+ramstage-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += fsp_reset.c
ramstage-y += gpio.c
ramstage-y += igd.c
ramstage-y += lpc.c
diff --git a/src/soc/intel/skylake/fsp_reset.c b/src/soc/intel/skylake/fsp_reset.c
new file mode 100644
index 0000000000..4751872a47
--- /dev/null
+++ b/src/soc/intel/skylake/fsp_reset.c
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <bootstate.h>
+#include <vendorcode/google/chromeos/vboot_handoff.h>
+
+static int is_recovery; /* flag to identify recovery mode */
+
+/*
+ * coreboot used to clear recovery status towards romstage end after FSP
+ * memory init. Later inside FSP silicon init due to HSIO CRC mismatch
+ * or other silicon related programming may request for an additional
+ * reset. Thus on the next boot the system resumed in normal mode rather than
+ * recovery because it lost its original state due to FSP silicon init reset.
+ * Hence it needs an addition reset to get into old state and continue
+ * booting into recovery mode. This function will set recovery reason
+ * during Silicon init, in case of recovery mode booting,
+ * so, system will not lose its original context.
+ */
+static void set_recovery_request(void *unused)
+{
+ is_recovery = recovery_mode_enabled();
+ /*
+ * Set recovery flag during Recovery Mode Silicon Init
+ * & store recovery request into VBNV
+ */
+ if (is_recovery)
+ set_recovery_mode_into_vbnv(vboot_recovery_reason());
+
+}
+
+static void clear_recovery_request(void *unused)
+{
+ /*
+ * Done with Silicon Init, it's safe to clear
+ * reset request now with assumption that no reset occurs hereafter
+ * so we will not miss original data.
+ */
+ if (is_recovery)
+ set_recovery_mode_into_vbnv(0);
+}
+/*
+ * On Recovery Path Set Recovery Request during early RAMSTAGE
+ * before initiated Silicon Init
+ */
+BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, set_recovery_request, NULL);
+/*
+ * On Recovery Path Clear Recovery Request during early RAMSTAGE
+ * end of Silicon Init
+ */
+BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, clear_recovery_request, NULL);
diff --git a/src/vendorcode/google/chromeos/chromeos.h b/src/vendorcode/google/chromeos/chromeos.h
index caf18946bf..9dbb68129d 100644
--- a/src/vendorcode/google/chromeos/chromeos.h
+++ b/src/vendorcode/google/chromeos/chromeos.h
@@ -29,6 +29,7 @@ void save_chromeos_gpios(void);
/* functions implemented in vbnv.c: */
int get_recovery_mode_from_vbnv(void);
+void set_recovery_mode_into_vbnv(int recovery_reason);
int vboot_wants_oprom(void);
void read_vbnv(uint8_t *vbnv_copy);
diff --git a/src/vendorcode/google/chromeos/vbnv_cmos.c b/src/vendorcode/google/chromeos/vbnv_cmos.c
index d7850b6796..27f7f0a211 100644
--- a/src/vendorcode/google/chromeos/vbnv_cmos.c
+++ b/src/vendorcode/google/chromeos/vbnv_cmos.c
@@ -104,6 +104,22 @@ static void vbnv_setup(void)
car_set_var(vbnv_initialized, 1);
}
+void set_recovery_mode_into_vbnv(int recovery_reason)
+{
+ uint8_t vbnv_copy[CONFIG_VBNV_SIZE];
+ uint8_t crc_val;
+
+ read_vbnv(vbnv_copy);
+
+ vbnv_copy[RECOVERY_OFFSET] = recovery_reason;
+
+ crc_val = crc8(vbnv_copy, CRC_OFFSET);
+
+ vbnv_copy[CRC_OFFSET] = crc_val;
+
+ save_vbnv(vbnv_copy);
+}
+
int get_recovery_mode_from_vbnv(void)
{
if (!is_vbnv_initialized())
diff --git a/src/vendorcode/google/chromeos/vboot_common.c b/src/vendorcode/google/chromeos/vboot_common.c
index ac16382186..448aad6db0 100644
--- a/src/vendorcode/google/chromeos/vboot_common.c
+++ b/src/vendorcode/google/chromeos/vboot_common.c
@@ -77,6 +77,21 @@ int vboot_enable_recovery(void)
return vboot_handoff_flag(VB_INIT_OUT_ENABLE_RECOVERY);
}
+int vboot_recovery_reason(void)
+{
+ struct vboot_handoff *vbho;
+ VbSharedDataHeader *sd;
+
+ vbho = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
+
+ if (vbho == NULL)
+ return 0;
+
+ sd = (VbSharedDataHeader *)vbho->shared_data;
+
+ return sd->recovery_reason;
+}
+
void vboot_reboot(void)
{
if (IS_ENABLED(CONFIG_CONSOLE_CBMEM_DUMP_TO_UART))
diff --git a/src/vendorcode/google/chromeos/vboot_common.h b/src/vendorcode/google/chromeos/vboot_common.h
index cc79fa5efd..fbffc29d54 100644
--- a/src/vendorcode/google/chromeos/vboot_common.h
+++ b/src/vendorcode/google/chromeos/vboot_common.h
@@ -42,6 +42,8 @@ int vboot_skip_display_init(void);
int vboot_enable_recovery(void);
int vboot_enable_developer(void);
+int vboot_recovery_reason(void);
+
void vboot_reboot(void);
/* Main logic for verified boot. verstage() is the stage entry point