mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-25 12:33:41 +00:00
1e94b46f73
This old patch was marked as deferred. Bring it back to life, to continue towards the removal of common.h Move this out of the common header and include it only where needed. Signed-off-by: Simon Glass <sjg@chromium.org>
191 lines
4.3 KiB
C
191 lines
4.3 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 <linux/printk.h>
|
|
#include "stm32prog.h"
|
|
|
|
struct stm32prog_data *stm32prog_data;
|
|
|
|
static void enable_vidconsole(void)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
|
|
static int do_stm32prog(struct cmd_tbl *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;
|
|
|
|
if (argc < 3 || argc > 5)
|
|
return CMD_RET_USAGE;
|
|
|
|
if (IS_ENABLED(CONFIG_CMD_STM32PROG_USB) && !strcmp(argv[1], "usb"))
|
|
link = LINK_USB;
|
|
else if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL) && !strcmp(argv[1], "serial"))
|
|
link = LINK_SERIAL;
|
|
|
|
if (link == LINK_UNDEFINED) {
|
|
log_err("not supported link=%s\n", argv[1]);
|
|
return CMD_RET_USAGE;
|
|
}
|
|
|
|
dev = (int)dectoul(argv[2], NULL);
|
|
|
|
addr = CONFIG_SYS_LOAD_ADDR;
|
|
size = 0;
|
|
if (argc > 3) {
|
|
addr = hextoul(argv[3], NULL);
|
|
if (!addr)
|
|
return CMD_RET_FAILURE;
|
|
}
|
|
if (argc > 4)
|
|
size = hextoul(argv[4], NULL);
|
|
|
|
/* check STM32IMAGE presence */
|
|
if (size == 0) {
|
|
stm32prog_header_check(addr, &header);
|
|
if (header.type == HEADER_STM32IMAGE) {
|
|
size = header.image_length + header.length;
|
|
}
|
|
}
|
|
|
|
if (IS_ENABLED(CONFIG_VIDEO))
|
|
enable_vidconsole();
|
|
|
|
data = (struct stm32prog_data *)malloc(sizeof(*data));
|
|
|
|
if (!data) {
|
|
log_err("Alloc failed.");
|
|
return CMD_RET_FAILURE;
|
|
}
|
|
stm32prog_data = data;
|
|
|
|
ret = stm32prog_init(data, addr, size);
|
|
if (ret)
|
|
log_debug("Invalid or missing layout file at 0x%lx.\n", addr);
|
|
|
|
/* 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;
|
|
}
|
|
|
|
stm32prog_clean(data);
|
|
free(stm32prog_data);
|
|
stm32prog_data = NULL;
|
|
|
|
puts("Download done\n");
|
|
|
|
if (data->uimage) {
|
|
char boot_addr_start[20];
|
|
char dtb_addr[20];
|
|
char initrd_addr[40];
|
|
char *bootm_argv[5] = {
|
|
"bootm", boot_addr_start, "-", dtb_addr, NULL
|
|
};
|
|
const void *uimage = (void *)data->uimage;
|
|
const void *dtb = (void *)data->dtb;
|
|
const void *initrd = (void *)data->initrd;
|
|
|
|
if (!dtb)
|
|
bootm_argv[3] = env_get("fdtcontroladdr");
|
|
else
|
|
snprintf(dtb_addr, sizeof(dtb_addr) - 1,
|
|
"0x%p", dtb);
|
|
|
|
snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
|
|
"0x%p", uimage);
|
|
|
|
if (initrd) {
|
|
snprintf(initrd_addr, sizeof(initrd_addr) - 1, "0x%p:0x%zx",
|
|
initrd, data->initrd_size);
|
|
bootm_argv[2] = initrd_addr;
|
|
}
|
|
|
|
printf("Booting kernel at %s %s %s...\n\n\n",
|
|
boot_addr_start, bootm_argv[2], bootm_argv[3]);
|
|
/* Try bootm for legacy and FIT format image */
|
|
if (genimg_get_format(uimage) != IMAGE_FORMAT_INVALID)
|
|
do_bootm(cmdtp, 0, 4, bootm_argv);
|
|
else if (IS_ENABLED(CONFIG_CMD_BOOTZ))
|
|
do_bootz(cmdtp, 0, 4, bootm_argv);
|
|
}
|
|
if (data->script)
|
|
cmd_source_script(data->script, NULL, NULL);
|
|
|
|
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,
|
|
"start communication with tools STM32Cubeprogrammer",
|
|
"<link> <dev> [<addr>] [<size>]\n"
|
|
" <link> = serial|usb\n"
|
|
" <dev> = device instance\n"
|
|
" <addr> = address of flashlayout\n"
|
|
" <size> = size of flashlayout (optional for image with STM32 header)\n"
|
|
);
|
|
|
|
|
|
bool stm32prog_get_fsbl_nor(void)
|
|
{
|
|
if (stm32prog_data)
|
|
return stm32prog_data->fsbl_nor_detected;
|
|
|
|
return false;
|
|
}
|