Blame view

common/cmd_fpga.c 6.7 KB
4a9cbbe83   wdenk   Initial revision
1
2
3
4
  /*
   * (C) Copyright 2000, 2001
   * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
   *
1a4596601   Wolfgang Denk   Add GPL-2.0+ SPDX...
5
   * SPDX-License-Identifier:	GPL-2.0+
4a9cbbe83   wdenk   Initial revision
6
7
8
9
10
11
12
   */
  
  /*
   *  FPGA support
   */
  #include <common.h>
  #include <command.h>
8bde7f776   wdenk   * Code cleanup:
13
  #include <fpga.h>
c3d2b4b48   wdenk   Code cleanup.
14
  #include <malloc.h>
4a9cbbe83   wdenk   Initial revision
15

4a9cbbe83   wdenk   Initial revision
16
  /* Local functions */
fc598412c   Michal Simek   cmd: fpga: Clean ...
17
  static int fpga_get_op(char *opstr);
4a9cbbe83   wdenk   Initial revision
18
19
20
21
22
  
  /* Local defines */
  #define FPGA_NONE   -1
  #define FPGA_INFO   0
  #define FPGA_LOAD   1
30ce5ab04   wdenk   * Patch by Gleb N...
23
  #define FPGA_LOADB  2
4a9cbbe83   wdenk   Initial revision
24
  #define FPGA_DUMP   3
f0ff4692f   Stefan Roese   Add FPGA Altera C...
25
  #define FPGA_LOADMK 4
4a9cbbe83   wdenk   Initial revision
26
27
28
29
30
31
32
33
34
  
  /* ------------------------------------------------------------------------- */
  /* command form:
   *   fpga <op> <device number> <data addr> <datasize>
   * where op is 'load', 'dump', or 'info'
   * If there is no device number field, the fpga environment variable is used.
   * If there is no data addr field, the fpgadata environment variable is used.
   * The info command requires no data address field.
   */
fc598412c   Michal Simek   cmd: fpga: Clean ...
35
  int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
