183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
22e192b24SSimon Glass /*
32e192b24SSimon Glass * (C) Copyright 2000, 2001
42e192b24SSimon Glass * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
52e192b24SSimon Glass */
62e192b24SSimon Glass
72e192b24SSimon Glass /*
82e192b24SSimon Glass * FPGA support
92e192b24SSimon Glass */
102e192b24SSimon Glass #include <common.h>
112e192b24SSimon Glass #include <command.h>
122e192b24SSimon Glass #include <fpga.h>
132e192b24SSimon Glass #include <fs.h>
142e192b24SSimon Glass #include <malloc.h>
152e192b24SSimon Glass
do_fpga_get_device(char * arg)16f4c7a4aeSMichal Simek static long do_fpga_get_device(char *arg)
17f4c7a4aeSMichal Simek {
18f4c7a4aeSMichal Simek long dev = FPGA_INVALID_DEVICE;
19f4c7a4aeSMichal Simek char *devstr = env_get("fpga");
20f4c7a4aeSMichal Simek
21f4c7a4aeSMichal Simek if (devstr)
22f4c7a4aeSMichal Simek /* Should be strtol to handle -1 cases */
23f4c7a4aeSMichal Simek dev = simple_strtol(devstr, NULL, 16);
24f4c7a4aeSMichal Simek
258c75f794SMichal Simek if (dev == FPGA_INVALID_DEVICE && arg)
26f4c7a4aeSMichal Simek dev = simple_strtol(arg, NULL, 16);
27f4c7a4aeSMichal Simek
28f4c7a4aeSMichal Simek debug("%s: device = %ld\n", __func__, dev);
29f4c7a4aeSMichal Simek
30f4c7a4aeSMichal Simek return dev;
31f4c7a4aeSMichal Simek }
32f4c7a4aeSMichal Simek
do_fpga_check_params(long * dev,long * fpga_data,size_t * data_size,cmd_tbl_t * cmdtp,int argc,char * const argv[])3385754795SMichal Simek static int do_fpga_check_params(long *dev, long *fpga_data, size_t *data_size,
3485754795SMichal Simek cmd_tbl_t *cmdtp, int argc, char *const argv[])
3585754795SMichal Simek {
3685754795SMichal Simek size_t local_data_size;
3785754795SMichal Simek long local_fpga_data;
3885754795SMichal Simek
3985754795SMichal Simek debug("%s %d, %d\n", __func__, argc, cmdtp->maxargs);
4085754795SMichal Simek
4185754795SMichal Simek if (argc != cmdtp->maxargs) {
4285754795SMichal Simek debug("fpga: incorrect parameters passed\n");
4385754795SMichal Simek return CMD_RET_USAGE;
4485754795SMichal Simek }
4585754795SMichal Simek
4685754795SMichal Simek *dev = do_fpga_get_device(argv[0]);
4785754795SMichal Simek
4885754795SMichal Simek local_fpga_data = simple_strtol(argv[1], NULL, 16);
4985754795SMichal Simek if (!local_fpga_data) {
5085754795SMichal Simek debug("fpga: zero fpga_data address\n");
5185754795SMichal Simek return CMD_RET_USAGE;
5285754795SMichal Simek }
5385754795SMichal Simek *fpga_data = local_fpga_data;
5485754795SMichal Simek
5585754795SMichal Simek local_data_size = simple_strtoul(argv[2], NULL, 16);
5685754795SMichal Simek if (!local_data_size) {
5785754795SMichal Simek debug("fpga: zero size\n");
5885754795SMichal Simek return CMD_RET_USAGE;
5985754795SMichal Simek }
6085754795SMichal Simek *data_size = local_data_size;
6185754795SMichal Simek
6285754795SMichal Simek return 0;
6385754795SMichal Simek }
6485754795SMichal Simek
65323fe38eSMichal Simek #if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
do_fpga_loads(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])66*b5d19a93SMichal Simek int do_fpga_loads(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
672e192b24SSimon Glass {
682e192b24SSimon Glass size_t data_size = 0;
69*b5d19a93SMichal Simek long fpga_data, dev;
70*b5d19a93SMichal Simek int ret;
71cedd48e2SSiva Durga Prasad Paladugu struct fpga_secure_info fpga_sec_info;
72cedd48e2SSiva Durga Prasad Paladugu
73cedd48e2SSiva Durga Prasad Paladugu memset(&fpga_sec_info, 0, sizeof(fpga_sec_info));
742e192b24SSimon Glass
75*b5d19a93SMichal Simek if (argc < 5) {
76*b5d19a93SMichal Simek debug("fpga: incorrect parameters passed\n");
77f5953610SSiva Durga Prasad Paladugu return CMD_RET_USAGE;
78f5953610SSiva Durga Prasad Paladugu }
79f5953610SSiva Durga Prasad Paladugu
80*b5d19a93SMichal Simek if (argc == 6)
81cedd48e2SSiva Durga Prasad Paladugu fpga_sec_info.userkey_addr = (u8 *)(uintptr_t)
82*b5d19a93SMichal Simek simple_strtoull(argv[5],
83cedd48e2SSiva Durga Prasad Paladugu NULL, 16);
84*b5d19a93SMichal Simek else
85*b5d19a93SMichal Simek /*
86*b5d19a93SMichal Simek * If 6th parameter is not passed then do_fpga_check_params
87*b5d19a93SMichal Simek * will get 5 instead of expected 6 which means that function
88*b5d19a93SMichal Simek * return CMD_RET_USAGE. Increase number of params +1 to pass
89*b5d19a93SMichal Simek * this.
90*b5d19a93SMichal Simek */
91*b5d19a93SMichal Simek argc++;
92*b5d19a93SMichal Simek
93*b5d19a93SMichal Simek fpga_sec_info.encflag = (u8)simple_strtoul(argv[4], NULL, 16);
94*b5d19a93SMichal Simek fpga_sec_info.authflag = (u8)simple_strtoul(argv[3], NULL, 16);
9544d839bdSMichal Simek
9644d839bdSMichal Simek if (fpga_sec_info.authflag >= FPGA_NO_ENC_OR_NO_AUTH &&
9744d839bdSMichal Simek fpga_sec_info.encflag >= FPGA_NO_ENC_OR_NO_AUTH) {
98*b5d19a93SMichal Simek debug("fpga: Use <fpga load> for NonSecure bitstream\n");
9944d839bdSMichal Simek return CMD_RET_USAGE;
10044d839bdSMichal Simek }
10144d839bdSMichal Simek
10244d839bdSMichal Simek if (fpga_sec_info.encflag == FPGA_ENC_USR_KEY &&
10344d839bdSMichal Simek !fpga_sec_info.userkey_addr) {
104*b5d19a93SMichal Simek debug("fpga: User key not provided\n");
10544d839bdSMichal Simek return CMD_RET_USAGE;
10644d839bdSMichal Simek }
10744d839bdSMichal Simek
108*b5d19a93SMichal Simek ret = do_fpga_check_params(&dev, &fpga_data, &data_size,
109*b5d19a93SMichal Simek cmdtp, argc, argv);
110*b5d19a93SMichal Simek if (ret)
111*b5d19a93SMichal Simek return ret;
112*b5d19a93SMichal Simek
113*b5d19a93SMichal Simek return fpga_loads(dev, (void *)fpga_data, data_size, &fpga_sec_info);
114*b5d19a93SMichal Simek }
115cedd48e2SSiva Durga Prasad Paladugu #endif
1162e192b24SSimon Glass
11749503f9aSMichal Simek #if defined(CONFIG_CMD_FPGA_LOADFS)
do_fpga_loadfs(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])11849503f9aSMichal Simek static int do_fpga_loadfs(cmd_tbl_t *cmdtp, int flag, int argc,
11949503f9aSMichal Simek char *const argv[])
12049503f9aSMichal Simek {
12149503f9aSMichal Simek size_t data_size = 0;
12249503f9aSMichal Simek long fpga_data, dev;
12349503f9aSMichal Simek int ret;
12449503f9aSMichal Simek fpga_fs_info fpga_fsinfo;
12549503f9aSMichal Simek
12649503f9aSMichal Simek ret = do_fpga_check_params(&dev, &fpga_data, &data_size,
12749503f9aSMichal Simek cmdtp, argc, argv);
12849503f9aSMichal Simek if (ret)
12949503f9aSMichal Simek return ret;
13049503f9aSMichal Simek
13149503f9aSMichal Simek fpga_fsinfo.fstype = FS_TYPE_ANY;
13249503f9aSMichal Simek fpga_fsinfo.blocksize = (unsigned int)simple_strtoul(argv[3], NULL, 16);
13349503f9aSMichal Simek fpga_fsinfo.interface = argv[4];
13449503f9aSMichal Simek fpga_fsinfo.dev_part = argv[5];
13549503f9aSMichal Simek fpga_fsinfo.filename = argv[6];
13649503f9aSMichal Simek
13749503f9aSMichal Simek return fpga_fsload(dev, (void *)fpga_data, data_size, &fpga_fsinfo);
13849503f9aSMichal Simek }
13949503f9aSMichal Simek #endif
14049503f9aSMichal Simek
do_fpga_info(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])141f4c7a4aeSMichal Simek static int do_fpga_info(cmd_tbl_t *cmdtp, int flag, int argc,
142f4c7a4aeSMichal Simek char * const argv[])
143f4c7a4aeSMichal Simek {
144f4c7a4aeSMichal Simek long dev = do_fpga_get_device(argv[0]);
145f4c7a4aeSMichal Simek
146f4c7a4aeSMichal Simek return fpga_info(dev);
147f4c7a4aeSMichal Simek }
148f4c7a4aeSMichal Simek
do_fpga_dump(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])14985754795SMichal Simek static int do_fpga_dump(cmd_tbl_t *cmdtp, int flag, int argc,
15085754795SMichal Simek char * const argv[])
15185754795SMichal Simek {
15285754795SMichal Simek size_t data_size = 0;
15385754795SMichal Simek long fpga_data, dev;
15485754795SMichal Simek int ret;
15585754795SMichal Simek
15685754795SMichal Simek ret = do_fpga_check_params(&dev, &fpga_data, &data_size,
15785754795SMichal Simek cmdtp, argc, argv);
15885754795SMichal Simek if (ret)
15985754795SMichal Simek return ret;
16085754795SMichal Simek
16185754795SMichal Simek return fpga_dump(dev, (void *)fpga_data, data_size);
16285754795SMichal Simek }
16385754795SMichal Simek
do_fpga_load(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])16485754795SMichal Simek static int do_fpga_load(cmd_tbl_t *cmdtp, int flag, int argc,
16585754795SMichal Simek char * const argv[])
16685754795SMichal Simek {
16785754795SMichal Simek size_t data_size = 0;
16885754795SMichal Simek long fpga_data, dev;
16985754795SMichal Simek int ret;
17085754795SMichal Simek
17185754795SMichal Simek ret = do_fpga_check_params(&dev, &fpga_data, &data_size,
17285754795SMichal Simek cmdtp, argc, argv);
17385754795SMichal Simek if (ret)
17485754795SMichal Simek return ret;
17585754795SMichal Simek
17685754795SMichal Simek return fpga_load(dev, (void *)fpga_data, data_size, BIT_FULL);
17785754795SMichal Simek }
17885754795SMichal Simek
do_fpga_loadb(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])17985754795SMichal Simek static int do_fpga_loadb(cmd_tbl_t *cmdtp, int flag, int argc,
18085754795SMichal Simek char * const argv[])
18185754795SMichal Simek {
18285754795SMichal Simek size_t data_size = 0;
18385754795SMichal Simek long fpga_data, dev;
18485754795SMichal Simek int ret;
18585754795SMichal Simek
18685754795SMichal Simek ret = do_fpga_check_params(&dev, &fpga_data, &data_size,
18785754795SMichal Simek cmdtp, argc, argv);
18885754795SMichal Simek if (ret)
18985754795SMichal Simek return ret;
19085754795SMichal Simek
19185754795SMichal Simek return fpga_loadbitstream(dev, (void *)fpga_data, data_size, BIT_FULL);
19285754795SMichal Simek }
19385754795SMichal Simek
19485754795SMichal Simek #if defined(CONFIG_CMD_FPGA_LOADP)
do_fpga_loadp(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])19585754795SMichal Simek static int do_fpga_loadp(cmd_tbl_t *cmdtp, int flag, int argc,
19685754795SMichal Simek char * const argv[])
19785754795SMichal Simek {
19885754795SMichal Simek size_t data_size = 0;
19985754795SMichal Simek long fpga_data, dev;
20085754795SMichal Simek int ret;
20185754795SMichal Simek
20285754795SMichal Simek ret = do_fpga_check_params(&dev, &fpga_data, &data_size,
20385754795SMichal Simek cmdtp, argc, argv);
20485754795SMichal Simek if (ret)
20585754795SMichal Simek return ret;
20685754795SMichal Simek
20785754795SMichal Simek return fpga_load(dev, (void *)fpga_data, data_size, BIT_PARTIAL);
20885754795SMichal Simek }
20985754795SMichal Simek #endif
21085754795SMichal Simek
21185754795SMichal Simek #if defined(CONFIG_CMD_FPGA_LOADBP)
do_fpga_loadbp(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])21285754795SMichal Simek static int do_fpga_loadbp(cmd_tbl_t *cmdtp, int flag, int argc,
21385754795SMichal Simek char * const argv[])
21485754795SMichal Simek {
21585754795SMichal Simek size_t data_size = 0;
21685754795SMichal Simek long fpga_data, dev;
21785754795SMichal Simek int ret;
21885754795SMichal Simek
21985754795SMichal Simek ret = do_fpga_check_params(&dev, &fpga_data, &data_size,
22085754795SMichal Simek cmdtp, argc, argv);
22185754795SMichal Simek if (ret)
22285754795SMichal Simek return ret;
22385754795SMichal Simek
22485754795SMichal Simek return fpga_loadbitstream(dev, (void *)fpga_data, data_size,
22585754795SMichal Simek BIT_PARTIAL);
22685754795SMichal Simek }
22785754795SMichal Simek #endif
22885754795SMichal Simek
2292892fe80SMichal Simek #if defined(CONFIG_CMD_FPGA_LOADMK)
do_fpga_loadmk(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])2302892fe80SMichal Simek static int do_fpga_loadmk(cmd_tbl_t *cmdtp, int flag, int argc,
2312892fe80SMichal Simek char * const argv[])
2322892fe80SMichal Simek {
2332892fe80SMichal Simek size_t data_size = 0;
2342892fe80SMichal Simek void *fpga_data = NULL;
2352892fe80SMichal Simek #if defined(CONFIG_FIT)
2362892fe80SMichal Simek const char *fit_uname = NULL;
2372892fe80SMichal Simek ulong fit_addr;
2382892fe80SMichal Simek #endif
2392892fe80SMichal Simek ulong dev = do_fpga_get_device(argv[0]);
2402892fe80SMichal Simek char *datastr = env_get("fpgadata");
2412892fe80SMichal Simek
2428c75f794SMichal Simek debug("fpga: argc %x, dev %lx, datastr %s\n", argc, dev, datastr);
2438c75f794SMichal Simek
2448c75f794SMichal Simek if (dev == FPGA_INVALID_DEVICE) {
2458c75f794SMichal Simek debug("fpga: Invalid fpga device\n");
2468c75f794SMichal Simek return CMD_RET_USAGE;
2478c75f794SMichal Simek }
2488c75f794SMichal Simek
2498c75f794SMichal Simek if (argc == 0 && !datastr) {
2508c75f794SMichal Simek debug("fpga: No datastr passed\n");
2518c75f794SMichal Simek return CMD_RET_USAGE;
2528c75f794SMichal Simek }
2532892fe80SMichal Simek
2542892fe80SMichal Simek if (argc == 2) {
2558c75f794SMichal Simek datastr = argv[1];
2568c75f794SMichal Simek debug("fpga: Full command with two args\n");
2578c75f794SMichal Simek } else if (argc == 1 && !datastr) {
2588c75f794SMichal Simek debug("fpga: Dev is setup - fpgadata passed\n");
2598c75f794SMichal Simek datastr = argv[0];
2608c75f794SMichal Simek }
2618c75f794SMichal Simek
2622892fe80SMichal Simek #if defined(CONFIG_FIT)
2638c75f794SMichal Simek if (fit_parse_subimage(datastr, (ulong)fpga_data,
2642892fe80SMichal Simek &fit_addr, &fit_uname)) {
2652892fe80SMichal Simek fpga_data = (void *)fit_addr;
2662892fe80SMichal Simek debug("* fpga: subimage '%s' from FIT image ",
2672892fe80SMichal Simek fit_uname);
2682892fe80SMichal Simek debug("at 0x%08lx\n", fit_addr);
2692892fe80SMichal Simek } else
2702892fe80SMichal Simek #endif
2712892fe80SMichal Simek {
2728c75f794SMichal Simek fpga_data = (void *)simple_strtoul(datastr, NULL, 16);
2732892fe80SMichal Simek debug("* fpga: cmdline image address = 0x%08lx\n",
2742892fe80SMichal Simek (ulong)fpga_data);
2752892fe80SMichal Simek }
2762892fe80SMichal Simek debug("%s: fpga_data = 0x%lx\n", __func__, (ulong)fpga_data);
2772892fe80SMichal Simek if (!fpga_data) {
2782892fe80SMichal Simek puts("Zero fpga_data address\n");
2792892fe80SMichal Simek return CMD_RET_USAGE;
2802892fe80SMichal Simek }
2812892fe80SMichal Simek
2822892fe80SMichal Simek switch (genimg_get_format(fpga_data)) {
2832892fe80SMichal Simek #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
2842892fe80SMichal Simek case IMAGE_FORMAT_LEGACY:
2852892fe80SMichal Simek {
2862892fe80SMichal Simek image_header_t *hdr = (image_header_t *)fpga_data;
2872892fe80SMichal Simek ulong data;
2882892fe80SMichal Simek u8 comp;
2892892fe80SMichal Simek
2902892fe80SMichal Simek comp = image_get_comp(hdr);
2912892fe80SMichal Simek if (comp == IH_COMP_GZIP) {
2922892fe80SMichal Simek #if defined(CONFIG_GZIP)
2932892fe80SMichal Simek ulong image_buf = image_get_data(hdr);
2942892fe80SMichal Simek ulong image_size = ~0UL;
2952892fe80SMichal Simek
2962892fe80SMichal Simek data = image_get_load(hdr);
2972892fe80SMichal Simek
2982892fe80SMichal Simek if (gunzip((void *)data, ~0UL, (void *)image_buf,
2992892fe80SMichal Simek &image_size) != 0) {
3002892fe80SMichal Simek puts("GUNZIP: error\n");
301a2d1033bSMichal Simek return CMD_RET_FAILURE;
3022892fe80SMichal Simek }
3032892fe80SMichal Simek data_size = image_size;
3042892fe80SMichal Simek #else
3052892fe80SMichal Simek puts("Gunzip image is not supported\n");
3062892fe80SMichal Simek return 1;
3072892fe80SMichal Simek #endif
3082892fe80SMichal Simek } else {
3092892fe80SMichal Simek data = (ulong)image_get_data(hdr);
3102892fe80SMichal Simek data_size = image_get_data_size(hdr);
3112892fe80SMichal Simek }
3122892fe80SMichal Simek return fpga_load(dev, (void *)data, data_size,
3132892fe80SMichal Simek BIT_FULL);
3142892fe80SMichal Simek }
3152892fe80SMichal Simek #endif
3162892fe80SMichal Simek #if defined(CONFIG_FIT)
3172892fe80SMichal Simek case IMAGE_FORMAT_FIT:
3182892fe80SMichal Simek {
3192892fe80SMichal Simek const void *fit_hdr = (const void *)fpga_data;
3202892fe80SMichal Simek int noffset;
3212892fe80SMichal Simek const void *fit_data;
3222892fe80SMichal Simek
3232892fe80SMichal Simek if (!fit_uname) {
3242892fe80SMichal Simek puts("No FIT subimage unit name\n");
325a2d1033bSMichal Simek return CMD_RET_FAILURE;
3262892fe80SMichal Simek }
3272892fe80SMichal Simek
3282892fe80SMichal Simek if (!fit_check_format(fit_hdr)) {
3292892fe80SMichal Simek puts("Bad FIT image format\n");
330a2d1033bSMichal Simek return CMD_RET_FAILURE;
3312892fe80SMichal Simek }
3322892fe80SMichal Simek
3332892fe80SMichal Simek /* get fpga component image node offset */
3342892fe80SMichal Simek noffset = fit_image_get_node(fit_hdr, fit_uname);
3352892fe80SMichal Simek if (noffset < 0) {
3362892fe80SMichal Simek printf("Can't find '%s' FIT subimage\n", fit_uname);
337a2d1033bSMichal Simek return CMD_RET_FAILURE;
3382892fe80SMichal Simek }
3392892fe80SMichal Simek
3402892fe80SMichal Simek /* verify integrity */
3412892fe80SMichal Simek if (!fit_image_verify(fit_hdr, noffset)) {
3422892fe80SMichal Simek puts("Bad Data Hash\n");
343a2d1033bSMichal Simek return CMD_RET_FAILURE;
3442892fe80SMichal Simek }
3452892fe80SMichal Simek
3462892fe80SMichal Simek /* get fpga subimage data address and length */
3472892fe80SMichal Simek if (fit_image_get_data(fit_hdr, noffset, &fit_data,
3482892fe80SMichal Simek &data_size)) {
3492892fe80SMichal Simek puts("Fpga subimage data not found\n");
350a2d1033bSMichal Simek return CMD_RET_FAILURE;
3512892fe80SMichal Simek }
3522892fe80SMichal Simek
3532892fe80SMichal Simek return fpga_load(dev, fit_data, data_size, BIT_FULL);
3542892fe80SMichal Simek }
3552892fe80SMichal Simek #endif
3562892fe80SMichal Simek default:
3572892fe80SMichal Simek puts("** Unknown image type\n");
358a2d1033bSMichal Simek return CMD_RET_FAILURE;
3592892fe80SMichal Simek }
3602892fe80SMichal Simek }
3612892fe80SMichal Simek #endif
3622892fe80SMichal Simek
3639657d97cSMichal Simek static cmd_tbl_t fpga_commands[] = {
364f4c7a4aeSMichal Simek U_BOOT_CMD_MKENT(info, 1, 1, do_fpga_info, "", ""),
36585754795SMichal Simek U_BOOT_CMD_MKENT(dump, 3, 1, do_fpga_dump, "", ""),
36685754795SMichal Simek U_BOOT_CMD_MKENT(load, 3, 1, do_fpga_load, "", ""),
36785754795SMichal Simek U_BOOT_CMD_MKENT(loadb, 3, 1, do_fpga_loadb, "", ""),
36885754795SMichal Simek #if defined(CONFIG_CMD_FPGA_LOADP)
36985754795SMichal Simek U_BOOT_CMD_MKENT(loadp, 3, 1, do_fpga_loadp, "", ""),
37085754795SMichal Simek #endif
37185754795SMichal Simek #if defined(CONFIG_CMD_FPGA_LOADBP)
37285754795SMichal Simek U_BOOT_CMD_MKENT(loadbp, 3, 1, do_fpga_loadbp, "", ""),
37385754795SMichal Simek #endif
37449503f9aSMichal Simek #if defined(CONFIG_CMD_FPGA_LOADFS)
37549503f9aSMichal Simek U_BOOT_CMD_MKENT(loadfs, 7, 1, do_fpga_loadfs, "", ""),
37649503f9aSMichal Simek #endif
3772892fe80SMichal Simek #if defined(CONFIG_CMD_FPGA_LOADMK)
3782892fe80SMichal Simek U_BOOT_CMD_MKENT(loadmk, 2, 1, do_fpga_loadmk, "", ""),
3792892fe80SMichal Simek #endif
380*b5d19a93SMichal Simek #if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
381*b5d19a93SMichal Simek U_BOOT_CMD_MKENT(loads, 6, 1, do_fpga_loads, "", ""),
382*b5d19a93SMichal Simek #endif
3839657d97cSMichal Simek };
3849657d97cSMichal Simek
do_fpga_wrapper(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])3859657d97cSMichal Simek static int do_fpga_wrapper(cmd_tbl_t *cmdtp, int flag, int argc,
3869657d97cSMichal Simek char *const argv[])
3879657d97cSMichal Simek {
3889657d97cSMichal Simek cmd_tbl_t *fpga_cmd;
3899657d97cSMichal Simek int ret;
3909657d97cSMichal Simek
3919657d97cSMichal Simek if (argc < 2)
3929657d97cSMichal Simek return CMD_RET_USAGE;
3939657d97cSMichal Simek
3949657d97cSMichal Simek fpga_cmd = find_cmd_tbl(argv[1], fpga_commands,
3959657d97cSMichal Simek ARRAY_SIZE(fpga_commands));
3969657d97cSMichal Simek if (!fpga_cmd) {
3979657d97cSMichal Simek debug("fpga: non existing command\n");
3989657d97cSMichal Simek return CMD_RET_USAGE;
3999657d97cSMichal Simek }
4009657d97cSMichal Simek
4019657d97cSMichal Simek argc -= 2;
4029657d97cSMichal Simek argv += 2;
4039657d97cSMichal Simek
4049657d97cSMichal Simek if (argc > fpga_cmd->maxargs) {
4059657d97cSMichal Simek debug("fpga: more parameters passed\n");
4069657d97cSMichal Simek return CMD_RET_USAGE;
4079657d97cSMichal Simek }
4089657d97cSMichal Simek
4099657d97cSMichal Simek ret = fpga_cmd->cmd(fpga_cmd, flag, argc, argv);
4109657d97cSMichal Simek
4119657d97cSMichal Simek return cmd_process_error(fpga_cmd, ret);
4129657d97cSMichal Simek }
4139657d97cSMichal Simek
414cedd48e2SSiva Durga Prasad Paladugu #if defined(CONFIG_CMD_FPGA_LOADFS) || defined(CONFIG_CMD_FPGA_LOAD_SECURE)
4159657d97cSMichal Simek U_BOOT_CMD(fpga, 9, 1, do_fpga_wrapper,
4162e192b24SSimon Glass #else
4179657d97cSMichal Simek U_BOOT_CMD(fpga, 6, 1, do_fpga_wrapper,
4182e192b24SSimon Glass #endif
4192e192b24SSimon Glass "loadable FPGA image support",
4202e192b24SSimon Glass "[operation type] [device number] [image address] [image size]\n"
4212e192b24SSimon Glass "fpga operations:\n"
4222e192b24SSimon Glass " dump\t[dev] [address] [size]\tLoad device to memory buffer\n"
4232e192b24SSimon Glass " info\t[dev]\t\t\tlist known device information\n"
4242e192b24SSimon Glass " load\t[dev] [address] [size]\tLoad device from memory buffer\n"
4252e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADP)
4262e192b24SSimon Glass " loadp\t[dev] [address] [size]\t"
4272e192b24SSimon Glass "Load device from memory buffer with partial bitstream\n"
4282e192b24SSimon Glass #endif
4292e192b24SSimon Glass " loadb\t[dev] [address] [size]\t"
4302e192b24SSimon Glass "Load device from bitstream buffer (Xilinx only)\n"
4312e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADBP)
4322e192b24SSimon Glass " loadbp\t[dev] [address] [size]\t"
4332e192b24SSimon Glass "Load device from bitstream buffer with partial bitstream"
4342e192b24SSimon Glass "(Xilinx only)\n"
4352e192b24SSimon Glass #endif
4362e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADFS)
4372e192b24SSimon Glass "Load device from filesystem (FAT by default) (Xilinx only)\n"
4382e192b24SSimon Glass " loadfs [dev] [address] [image size] [blocksize] <interface>\n"
4392e192b24SSimon Glass " [<dev[:part]>] <filename>\n"
4402e192b24SSimon Glass #endif
4412e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADMK)
4422e192b24SSimon Glass " loadmk [dev] [address]\tLoad device generated with mkimage"
4432e192b24SSimon Glass #if defined(CONFIG_FIT)
4442e192b24SSimon Glass "\n"
4452e192b24SSimon Glass "\tFor loadmk operating on FIT format uImage address must include\n"
4462e192b24SSimon Glass "\tsubimage unit name in the form of addr:<subimg_uname>"
4472e192b24SSimon Glass #endif
4482e192b24SSimon Glass #endif
449cedd48e2SSiva Durga Prasad Paladugu #if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
450cedd48e2SSiva Durga Prasad Paladugu "Load encrypted bitstream (Xilinx only)\n"
451cedd48e2SSiva Durga Prasad Paladugu " loads [dev] [address] [size] [auth-OCM-0/DDR-1/noauth-2]\n"
452cedd48e2SSiva Durga Prasad Paladugu " [enc-devkey(0)/userkey(1)/nenc(2) [Userkey address]\n"
453cedd48e2SSiva Durga Prasad Paladugu "Loads the secure bistreams(authenticated/encrypted/both\n"
454cedd48e2SSiva Durga Prasad Paladugu "authenticated and encrypted) of [size] from [address].\n"
455cedd48e2SSiva Durga Prasad Paladugu "The auth-OCM/DDR flag specifies to perform authentication\n"
456cedd48e2SSiva Durga Prasad Paladugu "in OCM or in DDR. 0 for OCM, 1 for DDR, 2 for no authentication.\n"
457cedd48e2SSiva Durga Prasad Paladugu "The enc flag specifies which key to be used for decryption\n"
458cedd48e2SSiva Durga Prasad Paladugu "0-device key, 1-user key, 2-no encryption.\n"
459cedd48e2SSiva Durga Prasad Paladugu "The optional Userkey address specifies from which address key\n"
460cedd48e2SSiva Durga Prasad Paladugu "has to be used for decryption if user key is selected.\n"
461cedd48e2SSiva Durga Prasad Paladugu "NOTE: the sceure bitstream has to be created using xilinx\n"
462cedd48e2SSiva Durga Prasad Paladugu "bootgen tool only.\n"
463cedd48e2SSiva Durga Prasad Paladugu #endif
4642e192b24SSimon Glass );
465