source: tt-loader/main.c @ 13

Last change on this file since 13 was 13, checked in by guillaume, 14 years ago

Fix compilation in some case

File size: 26.6 KB
Line 
1/*
2 * tt-loader - A system loader through USB derived from OMAP Flash Loader
3 *
4 * Copyright (C) 2008 Guillaume Bougard <gbougard@pkg.fr>
5 * Copyright (C) 2005 Luis Recuerda <lrec@helios.homeip.net>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 *
21 */
22
23#include <stdio.h>
24#include <string.h>
25#include <unistd.h>
26#include <sys/stat.h>
27#include <sys/types.h>
28#include <sys/times.h>
29#include <fcntl.h>
30#include <usb.h>
31#include <endian.h>
32#include <byteswap.h>
33#include <errno.h>
34
35extern unsigned long crc32( unsigned long crc, char* buf, unsigned int len);
36
37/*
38 * Here Vendor/Product detected for the target device
39 */
40#define OMAP_VENDOR             0x0451
41#define OMAP_PRODUCT    0x3f01
42
43#define IN_EP   0x81
44#define OUT_EP  0x02
45
46/*
47 * Length of memory dump lines
48 */
49#define DUMP_LINE_SIZE          32
50
51struct mem_file {
52        void *content ;
53        int size ;
54        char *filename ;
55};
56
57/*
58 * MAX_SIZE is the maximum size of the 2nd.bin program
59 */
60#define MAX_SIZE        65536
61#define CHUNK_SIZE      8192
62static char     buffer[MAX_SIZE + 128];
63static int      buffsize = 0;
64static struct mem_file cmdfile = { NULL, 0, NULL };
65static double btime ;
66static double ticks ;
67
68#define log1(X)         fprintf(stderr, "%9.3f: "X,((double)times(NULL)-btime)/ticks)
69#define log2(X,Y)       fprintf(stderr, "%9.3f: "X,((double)times(NULL)-btime)/ticks,(Y))
70#define log3(X,Y,Z)     fprintf(stderr, "%9.3f: "X,((double)times(NULL)-btime)/ticks,(Y),(Z))
71#define log4(W,X,Y,Z)   fprintf(stderr, "%9.3f: "W,((double)times(NULL)-btime)/ticks,(X),(Y),(Z))
72
73#if __BYTE_ORDER == __LITTLE_ENDIAN
74# define cpu_to_le32(x) (x)
75# define le32_to_cpu(x) (x)
76#else
77# define cpu_to_le32(x) bswap_32 (x)
78# define le32_to_cpu(x) bswap_32 (x)
79#endif
80
81static inline unsigned round_up (unsigned v, unsigned d)
82{
83        v+= --d;
84        return v & ~d;
85}
86
87static int stringcopy( char * dest, const char *src, int max )
88{
89        char *tmp = dest, *s = (char *) src;
90        int count = 0 ;
91       
92        while (count++ < max)
93                if (!(*tmp++ = *s++ ))
94                        break ;
95       
96        return count;
97}
98
99static int send_cmd (usb_dev_handle *handle, const char req, const char *src)
100{
101        int     res, len = 5 ;
102       
103        buffer[0]= 'T';
104        buffer[1]= 'I';
105        buffer[2]= 'S';
106        buffer[3]= req ;
107        buffer[4]= '\0' ;
108        if (src!=NULL)
109                len += stringcopy (&buffer[4], src, 60);
110        else
111                len = 4 ;
112        buffer[63]= '\0' ; // truncate anyway
113       
114        res= usb_bulk_write (handle, OUT_EP, buffer, len, 1000);
115        if (res < len)
116        {
117                log2("Error in usb_bulk_write during send_char: %d/4\n", res);
118                return 0;
119        }
120       
121        return 1;
122}
123
124static int send_binsize (usb_dev_handle *handle, int size)
125{
126        int     res;
127        buffer[0]= 'T';
128        buffer[1]= 'I';
129        buffer[2]= 'S';
130        buffer[3]= 's';
131        *(u_int32_t *) &buffer[4]= cpu_to_le32 ( size < CHUNK_SIZE ? size : CHUNK_SIZE );
132       
133        res= usb_bulk_write (handle, OUT_EP, buffer, 8, 1000);
134        if (res < 8)
135        {
136                log2("Error in usb_bulk_write during send_binsize: %d/8\n", res);
137                return 0;
138        }
139       
140        return 1;
141}
142
143static int send_word (usb_dev_handle *handle, const char req, int word)
144{
145        int     res;
146        buffer[0]= 'T';
147        buffer[1]= 'I';
148        buffer[2]= 'S';
149        buffer[3]= req;
150        *(u_int32_t *) &buffer[4]= cpu_to_le32 (word);
151       
152        res= usb_bulk_write (handle, OUT_EP, buffer, 8, 1000);
153        if (res < 8)
154        {
155                log2("Error in usb_bulk_write: %d/8\n", res);
156                return 0;
157        }
158       
159        return 1;
160}
161
162static int send_poke (usb_dev_handle *handle, int poke)
163{
164        int     res;
165        buffer[0]= 'T';
166        buffer[1]= 'I';
167        buffer[2]= 'S';
168        buffer[3]= 'p';
169        *(u_int32_t *) &buffer[4]= cpu_to_le32 (poke);
170       
171        res= usb_bulk_write (handle, OUT_EP, buffer, 8, 1000);
172        if (res < 8)
173        {
174                log2("Error in usb_bulk_write: %d/8\n", res);
175                return 0;
176        }
177       
178        return 1;
179}
180
181static struct mem_file readfile( char *filename )
182{
183        struct mem_file toread = { NULL, 0, NULL };
184        int fd= open (filename, O_RDONLY);
185       
186        if (fd < 0)
187        {
188                log3("Error opening %s file (err=%d)\n", filename, errno);
189                return toread;
190        }
191       
192        toread.size = lseek (fd, 0, SEEK_END);
193        if (toread.size < 0  ||  lseek (fd, 0, SEEK_SET) < 0)
194        {
195                log3("Error with lseek other %s file (err=%d)\n", filename, errno);
196                close (fd);
197                return toread;
198        }
199       
200        toread.content= malloc (round_up (toread.size, 4));
201        if (toread.content == NULL)
202        {
203                log2("Out of memory requesting %d bytes\n", toread.size);
204                close (fd);
205                return toread;
206        }
207       
208        if ((toread.size= read (fd, toread.content, toread.size)) < 0)
209        {
210                log3("Error reading %s file (err=%d)\n", filename, errno);
211                close (fd);
212                return toread;
213        }
214       
215        close (fd);
216       
217        return toread ;
218}
219
220static int savefile( char *filename, struct mem_file buffer )
221{
222        int fd= creat (filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH );
223       
224        if (fd < 0)
225        {
226                log3("Error opening %s file for writing (err=%d)\n", filename, errno);
227                return 1;
228        }
229       
230        if (buffer.size != write (fd, buffer.content, buffer.size))
231        {
232                log3("Error writing %s file (err=%d)\n", filename, errno);
233                close (fd);
234                return 1;
235        }
236       
237        close (fd);
238       
239        return 0 ;
240}
241
242static int process (usb_dev_handle *handle)
243{
244        int     err = -1 ;
245       
246        log1("OMAP found, trying to configure it\n");
247       
248        for (;;)
249        {
250                err= usb_set_configuration (handle, 1);
251                if (err == 0)
252                        break;
253               
254                if (err == -ENODEV)
255                {
256                        log1("OMAP error, retrying\n");
257                        return 1;
258                }
259               
260                sleep (1);
261        }
262       
263        err = usb_claim_interface (handle, 0);
264        if ( err < 0)
265                log2("Error in usb_claim_interface (%d)\n",err);
266        else
267        {
268                char inbuff[MAX_SIZE + 128];
269                int     insize= usb_bulk_read (handle, IN_EP, inbuff, sizeof (inbuff), 1000);
270               
271                if (insize < 48)
272                        log2("Error in usb_bulk_read: %d\n", insize);
273                else
274                {
275                        log1("OMAP 1st boot contacted, sending 2nd boot\n");
276                       
277                        memcpy (&buffer[20], inbuff, 44);
278                        memcpy (&buffer[80], inbuff, 48);
279                       
280                        char *p = buffer;
281                        int     size= buffsize;
282                        while (size > 0)
283                        {
284                                int chunksize = size < CHUNK_SIZE ? size : CHUNK_SIZE ;
285                                int     outsize = usb_bulk_write (handle, OUT_EP, p, chunksize, 1000);
286                                if (outsize < chunksize)
287                                {
288                                        log3("Error in usb_bulk_write: %d/%d\n", outsize,chunksize);
289                                        break;
290                                }
291
292                                p+= chunksize;
293                                size-= chunksize;
294                        }
295                       
296                        if (size <= 0)
297                        {
298                                log2("Sent %d bytes to OMAP\n",buffsize);
299                               
300                                p= NULL;
301                                size= 0;
302                               
303                                int     res=1, sz= 0, loop= 1, cmd=0, ftag=0, finfo=0, fline=0 ;
304                                int vendor, device, info ;
305                                char *cmdp = cmdfile.content ;
306                                struct mem_file current = { NULL, 0, NULL };
307                               
308                                err = 1 ; // Set error by default
309                               
310                                while (loop != 0)
311                                {
312                                        if (loop<0) loop++ ; // Avoid infinite loop
313                                       
314                                        if (res>0 || ftag)
315                                                res= usb_bulk_read (handle, IN_EP,
316                                                        inbuff, sizeof (inbuff), 5000);
317                                       
318                                        if (res < 0)
319                                        {
320                                                log2("Error in usb_bulk_read: %d\n",res);
321                                                break;
322                                        }
323                                       
324                                        if (ftag)
325                                        {
326                                                switch (ftag)
327                                                {
328                                                        case 0xaaaa0001:
329                                                                // A string should be in the buffer with length still set in finfo
330                                                                if ( res != finfo)
331                                                                {
332                                                                        log3("Error waiting string from flasher program: length = %d vs %d expected\n", res, finfo);
333                                                                        break ;
334                                                                }
335                                                                // Fix the string just in case
336                                                                inbuff[res] = '\0' ;
337                                                                if (fline)
338                                                                        fprintf(stderr, "%s",inbuff);
339                                                                else
340                                                                        log2("Flasher: %s", inbuff);
341                                                                if ( inbuff[res-1] == '\n' )
342                                                                        fline = 0 ;
343                                                                else
344                                                                        fline ++ ;
345                                                                break ;
346                                                        case 0xaaaa0002:
347                                                                finfo = le32_to_cpu (*(u_int32_t *) inbuff);
348                                                                break ;
349                                                        case 0xaaaa0003:
350                                                                finfo = le32_to_cpu (*(u_int32_t *) inbuff);
351                                                                log2("Flasher: NAND read = 0x%08X\n", finfo);
352                                                                break ;
353                                                        case 0xaaaa0004:
354                                                                finfo = le32_to_cpu (*(u_int32_t *) inbuff);
355                                                                log2("Flasher: NAND size = 0x%08X\n", finfo);
356                                                                break ;
357                                                        case 0xaaaa0005:
358                                                                finfo = le32_to_cpu (*(u_int32_t *) inbuff);
359                                                                log2("Flasher: Error code = %d\n", finfo);
360                                                                err = - finfo ; // Will quit on error
361                                                                break ;
362                                                        case 0xaaaa0006:
363                                                                finfo = le32_to_cpu (*(u_int32_t *) inbuff);
364                                                                log2("Flasher: NAND remain = 0x%08X\n", finfo);
365                                                                break ;
366                                                }
367                                                ftag = 0 ;
368                                                continue ;
369                                        }
370                                       
371                                        if (err<0)
372                                        {
373                                                err = -err ; // Keep err as positive number
374                                                if (send_cmd (handle,'e',NULL))
375                                                        log1("Asking stop\n");
376                                                else
377                                                        log1("Can't ask to stop\n");
378                                                break ; // Leave loop
379                                        }
380
381                                        if (res >= 4)
382                                        {
383                                                if (inbuff[0] == 'T'  &&  inbuff[1] == 'I'  &&
384                                                        inbuff[2] == 'S')
385                                                {
386                                                        switch (inbuff[3])
387                                                        {
388                                                        case 'f':
389                                                                // Target claims a file
390                                                                log3("OMAP File asked: %s (%d bytes)\n", &inbuff[4], size);
391                                                                if (!send_binsize (handle, size))
392                                                                        loop = 0 ; // Just quit on error
393                                                                break;
394                                                               
395                                                        case 'o':
396                                                                // Update upload file buffer offset
397                                                                sz= le32_to_cpu (*(u_int32_t *) &inbuff[4]);
398                                                                p+= sz;
399                                                                size-= sz;
400                                                                //log3("OMAP seek %d to 0x%08lX\n", sz, (long)p-(long)current.content);                                         // DEBUG
401                                                                if (size > 0  &&  !send_binsize (handle, size))
402                                                                        loop = 0 ; // Just quit on error
403                                                                if (size==0)
404                                                                        res = 0 ;
405                                                                break;
406                                                               
407                                                        case 'n':
408                                                                // Upload a requested size chunk from the file buffer
409                                                                sz= le32_to_cpu (*(u_int32_t *) &inbuff[4]);
410                                                                //log2("OMAP read %d\n", sz);                                   // DEBUG
411                                                                res= usb_bulk_write (handle, OUT_EP, p, sz, 1000);
412                                                                if (res < sz)
413                                                                {
414                                                                        log3("Error in usb_bulk_write: %d/%d\n", res, sz);
415                                                                        loop = 0 ; // Just quit on error
416                                                                }
417                                                                break;
418                                                               
419                                                        case 'I':
420                                                                info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
421                                                                log2("OMAP integer info: %d\n", info);
422                                                                break;
423                                                               
424                                                        case 'x':
425                                                                info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
426                                                                u_int32_t len = le32_to_cpu (*(u_int32_t *) &inbuff[8]);
427                                                                u_int32_t crc = le32_to_cpu (*(u_int32_t *) &inbuff[12]);
428                                                                log4("OMAP crc32 computing: pos 0x%08x/0x%08x, current crc32 0x%08X\n",info,len,crc);
429                                                                break;
430                                                               
431                                                        case 'A':
432                                                                info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
433                                                                log2("OMAP address info: 0x%08X\n", info);
434                                                                break;
435                                                               
436                                                        case 'C':
437                                                                info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
438                                                                log2("OMAP crc32 found: 0x%08X\n", info);
439                                                                break;
440                                                               
441                                                        case 'i':
442                                                                info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
443                                                                log2("OMAP Info returned: 0x%08X\n", info);
444                                                                res = 0 ; // Target is waiting a new command
445                                                                break;
446                                                               
447                                                        case 'v':
448                                                                vendor= le32_to_cpu (*(u_int32_t *) &inbuff[4]);
449                                                                log2("Flash Vendor found: 0x%02X\n", vendor);
450                                                                break;
451                                                               
452                                                        case 'd':
453                                                                device= le32_to_cpu (*(u_int32_t *) &inbuff[4]);
454                                                                log2("Flash Device found: 0x%02X\n", device);
455                                                                break;
456                                                               
457                                                        case 'm':
458                                                                log2("OMAP Message: %s\n", &inbuff[4]);
459                                                                break;
460                                                               
461                                                        case 'D':
462                                                                if (!current.content)
463                                                                {
464                                                                        log1("Can't dump memory without buffer\n");
465                                                                        loop = 0 ;
466                                                                        break ;
467                                                                }
468                                                                res -= 4 ;
469                                                                if (res < 1)
470                                                                {
471                                                                        log2("Received empty memory dump (res=%d)\n",res);
472                                                                        // reset buffer size anyway
473                                                                        current.size = 0 ;
474                                                                        res = 0 ; // Target is waiting a new command
475                                                                       
476                                                                } else {
477                                                                        if (res > size)
478                                                                        {
479                                                                                log2("Can't dump %d bytes as buffer is full\n",res);
480                                                                                loop = 0 ;
481                                                                                break ;
482                                                                        }
483                                                                        memcpy(p,&inbuff[4],res);
484                                                                        p += res ;
485                                                                        size -= res ;
486                                                                }
487                                                                if ( size == 0 )
488                                                                {
489                                                                        log2("%d bytes dumped to buffer\n",current.size);
490                                                                        res = 0 ; // Target is waiting a new command
491                                                                }
492                                                                break;
493                                                               
494                                                        case 'M':
495                                                                sz = 0 ;
496                                                                res -= 4 ;
497                                                                while (sz<res)
498                                                                {
499                                                                        log2("0x%08X | ",info);
500                                                                       
501                                                                        loop=0 ;
502                                                                        while (++loop<=DUMP_LINE_SIZE)
503                                                                                fprintf (stderr,"%02hhX", inbuff[3+sz+loop]);
504                                                                        fprintf (stderr, " |");
505                                                                       
506                                                                        loop=0 ;
507                                                                        while (++loop<=DUMP_LINE_SIZE)
508                                                                                if ((int)inbuff[3+sz+loop]>=0x20 && (int)inbuff[3+sz+loop]<0x7f)
509                                                                                        fprintf (stderr,"%c", inbuff[3+sz+loop]);
510                                                                                else
511                                                                                        fprintf (stderr,".");
512                                                                       
513                                                                        fprintf (stderr,"|\n");
514                                                                       
515                                                                        info += DUMP_LINE_SIZE;
516                                                                        sz += DUMP_LINE_SIZE;
517                                                                }
518                                                                res = 0 ; // Target is waiting a new command
519                                                                break;
520                                                               
521                                                        case 'r':
522                                                                log2("OMAP is ready: %s\n", &inbuff[4]);
523                                                                res = 0 ; // Target is waiting a new command
524                                                                break;
525
526                                                        case 'b':
527                                                                // Boot command has been received
528                                                                info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
529                                                                log2("OMAP is booting at address: 0x%08X\n", info);
530                                                                loop = err = res = 0 ; // Quit now
531                                                                break;
532
533                                                        default:
534                                                                log2("Unknown packet type '%c'\n", inbuff[3]);
535                                                                break;
536                                                        }
537                                                } else
538                                                {
539                                                        info = le32_to_cpu (*(u_int32_t *) inbuff);
540                                                        switch (info)
541                                                        {
542                                                                case 0xaaaa0001:
543                                                                case 0xaaaa0002:
544                                                                case 0xaaaa0003:
545                                                                case 0xaaaa0004:
546                                                                case 0xaaaa0005:
547                                                                case 0xaaaa0006:
548                                                                        ftag = info ;
549                                                                        break ;
550                                                                case 0xff555580:
551                                                                        log1("Flasher: Command finished\n");
552                                                                        break ;
553                                                                default:
554                                                                        // Fix the string just in case
555                                                                        inbuff[res] = '\0' ;
556                                                                        // Strip final EOL in the string
557                                                                        if ( inbuff[res-1] == '\n' )
558                                                                                inbuff[res-1] = '\0' ;
559                                                                        if (res==4)
560                                                                                log3("Got: %s (0x%08X)\n", inbuff, info);
561                                                                        else
562                                                                                log2("Got: %s\n", inbuff);
563                                                        }
564                                                }
565                                        }
566                                        else
567                                        {
568                                                // Manage commands
569                                                if (cmd + 1 >= cmdfile.size)
570                                                {
571                                                        if (loop>0) {
572                                                                log1("Command file read finished\n");
573                                                                loop = 0 ;
574                                                        }
575                                                       
576                                                } else {
577                                                        // res < 4
578                                                        //log2("Next command is '%c'\n", cmdp[cmd]);                    // DEBUG
579                                                        switch (cmdp[cmd])
580                                                        {
581                                                        case 'D': // Save downloaded memory to a file still specified
582                                                                if (current.filename == NULL)
583                                                                {
584                                                                        log1("Can't save without a file specified with 'F' command\n");
585                                                                        loop = 0 ; // Just quit on error
586                                                                        break ;
587                                                                }
588                                                                if (current.content == NULL)
589                                                                {
590                                                                        log2("Can't save without download buffer to file '%s'\n",current.filename);
591                                                                        loop = 0 ; // Just quit on error
592                                                                        break ;
593                                                                }
594                                                                if (current.size==0)
595                                                                        log2("Nothing to save, file %s is still up to date\n",current.filename);
596                                                                else if (savefile(current.filename, current)==0)
597                                                                {
598                                                                        info = crc32(0,current.content,current.size);
599                                                                        log3("Downloaded memory saved to file %s with CRC32=0x%08X\n",current.filename,info);
600                                                                } else
601                                                                {
602                                                                        log2("Can't save downloaded memory saved to file %s\n",current.filename);
603                                                                        // Just quit on error
604                                                                        loop = 0 ;
605                                                                }
606                                                                // Release memory
607                                                                free((void *)current.content);
608                                                                free((void *)current.filename);
609                                                                current.content = NULL ;
610                                                                current.filename = NULL ;
611                                                                res -- ;
612                                                                break;
613                                                        case 'd': // Save downloaded memory to a file
614                                                                cmd += 2 ;
615                                                                if (cmd >= cmdfile.size || cmdp[cmd] == '\0')
616                                                                {
617                                                                        log1("Bad 'd' format in command download\n");
618                                                                        break ;
619                                                                }
620                                                                if (current.content == NULL)
621                                                                {
622                                                                        log2("Can't save without download buffer to file '%s'\n",&cmdp[cmd]);
623                                                                        loop = 0 ; // Just quit on error
624                                                                        break ;
625                                                                }
626                                                                if (current.size==0)
627                                                                        log2("Nothing to save, file %s is still up to date\n",&cmdp[cmd]);
628                                                                else if (savefile(&cmdp[cmd], current)==0)
629                                                                {
630                                                                        info = crc32(0,current.content,current.size);
631                                                                        log3("Downloaded memory saved to file %s with CRC32=0x%08X\n",&cmdp[cmd],info);
632                                                                } else
633                                                                {
634                                                                        log2("Can't save downloaded memory saved to file %s\n",&cmdp[cmd]);
635                                                                        // Just quit on error
636                                                                        loop = 0 ;
637                                                                }
638                                                                // Release memory
639                                                                free((void *)current.content);
640                                                                current.content = NULL ;
641                                                                res -- ;
642                                                                break;
643                                                        case 'f': // Put a file to be uploaded in a memory buffer
644                                                                cmd += 2 ;
645                                                                if (cmd >= cmdfile.size || cmdp[cmd] == '\0')
646                                                                {
647                                                                        log1("Bad 'f' format in command file\n");
648                                                                        break ;
649                                                                }
650                                                                // Free previously used memory buffer
651                                                                if (current.content != NULL)
652                                                                        free((void *)current.content);
653                                                                current = readfile(&cmdp[cmd]);
654                                                                if (current.content == NULL)
655                                                                {
656                                                                        log2("Can't read file '%s'\n",&cmdp[cmd]);
657                                                                        loop = 0 ; // Just quit on error
658                                                                        break ;
659                                                                }
660                                                                p = current.content ;
661                                                                size = current.size ;
662                                                                // Say to OMAP target it can reclaim the file
663                                                                if (send_cmd (handle,'f',(const char *)&cmdp[cmd]))
664                                                                        log1("File loaded and ready for upload\n");
665                                                                else
666                                                                {
667                                                                        log1("Can't say we are ready for upload\n");
668                                                                        // Just quit on error
669                                                                        loop = 0 ;
670                                                                }
671                                                                break;
672                                                        case 'F': // Set a filename that would be loaded to check crc and saved
673                                                                cmd += 2 ;
674                                                                if (cmd >= cmdfile.size || cmdp[cmd] == '\0')
675                                                                {
676                                                                        log1("Bad 'F' format in command file\n");
677                                                                        break ;
678                                                                }
679                                                                // Free previously used memory buffer
680                                                                if (current.filename != NULL)
681                                                                        free((void *)current.filename);
682                                                                info = strlen(&cmdp[cmd]);
683                                                                if (info == 0)
684                                                                {
685                                                                        log2("Can't read filename '%s' length\n",&cmdp[cmd]);
686                                                                        loop = 0 ; // Just quit on error
687                                                                        break ;
688                                                                }
689                                                                current.filename = malloc (++info);
690                                                                if (current.filename == NULL)
691                                                                {
692                                                                        log2("Out of memory requesting %d bytes\n", info);
693                                                                        loop = 0 ; // Just quit on error
694                                                                        break ;
695                                                                }
696                                                                if (info!=stringcopy(current.filename,&cmdp[cmd],info))
697                                                                {
698                                                                        log2("Can't read filename '%s'\n",&cmdp[cmd]);
699                                                                        loop = 0 ; // Just quit on error
700                                                                        break ;
701                                                                }
702                                                                // still read next command
703                                                                res -- ;
704                                                                break;
705                                                        case 'C': // Get a CRC32 and send it to target
706                                                                cmd += 2 ;
707                                                                if (sscanf((const char *)&cmdp[cmd], "%i", &info) != 1)
708                                                                {
709                                                                        log2("Can't read crc32 '%s'\n",&cmdp[cmd]);
710                                                                        loop = 0 ; // Just quit on error
711                                                                        break ;
712                                                                }
713                                                                // compute the current CRC32 if a file is referenced and exists
714                                                                if (!info && current.filename != NULL)
715                                                                {
716                                                                        struct mem_file loader = readfile(current.filename);
717                                                                        if (loader.content == NULL)
718                                                                        {
719                                                                                log2("Can't read file '%s', will be initialized with target\n",current.filename);
720                                                                        } else
721                                                                        {
722                                                                                log3("Checking CRC32 of %d bytes from %s file\n",loader.size,current.filename);
723                                                                                info = crc32(0,loader.content,loader.size);
724                                                                                free(loader.content);
725                                                                        }
726                                                                }
727                                                                if (send_word (handle, 'C', info))
728                                                                        log2("Sending crc32 0x%02X\n", info);
729                                                                else
730                                                                {
731                                                                        log2("Can't send crc32 0x%02X\n", info);
732                                                                        loop = 0 ; // Just quit on error
733                                                                }
734                                                                break;
735                                                        case 'a': // Get an address and send it to target
736                                                                cmd += 2 ;
737                                                                if (sscanf((const char *)&cmdp[cmd], "%i", &info) != 1)
738                                                                {
739                                                                        log2("Can't read address '%s'\n",&cmdp[cmd]);
740                                                                        loop = 0 ; // Just quit on error
741                                                                        break ;
742                                                                }
743                                                                if (send_word (handle, 'a', info))
744                                                                        log2("Sending address 0x%02X\n", info);
745                                                                else
746                                                                {
747                                                                        log2("Can't send address 0x%02X\n", info);
748                                                                        loop = 0 ; // Just quit on error
749                                                                }
750                                                                break;
751                                                        case 'm': // Get a size in kB and ask a memory download
752                                                                cmd += 2 ;
753                                                                if (sscanf((const char *)&cmdp[cmd], "%i", &info) != 1)
754                                                                {
755                                                                        log2("Can't read size '%s'\n",&cmdp[cmd]);
756                                                                        loop = 0 ; // Just quit on error
757                                                                        break ;
758                                                                }
759                                                                // size unit is kbytes
760                                                                size = info * 1024 ;
761                                                                // Free previously used memory buffer
762                                                                if (current.content != NULL)
763                                                                        free((void *)current.content);
764                                                                current.size = size ;
765                                                                p = malloc (round_up (size, 4));
766                                                                if ( p == NULL)
767                                                                {
768                                                                        log2("Out of memory requesting %d bytes\n", round_up (size, 4));
769                                                                        loop=0 ;
770                                                                        break ;
771                                                                }
772                                                                current.content = p ;
773                                                                if (!(send_word (handle,'m',size)))
774                                                                {
775                                                                        log2("Can't ask to download %d bytes from memory\n",size);
776                                                                        loop = 0 ; // Just quit on error
777                                                                } else
778                                                                        log2("Allocated %d kBytes to download memory\n",info);
779                                                                break;
780                                                        case 'M': // Ask memory dump
781                                                                if (!(send_cmd (handle,'M',NULL)))
782                                                                {
783                                                                        log1("Can't ask to read memory\n");
784                                                                        loop = 0 ; // Just quit on error
785                                                                }
786                                                                break;
787                                                        case 'P': // Ask a peek onto the address
788                                                                if (!(send_cmd (handle,'P',NULL)))
789                                                                {
790                                                                        log1("Can't ask to peek memory\n");
791                                                                        loop = 0 ; // Just quit on error
792                                                                }
793                                                                break;
794                                                        case 'S': // Ask to change stack to the last given address
795                                                                if (send_cmd (handle,'S',NULL))
796                                                                        log1("Asking stack relocate\n");
797                                                                else
798                                                                {
799                                                                        log1("Can't ask to relocate stack\n");
800                                                                        loop = 0 ; // Just quit on error
801                                                                }
802                                                                break;
803                                                        case 'c': // Make a call to the last given address
804                                                                if (send_cmd (handle,'c',NULL))
805                                                                        log1("Asking function call\n");
806                                                                else
807                                                                {
808                                                                        log1("Can't ask to call a function\n");
809                                                                        loop = 0 ; // Just quit on error
810                                                                }
811                                                                break;
812                                                        case 'b': // Boot the target by just branching to the last given address
813                                                                if (send_cmd (handle,'b',NULL)) {
814                                                                        log1("Asking boot\n");
815                                                                        // Quit now witout error set
816                                                                        loop = err = -10 ;
817                                                                        cmd = cmdfile.size ;
818                                                                        res = 1 ;
819                                                                } else
820                                                                {
821                                                                        log1("Can't ask to boot\n");
822                                                                        loop = 0 ; // Just quit on error
823                                                                }
824                                                                break;
825                                                        case 'e': // End of commands
826                                                                log1("Commands read and sent\n");
827                                                                if (send_cmd (handle,'e',NULL))
828                                                                        log1("Asking stop\n");
829                                                                else
830                                                                        log1("Can't ask to stop\n");
831                                                                // Quit now witout error set
832                                                                loop = err = 0 ;
833                                                                cmd = cmdfile.size ;
834                                                                res = 1 ;
835                                                                break ;
836                                                        case 'k': // Boot a linux kernel to the last given address
837                                                                cmd += 2 ;
838                                                                if (sscanf((const char *)&cmdp[cmd], "%i", &info) != 1)
839                                                                {
840                                                                        log2("Can't read mach id '%s'\n",&cmdp[cmd]);
841                                                                        loop = 0 ; // Just quit on error
842                                                                        break ;
843                                                                }
844                                                                if (send_word (handle,'k', info)) {
845                                                                        log1("Asking kernel to boot\n");
846                                                                        // Quit now witout error set
847                                                                        loop = err = -10 ;
848                                                                        cmd = cmdfile.size ;
849                                                                        res = 1 ;
850                                                                } else
851                                                                {
852                                                                        log1("Can't ask to boot a kernel\n");
853                                                                        loop = 0 ; // Just quit on error
854                                                                }
855                                                                break;
856                                                        case 'p': // poke
857                                                                cmd += 2 ;
858                                                                if (sscanf((const char *)&cmdp[cmd], "%i", &info) != 1)
859                                                                {
860                                                                        log2("Can't read value to poke '%s'\n",&cmdp[cmd]);
861                                                                        loop = 0 ; // Just quit on error
862                                                                        break ;
863                                                                }
864                                                                if (send_poke (handle, info))
865                                                                        log2("Sending poke 0x%08X\n", info);
866                                                                else
867                                                                {
868                                                                        log2("Can't send poke 0x%08X\n", info);
869                                                                        loop = 0 ; // Just quit on error
870                                                                }
871                                                                break;
872                                                        case '#':
873                                                                cmd += 2 ;
874                                                                log2("%s\n", &cmdp[cmd]);
875                                                        case '/':
876                                                                // skip comments
877                                                                res -- ;
878                                                                break ;
879                                                               
880                                                        default:
881                                                                log2("Unknown command type '%c'\n",cmdp[cmd]);
882                                                                break;
883                                                        }
884                                                        // kind of readline
885                                                        while (cmdp[++cmd] != '\0' && cmd < cmdfile.size);
886                                                        // point to next line
887                                                        while (cmdp[++cmd] == '\0' && cmd < cmdfile.size);
888                                                        res ++ ;
889                                                }
890                                        }
891                                }
892                                // Free used memory buffer
893                                if (current.content != NULL)
894                                        free((void *)current.content);
895                                if (current.filename != NULL)
896                                        free((void *)current.filename);
897                        }
898                }
899        }
900       
901        if (err>=0) {
902                log1("Releasing usb interface\n");
903                err = usb_release_interface (handle, 0);
904                if (err < 0)
905                        log2("Error in usb_release_interface (%d)\n",err);
906                log1("Released usb interface\n");
907        }
908       
909        return err ;
910}
911
912enum {
913        ARG_PROGNAME,
914        ARG_2NDFILE,
915        ARG_CMDFILE,
916        NUM_ARGS
917};
918
919int main (int argc, char *argv[])
920{
921        int     size;
922        btime = (double) times(NULL);
923        ticks = (double) sysconf(_SC_CLK_TCK) / 1000 ;
924       
925        if (argc < NUM_ARGS)
926        {
927                log2("Usage: %s <2nd_boot_file> <command_file>\n", argv[ARG_PROGNAME]);
928                return 1;
929        }
930       
931        memset (buffer, 0, 128);
932       
933        u_int32_t       *p= (u_int32_t *) buffer;
934        p[0x00]= cpu_to_le32 (0xf0030002);
935       
936        int     fd= open (argv[ARG_2NDFILE], O_RDONLY);
937        if (fd < 0)
938        {
939                log1("open 2nd boot file\n");
940                return 1;
941        }
942        else
943        {
944                size= read (fd, &buffer[128], MAX_SIZE);
945                if (size < 0)
946                {
947                        log1("read 2nd boot file\n");
948                        close (fd);
949                        return 1;
950                }
951               
952                close (fd);
953                if (size < 1024)
954                {
955                        log2("2ndfile is too small! (%d bytes)\n", size);
956                        return 1;
957                }
958        }
959       
960        size= round_up (size, 4);
961       
962        p[0x21]= cpu_to_le32 (size - 0x40);
963       
964        p[0x01]= cpu_to_le32 (size);
965        p[0x02]= cpu_to_le32 (size);
966        p[0x03]= cpu_to_le32 (size);
967        p[0x10]= cpu_to_le32 (size);
968        p[0x11]= cpu_to_le32 (size);
969        p[0x12]= cpu_to_le32 (size);
970       
971        buffsize= 128 + round_up (size, 4);
972       
973        cmdfile = readfile(argv[ARG_CMDFILE]);
974        if (cmdfile.content == NULL)
975        {
976                log1("open cmdfile\n");
977                return 1;
978        } else {
979                int i = 0 ;
980                char *cmdbuffer = (char *)cmdfile.content ;
981                do {
982                        if (cmdbuffer[i] == '\n' || cmdbuffer[i] == '\r' || cmdbuffer[i] == ';')
983                                cmdbuffer[i] = '\0' ;
984                        // Skip comment line
985                        if (cmdbuffer[i] == '/') {
986                                while ( i++ < cmdfile.size ) {
987                                        if (cmdbuffer[i] == '\n' || cmdbuffer[i] == '\r') {
988                                                i-- ;
989                                                break ;
990                                        }
991                                }
992                        }
993                } while ( i++ < cmdfile.size );
994        }
995       
996        usb_init ();
997        usb_find_busses ();
998       
999        log1("Try to found OMAP730-USB connection\n");
1000       
1001        int     n= usb_find_devices ();
1002        if (n)
1003        {
1004                log1("Searching OMAP730-USB connection...\n");
1005                struct usb_bus  *bus;
1006                for (bus= usb_get_busses (); bus; bus= bus->next)
1007                {
1008                        struct usb_device       *dev;
1009                       
1010                        for (dev= bus->devices; dev; dev= dev->next)
1011                        {
1012                                usb_dev_handle  *handle;
1013                                if (dev->descriptor.idVendor == OMAP_VENDOR  &&
1014                                        dev->descriptor.idProduct == OMAP_PRODUCT  &&
1015                                        (handle= usb_open (dev)) != NULL)
1016                                {
1017                                        log1("Found OMAP730-USB connection\n");
1018                                        int res= process (handle);
1019                                        usb_close (handle);
1020                                        if (res == 0) {
1021                                                log1("OMAP730-USB connection processed\n");
1022                                                return 0 ;
1023                                        } else
1024                                                log1("OMAP730-USB processing failed\n");
1025                                }
1026                        }
1027                }
1028               
1029        } else {
1030                log1("No USB bus found\n");
1031        }
1032       
1033        // Free memory
1034        if (cmdfile.content!=NULL)
1035                free((void *)cmdfile.content);
1036       
1037        log1("No target connection found\n");
1038        return 1 ;
1039}
Note: See TracBrowser for help on using the repository browser.