diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/bootm.c | 10 | ||||
-rw-r--r-- | common/image-fit.c | 11 | ||||
-rw-r--r-- | common/image.c | 94 | ||||
-rw-r--r-- | common/spl/spl.c | 51 |
4 files changed, 155 insertions, 11 deletions
diff --git a/common/bootm.c b/common/bootm.c index c965326..4941414 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -246,6 +246,16 @@ int bootm_find_images(int flag, int argc, char * const argv[]) #endif #if IMAGE_ENABLE_FIT +#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_XILINX) + /* find bitstreams */ + ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT, + NULL, NULL); + if (ret) { + printf("FPGA image is corrupted or invalid\n"); + return 1; + } +#endif + /* find all of the loadables */ ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT, NULL, NULL); diff --git a/common/image-fit.c b/common/image-fit.c index c86b7c6..9873957 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -422,7 +422,8 @@ void fit_image_print(const void *fit, int image_noffset, const char *p) } if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || - (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK)) { + (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK) || + (type == IH_TYPE_FPGA)) { ret = fit_image_get_load(fit, image_noffset, &load); printf("%s Load Address: ", p); if (ret) @@ -1483,6 +1484,10 @@ void fit_conf_print(const void *fit, int noffset, const char *p) if (uname) printf("%s FDT: %s\n", p, uname); + uname = (char *)fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL); + if (uname) + printf("%s FPGA: %s\n", p, uname); + /* Print out all of the specified loadables */ for (loadables_index = 0; fdt_get_string_index(fit, noffset, @@ -1567,6 +1572,8 @@ static const char *fit_get_image_type_property(int type) return FIT_SETUP_PROP; case IH_TYPE_LOADABLE: return FIT_LOADABLE_PROP; + case IH_TYPE_FPGA: + return FIT_FPGA_PROP; } return "unknown"; @@ -1681,7 +1688,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr, fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD)); - os_ok = image_type == IH_TYPE_FLATDT || + os_ok = image_type == IH_TYPE_FLATDT || IH_TYPE_FPGA || fit_image_check_os(fit, noffset, IH_OS_LINUX) || fit_image_check_os(fit, noffset, IH_OS_OPENRTOS); diff --git a/common/image.c b/common/image.c index 26d6c9a..0be09e5 100644 --- a/common/image.c +++ b/common/image.c @@ -32,6 +32,8 @@ #if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT #include <libfdt.h> #include <fdt_support.h> +#include <fpga.h> +#include <xilinx.h> #endif #include <u-boot/md5.h> @@ -159,6 +161,8 @@ static const table_entry_t uimage_type[] = { { IH_TYPE_RKSD, "rksd", "Rockchip SD Boot Image" }, { IH_TYPE_RKSPI, "rkspi", "Rockchip SPI Boot Image" }, { IH_TYPE_ZYNQIMAGE, "zynqimage", "Xilinx Zynq Boot Image" }, + { IH_TYPE_ZYNQMPIMAGE, "zynqmpimage", "Xilinx ZynqMP Boot Image" }, + { IH_TYPE_FPGA, "fpga", "FPGA Image" }, { -1, "", "", }, }; @@ -1210,6 +1214,96 @@ int boot_get_setup(bootm_headers_t *images, uint8_t arch, } #if IMAGE_ENABLE_FIT +#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_XILINX) +int boot_get_fpga(int argc, char * const argv[], bootm_headers_t *images, + uint8_t arch, const ulong *ld_start, ulong * const ld_len) +{ + ulong tmp_img_addr, img_data, img_len; + void *buf; + int conf_noffset; + int fit_img_result; + char *uname, *name; + int err; + int devnum = 0; /* TODO support multi fpga platforms */ + const fpga_desc * const desc = fpga_get_desc(devnum); + xilinx_desc *desc_xilinx = desc->devdesc; + + /* Check to see if the images struct has a FIT configuration */ + if (!genimg_has_config(images)) { + debug("## FIT configuration was not specified\n"); + return 0; + } + + /* + * Obtain the os FIT header from the images struct + * copy from dataflash if needed + */ + tmp_img_addr = map_to_sysmem(images->fit_hdr_os); + tmp_img_addr = genimg_get_image(tmp_img_addr); + buf = map_sysmem(tmp_img_addr, 0); + /* + * Check image type. For FIT images get FIT node + * and attempt to locate a generic binary. + */ + switch (genimg_get_format(buf)) { + case IMAGE_FORMAT_FIT: + conf_noffset = fit_conf_get_node(buf, images->fit_uname_cfg); + + err = fdt_get_string_index(buf, conf_noffset, FIT_FPGA_PROP, 0, + (const char **)&uname); + if (err < 0) { + debug("## FPGA image is not specified\n"); + return 0; + } + fit_img_result = fit_image_load(images, + tmp_img_addr, + (const char **)&uname, + &(images->fit_uname_cfg), + arch, + IH_TYPE_FPGA, + BOOTSTAGE_ID_FPGA_INIT, + FIT_LOAD_OPTIONAL_NON_ZERO, + &img_data, &img_len); + + debug("FPGA image (%s) loaded to 0x%lx/size 0x%lx\n", + uname, img_data, img_len); + + if (fit_img_result < 0) { + /* Something went wrong! */ + return fit_img_result; + } + + if (img_len >= desc_xilinx->size) { + name = "full"; + err = fpga_loadbitstream(devnum, (char *)img_data, + img_len, BIT_FULL); + if (err) + err = fpga_load(devnum, (const void *)img_data, + img_len, BIT_FULL); + } else { + name = "partial"; + err = fpga_loadbitstream(devnum, (char *)img_data, + img_len, BIT_PARTIAL); + if (err) + err = fpga_load(devnum, (const void *)img_data, + img_len, BIT_PARTIAL); + } + + printf(" Programming %s bitstream... ", name); + if (err) + printf("failed\n"); + else + printf("OK\n"); + break; + default: + printf("The given image format is not supported (corrupt?)\n"); + return 1; + } + + return 0; +} +#endif + int boot_get_loadable(int argc, char * const argv[], bootm_headers_t *images, uint8_t arch, const ulong *ld_start, ulong * const ld_len) { diff --git a/common/spl/spl.c b/common/spl/spl.c index 93f9bd1..bdde716 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -64,6 +64,11 @@ __weak void spl_board_prepare_for_linux(void) /* Nothing to do! */ } +__weak void spl_board_prepare_for_boot(void) +{ + /* Nothing to do! */ +} + void spl_set_header_raw_uboot(void) { spl_image.size = CONFIG_SYS_MONITOR_LEN; @@ -135,20 +140,47 @@ __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) image_entry(); } +#ifndef CONFIG_SPL_LOAD_FIT_ADDRESS +# define CONFIG_SPL_LOAD_FIT_ADDRESS 0 +#endif + #ifdef CONFIG_SPL_RAM_DEVICE +static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector, + ulong count, void *buf) +{ + debug("%s: sector %lx, count %lx, buf %lx\n", + __func__, sector, count, (ulong)buf); + memcpy(buf, (void *)(CONFIG_SPL_LOAD_FIT_ADDRESS + sector), count); + return count; +} + static int spl_ram_load_image(void) { - const struct image_header *header; + struct image_header *header; - /* - * Get the header. It will point to an address defined by handoff - * which will tell where the image located inside the flash. For - * now, it will temporary fixed to address pointed by U-Boot. - */ - header = (struct image_header *) - (CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); + header = (struct image_header *)CONFIG_SPL_LOAD_FIT_ADDRESS; + + if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && + image_get_magic(header) == FDT_MAGIC) { + struct spl_load_info load; + + debug("Found FIT\n"); + load.bl_len = 1; + load.read = spl_ram_load_read; + spl_load_simple_fit(&load, 0, header); + } else { + debug("Legacy image\n"); + /* + * Get the header. It will point to an address defined by + * handoff which will tell where the image located inside + * the flash. For now, it will temporary fixed to address + * pointed by U-Boot. + */ + header = (struct image_header *) + (CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); - spl_parse_image_header(header); + spl_parse_image_header(header); + } return 0; } @@ -404,6 +436,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) #endif debug("loaded - jumping to U-Boot..."); + spl_board_prepare_for_boot(); jump_to_image_no_args(&spl_image); } |