diff options
-rw-r--r-- | src/mainboard/intel/galileo/vboot.c | 7 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/Makefile.inc | 4 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/pmutil.c | 22 | ||||
-rw-r--r-- | src/soc/intel/apollolake/pmutil.c | 6 | ||||
-rw-r--r-- | src/soc/intel/baytrail/pmutil.c | 6 | ||||
-rw-r--r-- | src/soc/intel/braswell/pmutil.c | 6 | ||||
-rw-r--r-- | src/soc/intel/broadwell/pmutil.c | 6 | ||||
-rw-r--r-- | src/soc/intel/cannonlake/pmutil.c | 6 | ||||
-rw-r--r-- | src/soc/intel/skylake/pmutil.c | 6 | ||||
-rw-r--r-- | src/southbridge/intel/bd82x6x/early_pch_common.c | 6 | ||||
-rw-r--r-- | src/southbridge/intel/lynxpoint/pmutil.c | 6 | ||||
-rw-r--r-- | src/vboot/vbnv.c | 2 | ||||
-rw-r--r-- | src/vboot/vbnv.h | 5 | ||||
-rw-r--r-- | src/vboot/vbnv_cmos.c | 59 |
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) { |