u-boot/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
Patrick Delaunay 306a5cf24f stm32mp: stm32prog: add support of RAM target
Add support of RAM target in flashlayout to load kernel image
("system") and device tree ("filesystem") in DDR with DFU and
start these images.

The flashlayout.tsv is:

-	0x01	fsbl		Binary		none	0x00000000	tf-a.stm32
-	0x03	ssbl		Binary		none	0x00000000	u-boot.stm32
P	0x10	kernel		System		ram0	0xC2000000	uImage.bin
P	0x11	dtb		FileSystem	ram0	0xC4000000	dtb.bin

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Reviewed-by: Patrice Chotard <patrice.chotard@st.com>
2020-05-14 09:02:12 +02:00

192 lines
4.2 KiB
C

// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
* Copyright (C) 2020, STMicroelectronics - All Rights Reserved
*/
#include <common.h>
#include <command.h>
#include <dfu.h>
#include <image.h>
#include <asm/arch/stm32prog.h>
#include "stm32prog.h"
struct stm32prog_data *stm32prog_data;
static void enable_vidconsole(void)
{
#ifdef CONFIG_DM_VIDEO
char *stdname;
char buf[64];
stdname = env_get("stdout");
if (!stdname || !strstr(stdname, "vidconsole")) {
if (!stdname)
snprintf(buf, sizeof(buf), "serial,vidconsole");
else
snprintf(buf, sizeof(buf), "%s,vidconsole", stdname);
env_set("stdout", buf);
}
stdname = env_get("stderr");
if (!stdname || !strstr(stdname, "vidconsole")) {
if (!stdname)
snprintf(buf, sizeof(buf), "serial,vidconsole");
else
snprintf(buf, sizeof(buf), "%s,vidconsole", stdname);
env_set("stderr", buf);
}
#endif
}
static int do_stm32prog(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
ulong addr, size;
int dev, ret;
enum stm32prog_link_t link = LINK_UNDEFINED;
bool reset = false;
struct image_header_s header;
struct stm32prog_data *data;
u32 uimage, dtb;
if (argc < 3 || argc > 5)
return CMD_RET_USAGE;
if (!strcmp(argv[1], "usb"))
link = LINK_USB;
else if (!strcmp(argv[1], "serial"))
link = LINK_SERIAL;
if (link == LINK_UNDEFINED) {
pr_err("not supported link=%s\n", argv[1]);
return CMD_RET_USAGE;
}
dev = (int)simple_strtoul(argv[2], NULL, 10);
addr = STM32_DDR_BASE;
size = 0;
if (argc > 3) {
addr = simple_strtoul(argv[3], NULL, 16);
if (!addr)
return CMD_RET_FAILURE;
}
if (argc > 4)
size = simple_strtoul(argv[4], NULL, 16);
/* check STM32IMAGE presence */
if (size == 0 &&
!stm32prog_header_check((struct raw_header_s *)addr, &header)) {
size = header.image_length + BL_HEADER_SIZE;
/* uImage detected in STM32IMAGE, execute the script */
if (IMAGE_FORMAT_LEGACY ==
genimg_get_format((void *)(addr + BL_HEADER_SIZE)))
return image_source_script(addr + BL_HEADER_SIZE,
"script@1");
}
enable_vidconsole();
data = (struct stm32prog_data *)malloc(sizeof(*data));
if (!data) {
pr_err("Alloc failed.");
return CMD_RET_FAILURE;
}
stm32prog_data = data;
ret = stm32prog_init(data, addr, size);
if (ret)
printf("Invalid or missing layout file.");
/* prepare DFU for device read/write */
ret = stm32prog_dfu_init(data);
if (ret)
goto cleanup;
switch (link) {
case LINK_SERIAL:
ret = stm32prog_serial_init(data, dev);
if (ret)
goto cleanup;
reset = stm32prog_serial_loop(data);
break;
case LINK_USB:
reset = stm32prog_usb_loop(data, dev);
break;
default:
goto cleanup;
}
uimage = data->uimage;
dtb = data->dtb;
stm32prog_clean(data);
free(stm32prog_data);
stm32prog_data = NULL;
puts("Download done\n");
if (uimage) {
char boot_addr_start[20];
char dtb_addr[20];
char *bootm_argv[5] = {
"bootm", boot_addr_start, "-", dtb_addr, NULL
};
if (!dtb)
bootm_argv[3] = env_get("fdtcontroladdr");
else
snprintf(dtb_addr, sizeof(dtb_addr) - 1,
"0x%x", dtb);
snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
"0x%x", uimage);
printf("Booting kernel at %s - %s...\n\n\n",
boot_addr_start, bootm_argv[3]);
/* Try bootm for legacy and FIT format image */
if (genimg_get_format((void *)uimage) != IMAGE_FORMAT_INVALID)
do_bootm(cmdtp, 0, 4, bootm_argv);
else if CONFIG_IS_ENABLED(CMD_BOOTZ)
do_bootz(cmdtp, 0, 4, bootm_argv);
}
if (reset) {
puts("Reset...\n");
run_command("reset", 0);
}
return CMD_RET_SUCCESS;
cleanup:
stm32prog_clean(data);
free(stm32prog_data);
stm32prog_data = NULL;
return CMD_RET_FAILURE;
}
U_BOOT_CMD(stm32prog, 5, 0, do_stm32prog,
"<link> <dev> [<addr>] [<size>]\n"
"start communication with tools STM32Cubeprogrammer on <link> with Flashlayout at <addr>",
"<link> = serial|usb\n"
"<dev> = device instance\n"
"<addr> = address of flashlayout\n"
"<size> = size of flashlayout\n"
);
bool stm32prog_get_tee_partitions(void)
{
if (stm32prog_data)
return stm32prog_data->tee_detected;
return false;
}
bool stm32prog_get_fsbl_nor(void)
{
if (stm32prog_data)
return stm32prog_data->fsbl_nor_detected;
return false;
}