[U-Boot] [PATCH v2 36/38] x86: Add support for booting from Fast SPI

Bin Meng bmeng.cn at gmail.com
Wed Oct 2 14:08:03 UTC 2019


On Wed, Sep 25, 2019 at 10:13 PM Simon Glass <sjg at chromium.org> wrote:
>
> Most x86 CPUs use a mechanism where the SPI flash is mapped into the very
> top of 32-bit address space, so that it can be executed in place and read
> simply by copying from memory. For an 8MB ROM the mapping starts at
> 0xff800000.
>
> However some recent Intel CPUs do not use a simple 1:1 memory map. Instead
> the map starts at a different address and not all of the SPI flash is
> accessible through the map. This 'Fast SPI' feature requires that U-Boot
> check the location of the map. It is also possible (optionally) to read
> from the SPI flash using a driver.
>
> Add support for booting from Fast SPI. The memory-mapped version is used
> by both TPL and SPL on apollolake.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> Changes in v2:
> - Rename the fast SPI headers
>
>  arch/x86/cpu/intel_common/Makefile   |  1 +
>  arch/x86/cpu/intel_common/fast_spi.c | 48 ++++++++++++++++++++++++++++
>  arch/x86/include/asm/spl.h           |  1 +
>  3 files changed, 50 insertions(+)
>  create mode 100644 arch/x86/cpu/intel_common/fast_spi.c
>
> diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile
> index 07f27c29ec7..2de567dd9fe 100644
> --- a/arch/x86/cpu/intel_common/Makefile
> +++ b/arch/x86/cpu/intel_common/Makefile
> @@ -9,6 +9,7 @@ obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += report_platform.o
>  obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += mrc.o
>  endif
>  obj-y += cpu.o
> +obj-$(CONFIG_SPI_FLASH_INTEL_FAST) += fast_spi.o
>  obj-y += lpc.o
>  ifndef CONFIG_TARGET_EFI_APP
>  obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += microcode.o
> diff --git a/arch/x86/cpu/intel_common/fast_spi.c b/arch/x86/cpu/intel_common/fast_spi.c
> new file mode 100644
> index 00000000000..a7334ecf1a3
> --- /dev/null
> +++ b/arch/x86/cpu/intel_common/fast_spi.c
> @@ -0,0 +1,48 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2019 Google LLC
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/pci.h>
> +#include <asm/arch/fast_spi.h>
> +#include <asm/arch/iomap.h>
> +
> +/*
> + * Returns bios_start and fills in size of the BIOS region.
> + */
> +ulong fast_spi_get_bios_region(struct fast_spi_regs *regs, size_t *bios_size)

I suspect we need a public header file for these 2 APIs?

> +{
> +       ulong bios_start, bios_end;
> +
> +       /*
> +        * BIOS_BFPREG provides info about BIOS-Flash Primary Region Base and
> +        * Limit. Base and Limit fields are in units of 4K.
> +        */
> +       u32 val = readl(&regs->bfp);
> +
> +       bios_start = (val & SPIBAR_BFPREG_PRB_MASK) << 12;
> +       bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >>
> +                    SPIBAR_BFPREG_PRL_SHIFT) + 1) << 12;
> +       *bios_size = bios_end - bios_start;
> +
> +       return bios_start;
> +}
> +
> +int fast_spi_get_bios_mmap(ulong *map_basep, size_t *map_sizep, uint *offsetp)
> +{
> +       struct fast_spi_regs *regs;
> +       ulong bar, base, mmio_base;
> +
> +       /* Special case to find mapping without probing the device */
> +       pci_x86_read_config(NULL, PCH_DEV_SPI, PCI_BASE_ADDRESS_0, &bar,
> +                           PCI_SIZE_32);
> +       mmio_base = bar & PCI_BASE_ADDRESS_MEM_MASK;
> +       regs = (struct fast_spi_regs *)mmio_base;
> +       base = fast_spi_get_bios_region(regs, map_sizep);
> +       *map_basep = (u32)-*map_sizep - base;
> +       *offsetp = base;
> +
> +       return 0;
> +}
> diff --git a/arch/x86/include/asm/spl.h b/arch/x86/include/asm/spl.h
> index 1bef4877eb3..cc6cac08f23 100644
> --- a/arch/x86/include/asm/spl.h
> +++ b/arch/x86/include/asm/spl.h
> @@ -11,6 +11,7 @@
>
>  enum {
>         BOOT_DEVICE_SPI_MMAP    = 10,
> +       BOOT_DEVICE_FAST_SPI,
>         BOOT_DEVICE_CROS_VBOOT,
>  };
>
> --

Regards,
Bin


More information about the U-Boot mailing list