diff --git a/app/zynq-common/init.c b/app/zynq-common/init.c index 077765e2..e2d4b7d3 100644 --- a/app/zynq-common/init.c +++ b/app/zynq-common/init.c @@ -22,22 +22,31 @@ */ #include #include +#include +#include #include -#include +#include +#include #include #include -#include +#include +#include #include +#include + +#if WITH_LIB_MINIP #include +#endif static void zybo_common_target_init(uint level) { + status_t err; + /* zybo has a spiflash on qspi */ spiflash_detect(); bdev_t *spi = bio_open("spi0"); - if (spi) { /* find or create a partition table at the start of flash */ if (ptable_scan(spi, 0) < 0) { @@ -46,18 +55,13 @@ static void zybo_common_target_init(uint level) struct ptable_entry entry = { 0 }; + /* find and recover sysparams */ if (ptable_find("sysparam", &entry) < 0) { /* didn't find sysparam partition, create it */ ptable_add("sysparam", 0x1000, 0x1000, 0); ptable_find("sysparam", &entry); } - /* create bootloader partition if it does not exist */ - ptable_add("bootloader", 0x20000, 0x40000, 0); - - printf("flash partition table:\n"); - ptable_dump(); - if (entry.length > 0) { sysparam_scan(spi, entry.offset, entry.length); @@ -70,8 +74,55 @@ static void zybo_common_target_init(uint level) sysparam_dump(true); } + + /* create bootloader partition if it does not exist */ + ptable_add("bootloader", 0x20000, 0x40000, 0); + + printf("flash partition table:\n"); + ptable_dump(); } + /* recover boot arguments */ + const char *cmdline = bootargs_get_command_line(); + if (cmdline) { + printf("command line: '%s'\n", cmdline); + } + + /* see if we came from a bootimage */ + uintptr_t bootimage_phys; + size_t bootimage_size; + if (bootargs_get_bootimage_pointer(&bootimage_phys, &bootimage_size) >= 0) { + printf("our bootimage is at phys 0x%lx, size %zx\n", bootimage_phys, bootimage_size); + + void *ptr = paddr_to_kvaddr(bootimage_phys); + if (ptr) { + bootimage_t *bi; + if (bootimage_open(ptr, bootimage_size, &bi) >= 0) { + /* we have a valid bootimage, find the fpga section */ + const void *fpga_ptr; + size_t fpga_len; + + if (bootimage_get_file_section(bi, TYPE_FPGA_IMAGE, &fpga_ptr, &fpga_len) >= 0) { + /* we have a fpga image */ + + /* lookup the physical address of the bitfile */ + paddr_t pa = kvaddr_to_paddr((void *)fpga_ptr); + if (pa != 0) { + /* program the fpga with it*/ + printf("loading fpga image at %p (phys 0x%lx), len %zx\n", fpga_ptr, pa, fpga_len); + zynq_reset_fpga(); + err = zynq_program_fpga(pa, fpga_len); + if (err < 0) { + printf("error %d loading fpga\n", err); + } + printf("fpga image loaded\n"); + } + } + } + } + } + +#if WITH_LIB_MINIP /* pull some network stack related params out of the sysparam block */ uint8_t mac_addr[6]; uint32_t ip_addr = IPV4_NONE; @@ -105,6 +156,7 @@ static void zybo_common_target_init(uint level) minip_init_dhcp(gem_send_raw_pkt, NULL); } gem_set_callback(minip_rx_driver_callback); +#endif } /* init after target_init() */ diff --git a/app/zynq-common/rules.mk b/app/zynq-common/rules.mk index 73edb904..f40f537a 100644 --- a/app/zynq-common/rules.mk +++ b/app/zynq-common/rules.mk @@ -3,6 +3,8 @@ LOCAL_DIR := $(GET_LOCAL_DIR) MODULE := $(LOCAL_DIR) MODULE_DEPS += \ + lib/bootargs \ + lib/bootimage \ lib/minip \ lib/sysparam \ lib/ptable