[PATCH v2 00/45] dm: core: Support multiple device trees in ofnode

At present the ofnode interface is somewhat limited, in that it cannot access the device tree provided by the OS, only the one used by U-Boot itself (assuming these are separate). This prevents using ofnode functions to handle device tree fixups, i.e. ft_board_setup() and the like.
The ofnode interface was introduced to allow a consistent API to access the device tree, whether a flat tree or a live tree (OF_LIVE) is in use.
With the flat tree, adding nodes and properties at the start of the tree (as often happens when writing to the /chosen node) requires copying a lot of data for each operation. With live tree, such operations are quite a bit faster, since there is no memory copying required. This has to be weighed against the required memory allocation with OF_LIVE, as well as the cost of unflattening and flattening the device tree which U-Boot is running.
This series enables support for access to multiple device trees with the ofnode interface. This is already available to some extent with OF_LIVE, but some of the ofnode functions need changes to allow the tree to be specified.
The mechanism works by using the top 1-4 bits of the device tree offset. The sign bit is not affected, since negative values must be supported.
With this implemented, it becomes possible to use the ofnode interface to do device tree fixups. The only current user is the EVT_FT_FIXUP event.
This has two main benefits:
- ofnode can now be used everywhere, in preference to the libfdt calls - live tree can eventually be used everywhere, with potential speed improvements when larger number of fixups are used
This series is only a step along the way. Firstly, while it is possible to access the 'fix-up' tree using OF_LIVE, most of the fixup functions use flat tree directly, rather than the ofnode interface. These need to be updated. Also the tree must be flattened again before it is passed to the OS. This is not currently implemented.
With OFNODE_MULTI_TREE disabled this has almost no effect on code size: around 4 bytes if EVENT is enabled, 0 if not. With the feature enabled, the increase is around 700 bytes, e.g. on venice2:
$ buildman -b ofn2a venice2 -sS --step 0 Summary of 2 commits for 1 boards (1 thread, 64 jobs per thread) 01: image: Drop some other #ifdefs in image-board.c arm: w+ venice2 48: wip arm: (for 1/1 boards) all +668.0 text +668.0
This size increase is not too bad, considering the extra functionality, but is too large to enable everywhere. So for now this features needs to be opt-in only, based on EVENT.
Changes in v2: - Return the existing node with -EEXIST - Allow len to be passed in as -1 - Add a comment as to why strncmp() is not enough - Add a comment why the len parameter is needed - Add a comment why the new_name variable is used - Add tests for the memory checks in of_add_subnode() - Fix memory checks - Fix 'property' comment - Add lots more tests and a few other fixes - Gosh that code was a mess - Add new patch to rename ofnode_get_property_by_prop() - Substantially expanded to improve the ofnode implementation/interface - Added more ofnode tests - Minor reworks of the ofnode internals, using oftree - Added testing of memory-allocation failures
Simon Glass (45): image: Fix BOOTM_STATE values treewide: Drop bootm_headers_t typedef treewide: Drop image_info_t typedef treewide: Drop image_header_t typedef log: update the comment for log_msg_ret() sandbox: power: Update PMIC driver to use log event: Fix a typo in the EVENT help event: Allow multiple spy declarations for each event dm: core: Pass a root node to of_find_node_by_phandle() event: Pass the images to EVT_FT_FIXUP test: Fix missing livetree test runs test: Support testing malloc() failures dm: core: Document the livetree structures properly dm: core: Allow adding ofnode subnodes dm: core: Support writing a property to an empty node dm: core: Drop the const from ofnode test: Make a copy of the device tree before running a test test: Detect a change in the device tree test: Drop the UT_TESTF_LIVE_OR_FLAT flag sandbox: Add a function to load a relative file path sandbox: Support loading the other FDT sandbox: Support setting up the other FDT for testing sandbox: test: Provide an easy way to use the other FDT dm: core: Reduce code size with dev_of_offset() dm: core: Rename ofnode_get_first/next_property() dm: core: Rename ofnode_get_property_by_prop() dm: core: Avoid creating a name property when unflattening dm: core: Add a macro to iterate through properties dm: core: Drop ofnode_is_available() dm: core: Expand integer-reading tests dm: core: Provide a way to reset the device tree dm: core: Add an ofnode function to obtain the flat tree dm: core: Add ofnode functions to obtain an oftree dm: core: Add a way to look up a phandle in an oftree dm: core: Allow obtaining a node offset in the same tree dm: core: Split ofnode_path_root() into two functions dm: core: Add definitions for multiple ofnode trees dm: core: Add the ofnode multi-tree implementation dm: core: Complete phandle implementation using the other FDT dm: core: Update comments for default-FDT ofnode functions dm: core: Create a function to get a live tree in a test dm: core: Expand ofnode tests vbe: Allow test to run with live/flat tree dm: core: Allow copying ofnode property data when writing dm: core: Support copying properties with ofnode
arch/arc/lib/bootm.c | 8 +- arch/arm/lib/bootm.c | 13 +- arch/arm/mach-aspeed/ast2600/spl.c | 4 +- arch/arm/mach-imx/hab.c | 2 +- arch/arm/mach-imx/spl_imx_romapi.c | 6 +- arch/arm/mach-k3/common.c | 2 +- arch/arm/mach-k3/sysfw-loader.c | 6 +- arch/arm/mach-keystone/cmd_mon.c | 6 +- arch/arm/mach-socfpga/board.c | 2 +- arch/arm/mach-sunxi/spl_spi_sunxi.c | 4 +- arch/arm/mach-tegra/xusb-padctl-common.c | 2 +- arch/m68k/lib/bootm.c | 2 +- arch/microblaze/lib/bootm.c | 6 +- arch/mips/lib/bootm.c | 16 +- arch/mips/mach-jz47xx/jz4780/jz4780.c | 6 +- arch/mips/mach-mtmips/mt7621/spl/spl.c | 4 +- arch/mips/mach-mtmips/mt7621/tpl/tpl.c | 4 +- arch/nios2/lib/bootm.c | 2 +- arch/powerpc/lib/bootm.c | 16 +- arch/riscv/lib/andes_plic.c | 2 +- arch/riscv/lib/bootm.c | 8 +- arch/riscv/lib/smp.c | 2 +- arch/sandbox/cpu/cpu.c | 34 +- arch/sandbox/cpu/start.c | 16 +- arch/sandbox/cpu/state.c | 48 ++ arch/sandbox/dts/Makefile | 2 +- arch/sandbox/dts/other.dts | 35 ++ arch/sandbox/include/asm/malloc.h | 1 + arch/sandbox/include/asm/state.h | 30 + arch/sandbox/include/asm/test.h | 19 + arch/sandbox/lib/bootm.c | 2 +- arch/sh/lib/bootm.c | 2 +- arch/x86/lib/bootm.c | 8 +- arch/xtensa/lib/bootm.c | 2 +- board/synopsys/hsdk/hsdk.c | 2 +- board/ti/ks2_evm/board.c | 4 +- boot/boot_fit.c | 4 +- boot/bootm.c | 26 +- boot/bootm_os.c | 35 +- boot/image-android.c | 6 +- boot/image-board.c | 26 +- boot/image-fdt.c | 13 +- boot/image-fit.c | 16 +- boot/image.c | 14 +- boot/vbe_simple.c | 2 +- cmd/bootefi.c | 2 +- cmd/booti.c | 2 +- cmd/bootm.c | 4 +- cmd/bootz.c | 2 +- cmd/disk.c | 4 +- cmd/fpga.c | 2 +- cmd/nand.c | 4 +- cmd/source.c | 2 +- cmd/ximg.c | 4 +- common/Kconfig | 2 +- common/board_r.c | 2 + common/dlmalloc.c | 19 + common/spl/spl.c | 10 +- common/spl/spl_ext.c | 4 +- common/spl/spl_fat.c | 6 +- common/spl/spl_legacy.c | 8 +- common/spl/spl_mmc.c | 4 +- common/spl/spl_nand.c | 4 +- common/spl/spl_net.c | 2 +- common/spl/spl_nor.c | 8 +- common/spl/spl_onenand.c | 2 +- common/spl/spl_ram.c | 8 +- common/spl/spl_sata.c | 2 +- common/spl/spl_semihosting.c | 4 +- common/spl/spl_spi.c | 6 +- common/spl/spl_ubi.c | 4 +- common/spl/spl_xip.c | 2 +- common/spl/spl_ymodem.c | 14 +- common/splash_source.c | 6 +- doc/develop/driver-model/livetree.rst | 37 +- doc/uImage.FIT/source_file_format.txt | 2 +- drivers/core/Kconfig | 24 + drivers/core/fdtaddr.c | 18 +- drivers/core/of_access.c | 83 ++- drivers/core/ofnode.c | 442 +++++++++++--- drivers/core/read.c | 6 +- drivers/cpu/imx8_cpu.c | 2 +- drivers/cpu/riscv_cpu.c | 2 +- drivers/crypto/fsl/jr.c | 2 +- drivers/firmware/scmi/scmi_agent-uclass.c | 2 +- drivers/fpga/socfpga_arria10.c | 4 +- drivers/mtd/mtdpart.c | 4 +- drivers/mtd/nand/raw/zynq_nand.c | 2 +- drivers/net/fec_mxc.c | 2 +- drivers/net/fsl_enetc.c | 2 +- drivers/net/mscc_eswitch/felix_switch.c | 2 +- drivers/net/sja1105.c | 2 +- drivers/net/ti/am65-cpsw-nuss.c | 2 +- drivers/pci/pci-uclass.c | 2 +- drivers/pci/pci_mvebu.c | 2 +- drivers/pci/pci_tegra.c | 2 +- drivers/pci/pcie_mediatek.c | 4 +- drivers/power/pmic/sandbox.c | 10 +- drivers/usb/gadget/f_sdp.c | 2 +- env/common.c | 6 +- include/asm-generic/global_data.h | 4 + include/bootm.h | 6 +- include/configs/uniphier.h | 2 +- include/dm/device.h | 6 +- include/dm/of.h | 15 +- include/dm/of_access.h | 29 +- include/dm/ofnode.h | 345 +++++++++-- include/dm/ofnode_decl.h | 37 +- include/dm/read.h | 8 +- include/event.h | 6 +- include/image.h | 118 ++-- include/log.h | 5 +- include/malloc.h | 12 + include/spl.h | 8 +- include/tee/optee.h | 4 +- include/test/test.h | 30 +- include/test/ut.h | 5 + lib/efi_loader/efi_dt_fixup.c | 2 +- lib/fdtdec.c | 7 +- lib/of_live.c | 7 +- net/dsa-uclass.c | 2 +- scripts/event_dump.py | 4 +- test/boot/vbe_simple.c | 25 +- test/dm/ofnode.c | 696 +++++++++++++++++++++- test/dm/ofread.c | 11 +- test/image/spl_load.c | 4 +- test/test-main.c | 136 ++++- tools/binman/ftest.py | 4 +- tools/default_image.c | 31 +- tools/fit_image.c | 4 +- tools/imx8mimage.c | 8 +- tools/mkimage.c | 2 +- tools/mtk_image.c | 10 +- 133 files changed, 2253 insertions(+), 621 deletions(-) create mode 100644 arch/sandbox/dts/other.dts

