summaryrefslogtreecommitdiff
path: root/common/spl/spl.c
AgeCommit message (Collapse)Author
4 daysspl: Remove unused CONFIG_SPL_FRAMEWORK_BOARD_INIT_F optionTom Rini
The option CONFIG_SPL_FRAMEWORK_BOARD_INIT_F enables a simple board_init_f function in SPL. This however is never enabled, so remove this function and option. Signed-off-by: Tom Rini <[email protected]>
2026-02-20spl: fix stack placement in spl_relocate_stack_gd()Ronald Wahl
Currently when CONFIG_SPL_STACK_R and CONFIG_SPL_SYS_MALLOC_SIMPLE is enabled then spl_relocate_stack_gd() will setup a layout where the stack lays inside the heap and grows down to heap start. Also the global data is part of the heap. This can lead to corruption of stack and global data. The current layout is: 0x0 +-------------+ . . . . gd->malloc_base +- - - - - - -+ | |\ | HEAP/STACK | \ | | } SPL_STACK_R_MALLOC_SIMPLE_LEN gd->start_addr_sp +- - - - - - -+ / (gd->malloc_limit) | GLOBAL DATA |/ CONFIG_SPL_STACK_R_ADDR +-------------+ The above broken layout was actually introduced with commit adc421e4cee8 ("arm: move gd handling outside of C code"). This commit changes the layout so that the stack is below the heap and the global data. It is now similar to the one before relocation: 0x0+-------------+ . . . . +- - - - - - -+ | | | STACK | | | gd->start_addr_sp +-------------+ | GLOBAL DATA | gd->malloc_base +-------------+ | |\ | HEAP | } SPL_STACK_R_MALLOC_SIMPLE_LEN | |/ (gd->malloc_limit) CONFIG_SPL_STACK_R_ADDR +-------------+ Fixes: adc421e4cee8 ("arm: move gd handling outside of C code") Cc: Tom Rini <[email protected]> Cc: Anshul Dalal <[email protected]> Cc: Leo Yu-Chi Liang <[email protected]> Cc: Dhruva Gole <[email protected]> Cc: Simon Glass <[email protected]> Cc: Albert ARIBAUD <[email protected]> Signed-off-by: Ronald Wahl <[email protected]>
2025-11-06spl: remove redundant prints in boot_from_devicesAnshul Dalal
The null check for loader in boot_from_devices was moved earlier in the code path by the commit ae409a84e7bff ("spl: NULL check variable before dereference"), therefore the subsequent null checks for loader are not necessary. This patch removes those checks and refactors the prints to be more useful in case of errors. Signed-off-by: Anshul Dalal <[email protected]>
2025-11-03spl: remove usage of CMD_BOOTx from image parsingAnshul Dalal
Using CMD_* configs from spl doesn't make logical sense. Therefore this patch replaces the checks for CMD_BOOTx with newly added library symbols LIB_BOOT[IMZ] and SPL_LIB_BOOT[IMZ] which are enabled by their respective CMD_* or SPL_* counterparts. On platforms with non-secure falcon mode, SPL_BOOTZ is enabled by default for 32-bit ARM systems and SPL_BOOTI is enabled by default for 64-bit ARM and RISCV. The respective C files (image.c/zimage.c) are compiled based on library symbols $(PHASE_)LIB_BOOTx instead which are in turn selected by both CMD_BOOTx and SPL_BOOTx as required. Signed-off-by: Anshul Dalal <[email protected]> Reviewed-by: Tom Rini <[email protected]>
2025-10-22spl: split spl_board_fixups to arch/board specificAnshul Dalal
The current spl_board_fixups API allows for modification of spl_image before the SPL jumps to it. This can be used to modify the DT for the next boot stage, however the current API only allows either the machine arch or the board to use it. This limits the utility of the API as there might be certain fixups that should be applied to all boards sharing the same machine architecture with others being board specific. For TI's K3 specifically, this prevents us from performing architecture level fixups since a lot of TI boards are already making use of the spl_board_fixups API. Therefore this patch splits the API into two to allow both board and the architecture specific fixups. The order is kept as arch then board to give board specific fixups the precedence. Reviewed-by: Dhruva Gole <[email protected]> Signed-off-by: Anshul Dalal <[email protected]> Tested-by: Wadim Egorov <[email protected]>
2025-10-20spl: set fdt address as spl_image arg in falcon modeAnshul Dalal
The arg field of `struct spl_image_info` is used by jump_to_image_linux as the argument for the kernel in falcon mode. Since commit 601cebc29d2a ("cmd: spl: Remove ATAG support from this command"), fdt is the only valid argument for kernel in falcon mode. However fdt was only being set as the argument in nor and xip boot modes, this patch fixes it for all boot modes and removes the now redundant code from spl_nor and spl_xip. Signed-off-by: Anshul Dalal <[email protected]>
2025-10-20spl: make args file optional in falcon modeAnshul Dalal
Falcon mode loads a kernel file and an args file which is the device-tree. However in the case of kernel file being a FIT that contains the device-tree within it, loading the args file is not required. Therefore, this patch introduces a new SPL_OS_BOOT_ARGS config options that allows us to enable or disable loading of the args file in falcon mode. Signed-off-by: Anshul Dalal <[email protected]>
2025-08-14common: spl: fix compilation warningLeo Yu-Chi Liang
Explicitly specify the type by replacing macro with variable to fix the possible compilation warning. Signed-off-by: Leo Yu-Chi Liang <[email protected]>
2025-07-29spl: NULL check variable before dereferenceAndrew Goodbody
In boot_from_devices the variable loader is not NULL checked after assignment and before first use but later code does check it for NULL. Add a NULL check before first use. This issue was found by Smatch. Signed-off-by: Andrew Goodbody <[email protected]>
2025-06-13spl: Rename jump_to_image_no_args()Simon Glass
This function is currently a misnomer at times as we have cases where it passes arguments to the image. In preparation for making that be a more common case rename this function to jump_to_image(...). In order to do this, rename jump_to_image in board_init_r(...) to jumper so that we do not have a conflict. Signed-off-by: Simon Glass <[email protected]> [trini: Reword the commit message, adding missing cases of jump_to_image_no_args()] Signed-off-by: Tom Rini <[email protected]>
2025-02-03vbe: Provide VPL binman-symbols for the next phaseSimon Glass
Add support for moving from TPL->VPL->SPL so that the VPL build can fit properly into the boot flow. Use #ifdefs to avoid creating unwanted symbols which Binman would then try (and perhaps fail) to provide. Add debugging to indicate the next phase. Signed-off-by: Simon Glass <[email protected]>
2025-01-22Merge patch series "vbe: Series part F"Tom Rini
Simon Glass <[email protected]> says: This includes various patches towards implementing the VBE abrec bootmeth in U-Boot. It mostly focuses on introducing a relocating SPL-loader so that VBE can run in the limited amount of SRAM available on many devices. Another minor new feature is support in VBE for specifying the image phase when loading from a FIT. This allows a single FIT to include images for several boot phases, thus simplifying image-creation. One lingering niggle in this series is that it has a different code path for sandbox, since it does not support the relocating jump. It should be possible to resolve this with additional work, but I have not attempted this so far. For v2, I have split the first patch into 5 pieces, to make it easier to see the code-size impact, plus added a few tweaks to reduce code size. Again, only MMC is supported so far. Looking ahead, series G will have some more plumbing and H some rk3399 pieces. That should be enough to complete these feature. Here is a run in my lab, with the VBE ABrec bootmeth. You can see that VPL runs before memory is set up. SPL sets up memory and can be upgraded in the field reliably. $ ub-int vbe Building U-Boot in sourcedir for rk3399-generic Bootstrapping U-Boot from dir /tmp/b/rk3399-generic Writing U-Boot using method rockchip U-Boot TPL 2025.01-rc3-00345-gdfbdbf1eb56c-dirty (Jan 08 2025 - 10:47:58) Trying to boot from vbe_abrec load: Firefly-RK3399 Board Using 'config-3' configuration Trying 'image-vpl' firmware subimage Using 'config-3' configuration Trying 'fdt-3' fdt subimage U-Boot VPL 2025.01-rc3-00345-gdfbdbf1eb56c-dirty (Jan 08 2025 - 10:47:58) Trying to boot from vbe_abrec load: Firefly-RK3399 Board Starting with empty state VBE: Firmware pick A at 800000 Using 'config-3' configuration Trying 'spl' firmware subimage Using 'config-3' configuration Trying 'fdt-3' fdt subimage Channel 0: DDR3, 800MHz BW=32 Col=10 Bk=8 CS0 Row=15 CS1 Row=15 CS=2 Die BW=16 Size=2048MB Channel 1: DDR3, 800MHz BW=32 Col=10 Bk=8 CS0 Row=15 CS1 Row=15 CS=2 Die BW=16 Size=2048MB 256B stride U-Boot SPL 2025.01-rc3-00345-gdfbdbf1eb56c-dirty (Jan 08 2025 - 10:47:58 -0700) Trying to boot from vbe_abrec load: Firefly-RK3399 Board VBE: Firmware pick A at 900000 load_simple_fit: Skip load 'atf-5': image size is 0! Relocating bloblist ff8eff00 to 100000: done ns16550_serial serial@ff1a0000: pinctrl_select_state_full: uclass_get_device_by_phandle_id: err=-19 U-Boot 2025.01-rc3-00345-gdfbdbf1eb56c-dirty (Jan 08 2025 - 10:47:58 -0700) SoC: Rockchip rk3399 Reset cause: POR Model: Firefly-RK3399 Board DRAM: 4 GiB (effective 3.9 GiB) Core: 314 devices, 33 uclasses, devicetree: separate MMC: mmc@fe310000: 3, mmc@fe320000: 1, mmc@fe330000: 0 Loading Environment from SPIFlash... Invalid bus 0 (err=-19) *** Warning - spi_flash_probe_bus_cs() failed, using default environment In: serial,usbkbd Out: serial,vidconsole Err: serial,vidconsole Model: Firefly-RK3399 Board Net: PMIC: RK808 eth0: ethernet@fe300000 starting USB... Bus usb@fe380000: USB EHCI 1.00 Bus usb@fe3a0000: USB OHCI 1.0 Bus usb@fe3c0000: USB EHCI 1.00 Bus usb@fe3e0000: USB OHCI 1.0 Bus usb@fe900000: Register 2000140 NbrPorts 2 Starting the controller USB XHCI 1.10 scanning bus usb@fe380000 for devices... 1 USB Device(s) found scanning bus usb@fe3a0000 for devices... 1 USB Device(s) found scanning bus usb@fe3c0000 for devices... 2 USB Device(s) found scanning bus usb@fe3e0000 for devices... 1 USB Device(s) found scanning bus usb@fe900000 for devices... 1 USB Device(s) found scanning usb for storage devices... 0 Storage Device(s) found Hit any key to stop autoboot: 0 Link: https://lore.kernel.org/r/[email protected]
2025-01-22spl: Plumb in the relocating loaderSimon Glass
This is fairly easy to use. The SPL loader sets up some fields in the spl_image_info struct and calls spl_reloc_prepare(). When SPL is ready to do the jump it must call spl_reloc_jump() instead of jump_to_image(). Add this logic. Signed-off-by: Simon Glass <[email protected]>
2025-01-22spl: Add a type for the jumper functionSimon Glass
This function will be used by the relocating jumper too, so add a typedef to the header file to avoid mismatches. Signed-off-by: Simon Glass <[email protected]>
2025-01-14common: Move autoprobe out to board initSimon Glass
Rather than doing autoprobe within the driver model code, move it out to the board-init code. This makes it clear that it is a separate step from binding devices. For now this is always done twice, before and after relocation, but we should discuss whether it might be possible to drop the post-relocation probe. For boards with SPL, the autoprobe is still done there as well. Note that with this change, autoprobe happens after the EVT_DM_POST_INIT_R/F events are sent, rather than before. Link: https://lore.kernel.org/u-boot/[email protected]/ Signed-off-by: Simon Glass <[email protected]>
2024-12-27spl: Drop a duplicate variable in boot_from_devices()Simon Glass
The variable 'ret' is defined twice, which is not intended. This may have been a local merge error. Signed-off-by: Simon Glass <[email protected]> Fixes: 2eefeb6d893 ("spl: Report a loader failure")
2024-12-27spl: Support a relocated stack in any XPL phaseSimon Glass
The current check looks only at SPL, but TPL or VPL might have a different setting. Update the condition. Signed-off-by: Simon Glass <[email protected]>
2024-12-27spl: Allow serial to be disabled in any XPL phaseSimon Glass
The current check looks only at SPL, but TPL or VPL might have a different setting. Update the condition. Signed-off-by: Simon Glass <[email protected]>
2024-12-27spl: Report a loader failureSimon Glass
If a loader returns an error code it is silently ignored. Show a message to at least provide some feedback to the user. Signed-off-by: Simon Glass <[email protected]>
2024-12-12Revert "Merge patch series "vbe: Series part E""Tom Rini
This reverts commit 1fdf53ace13f745fe8ad4d2d4e79eed98088d555, reversing changes made to e5aef1bbf11412eebd4c242b46adff5301353c30. I had missed that this caused too much size growth on rcar3_salvator-x. Signed-off-by: Tom Rini <[email protected]>
2024-12-12spl: Drop a duplicate variable in boot_from_devices()Simon Glass
The variable 'ret' is defined twice, which is not intended. This may have been a local merge error. Signed-off-by: Simon Glass <[email protected]> Fixes: 2eefeb6d893 ("spl: Report a loader failure")
2024-12-12spl: Support a relocated stack in any XPL phaseSimon Glass
The current check looks only at SPL, but TPL or VPL might have a different setting. Update the condition. Signed-off-by: Simon Glass <[email protected]>
2024-12-12spl: Allow serial to be disabled in any XPL phaseSimon Glass
The current check looks only at SPL, but TPL or VPL might have a different setting. Update the condition. Signed-off-by: Simon Glass <[email protected]>
2024-12-12spl: Report a loader failureSimon Glass
If a loader returns an error code it is silently ignored. Show a message to at least provide some feedback to the user. Signed-off-by: Simon Glass <[email protected]>
2024-10-25common: Tidy up how malloc() is initedSimon Glass
The call to malloc() is a bit strange. The naming of the arguments suggests that an address is passed, but in fact it is a pointer, at least in the board_init_r() function and SPL equivalent. Update it to work as described. Add a function comment as well. Note that this does adjustment does not extend into the malloc() implementation itself, apart from changing mem_malloc_init(), since there are lots of casts and pointers and integers are used interchangeably. Signed-off-by: Simon Glass <[email protected]> Reviewed-by: Tom Rini <[email protected]> Reviewed-by: Ilias Apalodimas <[email protected]>
2024-10-11spl: Rename SPL_TPL_NAME and SPL_TPL_PROMPTSimon Glass
Rename these to use the word PHASE instead. Signed-off-by: Simon Glass <[email protected]>
2024-10-11xpl: Rename spl_phase_prefix() and spl_phase_name()Simon Glass
Use simpler names for these functions. Signed-off-by: Simon Glass <[email protected]>
2024-10-11xpl: Rename spl_next_phase() and spl_prev_phase()Simon Glass
Rename this to use the xpl prefix. Signed-off-by: Simon Glass <[email protected]>
2024-10-11xpl: Rename spl_phase() to xpl_phase()Simon Glass
Rename this function to indicate that it refers to any xPL phase. Signed-off-by: Simon Glass <[email protected]>
2024-10-11xpl: Rename spl_phase to xpl_phase_tSimon Glass
This name fits better with the new naming scheme, so update it. Signed-off-by: Simon Glass <[email protected]>
2024-10-11xpl: Rename u_boot_first_phase to xpl_is_first_phase()Simon Glass
This is a better name for this function, so update it. Tidy up the function comment to mention VPL. Signed-off-by: Simon Glass <[email protected]>
2024-09-03Merge patch series "Make LMB memory map global and persistent"Tom Rini
Sughosh Ganu <[email protected]> says: This is a follow-up from an earlier RFC series [1] for making the LMB and EFI memory allocations work together. This is a non-rfc version with only the LMB part of the patches, for making the LMB memory map global and persistent. This is part one of a set of patches which aim to have the LMB and EFI memory allocations work together. This requires making the LMB memory map global and persistent, instead of having local, caller specific maps. This is being done keeping in mind the usage of LMB memory by platforms where the same memory region can be used to load multiple different images. What is not allowed is to overwrite memory that has been allocated by the other module, currently the EFI memory module. This is being achieved by introducing a new flag, LMB_NOOVERWRITE, which represents memory which cannot be re-requested once allocated. The data structures (alloced lists) required for maintaining the LMB map are initialised during board init. The LMB module is enabled by default for the main U-Boot image, while it needs to be enabled for SPL. This version also uses a stack implementation, as suggested by Simon Glass to temporarily store the lmb structure instance which is used during normal operation when running lmb tests. This does away with the need to run the lmb tests separately. The tests have been tweaked where needed because of these changes. The second part of the patches, to be sent subsequently, would work on having the EFI allocations work with the LMB API's. [1] - https://lore.kernel.org/u-boot/[email protected]/T/#t Notes: 1) These patches are on next, as the alist patches have been applied to that branch. 2) I have tested the boot on the ST DK2 board, but it would be good to get a T-b/R-b from the ST maintainers. 3) It will be good to test these changes on a PowerPC platform (ideally an 85xx, as I do not have one).
2024-09-03spl: call spl_board_init() at the end of the spl init sequenceSughosh Ganu
The spl_board_init() function on sandbox invokes the unit tests. Invoking the tests should be done once the rest of the system has been initialised. Call the spl_board_init() function at the very end, once the rest of the initilisation functions have been called, including the setting up of the LMB memory map. Signed-off-by: Sughosh Ganu <[email protected]> Reviewed-by: Simon Glass <[email protected]>
2024-09-03lmb: init: initialise the lmb data structures during board initSughosh Ganu
The memory map maintained by the LMB module is now persistent and global. This memory map is being maintained through the alloced list structure which can be extended at runtime -- there is one list for the available memory, and one for the used memory. Allocate and initialise these lists during the board init. Signed-off-by: Sughosh Ganu <[email protected]> Reviewed-by: Simon Glass <[email protected]> Reviewed-by: Ilias Apalodimas <[email protected]>
2024-08-30Merge patch series "Add support for Ethernet Boot on SK-AM62"Tom Rini
Chintan Vankar <[email protected]> says: This series enables Ethernet Boot on SK-AM62 device. This series is based on commit 'f4f845b85926' of origin/next branch of U-Boot. Logs for Ethernet Boot for AM625-SK: https://gist.github.com/chintanv133/464782796a9a60b9f5a49e674c5fc31a
2024-08-30common: spl: spl: Init DRAM size in R5/A53 SPLChintan Vankar
Initialize DRAM size in SPL stage since networking requires DDR to be initialized. Reviewed-by: Dhruva Gole <[email protected]> Reviewed-by: Tom Rini <[email protected]> Signed-off-by: Kishon Vijay Abraham I <[email protected]> Signed-off-by: Chintan Vankar <[email protected]>
2024-08-26global_data: Reduce size of early-malloc varsSimon Glass
The early malloc region is normally quite small and is certainly less than 4GB, so use a 32-bit value for the limit and pointer. Update the comments for clarity while we are here. Signed-off-by: Simon Glass <[email protected]>
2024-08-26global_data: Convert have_console into a flagSimon Glass
We don't need a full word for this boolean value. Convert it into a flag to save space in global_data. Reviewed-by: Alexander Sverdlin <[email protected]> Signed-off-by: Simon Glass <[email protected]>
2024-08-23spl: Remove remaining #ifdef in spl_parse_image_header()Simon Glass
Define spl_set_header_raw_uboot() always so we can drop the last #ifdef in this function. Signed-off-by: Simon Glass <[email protected]> Reviewed-by: Sean Anderson <[email protected]> Reviewed-by: Quentin Schulz <[email protected]>
2024-08-23spl: Remove some #ifdefs in spl_parse_image_header()Simon Glass
This function has a number of unnecessary #ifdefs so remove them. Signed-off-by: Simon Glass <[email protected]> Reviewed-by: Sean Anderson <[email protected]> Reviewed-by: Quentin Schulz <[email protected]>
2024-08-23spl: Correct use of CMD_BOOTI and CMD_BOOTZSimon Glass
These should have a CONFIG_ prefix. Add it. Signed-off-by: Simon Glass <[email protected]> Fixes: 7a0d88076b9 ("Add in the ability to load and boot an uncompr...") Reviewed-by: Sean Anderson <[email protected]> Reviewed-by: Quentin Schulz <[email protected]>
2024-08-09spl: Plumb in the Universal Payload handoffSimon Glass
Specify the FIT and include information about each loaded image, as required by the UPL handoff. Write the UPL handoff into the bloblist before jumping to the next phase. Control this using a runtime flag to avoid conflicting with other handoff mechanisms. Signed-off-by: Simon Glass <[email protected]>
2024-06-17spl: Introduce SoC specific init functionLukas Funke
Some architectures use spl_board_init() in their SoC specific implementation. Board developers should be able to add board specific implementation via spl_board_init(). Hence, introduce a spl_soc_init() method which is called right before spl_board_init() for SoC specific implementation. Signed-off-by: Lukas Funke <[email protected]> Reviewed-by: Devarsh Thakkar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Michal Simek <[email protected]>
2024-05-20Restore patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet"Tom Rini
As part of bringing the master branch back in to next, we need to allow for all of these changes to exist here. Reported-by: Jonas Karlman <[email protected]> Signed-off-by: Tom Rini <[email protected]>
2024-05-19Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""Tom Rini
When bringing in the series 'arm: dts: am62-beagleplay: Fix Beagleplay Ethernet"' I failed to notice that b4 noticed it was based on next and so took that as the base commit and merged that part of next to master. This reverts commit c8ffd1356d42223cbb8c86280a083cc3c93e6426, reversing changes made to 2ee6f3a5f7550de3599faef9704e166e5dcace35. Reported-by: Jonas Karlman <[email protected]> Signed-off-by: Tom Rini <[email protected]>
2024-05-06global: Make <asm/global_data.h> include <asm/u-boot.h>Tom Rini
This follows the example of RISC-V where <asm/global_data.h> includes <asm/u-boot.h> directly as "gd" includes a reference to bd_info already and so the first must include the second anyhow. We then remove <asm/u-boot.h> from all of the places which include references to "gd" an so have <asm/global_data.h> already. Signed-off-by: Tom Rini <[email protected]>
2024-05-06common: Remove <common.h> and add needed includesTom Rini
Remove <common.h> from all "commmon/" files and when needed add missing include files directly. Signed-off-by: Tom Rini <[email protected]>
2024-03-02log: fixup log_head after relocating global dataThomas Weißschuh
When `gd` is relocated during `spl_relocate_stack_gd()` the doubly-linked circular list in the `log_head` member is broken. The last element of the list should point back to the initial `list_head`, but as the initial `list_head` is moved the pointer becomes stale. As a result the loop in `log_dispatch` would never finish. Signed-off-by: Thomas Weißschuh <[email protected]>
2024-01-29spl: Enforce framebuffer reservation from end of RAMDevarsh Thakkar
Add an API which enforces framebuffer reservation from end of RAM. This is done so that next stage can directly skip this region before carrying out further reservations. Signed-off-by: Devarsh Thakkar <[email protected]> Reviewed-by: Simon Glass <[email protected]>
2023-11-16spl: Add generic spl_load functionSean Anderson
Implementers of SPL_LOAD_IMAGE_METHOD have to correctly determine what type of image is being loaded and then call the appropriate image load function correctly. This is tricky, because some image load functions expect the whole image to already be loaded (CONFIG_SPL_LOAD_FIT_FULL), some will load the image automatically using spl_load_info.read() (CONFIG_SPL_LOAD_FIT/CONFIG_SPL_LOAD_IMX_CONTAINER), and some just parse the header and expect the caller to do the actual loading afterwards (legacy/raw images). Load methods often only support a subset of the above methods, meaning that not all image types can be used with all load methods. Further, the code to invoke these functions is duplicated between different load functions. To address this problem, this commit introduces a "spl_load" function. It aims to handle image detection and correct invocation of each of the parse/load functions. Although this function generally results in a size reduction with several users, it tends to bloat boards with only a single user. This is generally because programmers open-coding the contents of this function can make optimizations based on the specific loader. For example, NOR flash is memory-mapped, so it never bothers calling load->read. The compiler can't really make these optimizations across translation units. LTO solves this, but it is only available on some arches. To address this, perform "pseudo-LTO" by inlining spl_load when there are one or fewer users. At the moment, there are no users, so define SPL_LOAD_USERS to be 0. Signed-off-by: Sean Anderson <[email protected]> Reviewed-by: Simon Glass <[email protected]>