mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-08-22 23:21:24 +02:00
Merge branch '2021-10-25-assorted-updates'
- Allow redundant environment on the eMMC HW boot partitions - Use LMB in "loads" - env, dfu + spi, OPTEE bugfixes
This commit is contained in:
commit
75e33b378b
@ -77,3 +77,14 @@ void __noreturn jump_to_image_linux(struct spl_image_info *spl_image)
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_ARM64 */
|
#endif /* CONFIG_ARM64 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(OPTEE_IMAGE)
|
||||||
|
void __noreturn jump_to_image_optee(struct spl_image_info *spl_image)
|
||||||
|
{
|
||||||
|
/* flush and turn off caches before jumping to OPTEE */
|
||||||
|
cleanup_before_linux();
|
||||||
|
|
||||||
|
spl_optee_entry(NULL, NULL, spl_image->fdt_addr,
|
||||||
|
(void *)spl_image->entry_point);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
12
cmd/load.c
12
cmd/load.c
@ -16,6 +16,7 @@
|
|||||||
#include <exports.h>
|
#include <exports.h>
|
||||||
#include <flash.h>
|
#include <flash.h>
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
|
#include <lmb.h>
|
||||||
#include <mapmem.h>
|
#include <mapmem.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <s_record.h>
|
#include <s_record.h>
|
||||||
@ -137,6 +138,7 @@ static int do_load_serial(struct cmd_tbl *cmdtp, int flag, int argc,
|
|||||||
|
|
||||||
static ulong load_serial(long offset)
|
static ulong load_serial(long offset)
|
||||||
{
|
{
|
||||||
|
struct lmb lmb;
|
||||||
char record[SREC_MAXRECLEN + 1]; /* buffer for one S-Record */
|
char record[SREC_MAXRECLEN + 1]; /* buffer for one S-Record */
|
||||||
char binbuf[SREC_MAXBINLEN]; /* buffer for binary data */
|
char binbuf[SREC_MAXBINLEN]; /* buffer for binary data */
|
||||||
int binlen; /* no. of data bytes in S-Rec. */
|
int binlen; /* no. of data bytes in S-Rec. */
|
||||||
@ -147,6 +149,9 @@ static ulong load_serial(long offset)
|
|||||||
ulong start_addr = ~0;
|
ulong start_addr = ~0;
|
||||||
ulong end_addr = 0;
|
ulong end_addr = 0;
|
||||||
int line_count = 0;
|
int line_count = 0;
|
||||||
|
long ret;
|
||||||
|
|
||||||
|
lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
|
||||||
|
|
||||||
while (read_record(record, SREC_MAXRECLEN + 1) >= 0) {
|
while (read_record(record, SREC_MAXRECLEN + 1) >= 0) {
|
||||||
type = srec_decode(record, &binlen, &addr, binbuf);
|
type = srec_decode(record, &binlen, &addr, binbuf);
|
||||||
@ -172,7 +177,14 @@ static ulong load_serial(long offset)
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
ret = lmb_reserve(&lmb, store_addr, binlen);
|
||||||
|
if (ret) {
|
||||||
|
printf("\nCannot overwrite reserved area (%08lx..%08lx)\n",
|
||||||
|
store_addr, store_addr + binlen);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
memcpy((char *)(store_addr), binbuf, binlen);
|
memcpy((char *)(store_addr), binbuf, binlen);
|
||||||
|
lmb_free(&lmb, store_addr, binlen);
|
||||||
}
|
}
|
||||||
if ((store_addr) < start_addr)
|
if ((store_addr) < start_addr)
|
||||||
start_addr = store_addr;
|
start_addr = store_addr;
|
||||||
|
@ -174,6 +174,14 @@ __weak void spl_board_prepare_for_optee(void *fdt)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(OPTEE_IMAGE)
|
||||||
|
__weak void __noreturn jump_to_image_optee(struct spl_image_info *spl_image)
|
||||||
|
{
|
||||||
|
spl_optee_entry(NULL, NULL, spl_image->fdt_addr,
|
||||||
|
(void *)spl_image->entry_point);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
__weak void spl_board_prepare_for_boot(void)
|
__weak void spl_board_prepare_for_boot(void)
|
||||||
{
|
{
|
||||||
/* Nothing to do! */
|
/* Nothing to do! */
|
||||||
@ -780,8 +788,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
|
|||||||
case IH_OS_TEE:
|
case IH_OS_TEE:
|
||||||
debug("Jumping to U-Boot via OP-TEE\n");
|
debug("Jumping to U-Boot via OP-TEE\n");
|
||||||
spl_board_prepare_for_optee(spl_image.fdt_addr);
|
spl_board_prepare_for_optee(spl_image.fdt_addr);
|
||||||
spl_optee_entry(NULL, NULL, spl_image.fdt_addr,
|
jump_to_image_optee(&spl_image);
|
||||||
(void *)spl_image.entry_point);
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_IS_ENABLED(OPENSBI)
|
#if CONFIG_IS_ENABLED(OPENSBI)
|
||||||
|
@ -24,8 +24,18 @@ static int dfu_get_medium_size_sf(struct dfu_entity *dfu, u64 *size)
|
|||||||
static int dfu_read_medium_sf(struct dfu_entity *dfu, u64 offset, void *buf,
|
static int dfu_read_medium_sf(struct dfu_entity *dfu, u64 offset, void *buf,
|
||||||
long *len)
|
long *len)
|
||||||
{
|
{
|
||||||
return spi_flash_read(dfu->data.sf.dev, dfu->data.sf.start + offset,
|
long seglen = *len;
|
||||||
*len, buf);
|
int ret;
|
||||||
|
|
||||||
|
if (seglen > (16 << 20))
|
||||||
|
seglen = (16 << 20);
|
||||||
|
|
||||||
|
ret = spi_flash_read(dfu->data.sf.dev, dfu->data.sf.start + offset,
|
||||||
|
seglen, buf);
|
||||||
|
if (!ret)
|
||||||
|
*len = seglen;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u64 find_sector(struct dfu_entity *dfu, u64 start, u64 offset)
|
static u64 find_sector(struct dfu_entity *dfu, u64 start, u64 offset)
|
||||||
|
5
env/Kconfig
vendored
5
env/Kconfig
vendored
@ -200,6 +200,11 @@ config ENV_IS_IN_MMC
|
|||||||
This value may also be positive or negative; this is handled in the
|
This value may also be positive or negative; this is handled in the
|
||||||
same way as CONFIG_ENV_OFFSET.
|
same way as CONFIG_ENV_OFFSET.
|
||||||
|
|
||||||
|
In case CONFIG_SYS_MMC_ENV_PART is 1 (i.e. environment in eMMC boot
|
||||||
|
partition) then setting CONFIG_ENV_OFFSET_REDUND to the same value
|
||||||
|
as CONFIG_ENV_OFFSET makes use of the second eMMC boot partition for
|
||||||
|
the redundant environment copy.
|
||||||
|
|
||||||
This value is also in units of bytes, but must also be aligned to
|
This value is also in units of bytes, but must also be aligned to
|
||||||
an MMC sector boundary.
|
an MMC sector boundary.
|
||||||
|
|
||||||
|
61
env/mmc.c
vendored
61
env/mmc.c
vendored
@ -26,6 +26,18 @@
|
|||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In case the environment is redundant, stored in eMMC hardware boot
|
||||||
|
* partition and the environment and redundant environment offsets are
|
||||||
|
* identical, store the environment and redundant environment in both
|
||||||
|
* eMMC boot partitions, one copy in each.
|
||||||
|
* */
|
||||||
|
#if (defined(CONFIG_SYS_REDUNDAND_ENVIRONMENT) && \
|
||||||
|
(CONFIG_SYS_MMC_ENV_PART == 1) && \
|
||||||
|
(CONFIG_ENV_OFFSET == CONFIG_ENV_OFFSET_REDUND))
|
||||||
|
#define ENV_MMC_HWPART_REDUND
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(OF_CONTROL)
|
#if CONFIG_IS_ENABLED(OF_CONTROL)
|
||||||
static inline int mmc_offset_try_partition(const char *str, int copy, s64 *val)
|
static inline int mmc_offset_try_partition(const char *str, int copy, s64 *val)
|
||||||
{
|
{
|
||||||
@ -126,13 +138,11 @@ __weak uint mmc_get_env_part(struct mmc *mmc)
|
|||||||
|
|
||||||
static unsigned char env_mmc_orig_hwpart;
|
static unsigned char env_mmc_orig_hwpart;
|
||||||
|
|
||||||
static int mmc_set_env_part(struct mmc *mmc)
|
static int mmc_set_env_part(struct mmc *mmc, uint part)
|
||||||
{
|
{
|
||||||
uint part = mmc_get_env_part(mmc);
|
|
||||||
int dev = mmc_get_env_dev();
|
int dev = mmc_get_env_dev();
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
env_mmc_orig_hwpart = mmc_get_blk_desc(mmc)->hwpart;
|
|
||||||
ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part);
|
ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part);
|
||||||
if (ret)
|
if (ret)
|
||||||
puts("MMC partition switch failed\n");
|
puts("MMC partition switch failed\n");
|
||||||
@ -140,7 +150,7 @@ static int mmc_set_env_part(struct mmc *mmc)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline int mmc_set_env_part(struct mmc *mmc) {return 0; };
|
static inline int mmc_set_env_part(struct mmc *mmc, uint part) {return 0; };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char *init_mmc_for_env(struct mmc *mmc)
|
static const char *init_mmc_for_env(struct mmc *mmc)
|
||||||
@ -157,7 +167,8 @@ static const char *init_mmc_for_env(struct mmc *mmc)
|
|||||||
if (mmc_init(mmc))
|
if (mmc_init(mmc))
|
||||||
return "MMC init failed";
|
return "MMC init failed";
|
||||||
#endif
|
#endif
|
||||||
if (mmc_set_env_part(mmc))
|
env_mmc_orig_hwpart = mmc_get_blk_desc(mmc)->hwpart;
|
||||||
|
if (mmc_set_env_part(mmc, mmc_get_env_part(mmc)))
|
||||||
return "MMC partition switch failed";
|
return "MMC partition switch failed";
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -209,6 +220,13 @@ static int env_mmc_save(void)
|
|||||||
#ifdef CONFIG_ENV_OFFSET_REDUND
|
#ifdef CONFIG_ENV_OFFSET_REDUND
|
||||||
if (gd->env_valid == ENV_VALID)
|
if (gd->env_valid == ENV_VALID)
|
||||||
copy = 1;
|
copy = 1;
|
||||||
|
|
||||||
|
#ifdef ENV_MMC_HWPART_REDUND
|
||||||
|
ret = mmc_set_env_part(mmc, copy + 1);
|
||||||
|
if (ret)
|
||||||
|
goto fini;
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mmc_get_env_addr(mmc, copy, &offset)) {
|
if (mmc_get_env_addr(mmc, copy, &offset)) {
|
||||||
@ -263,20 +281,32 @@ static int env_mmc_erase(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mmc_get_env_addr(mmc, copy, &offset))
|
if (mmc_get_env_addr(mmc, copy, &offset)) {
|
||||||
return CMD_RET_FAILURE;
|
ret = CMD_RET_FAILURE;
|
||||||
|
goto fini;
|
||||||
|
}
|
||||||
|
|
||||||
ret = erase_env(mmc, CONFIG_ENV_SIZE, offset);
|
ret = erase_env(mmc, CONFIG_ENV_SIZE, offset);
|
||||||
|
|
||||||
#ifdef CONFIG_ENV_OFFSET_REDUND
|
#ifdef CONFIG_ENV_OFFSET_REDUND
|
||||||
copy = 1;
|
copy = 1;
|
||||||
|
|
||||||
if (mmc_get_env_addr(mmc, copy, &offset))
|
#ifdef ENV_MMC_HWPART_REDUND
|
||||||
return CMD_RET_FAILURE;
|
ret = mmc_set_env_part(mmc, copy + 1);
|
||||||
|
if (ret)
|
||||||
|
goto fini;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (mmc_get_env_addr(mmc, copy, &offset)) {
|
||||||
|
ret = CMD_RET_FAILURE;
|
||||||
|
goto fini;
|
||||||
|
}
|
||||||
|
|
||||||
ret |= erase_env(mmc, CONFIG_ENV_SIZE, offset);
|
ret |= erase_env(mmc, CONFIG_ENV_SIZE, offset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
fini:
|
||||||
|
fini_mmc_for_env(mmc);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_CMD_SAVEENV && !CONFIG_SPL_BUILD */
|
#endif /* CONFIG_CMD_SAVEENV && !CONFIG_SPL_BUILD */
|
||||||
@ -325,7 +355,20 @@ static int env_mmc_load(void)
|
|||||||
goto fini;
|
goto fini;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENV_MMC_HWPART_REDUND
|
||||||
|
ret = mmc_set_env_part(mmc, 1);
|
||||||
|
if (ret)
|
||||||
|
goto fini;
|
||||||
|
#endif
|
||||||
|
|
||||||
read1_fail = read_env(mmc, CONFIG_ENV_SIZE, offset1, tmp_env1);
|
read1_fail = read_env(mmc, CONFIG_ENV_SIZE, offset1, tmp_env1);
|
||||||
|
|
||||||
|
#ifdef ENV_MMC_HWPART_REDUND
|
||||||
|
ret = mmc_set_env_part(mmc, 2);
|
||||||
|
if (ret)
|
||||||
|
goto fini;
|
||||||
|
#endif
|
||||||
|
|
||||||
read2_fail = read_env(mmc, CONFIG_ENV_SIZE, offset2, tmp_env2);
|
read2_fail = read_env(mmc, CONFIG_ENV_SIZE, offset2, tmp_env2);
|
||||||
|
|
||||||
ret = env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
|
ret = env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
|
||||||
|
@ -468,6 +468,15 @@ int spl_board_boot_device(u32 boot_device);
|
|||||||
*/
|
*/
|
||||||
void __noreturn jump_to_image_linux(struct spl_image_info *spl_image);
|
void __noreturn jump_to_image_linux(struct spl_image_info *spl_image);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jump_to_image_linux() - Jump to OP-TEE OS from SPL
|
||||||
|
*
|
||||||
|
* This jumps into OP-TEE OS using the information in @spl_image.
|
||||||
|
*
|
||||||
|
* @spl_image: Image description to set up
|
||||||
|
*/
|
||||||
|
void __noreturn jump_to_image_optee(struct spl_image_info *spl_image);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* spl_start_uboot() - Check if SPL should start the kernel or U-Boot
|
* spl_start_uboot() - Check if SPL should start the kernel or U-Boot
|
||||||
*
|
*
|
||||||
@ -759,7 +768,7 @@ struct bl_params *bl2_plat_get_bl31_params_v2_default(uintptr_t bl32_entry,
|
|||||||
* @arg2: device tree address, (ARMv7 standard bootarg #2)
|
* @arg2: device tree address, (ARMv7 standard bootarg #2)
|
||||||
* @arg3: non-secure entry address (ARMv7 bootarg #0)
|
* @arg3: non-secure entry address (ARMv7 bootarg #0)
|
||||||
*/
|
*/
|
||||||
void spl_optee_entry(void *arg0, void *arg1, void *arg2, void *arg3);
|
void __noreturn spl_optee_entry(void *arg0, void *arg1, void *arg2, void *arg3);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* spl_invoke_opensbi - boot using a RISC-V OpenSBI image
|
* spl_invoke_opensbi - boot using a RISC-V OpenSBI image
|
||||||
|
Loading…
x
Reference in New Issue
Block a user