From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bin Meng Date: Wed, 2 Oct 2019 22:08:03 +0800 Subject: [U-Boot] [PATCH v2 36/38] x86: Add support for booting from Fast SPI In-Reply-To: <20190925141147.191166-37-sjg@chromium.org> References: <20190925141147.191166-1-sjg@chromium.org> <20190925141147.191166-37-sjg@chromium.org> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On Wed, Sep 25, 2019 at 10:13 PM Simon Glass 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 > --- > > 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 > +#include > +#include > +#include > +#include > + > +/* > + * 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(®s->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