From 895ae8726dea182c8512fc6154bd0f9a6a06657b Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 7 Oct 2019 00:37:45 +0200 Subject: cbfs: do not pack struct cbfs_cachenode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the __packed attribute sandbox_defconfig cannot be compiled with GCC 9.2.1: fs/cbfs/cbfs.c: In function ‘file_cbfs_fill_cache’: fs/cbfs/cbfs.c:164:16: error: taking address of packed member of ‘struct cbfs_cachenode’ may result in an unaligned pointer value [-Werror=address-of-packed-member] 164 | cache_tail = &new_node->next; | ^~~~~~~~~~~~~~~ struct cbfs_cachenode is only an internal structure. So let's rearrange the fields such that the structure is naturally packed and remove the __packed attribute. Signed-off-by: Heinrich Schuchardt Reviewed-by: Bin Meng Reviewed-by: Simon Glass --- include/cbfs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/cbfs.h b/include/cbfs.h index 6d4c4d4b06..f3bc8ca24a 100644 --- a/include/cbfs.h +++ b/include/cbfs.h @@ -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; -- cgit From 15c981cc8adc26501e3a19ca7fb35705870ef597 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:31:34 -0600 Subject: binman: Correct symbol calculation with non-zero image base At present binman adds the image base address to the symbol value before it writes it to the binary. This is not correct since the symbol value itself (e.g. image position) has no relationship to the image base. Fix this and update the tests to cover this case. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- tools/binman/elf.py | 4 +--- tools/binman/test/u_boot_binman_syms.lds | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/binman/elf.py b/tools/binman/elf.py index 7bc7cf61b5..0c1a5b44b6 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -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) diff --git a/tools/binman/test/u_boot_binman_syms.lds b/tools/binman/test/u_boot_binman_syms.lds index 926df873cb..825fc3f649 100644 --- a/tools/binman/test/u_boot_binman_syms.lds +++ b/tools/binman/test/u_boot_binman_syms.lds @@ -9,7 +9,7 @@ ENTRY(_start) SECTIONS { - . = 0x00000000; + . = 0x00000010; _start = .; . = ALIGN(4); -- cgit From bc6a88fafef7c9a844136b1f4a8d25b8e79a2b31 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:31:35 -0600 Subject: binman: Add support for Intel FSP-S This entry is used to hold an Intel FSP-S (Firmware Support Package Silicon init) binary. Add support for this in binman. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- tools/binman/README.entries | 17 +++++++++++++++++ tools/binman/etype/intel_fsp_s.py | 27 +++++++++++++++++++++++++++ tools/binman/ftest.py | 6 ++++++ tools/binman/test/153_intel_fsp_s.dts | 14 ++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 tools/binman/etype/intel_fsp_s.py create mode 100644 tools/binman/test/153_intel_fsp_s.dts diff --git a/tools/binman/README.entries b/tools/binman/README.entries index bce2244596..0c0c9675b0 100644 --- a/tools/binman/README.entries +++ b/tools/binman/README.entries @@ -444,6 +444,23 @@ 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-ifwi: Entry containing an Intel Integrated Firmware Image (IFWI) file ---------------------------------------------------------------------------------- diff --git a/tools/binman/etype/intel_fsp_s.py b/tools/binman/etype/intel_fsp_s.py new file mode 100644 index 0000000000..3d6900d1fb --- /dev/null +++ b/tools/binman/etype/intel_fsp_s.py @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2019 Google LLC +# Written by Simon Glass +# +# 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) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 7000de9d42..eb9aec61cc 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -73,6 +73,7 @@ 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' # The expected size for the device tree in some tests EXTRACT_DTB_SIZE = 0x3c9 @@ -149,6 +150,7 @@ 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) cls._elf_testdir = os.path.join(cls._indir, 'elftest') elf_test.BuildElfTestFiles(cls._elf_testdir) @@ -3332,6 +3334,10 @@ 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)]) if __name__ == "__main__": diff --git a/tools/binman/test/153_intel_fsp_s.dts b/tools/binman/test/153_intel_fsp_s.dts new file mode 100644 index 0000000000..579618a8fa --- /dev/null +++ b/tools/binman/test/153_intel_fsp_s.dts @@ -0,0 +1,14 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + size = <16>; + + intel-fsp-s { + filename = "fsp_s.bin"; + }; + }; +}; -- cgit From 998d1482cdf980c083cdd95078fd86b53f963c41 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:31:36 -0600 Subject: binman: Add support for Intel FSP-T This entry is used to hold an Intel FSP-T (Firmware Support Package Temp-RAM init) binary. Add support for this in binman. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- tools/binman/README.entries | 16 ++++++++++++++++ tools/binman/etype/intel_fsp_t.py | 26 ++++++++++++++++++++++++++ tools/binman/ftest.py | 7 +++++++ tools/binman/test/154_intel_fsp_t.dts | 14 ++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 tools/binman/etype/intel_fsp_t.py create mode 100644 tools/binman/test/154_intel_fsp_t.dts diff --git a/tools/binman/README.entries b/tools/binman/README.entries index 0c0c9675b0..1099433521 100644 --- a/tools/binman/README.entries +++ b/tools/binman/README.entries @@ -461,6 +461,22 @@ 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 ---------------------------------------------------------------------------------- diff --git a/tools/binman/etype/intel_fsp_t.py b/tools/binman/etype/intel_fsp_t.py new file mode 100644 index 0000000000..813a81f2e6 --- /dev/null +++ b/tools/binman/etype/intel_fsp_t.py @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2019 Google LLC +# Written by Simon Glass +# +# 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) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index eb9aec61cc..494e218cbc 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -74,6 +74,7 @@ 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 @@ -151,6 +152,7 @@ class TestFunctional(unittest.TestCase): 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) @@ -3339,6 +3341,11 @@ class TestFunctional(unittest.TestCase): 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__": unittest.main() diff --git a/tools/binman/test/154_intel_fsp_t.dts b/tools/binman/test/154_intel_fsp_t.dts new file mode 100644 index 0000000000..8da749c157 --- /dev/null +++ b/tools/binman/test/154_intel_fsp_t.dts @@ -0,0 +1,14 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + size = <16>; + + intel-fsp-t { + filename = "fsp_t.bin"; + }; + }; +}; -- cgit From 211193dc5c732af1b88be0e6c23715f83afd1cb0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:31:37 -0600 Subject: binman: Fix up comment in intel-fsp-m This comment references the wrong FSP component. Fix it. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- tools/binman/etype/intel_fsp_m.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/binman/etype/intel_fsp_m.py b/tools/binman/etype/intel_fsp_m.py index 2d6b2b6621..bb1de73e41 100644 --- a/tools/binman/etype/intel_fsp_m.py +++ b/tools/binman/etype/intel_fsp_m.py @@ -2,7 +2,7 @@ # Copyright 2019 Google LLC # Written by Simon Glass # -# 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 -- cgit From e1500a6ce29a8424cc0c0a2fa82e694419941dd1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:31:45 -0600 Subject: spl: Correct priority selection for image loaders At present the name of the image comes first in the linker-list symbol used. This means that the name of the function sets the sort order, which is not the intention. Update it to put the boot-device type first, then the priority. This produces the expected behaviour. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- include/spl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/spl.h b/include/spl.h index b5387ef273..08ffddac29 100644 --- a/include/spl.h +++ b/include/spl.h @@ -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, \ } -- cgit From c53b318e1bad2e0d5c2b846fadfc79ec77bfc5f7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:31:47 -0600 Subject: spi: Add support for memory-mapped flash On x86 platforms the SPI flash can be mapped into memory so that the contents can be read with normal memory accesses. Add a new SPI method to find the location of the SPI flash in memory. This differs from the existing device-tree "memory-map" mechanism in that the location can be discovered at run-time. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/spi/sandbox_spi.c | 11 +++++++++++ drivers/spi/spi-uclass.c | 14 ++++++++++++++ include/spi.h | 27 +++++++++++++++++++++++++++ test/dm/sf.c | 9 +++++++++ 4 files changed, 61 insertions(+) diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c index 16473ec7a0..6b610ff823 100644 --- a/drivers/spi/sandbox_spi.c +++ b/drivers/spi/sandbox_spi.c @@ -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[] = { diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 947516073e..665611f7e2 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -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)); diff --git a/include/spi.h b/include/spi.h index 3f79168df3..6fbb4336ce 100644 --- a/include/spi.h +++ b/include/spi.h @@ -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) diff --git a/test/dm/sf.c b/test/dm/sf.c index 3788d59052..65aab4f2e9 100644 --- a/test/dm/sf.c +++ b/test/dm/sf.c @@ -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 -- cgit From 63473ee8c5c570b38b757ba7bb8e25585d7917d8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:31:48 -0600 Subject: dm: doc: Correct of-platdata driver name Add a note about the driver name in the of-platdata documentation since the naming must follow the compatible string. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- doc/driver-model/of-plat.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/driver-model/of-plat.rst b/doc/driver-model/of-plat.rst index a38e58e4d2..557957d2a1 100644 --- a/doc/driver-model/of-plat.rst +++ b/doc/driver-model/of-plat.rst @@ -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, -- cgit From c52b5e8e2ce7f4cd3a9116083debd27ef23046d7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:31:52 -0600 Subject: spl: Add a size check for TPL We have the ability to enforce a maximum size for SPL but not yet for TPL. Add a new option for this. Document the size check macro while we are here. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- Makefile | 7 +++++++ common/spl/Kconfig | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/Makefile b/Makefile index a96c6ce81e..3000d30be2 100644 --- a/Makefile +++ b/Makefile @@ -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) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 86d7edfee1..c661809923 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -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 -- cgit From 096c71e34bac7551aa228bbcb9e1c867ad9e5d07 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:31:54 -0600 Subject: x86: timer: Set up the timer in timer_early_get_count() This function can be called before the timer is set up. Make sure that the init function is called so that it works correctly. This is needed so that bootstage can work correctly in TPL. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/timer/tsc_timer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c index 919caba8a1..f19d2237e4 100644 --- a/drivers/timer/tsc_timer.c +++ b/drivers/timer/tsc_timer.c @@ -461,6 +461,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; } -- cgit From a478a26cd00bbe14d51952b9ae3620415fbdf2b2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:37:47 -0600 Subject: x86: timer: Use a separate flag for whether timer is inited At present the value of the timer base is used to determine whether the timer has been set up or not. It is true that the timer is essentially never exactly 0 when it is read. However 'time 0' may indicate the time that the machine was reset so it is useful to be able to denote that. Update the code to use a separate flag instead. Signed-off-by: Simon Glass Tested-by: Aiden Park Reviewed-by: Aiden Park Reviewed-by: Bin Meng --- arch/x86/include/asm/global_data.h | 1 + drivers/timer/tsc_timer.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index 17a4d34491..7f3ada06f6 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -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 */ diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c index f19d2237e4..637c8ff25a 100644 --- a/drivers/timer/tsc_timer.c +++ b/drivers/timer/tsc_timer.c @@ -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) -- cgit From c0e2c81d8e845cd700bb2311514f9d6877f784bb Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:37:49 -0600 Subject: x86: spl: Support init of a PUNIT The x86 power unit handles power management. Support initing this device which is modelled as a new type of system controller since there are no operations needed. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/include/asm/cpu.h | 1 + arch/x86/lib/spl.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index feee0f915f..21a05dab7d 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -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 { diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c index 7623fc9ada..a8eaafeb5b 100644 --- a/arch/x86/lib/spl.c +++ b/arch/x86/lib/spl.c @@ -5,11 +5,15 @@ #include #include +#include #include #include +#include #include +#include #include #include +#include #include #include #include @@ -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,6 +61,8 @@ 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; @@ -101,6 +133,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; -- cgit From 0ced70a0bb7a114226c831bf2058681011c0fb4e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:37:50 -0600 Subject: x86: tpl: Add a fake PCI bus In TPL we try to minimise code size so do not include the PCI subsystem. We can use fixed BARs and drivers can directly program the devices that they need. However we do need to bind the devices on the PCI bus and without PCI this does not ordinarily happen. As a work-around, define a fake PCI bus which does this binding, but no other PCI operations. This is a convenient way to ensure that we can use the same device tree for TPL, SPL and U-Boot proper: TPL - CONFIG_TPL_PCI is not set (no auto-config, fake PCI bus) SPL - CONFIG_SPL_PCI is set (no auto-config but with real PCI bus) U-Boot - CONFIG_PCI is set (full auto-config after relocation) Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/lib/tpl.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/x86/lib/tpl.c b/arch/x86/lib/tpl.c index d70f590541..6ca3f7b1f2 100644 --- a/arch/x86/lib/tpl.c +++ b/arch/x86/lib/tpl.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -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 -- cgit From ece3a4607010226082f2e08afa37419e01ad853f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:37:54 -0600 Subject: x86: Add a CPU init function for TPL For TPL we only need to set up the features and identify the CPU to a basic level. Add a function to handle that. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/i386/cpu.c | 8 ++++++++ arch/x86/include/asm/u-boot-x86.h | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c index 90b546e741..31663714a0 100644 --- a/arch/x86/cpu/i386/cpu.c +++ b/arch/x86/cpu/i386/cpu.c @@ -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()) diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 2466ad2ad3..3e5d56d075 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -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); /* -- cgit From 0e72ac715007a85cf89683883bd84bdcfa185b0a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:37:55 -0600 Subject: x86: Move CPU init to before spl_init() At present we call spl_init() before identifying the CPU. This is not a good idea - e.g. if bootstage is enabled then it will try to set up the timer which works better if the CPU is identified. Put explicit code at each entry pointer to identify the CPU. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/start_from_spl.S | 1 + arch/x86/lib/spl.c | 4 ++++ arch/x86/lib/tpl.c | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/arch/x86/cpu/start_from_spl.S b/arch/x86/cpu/start_from_spl.S index a73b4d7c45..22cab2dd6c 100644 --- a/arch/x86/cpu/start_from_spl.S +++ b/arch/x86/cpu/start_from_spl.S @@ -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 diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c index a8eaafeb5b..1677f80b25 100644 --- a/arch/x86/lib/spl.c +++ b/arch/x86/lib/spl.c @@ -67,6 +67,10 @@ static int x86_spl_init(void) 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__); diff --git a/arch/x86/lib/tpl.c b/arch/x86/lib/tpl.c index 6ca3f7b1f2..363984f7f2 100644 --- a/arch/x86/lib/tpl.c +++ b/arch/x86/lib/tpl.c @@ -24,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__); -- cgit From 09455d3a8fe0f3413a820fc26f016a2d9ec496e8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:37:56 -0600 Subject: x86: Don't print CPU info in TPL We don't need to do this and it is done (in more detail) in U-Boot proper. Drop this to save code space. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/lib/tpl.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/x86/lib/tpl.c b/arch/x86/lib/tpl.c index 363984f7f2..815849c7ff 100644 --- a/arch/x86/lib/tpl.c +++ b/arch/x86/lib/tpl.c @@ -45,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; } -- cgit From 73c6cd6c0bdb3af76d573f619bbcc141758bb16b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:37:57 -0600 Subject: x86: Quieten TPL's jump_to_image_no_args() We already a message indicating that U-Boot is about to jump to SPL, so make this one a debug() to reduce code size. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/lib/tpl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/lib/tpl.c b/arch/x86/lib/tpl.c index 815849c7ff..784e3a02de 100644 --- a/arch/x86/lib/tpl.c +++ b/arch/x86/lib/tpl.c @@ -107,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(); } -- cgit