
Hi Simon,
On Mon, Nov 25, 2019 at 12:11 PM Simon Glass sjg@chromium.org wrote:
Add support for some important configuration options and FSP memory init. The memory init uses swizzle tables from the device tree.
Support for the FSP_S binary is also included.
Bootstage timing is used for both FSP_M and FSP_S and memory-mapped SPI reads.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v5:
- Drop SAFETY_MARGIN
Changes in v4:
- Add a LOG_CATEGORY for silicon init
- Drop duplicate VBT file CONFIG
- Enable HAVE_VBT for FSP2 also
- Explain the 'twisty headers' comment
- Fix FSP_M reference to refer to FSP_S in commit message
- Fix comment on fsp_silicon_init()
- Rename arch_fsp_s_preinit() to arch_fsps_preinit()
- Rename get_coreboot_fsp() and add comments
- Switch over to use pinctrl for pad init/config
- Use lower-case pinctrl in arch_cpu_init_dm()
Changes in v3:
- Add a proper implementation of fsp_notify
- Add an fsp: tag
- Add bootstage timing for memory-mapped reads
- Add fsp_locate_fsp to locate an fsp component
- Add fspm_done() hook
- Add support for FSP-S component and VBT
- Simplify types for fsp_locate_fsp()
- Switch mmap to use SPI instead of SPI flash
Changes in v2: None
arch/x86/Kconfig | 54 ++++++- arch/x86/include/asm/fsp2/fsp_api.h | 63 ++++++++ arch/x86/include/asm/fsp2/fsp_internal.h | 97 +++++++++++++ arch/x86/lib/fsp2/Makefile | 10 ++ arch/x86/lib/fsp2/fsp_common.c | 13 ++ arch/x86/lib/fsp2/fsp_dram.c | 77 ++++++++++ arch/x86/lib/fsp2/fsp_init.c | 174 +++++++++++++++++++++++ arch/x86/lib/fsp2/fsp_meminit.c | 97 +++++++++++++ arch/x86/lib/fsp2/fsp_silicon_init.c | 54 +++++++ arch/x86/lib/fsp2/fsp_support.c | 131 +++++++++++++++++ include/bootstage.h | 3 + 11 files changed, 770 insertions(+), 3 deletions(-) create mode 100644 arch/x86/include/asm/fsp2/fsp_api.h create mode 100644 arch/x86/include/asm/fsp2/fsp_internal.h create mode 100644 arch/x86/lib/fsp2/Makefile create mode 100644 arch/x86/lib/fsp2/fsp_common.c create mode 100644 arch/x86/lib/fsp2/fsp_dram.c create mode 100644 arch/x86/lib/fsp2/fsp_init.c create mode 100644 arch/x86/lib/fsp2/fsp_meminit.c create mode 100644 arch/x86/lib/fsp2/fsp_silicon_init.c create mode 100644 arch/x86/lib/fsp2/fsp_support.c
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 17a6fe6d3d..6bac5d5fe8 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -326,7 +326,7 @@ config X86_RAMTEST
config FLASH_DESCRIPTOR_FILE string "Flash descriptor binary filename"
depends on HAVE_INTEL_ME
depends on HAVE_INTEL_ME || FSP_VERSION2 default "descriptor.bin" help The filename of the file to use as flash descriptor in the
@@ -411,6 +411,54 @@ config FSP_ADDR The default base address of 0xfffc0000 indicates that the binary must be located at offset 0xc0000 from the beginning of a 1MB flash device.
+if FSP_VERSION2
+config FSP_FILE_T
string "Firmware-Support-Package binary filename (Temp RAM)"
default "fsp_t.bin"
help
The filename of the file to use for the temporary-RAM init phase from
the Firmware-Support-Package binary. Put this in the board directory.
nits: Firmware Support Package (drop -)
It is used to set up an initial area of RAM which can be used for the
stack and other purposes, while bringing up the main system DRAM.
+config FSP_ADDR_T
hex "Firmware-Support-Package binary location (Temp RAM)"
default 0xffff8000
help
FSP is not Position-Independent Code (PIC) and FSP components have to
be rebased if placed at a location which is different from the
perferred base address specified during the FSP build. Use Intel's
Binary Configuration Tool (BCT) to do the rebase.
+config FSP_FILE_M
string "Firmware-Support-Package binary filename (Memory Init)"
default "fsp_m.bin"
help
The filename of the file to use for the RAM init phase from the
Firmware Support Package binary. Put this in the board directory.
It is used to set up the main system DRAM and runs in SPL, once
temporary RAM (CAR) is working.
+config FSP_FILE_S
string "Firmware-Support-Package binary filename (Silicon Init)"
default "fsp_s.bin"
help
The filename of the file to use for the Silicon init phase from the
Firmware Support Package binary. Put this in the board directory.
It is used to set up the silicon to work correctly and must be
executed after DRAM is running.
+config IFWI_INPUT_FILE
string "Filename containing FIT (Firmware Interface Table) with IFWI"
default "fitimage.bin"
help
The IFWI is obtained by running a tool on this file to extract the
IFWI. Put this in the board directory. The IFWI contains U-Boot TPL,
microcode and other internal items.
+endif
config FSP_TEMP_RAM_ADDR hex depends on FSP_VERSION1 @@ -595,7 +643,7 @@ config VGA_BIOS_ADDR
config HAVE_VBT bool "Add a Video BIOS Table (VBT) image"
depends on FSP_VERSION1
depends on HAVE_FSP help Select this option if you have a Video BIOS Table (VBT) image that you would like to add to your ROM. This is normally required if you
@@ -629,7 +677,7 @@ config VBT_ADDR
config VIDEO_FSP bool "Enable FSP framebuffer driver support"
depends on HAVE_VBT && DM_VIDEO
depends on (HAVE_VBT || FSP_VERSION2) && DM_VIDEO
I think the original logic already satisfies the dependency requirement, that we don't need explicitly list FSP_VERSION2 here.
help Turn on this option to enable a framebuffer driver when U-Boot is using Video BIOS Table (VBT) image for FSP firmware to initialize
diff --git a/arch/x86/include/asm/fsp2/fsp_api.h b/arch/x86/include/asm/fsp2/fsp_api.h new file mode 100644 index 0000000000..af1e8857b9 --- /dev/null +++ b/arch/x86/include/asm/fsp2/fsp_api.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: Intel */ +/*
- Copyright (C) 2015-2016 Intel Corp.
- (Written by Andrey Petrov andrey.petrov@intel.com for Intel Corp.)
- (Written by Alexandru Gagniuc alexandrux.gagniuc@intel.com for Intel Corp.)
- Mostly taken from coreboot fsp2_0/memory_init.c
- */
+#ifndef __ASM_FSP2_API_H +#define __ASM_FSP2_API_H
+#include <asm/fsp/fsp_api.h>
+struct fspm_upd; +struct fsps_upd; +struct hob_header;
+enum fsp_boot_mode {
FSP_BOOT_WITH_FULL_CONFIGURATION = 0x00,
FSP_BOOT_WITH_MINIMAL_CONFIGURATION = 0x01,
FSP_BOOT_ASSUMING_NO_CONFIGURATION_CHANGES = 0x02,
FSP_BOOT_ON_S4_RESUME = 0x05,
FSP_BOOT_ON_S3_RESUME = 0x11,
FSP_BOOT_ON_FLASH_UPDATE = 0x12,
FSP_BOOT_IN_RECOVERY_MODE = 0x20
+};
+struct __packed fsp_upd_header {
u64 signature;
u8 revision;
u8 reserved[23];
+};
+/**
- fsp_memory_init() - Init the SDRAM
- @s3wake: true if we are booting from resume, so cannot reinit the mememory
from scatch since we will lose its contents
- @use_spi_flash: true to use the fast SPI driver to read FSP, otherwise use
mapped SPI
- @return 0 if OK, -ve on error
- */
+int fsp_memory_init(bool s3wake, bool use_spi_flash);
+typedef asmlinkage int (*fsp_memory_init_func)(struct fspm_upd *params,
struct hob_header **hobp);
+/**
- fsp_silicon_init() - Init the silicon
- This calls the FSP's 'silicon init' entry point
- @s3wake: true if we are booting from resume, so cannot reinit the mememory
from scatch since we will lose its contents
- @use_spi_flash: true to use the fast SPI driver to read FSP, otherwise use
mapped SPI
- @return 0 if OK, -ve on error
- */
+int fsp_silicon_init(bool s3wake, bool use_spi_flash);
+typedef asmlinkage int (*fsp_silicon_init_func)(struct fsps_upd *params);
+#endif diff --git a/arch/x86/include/asm/fsp2/fsp_internal.h b/arch/x86/include/asm/fsp2/fsp_internal.h new file mode 100644 index 0000000000..f751fbf961 --- /dev/null +++ b/arch/x86/include/asm/fsp2/fsp_internal.h @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: Intel */ +/*
- Copyright (C) 2015-2016 Intel Corp.
- (Written by Alexandru Gagniuc alexandrux.gagniuc@intel.com for Intel Corp.)
- Mostly taken from coreboot
- */
+#ifndef __ASM_FSP_INTERNAL_H +#define __ASM_FSP_INTERNAL_H
+struct binman_entry; +struct fsp_header; +struct fspm_upd; +struct fsps_upd;
+enum fsp_type_t {
FSP_M,
FSP_S,
+};
+int fsp_get_header(ulong offset, ulong size, bool use_spi_flash,
struct fsp_header **fspp);
+/**
- fsp_locate_fsp() - Locate an FSP component
- This finds an FSP component by various methods. It is not as general-purpose
- as it looks, since it expects FSP-M to be requested in SPL (only), and FSP-S
- to be requested in U-Boot proper.
- @type: Component to locate
- @entry: Returns location of component
- @use_spi_flash: true to read using the Fast SPI driver, false to use
memory-mapped SPI flash
- @devp: Returns northbridge device
- @hdrp: Returns FSP header
- @rom_offsetp: If non-NULL, returns the offset to add to any image position to
find the memory-mapped location of that position. For example, for ROM
position 0x1000, it will be mapped into 0x1000 + *rom_offsetp.
- */
+int fsp_locate_fsp(enum fsp_type_t type, struct binman_entry *entry,
bool use_spi_flash, struct udevice **devp,
struct fsp_header **hdrp, ulong *rom_offsetp);
+/**
- arch_fsps_preinit() - Perform init needed before calling FSP-S
- This allows use of probed drivers and PCI so is a convenient place to do any
- init that is needed before FSP-S is called. After this, U-Boot relocates and
- calls arch_fsp_init_r() before PCI is probed, and that function is not
- allowed to probe PCI before calling FSP-S.
- */
+int arch_fsps_preinit(void);
+/**
- fspm_update_config() - Set up the config structure for FSP-M
- @dev: Hostbridge device containing config
- @upd: Config data to fill in
- @return 0 if OK, -ve on error
- */
+int fspm_update_config(struct udevice *dev, struct fspm_upd *upd);
+/**
- fspm_done() - Indicate that memory init is complete
- This allows the board to do whatever post-init it needs before things
- continue.
- @dev: Hostbridge device
- @return 0 if OK, -ve on error
- */
+int fspm_done(struct udevice *dev);
+/**
- fsps_update_config() - Set up the config structure for FSP-S
- @dev: Hostbridge device containing config
- @rom_offset: Value to add to convert from ROM offset to memory-mapped address
- @upd: Config data to fill in
- @return 0 if OK, -ve on error
- */
+int fsps_update_config(struct udevice *dev, ulong rom_offset,
struct fsps_upd *upd);
+/**
- prepare_mrc_cache() - Read the MRC cache into the product-data struct
- This looks for cached Memory-reference code (MRC) data and stores it into
- @upd for use by the FSP-M binary.
- @return 0 if OK, -ENOENT if no data (whereupon the caller can continue and
expect a slower boot), other -ve value on other error
- */
+int prepare_mrc_cache(struct fspm_upd *upd);
+#endif diff --git a/arch/x86/lib/fsp2/Makefile b/arch/x86/lib/fsp2/Makefile new file mode 100644 index 0000000000..ddbe2d0db2 --- /dev/null +++ b/arch/x86/lib/fsp2/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2019 Google LLC
+obj-y += fsp_common.o +obj-y += fsp_dram.o +obj-y += fsp_init.o +obj-y += fsp_meminit.o +obj-y += fsp_silicon_init.o +obj-y += fsp_support.o diff --git a/arch/x86/lib/fsp2/fsp_common.c b/arch/x86/lib/fsp2/fsp_common.c new file mode 100644 index 0000000000..f69456e43a --- /dev/null +++ b/arch/x86/lib/fsp2/fsp_common.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright 2019 Google LLC
- Written by Simon Glass sjg@chromium.org
- */
+#include <common.h> +#include <init.h>
+int arch_fsp_init(void) +{
return 0;
+} diff --git a/arch/x86/lib/fsp2/fsp_dram.c b/arch/x86/lib/fsp2/fsp_dram.c new file mode 100644 index 0000000000..7d1b150ef0 --- /dev/null +++ b/arch/x86/lib/fsp2/fsp_dram.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright 2019 Google LLC
- Written by Simon Glass sjg@chromium.org
- */
+#include <common.h> +#include <acpi_s3.h> +#include <handoff.h> +#include <spl.h> +#include <asm/arch/cpu.h> +#include <asm/fsp/fsp_support.h> +#include <asm/fsp2/fsp_api.h> +#include <asm/fsp2/fsp_internal.h>
+int dram_init(void) +{
int ret;
if (spl_phase() == PHASE_SPL) {
+#ifdef CONFIG_HAVE_ACPI_RESUME
bool s3wake = gd->arch.prev_sleep_state == ACPI_S3;
+#else
bool s3wake = false;
+#endif
ret = fsp_memory_init(s3wake, BOOT_FROM_FAST_SPI_FLASH);
if (ret) {
debug("Memory init failed (err=%x)\n", ret);
return ret;
}
/* The FSP has already set up DRAM, so grab the info we need */
ret = fsp_scan_for_ram_size();
if (ret)
return ret;
+#ifdef CONFIG_ENABLE_MRC_CACHE
gd->arch.mrc[MRC_TYPE_NORMAL].buf =
fsp_get_nvs_data(gd->arch.hob_list,
&gd->arch.mrc[MRC_TYPE_NORMAL].len);
gd->arch.mrc[MRC_TYPE_VAR].buf =
fsp_get_var_nvs_data(gd->arch.hob_list,
&gd->arch.mrc[MRC_TYPE_VAR].len);
log_debug("normal %x, var %x\n",
gd->arch.mrc[MRC_TYPE_NORMAL].len,
gd->arch.mrc[MRC_TYPE_VAR].len);
+#endif
} else {
+#if CONFIG_IS_ENABLED(HANDOFF)
struct spl_handoff *ho = gd->spl_handoff;
if (!ho) {
debug("No SPL handoff found\n");
return -ESTRPIPE;
}
gd->ram_size = ho->ram_size;
handoff_load_dram_banks(ho);
+#endif
ret = arch_fsps_preinit();
if (ret)
return log_msg_ret("fsp_s_preinit", ret);
}
return 0;
+}
+ulong board_get_usable_ram_top(ulong total_size) +{ +#if CONFIG_IS_ENABLED(HANDOFF)
struct spl_handoff *ho = gd->spl_handoff;
return ho->arch.usable_ram_top;
+#endif
return gd->ram_top;
+} diff --git a/arch/x86/lib/fsp2/fsp_init.c b/arch/x86/lib/fsp2/fsp_init.c new file mode 100644 index 0000000000..bcc385e876 --- /dev/null +++ b/arch/x86/lib/fsp2/fsp_init.c @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright 2019 Google LLC
- */
+#include <common.h> +#include <binman.h> +#include <binman_sym.h> +#include <cbfs.h> +#include <dm.h> +#include <init.h> +#include <spi.h> +#include <spl.h> +#include <spi_flash.h> +#include <asm/intel_pinctrl.h> +#include <dm/uclass-internal.h> +#include <asm/fsp2/fsp_internal.h>
+int arch_cpu_init_dm(void) +{
struct udevice *dev;
ofnode node;
int ret;
/* Make sure pads are set up early in U-Boot */
if (spl_phase() != PHASE_BOARD_F)
return 0;
/* Probe all pinctrl devices to set up the pads */
ret = uclass_first_device_err(UCLASS_PINCTRL, &dev);
if (ret)
return log_msg_ret("no fsp pinctrl", ret);
node = ofnode_path("fsp");
if (!ofnode_valid(node))
return log_msg_ret("no fsp params", -EINVAL);
ret = pinctrl_config_pads_for_node(dev, node);
if (ret)
return log_msg_ret("pad config", ret);
return ret;
+}
+#if !defined(CONFIG_TPL_BUILD) +binman_sym_declare(ulong, intel_fsp_m, image_pos); +binman_sym_declare(ulong, intel_fsp_m, size);
+/**
- get_cbfs_fsp() - Obtain the FSP by looking up in CBFS
- This looks up an FSP in a CBFS. It is used mostly for testing, when booting
- U-Boot from a hybrid image containing coreboot as the first-stage bootloader.
- @type; Type to look up (only FSP_M supported at present)
- @map_base: Base memory address for mapped SPI
- @entry: Returns an entry containing the position of the FSP image
- */
+static int get_cbfs_fsp(enum fsp_type_t type, ulong map_base,
struct binman_entry *entry)
+{
/*
* Use a hard-coded position of CBFS in the ROM for now. It would be
* possible to read the position using the FMAP in the ROM, but since
* this code is only used for development, it doesn't seem worth it.
I don't understand why this code is only used for development.
* Use the 'cbfstool <image> layout' command to get these values, e.g.:
* 'COREBOOT' (CBFS, size 1814528, offset 2117632)
Does file_cbfs_find() and its friends in fs/cbfs.c help?
*/
ulong cbfs_base = 0x205000;
ulong cbfs_size = 0x1bb000;
struct cbfs_priv *cbfs;
int ret;
ret = cbfs_init_mem(map_base + cbfs_base, cbfs_size, &cbfs);
if (ret)
return ret;
if (!ret) {
const struct cbfs_cachenode *node;
node = cbfs_find_file(cbfs, "fspm.bin");
if (!node)
return log_msg_ret("fspm node", -ENOENT);
entry->image_pos = (ulong)node->data;
entry->size = node->data_length;
}
return 0;
+}
[snip]
Regards, Bin