summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mainboard/intel/galileo/vboot.c7
-rw-r--r--src/soc/amd/stoneyridge/Makefile.inc4
-rw-r--r--src/soc/amd/stoneyridge/pmutil.c22
-rw-r--r--src/soc/intel/apollolake/pmutil.c6
-rw-r--r--src/soc/intel/baytrail/pmutil.c6
-rw-r--r--src/soc/intel/braswell/pmutil.c6
-rw-r--r--src/soc/intel/broadwell/pmutil.c6
-rw-r--r--src/soc/intel/cannonlake/pmutil.c6
-rw-r--r--src/soc/intel/skylake/pmutil.c6
-rw-r--r--src/southbridge/intel/bd82x6x/early_pch_common.c6
-rw-r--r--src/southbridge/intel/lynxpoint/pmutil.c6
-rw-r--r--src/vboot/vbnv.c2
-rw-r--r--src/vboot/vbnv.h5
-rw-r--r--src/vboot/vbnv_cmos.c59
14 files changed, 133 insertions, 14 deletions
diff --git a/src/mainboard/intel/galileo/vboot.c b/src/mainboard/intel/galileo/vboot.c
index ffea7698b0..b0fa2f2956 100644
--- a/src/mainboard/intel/galileo/vboot.c
+++ b/src/mainboard/intel/galileo/vboot.c
@@ -25,6 +25,7 @@
#include "gen2.h"
#include <spi_flash.h>
#include <vboot/vboot_common.h>
+#include <vboot/vbnv.h>
int clear_recovery_mode_switch(void)
{
@@ -98,3 +99,9 @@ void __attribute__((weak)) vboot_platform_prepare_reboot(void)
/* Reset the TPM */
reg_script_run(script);
}
+
+int vbnv_cmos_failed(void)
+{
+ /* Indicate no failure until RTC failure bits are supported. */
+ return 0;
+}
diff --git a/src/soc/amd/stoneyridge/Makefile.inc b/src/soc/amd/stoneyridge/Makefile.inc
index b6669f1cef..06d9f5820d 100644
--- a/src/soc/amd/stoneyridge/Makefile.inc
+++ b/src/soc/amd/stoneyridge/Makefile.inc
@@ -41,6 +41,7 @@ bootblock-$(CONFIG_STONEYRIDGE_UART) += uart.c
bootblock-y += fixme.c
bootblock-y += bootblock/bootblock.c
bootblock-y += early_setup.c
+bootblock-y += pmutil.c
bootblock-y += tsc_freq.c
romstage-y += romstage.c
@@ -50,12 +51,14 @@ romstage-$(CONFIG_USBDEBUG_IN_ROMSTAGE) += enable_usbdebug.c
romstage-y += fixme.c
romstage-y += gpio.c
romstage-$(CONFIG_STONEYRIDGE_IMC_FWM) += imc.c
+romstage-y += pmutil.c
romstage-y += smbus.c
romstage-y += smbus_spd.c
romstage-y += ramtop.c
romstage-$(CONFIG_STONEYRIDGE_UART) += uart.c
romstage-y += tsc_freq.c
+verstage-y += pmutil.c
verstage-y += reset.c
verstage-$(CONFIG_STONEYRIDGE_UART) += uart.c
verstage-y += tsc_freq.c
@@ -71,6 +74,7 @@ ramstage-$(CONFIG_STONEYRIDGE_IMC_FWM) += imc.c
ramstage-y += lpc.c
ramstage-y += model_15_init.c
ramstage-y += northbridge.c
+ramstage-y += pmutil.c
ramstage-y += reset.c
ramstage-y += sata.c
ramstage-y += sm.c
diff --git a/src/soc/amd/stoneyridge/pmutil.c b/src/soc/amd/stoneyridge/pmutil.c
new file mode 100644
index 0000000000..5bbea2ac6b
--- /dev/null
+++ b/src/soc/amd/stoneyridge/pmutil.c
@@ -0,0 +1,22 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2017 Google Inc.
+ *
+ * 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 <vboot/vbnv.h>
+
+int vbnv_cmos_failed(void)
+{
+ /* FIXME: RTC failure checking not supported. */
+ return 0;
+}
diff --git a/src/soc/intel/apollolake/pmutil.c b/src/soc/intel/apollolake/pmutil.c
index abf47b7782..666ef83763 100644
--- a/src/soc/intel/apollolake/pmutil.c
+++ b/src/soc/intel/apollolake/pmutil.c
@@ -34,6 +34,7 @@
#include <soc/pci_devs.h>
#include <soc/pm.h>
#include <timer.h>
+#include <vboot/vbnv.h>
#include "chip.h"
static uintptr_t read_pmc_mmio_bar(void)
@@ -217,3 +218,8 @@ int soc_get_rtc_failed(void)
return rtc_failed(ps->gen_pmcon1);
}
+
+int vbnv_cmos_failed(void)
+{
+ return rtc_failed(read32((void *)(read_pmc_mmio_bar() + GEN_PMCON1)));
+}
diff --git a/src/soc/intel/baytrail/pmutil.c b/src/soc/intel/baytrail/pmutil.c
index ab2a4ba6d4..fbdea8f4da 100644
--- a/src/soc/intel/baytrail/pmutil.c
+++ b/src/soc/intel/baytrail/pmutil.c
@@ -22,6 +22,7 @@
#include <soc/lpc.h>
#include <soc/pci_devs.h>
#include <soc/pmc.h>
+#include <vboot/vbnv.h>
#if defined(__SIMPLE_DEVICE__)
@@ -378,3 +379,8 @@ int rtc_failure(void)
return rtc_fail;
}
+
+int vbnv_cmos_failed(void)
+{
+ return rtc_failure();
+}
diff --git a/src/soc/intel/braswell/pmutil.c b/src/soc/intel/braswell/pmutil.c
index 4154522d4e..b5f284ff95 100644
--- a/src/soc/intel/braswell/pmutil.c
+++ b/src/soc/intel/braswell/pmutil.c
@@ -23,6 +23,7 @@
#include <soc/pci_devs.h>
#include <soc/pm.h>
#include <stdint.h>
+#include <vboot/vbnv.h>
#if defined(__SIMPLE_DEVICE__)
@@ -374,3 +375,8 @@ int rtc_failure(void)
return rtc_fail;
}
+
+int vbnv_cmos_failed(void)
+{
+ return rtc_failure();
+}
diff --git a/src/soc/intel/broadwell/pmutil.c b/src/soc/intel/broadwell/pmutil.c
index 7cf184ee05..0edcd8c3a9 100644
--- a/src/soc/intel/broadwell/pmutil.c
+++ b/src/soc/intel/broadwell/pmutil.c
@@ -28,6 +28,7 @@
#include <soc/pci_devs.h>
#include <soc/pm.h>
#include <soc/gpio.h>
+#include <vboot/vbnv.h>
/* Print status bits with descriptive names */
static void print_status_bits(u32 status, const char *bit_names[])
@@ -463,3 +464,8 @@ int rtc_failure(void)
return !!rtc_failed;
}
+
+int vbnv_cmos_failed(void)
+{
+ return rtc_failure();
+}
diff --git a/src/soc/intel/cannonlake/pmutil.c b/src/soc/intel/cannonlake/pmutil.c
index ebd3d61cc8..cee3f95a10 100644
--- a/src/soc/intel/cannonlake/pmutil.c
+++ b/src/soc/intel/cannonlake/pmutil.c
@@ -40,6 +40,7 @@
#include <soc/pm.h>
#include <soc/smbus.h>
#include <timer.h>
+#include <vboot/vbnv.h>
#include "chip.h"
/*
@@ -207,3 +208,8 @@ int soc_get_rtc_failed(void)
return rtc_failed(ps->gen_pmcon_b);
}
+
+int vbnv_cmos_failed(void)
+{
+ return rtc_failed(read32(pmc_mmio_regs() + GEN_PMCON_B));
+}
diff --git a/src/soc/intel/skylake/pmutil.c b/src/soc/intel/skylake/pmutil.c
index 6ab949ba57..2a677fda74 100644
--- a/src/soc/intel/skylake/pmutil.c
+++ b/src/soc/intel/skylake/pmutil.c
@@ -38,6 +38,7 @@
#include <soc/pmc.h>
#include <soc/smbus.h>
#include <timer.h>
+#include <vboot/vbnv.h>
#include "chip.h"
/* Print status bits with descriptive names */
@@ -558,3 +559,8 @@ int rtc_failure(void)
return !!rtc_failed;
}
+
+int vbnv_cmos_failed(void)
+{
+ return rtc_failure();
+}
diff --git a/src/southbridge/intel/bd82x6x/early_pch_common.c b/src/southbridge/intel/bd82x6x/early_pch_common.c
index 0ea3dff001..f812247575 100644
--- a/src/southbridge/intel/bd82x6x/early_pch_common.c
+++ b/src/southbridge/intel/bd82x6x/early_pch_common.c
@@ -22,6 +22,7 @@
#include <arch/acpi.h>
#include <console/console.h>
#include <rules.h>
+#include <vboot/vbnv.h>
#if ENV_ROMSTAGE
uint64_t get_initial_timestamp(void)
@@ -70,3 +71,8 @@ int rtc_failure(void)
#endif
return !!(pci_read_config8(dev, GEN_PMCON_3) & RTC_BATTERY_DEAD);
}
+
+int vbnv_cmos_failed(void)
+{
+ return rtc_failure();
+}
diff --git a/src/southbridge/intel/lynxpoint/pmutil.c b/src/southbridge/intel/lynxpoint/pmutil.c
index 642d5befd0..55fe403495 100644
--- a/src/southbridge/intel/lynxpoint/pmutil.c
+++ b/src/southbridge/intel/lynxpoint/pmutil.c
@@ -24,6 +24,7 @@
#include <device/pci.h>
#include <device/pci_def.h>
#include <console/console.h>
+#include <vboot/vbnv.h>
#include "pch.h"
#if IS_ENABLED(CONFIG_INTEL_LYNXPOINT_LP)
@@ -563,3 +564,8 @@ int rtc_failure(void)
#endif
return !!(pci_read_config8(dev, GEN_PMCON_3) & RTC_BATTERY_DEAD);
}
+
+int vbnv_cmos_failed(void)
+{
+ return rtc_failure();
+}
diff --git a/src/vboot/vbnv.c b/src/vboot/vbnv.c
index 3eaa0ad4b2..79bdc8e5df 100644
--- a/src/vboot/vbnv.c
+++ b/src/vboot/vbnv.c
@@ -149,5 +149,7 @@ int vboot_wants_oprom(void)
void vbnv_init(uint8_t *vbnv_copy)
{
+ if (IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS))
+ vbnv_init_cmos(vbnv_copy);
read_vbnv(vbnv_copy);
}
diff --git a/src/vboot/vbnv.h b/src/vboot/vbnv.h
index 540f25c2ca..0288d0df4d 100644
--- a/src/vboot/vbnv.h
+++ b/src/vboot/vbnv.h
@@ -32,6 +32,11 @@ void vbnv_init(uint8_t *vbnv_copy);
void vbnv_reset(uint8_t *vbnv_copy);
/* CMOS backend */
+/* Initialize the vbnv cmos backing store. The vbnv_copy pointer is used for
+ optional temporary storage in the init function. */
+void vbnv_init_cmos(uint8_t *vbnv_copy);
+/* Return non-zero if cmos power was lost. */
+int vbnv_cmos_failed(void);
void read_vbnv_cmos(uint8_t *vbnv_copy);
void save_vbnv_cmos(const uint8_t *vbnv_copy);
diff --git a/src/vboot/vbnv_cmos.c b/src/vboot/vbnv_cmos.c
index 8bdcb31f9c..a311fddbb1 100644
--- a/src/vboot/vbnv_cmos.c
+++ b/src/vboot/vbnv_cmos.c
@@ -36,6 +36,27 @@ static void clear_vbnv_battery_cutoff_flag(uint8_t *vbnv_copy)
}
}
+/* Return non-zero if backup was used. */
+static int restore_from_backup(uint8_t *vbnv_copy)
+{
+ if (!IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS_BACKUP_TO_FLASH))
+ return 0;
+
+ printk(BIOS_INFO, "VBNV: CMOS invalid, restoring from flash\n");
+ read_vbnv_flash(vbnv_copy);
+
+ if (verify_vbnv(vbnv_copy)) {
+ clear_vbnv_battery_cutoff_flag(vbnv_copy);
+ save_vbnv_cmos(vbnv_copy);
+ printk(BIOS_INFO, "VBNV: Flash backup restored\n");
+ return 1;
+ }
+
+ printk(BIOS_INFO, "VBNV: Restore from flash failed\n");
+
+ return 0;
+}
+
void read_vbnv_cmos(uint8_t *vbnv_copy)
{
int i;
@@ -43,21 +64,11 @@ void read_vbnv_cmos(uint8_t *vbnv_copy)
for (i = 0; i < VBOOT_VBNV_BLOCK_SIZE; i++)
vbnv_copy[i] = cmos_read(CONFIG_VBOOT_VBNV_OFFSET + 14 + i);
- if (IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS_BACKUP_TO_FLASH)) {
- if (verify_vbnv(vbnv_copy))
- return;
+ /* Verify contents before attempting a restore from backup storage. */
+ if (verify_vbnv(vbnv_copy))
+ return;
- printk(BIOS_INFO, "VBNV: CMOS invalid, restoring from flash\n");
- read_vbnv_flash(vbnv_copy);
-
- if (verify_vbnv(vbnv_copy)) {
- clear_vbnv_battery_cutoff_flag(vbnv_copy);
- save_vbnv_cmos(vbnv_copy);
- printk(BIOS_INFO, "VBNV: Flash backup restored\n");
- } else {
- printk(BIOS_INFO, "VBNV: Restore from flash failed\n");
- }
- }
+ restore_from_backup(vbnv_copy);
}
void save_vbnv_cmos(const uint8_t *vbnv_copy)
@@ -68,6 +79,26 @@ void save_vbnv_cmos(const uint8_t *vbnv_copy)
cmos_write(vbnv_copy[i], CONFIG_VBOOT_VBNV_OFFSET + 14 + i);
}
+void vbnv_init_cmos(uint8_t *vbnv_copy)
+{
+ /* If no cmos failure just defer to the normal read path for checking
+ vbnv contents' integrity. */
+ if (!vbnv_cmos_failed())
+ return;
+
+ /* In the case of cmos failure force the backup. If backup wasn't used
+ force the vbnv cmos to be reset. */
+ if (!restore_from_backup(vbnv_copy)) {
+ vbnv_reset(vbnv_copy);
+ /* This parallels the vboot_reference implementation. */
+ vbnv_copy[HEADER_OFFSET] = HEADER_SIGNATURE |
+ HEADER_FIRMWARE_SETTINGS_RESET |
+ HEADER_KERNEL_SETTINGS_RESET;
+ regen_vbnv_crc(vbnv_copy);
+ save_vbnv_cmos(vbnv_copy);
+ }
+}
+
#if IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS_BACKUP_TO_FLASH)
static void back_up_vbnv_cmos(void *unused)
{