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:
Tom Rini 2021-10-26 09:31:48 -04:00
commit 75e33b378b
7 changed files with 111 additions and 14 deletions

View File

@ -77,3 +77,14 @@ void __noreturn jump_to_image_linux(struct spl_image_info *spl_image)
}
#endif /* CONFIG_ARM64 */
#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

View File

@ -16,6 +16,7 @@
#include <exports.h>
#include <flash.h>
#include <image.h>
#include <lmb.h>
#include <mapmem.h>
#include <net.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)
{
struct lmb lmb;
char record[SREC_MAXRECLEN + 1]; /* buffer for one S-Record */
char binbuf[SREC_MAXBINLEN]; /* buffer for binary data */
int binlen; /* no. of data bytes in S-Rec. */
@ -147,6 +149,9 @@ static ulong load_serial(long offset)
ulong start_addr = ~0;
ulong end_addr = 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) {
type = srec_decode(record, &binlen, &addr, binbuf);
@ -172,7 +177,14 @@ static ulong load_serial(long offset)
} else
#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);
lmb_free(&lmb, store_addr, binlen);
}
if ((store_addr) < start_addr)
start_addr = store_addr;

View File

@ -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)
{
/* Nothing to do! */
@ -780,8 +788,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
case IH_OS_TEE:
debug("Jumping to U-Boot via OP-TEE\n");
spl_board_prepare_for_optee(spl_image.fdt_addr);
spl_optee_entry(NULL, NULL, spl_image.fdt_addr,
(void *)spl_image.entry_point);
jump_to_image_optee(&spl_image);
break;
#endif
#if CONFIG_IS_ENABLED(OPENSBI)

View File

@ -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,
long *len)
{
return spi_flash_read(dfu->data.sf.dev, dfu->data.sf.start + offset,
*len, buf);
long seglen = *len;
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)

5
env/Kconfig vendored
View File

@ -200,6 +200,11 @@ config ENV_IS_IN_MMC
This value may also be positive or negative; this is handled in the
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
an MMC sector boundary.

61
env/mmc.c vendored
View File

@ -26,6 +26,18 @@
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)
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 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 ret = 0;
env_mmc_orig_hwpart = mmc_get_blk_desc(mmc)->hwpart;
ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part);
if (ret)
puts("MMC partition switch failed\n");
@ -140,7 +150,7 @@ static int mmc_set_env_part(struct mmc *mmc)
return ret;
}
#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
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))
return "MMC init failed";
#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 NULL;
@ -209,6 +220,13 @@ static int env_mmc_save(void)
#ifdef CONFIG_ENV_OFFSET_REDUND
if (gd->env_valid == ENV_VALID)
copy = 1;
#ifdef ENV_MMC_HWPART_REDUND
ret = mmc_set_env_part(mmc, copy + 1);
if (ret)
goto fini;
#endif
#endif
if (mmc_get_env_addr(mmc, copy, &offset)) {
@ -263,20 +281,32 @@ static int env_mmc_erase(void)
return 1;
}
if (mmc_get_env_addr(mmc, copy, &offset))
return CMD_RET_FAILURE;
if (mmc_get_env_addr(mmc, copy, &offset)) {
ret = CMD_RET_FAILURE;
goto fini;
}
ret = erase_env(mmc, CONFIG_ENV_SIZE, offset);
#ifdef CONFIG_ENV_OFFSET_REDUND
copy = 1;
if (mmc_get_env_addr(mmc, copy, &offset))
return CMD_RET_FAILURE;
#ifdef ENV_MMC_HWPART_REDUND
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);
#endif
fini:
fini_mmc_for_env(mmc);
return ret;
}
#endif /* CONFIG_CMD_SAVEENV && !CONFIG_SPL_BUILD */
@ -325,7 +355,20 @@ static int env_mmc_load(void)
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);
#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);
ret = env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,

View File

@ -468,6 +468,15 @@ int spl_board_boot_device(u32 boot_device);
*/
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
*
@ -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)
* @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