1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-01 08:42:12 +02:00
- Add support for Intel FSP-S and FSP-T in binman
- Correct priority selection for image loaders for SPL
- Add a size check for TPL
- Various small SPL/TPL bug fixes and changes
- SPI: Add support for memory-mapped flash
This commit is contained in:
Tom Rini
2019-11-03 19:28:54 -05:00
26 changed files with 311 additions and 18 deletions

View File

@@ -806,6 +806,12 @@ else
SPL_SIZE_CHECK =
endif
ifneq ($(CONFIG_TPL_SIZE_LIMIT),0)
TPL_SIZE_CHECK = @$(call size_check,$@,$(CONFIG_TPL_SIZE_LIMIT))
else
TPL_SIZE_CHECK =
endif
# Statically apply RELA-style relocations (currently arm64 only)
# This is useful for arm64 where static relocation needs to be performed on
# the raw binary, but certain simulators only accept an ELF file (but don't
@@ -1806,6 +1812,7 @@ spl/boot.bin: spl/u-boot-spl
tpl/u-boot-tpl.bin: tools prepare \
$(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_SPL_OF_PLATDATA),dts/dt.dtb)
$(Q)$(MAKE) obj=tpl -f $(srctree)/scripts/Makefile.spl all
$(TPL_SIZE_CHECK)
TAG_SUBDIRS := $(patsubst %,$(srctree)/%,$(u-boot-dirs) include)

View File

