From mboxrd@z Thu Jan 1 00:00:00 1970 From: Heinrich Schuchardt Date: Thu, 5 Sep 2019 21:43:59 +0200 Subject: [U-Boot] [PATCH v5 02/19] env: define env context for U-Boot environment In-Reply-To: <20190905082133.18996-3-takahiro.akashi@linaro.org> References: <20190905082133.18996-1-takahiro.akashi@linaro.org> <20190905082133.18996-3-takahiro.akashi@linaro.org> Message-ID: <5330f7e1-9af4-426f-0a4f-798e22027b09@gmx.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On 9/5/19 10:21 AM, AKASHI Takahiro wrote: > In this patch, env context fo U-Boot environment is defined to utilize > new env interfaces, maintaining the compatibility with the existing > semantics and Kconfig configuration. > > In this commit, FAT file system and flash device are only supported > devices for backing storages, but extending to other devices will be > quite straightforward. > > Signed-off-by: AKASHI Takahiro > --- > env/Kconfig.uboot | 671 ++++++++++++++++++++++++++++++++++++++++++++ > env/Makefile | 2 +- > env/env_ctx_uboot.c | 292 +++++++++++++++++++ > include/env.h | 3 + > 4 files changed, 967 insertions(+), 1 deletion(-) > create mode 100644 env/Kconfig.uboot > create mode 100644 env/env_ctx_uboot.c > > diff --git a/env/Kconfig.uboot b/env/Kconfig.uboot > new file mode 100644 > index 000000000000..e4334f7f2878 > --- /dev/null > +++ b/env/Kconfig.uboot > @@ -0,0 +1,671 @@ Only one of the options below should be selected. So, please, use a 'choice' statement. drives/video/Kconfig has an example. > +config ENV_IS_NOWHERE > + bool "U-Boot Environment is not stored" > + default y if !ENV_IS_IN_EEPROM && !ENV_IS_IN_EXT4 && \ > + !ENV_IS_IN_FAT && !ENV_IS_IN_FLASH && \ > + !ENV_IS_IN_MMC && !ENV_IS_IN_NAND && \ > + !ENV_IS_IN_NVRAM && !ENV_IS_IN_ONENAND && \ > + !ENV_IS_IN_REMOTE && !ENV_IS_IN_SPI_FLASH && \ > + !ENV_IS_IN_UBI > + help > + Define this if you don't want to or can't have an environment stored > + on a storage medium. In this case the environment will still exist > + while U-Boot is running, but once U-Boot exits it will not be > + stored. U-Boot will therefore always start up with a default > + environment. > + > +config ENV_IS_IN_EEPROM > + bool "Environment in EEPROM" > + depends on !CHAIN_OF_TRUST > + select ENV_DRV_EEPROM > + help > + Use this if you have an EEPROM or similar serial access > + device and a driver for it. > + > + - CONFIG_ENV_OFFSET: > + - CONFIG_ENV_SIZE: > + > + These two #defines specify the offset and size of the > + environment area within the total memory of your EEPROM. > + > + Note that we consider the length of the address field to > + still be one byte because the extra address bits are hidden > + in the chip address. > + > + - CONFIG_ENV_EEPROM_IS_ON_I2C > + define this, if you have I2C and SPI activated, and your > + EEPROM, which holds the environment, is on the I2C bus. > + > + - CONFIG_I2C_ENV_EEPROM_BUS > + if you have an Environment on an EEPROM reached over > + I2C muxes, you can define here, how to reach this > + EEPROM. For example: > + > + #define CONFIG_I2C_ENV_EEPROM_BUS 1 > + > + EEPROM which holds the environment, is reached over > + a pca9547 i2c mux with address 0x70, channel 3. > + > +config ENV_IS_IN_FAT > + bool "Environment is in a FAT filesystem" > + depends on !CHAIN_OF_TRUST > + default y if ARCH_BCM283X > + default y if ARCH_SUNXI && MMC > + default y if MMC_OMAP_HS && TI_COMMON_CMD_OPTIONS > + select ENV_DRV_FAT > + help > + Define this if you want to use the FAT file system for the environment. > + > +config ENV_IS_IN_EXT4 > + bool "Environment is in a EXT4 filesystem" > + depends on !CHAIN_OF_TRUST > + select ENV_DRV_EXT4 > + help > + Define this if you want to use the EXT4 file system for the environment. > + > +config ENV_IS_IN_FLASH > + bool "Environment in flash memory" > + depends on !CHAIN_OF_TRUST > + select ENV_DRV_FLASH > + default y if ARCH_CINTEGRATOR > + default y if ARCH_INTEGRATOR_CP > + default y if M548x || M547x || M5282 || MCF547x_8x > + default y if MCF532x || MCF52x2 > + default y if MPC86xx || MPC83xx > + default y if ARCH_MPC8572 || ARCH_MPC8548 || ARCH_MPC8641 > + default y if SH && !CPU_SH4 > + help > + Define this if you have a flash device which you want to use for the > + environment. > + > + a) The environment occupies one whole flash sector, which is > + "embedded" in the text segment with the U-Boot code. This > + happens usually with "bottom boot sector" or "top boot > + sector" type flash chips, which have several smaller > + sectors at the start or the end. For instance, such a > + layout can have sector sizes of 8, 2x4, 16, Nx32 kB. In > + such a case you would place the environment in one of the > + 4 kB sectors - with U-Boot code before and after it. With > + "top boot sector" type flash chips, you would put the > + environment in one of the last sectors, leaving a gap > + between U-Boot and the environment. > + > + CONFIG_ENV_OFFSET: > + > + Offset of environment data (variable area) to the > + beginning of flash memory; for instance, with bottom boot > + type flash chips the second sector can be used: the offset > + for this sector is given here. > + > + CONFIG_ENV_OFFSET is used relative to CONFIG_SYS_FLASH_BASE. > + > + CONFIG_ENV_ADDR: > + > + This is just another way to specify the start address of > + the flash sector containing the environment (instead of > + CONFIG_ENV_OFFSET). > + > + CONFIG_ENV_SECT_SIZE: > + > + Size of the sector containing the environment. > + > + > + b) Sometimes flash chips have few, equal sized, BIG sectors. > + In such a case you don't want to spend a whole sector for > + the environment. > + > + CONFIG_ENV_SIZE: > + > + If you use this in combination with CONFIG_ENV_IS_IN_FLASH > + and CONFIG_ENV_SECT_SIZE, you can specify to use only a part > + of this flash sector for the environment. This saves > + memory for the RAM copy of the environment. > + > + It may also save flash memory if you decide to use this > + when your environment is "embedded" within U-Boot code, > + since then the remainder of the flash sector could be used > + for U-Boot code. It should be pointed out that this is > + STRONGLY DISCOURAGED from a robustness point of view: > + updating the environment in flash makes it always > + necessary to erase the WHOLE sector. If something goes > + wrong before the contents has been restored from a copy in > + RAM, your target system will be dead. > + > + CONFIG_ENV_ADDR_REDUND > + CONFIG_ENV_SIZE_REDUND > + > + These settings describe a second storage area used to hold > + a redundant copy of the environment data, so that there is > + a valid backup copy in case there is a power failure during > + a "saveenv" operation. > + > + BE CAREFUL! Any changes to the flash layout, and some changes to the > + source code will make it necessary to adapt /u-boot.lds* > + accordingly! > + > +config ENV_IS_IN_MMC > + bool "Environment in an MMC device" > + depends on !CHAIN_OF_TRUST > + depends on MMC > + select ENV_DRV_MMC > + default y if ARCH_EXYNOS4 > + default y if MX6SX || MX7D > + default y if TEGRA30 || TEGRA124 > + default y if TEGRA_ARMV8_COMMON > + help > + Define this if you have an MMC device which you want to use for the > + environment. > + > + CONFIG_SYS_MMC_ENV_DEV: > + > + Specifies which MMC device the environment is stored in. > + > + CONFIG_SYS_MMC_ENV_PART (optional): > + > + Specifies which MMC partition the environment is stored in. If not > + set, defaults to partition 0, the user area. Common values might be > + 1 (first MMC boot partition), 2 (second MMC boot partition). > + > + CONFIG_ENV_OFFSET: > + CONFIG_ENV_SIZE: > + > + These two #defines specify the offset and size of the environment > + area within the specified MMC device. > + > + If offset is positive (the usual case), it is treated as relative to > + the start of the MMC partition. If offset is negative, it is treated > + as relative to the end of the MMC partition. This can be useful if > + your board may be fitted with different MMC devices, which have > + different sizes for the MMC partitions, and you always want the > + environment placed at the very end of the partition, to leave the > + maximum possible space before it, to store other data. > + > + These two values are in units of bytes, but must be aligned to an > + MMC sector boundary. > + > + CONFIG_ENV_OFFSET_REDUND (optional): > + > + Specifies a second storage area, of CONFIG_ENV_SIZE size, used to > + hold a redundant copy of the environment data. This provides a > + valid backup copy in case the other copy is corrupted, e.g. due > + to a power failure during a "saveenv" operation. > + > + This value may also be positive or negative; this is handled in the > + same way as CONFIG_ENV_OFFSET. > + > + This value is also in units of bytes, but must also be aligned to > + an MMC sector boundary. > + > + CONFIG_ENV_SIZE_REDUND (optional): > + > + This value need not be set, even when CONFIG_ENV_OFFSET_REDUND is > + set. If this value is set, it must be set to the same value as > + CONFIG_ENV_SIZE. > + > +config ENV_IS_IN_NAND > + bool "Environment in a NAND device" > + depends on !CHAIN_OF_TRUST > + select ENV_DRV_NAND > + help > + Define this if you have a NAND device which you want to use for the > + environment. > + > + - CONFIG_ENV_OFFSET: > + - CONFIG_ENV_SIZE: > + > + These two #defines specify the offset and size of the environment > + area within the first NAND device. CONFIG_ENV_OFFSET must be > + aligned to an erase block boundary. > + > + - CONFIG_ENV_OFFSET_REDUND (optional): > + > + This setting describes a second storage area of CONFIG_ENV_SIZE > + size used to hold a redundant copy of the environment data, so > + that there is a valid backup copy in case there is a power failure > + during a "saveenv" operation. CONFIG_ENV_OFFSET_REDUND must be > + aligned to an erase block boundary. > + > + - CONFIG_ENV_RANGE (optional): > + > + Specifies the length of the region in which the environment > + can be written. This should be a multiple of the NAND device's > + block size. Specifying a range with more erase blocks than > + are needed to hold CONFIG_ENV_SIZE allows bad blocks within > + the range to be avoided. > + > + - CONFIG_ENV_OFFSET_OOB (optional): > + > + Enables support for dynamically retrieving the offset of the > + environment from block zero's out-of-band data. The > + "nand env.oob" command can be used to record this offset. > + Currently, CONFIG_ENV_OFFSET_REDUND is not supported when > + using CONFIG_ENV_OFFSET_OOB. > + > +config ENV_IS_IN_NVRAM > + bool "Environment in a non-volatile RAM" > + depends on !CHAIN_OF_TRUST > + select ENV_DRV_NVRAM > + help > + Define this if you have some non-volatile memory device > + (NVRAM, battery buffered SRAM) which you want to use for the > + environment. > + > + - CONFIG_ENV_ADDR: > + - CONFIG_ENV_SIZE: > + > + These two #defines are used to determine the memory area you > + want to use for environment. It is assumed that this memory > + can just be read and written to, without any special > + provision. > + > +config ENV_IS_IN_ONENAND > + bool "Environment is in OneNAND" > + depends on !CHAIN_OF_TRUST > + select ENV_DRV_ONENAND > + help > + Define this if you want to put your local device's environment in > + OneNAND. > + > + - CONFIG_ENV_ADDR: > + - CONFIG_ENV_SIZE: > + > + These two #defines are used to determine the device range you > + want to use for environment. It is assumed that this memory > + can just be read and written to, without any special > + provision. > + > +config ENV_IS_IN_REMOTE > + bool "Environment is in remote memory space" > + depends on !CHAIN_OF_TRUST > + select ENV_DRV_REMOTE > + help > + Define this if you have a remote memory space which you > + want to use for the local device's environment. > + > + - CONFIG_ENV_ADDR: > + - CONFIG_ENV_SIZE: > + > + These two #defines specify the address and size of the > + environment area within the remote memory space. The > + local device can get the environment from remote memory > + space by SRIO or PCIE links. > + > +config ENV_IS_IN_SPI_FLASH > + bool "Environment is in SPI flash" > + depends on !CHAIN_OF_TRUST && SPI > + select ENV_DRV_SPI_FLASH > + default y if ARMADA_XP > + default y if INTEL_BAYTRAIL > + default y if INTEL_BRASWELL > + default y if INTEL_BROADWELL > + default y if NORTHBRIDGE_INTEL_IVYBRIDGE > + default y if INTEL_QUARK > + default y if INTEL_QUEENSBAY > + help > + Define this if you have a SPI Flash memory device which you > + want to use for the environment. > + > + - CONFIG_ENV_OFFSET: > + - CONFIG_ENV_SIZE: > + > + These two #defines specify the offset and size of the > + environment area within the SPI Flash. CONFIG_ENV_OFFSET must be > + aligned to an erase sector boundary. > + > + - CONFIG_ENV_SECT_SIZE: > + > + Define the SPI flash's sector size. > + > + - CONFIG_ENV_OFFSET_REDUND (optional): > + > + This setting describes a second storage area of CONFIG_ENV_SIZE > + size used to hold a redundant copy of the environment data, so > + that there is a valid backup copy in case there is a power failure > + during a "saveenv" operation. CONFIG_ENV_OFFSET_REDUND must be > + aligned to an erase sector boundary. > + > +config USE_ENV_SPI_BUS > + bool "SPI flash bus for environment" > + depends on ENV_IS_IN_SPI_FLASH > + help > + Force the SPI bus for environment. > + If not defined, use CONFIG_SF_DEFAULT_BUS. > + > +config ENV_SPI_BUS > + int "Value of SPI flash bus for environment" > + depends on USE_ENV_SPI_BUS > + help > + Value the SPI bus and chip select for environment. > + > +config USE_ENV_SPI_CS > + bool "SPI flash chip select for environment" > + depends on ENV_IS_IN_SPI_FLASH > + help > + Force the SPI chip select for environment. > + If not defined, use CONFIG_SF_DEFAULT_CS. > + > +config ENV_SPI_CS > + int "Value of SPI flash chip select for environment" > + depends on USE_ENV_SPI_CS > + help > + Value of the SPI chip select for environment. > + > +config USE_ENV_SPI_MAX_HZ > + bool "SPI flash max frequency for environment" > + depends on ENV_IS_IN_SPI_FLASH > + help > + Force the SPI max work clock for environment. > + If not defined, use CONFIG_SF_DEFAULT_SPEED. > + > +config ENV_SPI_MAX_HZ > + int "Value of SPI flash max frequency for environment" > + depends on USE_ENV_SPI_MAX_HZ > + help > + Value of the SPI max work clock for environment. > + > +config USE_ENV_SPI_MODE > + bool "SPI flash mode for environment" > + depends on ENV_IS_IN_SPI_FLASH > + help > + Force the SPI work mode for environment. > + > +config ENV_SPI_MODE > + hex "Value of SPI flash work mode for environment" > + depends on USE_ENV_SPI_MODE > + help > + Value of the SPI work mode for environment. > + See include/spi.h for value. > + > +config ENV_IS_IN_UBI > + bool "Environment in a UBI volume" > + depends on !CHAIN_OF_TRUST > + select ENV_DRV_UBI > + help > + Define this if you have an UBI volume that you want to use for the > + environment. This has the benefit of wear-leveling the environment > + accesses, which is important on NAND. > + > + - CONFIG_ENV_UBI_PART: > + > + Define this to a string that is the mtd partition containing the UBI. > + > + - CONFIG_ENV_UBI_VOLUME: > + > + Define this to the name of the volume that you want to store the > + environment in. > + > + - CONFIG_ENV_UBI_VOLUME_REDUND: > + > + Define this to the name of another volume to store a second copy of > + the environment in. This will enable redundant environments in UBI. > + It is assumed that both volumes are in the same MTD partition. > + > +config ENV_FAT_INTERFACE > + string "Name of the block device for the environment" > + depends on ENV_IS_IN_FAT > + default "mmc" if ARCH_SUNXI > + default "mmc" if TI_COMMON_CMD_OPTIONS || ARCH_ZYNQMP || ARCH_AT91 > + help > + Define this to a string that is the name of the block device. > + > +config ENV_FAT_DEVICE_AND_PART > + string "Device and partition for where to store the environment in FAT" > + depends on ENV_IS_IN_FAT > + default "0:1" if TI_COMMON_CMD_OPTIONS > + default "0:auto" if ARCH_ZYNQMP > + default "0:auto" if ARCH_SUNXI && MMC_SUNXI_SLOT_EXTRA = -1 > + default "1:auto" if ARCH_SUNXI && MMC_SUNXI_SLOT_EXTRA != -1 > + default "0" if ARCH_AT91 > + help > + Define this to a string to specify the partition of the device. It can > + be as following: > + > + "D:P", "D:0", "D", "D:" or "D:auto" (D, P are integers. And P >= 1) > + - "D:P": device D partition P. Error occurs if device D has no > + partition table. > + - "D:0": device D. > + - "D" or "D:": device D partition 1 if device D has partition > + table, or the whole device D if has no partition > + table. > + - "D:auto": first partition in device D with bootable flag set. > + If none, first valid partition in device D. If no > + partition table then means device D. > + > +config ENV_FAT_FILE > + string "Name of the FAT file to use for the environment" > + depends on ENV_IS_IN_FAT > + default "uboot.env" > + help > + It's a string of the FAT file name. This file use to store the > + environment. > + > +config ENV_EXT4_INTERFACE > + string "Name of the block device for the environment" > + depends on ENV_IS_IN_EXT4 > + help > + Define this to a string that is the name of the block device. > + > +config ENV_EXT4_DEVICE_AND_PART > + string "Device and partition for where to store the environment in EXT4" > + depends on ENV_IS_IN_EXT4 > + help > + Define this to a string to specify the partition of the device. It can > + be as following: > + > + "D:P", "D:0", "D", "D:" or "D:auto" (D, P are integers. And P >= 1) > + - "D:P": device D partition P. Error occurs if device D has no > + partition table. > + - "D:0": device D. > + - "D" or "D:": device D partition 1 if device D has partition > + table, or the whole device D if has no partition > + table. > + - "D:auto": first partition in device D with bootable flag set. > + If none, first valid partition in device D. If no > + partition table then means device D. > + > +config ENV_EXT4_FILE > + string "Name of the EXT4 file to use for the environment" > + depends on ENV_IS_IN_EXT4 > + default "uboot.env" > + help > + It's a string of the EXT4 file name. This file use to store the > + environment (explicit path to the file) > + > +if ARCH_ROCKCHIP || ARCH_SUNXI || ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL || ARC || ARCH_STM32MP || ARCH_OMAP2PLUS || ARCH_AT91 > + > +config ENV_OFFSET > + hex "Environment Offset" > + depends on (!ENV_IS_IN_UBI && !ENV_IS_NOWHERE) || ARCH_STM32MP > + default 0x3f8000 if ARCH_ROCKCHIP > + default 0x88000 if ARCH_SUNXI > + default 0xE0000 if ARCH_ZYNQ > + default 0x1E00000 if ARCH_ZYNQMP > + default 0 if ARC > + default 0x140000 if ARCH_AT91 > + default 0x260000 if ARCH_OMAP2PLUS > + help > + Offset from the start of the device (or partition) > + > +config ENV_SIZE > + hex "Environment Size" > + default 0x40000 if ENV_IS_IN_SPI_FLASH && ARCH_ZYNQMP > + default 0x20000 if ARCH_SUNXI || ARCH_ZYNQ || ARCH_OMAP2PLUS || ARCH_AT91 > + default 0x8000 if ARCH_ROCKCHIP || ARCH_ZYNQMP || ARCH_VERSAL > + default 0x4000 if ARC > + default 0x1f000 > + help > + Size of the environment storage area > + > +config ENV_SECT_SIZE > + hex "Environment Sector-Size" > + depends on (!ENV_IS_NOWHERE && (ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_OMAP2PLUS || ARCH_AT91) )|| ARCH_STM32MP > + default 0x40000 if ARCH_ZYNQMP > + default 0x20000 if ARCH_ZYNQ || ARCH_OMAP2PLUS || ARCH_AT91 > + help > + Size of the sector containing the environment. > + > +config ENV_UBI_PART > + string "UBI partition name" > + depends on ENV_IS_IN_UBI > + help > + MTD partition containing the UBI device > + > +config ENV_UBI_VOLUME > + string "UBI volume name" > + depends on ENV_IS_IN_UBI > + help > + Name of the volume that you want to store the environment in. > + > +config ENV_UBI_VOLUME_REDUND > + string "UBI redundant volume name" > + depends on ENV_IS_IN_UBI > + help > + Name of the redundant volume that you want to store the environment in. > + > +config ENV_UBI_VID_OFFSET > + int "ubi environment VID offset" > + depends on ENV_IS_IN_UBI > + default 0 > + help > + UBI VID offset for environment. If 0, no custom VID offset is used. > + > +endif > + > +config USE_DEFAULT_ENV_FILE > + bool "Create default environment from file" > + help > + Normally, the default environment is automatically generated > + based on the settings of various CONFIG_* options, as well > + as the CONFIG_EXTRA_ENV_SETTINGS. By selecting this option, > + you can instead define the entire default environment in an > + external file. > + > +config DEFAULT_ENV_FILE > + string "Path to default environment file" > + depends on USE_DEFAULT_ENV_FILE > + help > + The path containing the default environment. The format is > + the same as accepted by the mkenvimage tool: lines > + containing key=value pairs, blank lines and lines beginning > + with # are ignored. > + > +config ENV_VARS_UBOOT_RUNTIME_CONFIG > + bool "Add run-time information to the environment" > + help > + Enable this in order to add variables describing certain > + run-time determined information about the hardware to the > + environment. These will be named board_name, board_rev. > + > +if SPL_ENV_SUPPORT > +config SPL_ENV_IS_NOWHERE > + bool "SPL Environment is not stored" > + default y if ENV_IS_NOWHERE > + help > + Similar to ENV_IS_NOWHERE, used for SPL environment. > + > +config SPL_ENV_IS_IN_MMC > + bool "SPL Environment in an MMC device" > + depends on !SPL_ENV_IS_NOWHERE > + select ENV_DRV_MMC > + default y > + help > + Similar to ENV_IS_IN_MMC, used for SPL environment. > + > +config SPL_ENV_IS_IN_FAT > + bool "SPL Environment is in a FAT filesystem" > + depends on !SPL_ENV_IS_NOWHERE > + select ENV_DRV_FAT > + default y > + help > + Similar to ENV_IS_IN_FAT, used for SPL environment. > + > +config SPL_ENV_IS_IN_EXT4 > + bool "SPL Environment is in a EXT4 filesystem" > + depends on !SPL_ENV_IS_NOWHERE > + select ENV_DRV_EXT4 > + default y > + help > + Similar to ENV_IS_IN_EXT4, used for SPL environment. > + > +config SPL_ENV_IS_IN_NAND > + bool "SPL Environment in a NAND device" > + depends on !SPL_ENV_IS_NOWHERE > + select ENV_DRV_NAND > + default y > + help > + Similar to ENV_IS_IN_NAND, used for SPL environment. > + > +config SPL_ENV_IS_IN_SPI_FLASH > + bool "SPL Environment is in SPI flash" > + depends on !SPL_ENV_IS_NOWHERE > + select ENV_DRV_SPI_FLASH > + default y > + help > + Similar to ENV_IS_IN_SPI_FLASH, used for SPL environment. > + > +config SPL_ENV_IS_IN_FLASH > + bool "SPL Environment in flash memory" > + depends on !SPL_ENV_IS_NOWHERE > + select ENV_DRV_FLASH > + default y > + help > + Similar to ENV_IS_IN_FLASH, used for SPL environment. > + > +endif > + > +if TPL_ENV_SUPPORT > + > +config TPL_ENV_IS_NOWHERE > + bool "TPL Environment is not stored" > + default y if ENV_IS_NOWHERE > + help > + Similar to ENV_IS_NOWHERE, used for TPL environment. > + > +config TPL_ENV_IS_IN_MMC > + bool "TPL Environment in an MMC device" > + depends on !TPL_ENV_IS_NOWHERE > + select ENV_DRV_MMC > + default y > + help > + Similar to ENV_IS_IN_MMC, used for TPL environment. > + > +config TPL_ENV_IS_IN_FAT > + bool "TPL Environment is in a FAT filesystem" > + depends on !TPL_ENV_IS_NOWHERE > + select ENV_DRV_FAT > + default y > + help > + Similar to ENV_IS_IN_FAT, used for TPL environment. > + > +config TPL_ENV_IS_IN_EXT4 > + bool "TPL Environment is in a EXT4 filesystem" > + depends on !TPL_ENV_IS_NOWHERE > + select ENV_DRV_EXT4 > + default y > + help > + Similar to ENV_IS_IN_EXT4, used for TPL environment. > + > +config TPL_ENV_IS_IN_NAND > + bool "TPL Environment in a NAND device" > + depends on !TPL_ENV_IS_NOWHERE > + select ENV_DRV_NAND > + default y > + help > + Similar to ENV_IS_IN_NAND, used for TPL environment. > + > +config TPL_ENV_IS_IN_SPI_FLASH > + bool "TPL Environment is in SPI flash" > + depends on !TPL_ENV_IS_NOWHERE > + select ENV_DRV_SPI_FLASH > + default y > + help > + Similar to ENV_IS_IN_SPI_FLASH, used for TPL environment. > + > +config TPL_ENV_IS_IN_FLASH > + bool "TPL Environment in flash memory" > + depends on !TPL_ENV_IS_NOWHERE > + select ENV_DRV_FLASH > + default y > + help > + Similar to ENV_IS_IN_FLASH, used for TPL environment. > + > +endif > diff --git a/env/Makefile b/env/Makefile > index ee37cc822024..0168eb47f00d 100644 > --- a/env/Makefile > +++ b/env/Makefile > @@ -3,7 +3,7 @@ > # (C) Copyright 2004-2006 > # Wolfgang Denk, DENX Software Engineering, wd at denx.de. > > -obj-y += common.o env.o > +obj-y += common.o env.o env_ctx_uboot.o > > ifndef CONFIG_SPL_BUILD > obj-y += attr.o > diff --git a/env/env_ctx_uboot.c b/env/env_ctx_uboot.c > new file mode 100644 > index 000000000000..5ca645599347 > --- /dev/null > +++ b/env/env_ctx_uboot.c > @@ -0,0 +1,292 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) 2019 Linaro Limited > + * Author: AKASHI Takahiro > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +DECLARE_GLOBAL_DATA_PTR; > + > +#if !defined(ENV_IS_IN_DEVICE) && !defined(CONFIG_ENV_IS_NOWHERE) > +# error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|MMC|FAT|EXT4|\ > +NAND|NVRAM|ONENAND|SATA|SPI_FLASH|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE > +#endif > + > +struct hsearch_data env_htab = { > +#if CONFIG_IS_ENABLED(ENV_SUPPORT) > + /* defined in flags.c, only compile with ENV_SUPPORT */ > + .change_ok = env_flags_validate, > +#endif > +}; > + > +/* > + * NOTE: extracted from env/env.c > + */ > +static bool env_has_inited_uboot(struct env_context *ctx, > + enum env_location location) > +{ > + return gd->env_has_init & BIT(location); > +} > + > +static void env_set_inited_uboot(struct env_context *ctx, > + enum env_location location) > +{ > + gd->env_has_init |= BIT(location); > +} > + > +static int env_get_load_prio_uboot(struct env_context *ctx) > +{ > + return gd->env_load_prio; > +} > + > +static enum env_location env_get_location_uboot(struct env_context *ctx, > + enum env_operation op, int prio) > +{ > + gd->env_load_prio = prio; > + > + return env_locations[prio]; > +} > + > +int env_get_char_default_uboot(struct env_context *ctx, int index) > +{ > + return default_environment[index]; > +} > + > +int env_get_char_spec_uboot(struct env_context *ctx, int index) > +{ > + return *(uchar *)(gd->env_addr + index); > +} > + > +static int env_init_uboot(struct env_context *ctx) > +{ > + struct env_driver *drv; > + int ret = -ENOENT; > + int prio; > + > + for (prio = 0; (drv = env_driver_lookup(ctx, ENVOP_INIT, prio)); > + prio++) { > + if (!drv->init || !(ret = drv->init(ctx))) > + gd->env_has_init |= BIT(drv->location); > + > + debug("%s: Environment %s init done (ret=%d)\n", __func__, > + drv->name, ret); > + } > + > + if (!prio) > + return -ENODEV; > + > + if (ret == -ENOENT) { > + gd->env_addr = (ulong)&default_environment[0]; > + gd->env_valid = ENV_VALID; > + > + return 0; > + } > + > + return ret; > +} > + > +static int env_drv_init_uboot(struct env_context *ctx, enum env_location loc) > +{ > + __maybe_unused int ret; > + > + switch (loc) { > +#ifdef CONFIG_ENV_IS_IN_FLASH > + case ENVL_FLASH: { > + env_hdr_t *env_ptr; > + env_hdr_t *flash_addr; > + ulong end_addr; > + env_hdr_t *flash_addr_new; > + ulong end_addr_new; > + > +#ifdef ENV_IS_EMBEDDED > + env_ptr = &embedded_environment; > +#else /* ! ENV_IS_EMBEDDED */ > + env_ptr = (env_hdr_t *)CONFIG_ENV_ADDR; > +#endif /* ENV_IS_EMBEDDED */ > + flash_addr = (env_hdr_t *)CONFIG_ENV_ADDR; > + > +/* CONFIG_ENV_ADDR is supposed to be on sector boundary */ > + end_addr = CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1; > + > +#ifdef CONFIG_ENV_ADDR_REDUND > + flash_addr_new = (env_hdr_t *)CONFIG_ENV_ADDR_REDUND; > +/* CONFIG_ENV_ADDR_REDUND is supposed to be on sector boundary */ > + end_addr_new = CONFIG_ENV_ADDR_REDUND > + + CONFIG_ENV_SECT_SIZE - 1; > +#else > + flash_addr_new = NULL; > + end_addr_new = 0; > +#endif /* CONFIG_ENV_ADDR_REDUND */ > + > + ret = env_flash_init_params(ctx, env_ptr, flash_addr, end_addr, > + flash_addr_new, end_addr_new, > + (ulong)&default_environment[0]); > + if (ret) > + return -ENOENT; > + > + return 0; > + } > +#endif > +#ifdef CONFIG_ENV_IS_IN_FAT > + case ENVL_FAT: { > + ret = env_fat_init_params(ctx, > + CONFIG_ENV_FAT_INTERFACE, > + CONFIG_ENV_FAT_DEVICE_AND_PART, > + CONFIG_ENV_FAT_FILE); > + > + return -ENOENT; > + } > +#endif > +#ifdef CONFIG_ENV_DRV_NONE > + case ENVL_NOWHERE: > +#ifdef CONFIG_ENV_IS_NOWHERE > + gd->env_addr = (ulong)&default_environment[0]; > + gd->env_valid = ENV_INVALID; > + > + return 0; > +#else > + return -ENOENT; > +#endif > +#endif > + default: > + return -ENOENT; > + } > +} > + > +/* > + * NOTE: extracted from env/common.c > + */ > +void env_set_ready_uboot(struct env_context *ctx) > +{ > + gd->flags |= GD_FLG_ENV_READY; > +} > + > +bool env_is_ready_uboot(struct env_context *ctx) > +{ > + return (gd->flags & GD_FLG_ENV_READY); > +} > + > +void env_set_valid_uboot(struct env_context *ctx, enum env_valid valid) > +{ > + gd->env_valid = valid; > +} > + > +enum env_valid env_get_valid_uboot(struct env_context *ctx) > +{ > + return gd->env_valid; > +} > + > +void env_set_addr_uboot(struct env_context *ctx, ulong env_addr) > +{ > + gd->env_addr = env_addr; > +} > + > +ulong env_get_addr_uboot(struct env_context *ctx) > +{ > + return gd->env_addr; > +} > + > +/* > + * Look up the variable from the default environment > + */ > +char *env_get_default_uboot(struct env_context *ctx, const char *name) > +{ > + char *ret_val; > + unsigned long really_valid = gd->env_valid; > + unsigned long real_gd_flags = gd->flags; > + > + /* Pretend that the image is bad. */ > + gd->flags &= ~GD_FLG_ENV_READY; > + gd->env_valid = ENV_INVALID; > + ret_val = env_get(ctx, name); > + gd->env_valid = really_valid; > + gd->flags = real_gd_flags; > + return ret_val; > +} > + > +void env_set_default_env_uboot(struct env_context *ctx, const char *s, > + int flags) > +{ > + if (sizeof(default_environment) > ctx->env_size) { > + puts("*** Error - default environment is too large\n\n"); > + return; > + } > + > + if (s) { > + if ((flags & H_INTERACTIVE) == 0) > + printf("*** Warning - %s, using default environment\n\n", s); > + else > + puts(s); > + } else { > + debug("Using default environment\n"); > + } > + > + env_htab.ctx = ctx; > + if (himport_r(&env_htab, (char *)default_environment, > + sizeof(default_environment), '\0', flags, 0, > + 0, NULL) == 0) > + pr_err("## Error: Environment import failed: errno = %d\n", > + errno); > + > + gd->flags |= GD_FLG_ENV_READY; > + gd->flags |= GD_FLG_ENV_DEFAULT; > +} > + > +/* [re]set individual variables to their value in the default environment */ > +int env_set_default_vars_uboot(struct env_context *ctx, int nvars, > + char * const vars[], int flags) > +{ > + /* > + * Special use-case: import from default environment > + * (and use \0 as a separator) > + */ > + flags |= H_NOCLEAR; > + env_htab.ctx = ctx; > + return himport_r(&env_htab, (const char *)default_environment, > + sizeof(default_environment), '\0', > + flags, 0, nvars, vars); > +} > + > +void env_post_relocate_uboot(struct env_context *ctx) > +{ > + if (gd->env_valid == ENV_INVALID) { > +#if defined(CONFIG_ENV_IS_NOWHERE) || defined(CONFIG_SPL_BUILD) > + /* Environment not changeable */ > + env_set_default(ctx, NULL, 0); > +#else > + bootstage_error(BOOTSTAGE_ID_NET_CHECKSUM); > + env_set_default(ctx, "bad CRC", 0); > +#endif > + } else { > + env_load(ctx); > + } > +} > + > +U_BOOT_ENV_CONTEXT(uboot) = { > + .name = "uboot", > + .htab = &env_htab, > + .env_size = ENV_SIZE, > + .has_inited = env_has_inited_uboot, > + .set_inited = env_set_inited_uboot, > + .get_load_prio = env_get_load_prio_uboot, > + .get_location = env_get_location_uboot, > + .get_char_default = env_get_char_default_uboot, > + .get_char_spec = env_get_char_spec_uboot, > + .init = env_init_uboot, > + .drv_init = env_drv_init_uboot, > + .get_default = env_get_default_uboot, > + .set_default = env_set_default_env_uboot, > + .set_default_vars = env_set_default_vars_uboot, > + .set_ready = env_set_ready_uboot, > + .is_ready = env_is_ready_uboot, > + .set_valid = env_set_valid_uboot, > + .get_valid = env_get_valid_uboot, > + .set_addr = env_set_addr_uboot, > + .get_addr = env_get_addr_uboot, > + .post_relocate = env_post_relocate_uboot, > +}; > diff --git a/include/env.h b/include/env.h > index 203605e5e778..26abae2a5c42 100644 > --- a/include/env.h > +++ b/include/env.h > @@ -9,6 +9,7 @@ > #ifndef __ENV_H > #define __ENV_H > > +#include > #include > #include > > @@ -63,6 +64,8 @@ enum env_redund_flags { > ENV_REDUND_ACTIVE = 1, > }; > > +#define ctx_uboot ll_entry_get(struct env_context, uboot, env_contexts) Please, do not call ll_entry_get(,uboot,) multiple times. Just call it once during initialization and store the reference in a global variable. In this case you do not need the macro. Best regards Heinrich > + > /* Accessor functions */ > void env_set_ready(struct env_context *ctx); > bool env_is_ready(struct env_context *ctx); >