4a9cbbe83   wdenk   Initial revision
36
  {
d4ca31c40   wdenk   * Cleanup lowboot...
37
38
39
  	int op, dev = FPGA_INVALID_DEVICE;
  	size_t data_size = 0;
  	void *fpga_data = NULL;
fc598412c   Michal Simek   cmd: fpga: Clean ...
40
41
  	char *devstr = getenv("fpga");
  	char *datastr = getenv("fpgadata");
d4ca31c40   wdenk   * Cleanup lowboot...
42
  	int rc = FPGA_FAIL;
a790b5b23   Stefano Babic   cmd_fpga: cleanup...
43
  	int wrong_parms = 0;
fc598412c   Michal Simek   cmd: fpga: Clean ...
44
  #if defined(CONFIG_FIT)
c28c4d193   Marian Balakowicz   [new uImage] Add ...
45
46
47
  	const char *fit_uname = NULL;
  	ulong fit_addr;
  #endif
d4ca31c40   wdenk   * Cleanup lowboot...
48
49
  
  	if (devstr)
fc598412c   Michal Simek   cmd: fpga: Clean ...
50
  		dev = (int) simple_strtoul(devstr, NULL, 16);
d4ca31c40   wdenk   * Cleanup lowboot...
51
  	if (datastr)
fc598412c   Michal Simek   cmd: fpga: Clean ...
52
  		fpga_data = (void *)simple_strtoul(datastr, NULL, 16);
d4ca31c40   wdenk   * Cleanup lowboot...
53
54
55
  
  	switch (argc) {
  	case 5:		/* fpga <op> <dev> <data> <datasize> */
fc598412c   Michal Simek   cmd: fpga: Clean ...
56
  		data_size = simple_strtoul(argv[4], NULL, 16);
c28c4d193   Marian Balakowicz   [new uImage] Add ...
57

d4ca31c40   wdenk   * Cleanup lowboot...
58
  	case 4:		/* fpga <op> <dev> <data> */
c28c4d193   Marian Balakowicz   [new uImage] Add ...
59
  #if defined(CONFIG_FIT)
fc598412c   Michal Simek   cmd: fpga: Clean ...
60
61
  		if (fit_parse_subimage(argv[3], (ulong)fpga_data,
  				       &fit_addr, &fit_uname)) {
c28c4d193   Marian Balakowicz   [new uImage] Add ...
62
  			fpga_data = (void *)fit_addr;
fc598412c   Michal Simek   cmd: fpga: Clean ...
63
64
65
66
  			debug("*  fpga: subimage '%s' from FIT image ",
  			      fit_uname);
  			debug("at 0x%08lx
  ", fit_addr);
c28c4d193   Marian Balakowicz   [new uImage] Add ...
67
68
69
  		} else
  #endif
  		{
fc598412c   Michal Simek   cmd: fpga: Clean ...
70
  			fpga_data = (void *)simple_strtoul(argv[3], NULL, 16);
06297db06   Stefano Babic   FPGA: use debug()...
71
72
  			debug("*  fpga: cmdline image address = 0x%08lx
  ",
fc598412c   Michal Simek   cmd: fpga: Clean ...
73
  			      (ulong)fpga_data);
c28c4d193   Marian Balakowicz   [new uImage] Add ...
74
  		}
fc598412c   Michal Simek   cmd: fpga: Clean ...
75
76
  		debug("%s: fpga_data = 0x%x
  ", __func__, (uint)fpga_data);
c28c4d193   Marian Balakowicz   [new uImage] Add ...
77

d4ca31c40   wdenk   * Cleanup lowboot...
78
  	case 3:		/* fpga <op> <dev | data addr> */
fc598412c   Michal Simek   cmd: fpga: Clean ...
79
  		dev = (int)simple_strtoul(argv[2], NULL, 16);
06297db06   Stefano Babic   FPGA: use debug()...
80
81
  		debug("%s: device = %d
  ", __func__, dev);
d4ca31c40   wdenk   * Cleanup lowboot...
82
  		/* FIXME - this is a really weak test */
fc598412c   Michal Simek   cmd: fpga: Clean ...
83
84
  		if ((argc == 3) && (dev > fpga_count())) {
  			/* must be buffer ptr */
06297db06   Stefano Babic   FPGA: use debug()...
85
86
  			debug("%s: Assuming buffer pointer in arg 3
  ",
fc598412c   Michal Simek   cmd: fpga: Clean ...
87
  			      __func__);
c28c4d193   Marian Balakowicz   [new uImage] Add ...
88
89
  
  #if defined(CONFIG_FIT)
fc598412c   Michal Simek   cmd: fpga: Clean ...
90
91
  			if (fit_parse_subimage(argv[2], (ulong)fpga_data,
  					       &fit_addr, &fit_uname)) {
c28c4d193   Marian Balakowicz   [new uImage] Add ...
92
  				fpga_data = (void *)fit_addr;
fc598412c   Michal Simek   cmd: fpga: Clean ...
93
94
95
96
  				debug("*  fpga: subimage '%s' from FIT image ",
  				      fit_uname);
  				debug("at 0x%08lx
  ", fit_addr);
c28c4d193   Marian Balakowicz   [new uImage] Add ...
97
98
99
  			} else
  #endif
  			{
fc598412c   Michal Simek   cmd: fpga: Clean ...
100
101
102
103
  				fpga_data = (void *)dev;
  				debug("*  fpga: cmdline image addr = 0x%08lx
  ",
  				      (ulong)fpga_data);
c28c4d193   Marian Balakowicz   [new uImage] Add ...
104
  			}
06297db06   Stefano Babic   FPGA: use debug()...
105
106
  			debug("%s: fpga_data = 0x%x
  ",
fc598412c   Michal Simek   cmd: fpga: Clean ...
107
  			      __func__, (uint)fpga_data);
d4ca31c40   wdenk   * Cleanup lowboot...
108
109
  			dev = FPGA_INVALID_DEVICE;	/* reset device num */
  		}
c28c4d193   Marian Balakowicz   [new uImage] Add ...
110

d4ca31c40   wdenk   * Cleanup lowboot...
111
  	case 2:		/* fpga <op> */
fc598412c   Michal Simek   cmd: fpga: Clean ...
112
  		op = (int)fpga_get_op(argv[1]);
d4ca31c40   wdenk   * Cleanup lowboot...
113
  		break;
c28c4d193   Marian Balakowicz   [new uImage] Add ...
114

d4ca31c40   wdenk   * Cleanup lowboot...
115
  	default:
fc598412c   Michal Simek   cmd: fpga: Clean ...
116
117
  		debug("%s: Too many or too few args (%d)
  ", __func__, argc);
d4ca31c40   wdenk   * Cleanup lowboot...
118
119
120
  		op = FPGA_NONE;	/* force usage display */
  		break;
  	}
a790b5b23   Stefano Babic   cmd_fpga: cleanup...
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  	if (dev == FPGA_INVALID_DEVICE) {
  		puts("FPGA device not specified
  ");
  		op = FPGA_NONE;
  	}
  
  	switch (op) {
  	case FPGA_NONE:
  	case FPGA_INFO:
  		break;
  	case FPGA_LOAD:
  	case FPGA_LOADB:
  	case FPGA_DUMP:
  		if (!fpga_data || !data_size)
  			wrong_parms = 1;
  		break;
  	case FPGA_LOADMK:
  		if (!fpga_data)
  			wrong_parms = 1;
  		break;
  	}
  
  	if (wrong_parms) {
  		puts("Wrong parameters for FPGA request
  ");
  		op = FPGA_NONE;
  	}
d4ca31c40   wdenk   * Cleanup lowboot...
148
149
  	switch (op) {
  	case FPGA_NONE:
4c12eeb8b   Simon Glass   Convert cmd_usage...
150
  		return CMD_RET_USAGE;
d4ca31c40   wdenk   * Cleanup lowboot...
151
152
  
  	case FPGA_INFO:
fc598412c   Michal Simek   cmd: fpga: Clean ...
153
  		rc = fpga_info(dev);
d4ca31c40   wdenk   * Cleanup lowboot...
154
155
156
  		break;
  
  	case FPGA_LOAD:
fc598412c   Michal Simek   cmd: fpga: Clean ...
157
  		rc = fpga_load(dev, fpga_data, data_size);
d4ca31c40   wdenk   * Cleanup lowboot...
158
  		break;
30ce5ab04   wdenk   * Patch by Gleb N...
159
160
161
  	case FPGA_LOADB:
  		rc = fpga_loadbitstream(dev, fpga_data, data_size);
  		break;
f0ff4692f   Stefan Roese   Add FPGA Altera C...
162
  	case FPGA_LOADMK:
fc598412c   Michal Simek   cmd: fpga: Clean ...
163
  		switch (genimg_get_format(fpga_data)) {
d5934ad77   Marian Balakowicz   [new uImage] Add ...
164
165
  		case IMAGE_FORMAT_LEGACY:
  			{
fc598412c   Michal Simek   cmd: fpga: Clean ...
166
167
168
  				image_header_t *hdr =
  						(image_header_t *)fpga_data;
  				ulong data;
32d7cdd36   Michal Simek   fpga: Add support...
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
  				uint8_t comp;
  
  				comp = image_get_comp(hdr);
  				if (comp == IH_COMP_GZIP) {
  					ulong image_buf = image_get_data(hdr);
  					data = image_get_load(hdr);
  					ulong image_size = ~0UL;
  
  					if (gunzip((void *)data, ~0UL,
  						   (void *)image_buf,
  						   &image_size) != 0) {
  						puts("GUNZIP: error
  ");
  						return 1;
  					}
  					data_size = image_size;
  				} else {
  					data = (ulong)image_get_data(hdr);
  					data_size = image_get_data_size(hdr);
  				}
fc598412c   Michal Simek   cmd: fpga: Clean ...
189
  				rc = fpga_load(dev, (void *)data, data_size);
f0ff4692f   Stefan Roese   Add FPGA Altera C...
190
  			}
d5934ad77   Marian Balakowicz   [new uImage] Add ...
191
192
193
  			break;
  #if defined(CONFIG_FIT)
  		case IMAGE_FORMAT_FIT:
c28c4d193   Marian Balakowicz   [new uImage] Add ...
194
195
196
  			{
  				const void *fit_hdr = (const void *)fpga_data;
  				int noffset;
e6a857da7   Wolfgang Denk   fpga: constify to...
197
  				const void *fit_data;
c28c4d193   Marian Balakowicz   [new uImage] Add ...
198
199
  
  				if (fit_uname == NULL) {
fc598412c   Michal Simek   cmd: fpga: Clean ...
200
201
  					puts("No FIT subimage unit name
  ");
c28c4d193   Marian Balakowicz   [new uImage] Add ...
202
203
  					return 1;
  				}
fc598412c   Michal Simek   cmd: fpga: Clean ...
204
205
206
  				if (!fit_check_format(fit_hdr)) {
  					puts("Bad FIT image format
  ");
c28c4d193   Marian Balakowicz   [new uImage] Add ...
207
208
209
210
  					return 1;
  				}
  
  				/* get fpga component image node offset */
fc598412c   Michal Simek   cmd: fpga: Clean ...
211
212
  				noffset = fit_image_get_node(fit_hdr,
  							     fit_uname);
c28c4d193   Marian Balakowicz   [new uImage] Add ...
213
  				if (noffset < 0) {
fc598412c   Michal Simek   cmd: fpga: Clean ...
214
215
216
  					printf("Can't find '%s' FIT subimage
  ",
  					       fit_uname);
c28c4d193   Marian Balakowicz   [new uImage] Add ...
217
218
219
220
  					return 1;
  				}
  
  				/* verify integrity */
b8da83665   Simon Glass   image: Rename fit...
221
  				if (!fit_image_verify(fit_hdr, noffset)) {
c28c4d193   Marian Balakowicz   [new uImage] Add ...
222
223
224
225
226
227
  					puts ("Bad Data Hash
  ");
  					return 1;
  				}
  
  				/* get fpga subimage data address and length */
fc598412c   Michal Simek   cmd: fpga: Clean ...
228
229
230
231
  				if (fit_image_get_data(fit_hdr, noffset,
  						       &fit_data, &data_size)) {
  					puts("Fpga subimage data not found
  ");
c28c4d193   Marian Balakowicz   [new uImage] Add ...
232
233
  					return 1;
  				}
fc598412c   Michal Simek   cmd: fpga: Clean ...
234
  				rc = fpga_load(dev, fit_data, data_size);
c28c4d193   Marian Balakowicz   [new uImage] Add ...
235
  			}
d5934ad77   Marian Balakowicz   [new uImage] Add ...
236
237
238
  			break;
  #endif
  		default:
fc598412c   Michal Simek   cmd: fpga: Clean ...
239
240
  			puts("** Unknown image type
  ");
d5934ad77   Marian Balakowicz   [new uImage] Add ...
241
242
  			rc = FPGA_FAIL;
  			break;
f0ff4692f   Stefan Roese   Add FPGA Altera C...
243
244
  		}
  		break;
d4ca31c40   wdenk   * Cleanup lowboot...
245
  	case FPGA_DUMP:
fc598412c   Michal Simek   cmd: fpga: Clean ...
246
  		rc = fpga_dump(dev, fpga_data, data_size);
d4ca31c40   wdenk   * Cleanup lowboot...
247
248
249
  		break;
  
  	default:
fc598412c   Michal Simek   cmd: fpga: Clean ...
250
251
  		printf("Unknown operation
  ");
4c12eeb8b   Simon Glass   Convert cmd_usage...
252
  		return CMD_RET_USAGE;
d4ca31c40   wdenk   * Cleanup lowboot...
253
  	}
fc598412c   Michal Simek   cmd: fpga: Clean ...
254
  	return rc;
4a9cbbe83   wdenk   Initial revision
255
  }
4a9cbbe83   wdenk   Initial revision
256
257
258
259
  /*
   * Map op to supported operations.  We don't use a table since we
   * would just have to relocate it from flash anyway.
   */
fc598412c   Michal Simek   cmd: fpga: Clean ...
260
  static int fpga_get_op(char *opstr)
4a9cbbe83   wdenk   Initial revision
261
262
  {
  	int op = FPGA_NONE;
fc598412c   Michal Simek   cmd: fpga: Clean ...
263
  	if (!strcmp("info", opstr))
4a9cbbe83   wdenk   Initial revision
264
  		op = FPGA_INFO;
fc598412c   Michal Simek   cmd: fpga: Clean ...
265
  	else if (!strcmp("loadb", opstr))
30ce5ab04   wdenk   * Patch by Gleb N...
266
  		op = FPGA_LOADB;
fc598412c   Michal Simek   cmd: fpga: Clean ...
267
  	else if (!strcmp("load", opstr))
4a9cbbe83   wdenk   Initial revision
268
  		op = FPGA_LOAD;
fc598412c   Michal Simek   cmd: fpga: Clean ...
269
  	else if (!strcmp("loadmk", opstr))
f0ff4692f   Stefan Roese   Add FPGA Altera C...
270
  		op = FPGA_LOADMK;
fc598412c   Michal Simek   cmd: fpga: Clean ...
271
  	else if (!strcmp("dump", opstr))
4a9cbbe83   wdenk   Initial revision
272
  		op = FPGA_DUMP;
4a9cbbe83   wdenk   Initial revision
273

fc598412c   Michal Simek   cmd: fpga: Clean ...
274
275
276
  	if (op == FPGA_NONE)
  		printf("Unknown fpga operation \"%s\"
  ", opstr);
4a9cbbe83   wdenk   Initial revision
277
278
  	return op;
  }
fc598412c   Michal Simek   cmd: fpga: Clean ...
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
  U_BOOT_CMD(fpga, 6, 1, do_fpga,
  	   "loadable FPGA image support",
  	   "[operation type] [device number] [image address] [image size]
  "
  	   "fpga operations:
  "
  	   "  dump\t[dev]\t\t\tLoad device to memory buffer
  "
  	   "  info\t[dev]\t\t\tlist known device information
  "
  	   "  load\t[dev] [address] [size]\tLoad device from memory buffer
  "
  	   "  loadb\t[dev] [address] [size]\t"
  	   "Load device from bitstream buffer (Xilinx only)
  "
  	   "  loadmk [dev] [address]\tLoad device generated with mkimage"
c28c4d193   Marian Balakowicz   [new uImage] Add ...
295
  #if defined(CONFIG_FIT)
fc598412c   Michal Simek   cmd: fpga: Clean ...
296
297
298
299
300
  	   "
  "
  	   "\tFor loadmk operating on FIT format uImage address must include
  "
  	   "\tsubimage unit name in the form of addr:<subimg_uname>"
c28c4d193   Marian Balakowicz   [new uImage] Add ...
301
302
  #endif
  );