@@ -385,6 +385,14 @@ static void setup_mtrr(void)
}
}
int x86_cpu_init_tpl(void)
{
setup_cpu_features();
setup_identity();
return 0;
}
int x86_cpu_init_f(void)
{
if (ll_boot_init())

View File

@@ -31,6 +31,7 @@ _start:
call board_init_f_init_reserve
call x86_cpu_reinit_f
xorl %eax, %eax
call board_init_f
call board_init_f_r

View File

@@ -55,6 +55,7 @@ enum {
X86_SYSCON_PINCONF, /* Intel x86 pin configuration */
X86_SYSCON_PMU, /* Power Management Unit */
X86_SYSCON_SCU, /* System Controller Unit */
X86_SYSCON_PUNIT, /* Power unit */
};
struct cpuid_result {

View File

@@ -76,6 +76,7 @@ struct arch_global_data {
uint8_t x86_mask;
uint32_t x86_device;
uint64_t tsc_base; /* Initial value returned by rdtsc() */
bool tsc_inited; /* true if tsc is ready for use */
unsigned long clock_rate; /* Clock rate of timer in Hz */
void *new_fdt; /* Relocated FDT */
uint32_t bist; /* Built-in self test value */

View File

@@ -34,6 +34,15 @@ int x86_cpu_init_f(void);
*/
int x86_cpu_reinit_f(void);
/**
* x86_cpu_init_tpl() - Do the minimum possible CPU init
*
* This just sets up the CPU features and figured out the identity
*
* @return 0 (indicating success, to mimic cpu_init_f())
*/
int x86_cpu_init_tpl(void);
int cpu_init_f(void);
void setup_gdt(struct global_data *id, u64 *gdt_addr);
/*

View File

@@ -5,11 +5,15 @@
#include <common.h>
#include <debug_uart.h>
#include <dm.h>
#include <malloc.h>
#include <spl.h>
#include <syscon.h>
#include <asm/cpu.h>
#include <asm/cpu_common.h>
#include <asm/mrccache.h>
#include <asm/mtrr.h>
#include <asm/pci.h>
#include <asm/processor.h>
#include <asm/spl.h>
#include <asm-generic/sections.h>
@@ -21,6 +25,32 @@ __weak int arch_cpu_init_dm(void)
return 0;
}
#ifdef CONFIG_TPL
static int set_max_freq(void)
{
if (cpu_get_burst_mode_state() == BURST_MODE_UNAVAILABLE) {
/*
* Burst Mode has been factory-configured as disabled and is not
* available in this physical processor package
*/
debug("Burst Mode is factory-disabled\n");
return -ENOENT;
}
/* Enable burst mode */
cpu_set_burst_mode(true);
/* Enable speed step */
cpu_set_eist(true);
/* Set P-State ratio */
cpu_set_p_state_to_turbo_ratio();
return 0;
}
#endif
static int x86_spl_init(void)
{
#ifndef CONFIG_TPL
@@ -31,10 +61,16 @@ static int x86_spl_init(void)
* place it immediately below CONFIG_SYS_TEXT_BASE.
*/
char *ptr = (char *)0x110000;
#else
struct udevice *punit;
#endif
int ret;
debug("%s starting\n", __func__);
if (IS_ENABLED(TPL))
ret = x86_cpu_reinit_f();
else
ret = x86_cpu_init_f();
ret = spl_init();
if (ret) {
debug("%s: spl_init() failed\n", __func__);
@@ -101,6 +137,14 @@ static int x86_spl_init(void)
return ret;
}
mtrr_commit(true);
#else
ret = syscon_get_by_driver_data(X86_SYSCON_PUNIT, &punit);
if (ret)
debug("Could not find PUNIT (err=%d)\n", ret);
ret = set_max_freq();
if (ret)
debug("Failed to set CPU frequency (err=%d)\n", ret);
#endif
return 0;

View File

@@ -5,6 +5,7 @@
#include <common.h>
#include <debug_uart.h>
#include <dm.h>
#include <spl.h>
#include <asm/cpu.h>
#include <asm/mtrr.h>
@@ -23,6 +24,11 @@ static int x86_tpl_init(void)
int ret;
debug("%s starting\n", __func__);
ret = x86_cpu_init_tpl();
if (ret) {
debug("%s: x86_cpu_init_tpl() failed\n", __func__);
return ret;
}
ret = spl_init();
if (ret) {
debug("%s: spl_init() failed\n", __func__);
@@ -39,11 +45,6 @@ static int x86_tpl_init(void)
return ret;
}
preloader_console_init();
ret = print_cpuinfo();
if (ret) {
debug("%s: print_cpuinfo() failed\n", __func__);
return ret;
}
return 0;
}
@@ -106,7 +107,7 @@ int spl_spi_load_image(void)
void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
{
printf("Jumping to U-Boot SPL at %lx\n", (ulong)spl_image->entry_point);
debug("Jumping to U-Boot SPL at %lx\n", (ulong)spl_image->entry_point);
jump_to_spl(spl_image->entry_point);
hang();
}
@@ -115,3 +116,27 @@ void spl_board_init(void)
{
preloader_console_init();
}
#if !CONFIG_IS_ENABLED(PCI)
/*
* This is a fake PCI bus for TPL when it doesn't have proper PCI. It is enough
* to bind the devices on the PCI bus, some of which have early-regs properties
* providing fixed BARs. Individual drivers program these BARs themselves so
* that they can access the devices. The BARs are allocated statically in the
* device tree.
*
* Once SPL is running it enables PCI properly, but does not auto-assign BARs
* for devices, so the TPL BARs continue to be used. Once U-Boot starts it does
* the auto allocation (after relocation).
*/
static const struct udevice_id tpl_fake_pci_ids[] = {
{ .compatible = "pci-x86" },
{ }
};
U_BOOT_DRIVER(pci_x86) = {
.name = "pci_x86",
.id = UCLASS_SIMPLE_BUS,
.of_match = tpl_fake_pci_ids,
};
#endif

View File

@@ -1232,6 +1232,14 @@ config TPL
if TPL
config TPL_SIZE_LIMIT
hex "Maximum size of TPL image"
depends on TPL
default 0
help
Specifies the maximum length of the U-Boot TPL image.
If this value is zero, it is ignored.
config TPL_HANDOFF
bool "Pass hand-off information from TPL to SPL and U-Boot proper"
depends on HANDOFF && TPL_BLOBLIST

View File

@@ -269,7 +269,7 @@ For example:
};
U_BOOT_DRIVER(mmc_drv) = {
.name = "mmc",
.name = "vendor_mmc", /* matches compatible string */
.id = UCLASS_MMC,
.of_match = mmc_ids,
.ofdata_to_platdata = mmc_ofdata_to_platdata,

View File

@@ -122,11 +122,22 @@ static int sandbox_cs_info(struct udevice *bus, uint cs,
return 0;
}
static int sandbox_spi_get_mmap(struct udevice *dev, ulong *map_basep,
uint *map_sizep, uint *offsetp)
{
*map_basep = 0x1000;
*map_sizep = 0x2000;
*offsetp = 0x100;
return 0;
}
static const struct dm_spi_ops sandbox_spi_ops = {
.xfer = sandbox_spi_xfer,
.set_speed = sandbox_spi_set_speed,
.set_mode = sandbox_spi_set_mode,
.cs_info = sandbox_cs_info,
.get_mmap = sandbox_spi_get_mmap,
};
static const struct udevice_id sandbox_spi_ids[] = {

View File

@@ -92,6 +92,20 @@ int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
return spi_get_ops(bus)->xfer(dev, bitlen, dout, din, flags);
}
int dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep,
uint *offsetp)
{
struct udevice *bus = dev->parent;
struct dm_spi_ops *ops = spi_get_ops(bus);
if (bus->uclass->uc_drv->id != UCLASS_SPI)
return -EOPNOTSUPP;
if (!ops->get_mmap)
return -ENOSYS;
return ops->get_mmap(dev, map_basep, map_sizep, offsetp);
}
int spi_claim_bus(struct spi_slave *slave)
{
return log_ret(dm_spi_claim_bus(slave->dev));

View File

@@ -394,7 +394,7 @@ static int tsc_timer_get_count(struct udevice *dev, u64 *count)
static void tsc_timer_ensure_setup(bool early)
{
if (gd->arch.tsc_base)
if (gd->arch.tsc_inited)
return;
gd->arch.tsc_base = rdtsc();
@@ -425,6 +425,7 @@ static void tsc_timer_ensure_setup(bool early)
done:
gd->arch.clock_rate = fast_calibrate * 1000000;
}
gd->arch.tsc_inited = true;
}
static int tsc_timer_probe(struct udevice *dev)
@@ -461,6 +462,8 @@ unsigned long notrace timer_early_get_rate(void)
u64 notrace timer_early_get_count(void)
{
tsc_timer_ensure_setup(true);
return rdtsc() - gd->arch.tsc_base;
}

