build: Prepare config.h for inclusion in examples/tests
[platform/upstream/libusb.git] / examples / ezusb.c
1 /*
2  * Copyright © 2001 Stephen Williams (steve@icarus.com)
3  * Copyright © 2001-2002 David Brownell (dbrownell@users.sourceforge.net)
4  * Copyright © 2008 Roger Williams (rawqux@users.sourceforge.net)
5  * Copyright © 2012 Pete Batard (pete@akeo.ie)
6  * Copyright © 2013 Federico Manzan (f.manzan@gmail.com)
7  *
8  *    This source code is free software; you can redistribute it
9  *    and/or modify it in source code form under the terms of the GNU
10  *    General Public License as published by the Free Software
11  *    Foundation; either version 2 of the License, or (at your option)
12  *    any later version.
13  *
14  *    This program is distributed in the hope that it will be useful,
15  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *    GNU General Public License for more details.
18  *
19  *    You should have received a copy of the GNU General Public License
20  *    along with this program; if not, write to the Free Software
21  *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22  */
23
24 #include <config.h>
25
26 #include <stdio.h>
27 #include <errno.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdint.h>
31
32 #include "libusb.h"
33 #include "ezusb.h"
34
35 /*
36  * This file contains functions for uploading firmware into Cypress
37  * EZ-USB microcontrollers. These chips use control endpoint 0 and vendor
38  * specific commands to support writing into the on-chip SRAM. They also
39  * support writing into the CPUCS register, which is how we reset the
40  * processor after loading firmware (including the reset vector).
41  *
42  * These Cypress devices are 8-bit 8051 based microcontrollers with
43  * special support for USB I/O.  They come in several packages, and
44  * some can be set up with external memory when device costs allow.
45  * Note that the design was originally by AnchorChips, so you may find
46  * references to that vendor (which was later merged into Cypress).
47  * The Cypress FX parts are largely compatible with the Anchorhip ones.
48  */
49
50 int verbose = 1;
51
52 /*
53  * return true if [addr,addr+len] includes external RAM
54  * for Anchorchips EZ-USB or Cypress EZ-USB FX
55  */
56 static bool fx_is_external(uint32_t addr, size_t len)
57 {
58         /* with 8KB RAM, 0x0000-0x1b3f can be written
59          * we can't tell if it's a 4KB device here
60          */
61         if (addr <= 0x1b3f)
62                 return ((addr + len) > 0x1b40);
63
64         /* there may be more RAM; unclear if we can write it.
65          * some bulk buffers may be unused, 0x1b3f-0x1f3f
66          * firmware can set ISODISAB for 2KB at 0x2000-0x27ff
67          */
68         return true;
69 }
70
71 /*
72  * return true if [addr,addr+len] includes external RAM
73  * for Cypress EZ-USB FX2
74  */
75 static bool fx2_is_external(uint32_t addr, size_t len)
76 {
77         /* 1st 8KB for data/code, 0x0000-0x1fff */
78         if (addr <= 0x1fff)
79                 return ((addr + len) > 0x2000);
80
81         /* and 512 for data, 0xe000-0xe1ff */
82         else if (addr >= 0xe000 && addr <= 0xe1ff)
83                 return ((addr + len) > 0xe200);
84
85         /* otherwise, it's certainly external */
86         else
87                 return true;
88 }
89
90 /*
91  * return true if [addr,addr+len] includes external RAM
92  * for Cypress EZ-USB FX2LP
93  */
94 static bool fx2lp_is_external(uint32_t addr, size_t len)
95 {
96         /* 1st 16KB for data/code, 0x0000-0x3fff */
97         if (addr <= 0x3fff)
98                 return ((addr + len) > 0x4000);
99
100         /* and 512 for data, 0xe000-0xe1ff */
101         else if (addr >= 0xe000 && addr <= 0xe1ff)
102                 return ((addr + len) > 0xe200);
103
104         /* otherwise, it's certainly external */
105         else
106                 return true;
107 }
108
109
110 /*****************************************************************************/
111
112 /*
113  * These are the requests (bRequest) that the bootstrap loader is expected
114  * to recognize.  The codes are reserved by Cypress, and these values match
115  * what EZ-USB hardware, or "Vend_Ax" firmware (2nd stage loader) uses.
116  * Cypress' "a3load" is nice because it supports both FX and FX2, although
117  * it doesn't have the EEPROM support (subset of "Vend_Ax").
118  */
119 #define RW_INTERNAL     0xA0    /* hardware implements this one */
120 #define RW_MEMORY       0xA3
121
122 /*
123  * Issues the specified vendor-specific write request.
124  */
125 static int ezusb_write(libusb_device_handle *device, const char *label,
126         uint8_t opcode, uint32_t addr, const unsigned char *data, size_t len)
127 {
128         int status;
129
130         if (verbose > 1)
131                 logerror("%s, addr 0x%08x len %4u (0x%04x)\n", label, addr, (unsigned)len, (unsigned)len);
132         status = libusb_control_transfer(device,
133                 LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
134                 opcode, addr & 0xFFFF, addr >> 16,
135                 (unsigned char*)data, (uint16_t)len, 1000);
136         if (status != (signed)len) {
137                 if (status < 0)
138                         logerror("%s: %s\n", label, libusb_error_name(status));
139                 else
140                         logerror("%s ==> %d\n", label, status);
141         }
142         return (status < 0) ? -EIO : 0;
143 }
144
145 /*
146  * Issues the specified vendor-specific read request.
147  */
148 static int ezusb_read(libusb_device_handle *device, const char *label,
149         uint8_t opcode, uint32_t addr, const unsigned char *data, size_t len)
150 {
151         int status;
152
153         if (verbose > 1)
154                 logerror("%s, addr 0x%08x len %4u (0x%04x)\n", label, addr, (unsigned)len, (unsigned)len);
155         status = libusb_control_transfer(device,
156                 LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
157                 opcode, addr & 0xFFFF, addr >> 16,
158                 (unsigned char*)data, (uint16_t)len, 1000);
159         if (status != (signed)len) {
160                 if (status < 0)
161                         logerror("%s: %s\n", label, libusb_error_name(status));
162                 else
163                         logerror("%s ==> %d\n", label, status);
164         }
165         return (status < 0) ? -EIO : 0;
166 }
167
168 /*
169  * Modifies the CPUCS register to stop or reset the CPU.
170  * Returns false on error.
171  */
172 static bool ezusb_cpucs(libusb_device_handle *device, uint32_t addr, bool doRun)
173 {
174         int status;
175         uint8_t data = doRun ? 0x00 : 0x01;
176
177         if (verbose)
178                 logerror("%s\n", data ? "stop CPU" : "reset CPU");
179         status = libusb_control_transfer(device,
180                 LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
181                 RW_INTERNAL, addr & 0xFFFF, addr >> 16,
182                 &data, 1, 1000);
183         if ((status != 1) &&
184                 /* We may get an I/O error from libusb as the device disappears */
185                 ((!doRun) || (status != LIBUSB_ERROR_IO)))
186         {
187                 const char *mesg = "can't modify CPUCS";
188                 if (status < 0)
189                         logerror("%s: %s\n", mesg, libusb_error_name(status));
190                 else
191                         logerror("%s\n", mesg);
192                 return false;
193         } else
194                 return true;
195 }
196
197 /*
198  * Send an FX3 jumpt to address command
199  * Returns false on error.
200  */
201 static bool ezusb_fx3_jump(libusb_device_handle *device, uint32_t addr)
202 {
203         int status;
204
205         if (verbose)
206                 logerror("transfer execution to Program Entry at 0x%08x\n", addr);
207         status = libusb_control_transfer(device,
208                 LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
209                 RW_INTERNAL, addr & 0xFFFF, addr >> 16,
210                 NULL, 0, 1000);
211         /* We may get an I/O error from libusb as the device disappears */
212         if ((status != 0) && (status != LIBUSB_ERROR_IO))
213         {
214                 const char *mesg = "failed to send jump command";
215                 if (status < 0)
216                         logerror("%s: %s\n", mesg, libusb_error_name(status));
217                 else
218                         logerror("%s\n", mesg);
219                 return false;
220         } else
221                 return true;
222 }
223
224 /*****************************************************************************/
225
226 /*
227  * Parse an Intel HEX image file and invoke the poke() function on the
228  * various segments to implement policies such as writing to RAM (with
229  * a one or two stage loader setup, depending on the firmware) or to
230  * EEPROM (two stages required).
231  *
232  * image       - the hex image file
233  * context     - for use by poke()
234  * is_external - if non-null, used to check which segments go into
235  *               external memory (writable only by software loader)
236  * poke        - called with each memory segment; errors indicated
237  *               by returning negative values.
238  *
239  * Caller is responsible for halting CPU as needed, such as when
240  * overwriting a second stage loader.
241  */
242 static int parse_ihex(FILE *image, void *context,
243         bool (*is_external)(uint32_t addr, size_t len),
244         int (*poke) (void *context, uint32_t addr, bool external,
245         const unsigned char *data, size_t len))
246 {
247         unsigned char data[1023];
248         uint32_t data_addr = 0;
249         size_t data_len = 0;
250         int rc;
251         int first_line = 1;
252         bool external = false;
253
254         /* Read the input file as an IHEX file, and report the memory segments
255          * as we go.  Each line holds a max of 16 bytes, but uploading is
256          * faster (and EEPROM space smaller) if we merge those lines into larger
257          * chunks.  Most hex files keep memory segments together, which makes
258          * such merging all but free.  (But it may still be worth sorting the
259          * hex files to make up for undesirable behavior from tools.)
260          *
261          * Note that EEPROM segments max out at 1023 bytes; the upload protocol
262          * allows segments of up to 64 KBytes (more than a loader could handle).
263          */
264         for (;;) {
265                 char buf[512], *cp;
266                 char tmp, type;
267                 size_t len;
268                 unsigned idx, off;
269
270                 cp = fgets(buf, sizeof(buf), image);
271                 if (cp == NULL) {
272                         logerror("EOF without EOF record!\n");
273                         break;
274                 }
275
276                 /* EXTENSION: "# comment-till-end-of-line", for copyrights etc */
277                 if (buf[0] == '#')
278                         continue;
279
280                 if (buf[0] != ':') {
281                         logerror("not an ihex record: %s", buf);
282                         return -2;
283                 }
284
285                 /* ignore any newline */
286                 cp = strchr(buf, '\n');
287                 if (cp)
288                         *cp = 0;
289
290                 if (verbose >= 3)
291                         logerror("** LINE: %s\n", buf);
292
293                 /* Read the length field (up to 16 bytes) */
294                 tmp = buf[3];
295                 buf[3] = 0;
296                 len = strtoul(buf+1, NULL, 16);
297                 buf[3] = tmp;
298
299                 /* Read the target offset (address up to 64KB) */
300                 tmp = buf[7];
301                 buf[7] = 0;
302                 off = (unsigned int)strtoul(buf+3, NULL, 16);
303                 buf[7] = tmp;
304
305                 /* Initialize data_addr */
306                 if (first_line) {
307                         data_addr = off;
308                         first_line = 0;
309                 }
310
311                 /* Read the record type */
312                 tmp = buf[9];
313                 buf[9] = 0;
314                 type = (char)strtoul(buf+7, NULL, 16);
315                 buf[9] = tmp;
316
317                 /* If this is an EOF record, then make it so. */
318                 if (type == 1) {
319                         if (verbose >= 2)
320                                 logerror("EOF on hexfile\n");
321                         break;
322                 }
323
324                 if (type != 0) {
325                         logerror("unsupported record type: %u\n", type);
326                         return -3;
327                 }
328
329                 if ((len * 2) + 11 > strlen(buf)) {
330                         logerror("record too short?\n");
331                         return -4;
332                 }
333
334                 /* FIXME check for _physically_ contiguous not just virtually
335                  * e.g. on FX2 0x1f00-0x2100 includes both on-chip and external
336                  * memory so it's not really contiguous */
337
338                 /* flush the saved data if it's not contiguous,
339                 * or when we've buffered as much as we can.
340                 */
341                 if (data_len != 0
342                         && (off != (data_addr + data_len)
343                         /* || !merge */
344                         || (data_len + len) > sizeof(data))) {
345                                 if (is_external)
346                                         external = is_external(data_addr, data_len);
347                                 rc = poke(context, data_addr, external, data, data_len);
348                                 if (rc < 0)
349                                         return -1;
350                                 data_addr = off;
351                                 data_len = 0;
352                 }
353
354                 /* append to saved data, flush later */
355                 for (idx = 0, cp = buf+9 ;  idx < len ;  idx += 1, cp += 2) {
356                         tmp = cp[2];
357                         cp[2] = 0;
358                         data[data_len + idx] = (uint8_t)strtoul(cp, NULL, 16);
359                         cp[2] = tmp;
360                 }
361                 data_len += len;
362         }
363
364
365         /* flush any data remaining */
366         if (data_len != 0) {
367                 if (is_external)
368                         external = is_external(data_addr, data_len);
369                 rc = poke(context, data_addr, external, data, data_len);
370                 if (rc < 0)
371                         return -1;
372         }
373         return 0;
374 }
375
376 /*
377  * Parse a binary image file and write it as is to the target.
378  * Applies to Cypress BIX images for RAM or Cypress IIC images
379  * for EEPROM.
380  *
381  * image       - the BIX image file
382  * context     - for use by poke()
383  * is_external - if non-null, used to check which segments go into
384  *               external memory (writable only by software loader)
385  * poke        - called with each memory segment; errors indicated
386  *               by returning negative values.
387  *
388  * Caller is responsible for halting CPU as needed, such as when
389  * overwriting a second stage loader.
390  */
391 static int parse_bin(FILE *image, void *context,
392         bool (*is_external)(uint32_t addr, size_t len), int (*poke)(void *context,
393         uint32_t addr, bool external, const unsigned char *data, size_t len))
394 {
395         unsigned char data[4096];
396         uint32_t data_addr = 0;
397         size_t data_len = 0;
398         int rc;
399         bool external = false;
400
401         for (;;) {
402                 data_len = fread(data, 1, 4096, image);
403                 if (data_len == 0)
404                         break;
405                 if (is_external)
406                         external = is_external(data_addr, data_len);
407                 rc = poke(context, data_addr, external, data, data_len);
408                 if (rc < 0)
409                         return -1;
410                 data_addr += (uint32_t)data_len;
411         }
412         return feof(image)?0:-1;
413 }
414
415 /*
416  * Parse a Cypress IIC image file and invoke the poke() function on the
417  * various segments for writing to RAM
418  *
419  * image       - the IIC image file
420  * context     - for use by poke()
421  * is_external - if non-null, used to check which segments go into
422  *               external memory (writable only by software loader)
423  * poke        - called with each memory segment; errors indicated
424  *               by returning negative values.
425  *
426  * Caller is responsible for halting CPU as needed, such as when
427  * overwriting a second stage loader.
428  */
429 static int parse_iic(FILE *image, void *context,
430         bool (*is_external)(uint32_t addr, size_t len),
431         int (*poke)(void *context, uint32_t addr, bool external, const unsigned char *data, size_t len))
432 {
433         unsigned char data[4096];
434         uint32_t data_addr = 0;
435         size_t data_len = 0, read_len;
436         uint8_t block_header[4];
437         int rc;
438         bool external = false;
439         long file_size, initial_pos;
440
441         initial_pos = ftell(image);
442         if (initial_pos < 0)
443                 return -1;
444
445         if (fseek(image, 0L, SEEK_END) != 0)
446                 return -1;
447         file_size = ftell(image);
448         if (fseek(image, initial_pos, SEEK_SET) != 0)
449                 return -1;
450         for (;;) {
451                 /* Ignore the trailing reset IIC data (5 bytes) */
452                 if (ftell(image) >= (file_size - 5))
453                         break;
454                 if (fread(&block_header, 1, sizeof(block_header), image) != 4) {
455                         logerror("unable to read IIC block header\n");
456                         return -1;
457                 }
458                 data_len = (block_header[0] << 8) + block_header[1];
459                 data_addr = (block_header[2] << 8) + block_header[3];
460                 if (data_len > sizeof(data)) {
461                         /* If this is ever reported as an error, switch to using malloc/realloc */
462                         logerror("IIC data block too small - please report this error to libusb.info\n");
463                         return -1;
464                 }
465                 read_len = fread(data, 1, data_len, image);
466                 if (read_len != data_len) {
467                         logerror("read error\n");
468                         return -1;
469                 }
470                 if (is_external)
471                         external = is_external(data_addr, data_len);
472                 rc = poke(context, data_addr, external, data, data_len);
473                 if (rc < 0)
474                         return -1;
475         }
476         return 0;
477 }
478
479 /* the parse call will be selected according to the image type */
480 static int (*parse[IMG_TYPE_MAX])(FILE *image, void *context, bool (*is_external)(uint32_t addr, size_t len),
481            int (*poke)(void *context, uint32_t addr, bool external, const unsigned char *data, size_t len))
482            = { parse_ihex, parse_iic, parse_bin };
483
484 /*****************************************************************************/
485
486 /*
487  * For writing to RAM using a first (hardware) or second (software)
488  * stage loader and 0xA0 or 0xA3 vendor requests
489  */
490 typedef enum {
491         _undef = 0,
492         internal_only,          /* hardware first-stage loader */
493         skip_internal,          /* first phase, second-stage loader */
494         skip_external           /* second phase, second-stage loader */
495 } ram_mode;
496
497 struct ram_poke_context {
498         libusb_device_handle *device;
499         ram_mode mode;
500         size_t total, count;
501 };
502
503 #define RETRY_LIMIT 5
504
505 static int ram_poke(void *context, uint32_t addr, bool external,
506         const unsigned char *data, size_t len)
507 {
508         struct ram_poke_context *ctx = (struct ram_poke_context*)context;
509         int rc;
510         unsigned retry = 0;
511
512         switch (ctx->mode) {
513         case internal_only:             /* CPU should be stopped */
514                 if (external) {
515                         logerror("can't write %u bytes external memory at 0x%08x\n",
516                                 (unsigned)len, addr);
517                         return -EINVAL;
518                 }
519                 break;
520         case skip_internal:             /* CPU must be running */
521                 if (!external) {
522                         if (verbose >= 2) {
523                                 logerror("SKIP on-chip RAM, %u bytes at 0x%08x\n",
524                                         (unsigned)len, addr);
525                         }
526                         return 0;
527                 }
528                 break;
529         case skip_external:             /* CPU should be stopped */
530                 if (external) {
531                         if (verbose >= 2) {
532                                 logerror("SKIP external RAM, %u bytes at 0x%08x\n",
533                                         (unsigned)len, addr);
534                         }
535                         return 0;
536                 }
537                 break;
538         case _undef:
539         default:
540                 logerror("bug\n");
541                 return -EDOM;
542         }
543
544         ctx->total += len;
545         ctx->count++;
546
547         /* Retry this till we get a real error. Control messages are not
548          * NAKed (just dropped) so time out means is a real problem.
549          */
550         while ((rc = ezusb_write(ctx->device,
551                 external ? "write external" : "write on-chip",
552                 external ? RW_MEMORY : RW_INTERNAL,
553                 addr, data, len)) < 0
554                 && retry < RETRY_LIMIT) {
555                 if (rc != LIBUSB_ERROR_TIMEOUT)
556                         break;
557                 retry += 1;
558         }
559         return rc;
560 }
561
562 /*
563  * Load a Cypress Image file into target RAM.
564  * See http://www.cypress.com/?docID=41351 (AN76405 PDF) for more info.
565  */
566 static int fx3_load_ram(libusb_device_handle *device, const char *path)
567 {
568         uint32_t dCheckSum, dExpectedCheckSum, dAddress, i, dLen, dLength;
569         uint32_t* dImageBuf;
570         unsigned char *bBuf, hBuf[4], blBuf[4], rBuf[4096];
571         FILE *image;
572         int ret = 0;
573
574         image = fopen(path, "rb");
575         if (image == NULL) {
576                 logerror("unable to open '%s' for input\n", path);
577                 return -2;
578         } else if (verbose)
579                 logerror("open firmware image %s for RAM upload\n", path);
580
581         // Read header
582         if (fread(hBuf, sizeof(char), sizeof(hBuf), image) != sizeof(hBuf)) {
583                 logerror("could not read image header");
584                 ret = -3;
585                 goto exit;
586         }
587
588         // check "CY" signature byte and format
589         if ((hBuf[0] != 'C') || (hBuf[1] != 'Y')) {
590                 logerror("image doesn't have a CYpress signature\n");
591                 ret = -3;
592                 goto exit;
593         }
594
595         // Check bImageType
596         switch(hBuf[3]) {
597         case 0xB0:
598                 if (verbose)
599                         logerror("normal FW binary %s image with checksum\n", (hBuf[2]&0x01)?"data":"executable");
600                 break;
601         case 0xB1:
602                 logerror("security binary image is not currently supported\n");
603                 ret = -3;
604                 goto exit;
605         case 0xB2:
606                 logerror("VID:PID image is not currently supported\n");
607                 ret = -3;
608                 goto exit;
609         default:
610                 logerror("invalid image type 0x%02X\n", hBuf[3]);
611                 ret = -3;
612                 goto exit;
613         }
614
615         // Read the bootloader version
616         if (verbose) {
617                 if ((ezusb_read(device, "read bootloader version", RW_INTERNAL, 0xFFFF0020, blBuf, 4) < 0)) {
618                         logerror("Could not read bootloader version\n");
619                         ret = -8;
620                         goto exit;
621                 }
622                 logerror("FX3 bootloader version: 0x%02X%02X%02X%02X\n", blBuf[3], blBuf[2], blBuf[1], blBuf[0]);
623         }
624
625         dCheckSum = 0;
626         if (verbose)
627                 logerror("writing image...\n");
628         while (1) {
629                 if ((fread(&dLength, sizeof(uint32_t), 1, image) != 1) ||  // read dLength
630                         (fread(&dAddress, sizeof(uint32_t), 1, image) != 1)) { // read dAddress
631                         logerror("could not read image");
632                         ret = -3;
633                         goto exit;
634                 }
635                 if (dLength == 0)
636                         break; // done
637
638                 // coverity[tainted_data]
639                 dImageBuf = (uint32_t*)calloc(dLength, sizeof(uint32_t));
640                 if (dImageBuf == NULL) {
641                         logerror("could not allocate buffer for image chunk\n");
642                         ret = -4;
643                         goto exit;
644                 }
645
646                 // read sections
647                 if (fread(dImageBuf, sizeof(uint32_t), dLength, image) != dLength) {
648                         logerror("could not read image");
649                         free(dImageBuf);
650                         ret = -3;
651                         goto exit;
652                 }
653                 for (i = 0; i < dLength; i++)
654                         dCheckSum += dImageBuf[i];
655                 dLength <<= 2; // convert to Byte length
656                 bBuf = (unsigned char*) dImageBuf;
657
658                 while (dLength > 0) {
659                         dLen = 4096; // 4K max
660                         if (dLen > dLength)
661                                 dLen = dLength;
662                         if ((ezusb_write(device, "write firmware", RW_INTERNAL, dAddress, bBuf, dLen) < 0) ||
663                                 (ezusb_read(device, "read firmware", RW_INTERNAL, dAddress, rBuf, dLen) < 0)) {
664                                 logerror("R/W error\n");
665                                 free(dImageBuf);
666                                 ret = -5;
667                                 goto exit;
668                         }
669                         // Verify data: rBuf with bBuf
670                         for (i = 0; i < dLen; i++) {
671                                 if (rBuf[i] != bBuf[i]) {
672                                         logerror("verify error");
673                                         free(dImageBuf);
674                                         ret = -6;
675                                         goto exit;
676                                 }
677                         }
678
679                         dLength -= dLen;
680                         bBuf += dLen;
681                         dAddress += dLen;
682                 }
683                 free(dImageBuf);
684         }
685
686         // read pre-computed checksum data
687         if ((fread(&dExpectedCheckSum, sizeof(uint32_t), 1, image) != 1) ||
688                 (dCheckSum != dExpectedCheckSum)) {
689                 logerror("checksum error\n");
690                 ret = -7;
691                 goto exit;
692         }
693
694         // transfer execution to Program Entry
695         if (!ezusb_fx3_jump(device, dAddress)) {
696                 ret = -6;
697         }
698
699 exit:
700         fclose(image);
701         return ret;
702 }
703
704 /*
705  * Load a firmware file into target RAM. device is the open libusb
706  * device, and the path is the name of the source file. Open the file,
707  * parse the bytes, and write them in one or two phases.
708  *
709  * If stage == 0, this uses the first stage loader, built into EZ-USB
710  * hardware but limited to writing on-chip memory or CPUCS.  Everything
711  * is written during one stage, unless there's an error such as the image
712  * holding data that needs to be written to external memory.
713  *
714  * Otherwise, things are written in two stages.  First the external
715  * memory is written, expecting a second stage loader to have already
716  * been loaded.  Then file is re-parsed and on-chip memory is written.
717  */
718 int ezusb_load_ram(libusb_device_handle *device, const char *path, int fx_type, int img_type, int stage)
719 {
720         FILE *image;
721         uint32_t cpucs_addr;
722         bool (*is_external)(uint32_t off, size_t len);
723         struct ram_poke_context ctx;
724         int status;
725         uint8_t iic_header[8] = { 0 };
726         int ret = 0;
727
728         if (fx_type == FX_TYPE_FX3)
729                 return fx3_load_ram(device, path);
730
731         image = fopen(path, "rb");
732         if (image == NULL) {
733                 logerror("%s: unable to open for input.\n", path);
734                 return -2;
735         } else if (verbose > 1)
736                 logerror("open firmware image %s for RAM upload\n", path);
737
738         if (img_type == IMG_TYPE_IIC) {
739                 if ( (fread(iic_header, 1, sizeof(iic_header), image) != sizeof(iic_header))
740                   || (((fx_type == FX_TYPE_FX2LP) || (fx_type == FX_TYPE_FX2)) && (iic_header[0] != 0xC2))
741                   || ((fx_type == FX_TYPE_AN21) && (iic_header[0] != 0xB2))
742                   || ((fx_type == FX_TYPE_FX1) && (iic_header[0] != 0xB6)) ) {
743                         logerror("IIC image does not contain executable code - cannot load to RAM.\n");
744                         ret = -1;
745                         goto exit;
746                 }
747         }
748
749         /* EZ-USB original/FX and FX2 devices differ, apart from the 8051 core */
750         switch(fx_type) {
751         case FX_TYPE_FX2LP:
752                 cpucs_addr = 0xe600;
753                 is_external = fx2lp_is_external;
754                 break;
755         case FX_TYPE_FX2:
756                 cpucs_addr = 0xe600;
757                 is_external = fx2_is_external;
758                 break;
759         default:
760                 cpucs_addr = 0x7f92;
761                 is_external = fx_is_external;
762                 break;
763         }
764
765         /* use only first stage loader? */
766         if (stage == 0) {
767                 ctx.mode = internal_only;
768
769                 /* if required, halt the CPU while we overwrite its code/data */
770                 if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, false))
771                 {
772                         ret = -1;
773                         goto exit;
774                 }
775
776                 /* 2nd stage, first part? loader was already uploaded */
777         } else {
778                 ctx.mode = skip_internal;
779
780                 /* let CPU run; overwrite the 2nd stage loader later */
781                 if (verbose)
782                         logerror("2nd stage: write external memory\n");
783         }
784
785         /* scan the image, first (maybe only) time */
786         ctx.device = device;
787         ctx.total = ctx.count = 0;
788         status = parse[img_type](image, &ctx, is_external, ram_poke);
789         if (status < 0) {
790                 logerror("unable to upload %s\n", path);
791                 ret = status;
792                 goto exit;
793         }
794
795         /* second part of 2nd stage: rescan */
796         // TODO: what should we do for non HEX images there?
797         if (stage) {
798                 ctx.mode = skip_external;
799
800                 /* if needed, halt the CPU while we overwrite the 1st stage loader */
801                 if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, false))
802                 {
803                         ret = -1;
804                         goto exit;
805                 }
806
807                 /* at least write the interrupt vectors (at 0x0000) for reset! */
808                 rewind(image);
809                 if (verbose)
810                         logerror("2nd stage: write on-chip memory\n");
811                 status = parse_ihex(image, &ctx, is_external, ram_poke);
812                 if (status < 0) {
813                         logerror("unable to completely upload %s\n", path);
814                         ret = status;
815                         goto exit;
816                 }
817         }
818
819         if (verbose && (ctx.count != 0)) {
820                 logerror("... WROTE: %d bytes, %d segments, avg %d\n",
821                         (int)ctx.total, (int)ctx.count, (int)(ctx.total/ctx.count));
822         }
823
824         /* if required, reset the CPU so it runs what we just uploaded */
825         if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, true))
826                 ret = -1;
827
828 exit:
829         fclose(image);
830         return ret;
831 }