summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/bootm.c10
-rw-r--r--common/image-fit.c11
-rw-r--r--common/image.c94
-rw-r--r--common/spl/spl.c51
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);
}