View File

@@ -72,13 +72,13 @@ struct cbfs_fileheader {
struct cbfs_cachenode {
struct cbfs_cachenode *next;
u32 type;
void *data;
u32 data_length;
char *name;
u32 type;
u32 data_length;
u32 name_length;
u32 attributes_offset;
} __packed;
};
extern enum cbfs_result file_cbfs_result;

View File

@@ -462,6 +462,19 @@ struct dm_spi_ops {
* is invalid, other -ve value on error
*/
int (*cs_info)(struct udevice *bus, uint cs, struct spi_cs_info *info);
/**
* get_mmap() - Get memory-mapped SPI
*
* @dev: The SPI flash slave device
* @map_basep: Returns base memory address for mapped SPI
* @map_sizep: Returns size of mapped SPI
* @offsetp: Returns start offset of SPI flash where the map works
* correctly (offsets before this are not visible)
* @return 0 if OK, -EFAULT if memory mapping is not available
*/
int (*get_mmap)(struct udevice *dev, ulong *map_basep,
uint *map_sizep, uint *offsetp);
};
struct dm_spi_emul_ops {
@@ -650,6 +663,20 @@ void dm_spi_release_bus(struct udevice *dev);
int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags);
/**
* spi_get_mmap() - Get memory-mapped SPI
*
* @dev: SPI slave device to check
* @map_basep: Returns base memory address for mapped SPI
* @map_sizep: Returns size of mapped SPI
* @offsetp: Returns start offset of SPI flash where the map works
* correctly (offsets before this are not visible)
* @return 0 if OK, -ENOSYS if no operation, -EFAULT if memory mapping is not
* available
*/
int dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep,
uint *offsetp);
/* Access the operations for a SPI device */
#define spi_get_ops(dev) ((struct dm_spi_ops *)(dev)->driver->ops)
#define spi_emul_get_ops(dev) ((struct dm_spi_emul_ops *)(dev)->driver->ops)

