summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathon Hall <jonathon.hall@puri.sm>2023-09-27 12:50:59 -0400
committerMatt DeVillier <matt.devillier@gmail.com>2023-10-20 14:19:52 +0000
commiteb834d9d13d749fe8a4883e84a7d714eedef08db (patch)
tree92e74a51dd81a95d27f2db0a9e82696001669955
parent4ed3ea668c3933deb01c02d33613c764e257671a (diff)
drivers/intel/fsp2_0: Support embedding a second FSP-M/FSP-S
Support embedding a second FSP-M/FSP-S binary for an SoC that can select one at runtime. Comet Lake v1 and v2 are different steppings of the same SKUs, but they require different FSP binaries. Supporting both in a single build requires embedding both FSPs and selecting one at runtime based on the CPUID. This is desirable for a product that may have different CPU steppings but is not otherwise differentiated enough for a separate firmware build. An SoC can select PLATFORM_USES_SECOND_FSP to indicate that two FSP-M/ FSP-S binaries are required. Implement soc_select_fsp_m_cbfs() and soc_select_fsp_s_cbfs() to choose one based on platform-specific criteria. For Comet Lake, the first FSP is CML v1 and the second is CML v2, but in principle a platform could define any meaning for the first and second FSP. FSP-T is not affected, only one FSP-T can be embedded if FSP_CAR is used. Only one set of FSP headers is used, which is sufficient for Comet Lake v1/v2; their headers are equivalent. ADD_FSP_BINARIES, FSP_USE_REPO, and FSP_FULL_FD are supported for both sets of FSP-S/FSP-M but cannot be configured separately, both use the same configuration. Change-Id: Ied4c6c49a6bdf278238272edd47a2006258be8e5 Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm> Reviewed-on: https://review.coreboot.org/c/coreboot/+/78344 Reviewed-by: Michał Kopeć <michal.kopec@3mdeb.com> Reviewed-by: Matt DeVillier <matt.devillier@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin L Roth <gaumless@gmail.com>
-rw-r--r--src/drivers/intel/fsp2_0/Kconfig44
-rw-r--r--src/drivers/intel/fsp2_0/Makefile.inc35
-rw-r--r--src/drivers/intel/fsp2_0/include/fsp/util.h15
-rw-r--r--src/drivers/intel/fsp2_0/memory_init.c11
-rw-r--r--src/drivers/intel/fsp2_0/silicon_init.c8
5 files changed, 106 insertions, 7 deletions
diff --git a/src/drivers/intel/fsp2_0/Kconfig b/src/drivers/intel/fsp2_0/Kconfig
index ca17bc7c60..e27249ff3c 100644
--- a/src/drivers/intel/fsp2_0/Kconfig
+++ b/src/drivers/intel/fsp2_0/Kconfig
@@ -79,6 +79,16 @@ config ADD_FSP_BINARIES
help
Add the FSP-M and FSP-S binaries to CBFS.
+config PLATFORM_USES_SECOND_FSP
+ bool
+ default n
+ help
+ The platform uses two sets of FSP-M/FSP-S binaries and selects the
+ appropriate one at runtime. At least one platform requires different
+ binaries depending on CPU stepping, so supporting any stepping
+ requires embedding two FSPs. The platform indicates which is the
+ "first" and "second" FSP.
+
config FSP_T_CBFS
string "Name of FSP-T in CBFS"
depends on FSP_CAR
@@ -133,6 +143,40 @@ config FSP_S_FILE
help
The path and filename of the Intel FSP-S binary for this platform.
+if PLATFORM_USES_SECOND_FSP
+
+config FSP_S_CBFS_2
+ string "Name of the second FSP-S in CBFS"
+ default "fsps_2.bin"
+
+config FSP_M_CBFS_2
+ string "Name of the second FSP-M in CBFS"
+ default "fspm_2.bin"
+
+config FSP_FD_PATH_2
+ string "Location of the second FSP FD file" if FSP_FULL_FD && !FSP_USE_REPO
+ help
+ Path to the FSP FD file that contains the individual FSP-M and FSP-S
+ binaries. The file gets split at build-time.
+
+config FSP_M_FILE_2
+ string "Intel FSP-M (memory init) second binary path and filename" if !FSP_FULL_FD
+ depends on ADD_FSP_BINARIES
+ default "\$(obj)/Fsp_2_M.fd" if FSP_FULL_FD
+ help
+ The path and filename of the second Intel FSP-M binary for this
+ platform.
+
+config FSP_S_FILE_2
+ string "Intel FSP-S (silicon init) second binary path and filename" if !FSP_FULL_FD
+ depends on ADD_FSP_BINARIES
+ default "\$(obj)/Fsp_2_S.fd" if FSP_FULL_FD
+ help
+ The path and filename of the second Intel FSP-S binary for this
+ platform.
+
+endif
+
config FSP_CAR
bool
default n
diff --git a/src/drivers/intel/fsp2_0/Makefile.inc b/src/drivers/intel/fsp2_0/Makefile.inc
index 16742fd1a4..4af4158903 100644
--- a/src/drivers/intel/fsp2_0/Makefile.inc
+++ b/src/drivers/intel/fsp2_0/Makefile.inc
@@ -47,7 +47,9 @@ CPPFLAGS_common += -I$(src)/drivers/intel/fsp2_0/include
FSP_T_CBFS = $(call strip_quotes,$(CONFIG_FSP_T_CBFS))
FSP_M_CBFS = $(call strip_quotes,$(CONFIG_FSP_M_CBFS))
+FSP_M_CBFS_2 = $(call strip_quotes,$(CONFIG_FSP_M_CBFS_2))
FSP_S_CBFS = $(call strip_quotes,$(CONFIG_FSP_S_CBFS))
+FSP_S_CBFS_2 = $(call strip_quotes,$(CONFIG_FSP_S_CBFS_2))
# Add FSP blobs into cbfs. SoC code may supply additional options with
# -options, e.g --xip or -b
@@ -62,30 +64,47 @@ endif # CONFIG_FSP_T_XIP
endif # CONFIG_ADD_FSP_BINARIES && CONFIG_FSP_CAR
cbfs-files-$(CONFIG_ADD_FSP_BINARIES) += $(FSP_M_CBFS)
+ifeq ($(CONFIG_PLATFORM_USES_SECOND_FSP)$(CONFIG_ADD_FSP_BINARIES),yy)
+cbfs-files-y += $(FSP_M_CBFS_2)
+endif
$(FSP_M_CBFS)-file := $(call strip_quotes,$(CONFIG_FSP_M_FILE))
+$(FSP_M_CBFS_2)-file := $(call strip_quotes,$(CONFIG_FSP_M_FILE_2))
$(FSP_M_CBFS)-type := fsp
+$(FSP_M_CBFS_2)-type := fsp
ifeq ($(CONFIG_FSP_M_XIP),y)
$(FSP_M_CBFS)-options := --xip $(TXTIBB)
+$(FSP_M_CBFS_2)-options := --xip $(TXTIBB)
endif
ifeq ($(CONFIG_FSP_COMPRESS_FSP_M_LZMA),y)
$(FSP_M_CBFS)-compression := LZMA
+$(FSP_M_CBFS_2)-compression := LZMA
else ifeq ($(CONFIG_FSP_COMPRESS_FSP_M_LZ4),y)
$(FSP_M_CBFS)-compression := LZ4
+$(FSP_M_CBFS_2)-compression := LZ4
endif
ifneq ($(CONFIG_FSP_ALIGNMENT_FSP_M),)
$(FSP_M_CBFS)-align := $(CONFIG_FSP_ALIGNMENT_FSP_M)
+$(FSP_M_CBFS_2)-align := $(CONFIG_FSP_ALIGNMENT_FSP_M)
endif
cbfs-files-$(CONFIG_ADD_FSP_BINARIES) += $(FSP_S_CBFS)
+ifeq ($(CONFIG_PLATFORM_USES_SECOND_FSP)$(CONFIG_ADD_FSP_BINARIES),yy)
+cbfs-files-y += $(FSP_S_CBFS_2)
+endif
$(FSP_S_CBFS)-file := $(call strip_quotes,$(CONFIG_FSP_S_FILE))
+$(FSP_S_CBFS_2)-file := $(call strip_quotes,$(CONFIG_FSP_S_FILE_2))
$(FSP_S_CBFS)-type := fsp
+$(FSP_S_CBFS_2)-type := fsp
ifeq ($(CONFIG_FSP_COMPRESS_FSP_S_LZMA),y)
$(FSP_S_CBFS)-compression := LZMA
+$(FSP_S_CBFS_2)-compression := LZMA
else ifeq ($(CONFIG_FSP_COMPRESS_FSP_S_LZ4),y)
$(FSP_S_CBFS)-compression := LZ4
+$(FSP_S_CBFS_2)-compression := LZ4
endif
ifneq ($(CONFIG_FSP_ALIGNMENT_FSP_S),)
$(FSP_S_CBFS)-align := $(CONFIG_FSP_ALIGNMENT_FSP_S)
+$(FSP_S_CBFS_2)-align := $(CONFIG_FSP_ALIGNMENT_FSP_S)
endif
ifeq ($(CONFIG_FSP_FULL_FD),y)
@@ -99,6 +118,14 @@ $(obj)/Fsp_T.fd: $(call strip_quotes,$(CONFIG_FSP_FD_PATH)) $(obj)/Fsp_M.fd
true
endif
+ifeq ($(CONFIG_PLATFORM_USES_SECOND_FSP)$(CONFIG_FSP_FULL_FD),yy)
+$(obj)/Fsp_2_M.fd: $(call strip_quotes,$(CONFIG_FSP_FD_PATH_2)) $(DOTCONFIG)
+ python 3rdparty/fsp/Tools/SplitFspBin.py split -f $(CONFIG_FSP_FD_PATH_2) -o "$(obj)" -n "Fsp_2.fd"
+
+$(obj)/Fsp_2_S.fd: $(call strip_quotes,$(CONFIG_FSP_FD_PATH_2)) $(obj)/Fsp_M.fd
+ true
+endif
+
# Add logo to the cbfs image
cbfs-files-$(CONFIG_BMP_LOGO) += logo.bmp
logo.bmp-file := $(call strip_quotes,$(CONFIG_FSP2_0_LOGO_FILE_NAME))
@@ -126,6 +153,14 @@ endif # CONFIG_FSP_M_FILE
ifeq ($(call strip_quotes,$(CONFIG_FSP_S_FILE)),)
$(error No FSP-S binary file specified.)
endif # CONFIG_FSP_S_FILE
+ifeq ($(CONFIG_PLATFORM_USES_SECOND_FSP),y)
+ifeq ($(call strip_quotes,$(CONFIG_FSP_M_FILE_2)),)
+$(error No second FSP-M binary file specified.)
+endif # CONFIG_FSP_M_FILE_2
+ifeq ($(call strip_quotes,$(CONFIG_FSP_S_FILE_2)),)
+$(error No second FSP-S binary file specified.)
+endif # CONFIG_FSP_S_FILE_2
+endif # CONFIG_PLATFORM_USES_SECOND_FSP
else # CONFIG_ADD_FSP_BINARIES
build_complete:: warn_no_fsp_binaries
endif # CONFIG_ADD_FSP_BINARIES
diff --git a/src/drivers/intel/fsp2_0/include/fsp/util.h b/src/drivers/intel/fsp2_0/include/fsp/util.h
index 75b9ad844e..acf337f661 100644
--- a/src/drivers/intel/fsp2_0/include/fsp/util.h
+++ b/src/drivers/intel/fsp2_0/include/fsp/util.h
@@ -179,6 +179,21 @@ void fsp_handle_reset(uint32_t status);
/* SoC/chipset must provide this to handle platform-specific reset codes */
void chipset_handle_reset(uint32_t status);
+#if CONFIG(PLATFORM_USES_SECOND_FSP)
+/* The SoC must implement these to choose the appropriate FSP-M/FSP-S binary. */
+const char *soc_select_fsp_m_cbfs(void);
+const char *soc_select_fsp_s_cbfs(void);
+#else
+static inline const char *soc_select_fsp_m_cbfs(void)
+{
+ return CONFIG_FSP_M_CBFS;
+}
+static inline const char *soc_select_fsp_s_cbfs(void)
+{
+ return CONFIG_FSP_S_CBFS;
+}
+#endif
+
typedef asmlinkage uint32_t (*temp_ram_exit_fn)(void *param);
typedef asmlinkage uint32_t (*fsp_memory_init_fn)
(void *raminit_upd, void **hob_list);
diff --git a/src/drivers/intel/fsp2_0/memory_init.c b/src/drivers/intel/fsp2_0/memory_init.c
index c5920867f3..d0ddeafeee 100644
--- a/src/drivers/intel/fsp2_0/memory_init.c
+++ b/src/drivers/intel/fsp2_0/memory_init.c
@@ -238,7 +238,8 @@ static uint32_t fsp_mrc_version(void)
uint32_t ver = 0;
#if CONFIG(MRC_CACHE_USING_MRC_VERSION)
size_t fspm_blob_size;
- void *fspm_blob_file = cbfs_map(CONFIG_FSP_M_CBFS, &fspm_blob_size);
+ const char *fspm_cbfs = soc_select_fsp_m_cbfs();
+ void *fspm_blob_file = cbfs_map(fspm_cbfs, &fspm_blob_size);
if (!fspm_blob_file)
return 0;
@@ -386,16 +387,18 @@ void preload_fspm(void)
if (!CONFIG(CBFS_PRELOAD))
return;
- printk(BIOS_DEBUG, "Preloading %s\n", CONFIG_FSP_M_CBFS);
- cbfs_preload(CONFIG_FSP_M_CBFS);
+ const char *fspm_cbfs = soc_select_fsp_m_cbfs();
+ printk(BIOS_DEBUG, "Preloading %s\n", fspm_cbfs);
+ cbfs_preload(fspm_cbfs);
}
void fsp_memory_init(bool s3wake)
{
struct range_entry prog_ranges[2];
struct fspm_context context;
+ const char *fspm_cbfs = soc_select_fsp_m_cbfs();
struct fsp_load_descriptor fspld = {
- .fsp_prog = PROG_INIT(PROG_REFCODE, CONFIG_FSP_M_CBFS),
+ .fsp_prog = PROG_INIT(PROG_REFCODE, fspm_cbfs),
.arg = &context,
};
struct fsp_header *hdr = &context.header;
diff --git a/src/drivers/intel/fsp2_0/silicon_init.c b/src/drivers/intel/fsp2_0/silicon_init.c
index 094eed4160..e543628987 100644
--- a/src/drivers/intel/fsp2_0/silicon_init.c
+++ b/src/drivers/intel/fsp2_0/silicon_init.c
@@ -211,8 +211,9 @@ static void *fsps_allocator(void *arg_unused, size_t size, const union cbfs_mdat
void fsps_load(void)
{
+ const char *fsps_cbfs = soc_select_fsp_s_cbfs();
struct fsp_load_descriptor fspld = {
- .fsp_prog = PROG_INIT(PROG_REFCODE, CONFIG_FSP_S_CBFS),
+ .fsp_prog = PROG_INIT(PROG_REFCODE, fsps_cbfs),
.alloc = fsps_allocator,
};
struct prog *fsps = &fspld.fsp_prog;
@@ -245,8 +246,9 @@ void preload_fsps(void)
if (!CONFIG(CBFS_PRELOAD))
return;
- printk(BIOS_DEBUG, "Preloading %s\n", CONFIG_FSP_S_CBFS);
- cbfs_preload(CONFIG_FSP_S_CBFS);
+ const char *fsps_cbfs = soc_select_fsp_s_cbfs();
+ printk(BIOS_DEBUG, "Preloading %s\n", fsps_cbfs);
+ cbfs_preload(fsps_cbfs);
}
void fsp_silicon_init(void)