Tidy up the code style for these.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
include/image.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/include/image.h b/include/image.h index a148073113a..5e81fad8774 100644 --- a/include/image.h +++ b/include/image.h @@ -341,18 +341,18 @@ typedef struct bootm_headers {
int verify; /* env_get("verify")[0] != 'n' */
-#define BOOTM_STATE_START (0x00000001) -#define BOOTM_STATE_FINDOS (0x00000002) -#define BOOTM_STATE_FINDOTHER (0x00000004) -#define BOOTM_STATE_LOADOS (0x00000008) -#define BOOTM_STATE_RAMDISK (0x00000010) -#define BOOTM_STATE_FDT (0x00000020) -#define BOOTM_STATE_OS_CMDLINE (0x00000040) -#define BOOTM_STATE_OS_BD_T (0x00000080) -#define BOOTM_STATE_OS_PREP (0x00000100) -#define BOOTM_STATE_OS_FAKE_GO (0x00000200) /* 'Almost' run the OS */ -#define BOOTM_STATE_OS_GO (0x00000400) -#define BOOTM_STATE_PRE_LOAD 0x00000800 +#define BOOTM_STATE_START 0x00000001 +#define BOOTM_STATE_FINDOS 0x00000002 +#define BOOTM_STATE_FINDOTHER 0x00000004 +#define BOOTM_STATE_LOADOS 0x00000008 +#define BOOTM_STATE_RAMDISK 0x00000010 +#define BOOTM_STATE_FDT 0x00000020 +#define BOOTM_STATE_OS_CMDLINE 0x00000040 +#define BOOTM_STATE_OS_BD_T 0x00000080 +#define BOOTM_STATE_OS_PREP 0x00000100 +#define BOOTM_STATE_OS_FAKE_GO 0x00000200 /* 'Almost' run the OS */ +#define BOOTM_STATE_OS_GO 0x00000400 +#define BOOTM_STATE_PRE_LOAD 0x00000800 int state;
#if defined(CONFIG_LMB) && !defined(USE_HOSTCC)

On Tue, Sep 06, 2022 at 08:26:49PM -0600, Simon Glass wrote:
Tidy up the code style for these.
Signed-off-by: Simon Glass sjg@chromium.org
For the series, except for patch 30 that I have taken v3 of, applied to u-boot/next, thanks!

This is not needed and we should avoid typedefs. Use the struct instead.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
arch/arc/lib/bootm.c | 8 ++++---- arch/arm/lib/bootm.c | 13 +++++++------ arch/arm/mach-k3/common.c | 2 +- arch/arm/mach-socfpga/board.c | 2 +- arch/m68k/lib/bootm.c | 2 +- arch/microblaze/lib/bootm.c | 6 +++--- arch/mips/lib/bootm.c | 16 ++++++++-------- arch/nios2/lib/bootm.c | 2 +- arch/powerpc/lib/bootm.c | 16 ++++++++-------- arch/riscv/lib/bootm.c | 8 ++++---- arch/sandbox/lib/bootm.c | 2 +- arch/sh/lib/bootm.c | 2 +- arch/x86/lib/bootm.c | 6 +++--- arch/xtensa/lib/bootm.c | 2 +- board/synopsys/hsdk/hsdk.c | 2 +- boot/bootm.c | 16 ++++++++-------- boot/bootm_os.c | 28 +++++++++++++-------------- boot/image-board.c | 14 +++++++------- boot/image-fdt.c | 6 +++--- boot/image-fit.c | 16 ++++++++-------- cmd/bootefi.c | 2 +- cmd/booti.c | 2 +- cmd/bootz.c | 2 +- common/spl/spl.c | 2 +- include/bootm.h | 6 +++--- include/image.h | 36 +++++++++++++++++------------------ lib/efi_loader/efi_dt_fixup.c | 2 +- 27 files changed, 111 insertions(+), 110 deletions(-)
diff --git a/arch/arc/lib/bootm.c b/arch/arc/lib/bootm.c index 628addd87ed..07b2c1540d0 100644 --- a/arch/arc/lib/bootm.c +++ b/arch/arc/lib/bootm.c @@ -22,10 +22,10 @@ static int cleanup_before_linux(void) return 0; }
-__weak int board_prep_linux(bootm_headers_t *images) { return 0; } +__weak int board_prep_linux(struct bootm_headers *images) { return 0; }
/* Subcommand: PREP */ -static int boot_prep_linux(bootm_headers_t *images) +static int boot_prep_linux(struct bootm_headers *images) { int ret;
@@ -49,7 +49,7 @@ __weak void board_jump_and_run(ulong entry, int zero, int arch, uint params) }
/* Subcommand: GO */ -static void boot_jump_linux(bootm_headers_t *images, int flag) +static void boot_jump_linux(struct bootm_headers *images, int flag) { ulong kernel_entry; unsigned int r0, r2; @@ -79,7 +79,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) board_jump_and_run(kernel_entry, r0, 0, r2); }
-int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +int do_bootm_linux(int flag, int argc, char *argv[], struct bootm_headers *images) { /* No need for those on ARC */ if ((flag & BOOTM_STATE_OS_BD_T) || (flag & BOOTM_STATE_OS_CMDLINE)) diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 9f086f3b904..e414ef82673 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -192,10 +192,10 @@ static void do_nonsec_virt_switch(void) } #endif
-__weak void board_prep_linux(bootm_headers_t *images) { } +__weak void board_prep_linux(struct bootm_headers *images) { }
/* Subcommand: PREP */ -static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { char *commandline = env_get("bootargs");
@@ -288,7 +288,7 @@ static void switch_to_el1(void) #endif
/* Subcommand: GO */ -static void boot_jump_linux(bootm_headers_t *images, int flag) +static void boot_jump_linux(struct bootm_headers *images, int flag) { #ifdef CONFIG_ARM64 void (*kernel_entry)(void *fdt_addr, void *res0, void *res1, @@ -379,7 +379,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) * they are called if subcommand is equal 0. */ int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* No need for those on ARM */ if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) @@ -401,7 +401,7 @@ int do_bootm_linux(int flag, int argc, char *const argv[], }
#if defined(CONFIG_BOOTM_VXWORKS) -void boot_prep_vxworks(bootm_headers_t *images) +void boot_prep_vxworks(struct bootm_headers *images) { #if defined(CONFIG_OF_LIBFDT) int off; @@ -416,7 +416,8 @@ void boot_prep_vxworks(bootm_headers_t *images) #endif cleanup_before_linux(); } -void boot_jump_vxworks(bootm_headers_t *images) + +void boot_jump_vxworks(struct bootm_headers *images) { #if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI) armv8_setup_psci(); diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 3962f2800f9..14c37acbce7 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -493,7 +493,7 @@ bool soc_is_j7200(void) }
#ifdef CONFIG_ARM64 -void board_prep_linux(bootm_headers_t *images) +void board_prep_linux(struct bootm_headers *images) { debug("Linux kernel Image start = 0x%lx end = 0x%lx\n", images->os.start, images->os.end); diff --git a/arch/arm/mach-socfpga/board.c b/arch/arm/mach-socfpga/board.c index 72671632220..b49006c6c8a 100644 --- a/arch/arm/mach-socfpga/board.c +++ b/arch/arm/mach-socfpga/board.c @@ -114,7 +114,7 @@ void board_fit_image_post_process(const void *fit, int node, void **p_image, #endif
#if !IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_FIT) -void board_prep_linux(bootm_headers_t *images) +void board_prep_linux(struct bootm_headers *images) { if (!images->fit_uname_cfg) { if (IS_ENABLED(CONFIG_SOCFPGA_SECURE_VAB_AUTH) && diff --git a/arch/m68k/lib/bootm.c b/arch/m68k/lib/bootm.c index 9cade929541..c1c9bdceb50 100644 --- a/arch/m68k/lib/bootm.c +++ b/arch/m68k/lib/bootm.c @@ -36,7 +36,7 @@ void arch_lmb_reserve(struct lmb *lmb) }
int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int ret; struct bd_info *kbd; diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index 31b6659cdf7..4a5421497e5 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -37,7 +37,7 @@ void arch_lmb_reserve(struct lmb *lmb) arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096); }
-static void boot_jump_linux(bootm_headers_t *images, int flag) +static void boot_jump_linux(struct bootm_headers *images, int flag) { void (*thekernel)(char *cmdline, ulong rd, ulong dt); ulong dt = (ulong)images->ft_addr; @@ -71,7 +71,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) } }
-static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { if (CONFIG_IS_ENABLED(OF_LIBFDT) && CONFIG_IS_ENABLED(LMB) && images->ft_len) { debug("using: FDT\n"); @@ -83,7 +83,7 @@ static void boot_prep_linux(bootm_headers_t *images) }
int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { images->cmdline_start = (ulong)env_get("bootargs");
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index cab8da4860c..5fda914e6ba 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -71,7 +71,7 @@ static void linux_cmdline_dump(void) debug(" arg %03d: %s\n", i, linux_argv[i]); }
-static void linux_cmdline_legacy(bootm_headers_t *images) +static void linux_cmdline_legacy(struct bootm_headers *images) { const char *bootargs, *next, *quote;
@@ -111,7 +111,7 @@ static void linux_cmdline_legacy(bootm_headers_t *images) } }
-static void linux_cmdline_append(bootm_headers_t *images) +static void linux_cmdline_append(struct bootm_headers *images) { char buf[24]; ulong mem, rd_start, rd_size; @@ -164,7 +164,7 @@ static void linux_env_set(const char *env_name, const char *env_val) } }
-static void linux_env_legacy(bootm_headers_t *images) +static void linux_env_legacy(struct bootm_headers *images) { char env_buf[12]; const char *cp; @@ -213,7 +213,7 @@ static void linux_env_legacy(bootm_headers_t *images) } }
-static int boot_reloc_fdt(bootm_headers_t *images) +static int boot_reloc_fdt(struct bootm_headers *images) { /* * In case of legacy uImage's, relocation of FDT is already done @@ -243,7 +243,7 @@ int arch_fixup_fdt(void *blob) } #endif
-static int boot_setup_fdt(bootm_headers_t *images) +static int boot_setup_fdt(struct bootm_headers *images) { images->initrd_start = virt_to_phys((void *)images->initrd_start); images->initrd_end = virt_to_phys((void *)images->initrd_end); @@ -251,7 +251,7 @@ static int boot_setup_fdt(bootm_headers_t *images) &images->lmb); }
-static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { if (CONFIG_IS_ENABLED(MIPS_BOOT_FDT) && images->ft_len) { boot_reloc_fdt(images); @@ -271,7 +271,7 @@ static void boot_prep_linux(bootm_headers_t *images) } }
-static void boot_jump_linux(bootm_headers_t *images) +static void boot_jump_linux(struct bootm_headers *images) { typedef void __noreturn (*kernel_entry_t)(int, ulong, ulong, ulong); kernel_entry_t kernel = (kernel_entry_t) images->ep; @@ -302,7 +302,7 @@ static void boot_jump_linux(bootm_headers_t *images) }
int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* No need for those on MIPS */ if (flag & BOOTM_STATE_OS_BD_T) diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c index 3cb59bd9777..06c094d0f1c 100644 --- a/arch/nios2/lib/bootm.c +++ b/arch/nios2/lib/bootm.c @@ -17,7 +17,7 @@ DECLARE_GLOBAL_DATA_PTR; #define NIOS_MAGIC 0x534f494e /* enable command line and initrd passing */
int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*kernel)(int, int, int, char *) = (void *)images->ep; char *commandline = env_get("bootargs"); diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index e52aa75703f..8ce4ab3fe39 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -45,7 +45,7 @@ static void set_clocks_in_mhz (struct bd_info *kbd); #define CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE (768*1024*1024) #endif
-static void boot_jump_linux(bootm_headers_t *images) +static void boot_jump_linux(struct bootm_headers *images) { void (*kernel)(struct bd_info *, ulong r4, ulong r5, ulong r6, ulong r7, ulong r8, ulong r9); @@ -151,7 +151,7 @@ void arch_lmb_reserve(struct lmb *lmb) return ; }
-static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { #ifdef CONFIG_MP /* @@ -163,7 +163,7 @@ static void boot_prep_linux(bootm_headers_t *images) #endif }
-static int boot_cmdline_linux(bootm_headers_t *images) +static int boot_cmdline_linux(struct bootm_headers *images) { ulong of_size = images->ft_len; struct lmb *lmb = &images->lmb; @@ -184,7 +184,7 @@ static int boot_cmdline_linux(bootm_headers_t *images) return ret; }
-static int boot_bd_t_linux(bootm_headers_t *images) +static int boot_bd_t_linux(struct bootm_headers *images) { ulong of_size = images->ft_len; struct lmb *lmb = &images->lmb; @@ -205,7 +205,7 @@ static int boot_bd_t_linux(bootm_headers_t *images) return ret; }
-static int boot_body_linux(bootm_headers_t *images) +static int boot_body_linux(struct bootm_headers *images) { int ret;
@@ -224,7 +224,7 @@ static int boot_body_linux(bootm_headers_t *images) }
noinline int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int ret;
@@ -273,7 +273,7 @@ static void set_clocks_in_mhz (struct bd_info *kbd) }
#if defined(CONFIG_BOOTM_VXWORKS) -void boot_prep_vxworks(bootm_headers_t *images) +void boot_prep_vxworks(struct bootm_headers *images) { #if defined(CONFIG_OF_LIBFDT) int off; @@ -305,7 +305,7 @@ void boot_prep_vxworks(bootm_headers_t *images) #endif }
-void boot_jump_vxworks(bootm_headers_t *images) +void boot_jump_vxworks(struct bootm_headers *images) { /* PowerPC VxWorks boot interface conforms to the ePAPR standard * general purpuse registers: diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index 670d9c9ebcf..f5f8b4c7333 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -62,7 +62,7 @@ static void announce_and_cleanup(int fake) cleanup_before_linux(); }
-static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { if (CONFIG_IS_ENABLED(OF_LIBFDT) && CONFIG_IS_ENABLED(LMB) && images->ft_len) { debug("using: FDT\n"); @@ -76,7 +76,7 @@ static void boot_prep_linux(bootm_headers_t *images) } }
-static void boot_jump_linux(bootm_headers_t *images, int flag) +static void boot_jump_linux(struct bootm_headers *images, int flag) { void (*kernel)(ulong hart, void *dtb); int fake = (flag & BOOTM_STATE_OS_FAKE_GO); @@ -107,7 +107,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) }
int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* No need for those on RISC-V */ if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) @@ -129,7 +129,7 @@ int do_bootm_linux(int flag, int argc, char *const argv[], }
int do_bootm_vxworks(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { return do_bootm_linux(flag, argc, argv, images); } diff --git a/arch/sandbox/lib/bootm.c b/arch/sandbox/lib/bootm.c index d1d460b84a4..c1742f94de7 100644 --- a/arch/sandbox/lib/bootm.c +++ b/arch/sandbox/lib/bootm.c @@ -50,7 +50,7 @@ int bootz_setup(ulong image, ulong *start, ulong *end) return ret; }
-int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +int do_bootm_linux(int flag, int argc, char *argv[], struct bootm_headers *images) { if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { bootstage_mark(BOOTSTAGE_ID_RUN_OS); diff --git a/arch/sh/lib/bootm.c b/arch/sh/lib/bootm.c index 7ea04442b87..a5fad6c46c7 100644 --- a/arch/sh/lib/bootm.c +++ b/arch/sh/lib/bootm.c @@ -40,7 +40,7 @@ static unsigned long sh_check_cmd_arg(char *cmdline, char *key, int base) }
int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* Linux kernel load address */ void (*kernel) (void) = (void (*)(void))images->ep; diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c index 1bcdb3e30d2..4fdf1b2365a 100644 --- a/arch/x86/lib/bootm.c +++ b/arch/x86/lib/bootm.c @@ -69,7 +69,7 @@ int arch_fixup_memory_node(void *blob) #endif
/* Subcommand: PREP */ -static int boot_prep_linux(bootm_headers_t *images) +static int boot_prep_linux(struct bootm_headers *images) { char *cmd_line_dest = NULL; image_header_t *hdr; @@ -201,7 +201,7 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit) }
/* Subcommand: GO */ -static int boot_jump_linux(bootm_headers_t *images) +static int boot_jump_linux(struct bootm_headers *images) { debug("## Transferring control to Linux (at address %08lx, kernel %08lx) ...\n", images->ep, images->os.load); @@ -211,7 +211,7 @@ static int boot_jump_linux(bootm_headers_t *images) }
int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* No need for those on x86 */ if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) diff --git a/arch/xtensa/lib/bootm.c b/arch/xtensa/lib/bootm.c index 277af181683..fee33928150 100644 --- a/arch/xtensa/lib/bootm.c +++ b/arch/xtensa/lib/bootm.c @@ -134,7 +134,7 @@ static struct bp_tag *setup_fdt_tag(struct bp_tag *params, void *fdt_start) * Boot Linux. */
-int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +int do_bootm_linux(int flag, int argc, char *argv[], struct bootm_headers *images) { struct bp_tag *params, *params_start; ulong initrd_start, initrd_end; diff --git a/board/synopsys/hsdk/hsdk.c b/board/synopsys/hsdk/hsdk.c index 226fbba6296..4308c7e440a 100644 --- a/board/synopsys/hsdk/hsdk.c +++ b/board/synopsys/hsdk/hsdk.c @@ -844,7 +844,7 @@ static int hsdk_go_run(u32 cpu_start_reg) return 0; }
-int board_prep_linux(bootm_headers_t *images) +int board_prep_linux(struct bootm_headers *images) { int ret, ofst; char mask[15]; diff --git a/boot/bootm.c b/boot/bootm.c index 86dbfbcfed5..73f7552fe4c 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -41,10 +41,10 @@
DECLARE_GLOBAL_DATA_PTR;
-bootm_headers_t images; /* pointers to os/initrd/fdt images */ +struct bootm_headers images; /* pointers to os/initrd/fdt images */
static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], bootm_headers_t *images, + char *const argv[], struct bootm_headers *images, ulong *os_data, ulong *os_len);
__weak void board_quiesce_devices(void) @@ -52,7 +52,7 @@ __weak void board_quiesce_devices(void) }
#ifdef CONFIG_LMB -static void boot_start_lmb(bootm_headers_t *images) +static void boot_start_lmb(struct bootm_headers *images) { ulong mem_start; phys_size_t mem_size; @@ -65,7 +65,7 @@ static void boot_start_lmb(bootm_headers_t *images) } #else #define lmb_reserve(lmb, base, size) -static inline void boot_start_lmb(bootm_headers_t *images) { } +static inline void boot_start_lmb(struct bootm_headers *images) { } #endif
static int bootm_start(struct cmd_tbl *cmdtp, int flag, int argc, @@ -397,7 +397,7 @@ static int handle_decomp_error(int comp_type, size_t uncomp_size, #endif
#ifndef USE_HOSTCC -static int bootm_load_os(bootm_headers_t *images, int boot_progress) +static int bootm_load_os(struct bootm_headers *images, int boot_progress) { image_info_t os = images->os; ulong load = os.load; @@ -688,7 +688,7 @@ int bootm_process_cmdline_env(int flags) * unless the image type is standalone. */ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], int states, bootm_headers_t *images, + char *const argv[], int states, struct bootm_headers *images, int boot_progress) { boot_os_fn *boot_fn; @@ -878,7 +878,7 @@ static image_header_t *image_get_kernel(ulong img_addr, int verify) * address and length, otherwise NULL */ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], bootm_headers_t *images, + char *const argv[], struct bootm_headers *images, ulong *os_data, ulong *os_len) { #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) @@ -1002,7 +1002,7 @@ static int bootm_host_load_image(const void *fit, int req_image_type, { const char *fit_uname_config = NULL; ulong data, len; - bootm_headers_t images; + struct bootm_headers images; int noffset; ulong load_end, buf_size; uint8_t image_type; diff --git a/boot/bootm_os.c b/boot/bootm_os.c index f31820cd07e..bd266e790cd 100644 --- a/boot/bootm_os.c +++ b/boot/bootm_os.c @@ -24,7 +24,7 @@ DECLARE_GLOBAL_DATA_PTR;
static int do_bootm_standalone(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int (*appl)(int, char *const[]);
@@ -65,7 +65,7 @@ static void __maybe_unused fit_unsupported_reset(const char *msg)
#ifdef CONFIG_BOOTM_NETBSD static int do_bootm_netbsd(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*loader)(struct bd_info *, image_header_t *, char *, char *); image_header_t *os_hdr, *hdr; @@ -137,7 +137,7 @@ static int do_bootm_netbsd(int flag, int argc, char *const argv[],
#ifdef CONFIG_BOOTM_RTEMS static int do_bootm_rtems(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(struct bd_info *);
@@ -170,7 +170,7 @@ static int do_bootm_rtems(int flag, int argc, char *const argv[],
#if defined(CONFIG_BOOTM_OSE) static int do_bootm_ose(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(void);
@@ -203,7 +203,7 @@ static int do_bootm_ose(int flag, int argc, char *const argv[],
#if defined(CONFIG_BOOTM_PLAN9) static int do_bootm_plan9(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(void); char *s; @@ -252,7 +252,7 @@ static int do_bootm_plan9(int flag, int argc, char *const argv[], #if defined(CONFIG_BOOTM_VXWORKS) && \ (defined(CONFIG_PPC) || defined(CONFIG_ARM))
-static void do_bootvx_fdt(bootm_headers_t *images) +static void do_bootvx_fdt(struct bootm_headers *images) { #if defined(CONFIG_OF_LIBFDT) int ret; @@ -310,7 +310,7 @@ static void do_bootvx_fdt(bootm_headers_t *images) }
static int do_bootm_vxworks_legacy(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { if (flag != BOOTM_STATE_OS_GO) return 0; @@ -328,7 +328,7 @@ static int do_bootm_vxworks_legacy(int flag, int argc, char *const argv[], }
int do_bootm_vxworks(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { char *bootargs; int pos; @@ -364,7 +364,7 @@ int do_bootm_vxworks(int flag, int argc, char *const argv[],
#if defined(CONFIG_CMD_ELF) static int do_bootm_qnxelf(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { char *local_args[2]; char str[16]; @@ -402,7 +402,7 @@ static int do_bootm_qnxelf(int flag, int argc, char *const argv[],
#ifdef CONFIG_INTEGRITY static int do_bootm_integrity(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(void);
@@ -435,7 +435,7 @@ static int do_bootm_integrity(int flag, int argc, char *const argv[],
#ifdef CONFIG_BOOTM_OPENRTOS static int do_bootm_openrtos(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(void);
@@ -461,7 +461,7 @@ static int do_bootm_openrtos(int flag, int argc, char *const argv[],
#ifdef CONFIG_BOOTM_OPTEE static int do_bootm_tee(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int ret;
@@ -489,7 +489,7 @@ static int do_bootm_tee(int flag, int argc, char *const argv[],
#ifdef CONFIG_BOOTM_EFI static int do_bootm_efi(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int ret; efi_status_t efi_ret; @@ -588,7 +588,7 @@ __weak void board_preboot_os(void) }
int boot_selected_os(int argc, char *const argv[], int state, - bootm_headers_t *images, boot_os_fn *boot_fn) + struct bootm_headers *images, boot_os_fn *boot_fn) { arch_preboot_os(); board_preboot_os(); diff --git a/boot/image-board.c b/boot/image-board.c index 1be0a359aba..b61d64c65f8 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -301,7 +301,7 @@ int genimg_get_format(const void *img_addr) * 0, no FIT support or no configuration found * 1, configuration found */ -int genimg_has_config(bootm_headers_t *images) +int genimg_has_config(struct bootm_headers *images) { if (CONFIG_IS_ENABLED(FIT) && images->fit_uname_cfg) return 1; @@ -320,7 +320,7 @@ int genimg_has_config(bootm_headers_t *images) * Return: 0 if OK, -ENOPKG if no ramdisk (but an error should not be reported), * other -ve value on other error */ -static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, +static int select_ramdisk(struct bootm_headers *images, const char *select, u8 arch, ulong *rd_datap, ulong *rd_lenp) { const char *fit_uname_config; @@ -482,7 +482,7 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, * 1, if ramdisk image is found but corrupted, or invalid * rd_start and rd_end are set to 0 if no ramdisk exists */ -int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_ramdisk(int argc, char *const argv[], struct bootm_headers *images, u8 arch, ulong *rd_start, ulong *rd_end) { ulong rd_data, rd_len; @@ -646,7 +646,7 @@ error: return -1; }
-int boot_get_setup(bootm_headers_t *images, u8 arch, +int boot_get_setup(struct bootm_headers *images, u8 arch, ulong *setup_start, ulong *setup_len) { if (!CONFIG_IS_ENABLED(FIT)) @@ -655,7 +655,7 @@ int boot_get_setup(bootm_headers_t *images, u8 arch, return boot_get_setup_fit(images, arch, setup_start, setup_len); }
-int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_fpga(int argc, char *const argv[], struct bootm_headers *images, u8 arch, const ulong *ld_start, ulong * const ld_len) { ulong tmp_img_addr, img_data, img_len; @@ -758,7 +758,7 @@ static void fit_loadable_process(u8 img_type, fit_loadable_handler->handler(img_data, img_len); }
-int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_loadable(int argc, char *const argv[], struct bootm_headers *images, u8 arch, const ulong *ld_start, ulong * const ld_len) { /* @@ -919,7 +919,7 @@ int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd) return 0; }
-int image_setup_linux(bootm_headers_t *images) +int image_setup_linux(struct bootm_headers *images) { ulong of_size = images->ft_len; char **of_flat_tree = &images->ft_addr; diff --git a/boot/image-fdt.c b/boot/image-fdt.c index e75d051c872..78417bd8898 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -291,7 +291,7 @@ error: * other -ve value on other error */
-static int select_fdt(bootm_headers_t *images, const char *select, u8 arch, +static int select_fdt(struct bootm_headers *images, const char *select, u8 arch, ulong *fdt_addrp) { const char *buf; @@ -470,7 +470,7 @@ static int select_fdt(bootm_headers_t *images, const char *select, u8 arch, * of_flat_tree and of_size are set to 0 if no fdt exists */ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, - bootm_headers_t *images, char **of_flat_tree, ulong *of_size) + struct bootm_headers *images, char **of_flat_tree, ulong *of_size) { ulong img_addr; ulong fdt_addr; @@ -602,7 +602,7 @@ __weak int arch_fixup_fdt(void *blob) return 0; }
-int image_setup_libfdt(bootm_headers_t *images, void *blob, +int image_setup_libfdt(struct bootm_headers *images, void *blob, int of_size, struct lmb *lmb) { ulong *initrd_start = &images->initrd_start; diff --git a/boot/image-fit.c b/boot/image-fit.c index df3e5df8836..a7acd762272 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -1933,8 +1933,8 @@ static int fit_image_select(const void *fit, int rd_noffset, int verify) return 0; }
-int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name, - ulong addr) +int fit_get_node_from_config(struct bootm_headers *images, + const char *prop_name, ulong addr) { int cfg_noffset; void *fit_hdr; @@ -1995,7 +1995,7 @@ static const char *fit_get_image_type_property(int type) return "unknown"; }
-int fit_image_load(bootm_headers_t *images, ulong addr, +int fit_image_load(struct bootm_headers *images, ulong addr, const char **fit_unamep, const char **fit_uname_configp, int arch, int image_type, int bootstage_id, enum fit_load_op load_op, ulong *datap, ulong *lenp) @@ -2253,8 +2253,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr, return noffset; }
-int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, - ulong *setup_start, ulong *setup_len) +int boot_get_setup_fit(struct bootm_headers *images, uint8_t arch, + ulong *setup_start, ulong *setup_len) { int noffset; ulong addr; @@ -2274,9 +2274,9 @@ int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, }
#ifndef USE_HOSTCC -int boot_get_fdt_fit(bootm_headers_t *images, ulong addr, - const char **fit_unamep, const char **fit_uname_configp, - int arch, ulong *datap, ulong *lenp) +int boot_get_fdt_fit(struct bootm_headers *images, ulong addr, + const char **fit_unamep, const char **fit_uname_configp, + int arch, ulong *datap, ulong *lenp) { int fdt_noffset, cfg_noffset, count; const void *fit; diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 8ab0ff5a642..3041873afbb 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -281,7 +281,7 @@ efi_status_t efi_install_fdt(void *fdt) return EFI_SUCCESS; } #else - bootm_headers_t img = { 0 }; + struct bootm_headers img = { 0 }; efi_status_t ret;
if (fdt == EFI_FDT_USE_INTERNAL) { diff --git a/cmd/booti.c b/cmd/booti.c index 397d4b83236..6ac39193db8 100644 --- a/cmd/booti.c +++ b/cmd/booti.c @@ -21,7 +21,7 @@ DECLARE_GLOBAL_DATA_PTR; * Image booting support */ static int booti_start(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], bootm_headers_t *images) + char *const argv[], struct bootm_headers *images) { int ret; ulong ld; diff --git a/cmd/bootz.c b/cmd/bootz.c index 4f024bde5fe..f1423573d23 100644 --- a/cmd/bootz.c +++ b/cmd/bootz.c @@ -25,7 +25,7 @@ int __weak bootz_setup(ulong image, ulong *start, ulong *end) * zImage booting support */ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], bootm_headers_t *images) + char *const argv[], struct bootm_headers *images) { int ret; ulong zi_start, zi_end; diff --git a/common/spl/spl.c b/common/spl/spl.c index 29e0898f03d..13a343b9170 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -255,7 +255,7 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image) static int spl_load_fit_image(struct spl_image_info *spl_image, const struct image_header *header) { - bootm_headers_t images; + struct bootm_headers images; const char *fit_uname_config = NULL; uintptr_t fdt_hack; const char *uname; diff --git a/include/bootm.h b/include/bootm.h index 7ed5650fcaa..044a4797ed3 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -33,7 +33,7 @@ struct cmd_tbl; * not return. */ typedef int boot_os_fn(int flag, int argc, char *const argv[], - bootm_headers_t *images); + struct bootm_headers *images);
extern boot_os_fn do_bootm_linux; extern boot_os_fn do_bootm_vxworks; @@ -47,7 +47,7 @@ int bootm_host_load_images(const void *fit, int cfg_noffset); #endif
int boot_selected_os(int argc, char *const argv[], int state, - bootm_headers_t *images, boot_os_fn *boot_fn); + struct bootm_headers *images, boot_os_fn *boot_fn);
ulong bootm_disable_interrupts(void);
@@ -56,7 +56,7 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, ulong size);
int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], int states, bootm_headers_t *images, + char *const argv[], int states, struct bootm_headers *images, int boot_progress);
void arch_preboot_os(void); diff --git a/include/image.h b/include/image.h index 5e81fad8774..a725892cbed 100644 --- a/include/image.h +++ b/include/image.h @@ -290,7 +290,7 @@ typedef struct image_info { * Legacy and FIT format headers used by do_bootm() and do_bootm_<os>() * routines. */ -typedef struct bootm_headers { +struct bootm_headers { /* * Legacy os image header, if it is a multi component image * then boot_get_ramdisk() and get_fdt() will attempt to get @@ -358,7 +358,7 @@ typedef struct bootm_headers { #if defined(CONFIG_LMB) && !defined(USE_HOSTCC) struct lmb lmb; /* for memory mgmt */ #endif -} bootm_headers_t; +};
#ifdef CONFIG_LMB #define images_lmb(_images) (&(_images)->lmb) @@ -366,7 +366,7 @@ typedef struct bootm_headers { #define images_lmb(_images) NULL #endif
-extern bootm_headers_t images; +extern struct bootm_headers images;
/* * Some systems (for example LWMON) have very short watchdog periods; @@ -530,7 +530,7 @@ enum fit_load_op { FIT_LOAD_REQUIRED, /* Must be provided */ };
-int boot_get_setup(bootm_headers_t *images, uint8_t arch, ulong *setup_start, +int boot_get_setup(struct bootm_headers *images, uint8_t arch, ulong *setup_start, ulong *setup_len);
/* Image format types, returned by _get_format() routine */ @@ -544,11 +544,11 @@ ulong genimg_get_kernel_addr_fit(char * const img_addr, const char **fit_uname_kernel); ulong genimg_get_kernel_addr(char * const img_addr); int genimg_get_format(const void *img_addr); -int genimg_has_config(bootm_headers_t *images); +int genimg_has_config(struct bootm_headers *images);
-int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_fpga(int argc, char *const argv[], struct bootm_headers *images, uint8_t arch, const ulong *ld_start, ulong * const ld_len); -int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_ramdisk(int argc, char *const argv[], struct bootm_headers *images, uint8_t arch, ulong *rd_start, ulong *rd_end);
/** @@ -572,10 +572,10 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, * 0, if only valid images or no images are found * error code, if an error occurs during fit_image_load */ -int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_loadable(int argc, char *const argv[], struct bootm_headers *images, uint8_t arch, const ulong *ld_start, ulong *const ld_len);
-int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, +int boot_get_setup_fit(struct bootm_headers *images, uint8_t arch, ulong *setup_start, ulong *setup_len);
/** @@ -599,9 +599,9 @@ int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, * * Return: node offset of base image, or -ve error code on error */ -int boot_get_fdt_fit(bootm_headers_t *images, ulong addr, - const char **fit_unamep, const char **fit_uname_configp, - int arch, ulong *datap, ulong *lenp); +int boot_get_fdt_fit(struct bootm_headers *images, ulong addr, + const char **fit_unamep, const char **fit_uname_configp, + int arch, ulong *datap, ulong *lenp);
/** * fit_image_load() - load an image from a FIT @@ -633,7 +633,7 @@ int boot_get_fdt_fit(bootm_headers_t *images, ulong addr, * @param lenp Returns length of loaded image * Return: node offset of image, or -ve error code on error */ -int fit_image_load(bootm_headers_t *images, ulong addr, +int fit_image_load(struct bootm_headers *images, ulong addr, const char **fit_unamep, const char **fit_uname_configp, int arch, int image_type, int bootstage_id, enum fit_load_op load_op, ulong *datap, ulong *lenp); @@ -677,11 +677,11 @@ int image_source_script(ulong addr, const char *fit_uname); * @param prop_name Property name to look up (FIT_..._PROP) * @param addr Address of FIT in memory */ -int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name, - ulong addr); +int fit_get_node_from_config(struct bootm_headers *images, + const char *prop_name, ulong addr);
int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, - bootm_headers_t *images, + struct bootm_headers *images, char **of_flat_tree, ulong *of_size); void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob); int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size); @@ -871,7 +871,7 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, * @lmb: Points to logical memory block structure * Return: 0 if ok, <0 on failure */ -int image_setup_libfdt(bootm_headers_t *images, void *blob, +int image_setup_libfdt(struct bootm_headers *images, void *blob, int of_size, struct lmb *lmb);
/** @@ -883,7 +883,7 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob, * @param images Images information * Return: 0 if ok, <0 on failure */ -int image_setup_linux(bootm_headers_t *images); +int image_setup_linux(struct bootm_headers *images);
/** * bootz_setup() - Extract stat and size of a Linux xImage diff --git a/lib/efi_loader/efi_dt_fixup.c b/lib/efi_loader/efi_dt_fixup.c index d3923e5dba1..838023c78ff 100644 --- a/lib/efi_loader/efi_dt_fixup.c +++ b/lib/efi_loader/efi_dt_fixup.c @@ -145,7 +145,7 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb, efi_status_t ret; size_t required_size; size_t total_size; - bootm_headers_t img = { 0 }; + struct bootm_headers img = { 0 };
EFI_ENTRY("%p, %p, %p, %d", this, dtb, buffer_size, flags);

This is not needed and we should avoid typedefs. Use the struct instead.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
boot/bootm.c | 2 +- include/image.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/boot/bootm.c b/boot/bootm.c index 73f7552fe4c..93bdbb0455c 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -399,7 +399,7 @@ static int handle_decomp_error(int comp_type, size_t uncomp_size, #ifndef USE_HOSTCC static int bootm_load_os(struct bootm_headers *images, int boot_progress) { - image_info_t os = images->os; + struct image_info os = images->os; ulong load = os.load; ulong load_end; ulong blob_start = os.start; diff --git a/include/image.h b/include/image.h index a725892cbed..e1a65cce7ba 100644 --- a/include/image.h +++ b/include/image.h @@ -278,13 +278,13 @@ typedef struct image_header { uint8_t ih_name[IH_NMLEN]; /* Image Name */ } image_header_t;
-typedef struct image_info { +struct image_info { ulong start, end; /* start/end of blob */ ulong image_start, image_len; /* start of image within blob, len of image */ ulong load; /* load addr for the image */ uint8_t comp, type, os; /* compression, type of image, os type */ uint8_t arch; /* CPU architecture */ -} image_info_t; +};
/* * Legacy and FIT format headers used by do_bootm() and do_bootm_<os>() @@ -324,7 +324,7 @@ struct bootm_headers { int fit_noffset_setup;/* x86 setup subimage node offset */
#ifndef USE_HOSTCC - image_info_t os; /* os image info */ + struct image_info os; /* os image info */ ulong ep; /* entry point of OS */
ulong rd_start, rd_end;/* ramdisk start/end */

This is not needed and we should avoid typedefs. Use the struct instead and rename it to indicate that it really is a legacy struct.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
arch/arm/mach-aspeed/ast2600/spl.c | 4 +- arch/arm/mach-imx/hab.c | 2 +- arch/arm/mach-imx/spl_imx_romapi.c | 6 +-- arch/arm/mach-k3/sysfw-loader.c | 6 +-- arch/arm/mach-keystone/cmd_mon.c | 6 +-- arch/arm/mach-sunxi/spl_spi_sunxi.c | 4 +- arch/mips/mach-jz47xx/jz4780/jz4780.c | 6 +-- arch/mips/mach-mtmips/mt7621/spl/spl.c | 4 +- arch/mips/mach-mtmips/mt7621/tpl/tpl.c | 4 +- arch/x86/lib/bootm.c | 2 +- board/ti/ks2_evm/board.c | 4 +- boot/boot_fit.c | 4 +- boot/bootm.c | 8 ++-- boot/bootm_os.c | 7 ++-- boot/image-android.c | 6 +-- boot/image-board.c | 12 +++--- boot/image-fdt.c | 6 +-- boot/image.c | 14 +++---- cmd/bootm.c | 4 +- cmd/disk.c | 4 +- cmd/fpga.c | 2 +- cmd/nand.c | 4 +- cmd/source.c | 2 +- cmd/ximg.c | 4 +- common/spl/spl.c | 8 ++-- common/spl/spl_ext.c | 4 +- common/spl/spl_fat.c | 6 +-- common/spl/spl_legacy.c | 8 ++-- common/spl/spl_mmc.c | 4 +- common/spl/spl_nand.c | 4 +- common/spl/spl_net.c | 2 +- common/spl/spl_nor.c | 8 ++-- common/spl/spl_onenand.c | 2 +- common/spl/spl_ram.c | 8 ++-- common/spl/spl_sata.c | 2 +- common/spl/spl_semihosting.c | 4 +- common/spl/spl_spi.c | 6 +-- common/spl/spl_ubi.c | 4 +- common/spl/spl_xip.c | 2 +- common/spl/spl_ymodem.c | 14 +++---- common/splash_source.c | 6 +-- doc/uImage.FIT/source_file_format.txt | 2 +- drivers/fpga/socfpga_arria10.c | 4 +- drivers/usb/gadget/f_sdp.c | 2 +- include/configs/uniphier.h | 2 +- include/image.h | 52 ++++++++++++++------------ include/spl.h | 8 ++-- include/tee/optee.h | 4 +- test/image/spl_load.c | 4 +- tools/binman/ftest.py | 4 +- tools/default_image.c | 31 ++++++++------- tools/fit_image.c | 4 +- tools/imx8mimage.c | 8 ++-- tools/mkimage.c | 2 +- tools/mtk_image.c | 10 ++--- 55 files changed, 179 insertions(+), 175 deletions(-)
diff --git a/arch/arm/mach-aspeed/ast2600/spl.c b/arch/arm/mach-aspeed/ast2600/spl.c index 53c8a15bf9c..0952e73a457 100644 --- a/arch/arm/mach-aspeed/ast2600/spl.c +++ b/arch/arm/mach-aspeed/ast2600/spl.c @@ -56,9 +56,9 @@ out: return BOOT_DEVICE_RAM; }
-struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { - return (struct image_header *)(CONFIG_SYS_LOAD_ADDR); + return (struct legacy_img_hdr *)(CONFIG_SYS_LOAD_ADDR); }
#ifdef CONFIG_SPL_OS_BOOT diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 0d1a7766be8..c6747b257c4 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -589,7 +589,7 @@ static ulong get_image_ivt_offset(ulong img_addr) switch (genimg_get_format(buf)) { #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: - return (image_get_image_size((image_header_t *)img_addr) + return (image_get_image_size((struct legacy_img_hdr *)img_addr) + 0x1000 - 1) & ~(0x1000 - 1); #endif #if CONFIG_IS_ENABLED(FIT) diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c index cc3c1251dc9..8ab9f2f052a 100644 --- a/arch/arm/mach-imx/spl_imx_romapi.c +++ b/arch/arm/mach-imx/spl_imx_romapi.c @@ -72,7 +72,7 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image, int ret; u32 offset; u32 pagesize, size; - struct image_header *header; + struct legacy_img_hdr *header; u32 image_offset;
ret = rom_api_query_boot_infor(QUERY_IVT_OFF, &offset); @@ -84,14 +84,14 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image, return -1; }
- header = (struct image_header *)(CONFIG_SPL_IMX_ROMAPI_LOADADDR); + header = (struct legacy_img_hdr *)(CONFIG_SPL_IMX_ROMAPI_LOADADDR);
printf("image offset 0x%x, pagesize 0x%x, ivt offset 0x%x\n", image_offset, pagesize, offset);
offset = spl_romapi_get_uboot_base(image_offset, rom_bt_dev);
- size = ALIGN(sizeof(struct image_header), pagesize); + size = ALIGN(sizeof(struct legacy_img_hdr), pagesize); ret = rom_api_download_image((u8 *)header, offset, size);
if (ret != ROM_API_OKAY) { diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c index b3beeca9472..aea640b5700 100644 --- a/arch/arm/mach-k3/sysfw-loader.c +++ b/arch/arm/mach-k3/sysfw-loader.c @@ -88,10 +88,10 @@ static void *sysfw_load_address; * Populate SPL hook to override the default load address used by the SPL * loader function with a custom address for SYSFW loading. */ -struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { if (sysfw_loaded) - return (struct image_header *)(CONFIG_SYS_TEXT_BASE + offset); + return (struct legacy_img_hdr *)(CONFIG_SYS_TEXT_BASE + offset); else if (sysfw_load_address) return sysfw_load_address; else @@ -490,7 +490,7 @@ void k3_sysfw_loader(bool rom_loaded_sysfw, sysfw_loaded = true;
/* Ensure the SYSFW image is in FIT format */ - if (image_get_magic((const image_header_t *)sysfw_load_address) != + if (image_get_magic((const struct legacy_img_hdr *)sysfw_load_address) != FDT_MAGIC) panic("SYSFW image not in FIT format!\n");
diff --git a/arch/arm/mach-keystone/cmd_mon.c b/arch/arm/mach-keystone/cmd_mon.c index e26296b6da6..4734e4c7143 100644 --- a/arch/arm/mach-keystone/cmd_mon.c +++ b/arch/arm/mach-keystone/cmd_mon.c @@ -17,7 +17,7 @@ static int do_mon_install(struct cmd_tbl *cmdtp, int flag, int argc, { u32 addr, dpsc_base = 0x1E80000, freq, load_addr, size; int rcode = 0; - struct image_header *header; + struct legacy_img_hdr *header; u32 ecrypt_bm_addr = 0;
if (argc < 2) @@ -27,7 +27,7 @@ static int do_mon_install(struct cmd_tbl *cmdtp, int flag, int argc,
addr = hextoul(argv[1], NULL);
- header = (struct image_header *)addr; + header = (struct legacy_img_hdr *)addr;
if (image_get_magic(header) != IH_MAGIC) { printf("## Please update monitor image\n"); @@ -36,7 +36,7 @@ static int do_mon_install(struct cmd_tbl *cmdtp, int flag, int argc,
load_addr = image_get_load(header); size = image_get_data_size(header); - memcpy((void *)load_addr, (void *)(addr + sizeof(struct image_header)), + memcpy((void *)load_addr, (void *)(addr + sizeof(struct legacy_img_hdr)), size);
if (argc >= 3) diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c index de9aa68c4ac..925bf85f2d2 100644 --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c @@ -335,10 +335,10 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { int ret = 0; - struct image_header *header; - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); + struct legacy_img_hdr *header; uint32_t load_offset = sunxi_get_spl_size();
+ header = (struct legacy_img_hdr *)CONFIG_SYS_TEXT_BASE; load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
spi0_init(); diff --git a/arch/mips/mach-jz47xx/jz4780/jz4780.c b/arch/mips/mach-jz47xx/jz4780/jz4780.c index fefba12873b..310c0934a44 100644 --- a/arch/mips/mach-jz47xx/jz4780/jz4780.c +++ b/arch/mips/mach-jz47xx/jz4780/jz4780.c @@ -30,7 +30,7 @@ void board_init_f(ulong dummy) typedef void __noreturn (*image_entry_noargs_t)(void); struct mmc *mmc; unsigned long count; - struct image_header *header; + struct legacy_img_hdr *header; int ret;
/* Set global data pointer */ @@ -58,8 +58,8 @@ void board_init_f(ulong dummy) if (ret) hang();
- header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - - sizeof(struct image_header)); + header = (struct legacy_img_hdr *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct legacy_img_hdr));
count = blk_dread(mmc_get_blk_desc(mmc), CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, diff --git a/arch/mips/mach-mtmips/mt7621/spl/spl.c b/arch/mips/mach-mtmips/mt7621/spl/spl.c index 91eebc6c1fb..aa5b267bb96 100644 --- a/arch/mips/mach-mtmips/mt7621/spl/spl.c +++ b/arch/mips/mach-mtmips/mt7621/spl/spl.c @@ -64,7 +64,7 @@ void board_boot_order(u32 *spl_boot_list) unsigned long spl_nor_get_uboot_base(void) { const struct tpl_info *tpli; - const image_header_t *hdr; + const struct legacy_img_hdr *hdr; u32 addr;
addr = FLASH_MMAP_BASE + TPL_INFO_OFFSET; @@ -72,7 +72,7 @@ unsigned long spl_nor_get_uboot_base(void)
if (tpli->magic == TPL_INFO_MAGIC) { addr = FLASH_MMAP_BASE + tpli->size; - hdr = (const image_header_t *)KSEG1ADDR(addr); + hdr = (const struct legacy_img_hdr *)KSEG1ADDR(addr);
if (image_get_magic(hdr) == IH_MAGIC) { addr += sizeof(*hdr) + image_get_size(hdr); diff --git a/arch/mips/mach-mtmips/mt7621/tpl/tpl.c b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c index 2a828907a34..d77592da5fe 100644 --- a/arch/mips/mach-mtmips/mt7621/tpl/tpl.c +++ b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c @@ -116,7 +116,7 @@ static void mt7621_cache_init(void)
void __noreturn tpl_main(void) { - const image_header_t *hdr = (const image_header_t *)__image_copy_end; + const struct legacy_img_hdr *hdr = (const struct legacy_img_hdr *)__image_copy_end; image_entry_noargs_t image_entry; u32 loadaddr, size; uintptr_t data; @@ -132,7 +132,7 @@ void __noreturn tpl_main(void) image_entry = (image_entry_noargs_t)image_get_ep(hdr);
/* Load TPL image to L2 cache */ - data = (uintptr_t)__image_copy_end + sizeof(struct image_header); + data = (uintptr_t)__image_copy_end + sizeof(struct legacy_img_hdr); fill_lock_l2cache(data, loadaddr, size);
/* Jump to SPL */ diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c index 4fdf1b2365a..eafcddfa24b 100644 --- a/arch/x86/lib/bootm.c +++ b/arch/x86/lib/bootm.c @@ -72,7 +72,7 @@ int arch_fixup_memory_node(void *blob) static int boot_prep_linux(struct bootm_headers *images) { char *cmd_line_dest = NULL; - image_header_t *hdr; + struct legacy_img_hdr *hdr; int is_zimage = 0; void *data = NULL; size_t len; diff --git a/board/ti/ks2_evm/board.c b/board/ti/ks2_evm/board.c index 0c5c2c9146f..5ba3aa35a9f 100644 --- a/board/ti/ks2_evm/board.c +++ b/board/ti/ks2_evm/board.c @@ -64,9 +64,9 @@ int dram_init(void) return 0; }
-struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { - return (struct image_header *)(CONFIG_SYS_TEXT_BASE); + return (struct legacy_img_hdr *)(CONFIG_SYS_TEXT_BASE); }
int board_init(void) diff --git a/boot/boot_fit.c b/boot/boot_fit.c index dfc2a3117d1..4a493b36847 100644 --- a/boot/boot_fit.c +++ b/boot/boot_fit.c @@ -57,14 +57,14 @@ static int fdt_offset(const void *fit)
void *locate_dtb_in_fit(const void *fit) { - struct image_header *header; + struct legacy_img_hdr *header; int size; int ret;
size = fdt_totalsize(fit); size = (size + 3) & ~3;
- header = (struct image_header *)fit; + header = (struct legacy_img_hdr *)fit;
if (image_get_magic(header) != FDT_MAGIC) { debug("No FIT image appended to U-boot\n"); diff --git a/boot/bootm.c b/boot/bootm.c index 93bdbb0455c..f6713807fda 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -825,9 +825,9 @@ err: * pointer to a legacy image header if valid image was found * otherwise return NULL */ -static image_header_t *image_get_kernel(ulong img_addr, int verify) +static struct legacy_img_hdr *image_get_kernel(ulong img_addr, int verify) { - image_header_t *hdr = (image_header_t *)img_addr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)img_addr;
if (!image_check_magic(hdr)) { puts("Bad Magic Number\n"); @@ -882,7 +882,7 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, ulong *os_data, ulong *os_len) { #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) - image_header_t *hdr; + struct legacy_img_hdr *hdr; #endif ulong img_addr; const void *buf; @@ -940,7 +940,7 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, * kernel decompression. */ memmove(&images->legacy_hdr_os_copy, hdr, - sizeof(image_header_t)); + sizeof(struct legacy_img_hdr));
/* save pointer to image header */ images->legacy_hdr_os = hdr; diff --git a/boot/bootm_os.c b/boot/bootm_os.c index bd266e790cd..3e651b38ddb 100644 --- a/boot/bootm_os.c +++ b/boot/bootm_os.c @@ -67,8 +67,9 @@ static void __maybe_unused fit_unsupported_reset(const char *msg) static int do_bootm_netbsd(int flag, int argc, char *const argv[], struct bootm_headers *images) { - void (*loader)(struct bd_info *, image_header_t *, char *, char *); - image_header_t *os_hdr, *hdr; + void (*loader)(struct bd_info *bd, struct legacy_img_hdr *hdr, + char *console, char *cmdline); + struct legacy_img_hdr *os_hdr, *hdr; ulong kernel_data, kernel_len; char *cmdline;
@@ -115,7 +116,7 @@ static int do_bootm_netbsd(int flag, int argc, char *const argv[], cmdline = ""; }
- loader = (void (*)(struct bd_info *, image_header_t *, char *, char *))images->ep; + loader = (void (*)(struct bd_info *, struct legacy_img_hdr *, char *, char *))images->ep;
printf("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n", (ulong)loader); diff --git a/boot/image-android.c b/boot/image-android.c index 1fbbbba1eb0..2628db37412 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -63,7 +63,7 @@ int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify, ulong *os_data, ulong *os_len) { u32 kernel_addr = android_image_get_kernel_addr(hdr); - const struct image_header *ihdr = (const struct image_header *) + const struct legacy_img_hdr *ihdr = (const struct legacy_img_hdr *) ((uintptr_t)hdr + hdr->page_size);
/* @@ -159,8 +159,8 @@ ulong android_image_get_kcomp(const struct andr_img_hdr *hdr) { const void *p = (void *)((uintptr_t)hdr + hdr->page_size);
- if (image_get_magic((image_header_t *)p) == IH_MAGIC) - return image_get_comp((image_header_t *)p); + if (image_get_magic((struct legacy_img_hdr *)p) == IH_MAGIC) + return image_get_comp((struct legacy_img_hdr *)p); else if (get_unaligned_le32(p) == LZ4F_MAGIC) return IH_COMP_LZ4; else diff --git a/boot/image-board.c b/boot/image-board.c index b61d64c65f8..44b57768f00 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -40,10 +40,10 @@ DECLARE_GLOBAL_DATA_PTR; * pointer to a ramdisk image header, if image was found and valid * otherwise, return NULL */ -static const image_header_t *image_get_ramdisk(ulong rd_addr, u8 arch, - int verify) +static const struct legacy_img_hdr *image_get_ramdisk(ulong rd_addr, u8 arch, + int verify) { - const image_header_t *rd_hdr = (const image_header_t *)rd_addr; + const struct legacy_img_hdr *rd_hdr = (const struct legacy_img_hdr *)rd_addr;
if (!image_check_magic(rd_hdr)) { puts("Bad Magic Number\n"); @@ -273,9 +273,9 @@ ulong genimg_get_kernel_addr(char * const img_addr) int genimg_get_format(const void *img_addr) { if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) { - const image_header_t *hdr; + const struct legacy_img_hdr *hdr;
- hdr = (const image_header_t *)img_addr; + hdr = (const struct legacy_img_hdr *)img_addr; if (image_check_magic(hdr)) return IMAGE_FORMAT_LEGACY; } @@ -389,7 +389,7 @@ static int select_ramdisk(struct bootm_headers *images, const char *select, u8 a switch (genimg_get_format(buf)) { case IMAGE_FORMAT_LEGACY: if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) { - const image_header_t *rd_hdr; + const struct legacy_img_hdr *rd_hdr;
printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n", rd_addr); diff --git a/boot/image-fdt.c b/boot/image-fdt.c index 78417bd8898..ca51796322d 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -37,9 +37,9 @@ static void fdt_error(const char *msg) }
#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) -static const image_header_t *image_get_fdt(ulong fdt_addr) +static const struct legacy_img_hdr *image_get_fdt(ulong fdt_addr) { - const image_header_t *fdt_hdr = map_sysmem(fdt_addr, 0); + const struct legacy_img_hdr *fdt_hdr = map_sysmem(fdt_addr, 0);
image_print_contents(fdt_hdr);
@@ -358,7 +358,7 @@ static int select_fdt(struct bootm_headers *images, const char *select, u8 arch, switch (genimg_get_format(buf)) { #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: { - const image_header_t *fdt_hdr; + const struct legacy_img_hdr *fdt_hdr; ulong load, load_end; ulong image_start, image_data, image_end;
diff --git a/boot/image.c b/boot/image.c index a0d0cc2403d..9f95b3260a8 100644 --- a/boot/image.c +++ b/boot/image.c @@ -220,11 +220,11 @@ static const struct table_info table_info[IH_COUNT] = { /*****************************************************************************/ /* Legacy format routines */ /*****************************************************************************/ -int image_check_hcrc(const image_header_t *hdr) +int image_check_hcrc(const struct legacy_img_hdr *hdr) { ulong hcrc; ulong len = image_get_header_size(); - image_header_t header; + struct legacy_img_hdr header;
/* Copy header so we can blank CRC field for re-calculation */ memmove(&header, (char *)hdr, image_get_header_size()); @@ -235,7 +235,7 @@ int image_check_hcrc(const image_header_t *hdr) return (hcrc == image_get_hcrc(hdr)); }
-int image_check_dcrc(const image_header_t *hdr) +int image_check_dcrc(const struct legacy_img_hdr *hdr) { ulong data = image_get_data(hdr); ulong len = image_get_data_size(hdr); @@ -257,7 +257,7 @@ int image_check_dcrc(const image_header_t *hdr) * returns: * number of components */ -ulong image_multi_count(const image_header_t *hdr) +ulong image_multi_count(const struct legacy_img_hdr *hdr) { ulong i, count = 0; uint32_t *size; @@ -290,7 +290,7 @@ ulong image_multi_count(const image_header_t *hdr) * data address and size of the component, if idx is valid * 0 in data and len, if idx is out of range */ -void image_multi_getimg(const image_header_t *hdr, ulong idx, +void image_multi_getimg(const struct legacy_img_hdr *hdr, ulong idx, ulong *data, ulong *len) { int i; @@ -326,7 +326,7 @@ void image_multi_getimg(const image_header_t *hdr, ulong idx, } }
-static void image_print_type(const image_header_t *hdr) +static void image_print_type(const struct legacy_img_hdr *hdr) { const char __maybe_unused *os, *arch, *type, *comp;
@@ -352,7 +352,7 @@ static void image_print_type(const image_header_t *hdr) */ void image_print_contents(const void *ptr) { - const image_header_t *hdr = (const image_header_t *)ptr; + const struct legacy_img_hdr *hdr = (const struct legacy_img_hdr *)ptr; const char __maybe_unused *p;
p = IMAGE_INDENT_STRING; diff --git a/cmd/bootm.c b/cmd/bootm.c index 9fe8ce4a27c..d764a27002d 100644 --- a/cmd/bootm.c +++ b/cmd/bootm.c @@ -511,7 +511,7 @@ static int do_imls_nand(void) continue;
for (off = 0; off < mtd->size; off += mtd->erasesize) { - const image_header_t *header; + const struct legacy_img_hdr *header; int ret;
if (nand_block_isbad(mtd, off)) @@ -529,7 +529,7 @@ static int do_imls_nand(void) switch (genimg_get_format(buffer)) { #if defined(CONFIG_LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: - header = (const image_header_t *)buffer; + header = (const struct legacy_img_hdr *)buffer;
len = image_get_image_size(header); nand_imls_legacyimage(mtd, nand_dev, off, len); diff --git a/cmd/disk.c b/cmd/disk.c index cb3b990ba3a..3d7bc2f6018 100644 --- a/cmd/disk.c +++ b/cmd/disk.c @@ -20,7 +20,7 @@ int common_diskboot(struct cmd_tbl *cmdtp, const char *intf, int argc, ulong cnt; struct disk_partition info; #if defined(CONFIG_LEGACY_IMAGE_FORMAT) - image_header_t *hdr; + struct legacy_img_hdr *hdr; #endif struct blk_desc *dev_desc;
@@ -68,7 +68,7 @@ int common_diskboot(struct cmd_tbl *cmdtp, const char *intf, int argc, switch (genimg_get_format((void *) addr)) { #if defined(CONFIG_LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: - hdr = (image_header_t *) addr; + hdr = (struct legacy_img_hdr *)addr;
bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT);
diff --git a/cmd/fpga.c b/cmd/fpga.c index c4651dd403e..2d972d992bb 100644 --- a/cmd/fpga.c +++ b/cmd/fpga.c @@ -288,7 +288,7 @@ static int do_fpga_loadmk(struct cmd_tbl *cmdtp, int flag, int argc, #if defined(CONFIG_LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: { - image_header_t *hdr = (image_header_t *)fpga_data; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)fpga_data; ulong data; u8 comp;
diff --git a/cmd/nand.c b/cmd/nand.c index e730484d0b7..5bb43794e90 100644 --- a/cmd/nand.c +++ b/cmd/nand.c @@ -975,7 +975,7 @@ static int nand_load_image(struct cmd_tbl *cmdtp, struct mtd_info *mtd, char *s; size_t cnt; #if defined(CONFIG_LEGACY_IMAGE_FORMAT) - image_header_t *hdr; + struct legacy_img_hdr *hdr; #endif #if defined(CONFIG_FIT) const void *fit_hdr = NULL; @@ -1004,7 +1004,7 @@ static int nand_load_image(struct cmd_tbl *cmdtp, struct mtd_info *mtd, switch (genimg_get_format ((void *)addr)) { #if defined(CONFIG_LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: - hdr = (image_header_t *)addr; + hdr = (struct legacy_img_hdr *)addr;
bootstage_mark(BOOTSTAGE_ID_NAND_TYPE); image_print_contents (hdr); diff --git a/cmd/source.c b/cmd/source.c index 81e015b64ef..698d9f86d96 100644 --- a/cmd/source.c +++ b/cmd/source.c @@ -46,7 +46,7 @@ int image_source_script(ulong addr, const char *fit_uname) { ulong len; #if defined(CONFIG_LEGACY_IMAGE_FORMAT) - const image_header_t *hdr; + const struct legacy_img_hdr *hdr; #endif u32 *data; int verify; diff --git a/cmd/ximg.c b/cmd/ximg.c index 65ba41320a0..bdf691ffcba 100644 --- a/cmd/ximg.c +++ b/cmd/ximg.c @@ -42,7 +42,7 @@ do_imgextract(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int part = 0; #if defined(CONFIG_LEGACY_IMAGE_FORMAT) ulong count; - image_header_t *hdr = NULL; + struct legacy_img_hdr *hdr = NULL; #endif #if defined(CONFIG_FIT) const char *uname = NULL; @@ -78,7 +78,7 @@ do_imgextract(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) printf("## Copying part %d from legacy image " "at %08lx ...\n", part, addr);
- hdr = (image_header_t *)addr; + hdr = (struct legacy_img_hdr *)addr; if (!image_check_magic(hdr)) { printf("Bad Magic Number\n"); return 1; diff --git a/common/spl/spl.c b/common/spl/spl.c index 13a343b9170..d97d5eccb9d 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -222,7 +222,7 @@ __weak void spl_board_prepare_for_boot(void) /* Nothing to do! */ }
-__weak struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +__weak struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { return map_sysmem(CONFIG_SYS_TEXT_BASE + offset, 0); } @@ -253,7 +253,7 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image) #if CONFIG_IS_ENABLED(LOAD_FIT_FULL) /* Parse and load full fitImage in SPL */ static int spl_load_fit_image(struct spl_image_info *spl_image, - const struct image_header *header) + const struct legacy_img_hdr *header) { struct bootm_headers images; const char *fit_uname_config = NULL; @@ -354,7 +354,7 @@ __weak int spl_parse_board_header(struct spl_image_info *spl_image, }
__weak int spl_parse_legacy_header(struct spl_image_info *spl_image, - const struct image_header *header) + const struct legacy_img_hdr *header) { /* LEGACY image not supported */ debug("Legacy boot image support not enabled, proceeding to other boot methods\n"); @@ -363,7 +363,7 @@ __weak int spl_parse_legacy_header(struct spl_image_info *spl_image,
int spl_parse_image_header(struct spl_image_info *spl_image, const struct spl_boot_device *bootdev, - const struct image_header *header) + const struct legacy_img_hdr *header) { #if CONFIG_IS_ENABLED(LOAD_FIT_FULL) int ret = spl_load_fit_image(spl_image, header); diff --git a/common/spl/spl_ext.c b/common/spl/spl_ext.c index ebd914c4926..f117c630bfe 100644 --- a/common/spl/spl_ext.c +++ b/common/spl/spl_ext.c @@ -15,7 +15,7 @@ int spl_load_image_ext(struct spl_image_info *spl_image, const char *filename) { s32 err; - struct image_header *header; + struct legacy_img_hdr *header; loff_t filelen, actlen; struct disk_partition part_info = {};
@@ -41,7 +41,7 @@ int spl_load_image_ext(struct spl_image_info *spl_image, puts("spl: ext4fs_open failed\n"); goto end; } - err = ext4fs_read((char *)header, 0, sizeof(struct image_header), &actlen); + err = ext4fs_read((char *)header, 0, sizeof(struct legacy_img_hdr), &actlen); if (err < 0) { puts("spl: ext4fs_read failed\n"); goto end; diff --git a/common/spl/spl_fat.c b/common/spl/spl_fat.c index 5b270541fcc..f8a5b80a3bd 100644 --- a/common/spl/spl_fat.c +++ b/common/spl/spl_fat.c @@ -60,7 +60,7 @@ int spl_load_image_fat(struct spl_image_info *spl_image, const char *filename) { int err; - struct image_header *header; + struct legacy_img_hdr *header;
err = spl_register_fat_device(block_dev, partition); if (err) @@ -68,7 +68,7 @@ int spl_load_image_fat(struct spl_image_info *spl_image,
header = spl_get_load_buffer(-sizeof(*header), sizeof(*header));
- err = file_fat_read(filename, header, sizeof(struct image_header)); + err = file_fat_read(filename, header, sizeof(struct legacy_img_hdr)); if (err <= 0) goto end;
@@ -78,7 +78,7 @@ int spl_load_image_fat(struct spl_image_info *spl_image, if (err <= 0) goto end; err = spl_parse_image_header(spl_image, bootdev, - (struct image_header *)CONFIG_SYS_LOAD_ADDR); + (struct legacy_img_hdr *)CONFIG_SYS_LOAD_ADDR); if (err == -EAGAIN) return err; if (err == 0) diff --git a/common/spl/spl_legacy.c b/common/spl/spl_legacy.c index ae8731c782a..b3624dfbb77 100644 --- a/common/spl/spl_legacy.c +++ b/common/spl/spl_legacy.c @@ -16,9 +16,9 @@ #define LZMA_LEN (1 << 20)
int spl_parse_legacy_header(struct spl_image_info *spl_image, - const struct image_header *header) + const struct legacy_img_hdr *header) { - u32 header_size = sizeof(struct image_header); + u32 header_size = sizeof(struct legacy_img_hdr);
/* check uImage header CRC */ if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK) && @@ -67,7 +67,7 @@ int spl_parse_legacy_header(struct spl_image_info *spl_image, * following switch/case statement in spl_load_legacy_img() away due to * Dead Code Elimination. */ -static inline int spl_image_get_comp(const struct image_header *hdr) +static inline int spl_image_get_comp(const struct legacy_img_hdr *hdr) { if (IS_ENABLED(CONFIG_SPL_LZMA)) return image_get_comp(hdr); @@ -81,7 +81,7 @@ int spl_load_legacy_img(struct spl_image_info *spl_image, { __maybe_unused SizeT lzma_len; __maybe_unused void *src; - struct image_header hdr; + struct legacy_img_hdr hdr; ulong dataptr; int ret;
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 23a395e63d4..e4135b20487 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -20,7 +20,7 @@ static int mmc_load_legacy(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, struct mmc *mmc, - ulong sector, struct image_header *header) + ulong sector, struct legacy_img_hdr *header) { u32 image_offset_sectors; u32 image_size_sectors; @@ -83,7 +83,7 @@ int mmc_load_image_raw_sector(struct spl_image_info *spl_image, struct mmc *mmc, unsigned long sector) { unsigned long count; - struct image_header *header; + struct legacy_img_hdr *header; struct blk_desc *bd = mmc_get_blk_desc(mmc); int ret = 0;
diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c index 7b7579a2df1..a16738818c1 100644 --- a/common/spl/spl_nand.c +++ b/common/spl/spl_nand.c @@ -78,7 +78,7 @@ struct mtd_info * __weak nand_get_mtd(void)
static int spl_nand_load_element(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, - int offset, struct image_header *header) + int offset, struct legacy_img_hdr *header) { struct mtd_info *mtd = nand_get_mtd(); int bl_len = mtd ? mtd->writesize : 1; @@ -133,7 +133,7 @@ static int spl_nand_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { int err; - struct image_header *header; + struct legacy_img_hdr *header; int *src __attribute__((unused)); int *dst __attribute__((unused));
diff --git a/common/spl/spl_net.c b/common/spl/spl_net.c index a853e6aead4..b2c901b554b 100644 --- a/common/spl/spl_net.c +++ b/common/spl/spl_net.c @@ -28,7 +28,7 @@ static ulong spl_net_load_read(struct spl_load_info *load, ulong sector, static int spl_net_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct image_header *header = (struct image_header *)image_load_addr; + struct legacy_img_hdr *header = (struct legacy_img_hdr *)image_load_addr; int rv;
env_init(); diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c index 7986e930d28..281c6136f54 100644 --- a/common/spl/spl_nor.c +++ b/common/spl/spl_nor.c @@ -26,7 +26,7 @@ unsigned long __weak spl_nor_get_uboot_base(void) static int spl_nor_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - __maybe_unused const struct image_header *header; + __maybe_unused const struct legacy_img_hdr *header; __maybe_unused struct spl_load_info load;
/* @@ -41,7 +41,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, * Load Linux from its location in NOR flash to its defined * location in SDRAM */ - header = (const struct image_header *)CONFIG_SYS_OS_BASE; + header = (const struct legacy_img_hdr *)CONFIG_SYS_OS_BASE; #ifdef CONFIG_SPL_LOAD_FIT if (image_get_magic(header) == FDT_MAGIC) { int ret; @@ -72,7 +72,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image,
memcpy((void *)spl_image->load_addr, (void *)(CONFIG_SYS_OS_BASE + - sizeof(struct image_header)), + sizeof(struct legacy_img_hdr)), spl_image->size); #ifdef CONFIG_SYS_SPL_ARGS_ADDR spl_image->arg = (void *)CONFIG_SYS_SPL_ARGS_ADDR; @@ -92,7 +92,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, * defined location in SDRAM */ #ifdef CONFIG_SPL_LOAD_FIT - header = (const struct image_header *)spl_nor_get_uboot_base(); + header = (const struct legacy_img_hdr *)spl_nor_get_uboot_base(); if (image_get_magic(header) == FDT_MAGIC) { debug("Found FIT format U-Boot\n"); load.bl_len = 1; diff --git a/common/spl/spl_onenand.c b/common/spl/spl_onenand.c index f80769a0277..53a8c6de89e 100644 --- a/common/spl/spl_onenand.c +++ b/common/spl/spl_onenand.c @@ -18,7 +18,7 @@ static int spl_onenand_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct image_header *header; + struct legacy_img_hdr *header; int ret;
debug("spl: onenand\n"); diff --git a/common/spl/spl_ram.c b/common/spl/spl_ram.c index d64710878cf..2b1ac191523 100644 --- a/common/spl/spl_ram.c +++ b/common/spl/spl_ram.c @@ -41,9 +41,9 @@ static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector, static int spl_ram_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct image_header *header; + struct legacy_img_hdr *header;
- header = (struct image_header *)CONFIG_SPL_LOAD_FIT_ADDRESS; + header = (struct legacy_img_hdr *)CONFIG_SPL_LOAD_FIT_ADDRESS;
if (CONFIG_IS_ENABLED(IMAGE_PRE_LOAD)) { unsigned long addr = (unsigned long)header; @@ -53,7 +53,7 @@ static int spl_ram_load_image(struct spl_image_info *spl_image, return ret;
addr += image_load_offset; - header = (struct image_header *)addr; + header = (struct legacy_img_hdr *)addr; }
#if CONFIG_IS_ENABLED(DFU) @@ -87,7 +87,7 @@ static int spl_ram_load_image(struct spl_image_info *spl_image, u_boot_pos = (ulong)spl_get_load_buffer(-sizeof(*header), sizeof(*header)); } - header = (struct image_header *)map_sysmem(u_boot_pos, 0); + header = (struct legacy_img_hdr *)map_sysmem(u_boot_pos, 0);
spl_parse_image_header(spl_image, bootdev, header); } diff --git a/common/spl/spl_sata.c b/common/spl/spl_sata.c index 1351d78612a..3067560bdf7 100644 --- a/common/spl/spl_sata.c +++ b/common/spl/spl_sata.c @@ -30,7 +30,7 @@ static int spl_sata_load_image_raw(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, struct blk_desc *stor_dev, unsigned long sector) { - struct image_header *header; + struct legacy_img_hdr *header; unsigned long count; u32 image_size_sectors; u32 image_offset_sectors; diff --git a/common/spl/spl_semihosting.c b/common/spl/spl_semihosting.c index df6aeb29512..5b5e842a11b 100644 --- a/common/spl/spl_semihosting.c +++ b/common/spl/spl_semihosting.c @@ -27,7 +27,7 @@ static int spl_smh_load_image(struct spl_image_info *spl_image, const char *filename = CONFIG_SPL_FS_LOAD_PAYLOAD_NAME; int ret; long fd, len; - struct image_header *header = + struct legacy_img_hdr *header = spl_get_load_buffer(-sizeof(*header), sizeof(*header));
fd = smh_open(filename, MODE_READ | MODE_BINARY); @@ -43,7 +43,7 @@ static int spl_smh_load_image(struct spl_image_info *spl_image, } len = ret;
- ret = smh_read_full(fd, header, sizeof(struct image_header)); + ret = smh_read_full(fd, header, sizeof(struct legacy_img_hdr)); if (ret) { log_debug("could not read image header: %d\n", ret); goto out; diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c index d959ad11458..da6742416ed 100644 --- a/common/spl/spl_spi.c +++ b/common/spl/spl_spi.c @@ -26,7 +26,7 @@ static int spi_load_image_os(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, struct spi_flash *flash, - struct image_header *header) + struct legacy_img_hdr *header) { int err;
@@ -92,7 +92,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, int err = 0; unsigned int payload_offs; struct spi_flash *flash; - struct image_header *header; + struct legacy_img_hdr *header; unsigned int sf_bus = spl_spi_boot_bus(); unsigned int sf_cs = spl_spi_boot_cs();
@@ -139,7 +139,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, if (err) return err; err = spl_parse_image_header(spl_image, bootdev, - (struct image_header *)CONFIG_SYS_LOAD_ADDR); + (struct legacy_img_hdr *)CONFIG_SYS_LOAD_ADDR); } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) { struct spl_load_info load; diff --git a/common/spl/spl_ubi.c b/common/spl/spl_ubi.c index bdf5cc4c383..fb804f02089 100644 --- a/common/spl/spl_ubi.c +++ b/common/spl/spl_ubi.c @@ -15,7 +15,7 @@ int spl_ubi_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct image_header *header; + struct legacy_img_hdr *header; struct ubispl_info info; struct ubispl_load volumes[2]; int ret = 1; @@ -54,7 +54,7 @@ int spl_ubi_load_image(struct spl_image_info *spl_image,
ret = ubispl_load_volumes(&info, volumes, 2); if (!ret) { - header = (struct image_header *)volumes[0].load_addr; + header = (struct legacy_img_hdr *)volumes[0].load_addr; spl_parse_image_header(spl_image, bootdev, header); puts("Linux loaded.\n"); goto out; diff --git a/common/spl/spl_xip.c b/common/spl/spl_xip.c index e9a40b0ec79..1258d85e63d 100644 --- a/common/spl/spl_xip.c +++ b/common/spl/spl_xip.c @@ -25,6 +25,6 @@ static int spl_xip(struct spl_image_info *spl_image, } #endif return(spl_parse_image_header(spl_image, bootdev, - (const struct image_header *)CONFIG_SYS_UBOOT_BASE)); + (const struct legacy_img_hdr *)CONFIG_SYS_UBOOT_BASE)); } SPL_LOAD_IMAGE_METHOD("XIP", 0, BOOT_DEVICE_XIP, spl_xip); diff --git a/common/spl/spl_ymodem.c b/common/spl/spl_ymodem.c index fdd52610429..038b4438457 100644 --- a/common/spl/spl_ymodem.c +++ b/common/spl/spl_ymodem.c @@ -96,7 +96,7 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, int ret; connection_info_t info; char buf[BUF_SIZE]; - struct image_header *ih = NULL; + struct legacy_img_hdr *ih = NULL; ulong addr = 0;
info.mode = xyzModem_ymodem; @@ -111,9 +111,9 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, goto end_stream;
if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL) && - image_get_magic((struct image_header *)buf) == FDT_MAGIC) { + image_get_magic((struct legacy_img_hdr *)buf) == FDT_MAGIC) { addr = CONFIG_SYS_LOAD_ADDR; - ih = (struct image_header *)addr; + ih = (struct legacy_img_hdr *)addr;
memcpy((void *)addr, buf, res); size += res; @@ -129,7 +129,7 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, if (ret) return ret; } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && - image_get_magic((struct image_header *)buf) == FDT_MAGIC) { + image_get_magic((struct legacy_img_hdr *)buf) == FDT_MAGIC) { struct spl_load_info load; struct ymodem_fit_info info;
@@ -147,7 +147,7 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) size += res; } else { - ih = (struct image_header *)buf; + ih = (struct legacy_img_hdr *)buf; ret = spl_parse_image_header(spl_image, bootdev, ih); if (ret) goto end_stream; @@ -158,7 +158,7 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, #endif addr = spl_image->load_addr; memcpy((void *)addr, buf, res); - ih = (struct image_header *)addr; + ih = (struct legacy_img_hdr *)addr; size += res; addr += res;
@@ -177,7 +177,7 @@ end_stream:
#ifdef CONFIG_SPL_GZIP if (!(IS_ENABLED(CONFIG_SPL_LOAD_FIT) && - image_get_magic((struct image_header *)buf) == FDT_MAGIC) && + image_get_magic((struct legacy_img_hdr *)buf) == FDT_MAGIC) && (ih->ih_comp == IH_COMP_GZIP)) { if (gunzip((void *)(spl_image->load_addr + sizeof(*ih)), CONFIG_SYS_BOOTM_LEN, diff --git a/common/splash_source.c b/common/splash_source.c index 2c03cbdf928..87e55a54f8c 100644 --- a/common/splash_source.c +++ b/common/splash_source.c @@ -327,17 +327,17 @@ static int splash_load_fit(struct splash_location *location, u32 bmp_load_addr) int external_splash_addr; int external_splash_size; bool is_splash_external = false; - struct image_header *img_header; + struct legacy_img_hdr *img_header; const u32 *fit_header; u32 fit_size; - const size_t header_size = sizeof(struct image_header); + const size_t header_size = sizeof(struct legacy_img_hdr);
/* Read in image header */ res = splash_storage_read_raw(location, bmp_load_addr, header_size); if (res < 0) return res;
- img_header = (struct image_header *)bmp_load_addr; + img_header = (struct legacy_img_hdr *)bmp_load_addr; if (image_get_magic(img_header) != FDT_MAGIC) { printf("Could not find FDT magic\n"); return -EINVAL; diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt index 68701118409..0a03c942bda 100644 --- a/doc/uImage.FIT/source_file_format.txt +++ b/doc/uImage.FIT/source_file_format.txt @@ -23,7 +23,7 @@ in the system memory and passed to bootm as a arguments. Some of them may be missing: FDT is not present for legacy platforms, ramdisk is always optional. Additionally, old uImage format has been extended to support multi sub-images but the support is limited by simple format of the legacy uImage structure. -Single binary header 'struct image_header' is not flexible enough to cover all +Single binary header 'struct legacy_img_hdr' is not flexible enough to cover all possible scenarios.
All those factors combined clearly show that there is a need for new, more diff --git a/drivers/fpga/socfpga_arria10.c b/drivers/fpga/socfpga_arria10.c index d8089122af1..451d0b9b311 100644 --- a/drivers/fpga/socfpga_arria10.c +++ b/drivers/fpga/socfpga_arria10.c @@ -555,14 +555,14 @@ static int first_loading_rbf_to_buffer(struct udevice *dev, /* Load image header into buffer */ ret = request_firmware_into_buf(dev, fpga_loadfs->fpga_fsinfo->filename, - buffer_p, sizeof(struct image_header), + buffer_p, sizeof(struct legacy_img_hdr), 0); if (ret < 0) { debug("FPGA: Failed to read image header from flash.\n"); return -ENOENT; }
- if (image_get_magic((struct image_header *)buffer_p) != FDT_MAGIC) { + if (image_get_magic((struct legacy_img_hdr *)buffer_p) != FDT_MAGIC) { debug("FPGA: No FDT magic was found.\n"); return -EBADF; } diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c index 0fa7230b992..3bfb772a71a 100644 --- a/drivers/usb/gadget/f_sdp.c +++ b/drivers/usb/gadget/f_sdp.c @@ -835,7 +835,7 @@ static int sdp_handle_in_ep(struct spl_image_info *spl_image,
printf("Found header at 0x%08x\n", sdp_func->jmp_address);
- image_header_t *header = + struct legacy_img_hdr *header = sdp_ptr(sdp_func->jmp_address); #ifdef CONFIG_SPL_LOAD_FIT if (image_get_magic(header) == FDT_MAGIC) { diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 15ae0844c1a..d9e95abcc12 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -169,7 +169,7 @@
/* only for SPL */
-/* subtract sizeof(struct image_header) */ +/* subtract sizeof(struct legacy_img_hdr) */ #define CONFIG_SYS_UBOOT_BASE (0x130000 - 0x40)
#endif /* __CONFIG_UNIPHIER_H__ */ diff --git a/include/image.h b/include/image.h index e1a65cce7ba..b336cfa0842 100644 --- a/include/image.h +++ b/include/image.h @@ -263,7 +263,7 @@ enum { * Legacy format image header, * all data in network byte order (aka natural aka bigendian). */ -typedef struct image_header { +struct legacy_img_hdr { uint32_t ih_magic; /* Image Header Magic Number */ uint32_t ih_hcrc; /* Image Header CRC Checksum */ uint32_t ih_time; /* Image Creation Timestamp */ @@ -276,7 +276,7 @@ typedef struct image_header { uint8_t ih_type; /* Image Type */ uint8_t ih_comp; /* Compression Type */ uint8_t ih_name[IH_NMLEN]; /* Image Name */ -} image_header_t; +};
struct image_info { ulong start, end; /* start/end of blob */ @@ -296,8 +296,8 @@ struct bootm_headers { * then boot_get_ramdisk() and get_fdt() will attempt to get * data from second and third component accordingly. */ - image_header_t *legacy_hdr_os; /* image header pointer */ - image_header_t legacy_hdr_os_copy; /* header copy */ + struct legacy_img_hdr *legacy_hdr_os; /* image header pointer */ + struct legacy_img_hdr legacy_hdr_os_copy; /* header copy */ ulong legacy_hdr_valid;
/* @@ -696,11 +696,11 @@ int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd); /*******************************************************************/ static inline uint32_t image_get_header_size(void) { - return (sizeof(image_header_t)); + return sizeof(struct legacy_img_hdr); }
#define image_get_hdr_l(f) \ - static inline uint32_t image_get_##f(const image_header_t *hdr) \ + static inline uint32_t image_get_##f(const struct legacy_img_hdr *hdr) \ { \ return uimage_to_cpu(hdr->ih_##f); \ } @@ -713,7 +713,7 @@ image_get_hdr_l(ep) /* image_get_ep */ image_get_hdr_l(dcrc) /* image_get_dcrc */
#define image_get_hdr_b(f) \ - static inline uint8_t image_get_##f(const image_header_t *hdr) \ + static inline uint8_t image_get_##f(const struct legacy_img_hdr *hdr) \ { \ return hdr->ih_##f; \ } @@ -722,12 +722,12 @@ image_get_hdr_b(arch) /* image_get_arch */ image_get_hdr_b(type) /* image_get_type */ image_get_hdr_b(comp) /* image_get_comp */
-static inline char *image_get_name(const image_header_t *hdr) +static inline char *image_get_name(const struct legacy_img_hdr *hdr) { return (char *)hdr->ih_name; }
-static inline uint32_t image_get_data_size(const image_header_t *hdr) +static inline uint32_t image_get_data_size(const struct legacy_img_hdr *hdr) { return image_get_size(hdr); } @@ -743,22 +743,23 @@ static inline uint32_t image_get_data_size(const image_header_t *hdr) * returns: * image payload data start address */ -static inline ulong image_get_data(const image_header_t *hdr) +static inline ulong image_get_data(const struct legacy_img_hdr *hdr) { return ((ulong)hdr + image_get_header_size()); }
-static inline uint32_t image_get_image_size(const image_header_t *hdr) +static inline uint32_t image_get_image_size(const struct legacy_img_hdr *hdr) { return (image_get_size(hdr) + image_get_header_size()); } -static inline ulong image_get_image_end(const image_header_t *hdr) + +static inline ulong image_get_image_end(const struct legacy_img_hdr *hdr) { return ((ulong)hdr + image_get_image_size(hdr)); }
#define image_set_hdr_l(f) \ - static inline void image_set_##f(image_header_t *hdr, uint32_t val) \ + static inline void image_set_##f(struct legacy_img_hdr *hdr, uint32_t val) \ { \ hdr->ih_##f = cpu_to_uimage(val); \ } @@ -771,7 +772,7 @@ image_set_hdr_l(ep) /* image_set_ep */ image_set_hdr_l(dcrc) /* image_set_dcrc */
#define image_set_hdr_b(f) \ - static inline void image_set_##f(image_header_t *hdr, uint8_t val) \ + static inline void image_set_##f(struct legacy_img_hdr *hdr, uint8_t val) \ { \ hdr->ih_##f = val; \ } @@ -780,13 +781,13 @@ image_set_hdr_b(arch) /* image_set_arch */ image_set_hdr_b(type) /* image_set_type */ image_set_hdr_b(comp) /* image_set_comp */
-static inline void image_set_name(image_header_t *hdr, const char *name) +static inline void image_set_name(struct legacy_img_hdr *hdr, const char *name) { strncpy(image_get_name(hdr), name, IH_NMLEN); }
-int image_check_hcrc(const image_header_t *hdr); -int image_check_dcrc(const image_header_t *hdr); +int image_check_hcrc(const struct legacy_img_hdr *hdr); +int image_check_dcrc(const struct legacy_img_hdr *hdr); #ifndef USE_HOSTCC ulong env_get_bootm_low(void); phys_size_t env_get_bootm_size(void); @@ -794,15 +795,17 @@ phys_size_t env_get_bootm_mapsize(void); #endif void memmove_wd(void *to, void *from, size_t len, ulong chunksz);
-static inline int image_check_magic(const image_header_t *hdr) +static inline int image_check_magic(const struct legacy_img_hdr *hdr) { return (image_get_magic(hdr) == IH_MAGIC); } -static inline int image_check_type(const image_header_t *hdr, uint8_t type) + +static inline int image_check_type(const struct legacy_img_hdr *hdr, uint8_t type) { return (image_get_type(hdr) == type); } -static inline int image_check_arch(const image_header_t *hdr, uint8_t arch) + +static inline int image_check_arch(const struct legacy_img_hdr *hdr, uint8_t arch) { /* Let's assume that sandbox can load any architecture */ if (!tools_build() && IS_ENABLED(CONFIG_SANDBOX)) @@ -810,19 +813,20 @@ static inline int image_check_arch(const image_header_t *hdr, uint8_t arch) return (image_get_arch(hdr) == arch) || (image_get_arch(hdr) == IH_ARCH_ARM && arch == IH_ARCH_ARM64); } -static inline int image_check_os(const image_header_t *hdr, uint8_t os) + +static inline int image_check_os(const struct legacy_img_hdr *hdr, uint8_t os) { return (image_get_os(hdr) == os); }
-ulong image_multi_count(const image_header_t *hdr); -void image_multi_getimg(const image_header_t *hdr, ulong idx, +ulong image_multi_count(const struct legacy_img_hdr *hdr); +void image_multi_getimg(const struct legacy_img_hdr *hdr, ulong idx, ulong *data, ulong *len);
void image_print_contents(const void *hdr);
#ifndef USE_HOSTCC -static inline int image_check_target_arch(const image_header_t *hdr) +static inline int image_check_target_arch(const struct legacy_img_hdr *hdr) { #ifndef IH_ARCH_DEFAULT # error "please define IH_ARCH_DEFAULT in your arch asm/u-boot.h" diff --git a/include/spl.h b/include/spl.h index aac6648f946..0fc3686bbca 100644 --- a/include/spl.h +++ b/include/spl.h @@ -17,7 +17,7 @@ #include <mmc.h>
struct blk_desc; -struct image_header; +struct legacy_img_hdr;
/* Value in r0 indicates we booted from U-Boot */ #define UBOOT_NOT_LOADED_FROM_SPL 0x13578642 @@ -29,7 +29,7 @@ struct image_header; #define MMCSD_MODE_EMMCBOOT 3
struct blk_desc; -struct image_header; +struct legacy_img_hdr; struct spl_boot_device;
/* @@ -476,7 +476,7 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image); */ int spl_parse_image_header(struct spl_image_info *spl_image, const struct spl_boot_device *bootdev, - const struct image_header *header); + const struct legacy_img_hdr *header);
void spl_board_prepare_for_linux(void);
@@ -865,7 +865,7 @@ void spl_perform_fixups(struct spl_image_info *spl_image); * Returns memory area which can be populated by partial image data, * ie. uImage or fitImage header. */ -struct image_header *spl_get_load_buffer(ssize_t offset, size_t size); +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size);
void spl_save_restore_data(void); #endif diff --git a/include/tee/optee.h b/include/tee/optee.h index 5412bc7386e..77729450bb6 100644 --- a/include/tee/optee.h +++ b/include/tee/optee.h @@ -30,7 +30,7 @@ struct optee_header { };
static inline uint32_t -optee_image_get_entry_point(const struct image_header *hdr) +optee_image_get_entry_point(const struct legacy_img_hdr *hdr) { struct optee_header *optee_hdr = (struct optee_header *)(hdr + 1);
@@ -38,7 +38,7 @@ optee_image_get_entry_point(const struct image_header *hdr) }
static inline uint32_t -optee_image_get_load_addr(const struct image_header *hdr) +optee_image_get_load_addr(const struct legacy_img_hdr *hdr) { return optee_image_get_entry_point(hdr) - sizeof(struct optee_header); } diff --git a/test/image/spl_load.c b/test/image/spl_load.c index df389e26f90..4e27ff460ab 100644 --- a/test/image/spl_load.c +++ b/test/image/spl_load.c @@ -49,7 +49,7 @@ int board_fit_config_name_match(const char *name) return 0; }
-struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { return map_sysmem(0x100000, 0); } @@ -57,7 +57,7 @@ struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) static int spl_test_load(struct unit_test_state *uts) { struct spl_image_info image; - struct image_header *header; + struct legacy_img_hdr *header; struct text_ctx text_ctx; struct spl_load_info load; char fname[256]; diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 5422940e07e..6b4ef725770 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -5761,7 +5761,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap # Check that the data appears in the file somewhere self.assertIn(U_BOOT_SPL_DATA, data)
- # Get struct image_header -> ih_name + # Get struct legacy_img_hdr -> ih_name name = data[0x20:0x40]
# Build the filename that we expect to be placed in there, by virtue of @@ -5778,7 +5778,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap # Check that the data appears in the file somewhere self.assertIn(U_BOOT_SPL_DATA, data)
- # Get struct image_header -> ih_name + # Get struct legacy_img_hdr -> ih_name name = data[0x20:0x40]
# Build the filename that we expect to be placed in there, by virtue of diff --git a/tools/default_image.c b/tools/default_image.c index e164c0c27d1..4a067e65862 100644 --- a/tools/default_image.c +++ b/tools/default_image.c @@ -22,7 +22,7 @@ #include <u-boot/crc.h> #include <imximage.h>
-static image_header_t header; +static struct legacy_img_hdr header;
static int image_check_image_types(uint8_t type) { @@ -46,15 +46,15 @@ static int image_verify_header(unsigned char *ptr, int image_size, uint32_t len; const unsigned char *data; uint32_t checksum; - image_header_t header; - image_header_t *hdr = &header; + struct legacy_img_hdr header; + struct legacy_img_hdr *hdr = &header;
/* * create copy of header so that we can blank out the * checksum field for checking - this can't be done * on the PROT_READ mapped data. */ - memcpy(hdr, ptr, sizeof(image_header_t)); + memcpy(hdr, ptr, sizeof(struct legacy_img_hdr));
if (be32_to_cpu(hdr->ih_magic) != IH_MAGIC) { debug("%s: Bad Magic Number: "%s" is no valid image\n", @@ -63,7 +63,7 @@ static int image_verify_header(unsigned char *ptr, int image_size, }
data = (const unsigned char *)hdr; - len = sizeof(image_header_t); + len = sizeof(struct legacy_img_hdr);
checksum = be32_to_cpu(hdr->ih_hcrc); hdr->ih_hcrc = cpu_to_be32(0); /* clear for re-calculation */ @@ -74,8 +74,8 @@ static int image_verify_header(unsigned char *ptr, int image_size, return -FDT_ERR_BADSTATE; }
- data = (const unsigned char *)ptr + sizeof(image_header_t); - len = image_size - sizeof(image_header_t) ; + data = (const unsigned char *)ptr + sizeof(struct legacy_img_hdr); + len = image_size - sizeof(struct legacy_img_hdr);
checksum = be32_to_cpu(hdr->ih_dcrc); if (crc32(0, data, len) != checksum) { @@ -94,13 +94,12 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd, uint32_t imagesize; uint32_t ep; uint32_t addr; - - image_header_t * hdr = (image_header_t *)ptr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr;
checksum = crc32(0, (const unsigned char *)(ptr + - sizeof(image_header_t)), - sbuf->st_size - sizeof(image_header_t)); + sizeof(struct legacy_img_hdr)), + sbuf->st_size - sizeof(struct legacy_img_hdr));
time = imagetool_get_source_date(params->cmdname, sbuf->st_mtime); ep = params->ep; @@ -108,11 +107,11 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd,
if (params->type == IH_TYPE_FIRMWARE_IVT) /* Add size of CSF minus IVT */ - imagesize = sbuf->st_size - sizeof(image_header_t) + imagesize = sbuf->st_size - sizeof(struct legacy_img_hdr) + 0x2060 - sizeof(flash_header_v2_t);
else - imagesize = sbuf->st_size - sizeof(image_header_t); + imagesize = sbuf->st_size - sizeof(struct legacy_img_hdr);
if (params->os == IH_OS_TEE) { addr = optee_image_get_load_addr(hdr); @@ -134,14 +133,14 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd, image_set_name(hdr, params->imagename);
checksum = crc32(0, (const unsigned char *)hdr, - sizeof(image_header_t)); + sizeof(struct legacy_img_hdr));
image_set_hcrc(hdr, checksum); }
static int image_extract_subimage(void *ptr, struct image_tool_params *params) { - const image_header_t *hdr = (const image_header_t *)ptr; + const struct legacy_img_hdr *hdr = (const struct legacy_img_hdr *)ptr; ulong file_data; ulong file_len;
@@ -175,7 +174,7 @@ static int image_extract_subimage(void *ptr, struct image_tool_params *params) U_BOOT_IMAGE_TYPE( defimage, "Default Image support", - sizeof(image_header_t), + sizeof(struct legacy_img_hdr), (void *)&header, image_check_params, image_verify_header, diff --git a/tools/fit_image.c b/tools/fit_image.c index 979f2411ee0..923a9755b70 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -22,7 +22,7 @@ #include <version.h> #include <u-boot/crc.h>
-static image_header_t header; +static struct legacy_img_hdr header;
static int fit_add_file_data(struct image_tool_params *params, size_t size_inc, const char *tmpfile) @@ -915,7 +915,7 @@ static int fit_check_params(struct image_tool_params *params) U_BOOT_IMAGE_TYPE( fitimage, "FIT Image support", - sizeof(image_header_t), + sizeof(struct legacy_img_hdr), (void *)&header, fit_check_params, fit_verify_header, diff --git a/tools/imx8mimage.c b/tools/imx8mimage.c index a4699decf92..35d0a92bfdf 100644 --- a/tools/imx8mimage.c +++ b/tools/imx8mimage.c @@ -318,7 +318,7 @@ err_mmap: static int generate_ivt_for_fit(int fd, int fit_offset, uint32_t ep, uint32_t *fit_load_addr) { - image_header_t image_header; + struct legacy_img_hdr image_header; int ret;
uint32_t fit_size, load_addr; @@ -330,8 +330,8 @@ static int generate_ivt_for_fit(int fd, int fit_offset, uint32_t ep, exit(EXIT_FAILURE); }
- if (read(fd, (char *)&image_header, sizeof(image_header_t)) != - sizeof(image_header_t)) { + if (read(fd, (char *)&image_header, sizeof(struct legacy_img_hdr)) != + sizeof(struct legacy_img_hdr)) { fprintf(stderr, "generate_ivt_for_fit read failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); @@ -600,7 +600,7 @@ void build_image(int ofd) close(sld_fd);
file_off = sld_header_off; - file_off += sbuf.st_size + sizeof(image_header_t); + file_off += sbuf.st_size + sizeof(struct legacy_img_hdr); } }
diff --git a/tools/mkimage.c b/tools/mkimage.c index 597cb3a5ced..30c6df77081 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -845,7 +845,7 @@ copy_file (int ifd, const char *datafile, int pad) if (params.xflag) { unsigned char *p = NULL; /* - * XIP: do not append the image_header_t at the + * XIP: do not append the struct legacy_img_hdr at the * beginning of the file, but consume the space * reserved for it. */ diff --git a/tools/mtk_image.c b/tools/mtk_image.c index de5ce4d964c..0e031876c89 100644 --- a/tools/mtk_image.c +++ b/tools/mtk_image.c @@ -647,10 +647,10 @@ static uint32_t crc32be_cal(const void *data, size_t length)
static int mtk_image_verify_mt7621_header(const uint8_t *ptr, int print) { - const image_header_t *hdr = (const image_header_t *)ptr; + const struct legacy_img_hdr *hdr = (const struct legacy_img_hdr *)ptr; struct mt7621_nand_header *nhdr; uint32_t spl_size, crcval; - image_header_t header; + struct legacy_img_hdr header; int ret;
spl_size = image_get_size(hdr); @@ -710,7 +710,7 @@ static int mtk_image_verify_mt7621_header(const uint8_t *ptr, int print) static int mtk_image_verify_header(unsigned char *ptr, int image_size, struct image_tool_params *params) { - image_header_t *hdr = (image_header_t *)ptr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; union lk_hdr *lk = (union lk_hdr *)ptr;
/* nothing to verify for LK image header */ @@ -732,7 +732,7 @@ static int mtk_image_verify_header(unsigned char *ptr, int image_size,
static void mtk_image_print_header(const void *ptr) { - image_header_t *hdr = (image_header_t *)ptr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; union lk_hdr *lk = (union lk_hdr *)ptr;
if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) { @@ -914,7 +914,7 @@ static void mtk_image_set_nand_header(void *ptr, off_t filesize, static void mtk_image_set_mt7621_header(void *ptr, off_t filesize, uint32_t loadaddr) { - image_header_t *hdr = (image_header_t *)ptr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; struct mt7621_stage1_header *shdr; struct mt7621_nand_header *nhdr; uint32_t datasize, crcval;

Add some advice on string size here.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
include/log.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/log.h b/include/log.h index df497bad181..8a7b961bbfb 100644 --- a/include/log.h +++ b/include/log.h @@ -322,7 +322,10 @@ void __assert_fail(const char *assertion, const char *file, unsigned int line, * * or: * - * return log_msg_ret("fred failed", fred_call()); + * return log_msg_ret("get", fred_call()); + * + * It is recommended to use <= 3 characters for the name since this will only + * use 4 bytes in rodata */ #define log_ret(_ret) ({ \ int __ret = (_ret); \

Use the log functions instead of pr_...() so we can avoid using __func__.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/power/pmic/sandbox.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/power/pmic/sandbox.c b/drivers/power/pmic/sandbox.c index d7870915de8..acfeae2df97 100644 --- a/drivers/power/pmic/sandbox.c +++ b/drivers/power/pmic/sandbox.c @@ -4,11 +4,14 @@ * Przemyslaw Marczak p.marczak@samsung.com */
+#define LOG_CATEGORY UCLASS_PMIC + #include <common.h> #include <fdtdec.h> #include <errno.h> #include <dm.h> #include <i2c.h> +#include <log.h> #include <power/pmic.h> #include <power/regulator.h> #include <power/sandbox_pmic.h> @@ -28,7 +31,7 @@ static int sandbox_pmic_write(struct udevice *dev, uint reg, const uint8_t *buff, int len) { if (dm_i2c_write(dev, reg, buff, len)) { - pr_err("write error to device: %p register: %#x!\n", dev, reg); + log_err("write error to device: %p register: %#x!\n", dev, reg); return -EIO; }
@@ -39,7 +42,7 @@ static int sandbox_pmic_read(struct udevice *dev, uint reg, uint8_t *buff, int len) { if (dm_i2c_read(dev, reg, buff, len)) { - pr_err("read error from device: %p register: %#x!\n", dev, reg); + log_err("read error from device: %p register: %#x!\n", dev, reg); return -EIO; }
@@ -49,8 +52,7 @@ static int sandbox_pmic_read(struct udevice *dev, uint reg, static int sandbox_pmic_bind(struct udevice *dev) { if (!pmic_bind_children(dev, dev_ofnode(dev), pmic_children_info)) - pr_err("%s:%d PMIC: %s - no child found!", __func__, __LINE__, - dev->name); + log_err("PMIC: %s - no child found!\n", dev->name);
/* Always return success for this device - allows for PMIC I/O */ return 0;

On 9/7/22 11:26, Simon Glass wrote:
Use the log functions instead of pr_...() so we can avoid using __func__.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
Best Regards, Jaehoon Chung
(no changes since v1)
drivers/power/pmic/sandbox.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/power/pmic/sandbox.c b/drivers/power/pmic/sandbox.c index d7870915de8..acfeae2df97 100644 --- a/drivers/power/pmic/sandbox.c +++ b/drivers/power/pmic/sandbox.c @@ -4,11 +4,14 @@
- Przemyslaw Marczak p.marczak@samsung.com
*/
+#define LOG_CATEGORY UCLASS_PMIC
#include <common.h> #include <fdtdec.h> #include <errno.h> #include <dm.h> #include <i2c.h> +#include <log.h> #include <power/pmic.h> #include <power/regulator.h> #include <power/sandbox_pmic.h> @@ -28,7 +31,7 @@ static int sandbox_pmic_write(struct udevice *dev, uint reg, const uint8_t *buff, int len) { if (dm_i2c_write(dev, reg, buff, len)) {
pr_err("write error to device: %p register: %#x!\n", dev, reg);
return -EIO; }log_err("write error to device: %p register: %#x!\n", dev, reg);
@@ -39,7 +42,7 @@ static int sandbox_pmic_read(struct udevice *dev, uint reg, uint8_t *buff, int len) { if (dm_i2c_read(dev, reg, buff, len)) {
pr_err("read error from device: %p register: %#x!\n", dev, reg);
return -EIO; }log_err("read error from device: %p register: %#x!\n", dev, reg);
@@ -49,8 +52,7 @@ static int sandbox_pmic_read(struct udevice *dev, uint reg, static int sandbox_pmic_bind(struct udevice *dev) { if (!pmic_bind_children(dev, dev_ofnode(dev), pmic_children_info))
pr_err("%s:%d PMIC: %s - no child found!", __func__, __LINE__,
dev->name);
log_err("PMIC: %s - no child found!\n", dev->name);
/* Always return success for this device - allows for PMIC I/O */ return 0;

Fix the help message.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
common/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/Kconfig b/common/Kconfig index e7914ca750a..5cfa63b0db1 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -551,7 +551,7 @@ config EVENT help This enables sending and processing of events, to allow interested parties to be alerted when something happens. This is an attempt to - step the flow of weak functions, hooks, functions in board_f.c + stem the flow of weak functions, hooks, functions in board_f.c and board_r.c and the Kconfig options below.
See doc/develop/event.rst for more information.

At present only one spy is allowed per event. Update the naming to allow more than one, since some need this flexibility, e.g. the EVT_FT_FIXUP event.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
include/event.h | 4 ++-- scripts/event_dump.py | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/include/event.h b/include/event.h index e8f2f55c63d..ff883ca064e 100644 --- a/include/event.h +++ b/include/event.h @@ -143,8 +143,8 @@ static inline const char *event_spy_id(struct evspy_info *spy) * vbe_simple.c - so for now, make it global. */ #define EVENT_SPY(_type, _func) \ - __used ll_entry_declare(struct evspy_info, _type, evspy_info) = \ - _ESPY_REC(_type, _func) + __used ll_entry_declare(struct evspy_info, _type ## _3_ ## _func, \ + evspy_info) = _ESPY_REC(_type, _func)
/** * event_register - register a new spy diff --git a/scripts/event_dump.py b/scripts/event_dump.py index 751f41b183a..6aadddf28da 100755 --- a/scripts/event_dump.py +++ b/scripts/event_dump.py @@ -17,8 +17,10 @@ sys.path.insert(1, os.path.join(our_path, '../tools')) from binman import elf from patman import tools
+# A typical symbol looks like this: +# _u_boot_list_2_evspy_info_2_EVT_MISC_INIT_F_3_sandbox_misc_init_f PREFIX = '_u_boot_list_2_evspy_info_2_' -RE_EVTYPE = re.compile('%s(.*)' % PREFIX) +RE_EVTYPE = re.compile('%s(.*)_3_.*' % PREFIX)
def show_sym(fname, data, endian, evtype, sym): """Show information about an evspy entry

This function currently assumes that the control FDT is used. Update it to allow a root node to be passed, so it can work with any tree.
Also add a comment to ofnode_get_by_phandle() so that its purpose is clear.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/core/of_access.c | 7 ++++--- drivers/core/ofnode.c | 2 +- include/dm/of_access.h | 4 +++- include/dm/ofnode.h | 2 ++ 4 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index a52f5a6b18b..ee09bbb7550 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -445,14 +445,15 @@ struct device_node *of_find_node_by_prop_value(struct device_node *from, return np; }
-struct device_node *of_find_node_by_phandle(phandle handle) +struct device_node *of_find_node_by_phandle(struct device_node *root, + phandle handle) { struct device_node *np;
if (!handle) return NULL;
- for_each_of_allnodes(np) + for_each_of_allnodes_from(root, np) if (np->phandle == handle) break; (void)of_node_get(np); @@ -659,7 +660,7 @@ static int __of_parse_phandle_with_args(const struct device_node *np, * below. */ if (cells_name || cur_index == index) { - node = of_find_node_by_phandle(phandle); + node = of_find_node_by_phandle(NULL, phandle); if (!node) { debug("%s: could not find phandle\n", np->full_name); diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 45ea84e9fb8..bf8eaf6d09a 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -329,7 +329,7 @@ ofnode ofnode_get_by_phandle(uint phandle) ofnode node;
if (of_live_active()) - node = np_to_ofnode(of_find_node_by_phandle(phandle)); + node = np_to_ofnode(of_find_node_by_phandle(NULL, phandle)); else node.of_offset = fdt_node_offset_by_phandle(gd->fdt_blob, phandle); diff --git a/include/dm/of_access.h b/include/dm/of_access.h index 5b7821d0a1b..c0ac91a416a 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -258,11 +258,13 @@ struct device_node *of_find_node_by_prop_value(struct device_node *from, /** * of_find_node_by_phandle() - Find a node given a phandle * + * @root: root node to start from (NULL for default device tree) * @handle: phandle of the node to find * * Return: node pointer, or NULL if not found */ -struct device_node *of_find_node_by_phandle(phandle handle); +struct device_node *of_find_node_by_phandle(struct device_node *root, + phandle handle);
/** * of_read_u32() - Find and read a 32-bit integer from a property diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 7ce1e4c6d91..018ee70c2ff 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -461,6 +461,8 @@ int ofnode_get_path(ofnode node, char *buf, int buflen); /** * ofnode_get_by_phandle() - get ofnode from phandle * + * This uses the default (control) device tree + * * @phandle: phandle to look up * Return: ofnode reference to the phandle */

Pass the boot images along as well, in case the fixups need to look at them.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
boot/image-fdt.c | 1 + include/event.h | 2 ++ 2 files changed, 3 insertions(+)
diff --git a/boot/image-fdt.c b/boot/image-fdt.c index ca51796322d..884e089f2d8 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -669,6 +669,7 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, struct event_ft_fixup fixup;
fixup.tree = oftree_default(); + fixup.images = images; ret = event_notify(EVT_FT_FIXUP, &fixup, sizeof(fixup)); if (ret) { printf("ERROR: fdt fixup event failed: %d\n", ret); diff --git a/include/event.h b/include/event.h index ff883ca064e..3e6dcbc3dd6 100644 --- a/include/event.h +++ b/include/event.h @@ -60,9 +60,11 @@ union event_data { * struct event_ft_fixup - FDT fixup before booting * * @tree: tree to update + * @images: images which are being booted */ struct event_ft_fixup { oftree tree; + struct bootm_headers *images; } ft_fixup; };

At present the live tree tests are not run on sandbox. This bug is in two parts, with a duplicate flag value and incorrect logic in the test runner. This was not noticed because the bug was fixed in a later commit and does not cause test failures.
Fix this.
Fixes: 7b1dfc9fd7e ("dm: core: Prepare for updating the device tree with ofnode")
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
include/test/test.h | 2 +- test/dm/ofnode.c | 4 ++++ test/test-main.c | 3 +-- 3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/include/test/test.h b/include/test/test.h index c888d68b1ed..0d32d914685 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -47,7 +47,7 @@ enum { /* do extra driver model init and uninit */ UT_TESTF_DM = BIT(6), /* live or flat device tree, but not both in the same executable */ - UT_TESTF_LIVE_OR_FLAT = BIT(4), + UT_TESTF_LIVE_OR_FLAT = BIT(7), };
/** diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index f80993f8927..4624a08d275 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -546,6 +546,10 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) struct udevice *dev; ofnode node;
+ /* temporarily disable this test due to a failure fixed later */ + if (!of_live_active()) + return 0; + /* Test enabling devices */ node = ofnode_path("/usb@2");
diff --git a/test/test-main.c b/test/test-main.c index 31837e57a8f..c65cbd7c351 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -340,8 +340,7 @@ static int ut_run_test_live_flat(struct unit_test_state *uts, /* Run with the live tree if possible */ runs = 0; if (CONFIG_IS_ENABLED(OF_LIVE)) { - if (!(test->flags & - (UT_TESTF_FLAT_TREE | UT_TESTF_LIVE_OR_FLAT))) { + if (!(test->flags & UT_TESTF_FLAT_TREE)) { uts->of_live = true; ut_assertok(ut_run_test(uts, test, test->name)); runs++;

It is helpful to test that out-of-memory checks work correctly in code that calls malloc().
Add a simple way to force failure after a given number of malloc() calls.
Fix a header guard to avoid a build error on sandbox_vpl.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
arch/sandbox/include/asm/malloc.h | 1 + common/dlmalloc.c | 19 +++++++++++++++++++ include/malloc.h | 12 ++++++++++++ test/test-main.c | 1 + 4 files changed, 33 insertions(+)
diff --git a/arch/sandbox/include/asm/malloc.h b/arch/sandbox/include/asm/malloc.h index a1467b5eadd..8aaaa9cb87b 100644 --- a/arch/sandbox/include/asm/malloc.h +++ b/arch/sandbox/include/asm/malloc.h @@ -6,6 +6,7 @@ */
#ifndef __ASM_MALLOC_H +#define __ASM_MALLOC_H
void *malloc(size_t size); void free(void *ptr); diff --git a/common/dlmalloc.c b/common/dlmalloc.c index f48cd2a333d..41c7230424c 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -596,6 +596,9 @@ ulong mem_malloc_start = 0; ulong mem_malloc_end = 0; ulong mem_malloc_brk = 0;
+static bool malloc_testing; /* enable test mode */ +static int malloc_max_allocs; /* return NULL after this many calls to malloc() */ + void *sbrk(ptrdiff_t increment) { ulong old = mem_malloc_brk; @@ -1307,6 +1310,11 @@ Void_t* mALLOc(bytes) size_t bytes; return malloc_simple(bytes); #endif
+ if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) { + if (--malloc_max_allocs < 0) + return NULL; + } + /* check if mem_malloc_init() was run */ if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) { /* not initialized yet */ @@ -2470,6 +2478,17 @@ int initf_malloc(void) return 0; }
+void malloc_enable_testing(int max_allocs) +{ + malloc_testing = true; + malloc_max_allocs = max_allocs; +} + +void malloc_disable_testing(void) +{ + malloc_testing = false; +} + /*
History: diff --git a/include/malloc.h b/include/malloc.h index e8c8b254c0d..161ccbd1298 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -883,6 +883,18 @@ extern Void_t* sbrk();
void malloc_simple_info(void);
+/** + * malloc_enable_testing() - Put malloc() into test mode + * + * This only works if UNIT_TESTING is enabled + * + * @max_allocs: return -ENOMEM after max_allocs calls to malloc() + */ +void malloc_enable_testing(int max_allocs); + +/** malloc_disable_testing() - Put malloc() into normal mode */ +void malloc_disable_testing(void); + #if CONFIG_IS_ENABLED(SYS_MALLOC_SIMPLE) #define malloc malloc_simple #define realloc realloc_simple diff --git a/test/test-main.c b/test/test-main.c index c65cbd7c351..5b6b5ba5bbe 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -46,6 +46,7 @@ static int dm_test_pre_run(struct unit_test_state *uts) uts->force_fail_alloc = false; uts->skip_post_probe = false; gd->dm_root = NULL; + malloc_disable_testing(); if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA)) memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); arch_reset_for_test();

On 9/6/22 22:27, Simon Glass wrote:
It is helpful to test that out-of-memory checks work correctly in code that calls malloc().
Add a simple way to force failure after a given number of malloc() calls.
Fix a header guard to avoid a build error on sandbox_vpl.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v1)
arch/sandbox/include/asm/malloc.h | 1 + common/dlmalloc.c | 19 +++++++++++++++++++ include/malloc.h | 12 ++++++++++++ test/test-main.c | 1 + 4 files changed, 33 insertions(+)
diff --git a/arch/sandbox/include/asm/malloc.h b/arch/sandbox/include/asm/malloc.h index a1467b5eadd..8aaaa9cb87b 100644 --- a/arch/sandbox/include/asm/malloc.h +++ b/arch/sandbox/include/asm/malloc.h @@ -6,6 +6,7 @@ */
#ifndef __ASM_MALLOC_H +#define __ASM_MALLOC_H
void *malloc(size_t size); void free(void *ptr); diff --git a/common/dlmalloc.c b/common/dlmalloc.c index f48cd2a333d..41c7230424c 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -596,6 +596,9 @@ ulong mem_malloc_start = 0; ulong mem_malloc_end = 0; ulong mem_malloc_brk = 0;
+static bool malloc_testing; /* enable test mode */ +static int malloc_max_allocs; /* return NULL after this many calls to malloc() */
- void *sbrk(ptrdiff_t increment) { ulong old = mem_malloc_brk;
@@ -1307,6 +1310,11 @@ Void_t* mALLOc(bytes) size_t bytes; return malloc_simple(bytes); #endif
- if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) {
- if (--malloc_max_allocs < 0)
return NULL;
- }
- /* check if mem_malloc_init() was run */ if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) { /* not initialized yet */
@@ -2470,6 +2478,17 @@ int initf_malloc(void) return 0; }
+void malloc_enable_testing(int max_allocs) +{
- malloc_testing = true;
- malloc_max_allocs = max_allocs;
+}
+void malloc_disable_testing(void) +{
- malloc_testing = false;
+}
/*
History:
diff --git a/include/malloc.h b/include/malloc.h index e8c8b254c0d..161ccbd1298 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -883,6 +883,18 @@ extern Void_t* sbrk();
void malloc_simple_info(void);
+/**
- malloc_enable_testing() - Put malloc() into test mode
- This only works if UNIT_TESTING is enabled
- @max_allocs: return -ENOMEM after max_allocs calls to malloc()
- */
+void malloc_enable_testing(int max_allocs);
+/** malloc_disable_testing() - Put malloc() into normal mode */ +void malloc_disable_testing(void);
- #if CONFIG_IS_ENABLED(SYS_MALLOC_SIMPLE) #define malloc malloc_simple #define realloc realloc_simple
diff --git a/test/test-main.c b/test/test-main.c index c65cbd7c351..5b6b5ba5bbe 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -46,6 +46,7 @@ static int dm_test_pre_run(struct unit_test_state *uts) uts->force_fail_alloc = false; uts->skip_post_probe = false; gd->dm_root = NULL;
- malloc_disable_testing(); if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA)) memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); arch_reset_for_test();
Reviewed-by: Sean Anderson seanga2@gmail.com
but do we need to instrument rEALLOc too?

Hi Sean,
On Wed, 28 Sept 2022 at 11:18, Sean Anderson seanga2@gmail.com wrote:
On 9/6/22 22:27, Simon Glass wrote:
It is helpful to test that out-of-memory checks work correctly in code that calls malloc().
Add a simple way to force failure after a given number of malloc() calls.
Fix a header guard to avoid a build error on sandbox_vpl.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v1)
arch/sandbox/include/asm/malloc.h | 1 + common/dlmalloc.c | 19 +++++++++++++++++++ include/malloc.h | 12 ++++++++++++ test/test-main.c | 1 + 4 files changed, 33 insertions(+)
diff --git a/arch/sandbox/include/asm/malloc.h b/arch/sandbox/include/asm/malloc.h index a1467b5eadd..8aaaa9cb87b 100644 --- a/arch/sandbox/include/asm/malloc.h +++ b/arch/sandbox/include/asm/malloc.h @@ -6,6 +6,7 @@ */
#ifndef __ASM_MALLOC_H +#define __ASM_MALLOC_H
void *malloc(size_t size); void free(void *ptr); diff --git a/common/dlmalloc.c b/common/dlmalloc.c index f48cd2a333d..41c7230424c 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -596,6 +596,9 @@ ulong mem_malloc_start = 0; ulong mem_malloc_end = 0; ulong mem_malloc_brk = 0;
+static bool malloc_testing; /* enable test mode */ +static int malloc_max_allocs; /* return NULL after this many calls to malloc() */
- void *sbrk(ptrdiff_t increment) { ulong old = mem_malloc_brk;
@@ -1307,6 +1310,11 @@ Void_t* mALLOc(bytes) size_t bytes; return malloc_simple(bytes); #endif
- if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) {
- if (--malloc_max_allocs < 0)
return NULL;
- }
- /* check if mem_malloc_init() was run */ if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) { /* not initialized yet */
@@ -2470,6 +2478,17 @@ int initf_malloc(void) return 0; }
+void malloc_enable_testing(int max_allocs) +{
malloc_testing = true;
malloc_max_allocs = max_allocs;
+}
+void malloc_disable_testing(void) +{
malloc_testing = false;
+}
/*
History:
diff --git a/include/malloc.h b/include/malloc.h index e8c8b254c0d..161ccbd1298 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -883,6 +883,18 @@ extern Void_t* sbrk();
void malloc_simple_info(void);
+/**
- malloc_enable_testing() - Put malloc() into test mode
- This only works if UNIT_TESTING is enabled
- @max_allocs: return -ENOMEM after max_allocs calls to malloc()
- */
+void malloc_enable_testing(int max_allocs);
+/** malloc_disable_testing() - Put malloc() into normal mode */ +void malloc_disable_testing(void);
- #if CONFIG_IS_ENABLED(SYS_MALLOC_SIMPLE) #define malloc malloc_simple #define realloc realloc_simple
diff --git a/test/test-main.c b/test/test-main.c index c65cbd7c351..5b6b5ba5bbe 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -46,6 +46,7 @@ static int dm_test_pre_run(struct unit_test_state *uts) uts->force_fail_alloc = false; uts->skip_post_probe = false; gd->dm_root = NULL;
malloc_disable_testing(); if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA)) memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); arch_reset_for_test();
Reviewed-by: Sean Anderson seanga2@gmail.com
but do we need to instrument rEALLOc too?
We could, but I'd prefer to have a test which needs it first. Actually realloc() calls malloc() in some cases, so we are already messing with things here.
Regards, Simon

On 9/28/22 17:06, Simon Glass wrote:
Hi Sean,
On Wed, 28 Sept 2022 at 11:18, Sean Anderson seanga2@gmail.com wrote:
On 9/6/22 22:27, Simon Glass wrote:
It is helpful to test that out-of-memory checks work correctly in code that calls malloc().
Add a simple way to force failure after a given number of malloc() calls.
Fix a header guard to avoid a build error on sandbox_vpl.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v1)
arch/sandbox/include/asm/malloc.h | 1 + common/dlmalloc.c | 19 +++++++++++++++++++ include/malloc.h | 12 ++++++++++++ test/test-main.c | 1 + 4 files changed, 33 insertions(+)
diff --git a/arch/sandbox/include/asm/malloc.h b/arch/sandbox/include/asm/malloc.h index a1467b5eadd..8aaaa9cb87b 100644 --- a/arch/sandbox/include/asm/malloc.h +++ b/arch/sandbox/include/asm/malloc.h @@ -6,6 +6,7 @@ */
#ifndef __ASM_MALLOC_H +#define __ASM_MALLOC_H
void *malloc(size_t size); void free(void *ptr); diff --git a/common/dlmalloc.c b/common/dlmalloc.c index f48cd2a333d..41c7230424c 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -596,6 +596,9 @@ ulong mem_malloc_start = 0; ulong mem_malloc_end = 0; ulong mem_malloc_brk = 0;
+static bool malloc_testing; /* enable test mode */ +static int malloc_max_allocs; /* return NULL after this many calls to malloc() */
- void *sbrk(ptrdiff_t increment) { ulong old = mem_malloc_brk;
@@ -1307,6 +1310,11 @@ Void_t* mALLOc(bytes) size_t bytes; return malloc_simple(bytes); #endif
- if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) {
- if (--malloc_max_allocs < 0)
return NULL;
- }
- /* check if mem_malloc_init() was run */ if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) { /* not initialized yet */
@@ -2470,6 +2478,17 @@ int initf_malloc(void) return 0; }
+void malloc_enable_testing(int max_allocs) +{
malloc_testing = true;
malloc_max_allocs = max_allocs;
+}
+void malloc_disable_testing(void) +{
malloc_testing = false;
+}
/*
History:
diff --git a/include/malloc.h b/include/malloc.h index e8c8b254c0d..161ccbd1298 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -883,6 +883,18 @@ extern Void_t* sbrk();
void malloc_simple_info(void);
+/**
- malloc_enable_testing() - Put malloc() into test mode
- This only works if UNIT_TESTING is enabled
- @max_allocs: return -ENOMEM after max_allocs calls to malloc()
- */
+void malloc_enable_testing(int max_allocs);
+/** malloc_disable_testing() - Put malloc() into normal mode */ +void malloc_disable_testing(void);
- #if CONFIG_IS_ENABLED(SYS_MALLOC_SIMPLE) #define malloc malloc_simple #define realloc realloc_simple
diff --git a/test/test-main.c b/test/test-main.c index c65cbd7c351..5b6b5ba5bbe 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -46,6 +46,7 @@ static int dm_test_pre_run(struct unit_test_state *uts) uts->force_fail_alloc = false; uts->skip_post_probe = false; gd->dm_root = NULL;
malloc_disable_testing(); if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA)) memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); arch_reset_for_test();
Reviewed-by: Sean Anderson seanga2@gmail.com
but do we need to instrument rEALLOc too?
We could, but I'd prefer to have a test which needs it first. Actually realloc() calls malloc() in some cases, so we are already messing with things here.
Maybe it would be better to do this at the "top-level" instead. E.g. redefine the malloc() et al macro. That way we remove any double-counting.
--Sean

Hi Sean,
On Wed, 28 Sept 2022 at 15:50, Sean Anderson seanga2@gmail.com wrote:
On 9/28/22 17:06, Simon Glass wrote:
Hi Sean,
On Wed, 28 Sept 2022 at 11:18, Sean Anderson seanga2@gmail.com wrote:
On 9/6/22 22:27, Simon Glass wrote:
It is helpful to test that out-of-memory checks work correctly in code that calls malloc().
Add a simple way to force failure after a given number of malloc() calls.
Fix a header guard to avoid a build error on sandbox_vpl.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v1)
arch/sandbox/include/asm/malloc.h | 1 + common/dlmalloc.c | 19 +++++++++++++++++++ include/malloc.h | 12 ++++++++++++ test/test-main.c | 1 + 4 files changed, 33 insertions(+)
diff --git a/arch/sandbox/include/asm/malloc.h b/arch/sandbox/include/asm/malloc.h index a1467b5eadd..8aaaa9cb87b 100644 --- a/arch/sandbox/include/asm/malloc.h +++ b/arch/sandbox/include/asm/malloc.h @@ -6,6 +6,7 @@ */
#ifndef __ASM_MALLOC_H +#define __ASM_MALLOC_H
void *malloc(size_t size); void free(void *ptr); diff --git a/common/dlmalloc.c b/common/dlmalloc.c index f48cd2a333d..41c7230424c 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -596,6 +596,9 @@ ulong mem_malloc_start = 0; ulong mem_malloc_end = 0; ulong mem_malloc_brk = 0;
+static bool malloc_testing; /* enable test mode */ +static int malloc_max_allocs; /* return NULL after this many calls to malloc() */
- void *sbrk(ptrdiff_t increment) { ulong old = mem_malloc_brk;
@@ -1307,6 +1310,11 @@ Void_t* mALLOc(bytes) size_t bytes; return malloc_simple(bytes); #endif
- if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) {
- if (--malloc_max_allocs < 0)
return NULL;
- }
- /* check if mem_malloc_init() was run */ if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) { /* not initialized yet */
@@ -2470,6 +2478,17 @@ int initf_malloc(void) return 0; }
+void malloc_enable_testing(int max_allocs) +{
malloc_testing = true;
malloc_max_allocs = max_allocs;
+}
+void malloc_disable_testing(void) +{
malloc_testing = false;
+}
/*
History:
diff --git a/include/malloc.h b/include/malloc.h index e8c8b254c0d..161ccbd1298 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -883,6 +883,18 @@ extern Void_t* sbrk();
void malloc_simple_info(void);
+/**
- malloc_enable_testing() - Put malloc() into test mode
- This only works if UNIT_TESTING is enabled
- @max_allocs: return -ENOMEM after max_allocs calls to malloc()
- */
+void malloc_enable_testing(int max_allocs);
+/** malloc_disable_testing() - Put malloc() into normal mode */ +void malloc_disable_testing(void);
- #if CONFIG_IS_ENABLED(SYS_MALLOC_SIMPLE) #define malloc malloc_simple #define realloc realloc_simple
diff --git a/test/test-main.c b/test/test-main.c index c65cbd7c351..5b6b5ba5bbe 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -46,6 +46,7 @@ static int dm_test_pre_run(struct unit_test_state *uts) uts->force_fail_alloc = false; uts->skip_post_probe = false; gd->dm_root = NULL;
malloc_disable_testing(); if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA)) memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); arch_reset_for_test();
Reviewed-by: Sean Anderson seanga2@gmail.com
but do we need to instrument rEALLOc too?
We could, but I'd prefer to have a test which needs it first. Actually realloc() calls malloc() in some cases, so we are already messing with things here.
Maybe it would be better to do this at the "top-level" instead. E.g. redefine the malloc() et al macro. That way we remove any double-counting.
Yes, that makes sense. But again, I'd rather do this when we have a use case for making realloc() fail.
BTW has dlmalloc been updated in recent years?
Regards, Simon
--Sean

On 9/28/22 22:36, Simon Glass wrote:
Hi Sean,
On Wed, 28 Sept 2022 at 15:50, Sean Anderson seanga2@gmail.com wrote:
On 9/28/22 17:06, Simon Glass wrote:
Hi Sean,
On Wed, 28 Sept 2022 at 11:18, Sean Anderson seanga2@gmail.com wrote:
On 9/6/22 22:27, Simon Glass wrote:
It is helpful to test that out-of-memory checks work correctly in code that calls malloc().
Add a simple way to force failure after a given number of malloc() calls.
Fix a header guard to avoid a build error on sandbox_vpl.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v1)
arch/sandbox/include/asm/malloc.h | 1 + common/dlmalloc.c | 19 +++++++++++++++++++ include/malloc.h | 12 ++++++++++++ test/test-main.c | 1 + 4 files changed, 33 insertions(+)
diff --git a/arch/sandbox/include/asm/malloc.h b/arch/sandbox/include/asm/malloc.h index a1467b5eadd..8aaaa9cb87b 100644 --- a/arch/sandbox/include/asm/malloc.h +++ b/arch/sandbox/include/asm/malloc.h @@ -6,6 +6,7 @@ */
#ifndef __ASM_MALLOC_H
+#define __ASM_MALLOC_H
void *malloc(size_t size); void free(void *ptr);
diff --git a/common/dlmalloc.c b/common/dlmalloc.c index f48cd2a333d..41c7230424c 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -596,6 +596,9 @@ ulong mem_malloc_start = 0; ulong mem_malloc_end = 0; ulong mem_malloc_brk = 0;
+static bool malloc_testing; /* enable test mode */ +static int malloc_max_allocs; /* return NULL after this many calls to malloc() */
- void *sbrk(ptrdiff_t increment) { ulong old = mem_malloc_brk;
@@ -1307,6 +1310,11 @@ Void_t* mALLOc(bytes) size_t bytes; return malloc_simple(bytes); #endif
- if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) {
- if (--malloc_max_allocs < 0)
return NULL;
- }
/* check if mem_malloc_init() was run */ if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) { /* not initialized yet */
@@ -2470,6 +2478,17 @@ int initf_malloc(void) return 0; }
+void malloc_enable_testing(int max_allocs) +{
malloc_testing = true;
malloc_max_allocs = max_allocs;
+}
+void malloc_disable_testing(void) +{
malloc_testing = false;
+}
/*
History:
diff --git a/include/malloc.h b/include/malloc.h index e8c8b254c0d..161ccbd1298 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -883,6 +883,18 @@ extern Void_t* sbrk();
void malloc_simple_info(void);
+/**
- malloc_enable_testing() - Put malloc() into test mode
- This only works if UNIT_TESTING is enabled
- @max_allocs: return -ENOMEM after max_allocs calls to malloc()
- */
+void malloc_enable_testing(int max_allocs);
+/** malloc_disable_testing() - Put malloc() into normal mode */ +void malloc_disable_testing(void);
- #if CONFIG_IS_ENABLED(SYS_MALLOC_SIMPLE) #define malloc malloc_simple #define realloc realloc_simple
diff --git a/test/test-main.c b/test/test-main.c index c65cbd7c351..5b6b5ba5bbe 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -46,6 +46,7 @@ static int dm_test_pre_run(struct unit_test_state *uts) uts->force_fail_alloc = false; uts->skip_post_probe = false; gd->dm_root = NULL;
malloc_disable_testing(); if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA)) memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); arch_reset_for_test();
Reviewed-by: Sean Anderson seanga2@gmail.com
but do we need to instrument rEALLOc too?
We could, but I'd prefer to have a test which needs it first. Actually realloc() calls malloc() in some cases, so we are already messing with things here.
Maybe it would be better to do this at the "top-level" instead. E.g. redefine the malloc() et al macro. That way we remove any double-counting.
Yes, that makes sense. But again, I'd rather do this when we have a use case for making realloc() fail.
Fine by me.
BTW has dlmalloc been updated in recent years?
Apparently there's a 2.8.6, last updated in 2012 [1].
--Sean

On Thu, Sep 29, 2022 at 12:02:43AM -0400, Sean Anderson wrote:
On 9/28/22 22:36, Simon Glass wrote:
Hi Sean,
On Wed, 28 Sept 2022 at 15:50, Sean Anderson seanga2@gmail.com wrote:
On 9/28/22 17:06, Simon Glass wrote:
Hi Sean,
On Wed, 28 Sept 2022 at 11:18, Sean Anderson seanga2@gmail.com wrote:
On 9/6/22 22:27, Simon Glass wrote:
It is helpful to test that out-of-memory checks work correctly in code that calls malloc().
Add a simple way to force failure after a given number of malloc() calls.
Fix a header guard to avoid a build error on sandbox_vpl.
Signed-off-by: Simon Glass sjg@chromium.org
(no changes since v1)
arch/sandbox/include/asm/malloc.h | 1 + common/dlmalloc.c | 19 +++++++++++++++++++ include/malloc.h | 12 ++++++++++++ test/test-main.c | 1 + 4 files changed, 33 insertions(+)
diff --git a/arch/sandbox/include/asm/malloc.h b/arch/sandbox/include/asm/malloc.h index a1467b5eadd..8aaaa9cb87b 100644 --- a/arch/sandbox/include/asm/malloc.h +++ b/arch/sandbox/include/asm/malloc.h @@ -6,6 +6,7 @@ */
#ifndef __ASM_MALLOC_H
+#define __ASM_MALLOC_H
void *malloc(size_t size); void free(void *ptr);
diff --git a/common/dlmalloc.c b/common/dlmalloc.c index f48cd2a333d..41c7230424c 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -596,6 +596,9 @@ ulong mem_malloc_start = 0; ulong mem_malloc_end = 0; ulong mem_malloc_brk = 0;
+static bool malloc_testing; /* enable test mode */ +static int malloc_max_allocs; /* return NULL after this many calls to malloc() */
- void *sbrk(ptrdiff_t increment) { ulong old = mem_malloc_brk;
@@ -1307,6 +1310,11 @@ Void_t* mALLOc(bytes) size_t bytes; return malloc_simple(bytes); #endif
- if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) {
- if (--malloc_max_allocs < 0)
return NULL;
- }
/* check if mem_malloc_init() was run */ if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) { /* not initialized yet */
@@ -2470,6 +2478,17 @@ int initf_malloc(void) return 0; }
+void malloc_enable_testing(int max_allocs) +{
malloc_testing = true;
malloc_max_allocs = max_allocs;
+}
+void malloc_disable_testing(void) +{
malloc_testing = false;
+}
/*
History:
diff --git a/include/malloc.h b/include/malloc.h index e8c8b254c0d..161ccbd1298 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -883,6 +883,18 @@ extern Void_t* sbrk();
void malloc_simple_info(void);
+/**
- malloc_enable_testing() - Put malloc() into test mode
- This only works if UNIT_TESTING is enabled
- @max_allocs: return -ENOMEM after max_allocs calls to malloc()
- */
+void malloc_enable_testing(int max_allocs);
+/** malloc_disable_testing() - Put malloc() into normal mode */ +void malloc_disable_testing(void);
- #if CONFIG_IS_ENABLED(SYS_MALLOC_SIMPLE) #define malloc malloc_simple #define realloc realloc_simple
diff --git a/test/test-main.c b/test/test-main.c index c65cbd7c351..5b6b5ba5bbe 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -46,6 +46,7 @@ static int dm_test_pre_run(struct unit_test_state *uts) uts->force_fail_alloc = false; uts->skip_post_probe = false; gd->dm_root = NULL;
malloc_disable_testing(); if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA)) memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); arch_reset_for_test();
Reviewed-by: Sean Anderson seanga2@gmail.com
but do we need to instrument rEALLOc too?
We could, but I'd prefer to have a test which needs it first. Actually realloc() calls malloc() in some cases, so we are already messing with things here.
Maybe it would be better to do this at the "top-level" instead. E.g. redefine the malloc() et al macro. That way we remove any double-counting.
Yes, that makes sense. But again, I'd rather do this when we have a use case for making realloc() fail.
Fine by me.
BTW has dlmalloc been updated in recent years?
Apparently there's a 2.8.6, last updated in 2012 [1].
And I _think_ when I looked a year or two back there wasn't anything standing out as an important to try and update change in there. But I could be wrong and have missed something.

Clarify the data structure so it is easier for people to understand, particularly the corner cases.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
include/dm/of.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/include/dm/of.h b/include/dm/of.h index 9c9065b7932..fce7cef0ff6 100644 --- a/include/dm/of.h +++ b/include/dm/of.h @@ -31,10 +31,21 @@ struct property { /** * struct device_node: Device tree node * - * @name: Node name + * The top of this tree is typically gd->of_root which points to the root node. + * + * The head of the list of children for the root node (and any other node) is + * in @child, with @sibling providing a link to the next child. + * + * Each child has a pointer to its parent in @parent. + * + * A node may have properties in which case the head of the list of properties + * @properties pointers to the first one, with struct property->@next pointing + * to the next one. + * + * @name: Node name, "" for the root node * @type: Node type (value of device_type property) or "<NULL>" if none * @phandle: Phandle value of this none, or 0 if none - * @full_name: Full path to node, e.g. "/bus@1/spi@1100" + * @full_name: Full path to node, e.g. "/bus@1/spi@1100" ("/" for the root node) * @properties: Pointer to head of list of properties, or NULL if none * @parent: Pointer to parent node, or NULL if this is the root node * @child: Pointer to head of child node list, or NULL if no children

Add this feature to the ofnode interface, supporting both livetree and flattree. If the node exists it is returned, along with a -EEXIST error. Update the functions it calls to handle this too.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Return the existing node with -EEXIST - Allow len to be passed in as -1 - Add a comment as to why strncmp() is not enough - Add a comment why the len parameter is needed - Add a comment why the new_name variable is used - Add tests for the memory checks in of_add_subnode() - Fix memory checks - Fix 'property' comment - Add lots more tests and a few other fixes - Gosh that code was a mess
drivers/core/of_access.c | 63 +++++++++++++++++++++++++++++++++++ drivers/core/ofnode.c | 35 ++++++++++++++++++++ include/dm/of_access.h | 15 +++++++++ include/dm/ofnode.h | 13 ++++++++ test/dm/ofnode.c | 71 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 197 insertions(+)
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index ee09bbb7550..8306d69eed0 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -931,3 +931,66 @@ int of_write_prop(struct device_node *np, const char *propname, int len,
return 0; } + +int of_add_subnode(struct device_node *parent, const char *name, int len, + struct device_node **childp) +{ + struct device_node *child, *new, *last_sibling = NULL; + char *new_name, *full_name; + int parent_fnl; + + if (len == -1) + len = strlen(name); + __for_each_child_of_node(parent, child) { + /* + * make sure we don't use a child called "trevor" when we are + * searching for "trev". + */ + if (!strncmp(child->name, name, len) && strlen(name) == len) { + *childp = child; + return -EEXIST; + } + last_sibling = child; + } + + /* Subnode does not exist -> append new subnode */ + new = calloc(1, sizeof(struct device_node)); + if (!new) + return -ENOMEM; + + new_name = memdup(name, len + 1); + if (!new_name) { + free(new); + return -ENOMEM; + } + new_name[len] = '\0'; + + /* + * if the parent is the root node (named "") we don't need to prepend + * its full path + */ + parent_fnl = *parent->name ? strlen(parent->full_name) : 0; + full_name = calloc(1, parent_fnl + 1 + len + 1); + if (!full_name) { + free(new_name); + free(new); + return -ENOMEM; + } + new->name = new_name; /* assign to constant pointer */ + + strcpy(full_name, parent->full_name); /* "" for root node */ + full_name[parent_fnl] = '/'; + strlcpy(&full_name[parent_fnl + 1], name, len + 1); + new->full_name = full_name; + + /* Add as last sibling of the parent */ + if (last_sibling) + last_sibling->sibling = new; + if (!parent->child) + parent->child = new; + new->parent = parent; + + *childp = new; + + return 0; +} diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index bf8eaf6d09a..855f5f40647 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -1227,3 +1227,38 @@ phy_interface_t ofnode_read_phy_mode(ofnode node)
return PHY_INTERFACE_MODE_NA; } + +int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep) +{ + ofnode subnode; + int ret = 0; + + assert(ofnode_valid(node)); + + if (ofnode_is_np(node)) { + struct device_node *np, *child; + + np = (struct device_node *)ofnode_to_np(node); + ret = of_add_subnode(np, name, -1, &child); + if (ret && ret != -EEXIST) + return ret; + subnode = np_to_ofnode(child); + } else { + void *fdt = (void *)gd->fdt_blob; + int poffset = ofnode_to_offset(node); + int offset; + + offset = fdt_add_subnode(fdt, poffset, name); + if (offset == -FDT_ERR_EXISTS) { + offset = fdt_subnode_offset(fdt, poffset, name); + ret = -EEXIST; + } + if (offset < 0) + return -EINVAL; + subnode = offset_to_ofnode(offset); + } + + *subnodep = subnode; + + return ret; /* 0 or -EEXIST */ +} diff --git a/include/dm/of_access.h b/include/dm/of_access.h index c0ac91a416a..ed94dd3d3a4 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -533,4 +533,19 @@ struct device_node *of_get_stdout(void); int of_write_prop(struct device_node *np, const char *propname, int len, const void *value);
+/** + * of_add_subnode() - add a new subnode to a node + * + * @node: parent node to add to + * @name: name of subnode + * @len: length of name (so the caller does not need to nul-terminate a + * partial string), or -1 for strlen(@name) + * @subnodep: returns pointer to new subnode (valid if the function returns 0 + * or -EEXIST) + * Returns 0 if OK, -EEXIST if already exists, -ENOMEM if out of memory, other + * -ve on other error + */ +int of_add_subnode(struct device_node *node, const char *name, int len, + struct device_node **subnodep); + #endif diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 018ee70c2ff..e09127d1ce2 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -1260,6 +1260,19 @@ static inline const char *ofnode_conf_read_str(const char *prop_name) { return NULL; } + #endif /* CONFIG_DM */
+/** + * of_add_subnode() - add a new subnode to a node + * + * @parent: parent node to add to + * @name: name of subnode + * @nodep: returns pointer to new subnode (valid if the function returns 0 + * or -EEXIST) + * Returns 0 if OK, -EEXIST if already exists, -ENOMEM if out of memory, other + * -ve on other error + */ +int ofnode_add_subnode(ofnode parent, const char *name, ofnode *nodep); + #endif diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 4624a08d275..543dc546b95 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -605,3 +605,74 @@ static int dm_test_ofnode_u32(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_u32, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT); + +static int dm_test_ofnode_add_subnode(struct unit_test_state *uts) +{ + ofnode node, check, subnode; + char buf[128]; + + /* temporarily disable this test due to a failure fixed later */ + if (!of_live_active()) + return 0; + + node = ofnode_path("/lcd"); + ut_assert(ofnode_valid(node)); + ut_assertok(ofnode_add_subnode(node, "edmund", &subnode)); + check = ofnode_path("/lcd/edmund"); + ut_asserteq(subnode.of_offset, check.of_offset); + ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf))); + ut_asserteq_str("/lcd/edmund", buf); + + if (of_live_active()) { + struct device_node *child; + + ut_assertok(of_add_subnode((void *)ofnode_to_np(node), "edmund", + 2, &child)); + ut_asserteq_str("ed", child->name); + ut_asserteq_str("/lcd/ed", child->full_name); + check = ofnode_path("/lcd/ed"); + ut_asserteq_ptr(child, check.np); + ut_assertok(ofnode_get_path(np_to_ofnode(child), buf, + sizeof(buf))); + ut_asserteq_str("/lcd/ed", buf); + } + + /* An existing node should be returned with -EEXIST */ + ut_asserteq(-EEXIST, ofnode_add_subnode(node, "edmund", &check)); + ut_asserteq(subnode.of_offset, check.of_offset); + + /* add a root node */ + node = ofnode_path("/"); + ut_assert(ofnode_valid(node)); + ut_assertok(ofnode_add_subnode(node, "lcd2", &subnode)); + check = ofnode_path("/lcd2"); + ut_asserteq(subnode.of_offset, check.of_offset); + ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf))); + ut_asserteq_str("/lcd2", buf); + + if (of_live_active()) { + ulong start; + int i; + + /* + * Make sure each of the three malloc()checks in + * of_add_subnode() work + */ + for (i = 0; i < 3; i++) { + malloc_enable_testing(i); + start = ut_check_free(); + ut_asserteq(-ENOMEM, ofnode_add_subnode(node, "anthony", + &check)); + ut_assertok(ut_check_delta(start)); + } + + /* This should pass since we allow 3 allocations */ + malloc_enable_testing(3); + ut_assertok(ofnode_add_subnode(node, "anthony", &check)); + malloc_disable_testing(); + } + + return 0; +} +DM_TEST(dm_test_ofnode_add_subnode, + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT);

At present this does not work with livetree. Fix it and add a test.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/core/of_access.c | 8 ++++---- test/dm/ofnode.c | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index 8306d69eed0..85716ac621b 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -909,9 +909,6 @@ int of_write_prop(struct device_node *np, const char *propname, int len, pp_last = pp; }
- if (!pp_last) - return -ENOENT; - /* Property does not exist -> append new property */ new = malloc(sizeof(struct property)); if (!new) @@ -927,7 +924,10 @@ int of_write_prop(struct device_node *np, const char *propname, int len, new->length = len; new->next = NULL;
- pp_last->next = new; + if (pp_last) + pp_last->next = new; + else + np->properties = new;
return 0; } diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 543dc546b95..0f65ff939fb 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -672,6 +672,9 @@ static int dm_test_ofnode_add_subnode(struct unit_test_state *uts) malloc_disable_testing(); }
+ /* write to the empty node */ + ut_assertok(ofnode_write_string(subnode, "example", "text")); + return 0; } DM_TEST(dm_test_ofnode_add_subnode,

Now that we support writing to ofnodes, the const is not accurate. Drop it to avoid undesirable casting.
Also drop the ofnode_to_npw() which is now the same as ofnode_to_np().
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/core/ofnode.c | 4 ++-- include/dm/ofnode.h | 22 ++-------------------- include/dm/ofnode_decl.h | 2 +- 3 files changed, 5 insertions(+), 23 deletions(-)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 855f5f40647..ac6d259601c 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -206,7 +206,7 @@ ofnode ofnode_find_subnode(ofnode node, const char *subnode_name) debug("%s: %s: ", __func__, subnode_name);
if (ofnode_is_np(node)) { - const struct device_node *np = ofnode_to_np(node); + struct device_node *np = ofnode_to_np(node);
for (np = np->child; np; np = np->sibling) { if (!strcmp(subnode_name, np->name)) @@ -1109,7 +1109,7 @@ int ofnode_write_prop(ofnode node, const char *propname, const void *value, int len) { if (of_live_active()) - return of_write_prop(ofnode_to_npw(node), propname, len, value); + return of_write_prop(ofnode_to_np(node), propname, len, value); else return fdt_setprop((void *)gd->fdt_blob, ofnode_to_offset(node), propname, value, len); diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index e09127d1ce2..ee762442784 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -35,7 +35,7 @@ struct ofnode_phandle_args { * @node: Reference containing struct device_node * (possibly invalid) * Return: pointer to device node (can be NULL) */ -static inline const struct device_node *ofnode_to_np(ofnode node) +static inline struct device_node *ofnode_to_np(ofnode node) { #ifdef OF_CHECKS if (!of_live_active()) @@ -44,24 +44,6 @@ static inline const struct device_node *ofnode_to_np(ofnode node) return node.np; }
-/** - * ofnode_to_npw() - convert an ofnode to a writeable live DT node pointer - * - * This cannot be called if the reference contains an offset. - * - * @node: Reference containing struct device_node * (possibly invalid) - * Return: pointer to device node (can be NULL) - */ -static inline struct device_node *ofnode_to_npw(ofnode node) -{ -#ifdef OF_CHECKS - if (!of_live_active()) - return NULL; -#endif - /* Drop constant */ - return (struct device_node *)node.np; -} - /** * ofnode_to_offset() - convert an ofnode to a flat DT offset * @@ -117,7 +99,7 @@ static inline ofnode offset_to_ofnode(int of_offset) * @np: Live node pointer (can be NULL) * Return: reference to the associated node pointer */ -static inline ofnode np_to_ofnode(const struct device_node *np) +static inline ofnode np_to_ofnode(struct device_node *np) { ofnode node;
diff --git a/include/dm/ofnode_decl.h b/include/dm/ofnode_decl.h index 266253d5e33..8d0d7885aa6 100644 --- a/include/dm/ofnode_decl.h +++ b/include/dm/ofnode_decl.h @@ -39,7 +39,7 @@ * is not a really a pointer to a node: it is an offset value. See above. */ typedef union ofnode_union { - const struct device_node *np; + struct device_node *np; long of_offset; } ofnode;

When the flat device tree changes it can mess up the live tree since that uses the flat tree for its strings. This affects only a few sandbox tests which modify the device tree, but the number will grow as ofnode support for writing improves.
While the control FDT is not intended to change while U-Boot is running, some tests do so. For example, the ofnode interface only supports modifying properties in the control FDT, so tests must use that.
To solve this problem, keep a copy of the FDT and restore it as needed when the test is finished. The copy only happens on sandbox (except SPL builds), to reduce memory usage and because these tests are not useful on other boards. For other boards, a checksum is taken to ensure that nothing changes.
It would be possible to always checksum the FDT on sandbox and only restore it if needed, but this is slightly slower than restoring it every time, at least with crc8.
Move the code which checks for success to the very end, for clarity.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
doc/develop/driver-model/livetree.rst | 17 ++---- include/test/test.h | 6 +++ test/test-main.c | 78 +++++++++++++++++++++++++-- 3 files changed, 83 insertions(+), 18 deletions(-)
diff --git a/doc/develop/driver-model/livetree.rst b/doc/develop/driver-model/livetree.rst index faf3eb5b5f0..4ef8c517325 100644 --- a/doc/develop/driver-model/livetree.rst +++ b/doc/develop/driver-model/livetree.rst @@ -235,20 +235,9 @@ tree either present or absent. This is to make sure that the flat tree functions work correctly even with OF_LIVE is enabled. But if a test modifies the flat device tree, then the live tree can become invalid. Any live tree tests that run after that point will use a corrupted tree, e.g. with an incorrect property name -or worse. To deal with this we use a flag UT_TESTF_LIVE_OR_FLAT then ensures -that tests which write to the flat tree are not run if OF_LIVE is enabled. Only -the live tree version of the test is run, when OF_LIVE is enabled, with -sandbox_flattree running the flat tree version. - -This is of course a work-around, even if a reasonable one. One solution to this -problem would be to make a copy of the flat tree before the test and restore it -afterwards, in the same memory location, so that the live tree pointers work -again. Another would be to regenerate the live tree if a test modified the flat -tree. - -Neither of these solutions is currently implemented, since the situation that -causes the problem can only occur in sandbox tests, is somewhat esoteric and -the UT_TESTF_LIVE_OR_FLAT flag deals with it in a reasonable way. +or worse. To deal with this we take a copy of the device tree and restore it +after any test that modifies it. Note that this copy is not made on other +boards, only sandbox.
Multiple livetrees diff --git a/include/test/test.h b/include/test/test.h index 0d32d914685..cd201fb8d55 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -20,6 +20,9 @@ * @testdev: Test device * @force_fail_alloc: Force all memory allocs to fail * @skip_post_probe: Skip uclass post-probe processing + * @fdt_chksum: crc8 of the device tree contents + * @fdt_copy: Copy of the device tree + * @fdt_size: Size of the device-tree copy * @expect_str: Temporary string used to hold expected string value * @actual_str: Temporary string used to hold actual string value */ @@ -32,6 +35,9 @@ struct unit_test_state { struct udevice *testdev; int force_fail_alloc; int skip_post_probe; + uint fdt_chksum; + void *fdt_copy; + uint fdt_size; char expect_str[512]; char actual_str[512]; }; diff --git a/test/test-main.c b/test/test-main.c index 5b6b5ba5bbe..8a9439eec4a 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -8,14 +8,51 @@ #include <console.h> #include <dm.h> #include <event.h> +#include <os.h> #include <dm/root.h> #include <dm/test.h> #include <dm/uclass-internal.h> #include <test/test.h> #include <test/ut.h> +#include <u-boot/crc.h>
DECLARE_GLOBAL_DATA_PTR;
+/** + * enum fdtchk_t - what to do with the device tree (gd->fdt_blob) + * + * This affects what happens with the device tree before and after a test + * + * @FDTCHK_NONE: Do nothing + * @FDTCHK_CHECKSUM: Take a checksum of the FDT before the test runs and + * compare it afterwards to detect any changes + * @FDTCHK_COPY: Make a copy of the FDT and restore it afterwards + */ +enum fdtchk_t { + FDTCHK_NONE, + FDTCHK_CHECKSUM, + FDTCHK_COPY, +}; + +/** + * fdt_action() - get the required action for the FDT + * + * @return the action that should be taken for this build + */ +static enum fdtchk_t fdt_action(void) +{ + /* Do a copy for sandbox (but only the U-Boot build, not SPL) */ + if (CONFIG_IS_ENABLED(SANDBOX)) + return FDTCHK_COPY; + + /* For sandbox SPL builds, do nothing */ + if (IS_ENABLED(CONFIG_SANDBOX)) + return FDTCHK_NONE; + + /* For all other boards, do a checksum */ + return FDTCHK_CHECKSUM; +} + /* This is valid when a test is running, NULL otherwise */ static struct unit_test_state *cur_test_state;
@@ -45,6 +82,9 @@ static int dm_test_pre_run(struct unit_test_state *uts) uts->testdev = NULL; uts->force_fail_alloc = false; uts->skip_post_probe = false; + if (fdt_action() == FDTCHK_CHECKSUM) + uts->fdt_chksum = crc8(0, gd->fdt_blob, + fdt_totalsize(gd->fdt_blob)); gd->dm_root = NULL; malloc_disable_testing(); if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA)) @@ -63,6 +103,25 @@ static int dm_test_post_run(struct unit_test_state *uts) { int id;
+ if (gd->fdt_blob) { + switch (fdt_action()) { + case FDTCHK_COPY: + memcpy((void *)gd->fdt_blob, uts->fdt_copy, uts->fdt_size); + break; + case FDTCHK_CHECKSUM: { + uint chksum; + + chksum = crc8(0, gd->fdt_blob, fdt_totalsize(gd->fdt_blob)); + + if (chksum != uts->fdt_chksum) + printf("Device tree changed: cannot run live tree tests\n"); + break; + } + case FDTCHK_NONE: + break; + } + } + /* * With of-platdata-inst the uclasses are created at build time. If we * destroy them we cannot get them back since uclass_add() is not @@ -432,16 +491,27 @@ int ut_run_list(const char *category, const char *prefix, printf("Running %d %s tests\n", count, category);
uts.of_root = gd_of_root(); + if (fdt_action() == FDTCHK_COPY && gd->fdt_blob) { + uts.fdt_size = fdt_totalsize(gd->fdt_blob); + uts.fdt_copy = os_malloc(uts.fdt_size); + if (!uts.fdt_copy) { + printf("Out of memory for device tree copy\n"); + return -ENOMEM; + } + memcpy(uts.fdt_copy, gd->fdt_blob, uts.fdt_size); + } ret = ut_run_tests(&uts, prefix, tests, count, select_name);
+ /* Best efforts only...ignore errors */ + if (has_dm_tests) + dm_test_restore(uts.of_root); + if (IS_ENABLED(CONFIG_SANDBOX)) + os_free(uts.fdt_copy); + if (ret == -ENOENT) printf("Test '%s' not found\n", select_name); else printf("Failures: %d\n", uts.fail_count);
- /* Best efforts only...ignore errors */ - if (has_dm_tests) - dm_test_restore(uts.of_root); - return ret; }

If the device tree changes during a test and we cannot restore it, mark it as such so that future tests which need the live tree are skipped.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
include/asm-generic/global_data.h | 4 ++++ test/test-main.c | 19 ++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 805a6fd6797..57e6959ace1 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -635,6 +635,10 @@ enum gd_flags { * @GD_FLG_SMP_READY: SMP initialization is complete */ GD_FLG_SMP_READY = 0x80000, + /** + * @GD_FLG_FDT_CHANGED: Device tree change has been detected by tests + */ + GD_FLG_FDT_CHANGED = 0x100000, };
#endif /* __ASSEMBLY__ */ diff --git a/test/test-main.c b/test/test-main.c index 8a9439eec4a..7ab0d6ba53b 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -78,6 +78,10 @@ static int dm_test_pre_run(struct unit_test_state *uts) { bool of_live = uts->of_live;
+ if (of_live && (gd->flags & GD_FLG_FDT_CHANGED)) { + printf("Cannot run live tree test as device tree changed\n"); + return -EFAULT; + } uts->root = NULL; uts->testdev = NULL; uts->force_fail_alloc = false; @@ -112,9 +116,17 @@ static int dm_test_post_run(struct unit_test_state *uts) uint chksum;
chksum = crc8(0, gd->fdt_blob, fdt_totalsize(gd->fdt_blob)); - - if (chksum != uts->fdt_chksum) + if (chksum != uts->fdt_chksum) { + /* + * We cannot run any more tests that need the + * live tree, since its strings point into the + * flat tree, which has changed. This likely + * means that at least some of the pointers from + * the live tree point to different things + */ printf("Device tree changed: cannot run live tree tests\n"); + gd->flags |= GD_FLG_FDT_CHANGED; + } break; } case FDTCHK_NONE: @@ -412,7 +424,8 @@ static int ut_run_test_live_flat(struct unit_test_state *uts, * or it is a core test. */ if (!(test->flags & UT_TESTF_LIVE_TREE) && - (!runs || ut_test_run_on_flattree(test))) { + (!runs || ut_test_run_on_flattree(test)) && + !(gd->flags & GD_FLG_FDT_CHANGED)) { uts->of_live = false; ut_assertok(ut_run_test(uts, test, test->name)); runs++;

This was a workaround for a rare situation. Now that it will be more common and we have a proper fix, drop the flag. We can run both types of tests in the same sandbox executable, even if the flat device tree is modified.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
include/test/test.h | 2 -- test/dm/ofnode.c | 16 +++------------- 2 files changed, 3 insertions(+), 15 deletions(-)
diff --git a/include/test/test.h b/include/test/test.h index cd201fb8d55..c028bbb8c89 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -52,8 +52,6 @@ enum { UT_TESTF_CONSOLE_REC = BIT(5), /* needs console recording */ /* do extra driver model init and uninit */ UT_TESTF_DM = BIT(6), - /* live or flat device tree, but not both in the same executable */ - UT_TESTF_LIVE_OR_FLAT = BIT(7), };
/** diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 0f65ff939fb..a421392a976 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -546,10 +546,6 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) struct udevice *dev; ofnode node;
- /* temporarily disable this test due to a failure fixed later */ - if (!of_live_active()) - return 0; - /* Test enabling devices */ node = ofnode_path("/usb@2");
@@ -588,7 +584,7 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_ofnode_livetree_writing, - UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT); + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
static int dm_test_ofnode_u32(struct unit_test_state *uts) { @@ -603,18 +599,13 @@ static int dm_test_ofnode_u32(struct unit_test_state *uts)
return 0; } -DM_TEST(dm_test_ofnode_u32, - UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT); +DM_TEST(dm_test_ofnode_u32, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
static int dm_test_ofnode_add_subnode(struct unit_test_state *uts) { ofnode node, check, subnode; char buf[128];
- /* temporarily disable this test due to a failure fixed later */ - if (!of_live_active()) - return 0; - node = ofnode_path("/lcd"); ut_assert(ofnode_valid(node)); ut_assertok(ofnode_add_subnode(node, "edmund", &subnode)); @@ -677,5 +668,4 @@ static int dm_test_ofnode_add_subnode(struct unit_test_state *uts)
return 0; } -DM_TEST(dm_test_ofnode_add_subnode, - UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT); +DM_TEST(dm_test_ofnode_add_subnode, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);

At present this implementation is specific to loading the test FDT. We plan to load others, so create a generic function to handle this.
The path is now limited to 256 characters, to simplify the code.
When there is an empty argv[0] (which should not happen), the function now just uses the path as is, with no prefix.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
arch/sandbox/cpu/start.c | 16 +++++++--------- arch/sandbox/cpu/state.c | 22 ++++++++++++++++++++++ arch/sandbox/include/asm/state.h | 14 ++++++++++++++ 3 files changed, 43 insertions(+), 9 deletions(-)
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 90a84e93c79..642be164a39 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -205,21 +205,19 @@ SANDBOX_CMDLINE_OPT_SHORT(default_fdt, 'D', 0, static int sandbox_cmdline_cb_test_fdt(struct sandbox_state *state, const char *arg) { - const char *fmt = "/arch/sandbox/dts/test.dtb"; - char *p; + char buf[256]; char *fname; int len;
- len = strlen(state->argv[0]) + strlen(fmt) + 1; + len = state_get_rel_filename("arch/sandbox/dts/test.dtb", buf, + sizeof(buf)); + if (len < 0) + return len; + fname = os_malloc(len); if (!fname) return -ENOMEM; - strcpy(fname, state->argv[0]); - p = strrchr(fname, '/'); - if (!p) - p = fname + strlen(fname); - len -= p - fname; - snprintf(p, len, fmt); + strcpy(fname, buf); state->fdt_fname = fname;
return 0; diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index e0d01125bb5..787e0216594 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -396,6 +396,28 @@ bool autoboot_set_keyed(bool autoboot_keyed) return old_val; }
+int state_get_rel_filename(const char *rel_path, char *buf, int size) +{ + struct sandbox_state *state = state_get_current(); + int rel_len, prog_len; + char *p; + int len; + + rel_len = strlen(rel_path); + p = strrchr(state->argv[0], '/'); + prog_len = p ? p - state->argv[0] : 0; + + /* allow space for a / and a terminator */ + len = prog_len + 1 + rel_len + 1; + if (len > size) + return -ENOSPC; + strncpy(buf, state->argv[0], prog_len); + buf[prog_len] = '/'; + strcpy(buf + prog_len + 1, rel_path); + + return len; +} + int state_init(void) { state = &main_state; diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 07c768ae5df..12741ee064a 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -265,6 +265,20 @@ void state_reset_for_test(struct sandbox_state *state); */ void state_show(struct sandbox_state *state);
+/** + * state_get_rel_filename() - Get a filename relative to the executable + * + * This uses argv[0] to obtain a filename path + * + * @rel_path: Relative path to build, e.g. "arch/sandbox/dts/test.dtb". Must not + * have a trailing / + * @buf: Buffer to use to return the filename + * @size: Size of buffer + * @return length of filename (including terminator), -ENOSPC if @size is too + * small + */ +int state_get_rel_filename(const char *rel_path, char *buf, int size); + /** * Initialize the test system state */

We need an 'other' FDT which is different from the control FDT, so we can check that the ofnode tests correctly handle them both.
Add this to the build along with a way to read it into the sandbox state.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
arch/sandbox/cpu/state.c | 26 ++++++++++++++++++++++++ arch/sandbox/dts/Makefile | 2 +- arch/sandbox/dts/other.dts | 35 ++++++++++++++++++++++++++++++++ arch/sandbox/include/asm/state.h | 16 +++++++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 arch/sandbox/dts/other.dts
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index 787e0216594..fcc4a337e59 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -418,6 +418,32 @@ int state_get_rel_filename(const char *rel_path, char *buf, int size) return len; }
+int state_load_other_fdt(const char **bufp, int *sizep) +{ + struct sandbox_state *state = state_get_current(); + char fname[256]; + int len, ret; + + /* load the file if needed */ + if (!state->other_fdt_buf) { + len = state_get_rel_filename("arch/sandbox/dts/other.dtb", + fname, sizeof(fname)); + if (len < 0) + return len; + + ret = os_read_file(fname, &state->other_fdt_buf, + &state->other_size); + if (ret) { + log_err("Cannot read file '%s'\n", fname); + return ret; + } + } + *bufp = state->other_fdt_buf; + *sizep = state->other_size; + + return 0; +} + int state_init(void) { state = &main_state; diff --git a/arch/sandbox/dts/Makefile b/arch/sandbox/dts/Makefile index 6cbc9bbcaa1..b6a88479b22 100644 --- a/arch/sandbox/dts/Makefile +++ b/arch/sandbox/dts/Makefile @@ -5,7 +5,7 @@ dtb-$(CONFIG_SANDBOX) += sandbox64.dtb else dtb-$(CONFIG_SANDBOX) += sandbox.dtb endif -dtb-$(CONFIG_UT_DM) += test.dtb +dtb-$(CONFIG_UT_DM) += test.dtb other.dtb dtb-$(CONFIG_CMD_EXTENSION) += overlay0.dtbo overlay1.dtbo
include $(srctree)/scripts/Makefile.dts diff --git a/arch/sandbox/dts/other.dts b/arch/sandbox/dts/other.dts new file mode 100644 index 00000000000..395a7923228 --- /dev/null +++ b/arch/sandbox/dts/other.dts @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Other devicetree file for running sandbox tests + * + * This used for tests which want to check they can access multiple device + * trees. This one is loaded and checks are made that it is actually visible. + */ + +/dts-v1/; + +/ { + compatible = "sandbox-other"; + #address-cells = <1>; + #size-cells = <1>; + + node { + target = <&target 3 4>; + + subnode { + compatible = "sandbox-other2"; + str-prop = "other"; + }; + + subnode2 { + }; + }; + + target: target { + compatible = "sandbox-other2"; + #gpio-cells = <2>; + str-prop = "other"; + reg = <0x8000 0x100>; + status = "disabled"; + }; +}; diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 12741ee064a..fd42daad51c 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -108,6 +108,9 @@ struct sandbox_state { bool hwspinlock; /* Hardware Spinlock status */ bool allow_memio; /* Allow readl() etc. to work */
+ void *other_fdt_buf; /* 'other' FDT blob used by tests */ + int other_size; /* size of other FDT blob */ + /* * This struct is getting large. * @@ -279,6 +282,19 @@ void state_show(struct sandbox_state *state); */ int state_get_rel_filename(const char *rel_path, char *buf, int size);
+/** + * state_load_other_fdt() - load the 'other' FDT into a buffer + * + * This loads the other.dtb file into a buffer. This is typically used in tests. + * + * @bufp: Place to put allocated buffer pointer. The buffer is read using + * os_read_file() which calls os_malloc(), so does affect U-Boot's own malloc() + * space + * @sizep: Returns the size of the buffer + * @return 0 if OK, -ve on error + */ +int state_load_other_fdt(const char **bufp, int *sizep); + /** * Initialize the test system state */

Provide a way to copy over the 'other' FDT when running tests. This loads it and allocates memory for the copy, if not done already, then does the copy.
Avoid using U-Boot's malloc() pool for these copies, at least for now, since they are part of the test system.
Tidy up the cpu.c header files while here.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
arch/sandbox/cpu/cpu.c | 34 ++++++++++++++++++++++++++++++--- arch/sandbox/include/asm/test.h | 19 ++++++++++++++++++ include/test/test.h | 19 ++++++++++++++++-- 3 files changed, 67 insertions(+), 5 deletions(-)
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index d077948dd7b..636d3545b95 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -3,19 +3,22 @@ * Copyright (c) 2011 The Chromium OS Authors. */
+#define LOG_CATEGORY LOGC_SANDBOX + #include <common.h> #include <bootstage.h> #include <cpu_func.h> #include <errno.h> #include <log.h> -#include <asm/global_data.h> -#include <linux/delay.h> -#include <linux/libfdt.h> #include <os.h> +#include <asm/global_data.h> #include <asm/io.h> #include <asm/malloc.h> #include <asm/setjmp.h> #include <asm/state.h> +#include <dm/ofnode.h> +#include <linux/delay.h> +#include <linux/libfdt.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -373,3 +376,28 @@ ulong timer_get_boot_us(void)
return (count - base_count) / 1000; } + +int sandbox_load_other_fdt(void **fdtp, int *sizep) +{ + const char *orig; + int ret, size; + void *fdt = *fdtp; + + ret = state_load_other_fdt(&orig, &size); + if (ret) { + log_err("Cannot read other FDT\n"); + return log_msg_ret("ld", ret); + } + + if (!*fdtp) { + fdt = os_malloc(size); + if (!fdt) + return log_msg_ret("mem", -ENOMEM); + *sizep = size; + } + + memcpy(fdt, orig, *sizep); + *fdtp = fdt; + + return 0; +} diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 53a036b3abf..0406085917f 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -11,6 +11,8 @@ #include <video.h> #include <pci_ids.h>
+struct unit_test_state; + /* The sandbox driver always permits an I2C device with this address */ #define SANDBOX_I2C_TEST_ADDR 0x59
@@ -315,4 +317,21 @@ int sandbox_sdl_set_bpp(struct udevice *dev, enum video_log2_bpp l2bpp); */ void sandbox_set_fake_efi_mgr_dev(struct udevice *dev, bool fake_dev);
+/** + * sandbox_load_other_fdt() - load the 'other' FDT into the test state + * + * This copies the other.dtb file into the test state, so that a fresh version + * can be used for a test that is about to run. + * + * If @uts->other_fdt is NULL, as it is when first set up, this allocates a + * buffer for the other FDT and sets @uts->other_fdt_size to its size. + * + * In any case, the other FDT is copied from the sandbox state into + * @uts->other_fdt ready for use. + * + * @uts: Unit test state + * @return 0 if OK, -ve on error + */ +int sandbox_load_other_fdt(void **fdtp, int *sizep); + #endif diff --git a/include/test/test.h b/include/test/test.h index c028bbb8c89..d6149df0c6b 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -23,6 +23,8 @@ * @fdt_chksum: crc8 of the device tree contents * @fdt_copy: Copy of the device tree * @fdt_size: Size of the device-tree copy + * @other_fdt: Buffer for the other FDT (UT_TESTF_OTHER_FDT) + * @other_fdt_size: Size of the other FDT (UT_TESTF_OTHER_FDT) * @expect_str: Temporary string used to hold expected string value * @actual_str: Temporary string used to hold actual string value */ @@ -38,6 +40,8 @@ struct unit_test_state { uint fdt_chksum; void *fdt_copy; uint fdt_size; + void *other_fdt; + int other_fdt_size; char expect_str[512]; char actual_str[512]; }; @@ -130,13 +134,24 @@ enum { */ struct udevice *testbus_get_clear_removed(void);
-static inline void arch_reset_for_test(void) -{ #ifdef CONFIG_SANDBOX #include <asm/state.h> +#include <asm/test.h> +#endif
+static inline void arch_reset_for_test(void) +{ +#ifdef CONFIG_SANDBOX state_reset_for_test(state_get_current()); #endif } +static inline int test_load_other_fdt(struct unit_test_state *uts) +{ + int ret = 0; +#ifdef CONFIG_SANDBOX + ret = sandbox_load_other_fdt(&uts->other_fdt, &uts->other_fdt_size); +#endif + return ret; +}
#endif /* __TEST_TEST_H */

Add a test flag which indicates that the 'other' FDT should be set up ready for use. Handle this by copying in the FDT, unflattening it for livetree tests. Free the structures when the tests have run.
We cannot use the other FDT unless we are using live tree or OFNODE_MULTI_TREE is enabled, since only one tree is supported by the ofnode interface in that case. Add this condition into ut_run_test_live_flat() and update the comments.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
include/test/test.h | 3 +++ test/test-main.c | 39 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/include/test/test.h b/include/test/test.h index d6149df0c6b..ab80189ac71 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -25,6 +25,7 @@ * @fdt_size: Size of the device-tree copy * @other_fdt: Buffer for the other FDT (UT_TESTF_OTHER_FDT) * @other_fdt_size: Size of the other FDT (UT_TESTF_OTHER_FDT) + * @of_other: Live tree for the other FDT * @expect_str: Temporary string used to hold expected string value * @actual_str: Temporary string used to hold actual string value */ @@ -42,6 +43,7 @@ struct unit_test_state { uint fdt_size; void *other_fdt; int other_fdt_size; + struct device_node *of_other; char expect_str[512]; char actual_str[512]; }; @@ -56,6 +58,7 @@ enum { UT_TESTF_CONSOLE_REC = BIT(5), /* needs console recording */ /* do extra driver model init and uninit */ UT_TESTF_DM = BIT(6), + UT_TESTF_OTHER_FDT = BIT(7), /* read in other device tree */ };
/** diff --git a/test/test-main.c b/test/test-main.c index 7ab0d6ba53b..e06b5437121 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -8,6 +8,7 @@ #include <console.h> #include <dm.h> #include <event.h> +#include <of_live.h> #include <os.h> #include <dm/root.h> #include <dm/test.h> @@ -312,6 +313,20 @@ static int test_pre_run(struct unit_test_state *uts, struct unit_test *test) (test->flags & UT_TESTF_SCAN_FDT)) ut_assertok(dm_extended_scan(false));
+ if (IS_ENABLED(CONFIG_SANDBOX) && (test->flags & UT_TESTF_OTHER_FDT)) { + /* make sure the other FDT is available */ + ut_assertok(test_load_other_fdt(uts)); + + /* + * create a new live tree with it for every test, in case a + * test modifies the tree + */ + if (of_live_active()) { + ut_assertok(unflatten_device_tree(uts->other_fdt, + &uts->of_other)); + } + } + if (test->flags & UT_TESTF_CONSOLE_REC) { int ret = console_record_reset_enable();
@@ -339,6 +354,9 @@ static int test_post_run(struct unit_test_state *uts, struct unit_test *test) ut_assertok(dm_test_post_run(uts)); ut_assertok(event_uninit());
+ free(uts->of_other); + uts->of_other = NULL; + return 0; }
@@ -409,6 +427,9 @@ static int ut_run_test_live_flat(struct unit_test_state *uts, { int runs;
+ if ((test->flags & UT_TESTF_OTHER_FDT) && !IS_ENABLED(CONFIG_SANDBOX)) + return -EAGAIN; + /* Run with the live tree if possible */ runs = 0; if (CONFIG_IS_ENABLED(OF_LIVE)) { @@ -420,10 +441,20 @@ static int ut_run_test_live_flat(struct unit_test_state *uts, }
/* - * Run with the flat tree if we couldn't run it with live tree, - * or it is a core test. + * Run with the flat tree if: + * - it is not marked for live tree only + * - it doesn't require the 'other' FDT when OFNODE_MULTI_TREE_MAX is + * not enabled (since flat tree can only support a single FDT in that + * case + * - we couldn't run it with live tree, + * - it is a core test (dm tests except video) + * - the FDT is still valid and has not been updated by an earlier test + * (for sandbox we handle this by copying the tree, but not for other + * boards) */ if (!(test->flags & UT_TESTF_LIVE_TREE) && + (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) || + !(test->flags & UT_TESTF_OTHER_FDT)) && (!runs || ut_test_run_on_flattree(test)) && !(gd->flags & GD_FLG_FDT_CHANGED)) { uts->of_live = false; @@ -518,8 +549,10 @@ int ut_run_list(const char *category, const char *prefix, /* Best efforts only...ignore errors */ if (has_dm_tests) dm_test_restore(uts.of_root); - if (IS_ENABLED(CONFIG_SANDBOX)) + if (IS_ENABLED(CONFIG_SANDBOX)) { os_free(uts.fdt_copy); + os_free(uts.other_fdt); + }
if (ret == -ENOENT) printf("Test '%s' not found\n", select_name);

Update the function to mark it with the const attribute. Also avoid calling it multiple times in the devfdt_get_addr_index() function.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/core/fdtaddr.c | 18 +++++++++--------- include/dm/device.h | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c index c3a50a2b0c1..91bcd1a2c21 100644 --- a/drivers/core/fdtaddr.c +++ b/drivers/core/fdtaddr.c @@ -21,6 +21,8 @@ DECLARE_GLOBAL_DATA_PTR; fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) { #if CONFIG_IS_ENABLED(OF_REAL) + int offset = dev_of_offset(dev); + int parent = dev_of_offset(dev->parent); fdt_addr_t addr;
if (CONFIG_IS_ENABLED(OF_TRANSLATE)) { @@ -28,21 +30,19 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) int len = 0; int na, ns;
- na = fdt_address_cells(gd->fdt_blob, - dev_of_offset(dev->parent)); + na = fdt_address_cells(gd->fdt_blob, parent); if (na < 1) { debug("bad #address-cells\n"); return FDT_ADDR_T_NONE; }
- ns = fdt_size_cells(gd->fdt_blob, dev_of_offset(dev->parent)); + ns = fdt_size_cells(gd->fdt_blob, parent); if (ns < 0) { debug("bad #size-cells\n"); return FDT_ADDR_T_NONE; }
- reg = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "reg", - &len); + reg = fdt_getprop(gd->fdt_blob, offset, "reg", &len); if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns)))) { debug("Req index out of range\n"); return FDT_ADDR_T_NONE; @@ -56,7 +56,7 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) * bus setups. */ addr = fdt_translate_address((void *)gd->fdt_blob, - dev_of_offset(dev), reg); + offset, reg); } else { /* Non translatable if #size-cells == 0 */ addr = fdt_read_number(reg, na); @@ -66,9 +66,9 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) * Use the "simple" translate function for less complex * bus setups. */ - addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, - dev_of_offset(dev->parent), dev_of_offset(dev), - "reg", index, NULL, false); + addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, parent, + offset, "reg", index, + NULL, false); if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) { if (device_get_uclass_id(dev->parent) == UCLASS_SIMPLE_BUS) diff --git a/include/dm/device.h b/include/dm/device.h index 12c6ba37ff3..f3f953c9afc 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -253,7 +253,7 @@ static inline void dev_bic_flags(struct udevice *dev, u32 bic) * @dev: device to check * Return: reference of the device's DT node */ -static inline ofnode dev_ofnode(const struct udevice *dev) +static inline __attribute_const__ ofnode dev_ofnode(const struct udevice *dev) { #if CONFIG_IS_ENABLED(OF_REAL) return dev->node_; @@ -273,7 +273,7 @@ static inline ofnode dev_ofnode(const struct udevice *dev) #define dev_get_dma_offset(_dev) 0 #endif
-static inline int dev_of_offset(const struct udevice *dev) +static inline __attribute_const__ int dev_of_offset(const struct udevice *dev) { #if CONFIG_IS_ENABLED(OF_REAL) return ofnode_to_offset(dev_ofnode(dev)); @@ -282,7 +282,7 @@ static inline int dev_of_offset(const struct udevice *dev) #endif }
-static inline bool dev_has_ofnode(const struct udevice *dev) +static inline __attribute_const__ bool dev_has_ofnode(const struct udevice *dev) { #if CONFIG_IS_ENABLED(OF_REAL) return ofnode_valid(dev_ofnode(dev));

Drop the 'get' in these names since it does not fit with the rest of the API.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/core/ofnode.c | 4 ++-- drivers/core/read.c | 4 ++-- env/common.c | 4 ++-- include/dm/ofnode.h | 8 ++++---- include/dm/read.h | 6 +++--- test/dm/ofread.c | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index ac6d259601c..0ed6e905a50 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -718,7 +718,7 @@ const void *ofnode_get_property(ofnode node, const char *propname, int *lenp) propname, lenp); }
-int ofnode_get_first_property(ofnode node, struct ofprop *prop) +int ofnode_first_property(ofnode node, struct ofprop *prop) { prop->node = node;
@@ -737,7 +737,7 @@ int ofnode_get_first_property(ofnode node, struct ofprop *prop) return 0; }
-int ofnode_get_next_property(struct ofprop *prop) +int ofnode_next_property(struct ofprop *prop) { if (ofnode_is_np(prop->node)) { prop->prop = of_get_next_property(ofnode_to_np(prop->node), diff --git a/drivers/core/read.c b/drivers/core/read.c index c73508d2760..f121122d13f 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -266,12 +266,12 @@ const void *dev_read_prop(const struct udevice *dev, const char *propname,
int dev_read_first_prop(const struct udevice *dev, struct ofprop *prop) { - return ofnode_get_first_property(dev_ofnode(dev), prop); + return ofnode_first_property(dev_ofnode(dev), prop); }
int dev_read_next_prop(struct ofprop *prop) { - return ofnode_get_next_property(prop); + return ofnode_next_property(prop); }
const void *dev_read_prop_by_prop(struct ofprop *prop, diff --git a/env/common.c b/env/common.c index f9226e0690d..84f1d112de2 100644 --- a/env/common.c +++ b/env/common.c @@ -539,9 +539,9 @@ void env_import_fdt(void) return; }
- for (res = ofnode_get_first_property(node, &prop); + for (res = ofnode_first_property(node, &prop); !res; - res = ofnode_get_next_property(&prop)) { + res = ofnode_next_property(&prop)) { const char *name, *val;
val = ofnode_get_property_by_prop(&prop, &name, NULL); diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index ee762442784..f2e89d4febe 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -759,7 +759,7 @@ int ofnode_decode_display_timing(ofnode node, int index, const void *ofnode_get_property(ofnode node, const char *propname, int *lenp);
/** - * ofnode_get_first_property()- get the reference of the first property + * ofnode_first_property()- get the reference of the first property * * Get reference to the first property of the node, it is used to iterate * and read all the property with ofnode_get_property_by_prop(). @@ -768,10 +768,10 @@ const void *ofnode_get_property(ofnode node, const char *propname, int *lenp); * @prop: place to put argument reference * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found */ -int ofnode_get_first_property(ofnode node, struct ofprop *prop); +int ofnode_first_property(ofnode node, struct ofprop *prop);
/** - * ofnode_get_next_property() - get the reference of the next property + * ofnode_next_property() - get the reference of the next property * * Get reference to the next property of the node, it is used to iterate * and read all the property with ofnode_get_property_by_prop(). @@ -779,7 +779,7 @@ int ofnode_get_first_property(ofnode node, struct ofprop *prop); * @prop: reference of current argument and place to put reference of next one * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found */ -int ofnode_get_next_property(struct ofprop *prop); +int ofnode_next_property(struct ofprop *prop);
/** * ofnode_get_property_by_prop() - get a pointer to the value of a property diff --git a/include/dm/read.h b/include/dm/read.h index 1b54b69acf0..645549c3223 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -528,7 +528,7 @@ const void *dev_read_prop(const struct udevice *dev, const char *propname, int dev_read_first_prop(const struct udevice *dev, struct ofprop *prop);
/** - * ofnode_get_next_property() - get the reference of the next property + * ofnode_next_property() - get the reference of the next property * * Get reference to the next property of the node, it is used to iterate * and read all the property with dev_read_prop_by_prop(). @@ -1014,12 +1014,12 @@ static inline const void *dev_read_prop(const struct udevice *dev,
static inline int dev_read_first_prop(const struct udevice *dev, struct ofprop *prop) { - return ofnode_get_first_property(dev_ofnode(dev), prop); + return ofnode_first_property(dev_ofnode(dev), prop); }
static inline int dev_read_next_prop(struct ofprop *prop) { - return ofnode_get_next_property(prop); + return ofnode_next_property(prop); }
static inline const void *dev_read_prop_by_prop(struct ofprop *prop, diff --git a/test/dm/ofread.c b/test/dm/ofread.c index 8c7dd825136..95a24c3f42b 100644 --- a/test/dm/ofread.c +++ b/test/dm/ofread.c @@ -14,9 +14,9 @@ static int dm_test_ofnode_get_property_by_prop(struct unit_test_state *uts) int res, len, count = 0;
node = ofnode_path("/cros-ec/flash"); - for (res = ofnode_get_first_property(node, &prop); + for (res = ofnode_first_property(node, &prop); !res; - res = ofnode_get_next_property(&prop)) { + res = ofnode_next_property(&prop)) { value = ofnode_get_property_by_prop(&prop, &propname, &len); ut_assertnonnull(value); switch (count) {

The current name is quite unwieldy. Change it to use an ofprop_ prefix and shorten it. Fix the return-value comment while we are here.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add new patch to rename ofnode_get_property_by_prop()
drivers/core/ofnode.c | 4 ++-- drivers/core/read.c | 2 +- env/common.c | 2 +- include/dm/ofnode.h | 14 +++++++------- include/dm/read.h | 2 +- test/dm/ofread.c | 7 +++---- 6 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 0ed6e905a50..71b2c4f8c9d 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -754,8 +754,8 @@ int ofnode_next_property(struct ofprop *prop) return 0; }
-const void *ofnode_get_property_by_prop(const struct ofprop *prop, - const char **propname, int *lenp) +const void *ofprop_get_property(const struct ofprop *prop, + const char **propname, int *lenp) { if (ofnode_is_np(prop->node)) return of_get_property_by_prop(ofnode_to_np(prop->node), diff --git a/drivers/core/read.c b/drivers/core/read.c index f121122d13f..a0035207e41 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -277,7 +277,7 @@ int dev_read_next_prop(struct ofprop *prop) const void *dev_read_prop_by_prop(struct ofprop *prop, const char **propname, int *lenp) { - return ofnode_get_property_by_prop(prop, propname, lenp); + return ofprop_get_property(prop, propname, lenp); }
int dev_read_alias_seq(const struct udevice *dev, int *devnump) diff --git a/env/common.c b/env/common.c index 84f1d112de2..f9e4cae313f 100644 --- a/env/common.c +++ b/env/common.c @@ -544,7 +544,7 @@ void env_import_fdt(void) res = ofnode_next_property(&prop)) { const char *name, *val;
- val = ofnode_get_property_by_prop(&prop, &name, NULL); + val = ofprop_get_property(&prop, &name, NULL); env_set(name, val); } } diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index f2e89d4febe..81e332f697e 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -762,7 +762,7 @@ const void *ofnode_get_property(ofnode node, const char *propname, int *lenp); * ofnode_first_property()- get the reference of the first property * * Get reference to the first property of the node, it is used to iterate - * and read all the property with ofnode_get_property_by_prop(). + * and read all the property with ofprop_get_property(). * * @node: node to read * @prop: place to put argument reference @@ -774,7 +774,7 @@ int ofnode_first_property(ofnode node, struct ofprop *prop); * ofnode_next_property() - get the reference of the next property * * Get reference to the next property of the node, it is used to iterate - * and read all the property with ofnode_get_property_by_prop(). + * and read all the property with ofprop_get_property(). * * @prop: reference of current argument and place to put reference of next one * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found @@ -782,17 +782,17 @@ int ofnode_first_property(ofnode node, struct ofprop *prop); int ofnode_next_property(struct ofprop *prop);
/** - * ofnode_get_property_by_prop() - get a pointer to the value of a property + * ofprop_get_property() - get a pointer to the value of a property * * Get value for the property identified by the provided reference. * * @prop: reference on property * @propname: If non-NULL, place to property name on success, - * @lenp: If non-NULL, place to put length on success - * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found + * @lenp: If non-NULL, place to put length on success, or error code on failure + * Return: pointer to property, or NULL if not found */ -const void *ofnode_get_property_by_prop(const struct ofprop *prop, - const char **propname, int *lenp); +const void *ofprop_get_property(const struct ofprop *prop, + const char **propname, int *lenp);
/** * ofnode_is_available() - check if a node is marked available diff --git a/include/dm/read.h b/include/dm/read.h index 645549c3223..7f932aaaf39 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -1026,7 +1026,7 @@ static inline const void *dev_read_prop_by_prop(struct ofprop *prop, const char **propname, int *lenp) { - return ofnode_get_property_by_prop(prop, propname, lenp); + return ofprop_get_property(prop, propname, lenp); }
static inline int dev_read_alias_seq(const struct udevice *dev, int *devnump) diff --git a/test/dm/ofread.c b/test/dm/ofread.c index 95a24c3f42b..3523860d2b3 100644 --- a/test/dm/ofread.c +++ b/test/dm/ofread.c @@ -5,7 +5,7 @@ #include <dm/test.h> #include <test/ut.h>
-static int dm_test_ofnode_get_property_by_prop(struct unit_test_state *uts) +static int dm_test_ofprop_get_property(struct unit_test_state *uts) { ofnode node; struct ofprop prop; @@ -17,7 +17,7 @@ static int dm_test_ofnode_get_property_by_prop(struct unit_test_state *uts) for (res = ofnode_first_property(node, &prop); !res; res = ofnode_next_property(&prop)) { - value = ofnode_get_property_by_prop(&prop, &propname, &len); + value = ofprop_get_property(&prop, &propname, &len); ut_assertnonnull(value); switch (count) { case 0: @@ -46,5 +46,4 @@ static int dm_test_ofnode_get_property_by_prop(struct unit_test_state *uts)
return 0; } -DM_TEST(dm_test_ofnode_get_property_by_prop, - UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +DM_TEST(dm_test_ofprop_get_property, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);

The current implementation creates a 'name' value for every node. This is not needed for the latest device tree format, which includes a name in the node header.
Adjust the code to point the name at the node header instead.
Also simplify ofnode_get_name(), now that we can rely on it to set the name correctly. Update the comment to make it clear what name the root node has.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/core/ofnode.c | 2 +- include/dm/ofnode.h | 2 +- lib/of_live.c | 7 ++++++- 3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 71b2c4f8c9d..d0716b79f9d 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -294,7 +294,7 @@ const char *ofnode_get_name(ofnode node) }
if (ofnode_is_np(node)) - return strrchr(node.np->full_name, '/') + 1; + return node.np->name;
return fdt_get_name(gd->fdt_blob, ofnode_to_offset(node), NULL); } diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 81e332f697e..ac9babbb5b5 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -426,7 +426,7 @@ ofnode ofnode_get_parent(ofnode node); * ofnode_get_name() - get the name of a node * * @node: valid node to look up - * Return: name of node + * Return: name of node (for the root node this is "") */ const char *ofnode_get_name(ofnode node);
diff --git a/lib/of_live.c b/lib/of_live.c index 30cae9ab881..1b5964d09a9 100644 --- a/lib/of_live.c +++ b/lib/of_live.c @@ -97,6 +97,10 @@ static void *unflatten_dt_node(const void *blob, void *mem, int *poffset, char *fn;
fn = (char *)np + sizeof(*np); + if (new_format) { + np->name = pathp; + has_name = 1; + } np->full_name = fn; if (new_format) { /* rebuild full path for new format */ @@ -202,7 +206,8 @@ static void *unflatten_dt_node(const void *blob, void *mem, int *poffset, } if (!dryrun) { *prev_pp = NULL; - np->name = of_get_property(np, "name", NULL); + if (!has_name) + np->name = of_get_property(np, "name", NULL); np->type = of_get_property(np, "device_type", NULL);
if (!np->name)

Add a 'for_each' macro like we have for nodes.
Fix the comment for struct ofprop while we are here.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
include/dm/ofnode.h | 38 ++++++++++++++++++++++++++++++++++++++ include/dm/ofnode_decl.h | 2 +- test/dm/ofnode.c | 24 ++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index ac9babbb5b5..8428e1a661e 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -176,6 +176,20 @@ static inline ofnode ofnode_root(void) return node; }
+/** + * ofprop_valid() - check if an ofprop is valid + * + * @prop: Pointer to ofprop to check + * Return: true if the reference contains a valid ofprop, false if not + */ +static inline bool ofprop_valid(struct ofprop *prop) +{ + if (of_live_active()) + return prop->prop; + else + return prop->offset >= 0; +} + /** * oftree_default() - Returns the default device tree (U-Boot's control FDT) * @@ -781,6 +795,30 @@ int ofnode_first_property(ofnode node, struct ofprop *prop); */ int ofnode_next_property(struct ofprop *prop);
+/** + * ofnode_for_each_prop() - iterate over all properties of a node + * + * @prop: struct ofprop + * @node: node (lvalue, ofnode) + * + * This is a wrapper around a for loop and is used like this:: + * + * ofnode node; + * struct ofprop prop; + * + * ofnode_for_each_prop(prop, node) { + * ...use prop... + * } + * + * Note that this is implemented as a macro and @prop is used as + * iterator in the loop. The parent variable can be a constant or even a + * literal. + */ +#define ofnode_for_each_prop(prop, node) \ + for (ofnode_first_property(node, &prop); \ + ofprop_valid(&prop); \ + ofnode_next_property(&prop)) + /** * ofprop_get_property() - get a pointer to the value of a property * diff --git a/include/dm/ofnode_decl.h b/include/dm/ofnode_decl.h index 8d0d7885aa6..f666a0287ba 100644 --- a/include/dm/ofnode_decl.h +++ b/include/dm/ofnode_decl.h @@ -57,7 +57,7 @@ typedef union ofnode_union { * * @node: Pointer to device node * @offset: Pointer into flat device tree, used for flat tree. - * @prop: Pointer to property, used for live treee. + * @prop: Pointer to property, used for live tree. */
struct ofprop { diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index a421392a976..5ddfd0298a6 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -669,3 +669,27 @@ static int dm_test_ofnode_add_subnode(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_ofnode_add_subnode, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_for_each_prop(struct unit_test_state *uts) +{ + ofnode node, subnode; + struct ofprop prop; + int count; + + node = ofnode_path("/buttons"); + count = 0; + + /* we expect "compatible" for each node */ + ofnode_for_each_prop(prop, node) + count++; + ut_asserteq(1, count); + + /* there are two nodes, each with 2 properties */ + ofnode_for_each_subnode(subnode, node) + ofnode_for_each_prop(prop, subnode) + count++; + ut_asserteq(5, count); + + return 0; +} +DM_TEST(dm_test_ofnode_for_each_prop, UT_TESTF_SCAN_FDT);

This function is also available as ofnode_is_enabled(), so use that instead.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
arch/arm/mach-tegra/xusb-padctl-common.c | 2 +- arch/riscv/lib/andes_plic.c | 2 +- arch/riscv/lib/smp.c | 2 +- drivers/core/ofnode.c | 9 --------- drivers/cpu/imx8_cpu.c | 2 +- drivers/cpu/riscv_cpu.c | 2 +- drivers/crypto/fsl/jr.c | 2 +- drivers/firmware/scmi/scmi_agent-uclass.c | 2 +- drivers/mtd/mtdpart.c | 4 ++-- drivers/mtd/nand/raw/zynq_nand.c | 2 +- drivers/net/fec_mxc.c | 2 +- drivers/net/fsl_enetc.c | 2 +- drivers/net/mscc_eswitch/felix_switch.c | 2 +- drivers/net/sja1105.c | 2 +- drivers/net/ti/am65-cpsw-nuss.c | 2 +- drivers/pci/pci-uclass.c | 2 +- drivers/pci/pci_mvebu.c | 2 +- drivers/pci/pci_tegra.c | 2 +- drivers/pci/pcie_mediatek.c | 4 ++-- include/dm/ofnode.h | 8 -------- lib/fdtdec.c | 2 +- net/dsa-uclass.c | 2 +- 22 files changed, 22 insertions(+), 39 deletions(-)
diff --git a/arch/arm/mach-tegra/xusb-padctl-common.c b/arch/arm/mach-tegra/xusb-padctl-common.c index 8bdd44ad7ac..388ec499688 100644 --- a/arch/arm/mach-tegra/xusb-padctl-common.c +++ b/arch/arm/mach-tegra/xusb-padctl-common.c @@ -282,7 +282,7 @@ int tegra_xusb_process_nodes(ofnode nodes[], unsigned int count, debug("%s: count=%d\n", __func__, count); for (i = 0; i < count; i++) { debug("%s: i=%d, node=%p\n", __func__, i, nodes[i].np); - if (!ofnode_is_available(nodes[i])) + if (!ofnode_is_enabled(nodes[i])) continue;
padctl.socdata = socdata; diff --git a/arch/riscv/lib/andes_plic.c b/arch/riscv/lib/andes_plic.c index 5e113ee8c94..68514758a86 100644 --- a/arch/riscv/lib/andes_plic.c +++ b/arch/riscv/lib/andes_plic.c @@ -71,7 +71,7 @@ int riscv_init_ipi(void) continue;
/* skip if hart is marked as not available */ - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue;
/* read hart ID of CPU */ diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c index ba992100adf..c276b914bfc 100644 --- a/arch/riscv/lib/smp.c +++ b/arch/riscv/lib/smp.c @@ -27,7 +27,7 @@ static int send_ipi_many(struct ipi_data *ipi, int wait)
ofnode_for_each_subnode(node, cpus) { /* skip if hart is marked as not available in the device tree */ - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue;
/* read hart ID of CPU */ diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index d0716b79f9d..a6122550fe0 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -766,15 +766,6 @@ const void *ofprop_get_property(const struct ofprop *prop, propname, lenp); }
-bool ofnode_is_available(ofnode node) -{ - if (ofnode_is_np(node)) - return of_device_is_available(ofnode_to_np(node)); - else - return fdtdec_get_is_enabled(gd->fdt_blob, - ofnode_to_offset(node)); -} - fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property, fdt_size_t *sizep) { diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index abddbef57b8..b8eb2d28006 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -144,7 +144,7 @@ static int cpu_imx_get_count(const struct udevice *dev) ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) { const char *device_type;
- if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue;
device_type = ofnode_read_string(node, "device_type"); diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c index b30dceba37c..d6484d7f4b4 100644 --- a/drivers/cpu/riscv_cpu.c +++ b/drivers/cpu/riscv_cpu.c @@ -77,7 +77,7 @@ static int riscv_cpu_get_count(const struct udevice *dev) const char *device_type;
/* skip if hart is marked as not available in the device tree */ - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue;
device_type = ofnode_read_string(node, "device_type"); diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index acd29924f7e..8c0fb27b532 100644 --- a/drivers/crypto/fsl/jr.c +++ b/drivers/crypto/fsl/jr.c @@ -853,7 +853,7 @@ static int caam_jr_probe(struct udevice *dev)
/* Check for enabled job ring node */ ofnode_for_each_subnode(node, dev_ofnode(dev)) { - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue;
jr_node = ofnode_read_u32_default(node, "reg", -1); diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c index 2b6211c4e6a..c3f3d1f4400 100644 --- a/drivers/firmware/scmi/scmi_agent-uclass.c +++ b/drivers/firmware/scmi/scmi_agent-uclass.c @@ -65,7 +65,7 @@ static int scmi_bind_protocols(struct udevice *dev) struct driver *drv = NULL; u32 protocol_id;
- if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue;
if (ofnode_read_u32(node, "reg", &protocol_id)) diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 56aa58b58bb..4886392a1cf 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -895,7 +895,7 @@ int add_mtd_partitions_of(struct mtd_info *master) else parts = ofnode_find_subnode(master->flash_node, "partitions");
- if (!ofnode_valid(parts) || !ofnode_is_available(parts) || + if (!ofnode_valid(parts) || !ofnode_is_enabled(parts) || !ofnode_device_is_compatible(parts, "fixed-partitions")) return 0;
@@ -905,7 +905,7 @@ int add_mtd_partitions_of(struct mtd_info *master) fdt_addr_t offset; fdt_size_t size;
- if (!ofnode_is_available(child)) + if (!ofnode_is_enabled(child)) continue;
offset = ofnode_get_addr_size_index_notrans(child, 0, &size); diff --git a/drivers/mtd/nand/raw/zynq_nand.c b/drivers/mtd/nand/raw/zynq_nand.c index 10e9cd18b07..14cb2ba7043 100644 --- a/drivers/mtd/nand/raw/zynq_nand.c +++ b/drivers/mtd/nand/raw/zynq_nand.c @@ -1095,7 +1095,7 @@ static int zynq_nand_probe(struct udevice *dev) } }
- if (!ofnode_is_available(of_nand)) { + if (!ofnode_is_enabled(of_nand)) { debug("Nand node in dt disabled\n"); return dm_scan_fdt_dev(dev); } diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 8bc2b46d403..bbc4434ddb9 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -1078,7 +1078,7 @@ static int device_get_phy_addr(struct fec_priv *priv, struct udevice *dev) return ret; }
- if (!ofnode_is_available(phandle_args.node)) + if (!ofnode_is_enabled(phandle_args.node)) return -ENOENT;
priv->phy_of_node = phandle_args.node; diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c index cd4c2c29a65..7096133c313 100644 --- a/drivers/net/fsl_enetc.c +++ b/drivers/net/fsl_enetc.c @@ -320,7 +320,7 @@ static int enetc_probe(struct udevice *dev) { struct enetc_priv *priv = dev_get_priv(dev);
- if (ofnode_valid(dev_ofnode(dev)) && !ofnode_is_available(dev_ofnode(dev))) { + if (ofnode_valid(dev_ofnode(dev)) && !ofnode_is_enabled(dev_ofnode(dev))) { enetc_dbg(dev, "interface disabled\n"); return -ENODEV; } diff --git a/drivers/net/mscc_eswitch/felix_switch.c b/drivers/net/mscc_eswitch/felix_switch.c index 709c9e3ef51..2e5f45e5743 100644 --- a/drivers/net/mscc_eswitch/felix_switch.c +++ b/drivers/net/mscc_eswitch/felix_switch.c @@ -287,7 +287,7 @@ static int felix_probe(struct udevice *dev) int err;
if (ofnode_valid(dev_ofnode(dev)) && - !ofnode_is_available(dev_ofnode(dev))) { + !ofnode_is_enabled(dev_ofnode(dev))) { dev_dbg(dev, "switch disabled\n"); return -ENODEV; } diff --git a/drivers/net/sja1105.c b/drivers/net/sja1105.c index 4ca8709e347..48f044c6472 100644 --- a/drivers/net/sja1105.c +++ b/drivers/net/sja1105.c @@ -3316,7 +3316,7 @@ static int sja1105_probe(struct udevice *dev) int rc;
if (ofnode_valid(dev_ofnode(dev)) && - !ofnode_is_available(dev_ofnode(dev))) { + !ofnode_is_enabled(dev_ofnode(dev))) { dev_dbg(dev, "switch disabled\n"); return -ENODEV; } diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c index 9580fa37eaf..b79e06290a2 100644 --- a/drivers/net/ti/am65-cpsw-nuss.c +++ b/drivers/net/ti/am65-cpsw-nuss.c @@ -719,7 +719,7 @@ static int am65_cpsw_probe_nuss(struct udevice *dev)
node_name = ofnode_get_name(node);
- disabled = !ofnode_is_available(node); + disabled = !ofnode_is_enabled(node);
ret = ofnode_read_u32(node, "reg", &port_id); if (ret) { diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 16a6a699f92..058b2f6359d 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -766,7 +766,7 @@ static int pci_find_and_bind_driver(struct udevice *parent, if (ofnode_valid(dev_ofnode(parent))) pci_dev_find_ofnode(parent, bdf, &node);
- if (ofnode_valid(node) && !ofnode_is_available(node)) { + if (ofnode_valid(node) && !ofnode_is_enabled(node)) { debug("%s: Ignoring disabled device\n", __func__); return log_msg_ret("dis", -EPERM); } diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c index 5bd340a421b..93a7508d8a2 100644 --- a/drivers/pci/pci_mvebu.c +++ b/drivers/pci/pci_mvebu.c @@ -740,7 +740,7 @@ static int mvebu_pcie_bind(struct udevice *parent)
/* First phase: Fill mvebu_pcie struct for each port */ ofnode_for_each_subnode(subnode, dev_ofnode(parent)) { - if (!ofnode_is_available(subnode)) + if (!ofnode_is_enabled(subnode)) continue;
pcie = calloc(1, sizeof(*pcie)); diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c index bc489d5ec85..29d54117e93 100644 --- a/drivers/pci/pci_tegra.c +++ b/drivers/pci/pci_tegra.c @@ -531,7 +531,7 @@ static int tegra_pcie_parse_dt(struct udevice *dev, enum tegra_pci_id id,
lanes |= num_lanes << (index << 3);
- if (!ofnode_is_available(subnode)) + if (!ofnode_is_enabled(subnode)) continue;
port = malloc(sizeof(*port)); diff --git a/drivers/pci/pcie_mediatek.c b/drivers/pci/pcie_mediatek.c index 051a3bc9693..c6e30e24622 100644 --- a/drivers/pci/pcie_mediatek.c +++ b/drivers/pci/pcie_mediatek.c @@ -657,7 +657,7 @@ static int mtk_pcie_probe(struct udevice *dev) struct fdt_pci_addr addr; u32 slot = 0;
- if (!ofnode_is_available(subnode)) + if (!ofnode_is_enabled(subnode)) continue;
err = ofnode_read_pci_addr(subnode, 0, "reg", &addr); @@ -696,7 +696,7 @@ static int mtk_pcie_probe_v2(struct udevice *dev) pcie->priv = dev;
dev_for_each_subnode(subnode, dev) { - if (!ofnode_is_available(subnode)) + if (!ofnode_is_enabled(subnode)) continue;
err = ofnode_read_pci_addr(subnode, 0, "reg", &addr); diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 8428e1a661e..3219965553e 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -832,14 +832,6 @@ int ofnode_next_property(struct ofprop *prop); const void *ofprop_get_property(const struct ofprop *prop, const char **propname, int *lenp);
-/** - * ofnode_is_available() - check if a node is marked available - * - * @node: node to check - * Return: true if node's 'status' property is "okay" (or is missing) - */ -bool ofnode_is_available(ofnode node); - /** * ofnode_get_addr_size() - get address and size from a property * diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 96b6b71a606..eca01081c5d 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1058,7 +1058,7 @@ ofnode get_next_memory_node(ofnode mem) { do { mem = ofnode_by_prop_value(mem, "device_type", "memory", 7); - } while (!ofnode_is_available(mem)); + } while (!ofnode_is_enabled(mem));
return mem; } diff --git a/net/dsa-uclass.c b/net/dsa-uclass.c index 3bf4351c847..5b7046432ff 100644 --- a/net/dsa-uclass.c +++ b/net/dsa-uclass.c @@ -432,7 +432,7 @@ static int dsa_post_bind(struct udevice *dev) * skip registration if port id not found or if the port * is explicitly disabled in DT */ - if (!ofnode_valid(pnode) || !ofnode_is_available(pnode)) + if (!ofnode_valid(pnode) || !ofnode_is_enabled(pnode)) continue;
err = device_bind_driver_to_node(dev, DSA_PORT_CHILD_DRV_NAME,

The current tests do not cover all the behaviour. Add some more.
Tidy up a few inconsistencies between livetree and flattree which come to light with these tests. Also drop the -ENODATA error since it is never actually returned.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/core/of_access.c | 5 +- drivers/core/ofnode.c | 13 +++-- include/dm/of_access.h | 10 ++-- include/dm/ofnode.h | 8 +-- test/dm/ofnode.c | 102 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 17 deletions(-)
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index 85716ac621b..47f6b39ce5c 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -471,8 +471,7 @@ struct device_node *of_find_node_by_phandle(struct device_node *root, * @len: requested length of property value * * Return: the property value on success, -EINVAL if the property does not - * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the - * property data isn't large enough. + * exist and -EOVERFLOW if the property data isn't large enough. */ static void *of_find_property_value_of_size(const struct device_node *np, const char *propname, u32 len) @@ -481,8 +480,6 @@ static void *of_find_property_value_of_size(const struct device_node *np,
if (!prop) return ERR_PTR(-EINVAL); - if (!prop->value) - return ERR_PTR(-ENODATA); if (len > prop->length) return ERR_PTR(-EOVERFLOW);
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index a6122550fe0..45bc7f9375d 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -234,9 +234,16 @@ int ofnode_read_u32_array(ofnode node, const char *propname, return of_read_u32_array(ofnode_to_np(node), propname, out_values, sz); } else { - return fdtdec_get_int_array(gd->fdt_blob, - ofnode_to_offset(node), propname, - out_values, sz); + int ret; + + ret = fdtdec_get_int_array(gd->fdt_blob, + ofnode_to_offset(node), propname, + out_values, sz); + if (ret == -FDT_ERR_NOTFOUND) + return -EINVAL; + else if (ret == -FDT_ERR_BADLAYOUT) + return -EOVERFLOW; + return ret; } }
diff --git a/include/dm/of_access.h b/include/dm/of_access.h index ed94dd3d3a4..ee8bed8b8fb 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -295,8 +295,7 @@ int of_read_u32(const struct device_node *np, const char *propname, u32 *outp); * @outp: pointer to return value, modified only if return value is 0. * * Return: - * 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the + * 0 on success, -EINVAL if the property does not exist, or -EOVERFLOW if the * property data isn't large enough. */ int of_read_u32_index(const struct device_node *np, const char *propname, @@ -313,8 +312,7 @@ int of_read_u32_index(const struct device_node *np, const char *propname, * @outp: pointer to return value, modified only if return value is 0. * * Return: - * 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the + * 0 on success, -EINVAL if the property does not exist, or -EOVERFLOW if the * property data isn't large enough. */ int of_read_u64(const struct device_node *np, const char *propname, u64 *outp); @@ -330,8 +328,8 @@ int of_read_u64(const struct device_node *np, const char *propname, u64 *outp); * @out_values: pointer to return value, modified only if return value is 0. * @sz: number of array elements to read * Return: - * 0 on success, -EINVAL if the property does not exist, -ENODATA - * if property does not have a value, and -EOVERFLOW is longer than sz. + * 0 on success, -EINVAL if the property does not exist, or -EOVERFLOW if + * longer than sz. */ int of_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values, size_t sz); diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 3219965553e..e221591225b 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -333,12 +333,12 @@ const char *ofnode_read_string(ofnode node, const char *propname); * @propname: name of the property to read * @out_values: pointer to return value, modified only if return value is 0 * @sz: number of array elements to read - * Return: 0 if OK, -ve on error + * Return: 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough * * Search for a property in a device node and read 32-bit value(s) from - * it. Returns 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the - * property data isn't large enough. + * it. * * The out_values is modified only if a valid u32 value can be decoded. */ diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 5ddfd0298a6..eac0c50364a 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -320,6 +320,9 @@ static int dm_test_ofnode_get_path(struct unit_test_state *uts) res = ofnode_get_path(node, buf, 32); ut_asserteq(-ENOSPC, res);
+ res = ofnode_get_path(ofnode_root(), buf, 32); + ut_asserteq_str("/", buf); + return 0; } DM_TEST(dm_test_ofnode_get_path, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); @@ -589,6 +592,7 @@ DM_TEST(dm_test_ofnode_livetree_writing, static int dm_test_ofnode_u32(struct unit_test_state *uts) { ofnode node; + u32 val;
node = ofnode_path("/lcd"); ut_assert(ofnode_valid(node)); @@ -597,10 +601,62 @@ static int dm_test_ofnode_u32(struct unit_test_state *uts) ut_asserteq(1367, ofnode_read_u32_default(node, "xres", 123)); ut_assertok(ofnode_write_u32(node, "xres", 1366));
+ node = ofnode_path("/backlight"); + ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 0, &val)); + ut_asserteq(0, val); + ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 1, &val)); + ut_asserteq(16, val); + ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 8, &val)); + ut_asserteq(255, val); + ut_asserteq(-EOVERFLOW, + ofnode_read_u32_index(node, "brightness-levels", 9, &val)); + ut_asserteq(-EINVAL, ofnode_read_u32_index(node, "missing", 0, &val)); + return 0; } DM_TEST(dm_test_ofnode_u32, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+static int dm_test_ofnode_u32_array(struct unit_test_state *uts) +{ + ofnode node; + u32 val[10]; + + node = ofnode_path("/a-test"); + ut_assert(ofnode_valid(node)); + ut_assertok(ofnode_read_u32_array(node, "int-value", val, 1)); + ut_asserteq(-EINVAL, ofnode_read_u32_array(node, "missing", val, 1)); + ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "bool-value", val, + 1)); + + memset(val, '\0', sizeof(val)); + ut_assertok(ofnode_read_u32_array(node, "int-array", val + 1, 3)); + ut_asserteq(0, val[0]); + ut_asserteq(5678, val[1]); + ut_asserteq(9123, val[2]); + ut_asserteq(4567, val[3]); + ut_asserteq(0, val[4]); + ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "int-array", val, + 4)); + + return 0; +} +DM_TEST(dm_test_ofnode_u32_array, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_u64(struct unit_test_state *uts) +{ + ofnode node; + u64 val; + + node = ofnode_path("/a-test"); + ut_assert(ofnode_valid(node)); + ut_assertok(ofnode_read_u64(node, "int64-value", &val)); + ut_asserteq_64(0x1111222233334444, val); + ut_asserteq(-EINVAL, ofnode_read_u64(node, "missing", &val)); + + return 0; +} +DM_TEST(dm_test_ofnode_u64, UT_TESTF_SCAN_FDT); + static int dm_test_ofnode_add_subnode(struct unit_test_state *uts) { ofnode node, check, subnode; @@ -693,3 +749,49 @@ static int dm_test_ofnode_for_each_prop(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_ofnode_for_each_prop, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_by_compatible(struct unit_test_state *uts) +{ + const char *compat = "denx,u-boot-fdt-test"; + ofnode node; + int count; + + count = 0; + for (node = ofnode_null(); + node = ofnode_by_compatible(node, compat), ofnode_valid(node);) + count++; + ut_asserteq(11, count); + + return 0; +} +DM_TEST(dm_test_ofnode_by_compatible, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_find_subnode(struct unit_test_state *uts) +{ + ofnode node, subnode; + + node = ofnode_path("/buttons"); + + subnode = ofnode_find_subnode(node, "btn1"); + ut_assert(ofnode_valid(subnode)); + ut_asserteq_str("btn1", ofnode_get_name(subnode)); + + subnode = ofnode_find_subnode(node, "btn"); + ut_assert(!ofnode_valid(subnode)); + + return 0; +} +DM_TEST(dm_test_ofnode_find_subnode, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_get_name(struct unit_test_state *uts) +{ + ofnode node; + + node = ofnode_path("/buttons"); + ut_assert(ofnode_valid(node)); + ut_asserteq_str("buttons", ofnode_get_name(node)); + ut_asserteq_str("", ofnode_get_name(ofnode_root())); + + return 0; +} +DM_TEST(dm_test_ofnode_get_name, UT_TESTF_SCAN_FDT);

On Tue, Sep 06, 2022 at 08:27:18PM -0600, Simon Glass wrote:
The current tests do not cover all the behaviour. Add some more.
Tidy up a few inconsistencies between livetree and flattree which come to light with these tests. Also drop the -ENODATA error since it is never actually returned.
Signed-off-by: Simon Glass sjg@chromium.org
This causes phycore-rk3288 to exceed the SPL size.

Hi Tom,
On Thu, 29 Sept 2022 at 17:13, Tom Rini trini@konsulko.com wrote:
On Tue, Sep 06, 2022 at 08:27:18PM -0600, Simon Glass wrote:
The current tests do not cover all the behaviour. Add some more.
Tidy up a few inconsistencies between livetree and flattree which come to light with these tests. Also drop the -ENODATA error since it is never actually returned.
Signed-off-by: Simon Glass sjg@chromium.org
This causes phycore-rk3288 to exceed the SPL size.
Wow it might be right on the edge. I suppose I have a different toolchain as it works for me.
Anyway I'll send a new patch for this.
Regards, Simon

At present there is only one device tree used by the ofnode functions, except for some esoteric use of live tree. In preparation for supporting more than one, add a way to reset the list of device trees.
For now this does nothing.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
common/board_r.c | 2 ++ include/dm/ofnode.h | 8 ++++++++ lib/fdtdec.c | 5 ++++- test/test-main.c | 2 ++ 4 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/common/board_r.c b/common/board_r.c index 56eb60fa275..77e9ca0581f 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -233,6 +233,8 @@ static int initr_dm(void) { int ret;
+ oftree_reset(); + /* Save the pre-reloc driver model and start a new one */ gd->dm_root_f = gd->dm_root; gd->dm_root = NULL; diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index e221591225b..46802366667 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -27,6 +27,14 @@ struct ofnode_phandle_args { uint32_t args[OF_MAX_PHANDLE_ARGS]; };
+/** + * oftree_reset() - reset the state of the oftree list + * + * Reset the oftree list so it can be started again. This should be called + * once the control FDT is in place, but before the ofnode interface is used. + */ +static inline void oftree_reset(void) {} + /** * ofnode_to_np() - convert an ofnode to a live DT node pointer * diff --git a/lib/fdtdec.c b/lib/fdtdec.c index eca01081c5d..64c5b3da15e 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -13,7 +13,6 @@ #include <log.h> #include <malloc.h> #include <net.h> -#include <dm/of_extra.h> #include <env.h> #include <errno.h> #include <fdtdec.h> @@ -24,6 +23,8 @@ #include <serial.h> #include <asm/global_data.h> #include <asm/sections.h> +#include <dm/ofnode.h> +#include <dm/of_extra.h> #include <linux/ctype.h> #include <linux/lzo.h> #include <linux/ioport.h> @@ -1668,6 +1669,8 @@ int fdtdec_setup(void) ret = fdtdec_prepare_fdt(); if (!ret) ret = fdtdec_board_setup(gd->fdt_blob); + oftree_reset(); + return ret; }
diff --git a/test/test-main.c b/test/test-main.c index e06b5437121..1011dc16849 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -10,6 +10,7 @@ #include <event.h> #include <of_live.h> #include <os.h> +#include <dm/ofnode.h> #include <dm/root.h> #include <dm/test.h> #include <dm/uclass-internal.h> @@ -98,6 +99,7 @@ static int dm_test_pre_run(struct unit_test_state *uts)
/* Determine whether to make the live tree available */ gd_set_of_root(of_live ? uts->of_root : NULL); + oftree_reset(); ut_assertok(dm_init(of_live)); uts->root = dm_root();

The flat device tree is assumed to be the control FDT but this is not always the case. Update the ofnode implementation to obtain the node via an function call so we can eventually add support for selecting different trees.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/core/ofnode.c | 91 ++++++++++++++++++++++++------------------- include/dm/ofnode.h | 19 +++++++++ 2 files changed, 69 insertions(+), 41 deletions(-)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 45bc7f9375d..8e1996e8aa3 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -57,8 +57,8 @@ int ofnode_read_u32_index(ofnode node, const char *propname, int index, return of_read_u32_index(ofnode_to_np(node), propname, index, outp);
- cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname, - &len); + cell = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node), + propname, &len); if (!cell) { debug("(not found)\n"); return -EINVAL; @@ -103,8 +103,8 @@ int ofnode_read_u64(ofnode node, const char *propname, u64 *outp) if (ofnode_is_np(node)) return of_read_u64(ofnode_to_np(node), propname, outp);
- cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname, - &len); + cell = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node), + propname, &len); if (!cell || len < sizeof(*cell)) { debug("(not found)\n"); return -EINVAL; @@ -155,7 +155,7 @@ const void *ofnode_read_prop(ofnode node, const char *propname, int *sizep) len = prop->length; } } else { - val = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), + val = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node), propname, &len); } if (!val) { @@ -214,7 +214,7 @@ ofnode ofnode_find_subnode(ofnode node, const char *subnode_name) } subnode = np_to_ofnode(np); } else { - int ooffset = fdt_subnode_offset(gd->fdt_blob, + int ooffset = fdt_subnode_offset(ofnode_to_fdt(node), ofnode_to_offset(node), subnode_name); subnode = offset_to_ofnode(ooffset); } @@ -236,7 +236,7 @@ int ofnode_read_u32_array(ofnode node, const char *propname, } else { int ret;
- ret = fdtdec_get_int_array(gd->fdt_blob, + ret = fdtdec_get_int_array(ofnode_to_fdt(node), ofnode_to_offset(node), propname, out_values, sz); if (ret == -FDT_ERR_NOTFOUND) @@ -253,7 +253,7 @@ bool ofnode_is_enabled(ofnode node) if (ofnode_is_np(node)) { return of_device_is_available(ofnode_to_np(node)); } else { - return fdtdec_get_is_enabled(gd->fdt_blob, + return fdtdec_get_is_enabled(ofnode_to_fdt(node), ofnode_to_offset(node)); } } @@ -265,7 +265,7 @@ ofnode ofnode_first_subnode(ofnode node) return np_to_ofnode(node.np->child);
return offset_to_ofnode( - fdt_first_subnode(gd->fdt_blob, ofnode_to_offset(node))); + fdt_first_subnode(ofnode_to_fdt(node), ofnode_to_offset(node))); }
ofnode ofnode_next_subnode(ofnode node) @@ -275,7 +275,7 @@ ofnode ofnode_next_subnode(ofnode node) return np_to_ofnode(node.np->sibling);
return offset_to_ofnode( - fdt_next_subnode(gd->fdt_blob, ofnode_to_offset(node))); + fdt_next_subnode(ofnode_to_fdt(node), ofnode_to_offset(node))); } #endif /* !DM_INLINE_OFNODE */
@@ -287,7 +287,7 @@ ofnode ofnode_get_parent(ofnode node) if (ofnode_is_np(node)) parent = np_to_ofnode(of_get_parent(ofnode_to_np(node))); else - parent.of_offset = fdt_parent_offset(gd->fdt_blob, + parent.of_offset = fdt_parent_offset(ofnode_to_fdt(node), ofnode_to_offset(node));
return parent; @@ -303,7 +303,7 @@ const char *ofnode_get_name(ofnode node) if (ofnode_is_np(node)) return node.np->name;
- return fdt_get_name(gd->fdt_blob, ofnode_to_offset(node), NULL); + return fdt_get_name(ofnode_to_fdt(node), ofnode_to_offset(node), NULL); }
int ofnode_get_path(ofnode node, char *buf, int buflen) @@ -320,7 +320,7 @@ int ofnode_get_path(ofnode node, char *buf, int buflen) } else { int res;
- res = fdt_get_path(gd->fdt_blob, ofnode_to_offset(node), buf, + res = fdt_get_path(ofnode_to_fdt(node), ofnode_to_offset(node), buf, buflen); if (!res) return res; @@ -376,7 +376,7 @@ static fdt_addr_t __ofnode_get_addr_size_index(ofnode node, int index, } else { na = ofnode_read_simple_addr_cells(ofnode_get_parent(node)); ns = ofnode_read_simple_size_cells(ofnode_get_parent(node)); - return fdtdec_get_addr_size_fixed(gd->fdt_blob, + return fdtdec_get_addr_size_fixed(ofnode_to_fdt(node), ofnode_to_offset(node), "reg", index, na, ns, size, translate); @@ -424,7 +424,7 @@ int ofnode_stringlist_search(ofnode node, const char *property, } else { int ret;
- ret = fdt_stringlist_search(gd->fdt_blob, + ret = fdt_stringlist_search(ofnode_to_fdt(node), ofnode_to_offset(node), property, string); if (ret == -FDT_ERR_NOTFOUND) @@ -445,7 +445,8 @@ int ofnode_read_string_index(ofnode node, const char *property, int index, } else { int len;
- *outp = fdt_stringlist_get(gd->fdt_blob, ofnode_to_offset(node), + *outp = fdt_stringlist_get(ofnode_to_fdt(node), + ofnode_to_offset(node), property, index, &len); if (len < 0) return -EINVAL; @@ -458,7 +459,7 @@ int ofnode_read_string_count(ofnode node, const char *property) if (ofnode_is_np(node)) { return of_property_count_strings(ofnode_to_np(node), property); } else { - return fdt_stringlist_count(gd->fdt_blob, + return fdt_stringlist_count(ofnode_to_fdt(node), ofnode_to_offset(node), property); } } @@ -527,7 +528,7 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name, struct fdtdec_phandle_args args; int ret;
- ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, + ret = fdtdec_parse_phandle_with_args(ofnode_to_fdt(node), ofnode_to_offset(node), list_name, cells_name, cell_count, index, &args); @@ -546,7 +547,7 @@ int ofnode_count_phandle_with_args(ofnode node, const char *list_name, return of_count_phandle_with_args(ofnode_to_np(node), list_name, cells_name, cell_count); else - return fdtdec_parse_phandle_with_args(gd->fdt_blob, + return fdtdec_parse_phandle_with_args(ofnode_to_fdt(node), ofnode_to_offset(node), list_name, cells_name, cell_count, -1, NULL); } @@ -721,7 +722,7 @@ const void *ofnode_get_property(ofnode node, const char *propname, int *lenp) if (ofnode_is_np(node)) return of_get_property(ofnode_to_np(node), propname, lenp); else - return fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), + return fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node), propname, lenp); }
@@ -735,7 +736,7 @@ int ofnode_first_property(ofnode node, struct ofprop *prop) return -FDT_ERR_NOTFOUND; } else { prop->offset = - fdt_first_property_offset(gd->fdt_blob, + fdt_first_property_offset(ofnode_to_fdt(node), ofnode_to_offset(prop->node)); if (prop->offset < 0) return prop->offset; @@ -752,8 +753,9 @@ int ofnode_next_property(struct ofprop *prop) if (!prop->prop) return -FDT_ERR_NOTFOUND; } else { - prop->offset = fdt_next_property_offset(gd->fdt_blob, - prop->offset); + prop->offset = + fdt_next_property_offset(ofnode_to_fdt(prop->node), + prop->offset); if (prop->offset < 0) return prop->offset; } @@ -768,7 +770,7 @@ const void *ofprop_get_property(const struct ofprop *prop, return of_get_property_by_prop(ofnode_to_np(prop->node), prop->prop, propname, lenp); else - return fdt_getprop_by_offset(gd->fdt_blob, + return fdt_getprop_by_offset(ofnode_to_fdt(prop->node), prop->offset, propname, lenp); } @@ -793,7 +795,7 @@ fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property, else return of_read_number(prop, na); } else { - return fdtdec_get_addr_size(gd->fdt_blob, + return fdtdec_get_addr_size(ofnode_to_fdt(node), ofnode_to_offset(node), property, sizep); } @@ -812,7 +814,7 @@ const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname, return (uint8_t *)prop;
} else { - return fdtdec_locate_byte_array(gd->fdt_blob, + return fdtdec_locate_byte_array(ofnode_to_fdt(node), ofnode_to_offset(node), propname, sz); } } @@ -948,10 +950,10 @@ int ofnode_read_addr_cells(ofnode node) if (ofnode_is_np(node)) { return of_n_addr_cells(ofnode_to_np(node)); } else { - int parent = fdt_parent_offset(gd->fdt_blob, + int parent = fdt_parent_offset(ofnode_to_fdt(node), ofnode_to_offset(node));
- return fdt_address_cells(gd->fdt_blob, parent); + return fdt_address_cells(ofnode_to_fdt(node), parent); } }
@@ -960,10 +962,10 @@ int ofnode_read_size_cells(ofnode node) if (ofnode_is_np(node)) { return of_n_size_cells(ofnode_to_np(node)); } else { - int parent = fdt_parent_offset(gd->fdt_blob, + int parent = fdt_parent_offset(ofnode_to_fdt(node), ofnode_to_offset(node));
- return fdt_size_cells(gd->fdt_blob, parent); + return fdt_size_cells(ofnode_to_fdt(node), parent); } }
@@ -972,7 +974,8 @@ int ofnode_read_simple_addr_cells(ofnode node) if (ofnode_is_np(node)) return of_simple_addr_cells(ofnode_to_np(node)); else - return fdt_address_cells(gd->fdt_blob, ofnode_to_offset(node)); + return fdt_address_cells(ofnode_to_fdt(node), + ofnode_to_offset(node)); }
int ofnode_read_simple_size_cells(ofnode node) @@ -980,7 +983,8 @@ int ofnode_read_simple_size_cells(ofnode node) if (ofnode_is_np(node)) return of_simple_size_cells(ofnode_to_np(node)); else - return fdt_size_cells(gd->fdt_blob, ofnode_to_offset(node)); + return fdt_size_cells(ofnode_to_fdt(node), + ofnode_to_offset(node)); }
bool ofnode_pre_reloc(ofnode node) @@ -1017,7 +1021,8 @@ int ofnode_read_resource(ofnode node, uint index, struct resource *res) struct fdt_resource fres; int ret;
- ret = fdt_get_resource(gd->fdt_blob, ofnode_to_offset(node), + ret = fdt_get_resource(ofnode_to_fdt(node), + ofnode_to_offset(node), "reg", index, &fres); if (ret < 0) return -EINVAL; @@ -1046,7 +1051,8 @@ u64 ofnode_translate_address(ofnode node, const fdt32_t *in_addr) if (ofnode_is_np(node)) return of_translate_address(ofnode_to_np(node), in_addr); else - return fdt_translate_address(gd->fdt_blob, ofnode_to_offset(node), in_addr); + return fdt_translate_address(ofnode_to_fdt(node), + ofnode_to_offset(node), in_addr); }
u64 ofnode_translate_dma_address(ofnode node, const fdt32_t *in_addr) @@ -1054,7 +1060,8 @@ u64 ofnode_translate_dma_address(ofnode node, const fdt32_t *in_addr) if (ofnode_is_np(node)) return of_translate_dma_address(ofnode_to_np(node), in_addr); else - return fdt_translate_dma_address(gd->fdt_blob, ofnode_to_offset(node), in_addr); + return fdt_translate_dma_address(ofnode_to_fdt(node), + ofnode_to_offset(node), in_addr); }
int ofnode_get_dma_range(ofnode node, phys_addr_t *cpu, dma_addr_t *bus, u64 *size) @@ -1062,7 +1069,8 @@ int ofnode_get_dma_range(ofnode node, phys_addr_t *cpu, dma_addr_t *bus, u64 *si if (ofnode_is_np(node)) return of_get_dma_range(ofnode_to_np(node), cpu, bus, size); else - return fdt_get_dma_range(gd->fdt_blob, ofnode_to_offset(node), + return fdt_get_dma_range(ofnode_to_fdt(node), + ofnode_to_offset(node), cpu, bus, size); }
@@ -1072,7 +1080,7 @@ int ofnode_device_is_compatible(ofnode node, const char *compat) return of_device_is_compatible(ofnode_to_np(node), compat, NULL, NULL); else - return !fdt_node_check_compatible(gd->fdt_blob, + return !fdt_node_check_compatible(ofnode_to_fdt(node), ofnode_to_offset(node), compat); } @@ -1085,7 +1093,8 @@ ofnode ofnode_by_compatible(ofnode from, const char *compat) compat)); } else { return offset_to_ofnode(fdt_node_offset_by_compatible( - gd->fdt_blob, ofnode_to_offset(from), compat)); + ofnode_to_fdt(from), + ofnode_to_offset(from), compat)); } }
@@ -1098,7 +1107,7 @@ ofnode ofnode_by_prop_value(ofnode from, const char *propname, propval, proplen)); } else { return offset_to_ofnode(fdt_node_offset_by_prop_value( - gd->fdt_blob, ofnode_to_offset(from), + ofnode_to_fdt(from), ofnode_to_offset(from), propname, propval, proplen)); } } @@ -1109,7 +1118,7 @@ int ofnode_write_prop(ofnode node, const char *propname, const void *value, if (of_live_active()) return of_write_prop(ofnode_to_np(node), propname, len, value); else - return fdt_setprop((void *)gd->fdt_blob, ofnode_to_offset(node), + return fdt_setprop(ofnode_to_fdt(node), ofnode_to_offset(node), propname, value, len);
return 0; @@ -1242,7 +1251,7 @@ int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep) return ret; subnode = np_to_ofnode(child); } else { - void *fdt = (void *)gd->fdt_blob; + void *fdt = ofnode_to_fdt(node); int poffset = ofnode_to_offset(node); int offset;
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 46802366667..0423c072402 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -35,6 +35,25 @@ struct ofnode_phandle_args { */ static inline void oftree_reset(void) {}
+/** + * ofnode_to_fdt() - convert an ofnode to a flat DT pointer + * + * This cannot be called if the reference contains a node pointer. + * + * @node: Reference containing offset (possibly invalid) + * Return: DT offset (can be NULL) + */ +static inline void *ofnode_to_fdt(ofnode node) +{ +#ifdef OF_CHECKS + if (of_live_active()) + return NULL; +#endif + + /* Use the control FDT by default */ + return (void *)gd->fdt_blob; +} + /** * ofnode_to_np() - convert an ofnode to a live DT node pointer *

At present dm_test_ofnode_root() does this manually. Add some inline functions to handle it, so this code can be centralised.
Add oftree functions to produce a null tree and to check whether a tree is valid or not.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
include/dm/ofnode.h | 63 +++++++++++++++++++++++++++++++++++++++++++++ test/dm/ofnode.c | 7 +++-- 2 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 0423c072402..661f38bdc69 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -173,6 +173,38 @@ static inline bool ofnode_equal(ofnode ref1, ofnode ref2) return ref1.of_offset == ref2.of_offset; }
+/** + * oftree_valid() - check if an oftree is valid + * + * @tree: Reference containing oftree + * Return: true if the reference contains a valid oftree, false if node + */ +static inline bool oftree_valid(oftree tree) +{ + if (of_live_active()) + return tree.np; + else + return tree.fdt; +} + +/** + * oftree_null() - Obtain a null oftree + * + * This returns an oftree which points to no tree. It works both with the flat + * tree and livetree. + */ +static inline oftree oftree_null(void) +{ + oftree tree; + + if (of_live_active()) + tree.np = NULL; + else + tree.fdt = NULL; + + return tree; +} + /** * ofnode_null() - Obtain a null ofnode * @@ -234,6 +266,37 @@ static inline oftree oftree_default(void) return tree; }
+/** + * oftree_from_np() - Returns an oftree from a node pointer + * + * @root: Root node of the tree + * Returns: reference to the given node + */ +static inline oftree oftree_from_np(struct device_node *root) +{ + oftree tree; + + tree.np = root; + + return tree; +} + +/** + * oftree_from_fdt() - Returns an oftree from a flat device tree pointer + * + * @fdt: Device tree to use + * + * Returns: reference to the given node + */ +static inline oftree oftree_from_fdt(void *fdt) +{ + oftree tree; + + tree.fdt = fdt; + + return tree; +} + /** * ofnode_name_eq() - Check if the node name is equivalent to a given name * ignoring the unit address diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index eac0c50364a..f146b52d625 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -518,13 +518,16 @@ static int dm_test_ofnode_root(struct unit_test_state *uts) ut_assert(ofnode_valid(node)); ut_asserteq_str("sbe5", ofnode_get_name(node));
+ ut_assert(!oftree_valid(oftree_null())); + ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt))); if (of_live_active()) { ut_assertok(unflatten_device_tree(fdt, &root)); - tree.np = root; + tree = oftree_from_np(root); } else { - tree.fdt = fdt; + tree = oftree_from_fdt(fdt); } + ut_assert(oftree_valid(tree));
/* Make sure they don't work on this new tree */ node = ofnode_path_root(tree, "mmc0");

When we have multiple trees, the ofnode logic needs to be told which one to use. Create a new function which takes an oftree argument, along with a helper to obtain the FDT pointer from an oftree.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/core/ofnode.c | 14 ++++++++++++++ include/dm/ofnode.h | 25 +++++++++++++++++++++++++ test/dm/ofnode.c | 2 ++ 3 files changed, 41 insertions(+)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 8e1996e8aa3..9462b4e8615 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -344,6 +344,20 @@ ofnode ofnode_get_by_phandle(uint phandle) return node; }
+ofnode oftree_get_by_phandle(oftree tree, uint phandle) +{ + ofnode node; + + if (of_live_active()) + node = np_to_ofnode(of_find_node_by_phandle(tree.np, phandle)); + else + node.of_offset = + fdt_node_offset_by_phandle(oftree_lookup_fdt(tree), + phandle); + + return node; +} + static fdt_addr_t __ofnode_get_addr_size_index(ofnode node, int index, fdt_size_t *size, bool translate) { diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 661f38bdc69..5c2458ab4ab 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -102,6 +102,22 @@ static inline bool ofnode_valid(ofnode node) return node.of_offset >= 0; }
+/** + * oftree_lookup_fdt() - obtain the FDT pointer from an oftree + * + * This can only be called when flat tree is enabled + * + * @tree: Tree to look at + * @return FDT pointer from the tree + */ +static inline void *oftree_lookup_fdt(oftree tree) +{ + if (of_live_active()) + return NULL; + else + return tree.fdt; +} + /** * offset_to_ofnode() - convert a DT offset to an ofnode * @@ -554,6 +570,15 @@ int ofnode_get_path(ofnode node, char *buf, int buflen); */ ofnode ofnode_get_by_phandle(uint phandle);
+/** + * oftree_get_by_phandle() - get ofnode from phandle + * + * @tree: tree to use + * @phandle: phandle to look up + * Return: ofnode reference to the phandle + */ +ofnode oftree_get_by_phandle(oftree tree, uint phandle); + /** * ofnode_read_size() - read the size of a property * diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index f146b52d625..f6bb04642e8 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -36,6 +36,8 @@ static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts) /* test unknown phandle */ ut_assert(!ofnode_valid(ofnode_get_by_phandle(0x1000000)));
+ ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1))); + return 0; } DM_TEST(dm_test_ofnode_get_by_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);

In some cases we want to obtain an ofnode in the same tree as a different ofnode, such as when looking up a subnode. At present this is trivial, since there is only one tree. When there are multiple trees, this implementation will change.
Also move the ofnode_to_offset() function up higher in the header file, since we will need to provide a different implementation with multiple trees.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/core/ofnode.c | 19 ++++++++++--------- include/dm/ofnode.h | 44 +++++++++++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 21 deletions(-)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 9462b4e8615..d01d964f570 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -216,7 +216,7 @@ ofnode ofnode_find_subnode(ofnode node, const char *subnode_name) } else { int ooffset = fdt_subnode_offset(ofnode_to_fdt(node), ofnode_to_offset(node), subnode_name); - subnode = offset_to_ofnode(ooffset); + subnode = noffset_to_ofnode(node, ooffset); } debug("%s\n", ofnode_valid(subnode) ? ofnode_get_name(subnode) : "<none>"); @@ -264,7 +264,7 @@ ofnode ofnode_first_subnode(ofnode node) if (ofnode_is_np(node)) return np_to_ofnode(node.np->child);
- return offset_to_ofnode( + return noffset_to_ofnode(node, fdt_first_subnode(ofnode_to_fdt(node), ofnode_to_offset(node))); }
@@ -274,7 +274,7 @@ ofnode ofnode_next_subnode(ofnode node) if (ofnode_is_np(node)) return np_to_ofnode(node.np->sibling);
- return offset_to_ofnode( + return noffset_to_ofnode(node, fdt_next_subnode(ofnode_to_fdt(node), ofnode_to_offset(node))); } #endif /* !DM_INLINE_OFNODE */ @@ -1106,8 +1106,8 @@ ofnode ofnode_by_compatible(ofnode from, const char *compat) (struct device_node *)ofnode_to_np(from), NULL, compat)); } else { - return offset_to_ofnode(fdt_node_offset_by_compatible( - ofnode_to_fdt(from), + return noffset_to_ofnode(from, + fdt_node_offset_by_compatible(ofnode_to_fdt(from), ofnode_to_offset(from), compat)); } } @@ -1120,9 +1120,10 @@ ofnode ofnode_by_prop_value(ofnode from, const char *propname, (struct device_node *)ofnode_to_np(from), propname, propval, proplen)); } else { - return offset_to_ofnode(fdt_node_offset_by_prop_value( - ofnode_to_fdt(from), ofnode_to_offset(from), - propname, propval, proplen)); + return noffset_to_ofnode(from, + fdt_node_offset_by_prop_value(ofnode_to_fdt(from), + ofnode_to_offset(from), propname, propval, + proplen)); } }
@@ -1276,7 +1277,7 @@ int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep) } if (offset < 0) return -EINVAL; - subnode = offset_to_ofnode(offset); + subnode = noffset_to_ofnode(node, offset); }
*subnodep = subnode; diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 5c2458ab4ab..2a58c00ef7d 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -54,6 +54,23 @@ static inline void *ofnode_to_fdt(ofnode node) return (void *)gd->fdt_blob; }
+/** + * ofnode_to_offset() - convert an ofnode to a flat DT offset + * + * This cannot be called if the reference contains a node pointer. + * + * @node: Reference containing offset (possibly invalid) + * Return: DT offset (can be -1) + */ +static inline int ofnode_to_offset(ofnode node) +{ +#ifdef OF_CHECKS + if (of_live_active()) + return -1; +#endif + return node.of_offset; +} + /** * ofnode_to_np() - convert an ofnode to a live DT node pointer * @@ -72,20 +89,22 @@ static inline struct device_node *ofnode_to_np(ofnode node) }
/** - * ofnode_to_offset() - convert an ofnode to a flat DT offset + * noffset_to_ofnode() - convert a DT offset to an ofnode * - * This cannot be called if the reference contains a node pointer. - * - * @node: Reference containing offset (possibly invalid) - * Return: DT offset (can be -1) + * @other_node: Node in the same tree to use as a reference + * @of_offset: DT offset (either valid, or -1) + * Return: reference to the associated DT offset */ -static inline int ofnode_to_offset(ofnode node) +static inline ofnode noffset_to_ofnode(ofnode other_node, int of_offset) { -#ifdef OF_CHECKS + ofnode node; + if (of_live_active()) - return -1; -#endif - return node.of_offset; + node.np = NULL; + else + node.of_offset = of_offset; + + return node; }
/** @@ -1135,8 +1154,9 @@ ofnode ofnode_by_compatible(ofnode from, const char *compat); * Find the next node after @from that has a @propname with a value * @propval and a length @proplen. * - * @from: ofnode to start from (use ofnode_null() to start at the - * beginning) + * @from: ofnode to start from. Use ofnode_null() to start at the + * beginning, or the return value from oftree_root() to start at the first + * child of the root * @propname: property name to check * @propval: property value to search for * @proplen: length of the value in propval

This function turns out to be a little confusing since it looks up a path and also registers the tree. Split it into two, one that gets the root node and one that looks up a path, so the purpose is clear.
Registering the tree will happen in a function to be added in a later patch, called oftree_from_fdt().
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
boot/vbe_simple.c | 2 +- drivers/core/ofnode.c | 42 +++++++++++++++++++++++++++++++++++++----- include/dm/ofnode.h | 16 +++++++++++++--- test/boot/vbe_simple.c | 2 +- test/dm/ofnode.c | 6 +++--- 5 files changed, 55 insertions(+), 13 deletions(-)
diff --git a/boot/vbe_simple.c b/boot/vbe_simple.c index 0fc57388f35..61b6322ebe2 100644 --- a/boot/vbe_simple.c +++ b/boot/vbe_simple.c @@ -240,7 +240,7 @@ static int bootmeth_vbe_simple_ft_fixup(void *ctx, struct event *event) continue;
/* Check if there is a node to fix up */ - node = ofnode_path_root(tree, "/chosen/fwupd"); + node = oftree_path(tree, "/chosen/fwupd"); if (!ofnode_valid(node)) continue; node = ofnode_find_subnode(node, dev->name); diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index d01d964f570..88534a0a3d8 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -18,6 +18,26 @@ #include <linux/ioport.h> #include <asm/global_data.h>
+/** + * ofnode_from_tree_offset() - get an ofnode from a tree offset (flat tree) + * + * Looks up the tree and returns an ofnode with the correct of_offset + * + * If @offset is < 0 then this returns an ofnode with that offset + * + * @tree: tree to check + * @offset: offset within that tree (can be < 0) + * @return node for that offset + */ +static ofnode ofnode_from_tree_offset(oftree tree, int offset) +{ + ofnode node; + + node.of_offset = offset; + + return node; +} + bool ofnode_name_eq(ofnode node, const char *name) { const char *node_name; @@ -574,15 +594,27 @@ ofnode ofnode_path(const char *path) return offset_to_ofnode(fdt_path_offset(gd->fdt_blob, path)); }
-ofnode ofnode_path_root(oftree tree, const char *path) +ofnode oftree_root(oftree tree) { - if (of_live_active()) + if (of_live_active()) { + return np_to_ofnode(tree.np); + } else { + return ofnode_from_tree_offset(tree, 0); + } +} + +ofnode oftree_path(oftree tree, const char *path) +{ + if (of_live_active()) { return np_to_ofnode(of_find_node_opts_by_path(tree.np, path, NULL)); - else if (*path != '/' && tree.fdt != gd->fdt_blob) + } else if (*path != '/' && tree.fdt != gd->fdt_blob) { return ofnode_null(); /* Aliases only on control FDT */ - else - return offset_to_ofnode(fdt_path_offset(tree.fdt, path)); + } else { + int offset = fdt_path_offset(tree.fdt, path); + + return ofnode_from_tree_offset(tree, offset); + } }
const void *ofnode_read_chosen_prop(const char *propname, int *sizep) diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 2a58c00ef7d..5ec7126922b 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -815,18 +815,28 @@ int ofnode_count_phandle_with_args(ofnode node, const char *list_name, ofnode ofnode_path(const char *path);
/** - * ofnode_path_root() - find a node by full path from a root node + * oftree_path() - find a node by full path from a root node * * @tree: Device tree to use * @path: Full path to node, e.g. "/bus/spi@1" * Return: reference to the node found. Use ofnode_valid() to check if it exists */ -ofnode ofnode_path_root(oftree tree, const char *path); +ofnode oftree_path(oftree tree, const char *path); + +/** + * oftree_root() - get the root node of a tree + * + * @tree: Device tree to use + * Return: reference to the root node + */ +ofnode oftree_root(oftree tree);
/** * ofnode_read_chosen_prop() - get the value of a chosen property * - * This looks for a property within the /chosen node and returns its value + * This looks for a property within the /chosen node and returns its value. + * + * This only works with the control FDT. * * @propname: Property name to look for * @sizep: Returns size of property, or `FDT_ERR_...` error code if function diff --git a/test/boot/vbe_simple.c b/test/boot/vbe_simple.c index 2f6979cafcf..3f03fc3acd2 100644 --- a/test/boot/vbe_simple.c +++ b/test/boot/vbe_simple.c @@ -96,7 +96,7 @@ static int vbe_simple_test_base(struct unit_test_state *uts) fixup.tree.np = np; ut_assertok(event_notify(EVT_FT_FIXUP, &fixup, sizeof(fixup)));
- node = ofnode_path_root(fixup.tree, "/chosen/fwupd/firmware0"); + node = oftree_path(fixup.tree, "/chosen/fwupd/firmware0");
version = ofnode_read_string(node, "cur-version"); ut_assertnonnull(version); diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index f6bb04642e8..b73ab988287 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -532,15 +532,15 @@ static int dm_test_ofnode_root(struct unit_test_state *uts) ut_assert(oftree_valid(tree));
/* Make sure they don't work on this new tree */ - node = ofnode_path_root(tree, "mmc0"); + node = oftree_path(tree, "mmc0"); ut_assert(!ofnode_valid(node));
/* It should appear in the new tree */ - node = ofnode_path_root(tree, "/new-mmc"); + node = oftree_path(tree, "/new-mmc"); ut_assert(ofnode_valid(node));
/* ...and not in the control FDT */ - node = ofnode_path_root(oftree_default(), "/new-mmc"); + node = oftree_path(oftree_default(), "/new-mmc"); ut_assert(!ofnode_valid(node));
free(root);

At present, unless OF_LIVE is enabled, ofnode only supports access to one device tree, the control FDT. This is because only the node offset is encoded in ofnode, with the tree being implicit.
This makes ofnode (without OF_LIVE) unsuitable for device tree fixups, as implemented by ft_board_setup() and other such functions.
To solve this, we can use the top bits of the node offset to hold a tree ID.
Add the definitions for this.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/core/Kconfig | 24 ++++++++++++++++++++++++ include/dm/ofnode_decl.h | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index 007dc6a1de3..c9bf5de4332 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -400,6 +400,30 @@ config DM_DEV_READ_INLINE bool default y if !OF_LIVE
+config OFNODE_MULTI_TREE + bool "Allow the ofnode interface to access any tree" + default y if EVENT && !DM_DEV_READ_INLINE && !DM_INLINE_OFNODE + help + Normally U-Boot makes use of its control FDT, the one used to bind + devices and provide options. In some cases, U-Boot must also process + a separate FDT, e.g. one provided by the operating system, which + needs additions to the /chosen node. + + This works fine with live tree (OF_LIVE), but with flat tree the + offset provided in ofnode is only useful with the control FDT. This + option adds a 'tree ID' to the offset, so that multiple trees can + be used. Call oftree_from_fdt() to register a new tree. + +config OFNODE_MULTI_TREE_MAX + int "Maximum number of FDTs" + range 2 8 + depends on OFNODE_MULTI_TREE + default 4 + help + Sets the maximum number of device trees which can be used with the + ofnode interface when using flat trees (OF_LIVE). This is only + available in U-Boot proper and only after relocation. + config ACPIGEN bool "Support ACPI table generation in driver model" default y if SANDBOX || (GENERATE_ACPI_TABLE && !QEMU) diff --git a/include/dm/ofnode_decl.h b/include/dm/ofnode_decl.h index f666a0287ba..5c2115aab0b 100644 --- a/include/dm/ofnode_decl.h +++ b/include/dm/ofnode_decl.h @@ -31,8 +31,18 @@ * this increases code size slightly due to the subtraction. Since it offers no * real benefit, the approach described here seems best. * - * For now these points use constant types, since we don't allow writing - * the DT. + * Where multiple trees are in use, this works without any trouble with live + * tree, except for aliases, such as ofnode_path("mmc0"), which only work on the + * control FDT. When the flat tree is in use, the trees are registered and a + * 'tree ID' is encoded into the top bits of @of_offset - see immediately below + * for the associated macro definitions. Note that 64-bit machines use the same + * encoding, even though there is more space available. This is partly because + * the FDT format contains 32-bit values for things like the string-table + * offset, therefore 64-bit offsets cannot be supported anyway. + * + * For the multiple-tree case, an invalid offset (i.e. with of_offset < 0) is + * still invalid. It does not contain a tree ID. So there is no way of knowing + * which tree produced the invalid offset. * * @np: Pointer to device node, used for live tree * @of_offset: Pointer into flat device tree, used for flat tree. Note that this @@ -43,6 +53,25 @@ typedef union ofnode_union { long of_offset; } ofnode;
+/* shift for the tree ID within of_offset */ +#define OF_TREE_SHIFT 28 + +/* mask to obtain the device tree offset from of_offset */ +#define OF_TREE_MASK ((1 << OF_TREE_SHIFT) - 1) + +/* encode a tree ID and node offset into an of_offset value */ +#define OFTREE_NODE(tree_id, offs) ((tree_id) << OF_TREE_SHIFT | (offs)) + +/* decode the node offset from an of_offset value */ +#define OFTREE_OFFSET(of_offs) ((of_offs) & OF_TREE_MASK) + +/* decode the tree ID from an of_offset value */ +#define OFTREE_TREE_ID(of_offs) ((of_offs) >> OF_TREE_SHIFT) + +/* encode a node offset in the tree given by another node's of_offset value */ +#define OFTREE_MAKE_NODE(other_of_offset, offs) \ + (((offs) & OF_TREE_MASK) | ((other_of_offset) & ~OF_TREE_MASK)) + /** * struct ofprop - reference to a property of a device tree node *

Add the logic to redirect requests for the device tree through a function which can look up the tree ID. This works by using the top bits of ofnode.of_offset to encode a tree.
It is assumed that there will only be a few device trees used at runtime, typically the control FDT (always tree ID 0) and possibly a separate FDT to be passed the OS.
The maximum number of device trees supported at runtime is 8, with this implementation. That would use bits 30:28 of the node-offset value, meaning that the positive offset range is limited to bits 27:0, versus 30:1 with this feature disabled. That still allows a device tree of up to 256MB, which should be enough for most FITs. Larger ones can be supported by using external data with the FIT, or by enabling OF_LIVE.
Update the documentation a little and fix up the comment for ofnode_valid().
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
doc/develop/driver-model/livetree.rst | 13 +- drivers/core/ofnode.c | 170 +++++++++++++++++++++++++- include/dm/ofnode.h | 111 ++++++++++------- 3 files changed, 238 insertions(+), 56 deletions(-)
diff --git a/doc/develop/driver-model/livetree.rst b/doc/develop/driver-model/livetree.rst index 4ef8c517325..76be89b9633 100644 --- a/doc/develop/driver-model/livetree.rst +++ b/doc/develop/driver-model/livetree.rst @@ -250,11 +250,14 @@ a flat tree. It would be helpful to use livetree for fixups, since adding a lot of nodes and properties would involve less memory copying and be more efficient. As a step towards this, an `oftree` type has been introduced. It is normally set to -oftree_default() but can be set to other values. Eventually this should allow -the use of FDT fixups using the ofnode interface, instead of the low-level -libfdt one. - -See dm_test_ofnode_root() for some examples. +oftree_default() but can be set to other values using oftree_from_fdt(). +So long as OF_LIVE is disabled, it is possible to do fixups using the ofnode +interface. The OF_LIVE support required addition of the flattening step at the +end. + +See dm_test_ofnode_root() for some examples. The ofnode_path_root() function +causes a flat device tree to be 'registered' such that it can be used by the +ofnode interface.
Internal implementation diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 88534a0a3d8..7b0a993d305 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -4,6 +4,8 @@ * Written by Simon Glass sjg@chromium.org */
+#define LOG_CATEGORY LOGC_DT + #include <common.h> #include <dm.h> #include <fdtdec.h> @@ -18,22 +20,182 @@ #include <linux/ioport.h> #include <asm/global_data.h>
+DECLARE_GLOBAL_DATA_PTR; + +#if CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) +static void *oftree_list[CONFIG_OFNODE_MULTI_TREE_MAX]; +static int oftree_count; + +void oftree_reset(void) +{ + if (gd->flags & GD_FLG_RELOC) { + oftree_count = 0; + oftree_list[oftree_count++] = (void *)gd->fdt_blob; + } +} + +static int oftree_find(const void *fdt) +{ + int i; + + for (i = 0; i < oftree_count; i++) { + if (fdt == oftree_list[i]) + return i; + } + + return -1; +} + +static oftree oftree_ensure(void *fdt) +{ + oftree tree; + int i; + + if (gd->flags & GD_FLG_RELOC) { + i = oftree_find(fdt); + if (i == -1) { + if (oftree_count == CONFIG_OFNODE_MULTI_TREE_MAX) { + log_warning("Too many registered device trees (max %d)\n", + CONFIG_OFNODE_MULTI_TREE_MAX); + return oftree_null(); + } + + /* register the new tree */ + i = oftree_count++; + oftree_list[i] = fdt; + log_debug("oftree: registered tree %d: %p\n", i, fdt); + } + } else { + if (fdt != gd->fdt_blob) { + log_debug("Cannot only access control FDT before relocation\n"); + return oftree_null(); + } + } + + tree.fdt = fdt; + + return tree; +} + +void *ofnode_lookup_fdt(ofnode node) +{ + if (gd->flags & GD_FLG_RELOC) { + uint i = OFTREE_TREE_ID(node.of_offset); + + if (i > oftree_count) { + log_debug("Invalid tree ID %x\n", i); + return NULL; + } + + return oftree_list[i]; + } else { + return (void *)gd->fdt_blob; + } +} + +void *ofnode_to_fdt(ofnode node) +{ +#ifdef OF_CHECKS + if (of_live_active()) + return NULL; +#endif + if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) && ofnode_valid(node)) + return ofnode_lookup_fdt(node); + + /* Use the control FDT by default */ + return (void *)gd->fdt_blob; +} + +/** + * ofnode_to_offset() - convert an ofnode to a flat DT offset + * + * This cannot be called if the reference contains a node pointer. + * + * @node: Reference containing offset (possibly invalid) + * Return: DT offset (can be -1) + */ +int ofnode_to_offset(ofnode node) +{ +#ifdef OF_CHECKS + if (of_live_active()) + return -1; +#endif + if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) && node.of_offset >= 0) + return OFTREE_OFFSET(node.of_offset); + + return node.of_offset; +} + +oftree oftree_from_fdt(void *fdt) +{ + oftree tree; + + if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE)) + return oftree_ensure(fdt); + + tree.fdt = fdt; + + return tree; +} + +/** + * noffset_to_ofnode() - convert a DT offset to an ofnode + * + * @other_node: Node in the same tree to use as a reference + * @of_offset: DT offset (either valid, or -1) + * Return: reference to the associated DT offset + */ +ofnode noffset_to_ofnode(ofnode other_node, int of_offset) +{ + ofnode node; + + if (of_live_active()) + node.np = NULL; + else if (!CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) || of_offset < 0 || + !ofnode_valid(other_node)) + node.of_offset = of_offset; + else + node.of_offset = OFTREE_MAKE_NODE(other_node.of_offset, + of_offset); + + return node; +} + +#else /* !OFNODE_MULTI_TREE */ + +static inline int oftree_find(const void *fdt) +{ + return 0; +} + +#endif /* OFNODE_MULTI_TREE */ + /** * ofnode_from_tree_offset() - get an ofnode from a tree offset (flat tree) * - * Looks up the tree and returns an ofnode with the correct of_offset + * Looks up the tree and returns an ofnode with the correct of_offset (i.e. + * containing the tree ID). * - * If @offset is < 0 then this returns an ofnode with that offset + * If @offset is < 0 then this returns an ofnode with that offset and no tree + * ID. * * @tree: tree to check * @offset: offset within that tree (can be < 0) - * @return node for that offset + * @return node for that offset, with the correct ID */ static ofnode ofnode_from_tree_offset(oftree tree, int offset) { ofnode node;
- node.of_offset = offset; + if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) && offset >= 0) { + int tree_id = oftree_find(tree.fdt); + + if (tree_id == -1) + return ofnode_null(); + node.of_offset = OFTREE_NODE(tree_id, offset); + } else { + node.of_offset = offset; + }
return node; } diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 5ec7126922b..8e383c26d44 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -27,13 +27,14 @@ struct ofnode_phandle_args { uint32_t args[OF_MAX_PHANDLE_ARGS]; };
+#if CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) /** * oftree_reset() - reset the state of the oftree list * * Reset the oftree list so it can be started again. This should be called * once the control FDT is in place, but before the ofnode interface is used. */ -static inline void oftree_reset(void) {} +void oftree_reset(void);
/** * ofnode_to_fdt() - convert an ofnode to a flat DT pointer @@ -43,26 +44,50 @@ static inline void oftree_reset(void) {} * @node: Reference containing offset (possibly invalid) * Return: DT offset (can be NULL) */ +__attribute_const__ void *ofnode_to_fdt(ofnode node); + +/** + * ofnode_to_offset() - convert an ofnode to a flat DT offset + * + * This cannot be called if the reference contains a node pointer. + * + * @node: Reference containing offset (possibly invalid) + * Return: DT offset (can be -1) + */ +__attribute_const__ int ofnode_to_offset(ofnode node); + +/** + * oftree_from_fdt() - Returns an oftree from a flat device tree pointer + * + * @fdt: Device tree to use + * + * Returns: reference to the given node + */ +oftree oftree_from_fdt(void *fdt); + +/** + * noffset_to_ofnode() - convert a DT offset to an ofnode + * + * @other_node: Node in the same tree to use as a reference + * @of_offset: DT offset (either valid, or -1) + * Return: reference to the associated DT offset + */ +ofnode noffset_to_ofnode(ofnode other_node, int of_offset); + +#else /* !OFNODE_MULTI_TREE */ +static inline void oftree_reset(void) {} + static inline void *ofnode_to_fdt(ofnode node) { #ifdef OF_CHECKS if (of_live_active()) return NULL; #endif - /* Use the control FDT by default */ return (void *)gd->fdt_blob; }
-/** - * ofnode_to_offset() - convert an ofnode to a flat DT offset - * - * This cannot be called if the reference contains a node pointer. - * - * @node: Reference containing offset (possibly invalid) - * Return: DT offset (can be -1) - */ -static inline int ofnode_to_offset(ofnode node) +static inline __attribute_const__ int ofnode_to_offset(ofnode node) { #ifdef OF_CHECKS if (of_live_active()) @@ -71,6 +96,33 @@ static inline int ofnode_to_offset(ofnode node) return node.of_offset; }
+static inline oftree oftree_from_fdt(void *fdt) +{ + oftree tree; + + /* we cannot access other trees without OFNODE_MULTI_TREE */ + if (fdt == gd->fdt_blob) + tree.fdt = fdt; + else + tree.fdt = NULL; + + return tree; +} + +static inline ofnode noffset_to_ofnode(ofnode other_node, int of_offset) +{ + ofnode node; + + if (of_live_active()) + node.np = NULL; + else + node.of_offset = of_offset; + + return node; +} + +#endif /* OFNODE_MULTI_TREE */ + /** * ofnode_to_np() - convert an ofnode to a live DT node pointer * @@ -88,30 +140,11 @@ static inline struct device_node *ofnode_to_np(ofnode node) return node.np; }
-/** - * noffset_to_ofnode() - convert a DT offset to an ofnode - * - * @other_node: Node in the same tree to use as a reference - * @of_offset: DT offset (either valid, or -1) - * Return: reference to the associated DT offset - */ -static inline ofnode noffset_to_ofnode(ofnode other_node, int of_offset) -{ - ofnode node; - - if (of_live_active()) - node.np = NULL; - else - node.of_offset = of_offset; - - return node; -} - /** * ofnode_valid() - check if an ofnode is valid * * @node: Reference containing offset (possibly invalid) - * Return: true if the reference contains a valid ofnode, false if it is NULL + * Return: true if the reference contains a valid ofnode, false if not */ static inline bool ofnode_valid(ofnode node) { @@ -316,22 +349,6 @@ static inline oftree oftree_from_np(struct device_node *root) return tree; }
-/** - * oftree_from_fdt() - Returns an oftree from a flat device tree pointer - * - * @fdt: Device tree to use - * - * Returns: reference to the given node - */ -static inline oftree oftree_from_fdt(void *fdt) -{ - oftree tree; - - tree.fdt = fdt; - - return tree; -} - /** * ofnode_name_eq() - Check if the node name is equivalent to a given name * ignoring the unit address

We need to be able to look up phandles in any FDT, not just the control FDT. Use the 'other' FDT to test this, with a helper function which gets this as an oftree that can then we used as needed.
Add a few more tests and some comments at the top of the file, to explain what is going on.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
drivers/core/ofnode.c | 4 +-- include/test/ut.h | 5 +++ test/dm/ofnode.c | 80 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 2 deletions(-)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 7b0a993d305..1f477322d5d 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -533,9 +533,9 @@ ofnode oftree_get_by_phandle(oftree tree, uint phandle) if (of_live_active()) node = np_to_ofnode(of_find_node_by_phandle(tree.np, phandle)); else - node.of_offset = + node = ofnode_from_tree_offset(tree, fdt_node_offset_by_phandle(oftree_lookup_fdt(tree), - phandle); + phandle));
return node; } diff --git a/include/test/ut.h b/include/test/ut.h index 18740f5807c..f8b6a6a68a9 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -119,6 +119,11 @@ int ut_check_console_end(struct unit_test_state *uts); */ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
+/* Report a failure, with printf() string */ +#define ut_reportf(fmt, args...) \ + ut_failf(uts, __FILE__, __LINE__, __func__, "report", \ + fmt, ##args) + /* Assert that a condition is non-zero */ #define ut_assert(cond) \ if (!(cond)) { \ diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index b73ab988287..134a307f1b2 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -1,4 +1,20 @@ // SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2022 Google LLC + * + * There are two types of tests in this file: + * - normal ones which act on the control FDT (gd->fdt_blob or gd->of_root) + * - 'other' ones which act on the 'other' FDT (other.dts) + * + * The 'other' ones have an _ot suffix. + * + * The latter are used to check behaviour with multiple device trees, + * particularly with flat tree, where a tree ID is included in ofnode as part of + * the node offset. These tests are typically just for making sure that the + * offset makes it to libfdt correctly and that the resulting return value is + * correctly turned into an ofnode. The 'other' tests do not fully check the + * behaviour of each ofnode function, since that is done by the normal ones. + */
#include <common.h> #include <dm.h> @@ -13,6 +29,28 @@ #include <test/test.h> #include <test/ut.h>
+/** + * get_other_oftree() - Convert a flat tree into an oftree object + * + * @uts: Test state + * @return: oftree object for the 'other' FDT (see sandbox' other.dts) + */ +oftree get_other_oftree(struct unit_test_state *uts) +{ + oftree tree; + + if (of_live_active()) + tree = oftree_from_np(uts->of_other); + else + tree = oftree_from_fdt(uts->other_fdt); + + /* An invalid tree may cause failure or crashes */ + if (!oftree_valid(tree)) + ut_reportf("test needs the UT_TESTF_OTHER_FDT flag"); + + return tree; +} + static int dm_test_ofnode_compatible(struct unit_test_state *uts) { ofnode root_node = ofnode_path("/"); @@ -42,6 +80,20 @@ static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_get_by_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+static int dm_test_ofnode_get_by_phandle_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode node; + + ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1))); + node = oftree_get_by_phandle(otree, 1); + ut_assert(ofnode_valid(node)); + ut_asserteq_str("target", ofnode_get_name(node)); + + return 0; +} +DM_TEST(dm_test_ofnode_get_by_phandle_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts) { const char propname[] = "compatible"; @@ -185,6 +237,34 @@ static int dm_test_ofnode_phandle(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+static int dm_test_ofnode_phandle_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + struct ofnode_phandle_args args; + ofnode node; + int ret; + + node = oftree_path(otree, "/node"); + + /* Test ofnode_count_phandle_with_args with cell name */ + ret = ofnode_count_phandle_with_args(node, "missing", "#gpio-cells", 0); + ut_asserteq(-ENOENT, ret); + ret = ofnode_count_phandle_with_args(node, "target", "#invalid", 0); + ut_asserteq(-EINVAL, ret); + ret = ofnode_count_phandle_with_args(node, "target", "#gpio-cells", 0); + ut_asserteq(1, ret); + + ret = ofnode_parse_phandle_with_args(node, "target", "#gpio-cells", 0, + 0, &args); + ut_assertok(ret); + ut_asserteq(2, args.args_count); + ut_asserteq(3, args.args[0]); + ut_asserteq(4, args.args[1]); + + return 0; +} +DM_TEST(dm_test_ofnode_phandle_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_read_chosen(struct unit_test_state *uts) { const char *str;

Some ofnode functions can only operate on the default device tree, i.e. U-Boot's control FDT. Add comments to that effect. Fix up the reference to device tree bindings while we are here.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
include/dm/ofnode.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 8e383c26d44..113dd15afe3 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -868,6 +868,8 @@ const void *ofnode_read_chosen_prop(const char *propname, int *sizep); * This looks for a property within the /chosen node and returns its value, * checking that it is a valid nul-terminated string * + * This only works with the control FDT. + * * @propname: Property name to look for * Return: string value if found, else NULL */ @@ -879,6 +881,8 @@ const char *ofnode_read_chosen_string(const char *propname); * This looks up a named property in the chosen node and uses that as a path to * look up a code. * + * This only works with the control FDT. + * * @propname: Property name to look for * Return: the referenced node if present, else ofnode_null() */ @@ -889,6 +893,8 @@ ofnode ofnode_get_chosen_node(const char *propname); * * This looks for a property within the /aliases node and returns its value * + * This only works with the control FDT. + * * @propname: Property name to look for * @sizep: Returns size of property, or `FDT_ERR_...` error code if function * returns NULL @@ -902,6 +908,8 @@ const void *ofnode_read_aliases_prop(const char *propname, int *sizep); * This looks up a named property in the aliases node and uses that as a path to * look up a code. * + * This only works with the control FDT. + * * @propname: Property name to look for * Return: the referenced node if present, else ofnode_null() */ @@ -1387,7 +1395,9 @@ phy_interface_t ofnode_read_phy_mode(ofnode mac_node); * * This reads a property from the /config node of the devicetree. * - * See doc/config.txt for bindings + * This only works with the control FDT. + * + * See doc/device-tree-bindings/config.txt for bindings * * @prop_name: property name to look up * Return: true, if it exists, false if not @@ -1399,7 +1409,7 @@ bool ofnode_conf_read_bool(const char *prop_name); * * This reads a property from the /config node of the devicetree. * - * See doc/config.txt for bindings + * See doc/device-tree-bindings/config.txt for bindings * * @prop_name: property name to look up * @default_val: default value to return if the property is not found @@ -1412,7 +1422,9 @@ int ofnode_conf_read_int(const char *prop_name, int default_val); * * This reads a property from the /config node of the devicetree. * - * See doc/config.txt for bindings + * This only works with the control FDT. + * + * See doc/device-tree-bindings/config.txt for bindings * * @prop_name: property name to look up * Return: string value, if found, or NULL if not

Move this logic out of the test into separate functions, so we can use it in other tests.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
test/dm/ofnode.c | 57 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 8 deletions(-)
diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 134a307f1b2..be5e3155e32 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -51,6 +51,46 @@ oftree get_other_oftree(struct unit_test_state *uts) return tree; }
+/** + * get_oftree() - Convert a flat tree into an oftree object + * + * @uts: Test state + * @fdt: Pointer to flat tree + * @treep: Returns the tree, on success + * Return: 0 if OK, 1 if the tree failed to unflatten, -EOVERFLOW if there are + * too many flat trees to allow another one to be registers (see + * oftree_ensure()) + */ +int get_oftree(struct unit_test_state *uts, void *fdt, oftree *treep) +{ + oftree tree; + + if (of_live_active()) { + struct device_node *root; + + ut_assertok(unflatten_device_tree(fdt, &root)); + tree = oftree_from_np(root); + } else { + tree = oftree_from_fdt(fdt); + if (!oftree_valid(tree)) + return -EOVERFLOW; + } + *treep = tree; + + return 0; +} + +/** + * free_oftree() - Free memory used by get_oftree() + * + * @tree: Tree to free + */ +void free_oftree(oftree tree) +{ + if (of_live_active()) + free(tree.np); +} + static int dm_test_ofnode_compatible(struct unit_test_state *uts) { ofnode root_node = ofnode_path("/"); @@ -590,10 +630,10 @@ static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size)
static int dm_test_ofnode_root(struct unit_test_state *uts) { - struct device_node *root = NULL; char fdt[256]; oftree tree; ofnode node; + int ret;
/* Check that aliases work on the control FDT */ node = ofnode_get_aliases_node("ethernet3"); @@ -603,12 +643,13 @@ static int dm_test_ofnode_root(struct unit_test_state *uts) ut_assert(!oftree_valid(oftree_null()));
ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt))); - if (of_live_active()) { - ut_assertok(unflatten_device_tree(fdt, &root)); - tree = oftree_from_np(root); - } else { - tree = oftree_from_fdt(fdt); - } + ret = get_oftree(uts, fdt, &tree); + + /* skip the rest of this test if multiple FDTs are not supported */ + if (ret == -EOVERFLOW) + return 0; + + ut_assertok(ret); ut_assert(oftree_valid(tree));
/* Make sure they don't work on this new tree */ @@ -623,7 +664,7 @@ static int dm_test_ofnode_root(struct unit_test_state *uts) node = oftree_path(oftree_default(), "/new-mmc"); ut_assert(!ofnode_valid(node));
- free(root); + free_oftree(tree);
return 0; }

The current tests do not cover all functions, nor do they cover the new multi-tree functionality. Add and update the tests accordingly and update the 'future work' notes in the documentation.
There is a still more testing needed for the failure cases, since at present some ofnode functions return a libfdt error code instead of converting it to an errno.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
doc/develop/driver-model/livetree.rst | 7 +- test/dm/ofnode.c | 229 ++++++++++++++++++++++++-- 2 files changed, 214 insertions(+), 22 deletions(-)
diff --git a/doc/develop/driver-model/livetree.rst b/doc/develop/driver-model/livetree.rst index 76be89b9633..65b88f854eb 100644 --- a/doc/develop/driver-model/livetree.rst +++ b/doc/develop/driver-model/livetree.rst @@ -321,10 +321,7 @@ Adding a new function for device-tree access involves the following steps: Future work -----------
-Live tree support was introduced in U-Boot 2017.07. There is still quite a bit -of work to do to flesh this out: +Live tree support was introduced in U-Boot 2017.07. Some possible enhancements +are:
-- tests for all access functions -- more support for livetree modification -- addition of more access functions as needed - support for livetree in SPL and before relocation (if desired) diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index be5e3155e32..0912a53099d 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -100,7 +100,21 @@ static int dm_test_ofnode_compatible(struct unit_test_state *uts)
return 0; } -DM_TEST(dm_test_ofnode_compatible, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +DM_TEST(dm_test_ofnode_compatible, + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +/* check ofnode_device_is_compatible() with the 'other' FDT */ +static int dm_test_ofnode_compatible_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode oroot = oftree_root(otree); + + ut_assert(ofnode_valid(oroot)); + ut_assert(ofnode_device_is_compatible(oroot, "sandbox-other")); + + return 0; +} +DM_TEST(dm_test_ofnode_compatible_ot, UT_TESTF_OTHER_FDT);
static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts) { @@ -134,33 +148,56 @@ static int dm_test_ofnode_get_by_phandle_ot(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_get_by_phandle_ot, UT_TESTF_OTHER_FDT);
-static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts) +static int check_prop_values(struct unit_test_state *uts, ofnode start, + const char *propname, const char *propval, + int expect_count) { - const char propname[] = "compatible"; - const char propval[] = "denx,u-boot-fdt-test"; + int proplen = strlen(propval) + 1; const char *str; - ofnode node = ofnode_null(); + ofnode node; + int count;
/* Find first matching node, there should be at least one */ - node = ofnode_by_prop_value(node, propname, propval, sizeof(propval)); + node = ofnode_by_prop_value(start, propname, propval, proplen); ut_assert(ofnode_valid(node)); str = ofnode_read_string(node, propname); ut_assert(str && !strcmp(str, propval));
/* Find the rest of the matching nodes */ + count = 1; while (true) { - node = ofnode_by_prop_value(node, propname, propval, - sizeof(propval)); + node = ofnode_by_prop_value(node, propname, propval, proplen); if (!ofnode_valid(node)) break; str = ofnode_read_string(node, propname); - ut_assert(str && !strcmp(str, propval)); + ut_asserteq_str(propval, str); + count++; } + ut_asserteq(expect_count, count); + + return 0; +} + +static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts) +{ + ut_assertok(check_prop_values(uts, ofnode_null(), "compatible", + "denx,u-boot-fdt-test", 11));
return 0; } DM_TEST(dm_test_ofnode_by_prop_value, UT_TESTF_SCAN_FDT);
+static int dm_test_ofnode_by_prop_value_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + + ut_assertok(check_prop_values(uts, oftree_root(otree), "str-prop", + "other", 2)); + + return 0; +} +DM_TEST(dm_test_ofnode_by_prop_value_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_fmap(struct unit_test_state *uts) { struct fmap_entry entry; @@ -202,6 +239,25 @@ static int dm_test_ofnode_read(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_read, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+static int dm_test_ofnode_read_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + const char *val; + ofnode node; + int size; + + node = oftree_path(otree, "/node/subnode"); + ut_assert(ofnode_valid(node)); + + val = ofnode_read_prop(node, "str-prop", &size); + ut_assertnonnull(val); + ut_asserteq_str("other", val); + ut_asserteq(6, size); + + return 0; +} +DM_TEST(dm_test_ofnode_read_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_phandle(struct unit_test_state *uts) { struct ofnode_phandle_args args; @@ -377,6 +433,27 @@ static int dm_test_ofnode_get_child_count(struct unit_test_state *uts) DM_TEST(dm_test_ofnode_get_child_count, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+static int dm_test_ofnode_get_child_count_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode node, child_node; + u32 val; + + node = oftree_path(otree, "/node"); + ut_assert(ofnode_valid(node)); + + val = ofnode_get_child_count(node); + ut_asserteq(2, val); + + child_node = ofnode_first_subnode(node); + ut_assert(ofnode_valid(child_node)); + val = ofnode_get_child_count(child_node); + ut_asserteq(0, val); + + return 0; +} +DM_TEST(dm_test_ofnode_get_child_count_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_is_enabled(struct unit_test_state *uts) { ofnode root_node = ofnode_path("/"); @@ -389,6 +466,19 @@ static int dm_test_ofnode_is_enabled(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_is_enabled, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+static int dm_test_ofnode_is_enabled_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode root_node = oftree_root(otree); + ofnode node = oftree_path(otree, "/target"); + + ut_assert(ofnode_is_enabled(root_node)); + ut_assert(!ofnode_is_enabled(node)); + + return 0; +} +DM_TEST(dm_test_ofnode_is_enabled_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_get_reg(struct unit_test_state *uts) { ofnode node; @@ -425,30 +515,59 @@ static int dm_test_ofnode_get_reg(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_get_reg, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+static int dm_test_ofnode_get_reg_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode node = oftree_path(otree, "/target"); + fdt_addr_t addr; + + addr = ofnode_get_addr(node); + ut_asserteq(0x8000, addr); + + return 0; +} +DM_TEST(dm_test_ofnode_get_reg_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_get_path(struct unit_test_state *uts) { const char *path = "/translation-test@8000/noxlatebus@3,300/dev@42"; char buf[64]; ofnode node; - int res;
node = ofnode_path(path); ut_assert(ofnode_valid(node));
- res = ofnode_get_path(node, buf, 64); - ut_asserteq(0, res); + ut_assertok(ofnode_get_path(node, buf, sizeof(buf))); ut_asserteq_str(path, buf);
- res = ofnode_get_path(node, buf, 32); - ut_asserteq(-ENOSPC, res); + ut_asserteq(-ENOSPC, ofnode_get_path(node, buf, 32));
- res = ofnode_get_path(ofnode_root(), buf, 32); + ut_assertok(ofnode_get_path(ofnode_root(), buf, 32)); ut_asserteq_str("/", buf);
return 0; } DM_TEST(dm_test_ofnode_get_path, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+static int dm_test_ofnode_get_path_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + const char *path = "/node/subnode"; + ofnode node = oftree_path(otree, path); + char buf[64]; + + ut_assert(ofnode_valid(node)); + + ut_assertok(ofnode_get_path(node, buf, sizeof(buf))); + ut_asserteq_str(path, buf); + + ut_assertok(ofnode_get_path(oftree_root(otree), buf, 32)); + ut_asserteq_str("/", buf); + + return 0; +} +DM_TEST(dm_test_ofnode_get_path_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_conf(struct unit_test_state *uts) { ut_assert(!ofnode_conf_read_bool("missing")); @@ -608,13 +727,17 @@ DM_TEST(dm_test_ofnode_get_phy, 0); * @uts: Test state * @fdt: Place to write FDT * @size: Maximum size of space for fdt + * @id: id value to add to the tree ('id' property in root node) */ -static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size) +static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size, + int id) { ut_assertok(fdt_create(fdt, size)); ut_assertok(fdt_finish_reservemap(fdt)); ut_assert(fdt_begin_node(fdt, "") >= 0);
+ ut_assertok(fdt_property_u32(fdt, "id", id)); + ut_assert(fdt_begin_node(fdt, "aliases") >= 0); ut_assertok(fdt_property_string(fdt, "mmc0", "/new-mmc")); ut_assertok(fdt_end_node(fdt)); @@ -642,7 +765,7 @@ static int dm_test_ofnode_root(struct unit_test_state *uts)
ut_assert(!oftree_valid(oftree_null()));
- ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt))); + ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt), 0)); ret = get_oftree(uts, fdt, &tree);
/* skip the rest of this test if multiple FDTs are not supported */ @@ -892,6 +1015,23 @@ static int dm_test_ofnode_by_compatible(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_by_compatible, UT_TESTF_SCAN_FDT);
+static int dm_test_ofnode_by_compatible_ot(struct unit_test_state *uts) +{ + const char *compat = "sandbox-other2"; + oftree otree = get_other_oftree(uts); + ofnode node; + int count; + + count = 0; + for (node = oftree_root(otree); + node = ofnode_by_compatible(node, compat), ofnode_valid(node);) + count++; + ut_asserteq(2, count); + + return 0; +} +DM_TEST(dm_test_ofnode_by_compatible_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_find_subnode(struct unit_test_state *uts) { ofnode node, subnode; @@ -909,6 +1049,24 @@ static int dm_test_ofnode_find_subnode(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_find_subnode, UT_TESTF_SCAN_FDT);
+static int dm_test_ofnode_find_subnode_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode node, subnode; + + node = oftree_path(otree, "/node"); + + subnode = ofnode_find_subnode(node, "subnode"); + ut_assert(ofnode_valid(subnode)); + ut_asserteq_str("subnode", ofnode_get_name(subnode)); + + subnode = ofnode_find_subnode(node, "btn"); + ut_assert(!ofnode_valid(subnode)); + + return 0; +} +DM_TEST(dm_test_ofnode_find_subnode_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_get_name(struct unit_test_state *uts) { ofnode node; @@ -921,3 +1079,40 @@ static int dm_test_ofnode_get_name(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_ofnode_get_name, UT_TESTF_SCAN_FDT); + +/* try to access more FDTs than is supported */ +static int dm_test_ofnode_too_many(struct unit_test_state *uts) +{ + const int max_trees = CONFIG_IS_ENABLED(OFNODE_MULTI_TREE, + (CONFIG_OFNODE_MULTI_TREE_MAX), (1)); + const int fdt_size = 256; + const int num_trees = max_trees + 1; + char fdt[num_trees][fdt_size]; + int i; + + for (i = 0; i < num_trees; i++) { + oftree tree; + int ret; + + ut_assertok(make_ofnode_fdt(uts, fdt[i], fdt_size, i)); + ret = get_oftree(uts, fdt[i], &tree); + + /* + * With flat tree we have the control FDT using one slot. Live + * tree has no limit since it uses pointers, not integer tree + * IDs + */ + if (of_live_active() || i < max_trees - 1) { + ut_assertok(ret); + } else { + /* + * tree should be invalid when we try to register too + * many trees + */ + ut_asserteq(-EOVERFLOW, ret); + } + } + + return 0; +} +DM_TEST(dm_test_ofnode_too_many, UT_TESTF_SCAN_FDT);

This test can operate in all conditions now. Update the test and comments.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
test/boot/vbe_simple.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/test/boot/vbe_simple.c b/test/boot/vbe_simple.c index 3f03fc3acd2..8acd777f4cd 100644 --- a/test/boot/vbe_simple.c +++ b/test/boot/vbe_simple.c @@ -74,26 +74,22 @@ static int vbe_simple_test_base(struct unit_test_state *uts) node_ofs = fdt_add_subnode(fdt_buf, node_ofs, "firmware0"); ut_assert(node_ofs > 0);
- /* - * This can only work on the live tree, since the ofnode interface for - * flat tree assumes that ofnode points to the control FDT - */ - ut_assertok(unflatten_device_tree(fdt_buf, &np)); + if (of_live_active()) { + ut_assertok(unflatten_device_tree(fdt_buf, &np)); + fixup.tree = oftree_from_np(np); + } else { + fixup.tree = oftree_from_fdt(fdt_buf); + }
/* * It would be better to call image_setup_libfdt() here, but that * function does not allow passing an ofnode. We can pass fdt_buf but - * when it comes to send the evenr, it creates an ofnode that uses the + * when it comes to send the event, it creates an ofnode that uses the * control FDT, since it has no way of accessing the live tree created * here. * - * Two fix this we need: - * - image_setup_libfdt() is updated to use ofnode - * - ofnode updated to support access to an FDT other than the control - * FDT. This is partially implemented with live tree, but not with - * flat tree + * Two fix this we need image_setup_libfdt() is updated to use ofnode */ - fixup.tree.np = np; ut_assertok(event_notify(EVT_FT_FIXUP, &fixup, sizeof(fixup)));
node = oftree_path(fixup.tree, "/chosen/fwupd/firmware0"); @@ -111,5 +107,4 @@ static int vbe_simple_test_base(struct unit_test_state *uts)
return 0; } -BOOTSTD_TEST(vbe_simple_test_base, UT_TESTF_DM | UT_TESTF_SCAN_FDT | - UT_TESTF_LIVE_TREE); +BOOTSTD_TEST(vbe_simple_test_base, UT_TESTF_DM | UT_TESTF_SCAN_FDT);

At present ofnode_write_prop() is inconsistent between livetree and flattree, in that livetree requires the caller to ensure the property value is stable (e.g. in rodata or allocated) but flattree does not, since it makes a copy.
This makes the API call a bit painful to use, since the caller must do different things depending on OF_LIVE.
Add a new 'copy' argument which tells the function to make a copy if needed. Add some tests to cover this behaviour.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
doc/develop/driver-model/livetree.rst | 2 + drivers/core/ofnode.c | 29 +++++++++---- include/dm/ofnode.h | 12 ++++-- test/dm/ofnode.c | 62 ++++++++++++++++++++++++++- 4 files changed, 92 insertions(+), 13 deletions(-)
diff --git a/doc/develop/driver-model/livetree.rst b/doc/develop/driver-model/livetree.rst index 65b88f854eb..55aa3eac929 100644 --- a/doc/develop/driver-model/livetree.rst +++ b/doc/develop/driver-model/livetree.rst @@ -325,3 +325,5 @@ Live tree support was introduced in U-Boot 2017.07. Some possible enhancements are:
- support for livetree in SPL and before relocation (if desired) +- freeing leaked memory caused by writing new nodes / property values to the + livetree (ofnode_write_prop()) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 1f477322d5d..51a16537b0d 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -1322,15 +1322,27 @@ ofnode ofnode_by_prop_value(ofnode from, const char *propname, }
int ofnode_write_prop(ofnode node, const char *propname, const void *value, - int len) + int len, bool copy) { - if (of_live_active()) - return of_write_prop(ofnode_to_np(node), propname, len, value); - else + if (of_live_active()) { + void *newval; + int ret; + + if (copy) { + newval = malloc(len); + if (!newval) + return log_ret(-ENOMEM); + memcpy(newval, value, len); + value = newval; + } + ret = of_write_prop(ofnode_to_np(node), propname, len, value); + if (ret && copy) + free(newval); + return ret; + } else { return fdt_setprop(ofnode_to_fdt(node), ofnode_to_offset(node), propname, value, len); - - return 0; + } }
int ofnode_write_string(ofnode node, const char *propname, const char *value) @@ -1339,7 +1351,8 @@ int ofnode_write_string(ofnode node, const char *propname, const char *value)
debug("%s: %s = %s", __func__, propname, value);
- return ofnode_write_prop(node, propname, value, strlen(value) + 1); + return ofnode_write_prop(node, propname, value, strlen(value) + 1, + false); }
int ofnode_write_u32(ofnode node, const char *propname, u32 value) @@ -1354,7 +1367,7 @@ int ofnode_write_u32(ofnode node, const char *propname, u32 value) return -ENOMEM; *val = cpu_to_fdt32(value);
- return ofnode_write_prop(node, propname, val, sizeof(value)); + return ofnode_write_prop(node, propname, val, sizeof(value), false); }
int ofnode_set_enabled(ofnode node, bool value) diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 113dd15afe3..c7d61e94121 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -1310,19 +1310,23 @@ int ofnode_device_is_compatible(ofnode node, const char *compat); /** * ofnode_write_prop() - Set a property of a ofnode * - * Note that the value passed to the function is *not* allocated by the - * function itself, but must be allocated by the caller if necessary. However - * it does allocate memory for the property struct and name. + * Note that if @copy is false, the value passed to the function is *not* + * allocated by the function itself, but must be allocated by the caller if + * necessary. However it does allocate memory for the property struct and name. * * @node: The node for whose property should be set * @propname: The name of the property to set * @value: The new value of the property (must be valid prior to calling * the function) * @len: The length of the new value of the property + * @copy: true to allocate memory for the value. This only has any effect with + * live tree, since flat tree handles this automatically. It allows a + * node's value to be written to the tree, without requiring that the + * caller allocate it * Return: 0 if successful, -ve on error */ int ofnode_write_prop(ofnode node, const char *propname, const void *value, - int len); + int len, bool copy);
/** * ofnode_write_string() - Set a string property of a ofnode diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 0912a53099d..69ffba06534 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -822,7 +822,8 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr(dev)); /* reg = 0x42, size = 0x100 */ ut_assertok(ofnode_write_prop(node, "reg", - "\x00\x00\x00\x42\x00\x00\x01\x00", 8)); + "\x00\x00\x00\x42\x00\x00\x01\x00", 8, + false)); ut_asserteq(0x42, dev_read_addr(dev));
/* Test disabling devices */ @@ -838,6 +839,65 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) DM_TEST(dm_test_ofnode_livetree_writing, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+static int check_write_prop(struct unit_test_state *uts, ofnode node) +{ + char prop[] = "middle-name"; + char name[10]; + int len; + + strcpy(name, "cecil"); + len = strlen(name) + 1; + ut_assertok(ofnode_write_prop(node, prop, name, len, false)); + ut_asserteq_str(name, ofnode_read_string(node, prop)); + + /* change the underlying value, this should mess up the live tree */ + strcpy(name, "tony"); + if (of_live_active()) { + ut_asserteq_str(name, ofnode_read_string(node, prop)); + } else { + ut_asserteq_str("cecil", ofnode_read_string(node, prop)); + } + + /* try again, this time copying the property */ + strcpy(name, "mary"); + ut_assertok(ofnode_write_prop(node, prop, name, len, true)); + ut_asserteq_str(name, ofnode_read_string(node, prop)); + strcpy(name, "leah"); + + /* both flattree and livetree behave the same */ + ut_asserteq_str("mary", ofnode_read_string(node, prop)); + + return 0; +} + +/* writing the tree with and without copying the property */ +static int dm_test_ofnode_write_copy(struct unit_test_state *uts) +{ + ofnode node; + + node = ofnode_path("/a-test"); + ut_assertok(check_write_prop(uts, node)); + + return 0; +} +DM_TEST(dm_test_ofnode_write_copy, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_write_copy_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode node, check_node; + + node = oftree_path(otree, "/node"); + ut_assertok(check_write_prop(uts, node)); + + /* make sure the control FDT is not touched */ + check_node = ofnode_path("/node"); + ut_assertnull(ofnode_read_string(check_node, "middle-name")); + + return 0; +} +DM_TEST(dm_test_ofnode_write_copy_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_u32(struct unit_test_state *uts) { ofnode node;

Add a function to copy properties from one node to another.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Substantially expanded to improve the ofnode implementation/interface - Added more ofnode tests - Minor reworks of the ofnode internals, using oftree - Added testing of memory-allocation failures
drivers/core/ofnode.c | 24 ++++++++++++++++++ include/dm/ofnode.h | 16 ++++++++++++ test/dm/ofnode.c | 59 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+)
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 51a16537b0d..6bdab6886b6 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -1491,3 +1491,27 @@ int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep)
return ret; /* 0 or -EEXIST */ } + +int ofnode_copy_props(ofnode src, ofnode dst) +{ + struct ofprop prop; + + ofnode_for_each_prop(prop, src) { + const char *name; + const char *val; + int len, ret; + + val = ofprop_get_property(&prop, &name, &len); + if (!val) { + log_debug("Cannot read prop (err=%d)\n", len); + return log_msg_ret("get", -EINVAL); + } + ret = ofnode_write_prop(dst, name, val, len, true); + if (ret) { + log_debug("Cannot write prop (err=%d)\n", ret); + return log_msg_ret("wr", -EINVAL); + } + } + + return 0; +} diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index c7d61e94121..5ff6dd8089d 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -1465,4 +1465,20 @@ static inline const char *ofnode_conf_read_str(const char *prop_name) */ int ofnode_add_subnode(ofnode parent, const char *name, ofnode *nodep);
+/** + * ofnode_copy_props() - copy all properties from one node to another + * + * Makes a copy of all properties from the source note in the destination node. + * Existing properties in the destination node remain unchanged, except that + * any with the same name are overwritten, including changing the size of the + * property. + * + * For livetree, properties are copied / allocated, so the source tree does not + * need to be present afterwards. + * + * @src: Source node to read properties from + * @dst: Destination node to write properties too + */ +int ofnode_copy_props(ofnode src, ofnode dst); + #endif diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 69ffba06534..41811ec3bb5 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -1176,3 +1176,62 @@ static int dm_test_ofnode_too_many(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_ofnode_too_many, UT_TESTF_SCAN_FDT); + +static int check_copy_props(struct unit_test_state *uts, ofnode src, + ofnode dst) +{ + u32 reg[2], val; + + ut_assertok(ofnode_copy_props(src, dst)); + + ut_assertok(ofnode_read_u32(dst, "ping-expect", &val)); + ut_asserteq(3, val); + + ut_asserteq_str("denx,u-boot-fdt-test", + ofnode_read_string(dst, "compatible")); + + /* check that a property with the same name is overwritten */ + ut_assertok(ofnode_read_u32_array(dst, "reg", reg, ARRAY_SIZE(reg))); + ut_asserteq(3, reg[0]); + ut_asserteq(1, reg[1]); + + /* reset the compatible so the live tree does not change */ + ut_assertok(ofnode_write_string(dst, "compatible", "nothing")); + + return 0; +} + +static int dm_test_ofnode_copy_props(struct unit_test_state *uts) +{ + ofnode src, dst; + + /* + * These nodes are chosen so that the src node is before the destination + * node in the tree. This doesn't matter with livetree, but with + * flattree any attempt to insert a property earlier in the tree will + * mess up the offsets after it. + */ + src = ofnode_path("/b-test"); + dst = ofnode_path("/some-bus"); + + ut_assertok(check_copy_props(uts, src, dst)); + + /* check a property that is in the destination already */ + ut_asserteq_str("mux0", ofnode_read_string(dst, "mux-control-names")); + + return 0; +} +DM_TEST(dm_test_ofnode_copy_props, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_copy_props_ot(struct unit_test_state *uts) +{ + ofnode src, dst; + oftree otree = get_other_oftree(uts); + + src = ofnode_path("/b-test"); + dst = oftree_path(otree, "/node/subnode2"); + ut_assertok(check_copy_props(uts, src, dst)); + + return 0; +} +DM_TEST(dm_test_ofnode_copy_props_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
participants (4)
-
Jaehoon Chung
-
Sean Anderson
-
Simon Glass
-
Tom Rini