View File

@@ -332,14 +332,14 @@ struct spl_image_loader {
*/
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
#define SPL_LOAD_IMAGE_METHOD(_name, _priority, _boot_device, _method) \
SPL_LOAD_IMAGE(_method ## _priority ## _boot_device) = { \
SPL_LOAD_IMAGE(_boot_device ## _priority ## _method) = { \
.name = _name, \
.boot_device = _boot_device, \
.load_image = _method, \
}
#else
#define SPL_LOAD_IMAGE_METHOD(_name, _priority, _boot_device, _method) \
SPL_LOAD_IMAGE(_method ## _priority ## _boot_device) = { \
SPL_LOAD_IMAGE(_boot_device ## _priority ## _method) = { \
.boot_device = _boot_device, \
.load_image = _method, \
}

View File

@@ -23,6 +23,9 @@ static int dm_test_spi_flash(struct unit_test_state *uts)
int full_size = 0x200000;
int size = 0x10000;
u8 *src, *dst;
uint map_size;
ulong map_base;
uint offset;
int i;
src = map_sysmem(0x20000, full_size);
@@ -54,6 +57,12 @@ static int dm_test_spi_flash(struct unit_test_state *uts)
sandbox_sf_set_block_protect(emul, 0);
ut_asserteq(0, spl_flash_get_sw_write_prot(dev));
/* Check mapping */
ut_assertok(dm_spi_get_mmap(dev, &map_base, &map_size, &offset));
ut_asserteq(0x1000, map_base);
ut_asserteq(0x2000, map_size);
ut_asserteq(0x100, offset);
/*
* Since we are about to destroy all devices, we must tell sandbox
* to forget the emulation device

View File

@@ -444,6 +444,39 @@ See README.x86 for information about x86 binary blobs.
Entry: intel-fsp-s: Entry containing Intel Firmware Support Package (FSP) silicon init
--------------------------------------------------------------------------------------
Properties / Entry arguments:
- filename: Filename of file to read into entry
This file contains a binary blob which is used on some devices to set up
the silicon. U-Boot executes this code in U-Boot proper after SDRAM is
running, so that it can make full use of memory. Documentation is typically
not available in sufficient detail to allow U-Boot do this this itself.
An example filename is 'fsp_s.bin'
See README.x86 for information about x86 binary blobs.
Entry: intel-fsp-t: Entry containing Intel Firmware Support Package (FSP) temp ram init
---------------------------------------------------------------------------------------
Properties / Entry arguments:
- filename: Filename of file to read into entry
This file contains a binary blob which is used on some devices to set up
temporary memory (Cache-as-RAM or CAR). U-Boot executes this code in TPL so
that it has access to memory for its stack and initial storage.
An example filename is 'fsp_t.bin'
See README.x86 for information about x86 binary blobs.
Entry: intel-ifwi: Entry containing an Intel Integrated Firmware Image (IFWI) file
----------------------------------------------------------------------------------

View File

@@ -135,9 +135,7 @@ def LookupAndWriteSymbols(elf_fname, entry, section):
# Look up the symbol in our entry tables.
value = section.LookupSymbol(name, sym.weak, msg)
if value is not None:
value += base.address
else:
if value is None:
value = -1
pack_string = pack_string.lower()
value_bytes = struct.pack(pack_string, value)

View File

@@ -2,7 +2,7 @@
# Copyright 2019 Google LLC
# Written by Simon Glass <sjg@chromium.org>
#
# Entry-type module for Intel Firmware Support Package binary blob (T section)
# Entry-type module for Intel Firmware Support Package binary blob (M section)
#
from entry import Entry

View File

@@ -0,0 +1,27 @@
# SPDX-License-Identifier: GPL-2.0+
# Copyright 2019 Google LLC
# Written by Simon Glass <sjg@chromium.org>
#
# Entry-type module for Intel Firmware Support Package binary blob (S section)
#
from entry import Entry
from blob import Entry_blob
class Entry_intel_fsp_s(Entry_blob):
"""Entry containing Intel Firmware Support Package (FSP) silicon init
Properties / Entry arguments:
- filename: Filename of file to read into entry
This file contains a binary blob which is used on some devices to set up
the silicon. U-Boot executes this code in U-Boot proper after SDRAM is
running, so that it can make full use of memory. Documentation is typically
not available in sufficient detail to allow U-Boot do this this itself.
An example filename is 'fsp_s.bin'
See README.x86 for information about x86 binary blobs.
"""
def __init__(self, section, etype, node):
Entry_blob.__init__(self, section, etype, node)

View File

@@ -0,0 +1,26 @@
# SPDX-License-Identifier: GPL-2.0+
# Copyright 2019 Google LLC
# Written by Simon Glass <sjg@chromium.org>
#
# Entry-type module for Intel Firmware Support Package binary blob (T section)
#
from entry import Entry
from blob import Entry_blob
class Entry_intel_fsp_t(Entry_blob):
"""Entry containing Intel Firmware Support Package (FSP) temp ram init
Properties / Entry arguments:
- filename: Filename of file to read into entry
This file contains a binary blob which is used on some devices to set up
temporary memory (Cache-as-RAM or CAR). U-Boot executes this code in TPL so
that it has access to memory for its stack and initial storage.
An example filename is 'fsp_t.bin'
See README.x86 for information about x86 binary blobs.
"""
def __init__(self, section, etype, node):
Entry_blob.__init__(self, section, etype, node)

View File

@@ -73,6 +73,8 @@ FILES_DATA = (b"sorry I'm late\nOh, don't bother apologising, I'm " +
COMPRESS_DATA = b'compress xxxxxxxxxxxxxxxxxxxxxx data'
REFCODE_DATA = b'refcode'
FSP_M_DATA = b'fsp_m'
FSP_S_DATA = b'fsp_s'
FSP_T_DATA = b'fsp_t'
# The expected size for the device tree in some tests
EXTRACT_DTB_SIZE = 0x3c9
@@ -149,6 +151,8 @@ class TestFunctional(unittest.TestCase):
TestFunctional._MakeInputFile('bmpblk.bin', BMPBLK_DATA)
TestFunctional._MakeInputFile('refcode.bin', REFCODE_DATA)
TestFunctional._MakeInputFile('fsp_m.bin', FSP_M_DATA)
TestFunctional._MakeInputFile('fsp_s.bin', FSP_S_DATA)
TestFunctional._MakeInputFile('fsp_t.bin', FSP_T_DATA)
cls._elf_testdir = os.path.join(cls._indir, 'elftest')
elf_test.BuildElfTestFiles(cls._elf_testdir)
@@ -3332,6 +3336,15 @@ class TestFunctional(unittest.TestCase):
data = self._DoReadFile('152_intel_fsp_m.dts')
self.assertEqual(FSP_M_DATA, data[:len(FSP_M_DATA)])
def testPackFspS(self):
"""Test that an image with a FSP silicon-init binary can be created"""
data = self._DoReadFile('153_intel_fsp_s.dts')
self.assertEqual(FSP_S_DATA, data[:len(FSP_S_DATA)])
def testPackFspT(self):
"""Test that an image with a FSP temp-ram-init binary can be created"""
data = self._DoReadFile('154_intel_fsp_t.dts')
self.assertEqual(FSP_T_DATA, data[:len(FSP_T_DATA)])
if __name__ == "__main__":

View File

@@ -0,0 +1,14 @@
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
size = <16>;
intel-fsp-s {
filename = "fsp_s.bin";
};
};
};

View File

@@ -0,0 +1,14 @@
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
size = <16>;
intel-fsp-t {
filename = "fsp_t.bin";
};
};
};

View File

@@ -9,7 +9,7 @@ ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = 0x00000010;
_start = .;
. = ALIGN(4);