Michał Żygowski has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/30752
Change subject: src/drivers/intel/fsp1_0: add option to specify MRC and ucode location
......................................................................
src/drivers/intel/fsp1_0: add option to specify MRC and ucode location
Change aims to give better control over CBFS content on FSP1.0 boards.
Specifying location of MRC cache and microcode will allow to save more
space in CBFS.
Signed-off-by: Michał Żygowski <michal.zygowski(a)3mdeb.com>
Change-Id: I23e4e43bdddd7836ef74a2831e631d77599cdcca
---
M src/drivers/intel/fsp1_0/Kconfig
M src/drivers/intel/fsp1_0/Makefile.inc
2 files changed, 16 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/52/30752/1
diff --git a/src/drivers/intel/fsp1_0/Kconfig b/src/drivers/intel/fsp1_0/Kconfig
index c7f6c18..6044c0e 100644
--- a/src/drivers/intel/fsp1_0/Kconfig
+++ b/src/drivers/intel/fsp1_0/Kconfig
@@ -89,6 +89,19 @@
should be a full sector of the flash ROM chip and nothing else should
be included in CBFS in any sector that the fast boot cache data is in.
+config MRC_CACHE_LOC
+ hex "MRC cache location in CBFS"
+ depends on ENABLE_MRC_CACHE && !MRC_CACHE_FMAP
+ help
+ Define the location of MRC cache data in CBFS.
+
+config CPU_MICROCODE_CBFS_LOC
+ hex "Microcode update base address in CBFS"
+ depends on CPU_MICROCODE_CBFS_GENERATE || CPU_MICROCODE_CBFS_EXTERNAL_HEADER
+ help
+ The location (base address) in CBFS that contains the
+ microcode update binary.
+
config VIRTUAL_ROM_SIZE
hex "Virtual ROM Size"
default ROM_SIZE
diff --git a/src/drivers/intel/fsp1_0/Makefile.inc b/src/drivers/intel/fsp1_0/Makefile.inc
index 67741a9..4936022 100644
--- a/src/drivers/intel/fsp1_0/Makefile.inc
+++ b/src/drivers/intel/fsp1_0/Makefile.inc
@@ -44,6 +44,9 @@
mrc.cache-file := $(obj)/mrc.cache
mrc.cache-align := 0x10000
mrc.cache-type := mrc_cache
+ifneq ($(CONFIG_MRC_CACHE_LOC),)
+mrc.cache-COREBOOT-position := $(CONFIG_MRC_CACHE_LOC)
+endif
endif
endif
--
To view, visit https://review.coreboot.org/c/coreboot/+/30752
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I23e4e43bdddd7836ef74a2831e631d77599cdcca
Gerrit-Change-Number: 30752
Gerrit-PatchSet: 1
Gerrit-Owner: Michał Żygowski <michal.zygowski(a)3mdeb.com>
Gerrit-MessageType: newchange
Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/30792
Change subject: [WIP]drivers/fsp1.0: Use common code for to save fastboot data
......................................................................
[WIP]drivers/fsp1.0: Use common code for to save fastboot data
Change-Id: Ie8c355687d3d691ae4e3ca179b0b063598ff5ac2
Signed-off-by: Arthur Heymans <arthur(a)aheymans.xyz>
---
M src/drivers/intel/fsp1_0/Kconfig
M src/drivers/intel/fsp1_0/Makefile.inc
D src/drivers/intel/fsp1_0/fastboot_cache.c
M src/drivers/intel/fsp1_0/fsp_util.c
M src/drivers/intel/fsp1_0/fsp_util.h
M src/northbridge/intel/fsp_rangeley/fsp/Kconfig
M src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.c
M src/soc/intel/fsp_baytrail/fsp/chipset_fsp_util.c
M src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.c
M src/soc/intel/fsp_broadwell_de/romstage/romstage.c
M src/vendorcode/intel/Makefile.inc
11 files changed, 61 insertions(+), 425 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/92/30792/1
diff --git a/src/drivers/intel/fsp1_0/Kconfig b/src/drivers/intel/fsp1_0/Kconfig
index 4d1c4df..fa1b4c8 100644
--- a/src/drivers/intel/fsp1_0/Kconfig
+++ b/src/drivers/intel/fsp1_0/Kconfig
@@ -61,57 +61,12 @@
config ENABLE_FSP_FAST_BOOT
bool "Enable Fast Boot"
- select ENABLE_MRC_CACHE
default n
help
Enabling this feature will force the MRC data to be cached in NV
storage to be used for speeding up boot time on future reboots
and/or power cycles.
-config ENABLE_MRC_CACHE
- bool
- default y if HAVE_ACPI_RESUME
- default n
- help
- Enabling this feature will cause MRC data to be cached in NV storage.
- This can either be used for fast boot, or just because the FSP wants
- it to be saved.
-
-config MRC_CACHE_FMAP
- bool "Use MRC Cache in FMAP"
- depends on ENABLE_MRC_CACHE
- default n
- help
- Use the region "RW_MRC_CACHE" in FMAP instead of "mrc.cache" in CBFS.
- You must define a region in your FMAP named "RW_MRC_CACHE".
-
-config MRC_CACHE_SIZE
- hex "Fast Boot Data Cache Size"
- default 0x10000
- depends on ENABLE_MRC_CACHE
- depends on !MRC_CACHE_FMAP
- help
- This is the amount of space in NV storage that is reserved for the
- fast boot data cache storage.
-
- WARNING: Because this area will be erased and re-written, the size
- should be a full sector of the flash ROM chip and nothing else should
- be included in CBFS in any sector that the fast boot cache data is in.
-
-config VIRTUAL_ROM_SIZE
- hex "Virtual ROM Size"
- default ROM_SIZE
- depends on ENABLE_MRC_CACHE
- help
- This is used to calculate the offset of the MRC data cache in NV
- Storage for fast boot. If in doubt, leave this set to the default
- which sets the virtual size equal to the ROM size.
-
- Example: Cougar Canyon 2 has two 8 MB SPI ROMs. When the SPI ROMs are
- loaded with a 4 MB coreboot image, the virtual ROM size is 8 MB. When
- the SPI ROMs are loaded with an 8 MB coreboot image, the virtual ROM
- size is 16 MB.
-
config USE_GENERIC_FSP_CAR_INC
bool
default n
diff --git a/src/drivers/intel/fsp1_0/Makefile.inc b/src/drivers/intel/fsp1_0/Makefile.inc
index 67741a9..5580a8b7 100644
--- a/src/drivers/intel/fsp1_0/Makefile.inc
+++ b/src/drivers/intel/fsp1_0/Makefile.inc
@@ -18,9 +18,6 @@
ramstage-y += fsp_util.c hob.c
romstage-y += fsp_util.c hob.c
-ramstage-$(CONFIG_ENABLE_MRC_CACHE) += fastboot_cache.c
-romstage-$(CONFIG_ENABLE_MRC_CACHE) += fastboot_cache.c
-
CPPFLAGS_common += -Isrc/drivers/intel/fsp1_0 -I$(objgenerated)
cpu_incs-$(CONFIG_USE_GENERIC_FSP_CAR_INC) += $(src)/drivers/intel/fsp1_0/cache_as_ram.inc
@@ -33,18 +30,4 @@
fsp.bin-options := --xip
endif
-ifeq ($(CONFIG_ENABLE_MRC_CACHE),y)
-ifneq ($(CONFIG_MRC_CACHE_FMAP),y)
-$(obj)/mrc.cache:
- dd if=/dev/zero count=1 \
- bs=$(shell printf "%d" $(CONFIG_MRC_CACHE_SIZE) ) | \
- tr '\000' '\377' > $@
-
-cbfs-files-y += mrc.cache
-mrc.cache-file := $(obj)/mrc.cache
-mrc.cache-align := 0x10000
-mrc.cache-type := mrc_cache
-endif
-endif
-
endif
diff --git a/src/drivers/intel/fsp1_0/fastboot_cache.c b/src/drivers/intel/fsp1_0/fastboot_cache.c
deleted file mode 100644
index 76241c8..0000000
--- a/src/drivers/intel/fsp1_0/fastboot_cache.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Google Inc.
- * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
- *
- * 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 <stdint.h>
-#include <string.h>
-#include <bootstate.h>
-#include <console/console.h>
-#include <cbfs.h>
-#include <fmap.h>
-#include <ip_checksum.h>
-#include <device/device.h>
-#include <cbmem.h>
-#include <spi-generic.h>
-#include <spi_flash.h>
-#include <lib.h> // hexdump
-#include "fsp_util.h"
-
-/* convert a pointer to flash area into the offset inside the flash */
-static inline u32 to_flash_offset(void *p) {
- return ((u32)p + CONFIG_VIRTUAL_ROM_SIZE);
-}
-
-static struct mrc_data_container *next_mrc_block(
- struct mrc_data_container *mrc_cache)
-{
- /* MRC data blocks are aligned within the region */
- u32 mrc_size = sizeof(*mrc_cache) + mrc_cache->mrc_data_size;
- if (mrc_size & (MRC_DATA_ALIGN - 1UL)) {
- mrc_size &= ~(MRC_DATA_ALIGN - 1UL);
- mrc_size += MRC_DATA_ALIGN;
- }
-
- u8 *region_ptr = (u8*)mrc_cache;
- region_ptr += mrc_size;
- return (struct mrc_data_container *)region_ptr;
-}
-
-static int is_mrc_cache(struct mrc_data_container *mrc_cache)
-{
- return (!!mrc_cache) && (mrc_cache->mrc_signature == MRC_DATA_SIGNATURE);
-}
-
-static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr)
-{
- size_t region_size;
-
- if (IS_ENABLED(CONFIG_MRC_CACHE_FMAP)) {
- struct region_device rdev;
- if (fmap_locate_area_as_rdev("RW_MRC_CACHE", &rdev) == 0) {
- *mrc_region_ptr = rdev_mmap_full(&rdev);
- return region_device_sz(&rdev);
- }
- *mrc_region_ptr = NULL;
- return 0;
- } else {
- *mrc_region_ptr = cbfs_boot_map_with_leak("mrc.cache",
- CBFS_TYPE_MRC_CACHE,
- ®ion_size);
-
- return region_size;
- }
-}
-
-/*
- * Find the largest index block in the MRC cache. Return NULL if none is
- * found.
- */
-static struct mrc_data_container *find_current_mrc_cache_local
- (struct mrc_data_container *mrc_cache, u32 region_size)
-{
- u32 region_end;
- u32 entry_id = 0;
- struct mrc_data_container *mrc_next = mrc_cache;
-
- region_end = (u32) mrc_cache + region_size;
-
- /* Search for the last filled entry in the region */
- while (is_mrc_cache(mrc_next)) {
- entry_id++;
- mrc_cache = mrc_next;
- mrc_next = next_mrc_block(mrc_next);
- if ((u32)mrc_next >= region_end) {
- /* Stay in the MRC data region */
- break;
- }
- }
-
- if (entry_id == 0) {
- printk(BIOS_ERR, "%s: No valid fast boot cache found.\n", __func__);
- return NULL;
- }
-
- /* Verify checksum */
- if (mrc_cache->mrc_checksum !=
- compute_ip_checksum(mrc_cache->mrc_data,
- mrc_cache->mrc_data_size)) {
- printk(BIOS_ERR, "%s: fast boot cache checksum mismatch\n", __func__);
- return NULL;
- }
-
- printk(BIOS_DEBUG, "%s: picked entry %u from cache block\n", __func__,
- entry_id - 1);
-
- return mrc_cache;
-}
-
-/* SPI code needs malloc/free.
- * Also unknown if writing flash from XIP-flash code is a good idea
- */
-#if !defined(__PRE_RAM__)
-/* find the first empty block in the MRC cache area.
- * If there's none, return NULL.
- *
- * @mrc_cache_base - base address of the MRC cache area
- * @mrc_cache - current entry (for which we need to find next)
- * @region_size - total size of the MRC cache area
- */
-static struct mrc_data_container *find_next_mrc_cache
- (struct mrc_data_container *mrc_cache_base,
- struct mrc_data_container *mrc_cache,
- u32 region_size)
-{
- u32 region_end = (u32) mrc_cache_base + region_size;
- u32 mrc_data_size = mrc_cache->mrc_data_size;
-
- mrc_cache = next_mrc_block(mrc_cache);
- if (((u32)mrc_cache + mrc_data_size) >= region_end) {
- /* Crossed the boundary */
- mrc_cache = NULL;
- printk(BIOS_DEBUG, "%s: no available entries found\n",
- __func__);
- } else {
- printk(BIOS_DEBUG,
- "%s: picked next entry from cache block at %p\n",
- __func__, mrc_cache);
- }
-
- return mrc_cache;
-}
-
-void update_mrc_cache(void *unused)
-{
- printk(BIOS_DEBUG, "Updating fast boot cache data.\n");
- struct mrc_data_container *current = cbmem_find(CBMEM_ID_MRCDATA);
- struct mrc_data_container *cache, *cache_base;
- u32 cache_size;
- struct spi_flash flash;
-
- if (!current) {
- printk(BIOS_ERR, "No fast boot cache in cbmem. Can't update flash.\n");
- return;
- }
- if (current->mrc_data_size == -1) {
- printk(BIOS_ERR, "Fast boot cache data in cbmem invalid.\n");
- return;
- }
-
- cache_size = get_mrc_cache_region(&cache_base);
- if (cache_base == NULL) {
- printk(BIOS_ERR, "%s: could not find fast boot cache area\n",
- __func__);
- return;
- }
-
- /*
- * we need to:
- * 0. compare MRC data to last mrc-cache block (exit if same)
- */
- cache = find_current_mrc_cache_local(cache_base, cache_size);
-
- if (cache && (cache->mrc_data_size == current->mrc_data_size) &&
- (memcmp(cache, current, cache->mrc_data_size) == 0)) {
- printk(BIOS_DEBUG,
- "MRC data in flash is up to date. No update.\n");
- return;
- }
-
- /* 1. use spi_flash_probe() to find the flash, then... */
- spi_init();
- if (spi_flash_probe(0, 0, &flash)) {
- printk(BIOS_DEBUG, "Could not find SPI device\n");
- return;
- }
-
- /* 2. look up the first unused block */
- if (cache)
- cache = find_next_mrc_cache(cache_base, cache, cache_size);
-
- /*
- * 3. if no such place exists, erase entire mrc-cache range & use
- * block 0. First time around the erase is not needed, but this is a
- * small overhead for simpler code.
- */
- if (!cache) {
- printk(BIOS_DEBUG,
- "Need to erase the MRC cache region of %d bytes at %p\n",
- cache_size, cache_base);
-
- spi_flash_erase(&flash, to_flash_offset(cache_base),
- cache_size);
-
- /* we will start at the beginning again */
- cache = cache_base;
- }
- /* 4. write mrc data with spi_flash_write() */
- printk(BIOS_DEBUG, "Write MRC cache update to flash at %p\n",
- cache);
- spi_flash_write(&flash, to_flash_offset(cache),
- current->mrc_data_size + sizeof(*current), current);
-}
-
-#endif /* !defined(__PRE_RAM__) */
-
-void *find_and_set_fastboot_cache(void)
-{
- struct mrc_data_container *mrc_cache = NULL;
- if (((mrc_cache = find_current_mrc_cache()) == NULL) ||
- (mrc_cache->mrc_data_size == -1UL)) {
- printk(BIOS_DEBUG, "FSP MRC cache not present.\n");
- return NULL;
- }
- printk(BIOS_DEBUG, "FSP MRC cache present at %x.\n", (u32)mrc_cache);
- printk(BIOS_SPEW, "Saved MRC data:\n");
- hexdump32(BIOS_SPEW, (void *)mrc_cache->mrc_data, (mrc_cache->mrc_data_size) / 4);
- return (void *) mrc_cache->mrc_data;
-}
-
-struct mrc_data_container *find_current_mrc_cache(void)
-{
- struct mrc_data_container *cache_base;
- u32 cache_size;
-
- cache_size = get_mrc_cache_region(&cache_base);
- if (cache_base == NULL) {
- printk(BIOS_ERR, "%s: could not find fast boot cache area\n",
- __func__);
- return NULL;
- }
-
- /*
- * we need to:
- * 0. compare MRC data to last mrc-cache block (exit if same)
- */
- return find_current_mrc_cache_local(cache_base, cache_size);
-}
diff --git a/src/drivers/intel/fsp1_0/fsp_util.c b/src/drivers/intel/fsp1_0/fsp_util.c
index 71f6416..7253a56 100644
--- a/src/drivers/intel/fsp1_0/fsp_util.c
+++ b/src/drivers/intel/fsp1_0/fsp_util.c
@@ -23,6 +23,7 @@
#include <ip_checksum.h>
#include <timestamp.h>
#include <cpu/intel/microcode.h>
+#include <mrc_cache.h>
#ifndef __PRE_RAM__
/* Globals pointers for FSP structures */
@@ -213,6 +214,38 @@
}
#endif /* FSP_RESERVE_MEMORY_SIZE */
+#if defined(__ROMSTAGE__)
+/**
+ * Save the FSP memory HOB (mrc data) to the MRC area in CBMEM
+ */
+enum cb_err save_mrc_data(void *hob_start, uint32_t version)
+{
+ u32 *mrc_hob;
+ u32 *mrc_hob_data;
+ u32 mrc_hob_size;
+ int output_len;
+ const EFI_GUID mrc_guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
+
+ mrc_hob = GetNextGuidHob(&mrc_guid, hob_start);
+ if (mrc_hob == NULL){
+ printk(BIOS_DEBUG, "Memory Configure Data Hob is not present\n");
+ return CB_ERR;
+ }
+
+ mrc_hob_data = GET_GUID_HOB_DATA(mrc_hob);
+ mrc_hob_size = (u32) GET_HOB_LENGTH(mrc_hob);
+
+ printk(BIOS_DEBUG, "Memory Configure Data Hob at %p (size = 0x%x).\n",
+ (void *)mrc_hob_data, mrc_hob_size);
+
+ output_len = ALIGN(mrc_hob_size, 16);
+
+ return mrc_cache_stash_data(MRC_TRAINING_DATA, version, mrc_hob_data,
+ mrc_hob_size);
+}
+#endif
+
+
#ifndef __PRE_RAM__ /* Only parse HOB data in ramstage */
void print_fsp_info(void) {
@@ -237,86 +270,6 @@
(u8)(fsp_header_ptr->ImageRevision & 0xff));
}
-
-#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
-/**
- * Save the FSP memory HOB (mrc data) to the MRC area in CBMEM
- */
-int save_mrc_data(void *hob_start)
-{
- u32 *mrc_hob;
- u32 *mrc_hob_data;
- u32 mrc_hob_size;
- struct mrc_data_container *mrc_data;
- int output_len;
- const EFI_GUID mrc_guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
-
- mrc_hob = GetNextGuidHob(&mrc_guid, hob_start);
- if (mrc_hob == NULL){
- printk(BIOS_DEBUG, "Memory Configure Data Hob is not present\n");
- return(0);
- }
-
- mrc_hob_data = GET_GUID_HOB_DATA (mrc_hob);
- mrc_hob_size = (u32) GET_HOB_LENGTH(mrc_hob);
-
- printk(BIOS_DEBUG, "Memory Configure Data Hob at %p (size = 0x%x).\n",
- (void *)mrc_hob_data, mrc_hob_size);
-
- output_len = ALIGN(mrc_hob_size, 16);
-
- /* Save the MRC S3/fast boot/ADR restore data to cbmem */
- mrc_data = cbmem_add (CBMEM_ID_MRCDATA,
- output_len + sizeof(struct mrc_data_container));
-
- /* Just return if there was a problem with getting CBMEM */
- if (mrc_data == NULL) {
- printk(BIOS_WARNING, "CBMEM was not available to save the fast boot cache data.\n");
- return 0;
- }
-
- printk(BIOS_DEBUG, "Copy FSP MRC DATA to HOB (source addr %p, dest addr %p, %u bytes)\n",
- (void *)mrc_hob_data, mrc_data, output_len);
-
- mrc_data->mrc_signature = MRC_DATA_SIGNATURE;
- mrc_data->mrc_data_size = output_len;
- mrc_data->reserved = 0;
- memcpy(mrc_data->mrc_data, (const void *)mrc_hob_data, mrc_hob_size);
-
- /* Zero the unused space in aligned buffer. */
- if (output_len > mrc_hob_size)
- memset((mrc_data->mrc_data + mrc_hob_size), 0,
- output_len - mrc_hob_size);
-
- mrc_data->mrc_checksum = compute_ip_checksum(mrc_data->mrc_data,
- mrc_data->mrc_data_size);
-
- printk(BIOS_SPEW, "Fast boot data (includes align and checksum):\n");
- hexdump32(BIOS_SPEW, (void *)mrc_data->mrc_data, output_len / 4);
- return (1);
-}
-#endif /* CONFIG_ENABLE_MRC_CACHE */
-
-static void find_fsp_hob_update_mrc(void *unused)
-{
- /* Set the global HOB list pointer */
- FspHobListPtr = (void *)*((u32 *) cbmem_find(CBMEM_ID_HOB_POINTER));
-
- if (!FspHobListPtr){
- printk(BIOS_ERR, "ERROR: Could not find FSP HOB pointer in CBFS!\n");
- } else {
- /* 0x0000: Print all types */
- print_hob_type_structure(0x000, FspHobListPtr);
-
- #if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
- if (save_mrc_data(FspHobListPtr))
- update_mrc_cache(NULL);
- else
- printk(BIOS_DEBUG,"Not updating MRC data in flash.\n");
- #endif
- }
-}
-
/** @brief Notify FSP for PostPciEnumeration
*
* @param unused
@@ -348,7 +301,4 @@
BOOT_STATE_INIT_ENTRY(BS_DEV_ENUMERATE, BS_ON_EXIT, fsp_after_pci_enum, NULL);
BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, fsp_finalize, NULL);
-/* Update the MRC/fast boot cache as part of the late table writing stage */
-BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY,
- find_fsp_hob_update_mrc, NULL);
#endif /* #ifndef __PRE_RAM__ */
diff --git a/src/drivers/intel/fsp1_0/fsp_util.h b/src/drivers/intel/fsp1_0/fsp_util.h
index d5d0160..b960158 100644
--- a/src/drivers/intel/fsp1_0/fsp_util.h
+++ b/src/drivers/intel/fsp1_0/fsp_util.h
@@ -19,10 +19,7 @@
#include <chipset_fsp_util.h>
#include "fsp_values.h"
-#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
-int save_mrc_data(void *hob_start);
-void *find_and_set_fastboot_cache(void);
-#endif
+enum cb_err save_mrc_data(void *hob_start, uint32_t version);
volatile u8 *find_fsp(void);
void fsp_early_init(FSP_INFO_HEADER *fsp_info);
@@ -75,10 +72,6 @@
struct mrc_data_container *find_current_mrc_cache(void);
-#if !defined(__PRE_RAM__)
-void update_mrc_cache(void *unused);
-#endif
-
#endif
/* The offset in bytes from the start of the info structure */
diff --git a/src/northbridge/intel/fsp_rangeley/fsp/Kconfig b/src/northbridge/intel/fsp_rangeley/fsp/Kconfig
index 67ed66b..30fc94f 100644
--- a/src/northbridge/intel/fsp_rangeley/fsp/Kconfig
+++ b/src/northbridge/intel/fsp_rangeley/fsp/Kconfig
@@ -18,7 +18,6 @@
select PLATFORM_USES_FSP1_0
select USE_GENERIC_FSP_CAR_INC
select FSP_USES_UPD
- select ENABLE_MRC_CACHE #rangeley FSP always needs MRC data
config FSP_FILE
string
diff --git a/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.c b/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.c
index 7977575..03c51b3 100644
--- a/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.c
+++ b/src/northbridge/intel/fsp_rangeley/fsp/chipset_fsp_util.c
@@ -23,6 +23,7 @@
#include <device/device.h>
#include <southbridge/intel/fsp_rangeley/pci_devs.h>
#include <drivers/intel/fsp1_0/fsp_util.h>
+#include <include/mrc_cache.h>
#include <fspvpd.h>
#include <fspbootmode.h>
#include "../chip.h"
@@ -160,9 +161,11 @@
pFspInitParams->NvsBufferPtr = NULL;
pFspRtBuffer->Common.BootMode = BOOT_WITH_FULL_CONFIGURATION;
- /* Find the fastboot cache that was saved in the ROM */
- pFspInitParams->NvsBufferPtr = find_and_set_fastboot_cache();
-
+ struct region_device rdev;
+ if (mrc_cache_get_current(MRC_TRAINING_DATA, 1, &rdev)) {
+ /* Find the fastboot cache that was saved in the ROM */
+ pFspInitParams->NvsBufferPtr = rdev_mmap_full(&rdev);
+ }
return;
}
diff --git a/src/soc/intel/fsp_baytrail/fsp/chipset_fsp_util.c b/src/soc/intel/fsp_baytrail/fsp/chipset_fsp_util.c
index 3786c0c..99f9548 100644
--- a/src/soc/intel/fsp_baytrail/fsp/chipset_fsp_util.c
+++ b/src/soc/intel/fsp_baytrail/fsp/chipset_fsp_util.c
@@ -24,6 +24,7 @@
#include <device/pci_def.h>
#include <soc/pci_devs.h>
#include <drivers/intel/fsp1_0/fsp_util.h>
+#include <include/mrc_cache.h>
#include "../chip.h"
#include <arch/io.h>
#include <soc/pmc.h>
@@ -307,10 +308,13 @@
ConfigureDefaultUpdData(fsp_ptr, pFspRtBuffer->Common.UpdDataRgnPtr);
pFspInitParams->NvsBufferPtr = NULL;
-#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
- /* Find the fastboot cache that was saved in the ROM */
- pFspInitParams->NvsBufferPtr = find_and_set_fastboot_cache();
-#endif
+ if (IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT)) {
+ struct region_device rdev;
+ if (mrc_cache_get_current(MRC_TRAINING_DATA, 1, &rdev)) {
+ /* Find the fastboot cache that was saved in the ROM */
+ pFspInitParams->NvsBufferPtr = rdev_mmap_full(&rdev);
+ }
+ }
if (prev_sleep_state == ACPI_S3) {
/* S3 resume */
diff --git a/src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.c b/src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.c
index 800f686..3de1cea 100644
--- a/src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.c
+++ b/src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.c
@@ -24,6 +24,7 @@
#include <device/device.h>
#include <device/pci_def.h>
#include <drivers/intel/fsp1_0/fsp_util.h>
+#include <include/mrc_cache.h>
#include <soc/pci_devs.h>
#include <soc/romstage.h>
#include <chip.h>
@@ -128,11 +129,13 @@
ConfigureDefaultUpdData(pFspRtBuffer->Common.UpdDataRgnPtr);
pFspInitParams->NvsBufferPtr = NULL;
-#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
- /* Find the fastboot cache that was saved in the ROM */
- pFspInitParams->NvsBufferPtr = find_and_set_fastboot_cache();
-#endif
-
+ if (IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT)) {
+ struct region_device rdev;
+ if (mrc_cache_get_current(MRC_TRAINING_DATA, 1, &rdev)) {
+ /* Find the fastboot cache that was saved in the ROM */
+ pFspInitParams->NvsBufferPtr = rdev_mmap_full(&rdev);
+ }
+ }
return;
}
diff --git a/src/soc/intel/fsp_broadwell_de/romstage/romstage.c b/src/soc/intel/fsp_broadwell_de/romstage/romstage.c
index 003ae22..590aec8 100644
--- a/src/soc/intel/fsp_broadwell_de/romstage/romstage.c
+++ b/src/soc/intel/fsp_broadwell_de/romstage/romstage.c
@@ -117,12 +117,15 @@
post_code(0x4d);
cbmem_was_initted = !cbmem_recovery(0);
- /* Save the HOB pointer in CBMEM to be used in ramstage*/
+ /* Save the HOB pointer in CBMEM to be used in ramstage */
cbmem_hob_ptr = cbmem_add(CBMEM_ID_HOB_POINTER, sizeof(*hob_list_ptr));
if (cbmem_hob_ptr == NULL)
die("Could not allocate cbmem for HOB pointer");
*(u32 *)cbmem_hob_ptr = (u32)hob_list_ptr;
+#define MRC_CACHE_VERSION 1 /* TODO fetch FSP version */
+ save_mrc_data(cbmem_hob_ptr, 1);
+
/* Load the ramstage. */
post_code(0x4e);
run_ramstage();
diff --git a/src/vendorcode/intel/Makefile.inc b/src/vendorcode/intel/Makefile.inc
index 33b2f81..9543756 100644
--- a/src/vendorcode/intel/Makefile.inc
+++ b/src/vendorcode/intel/Makefile.inc
@@ -18,6 +18,7 @@
FSP_PATH := $(call strip_quotes,$(CONFIG_FSP_VENDORCODE_HEADER_PATH))
FSP_SRC_FILES := $(wildcard src/vendorcode/intel/$(FSP_PATH)/srx/*.c)
FSP_C_INPUTS := $(foreach file, $(FSP_SRC_FILES), $(FSP_PATH)/srx/$(notdir $(file)))
+romstage-y += $(FSP_C_INPUTS)
ramstage-y += $(FSP_C_INPUTS)
CFLAGS_x86_32 += -Isrc/vendorcode/intel/$(FSP_PATH)/include
--
To view, visit https://review.coreboot.org/c/coreboot/+/30792
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ie8c355687d3d691ae4e3ca179b0b063598ff5ac2
Gerrit-Change-Number: 30792
Gerrit-PatchSet: 1
Gerrit-Owner: Arthur Heymans <arthur(a)aheymans.xyz>
Gerrit-Reviewer: Arthur Heymans <arthur(a)aheymans.xyz>
Gerrit-Reviewer: David Guckian <david.guckian(a)intel.com>
Gerrit-Reviewer: Huang Jin <huang.jin(a)intel.com>
Gerrit-Reviewer: Martin Roth <martinroth(a)google.com>
Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com>
Gerrit-Reviewer: Patrick Rudolph <siro(a)das-labor.org>
Gerrit-Reviewer: Philipp Deppenwiese <zaolin.daisuki(a)gmail.com>
Gerrit-Reviewer: York Yang <york.yang(a)intel.com>
Gerrit-MessageType: newchange
Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/33447
Change subject: Documentation: Explain SimpleELF
......................................................................
Documentation: Explain SimpleELF
Explain coreboot's SELF format.
Change-Id: Ia217af7d39505393ed9324fbe53b4ca7f3069e2e
Signed-off-by: Patrick Rudolph <patrick.rudolph(a)9elements.com>
---
M Documentation/lib/payloads/index.md
A Documentation/lib/payloads/selfboot.md
M Documentation/payloads.md
3 files changed, 44 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/47/33447/1
diff --git a/Documentation/lib/payloads/index.md b/Documentation/lib/payloads/index.md
index 44daef1..b8eca8c 100644
--- a/Documentation/lib/payloads/index.md
+++ b/Documentation/lib/payloads/index.md
@@ -6,6 +6,10 @@
coreboot supports multiple payloads, depending on the architecture of the
selected mainboard.
+## SimpleELF
+
+- [SimpleELF format](selfboot.md)
+
## FIT
- [uImage.FIT support](fit.md)
diff --git a/Documentation/lib/payloads/selfboot.md b/Documentation/lib/payloads/selfboot.md
new file mode 100644
index 0000000..62a4393
--- /dev/null
+++ b/Documentation/lib/payloads/selfboot.md
@@ -0,0 +1,28 @@
+# Simple ELF standard
+
+coreboot is able to use static linked ELF binaries as payload.
+To reduce complexity the ELF binaries are converted to coreboot's SimpleELF
+(SELF) format.
+The payload is therefore split into multiple sections by `cbfstool` at
+build time, each having a unique loading address and possible compression.
+
+## SELF loader
+The SELF loader implementation can be found in `src/lib/selfboot.c`.
+It decompresses the SELF sections and places them in memory.
+
+If the payload overlaps with the loading stage (*RAMSTAGE*) and
+`CONFIG_RELOCATABLE_RAMSTAGE` is selected, the loading stage is moved to another
+location in RAM.
+
+SELF payloads are **never** relocatable and will always be placed at the
+address they specify. If it's not possible to load the payload at the specified
+address, the system won't boot.
+
+### Calling conventions
+The SELF payload is called with a pointer to the coreboot tables as first
+argument.
+
+**Note:** The only exception is made on [RISC-V] which does use the *HARTID*
+and a pointer to the *FDT* as arguments.
+
+[RISC-V]: ../../arch/riscv/index.md
diff --git a/Documentation/payloads.md b/Documentation/payloads.md
index b1eae61..650818e 100644
--- a/Documentation/payloads.md
+++ b/Documentation/payloads.md
@@ -7,6 +7,12 @@
There is various software in that space that is either explicitly written as
payload or can be made to work as one.
+## ELF
+
+Executable and linking format (ELF) compatible static linked binaries can be
+loaded as payload.
+ELF binaries are loaded through the [SELF] boot mechanism.
+
## SeaBIOS
[SeaBIOS](https://www.seabios.org) is an open source implementation of
@@ -14,6 +20,7 @@
since. While originally written for emulators such as QEMU, it can be made
to work as a coreboot payload and all the necessary code is in SeaBIOS'
mainline code.
+SeaBIOS is loaded through the [SELF] boot mechanism.
## Tianocore
@@ -40,3 +47,8 @@
firmware project drivers that often reinvent the wheel) and the ability to
define boot policy with familiar tools, no matter if those are shell scripts
or compiled userland programs written in C, Go or other programming languages.
+
+On x86 platforms Linux is loaded through the [SELF] boot mechanism, by adding a
+*tampoline code* at the start of the kernel.
+
+[SELF]: lib/payloads/selfboot.md
--
To view, visit https://review.coreboot.org/c/coreboot/+/33447
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ia217af7d39505393ed9324fbe53b4ca7f3069e2e
Gerrit-Change-Number: 33447
Gerrit-PatchSet: 1
Gerrit-Owner: Patrick Rudolph <patrick.rudolph(a)9elements.com>
Gerrit-MessageType: newchange
Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/36539 )
Change subject: [WIP]Documentation: Add Intel microcode update mechanism
......................................................................
[WIP]Documentation: Add Intel microcode update mechanism
Document microcode updates and how secure microcode updates are done in
GNU/Linux.
Propose how to do microcode updates in coreboot.
Change-Id: I78350fc81cb0de7b0b2d9cbd8537e6b3815916c0
Signed-off-by: Patrick Rudolph <siro(a)das-labor.org>
---
M Documentation/soc/intel/index.md
A Documentation/soc/intel/microcode/index.md
2 files changed, 111 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/39/36539/1
diff --git a/Documentation/soc/intel/index.md b/Documentation/soc/intel/index.md
index f30ff9a..1cf8548 100644
--- a/Documentation/soc/intel/index.md
+++ b/Documentation/soc/intel/index.md
@@ -2,6 +2,10 @@
This section contains documentation about coreboot on specific Intel SOCs.
+## Common
+
+- [Microcode updates](microcode/index.md)
+
## Platforms
- [Common code development strategy](code_development_model/code_development_model.md)
diff --git a/Documentation/soc/intel/microcode/index.md b/Documentation/soc/intel/microcode/index.md
new file mode 100644
index 0000000..b7f5949
--- /dev/null
+++ b/Documentation/soc/intel/microcode/index.md
@@ -0,0 +1,107 @@
+# Microcode updates on Intel CPUs
+
+## What are microcodes?
+
+```eval_rst
+Microcode is a computer hardware technique that interposes a layer of
+organisation between the CPU hardware and the programmer-visible
+instruction set architecture of the computer. [#1]_
+```
+
+In coreboot the microcode updates are stored in files in the CBFS and
+are used to update the CPU microcode at runtime using a special instruction.
+
+## How does a microcode update look like?
+
+The microcode update is a binary provided by Intel consisting out of
+a header and data.
+The header holds the processor signature for which the update is
+intented and additional metadata.
+For detailed information check the [Intel SDM] 253668-060US Chapter 9.11.1
+
+## When are mirocode updates done?
+
+Microcode updates are stored in the CPU's SRAM and thus needs to be loaded
+after a hard reset. However loading microcode updates is done multiple times
+in coreboot's boot sequence.
+
+On some CPUs it's neccessary to do an microcode update before:
+* Cache-As-RAM is enabled
+* Legacy Intel TXT FIT boot is run
+* MultiProcessor-Init is run
+
+On some CPUs it's neccessary to do an microcode update after:
+* SMM setup was done
+* SGX setup was done
+
+## How to do microcode updates?
+
+The following chapter is based multiple sources and testing due to lack of clear
+documentation.
+
+In order to safely update microcode on any generation the GNU/Linux kernel
+"late loading mechanism" takes a conservative approach and obeys the following
+rules:
+
+```eval_rst
+* All physical CPU cores must be updated with the same microcode version [#2]_
+* Caches need to be flushed on certain CPUs prior to microcode update [#3]_
+* The sibling thread must be idle while a microcode update is ongoing [#4]_
+* All other APs on the same package should be idle (or in Wait-for-SIPI) [#5]_
+* The microcode update is done sequentially [#6]_
+```
+
+The downside of this approach is that it's very slow.
+
+It seems to be possible to run microcode updates in parallel on APs on specific
+CPUs.
+
+## How to do microcode updates in coreboot ramstage?
+
+*TBD*
+
+Proposal:
+1. Run microcode update sequential by default
+2. Flush caches in non CAR environment before running a microcode update
+3. Switch to parallel microcode update after extensive testing (10000 boot cycles)
+
+For parallel microcde update:
+1. On Intel HT enabled CPUs spinlock the slibing thread of a logical core
+2. On Intel HT enabled CPUs only update one thread of a physical core
+3. Synchronize microcode loading. This will make sure no other computational work
+ is being done while an update occurs (thus no Wait-for-SIPI).
+
+## Intel Hyper-Threading enabled CPUs
+
+```eval_rst
+According to Intel SDM a Hyper-Threading enabled core shares the microcode unit
+between the logical CPU cores [#4]_. Intel NetBurst CPUs must not attempt to
+update the microcode on both logical cores at the same time, this is safe for
+newer CPU generations.
+```
+
+## Where to obtain the microcode updates?
+
+The microcode update files can be found on Intel's [Github Microcode].
+
+## References
+- [Wikipedia microcode]
+- [Github Microcode]
+- [Intel SDM]
+
+-------------
+```eval_rst
+.. [#1] Kent, Allen; Williams, James G. (April 5, 1993). `Encyclopedia of Computer Science and Technology: Volume 28 <http://https://books.google.com/books?id=EjWV8J8CQEYC>`_
+.. [#2] `Intel SDM Document 253668-060US`_ Chapter 9.11.6.3 "Update in a System Supporting Intel Hyper-Threading Technology"
+.. [#3] GNU/Linux commit by Ashok Raj `<https://lore.kernel.org/patchwork/patch/890717/>`_
+.. [#4] `Intel SDM Document 253668-060US`_ Chapter 8.8.5 "Microcode Update Resources"
+.. [#5] GNU/Linux commit by Ashok Raj `<https://lore.kernel.org/patchwork/patch/890713/>`_
+.. [#6] `Intel SDM Document 253668-060US`_ Chapter 9.11.6.3 "Update in a System Supporting Intel Hyper-Threading Technology"
+
+.. _Intel SDM Document 253668-060US: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-…
+
+```
+
+[Wikipedia microcode]: https://en.wikipedia.org/wiki/Microcode
+[Github Microcode]: https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files
+[Intel SDM]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-…
--
To view, visit https://review.coreboot.org/c/coreboot/+/36539
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I78350fc81cb0de7b0b2d9cbd8537e6b3815916c0
Gerrit-Change-Number: 36539
Gerrit-PatchSet: 1
Gerrit-Owner: Patrick Rudolph <siro(a)das-labor.org>
Gerrit-MessageType: newchange