View Issue Details

IDProjectCategoryView StatusLast Update
0004892UBootU-Bootpublic2021-10-05 12:20
Reporterderksen Assigned To 
PrioritynormalSeverityminorReproducibilityhave not tried
Status resolvedResolutionfixed 
Target Versionfsimx8mm-Y2021.04Fixed in Versionfsimx8mm-Y2021.04 
Summary0004892: fsimx8mm: Get rid of fs_nboot_args and use cfg_info instead
Descriptionfsimx8mm: Get rid of fs_nboot_args and use cfg_info instead

NBoot arguments are a relic from i.MX6. The legacy NBoot loader stored
a data structure with some board specific properties in DRAM and U-Boot
used this info to start all necessary drivers and to modify the Linux
device tree. But now the board configuration is available as BOARD-CFG
and devices are started by the DM driver model together with U-Boot's
own device tree. So basically, the NBoot args are not needed anymore.

On the other side, the BOARD-CFG is an own small device tree and thus
not very easy to parse. So it still makes sense to convert it to a
binary data structure that can be interpreted more easily. So the first
idea was to still set up an NBoot args structure to stay as similar as
possible to the previous board code in fsimx8mm.c. This was how it
was implemented up to now.

Unfortunately setting up the NBoot args is quite cumbersome. The data
is created in SPL in a variable, then before starting U-Boot, the data
needs to be copied to DRAM where U-Boot picks it up. Finally, after
U-Boot is relocated to the end of DRAM, the data is copied once again
to a local U-Boot variable. And even more, the fs_nboot_args structure
is not well suited for storing this information. It has entries that
are not meaningful on i.MX8 anymore and misses fields where we can store
things that are new in BOARD-CFG. For example it only provides 2x 8 bits
to represent board features, and SPL and U-Boot need to agree on the
meaning of these bits. This makes any changes to this mapping dangerous.
If a new U-Boot assumes one mapping, but an old SPL provides a different
mapping, then this will seriously go wrong.

This is why the new approach in this commit gets finally rid of the old
NBoot args and introduces a completely new data structure cfg_info for
holding the configuration information. In fact, SPL just needs very few
things from the BOARD-CFG and accesses them directly with regular fdt
functions. So there is no need to have such a binary structure in
SPL at all.

This means it is sufficient to set up this structure later in U-Boot.
U-Boot finds the BOARD-CFG at a defined place in OCRAM and the new
function fs_spl_setup_cfg_info() parses all values that are meaningful
to U-Boot and converts them to the new struct cfg_info. This structure
is also located in OCRAM, so there is no need to copy it again when
U-Boot relocates itself later. From now on, U-Boot can always refer to
this structure when it needs any configuration information.

Because struct cfg_info is now set up by U-Boot and is also used only
by U-Boot, the meaning of the feature bits can be arbitrarily chosen
and can also be changed at will without needing to take care of SPL.
Mapping problems as explained above are impossible now.

Most drivers are started automatically by the DM driver model now.
They read their parameters from U-Boot's device tree. So another task
is to modify this device tree according to the BOARD-CFG before U-Boot
actually uses it. For example the eMMC node must be disabled if the
board boots from NAND. This is done by enabling CONFIG_OF_BOARD_FIXUP.
Now board_f.c calls a function board_fix_fdt() in fsimx8mm.c that does
the proper modifications. Please read doc/driver-model/fdt-fixup.txt
for a description of this mechanism.

Actually later in ft_board_setup() before starting Linux, we can do
pretty much the same device tree modification, just on the Linux device
tree. This is why the modification code is moved to a separate function
do_fdt_board_setup() that is called in both cases.

Some functions in F&S common code also refer to struct fs_nboot_args.
By adding two different implementations in fs_board_common.c, one for
NBoot args and one for new cfg_info, and by adding a new function
fs_board_get_nboot_version(), the original code can be made generic.
The last change also needs new function fs_image_get_nboot_version()
in fs_image_common.c.

Now all code referring to fs_nboot_args can be dropped from spl.c and
fsimx8mm.c.

When all this is done, the only direct connection from spl.c to
fsimx8mm.c is the call of board_early_init_f() in SPL's board_init_f()
function. However it is only used to set up the watchdog pins. Copy
this code to spl.c. Now fsimx8mm.c and spl.c are completely independent
from each other. fsimx8mm.c is only needed in U-Boot and spl.c is only
needed in SPL. So change the Makefile accordingly. In the same spirit,
only fs_board_common and fs_image_common are needed in SPL. All other
common files need only be built in the non-SPL case.

There are some more changes related to the modifications above:

- To avoid an overflow in the dram_size entry in the BOARD-CFGs when RAM
  grows beyond 4GB, change the value to reflect size in MiB, not bytes.
- In SPL, if NAND resp. MMC pins are not set up by the fused boot device
  in fs_spl_early_load_boardcfg(), we need to set them up according to
  the BOARD-CFG later in basic_init().
- In U-Boot, when installing NBoot with command fsimage save, we must
  store to the device configured in the BOARD-CFG, not to the fused
  device. The fuses may not be blown, yet.
- To be able to disable eMMC in U-Boot when booting from NAND, we need
  an alias for the emmc node in the U-Boot device tree picocoremx8mm.dts.
  And all MMC entries must be available all the time, i.e. drop the
  surrounding #ifdef CONFIG_ENV_IS_IN_MMC ... #endif.
- Apply similar changes to picocoremx8mx.dts. Fix indendation and tabs.
- Add entry MX8MM_IOMUXC_NAND_READY_B_USDHC3_RESET_B to pins-imx8mm.h,
  it was missing. Convert the previous GPIO entry to the RESET entry.
- The mxs_nand driver does not yet use the DM driver model. So rename
  function board_nand_init() to mxs_nand_register(). Then we can have
  board_nand_init() in our own board file fsimx8mm.c and decide if we
  want to activate NAND or not. To not break existing code, keep a
  __weak board_nand_init() in mxs_nand.c that simply calls the new
  function mxs_nand_register(). Then if no own function is defined,
  (for example in SPL), everything is the same as before. Also rename
  mxs_nand_init() in mxs_nand_spl.c to mxs_nand_spl_init() to avoid
  confusions with the function in mxs_nand.c with the same name.
Forum Link

Activities

There are no notes attached to this issue.