Naresh Solanki (naresh.solanki(a)intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17246
-gerrit
commit a38eaa1284d240460764f77bc5532ef10612ae4b
Author: Naresh G Solanki <naresh.solanki(a)intel.com>
Date: Sun Nov 6 12:51:14 2016 +0530
vboot: No vboot verification when Chrome EC disabled
When Chrome EC is disabled, vboot hash is not available during S3 resume.
Hence disbale vboot verification when Chrome EC is not available.
Change-Id: I665f5f0e2e53da7b735de30443d323572d8a1a9c
Signed-off-by: Naresh G Solanki <naresh.solanki(a)intel.com>
---
src/vboot/vboot_logic.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/vboot/vboot_logic.c b/src/vboot/vboot_logic.c
index bc6ab48..e565cb6 100644
--- a/src/vboot/vboot_logic.c
+++ b/src/vboot/vboot_logic.c
@@ -119,6 +119,12 @@ static int handle_digest_result(void *slot_hash, size_t slot_hash_sz)
int is_resume;
/*
+ * If Chrome EC is not enabled then return
+ */
+ if (!IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC))
+ return 0;
+
+ /*
* Nothing to do since resuming on the platform doesn't require
* vboot verification again.
*/
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17241
-gerrit
commit a21804dbefbaa1af50ad3ca57867d949e36be958
Author: Furquan Shaikh <furquan(a)chromium.org>
Date: Sat Nov 5 23:52:08 2016 -0700
vboot: Add support for recovery mode with forced memory retraining
1. Add new function vboot_recovery_mode_memory_retrain that indicates if
recovery mode requires memory retraining to be performed.
2. Add helper functions {get,clear}_recovery_mode_retrain_switch to read
memory retrain switch. These are provided as weak functions which should
be implemented by mainboard just like {get,clear}_recovery_mode_switch.
3. Additionally, the switch for recovery mode with forced memory
training should be cleared when recovery mode switch is cleared.
BUG=chrome-os-partner:59352
BRANCH=None
TEST=Verified behavior of recovery mode with forced memory retraining on
reef.
Change-Id: I46c10fbf25bc100d9f562c36da3ac646c9dae7d1
Signed-off-by: Furquan Shaikh <furquan(a)chromium.org>
---
src/include/bootmode.h | 2 ++
src/vboot/bootmode.c | 15 +++++++++++++++
src/vboot/vboot_common.h | 1 +
src/vboot/vboot_handoff.c | 1 +
4 files changed, 19 insertions(+)
diff --git a/src/include/bootmode.h b/src/include/bootmode.h
index 21aa386..012bc39 100644
--- a/src/include/bootmode.h
+++ b/src/include/bootmode.h
@@ -22,7 +22,9 @@ int get_write_protect_state(void);
int get_sw_write_protect_state(void);
int get_developer_mode_switch(void);
int get_recovery_mode_switch(void);
+int get_recovery_mode_retrain_switch(void);
int clear_recovery_mode_switch(void);
+int clear_recovery_mode_retrain_switch(void);
int get_wipeout_mode_switch(void);
int get_lid_switch(void);
diff --git a/src/vboot/bootmode.c b/src/vboot/bootmode.c
index 12a4dc0..34377e1 100644
--- a/src/vboot/bootmode.c
+++ b/src/vboot/bootmode.c
@@ -162,6 +162,21 @@ int vboot_recovery_mode_enabled(void)
return !!vboot_check_recovery_request();
}
+int __attribute__((weak)) get_recovery_mode_retrain_switch(void)
+{
+ return 0;
+}
+
+int __attribute__((weak)) clear_recovery_mode_retrain_switch(void)
+{
+ return 0;
+}
+
+int vboot_recovery_mode_memory_retrain(void)
+{
+ return get_recovery_mode_retrain_switch();
+}
+
int vboot_developer_mode_enabled(void)
{
if (!IS_ENABLED(CONFIG_VBOOT))
diff --git a/src/vboot/vboot_common.h b/src/vboot/vboot_common.h
index 59fd44c..956b54c 100644
--- a/src/vboot/vboot_common.h
+++ b/src/vboot/vboot_common.h
@@ -107,5 +107,6 @@ void verstage_mainboard_init(void);
/* Check boot modes */
int vboot_developer_mode_enabled(void);
int vboot_recovery_mode_enabled(void);
+int vboot_recovery_mode_memory_retrain(void);
#endif /* __VBOOT_VBOOT_COMMON_H__ */
diff --git a/src/vboot/vboot_handoff.c b/src/vboot/vboot_handoff.c
index b0bd04c..a2409cf 100644
--- a/src/vboot/vboot_handoff.c
+++ b/src/vboot/vboot_handoff.c
@@ -163,6 +163,7 @@ void vboot_fill_handoff(void)
* is known to be up.
*/
clear_recovery_mode_switch();
+ clear_recovery_mode_retrain_switch();
}
/*
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17240
-gerrit
commit 9f86592651657ed9e505435a766f2839821fd65d
Author: Furquan Shaikh <furquan(a)chromium.org>
Date: Sun Nov 6 00:12:23 2016 -0700
google/chromeec: Sync ec_commands.h host events with ec codebase
BUG=chrome-os-partner:59352
BRANCH=None
TEST=Compiles successfully
Change-Id: Ibfa5681e16a97e342633104d2aae1fb0402939b8
Signed-off-by: Furquan Shaikh <furquan(a)chromium.org>
---
src/ec/google/chromeec/ec_commands.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/ec/google/chromeec/ec_commands.h b/src/ec/google/chromeec/ec_commands.h
index 4a551c2..ec404f0 100644
--- a/src/ec/google/chromeec/ec_commands.h
+++ b/src/ec/google/chromeec/ec_commands.h
@@ -471,9 +471,21 @@ enum host_event_code {
/* Emulate MKBP event */
EC_HOST_EVENT_MKBP = 27,
+ /* EC desires to change state of host-controlled USB mux */
+ EC_HOST_EVENT_USB_MUX = 28,
+
/* TABLET/LAPTOP mode event*/
EC_HOST_EVENT_MODE_CHANGE = 29,
+ /* Keyboard recovery combo with hardware reinitialization */
+ EC_HOST_EVENT_KEYBOARD_RECOVERY_HW_REINIT = 30,
+
+ /*
+ * Reserve this last bit to indicate that at least one bit in a
+ * secondary host event word is set. See crbug.com/633646.
+ */
+ EC_HOST_EVENT_EXTENDED = 31,
+
/*
* The high bit of the event mask is not used as a host event code. If
* it reads back as set, then the entire event mask should be
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17238
-gerrit
commit d9dc0ec5f16f8fc8bdb40461edc2e5967027ecd9
Author: Furquan Shaikh <furquan(a)chromium.org>
Date: Sat Nov 5 23:37:11 2016 -0700
fmap: Add support for checking existence of region
Implement fmap_region_exists which acts as a wrapper for checking if a
region name exists in FMAP.
BUG=chrome-os-partner:59352
BRANCH=None
TEST=Verified that fmap_exists returns existence of region names present
in FMAP.
Change-Id: I288ea8c7c57d3b0f237cdece42c4f5fe9c2c066a
Signed-off-by: Furquan Shaikh <furquan(a)chromium.org>
---
src/include/fmap.h | 3 +++
src/lib/fmap.c | 6 ++++++
2 files changed, 9 insertions(+)
diff --git a/src/include/fmap.h b/src/include/fmap.h
index 5834831..774fbfe 100644
--- a/src/include/fmap.h
+++ b/src/include/fmap.h
@@ -36,6 +36,9 @@ int fmap_locate_area_as_rdev_rw(const char *name, struct region_device *area);
* < 0 on error. */
int fmap_locate_area(const char *name, struct region *r);
+/* Check if region exists in fmap. Return 1 on success, 0 on error. */
+int fmap_region_exists(const char *name);
+
/* Find fmap area name by offset and size.
* Return 0 on success, < 0 on error. */
int fmap_find_region_name(const struct region * const ar,
diff --git a/src/lib/fmap.c b/src/lib/fmap.c
index 9602134..8cb7267 100644
--- a/src/lib/fmap.c
+++ b/src/lib/fmap.c
@@ -131,6 +131,12 @@ int fmap_locate_area(const char *name, struct region *ar)
return -1;
}
+int fmap_region_exists(const char *name)
+{
+ struct region ar;
+ return !fmap_locate_area(name, &ar);
+}
+
int fmap_find_region_name(const struct region * const ar,
char name[FMAP_STRLEN])
{
Andrey Petrov (andrey.petrov(a)intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17237
-gerrit
commit 14240a4dc605276990f4663f5748c34817f24adc
Author: Andrey Petrov <andrey.petrov(a)intel.com>
Date: Fri Nov 4 16:18:30 2016 -0700
WIP: soc/intel/apollolake: Add save/restore variable MRC cache
Apollolake MRC cache is divided into two regions: constant and variable.
Currently they are clubbed together. Since variable data changes across
cold reboot it triggers invalidation of the whole cache region. This
change declubs the data, adds routines to load/store variable data on
flash.
BUG=chrome-os-partner:57515
TEST=with patch series applied: cold reboot, make sure MRC is not
updated. Do S3 suspend/resume cycle.
Change-Id: I374519777abe9b9a1e6cceae5318decd405bb527
Signed-off-by: Andrey Petrov <andrey.petrov(a)intel.com>
---
src/soc/intel/apollolake/Makefile.inc | 1 +
src/soc/intel/apollolake/mrc.c | 90 +++++++++++++++++++++++++++++++++++
src/soc/intel/apollolake/mrc.h | 37 ++++++++++++++
src/soc/intel/apollolake/romstage.c | 40 +++++++++++++++-
4 files changed, 166 insertions(+), 2 deletions(-)
diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc
index 4f867e1..2c1bc23 100644
--- a/src/soc/intel/apollolake/Makefile.inc
+++ b/src/soc/intel/apollolake/Makefile.inc
@@ -33,6 +33,7 @@ romstage-y += lpc_lib.c
romstage-y += memmap.c
romstage-y += meminit.c
romstage-y += mmap_boot.c
+romstage-$(CONFIG_CACHE_MRC_SETTINGS) += mrc.c
romstage-y += tsc_freq.c
romstage-y += pmutil.c
romstage-y += reset.c
diff --git a/src/soc/intel/apollolake/mrc.c b/src/soc/intel/apollolake/mrc.c
new file mode 100644
index 0000000..11eeb93
--- /dev/null
+++ b/src/soc/intel/apollolake/mrc.c
@@ -0,0 +1,90 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Intel Corp.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <assert.h>
+#include <bootstate.h>
+#include <fmap.h>
+#include <ip_checksum.h>
+#include <string.h>
+
+#include "mrc.h"
+#include "soc/intel/common/nvm.h"
+
+#define MRC_VAR_DATA_SIGNATURE (('M'<<0)|('R'<<8)|('C'<<16)|('V'<<24))
+
+int mrc_save_variable_data(const void *payload, size_t payload_size)
+{
+ struct region_device rdev;
+ void *regbase;
+ struct mrc_saved_variable_data data;
+
+ if (!payload)
+ return -1;
+
+ if (payload_size > ARRAY_SIZE(data.payload))
+ return -1;
+
+ if (fmap_locate_area_as_rdev("RW_VAR_MRC_CACHE", &rdev) < 0)
+ return -1;
+
+ regbase = rdev_mmap_full(&rdev);
+ memset(&data, 0, sizeof(data));
+
+ data.signature = MRC_VAR_DATA_SIGNATURE;
+ data.size = payload_size;
+ data.checksum = compute_ip_checksum((void*)payload, payload_size);
+
+ memcpy(&data.payload, payload, MIN(payload_size,
+ ARRAY_SIZE(data.payload)));
+ rdev_munmap(&rdev, regbase);
+ nvm_erase(regbase, region_device_sz(&rdev));
+
+ return nvm_write(regbase, &data, sizeof(data));
+}
+
+int mrc_restore_variable_data(void *data)
+{
+ struct region_device rdev;
+ struct mrc_saved_variable_data *svd;
+ int ret = -1;
+
+ if (fmap_locate_area_as_rdev("RW_VAR_MRC_CACHE", &rdev) < 0)
+ return ret;
+
+ svd = (struct mrc_saved_variable_data*) rdev_mmap_full(&rdev);
+
+ if (!svd)
+ return ret;
+
+ if (svd->signature != MRC_VAR_DATA_SIGNATURE ||
+ svd->size > region_device_sz(&rdev) ||
+ svd->checksum != compute_ip_checksum(&svd->payload, svd->size)) {
+ printk(BIOS_WARNING, "Variable MRC data unusable\n");
+ } else {
+ memcpy(data, svd->payload,
+ MIN(ARRAY_SIZE(svd->payload), svd->size));
+ ret = 0;
+ }
+
+ rdev_munmap(&rdev, svd);
+ return ret;
+}
+
+int mrc_protect_variable_data(void)
+{
+ /* Not implemented yet */
+ return 0;
+}
diff --git a/src/soc/intel/apollolake/mrc.h b/src/soc/intel/apollolake/mrc.h
new file mode 100644
index 0000000..ddcb745
--- /dev/null
+++ b/src/soc/intel/apollolake/mrc.h
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef _SOC_APOLLOLAKE_MRC_H_
+#define _SOC_APOLLOLAKE_MRC_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MRC_MAX_VARDATA_SIZE 32
+
+struct mrc_saved_variable_data {
+ uint32_t signature;
+ unsigned long checksum;
+ size_t size;
+ uint8_t payload[MRC_MAX_VARDATA_SIZE];
+} __attribute__((packed));
+
+/* store variable data */
+int mrc_save_variable_data(const void *payload, size_t payload_size);
+/* restore MRC into provided storage */
+int mrc_restore_variable_data(void *data);
+int mrc_protect_variable_data(void);
+
+#endif
\ No newline at end of file
diff --git a/src/soc/intel/apollolake/romstage.c b/src/soc/intel/apollolake/romstage.c
index 1f6a38f..cc5d25a 100644
--- a/src/soc/intel/apollolake/romstage.c
+++ b/src/soc/intel/apollolake/romstage.c
@@ -40,8 +40,18 @@
#include <soc/uart.h>
#include <string.h>
#include <timestamp.h>
+#include "mrc.h"
+
+#include <lib.h>
static struct chipset_power_state power_state CAR_GLOBAL;
+static uint8_t mrc_var_buff[MRC_MAX_VARDATA_SIZE] CAR_GLOBAL;
+
+static const uint8_t variable_guid[16] = {
+ 0x7d, 0x14, 0x34, 0xa0, 0x0c, 0x69, 0x54, 0x41,
+ 0x8d, 0xe6, 0xc0, 0x44, 0x64, 0x1d, 0xe9, 0x42,
+};
+
/* High Performance Event Timer Configuration */
#define P2SB_HPTC 0x60
@@ -106,8 +116,9 @@ asmlinkage void car_stage_entry(void)
uintptr_t top_of_ram;
bool s3wake;
struct chipset_power_state *ps = car_get_var_ptr(&power_state);
- void *smm_base;
- size_t smm_size;
+ void *smm_base, *mrc_buff;
+ const void *new_var_data;
+ size_t smm_size, new_sz;
uintptr_t tseg_base;
timestamp_add_now(TS_START_ROMSTAGE);
@@ -119,6 +130,15 @@ asmlinkage void car_stage_entry(void)
s3wake = fill_power_state(ps) == ACPI_S3;
fsp_memory_init(s3wake);
+
+ /* Update saved MRC variable data if it doesn't match current */
+ new_var_data = fsp_find_extension_hob_by_guid(variable_guid, &new_sz);
+ mrc_buff = car_get_var_ptr(mrc_var_buff);
+ if (new_var_data && memcmp(mrc_buff, new_var_data, new_sz)) {
+ printk(BIOS_SPEW, "MRC variable data changed, updating..\n");
+ mrc_save_variable_data(new_var_data, new_sz);
+ }
+
if (postcar_frame_init(&pcf, 1*KiB))
die("Unable to initialize postcar frame.\n");
@@ -170,6 +190,8 @@ static void fill_console_params(FSPM_UPD *mupd)
void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd)
{
+ void *saved_data = car_get_var_ptr(mrc_var_buff);
+
fill_console_params(mupd);
mainboard_memory_init_params(mupd);
@@ -193,6 +215,20 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd)
* skip HECI2 reset.
*/
mupd->FspmConfig.EnableS3Heci2 = 0;
+
+ /*
+ * Apollolake splits MRC cache into two parts: constant and variable.
+ * The constant part is not expected to change often and variable is.
+ * Currently variable part consists of parameters that change on cold
+ * boot, such as scrambler seed, and some memory controller registers.
+ * Scrambler seed is vital for S3 resume case because attempt to use
+ * wrong/missing key renders DRAM contents into junk.
+ */
+
+ if (saved_data && mrc_restore_variable_data(saved_data) >= 0) {
+ mupd->FspmConfig.VariableNvsBufferPtr = saved_data;
+ printk(BIOS_DEBUG,"MRC variable data loaded\n");
+ }
}
__attribute__ ((weak))