]> git.sur5r.net Git - u-boot/blob - drivers/fpga/fpga.c
cmd: fpga: Add support to load secure bitstreams
[u-boot] / drivers / fpga / fpga.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2002
4  * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
5  */
6
7 /* Generic FPGA support */
8 #include <common.h>             /* core U-Boot definitions */
9 #include <xilinx.h>             /* xilinx specific definitions */
10 #include <altera.h>             /* altera specific definitions */
11 #include <lattice.h>
12
13 /* Local definitions */
14 #ifndef CONFIG_MAX_FPGA_DEVICES
15 #define CONFIG_MAX_FPGA_DEVICES         5
16 #endif
17
18 /* Local static data */
19 static int next_desc = FPGA_INVALID_DEVICE;
20 static fpga_desc desc_table[CONFIG_MAX_FPGA_DEVICES];
21
22 /*
23  * fpga_no_sup
24  * 'no support' message function
25  */
26 static void fpga_no_sup(char *fn, char *msg)
27 {
28         if (fn && msg)
29                 printf("%s: No support for %s.\n", fn, msg);
30         else if (msg)
31                 printf("No support for %s.\n", msg);
32         else
33                 printf("No FPGA support!\n");
34 }
35
36
37 /* fpga_get_desc
38  *      map a device number to a descriptor
39  */
40 const fpga_desc *const fpga_get_desc(int devnum)
41 {
42         fpga_desc *desc = (fpga_desc *)NULL;
43
44         if ((devnum >= 0) && (devnum < next_desc)) {
45                 desc = &desc_table[devnum];
46                 debug("%s: found fpga descriptor #%d @ 0x%p\n",
47                       __func__, devnum, desc);
48         }
49
50         return desc;
51 }
52
53 /*
54  * fpga_validate
55  *      generic parameter checking code
56  */
57 const fpga_desc *const fpga_validate(int devnum, const void *buf,
58                                      size_t bsize, char *fn)
59 {
60         const fpga_desc *desc = fpga_get_desc(devnum);
61
62         if (!desc)
63                 printf("%s: Invalid device number %d\n", fn, devnum);
64
65         if (!buf) {
66                 printf("%s: Null buffer.\n", fn);
67                 return (fpga_desc * const)NULL;
68         }
69         return desc;
70 }
71
72 /*
73  * fpga_dev_info
74  *      generic multiplexing code
75  */
76 static int fpga_dev_info(int devnum)
77 {
78         int ret_val = FPGA_FAIL; /* assume failure */
79         const fpga_desc * const desc = fpga_get_desc(devnum);
80
81         if (desc) {
82                 debug("%s: Device Descriptor @ 0x%p\n",
83                       __func__, desc->devdesc);
84
85                 switch (desc->devtype) {
86                 case fpga_xilinx:
87 #if defined(CONFIG_FPGA_XILINX)
88                         printf("Xilinx Device\nDescriptor @ 0x%p\n", desc);
89                         ret_val = xilinx_info(desc->devdesc);
90 #else
91                         fpga_no_sup((char *)__func__, "Xilinx devices");
92 #endif
93                         break;
94                 case fpga_altera:
95 #if defined(CONFIG_FPGA_ALTERA)
96                         printf("Altera Device\nDescriptor @ 0x%p\n", desc);
97                         ret_val = altera_info(desc->devdesc);
98 #else
99                         fpga_no_sup((char *)__func__, "Altera devices");
100 #endif
101                         break;
102                 case fpga_lattice:
103 #if defined(CONFIG_FPGA_LATTICE)
104                         printf("Lattice Device\nDescriptor @ 0x%p\n", desc);
105                         ret_val = lattice_info(desc->devdesc);
106 #else
107                         fpga_no_sup((char *)__func__, "Lattice devices");
108 #endif
109                         break;
110                 default:
111                         printf("%s: Invalid or unsupported device type %d\n",
112                                __func__, desc->devtype);
113                 }
114         } else {
115                 printf("%s: Invalid device number %d\n", __func__, devnum);
116         }
117
118         return ret_val;
119 }
120
121 /*
122  * fpga_init is usually called from misc_init_r() and MUST be called
123  * before any of the other fpga functions are used.
124  */
125 void fpga_init(void)
126 {
127         next_desc = 0;
128         memset(desc_table, 0, sizeof(desc_table));
129
130         debug("%s\n", __func__);
131 }
132
133 /*
134  * fpga_count
135  * Basic interface function to get the current number of devices available.
136  */
137 int fpga_count(void)
138 {
139         return next_desc;
140 }
141
142 /*
143  * fpga_add
144  *      Add the device descriptor to the device table.
145  */
146 int fpga_add(fpga_type devtype, void *desc)
147 {
148         int devnum = FPGA_INVALID_DEVICE;
149
150         if (!desc) {
151                 printf("%s: NULL device descriptor\n", __func__);
152                 return devnum;
153         }
154
155         if (next_desc < 0) {
156                 printf("%s: FPGA support not initialized!\n", __func__);
157         } else if ((devtype > fpga_min_type) && (devtype < fpga_undefined)) {
158                 if (next_desc < CONFIG_MAX_FPGA_DEVICES) {
159                         devnum = next_desc;
160                         desc_table[next_desc].devtype = devtype;
161                         desc_table[next_desc++].devdesc = desc;
162                 } else {
163                         printf("%s: Exceeded Max FPGA device count\n",
164                                __func__);
165                 }
166         } else {
167                 printf("%s: Unsupported FPGA type %d\n", __func__, devtype);
168         }
169
170         return devnum;
171 }
172
173 /*
174  * Return 1 if the fpga data is partial.
175  * This is only required for fpga drivers that support bitstream_type.
176  */
177 int __weak fpga_is_partial_data(int devnum, size_t img_len)
178 {
179         return 0;
180 }
181
182 /*
183  * Convert bitstream data and load into the fpga
184  */
185 int __weak fpga_loadbitstream(int devnum, char *fpgadata, size_t size,
186                               bitstream_type bstype)
187 {
188         printf("Bitstream support not implemented for this FPGA device\n");
189         return FPGA_FAIL;
190 }
191
192 #if defined(CONFIG_CMD_FPGA_LOADFS)
193 int fpga_fsload(int devnum, const void *buf, size_t size,
194                  fpga_fs_info *fpga_fsinfo)
195 {
196         int ret_val = FPGA_FAIL;           /* assume failure */
197         const fpga_desc *desc = fpga_validate(devnum, buf, size,
198                                               (char *)__func__);
199
200         if (desc) {
201                 switch (desc->devtype) {
202                 case fpga_xilinx:
203 #if defined(CONFIG_FPGA_XILINX)
204                         ret_val = xilinx_loadfs(desc->devdesc, buf, size,
205                                                 fpga_fsinfo);
206 #else
207                         fpga_no_sup((char *)__func__, "Xilinx devices");
208 #endif
209                         break;
210                 default:
211                         printf("%s: Invalid or unsupported device type %d\n",
212                                __func__, desc->devtype);
213                 }
214         }
215
216         return ret_val;
217 }
218 #endif
219
220 #if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
221 int fpga_loads(int devnum, const void *buf, size_t size,
222                struct fpga_secure_info *fpga_sec_info)
223 {
224         int ret_val = FPGA_FAIL;
225
226         const fpga_desc *desc = fpga_validate(devnum, buf, size,
227                                               (char *)__func__);
228
229         if (desc) {
230                 switch (desc->devtype) {
231                 case fpga_xilinx:
232 #if defined(CONFIG_FPGA_XILINX)
233                         ret_val = xilinx_loads(desc->devdesc, buf, size,
234                                                fpga_sec_info);
235 #else
236                         fpga_no_sup((char *)__func__, "Xilinx devices");
237 #endif
238                         break;
239                 default:
240                         printf("%s: Invalid or unsupported device type %d\n",
241                                __func__, desc->devtype);
242                 }
243         }
244
245         return ret_val;
246 }
247 #endif
248
249 /*
250  * Generic multiplexing code
251  */
252 int fpga_load(int devnum, const void *buf, size_t bsize, bitstream_type bstype)
253 {
254         int ret_val = FPGA_FAIL;           /* assume failure */
255         const fpga_desc *desc = fpga_validate(devnum, buf, bsize,
256                                               (char *)__func__);
257
258         if (desc) {
259                 switch (desc->devtype) {
260                 case fpga_xilinx:
261 #if defined(CONFIG_FPGA_XILINX)
262                         ret_val = xilinx_load(desc->devdesc, buf, bsize,
263                                               bstype);
264 #else
265                         fpga_no_sup((char *)__func__, "Xilinx devices");
266 #endif
267                         break;
268                 case fpga_altera:
269 #if defined(CONFIG_FPGA_ALTERA)
270                         ret_val = altera_load(desc->devdesc, buf, bsize);
271 #else
272                         fpga_no_sup((char *)__func__, "Altera devices");
273 #endif
274                         break;
275                 case fpga_lattice:
276 #if defined(CONFIG_FPGA_LATTICE)
277                         ret_val = lattice_load(desc->devdesc, buf, bsize);
278 #else
279                         fpga_no_sup((char *)__func__, "Lattice devices");
280 #endif
281                         break;
282                 default:
283                         printf("%s: Invalid or unsupported device type %d\n",
284                                __func__, desc->devtype);
285                 }
286         }
287
288         return ret_val;
289 }
290
291 /*
292  * fpga_dump
293  *      generic multiplexing code
294  */
295 int fpga_dump(int devnum, const void *buf, size_t bsize)
296 {
297         int ret_val = FPGA_FAIL;           /* assume failure */
298         const fpga_desc *desc = fpga_validate(devnum, buf, bsize,
299                                               (char *)__func__);
300
301         if (desc) {
302                 switch (desc->devtype) {
303                 case fpga_xilinx:
304 #if defined(CONFIG_FPGA_XILINX)
305                         ret_val = xilinx_dump(desc->devdesc, buf, bsize);
306 #else
307                         fpga_no_sup((char *)__func__, "Xilinx devices");
308 #endif
309                         break;
310                 case fpga_altera:
311 #if defined(CONFIG_FPGA_ALTERA)
312                         ret_val = altera_dump(desc->devdesc, buf, bsize);
313 #else
314                         fpga_no_sup((char *)__func__, "Altera devices");
315 #endif
316                         break;
317                 case fpga_lattice:
318 #if defined(CONFIG_FPGA_LATTICE)
319                         ret_val = lattice_dump(desc->devdesc, buf, bsize);
320 #else
321                         fpga_no_sup((char *)__func__, "Lattice devices");
322 #endif
323                         break;
324                 default:
325                         printf("%s: Invalid or unsupported device type %d\n",
326                                __func__, desc->devtype);
327                 }
328         }
329
330         return ret_val;
331 }
332
333 /*
334  * fpga_info
335  *      front end to fpga_dev_info.  If devnum is invalid, report on all
336  *      available devices.
337  */
338 int fpga_info(int devnum)
339 {
340         if (devnum == FPGA_INVALID_DEVICE) {
341                 if (next_desc > 0) {
342                         int dev;
343
344                         for (dev = 0; dev < next_desc; dev++)
345                                 fpga_dev_info(dev);
346
347                         return FPGA_SUCCESS;
348                 } else {
349                         printf("%s: No FPGA devices available.\n", __func__);
350                         return FPGA_FAIL;
351                 }
352         }
353
354         return fpga_dev_info(devnum);
355 }