OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [utils/] [bin2vmem.c] - Blame information for rev 283

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 julius
/*$$HEADER*/
2
/******************************************************************************/
3
/*                                                                            */
4
/*                    H E A D E R   I N F O R M A T I O N                     */
5
/*                                                                            */
6
/******************************************************************************/
7
 
8
// Project Name                   : ORPSoC v2
9
// File Name                      : bin2vmem.c
10
// Prepared By                    : jb, jb@orsoc.se
11
// Project Start                  : 2009-05-13
12
 
13
/*$$COPYRIGHT NOTICE*/
14
/******************************************************************************/
15
/*                                                                            */
16
/*                      C O P Y R I G H T   N O T I C E                       */
17
/*                                                                            */
18
/******************************************************************************/
19
/*
20
  This library is free software; you can redistribute it and/or
21
  modify it under the terms of the GNU Lesser General Public
22
  License as published by the Free Software Foundation;
23
  version 2.1 of the License, a copy of which is available from
24
  http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.
25
 
26
  This library is distributed in the hope that it will be useful,
27
  but WITHOUT ANY WARRANTY; without even the implied warranty of
28
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
29
  Lesser General Public License for more details.
30
 
31
  You should have received a copy of the GNU Lesser General Public
32
  License along with this library; if not, write to the Free Software
33
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
34
*/
35
 
36
/*$$DESCRIPTION*/
37
/******************************************************************************/
38
/*                                                                            */
39
/*                           D E S C R I P T I O N                            */
40
/*                                                                            */
41
/******************************************************************************/
42
//
43
// Generates VMEM output to stdout from binary images.
44
// Use with redirection like: ./bin2vmem app.bin > app.vmem
45
// To change either the number of bytes per word or word per line, change
46
// the following defines.
47
// Currently output is WORD addressed, NOT byte addressed
48
// eg: @00000000 00000000 00000000 00000000 00000000
49
//     @00000004 00000000 00000000 00000000 00000000
50
//     @00000008 00000000 00000000 00000000 00000000
51
//     @0000000c 00000000 00000000 00000000 00000000
52
//     etc..
53
//
54 45 julius
// OR
55
// 
56
// Output a list of the words, one per line, as Synplify appears to like
57
// specify this option with the -synfmt switch on the command line after
58
// the input file
59
// eg: ./bin2vmem data.bin -synfmt > data.vmem
60
//
61 6 julius
 
62 67 julius
#define WORDS_PER_LINE_DEFAULT 4
63
#define BYTES_PER_WORD_DEFAULT 4
64 6 julius
 
65 45 julius
#define FILENAME_CMDLINE_INDEX 1
66
#define FMT_CMDLINE_INDEX 2
67
 
68
#define FMT_WITH_ADDR 0
69
#define FMT_SYN 1
70
 
71 67 julius
#define PAD_FILL 0
72
 
73 6 julius
#include <stdio.h>
74
#include <stdlib.h>
75 67 julius
#include <stdint.h>
76 6 julius
#include <string.h>
77
 
78
int main(int argc, char **argv)
79
{
80
 
81 67 julius
        FILE  *fd = NULL;
82 6 julius
        int c;
83
        int i = 0;
84
        int write_size_word=0; // Disabled by default
85
        unsigned int image_size;
86 67 julius
        //int output_fmt = FMT_WITH_ADDR; // 0 - standard 4 per line with address, 1 - synfmt
87
        int bytes_per_word = BYTES_PER_WORD_DEFAULT, bytes_per_word_tmp;
88
        int words_per_line = WORDS_PER_LINE_DEFAULT;
89
        int printing_addr = 1; // Print address by default
90
        int pad_row_end = 0; // Default is we don't pad
91
        int pad_addr_end = 0; // Default is we don't pad
92
        int pad_row_number = 0;
93
        int pad_addr_number = 0;
94 6 julius
 
95
        // Counters keeping track of what we've printed
96 67 julius
        int current_word_addr = 0;
97 6 julius
        int word_counter = 0;
98 67 julius
        int total_word_counter = 0;
99 6 julius
        int byte_counter = 0;
100 67 julius
        int total_byte_counter = 0;
101
        int row_counter  = 1;
102 6 julius
 
103 67 julius
 
104
 
105 6 julius
        if(argc < 2) {
106
          fprintf(stderr,"\n\tInsufficient options.\n");
107
          fprintf(stderr,"\tPlease specify a binary file to convert to VMEM\n");
108
          fprintf(stderr,"\n\tbin2vmem - creates vmem output to stdout from bin\n");
109 45 julius
          fprintf(stderr,"\n\tBy default the output is word addressed 32-bit words\n");
110
          fprintf(stderr,"\tSpecify -synfmt on the command line after the filename\n");
111
          fprintf(stderr,"\tto output in the alterative format, which is a simple\n");
112 46 julius
          fprintf(stderr,"\tlist of the data words. The default bytes per word is 4.\n");
113 45 julius
 
114
          fprintf(stderr,"\n");
115 46 julius
          fprintf(stderr,"\tAdditionally, to specify the bytes per word (per line)\n");
116
          fprintf(stderr,"\twhen specifying the -synfmt simple list format, use the\n");
117
          fprintf(stderr,"\tswitch -bpw=N after specifying the -synfmt option. Example:\n");
118
          fprintf(stderr,"\t\t./bin2vmem prog.bin -synfmt -bpw=2 > prog.vmem\n");
119
          fprintf(stderr,"\n");
120 67 julius
          fprintf(stderr,"\n");
121
          fprintf(stderr,"Padding options:\n");
122
          fprintf(stderr,"\t--pad-to-row <num>\tPad up to num rows with 0\n");
123
          fprintf(stderr,"\t--pad-to-addr <addr>\t Pad UP to (not including) that address with 0\n");
124
          fprintf(stderr,"\n");
125 6 julius
          exit(1);
126
        }
127
 
128 67 julius
 
129 45 julius
 
130 67 julius
        if (argc > 1) // check for the -synfmt switch
131 45 julius
          {
132 67 julius
            for (i = 1; i< argc; i++)
133 46 julius
              {
134 67 julius
                if ((strcmp("-synfmt", argv[i]) == 0) || (strcmp("--synfmt", argv[i]) == 0))
135
                  {
136
                    words_per_line = 1;
137
                    printing_addr = 0;
138
                    //output_fmt = FMT_SYN; // output synthesis friendly format
139
                  }
140
                else if ((1 == sscanf(argv[i], "-bpw=%d", &bytes_per_word_tmp)) ||
141
                         (strcmp("--bpw", argv[i]) == 0))
142
                  {
143
                    if (strcmp("--bpw", argv[i]) == 0)
144
                      if (i+1 < argc)
145 46 julius
                        {
146 67 julius
                          bytes_per_word_tmp = atoi(argv[i+1]);
147
                          i++;
148 46 julius
                        }
149 67 julius
 
150
                    if(bytes_per_word_tmp > 0)
151
                      {
152
                        bytes_per_word = bytes_per_word_tmp;
153
                      }
154
 
155
                  }
156
                else if ((strcmp("--bpw", argv[i]) == 0))
157
                  {
158
                    if (i+1 < argc)
159
                      {
160
                        bytes_per_word_tmp = atoi(argv[i+1]);
161
                        i++;
162
                      }
163
                    if (bytes_per_word_tmp < 4 && bytes_per_word_tmp > 0)
164
                      {
165
                        bytes_per_word = bytes_per_word_tmp;
166
                      }
167
 
168
 
169
                  }
170
                else if (strcmp("--pad-to-row", argv[i]) == 0)
171
                  {
172
                    if (i+1 < argc)
173
                      {
174
                        uint32_t tmp_addr_dec;
175
                        if (!(sscanf(argv[i+1], "%d", &tmp_addr_dec) == 1))
176
                          {
177
                            fprintf(stderr,
178
                                    "Error: Number of rows to pad to not specified\n");
179
                            exit(1);
180
                          }
181
                        pad_row_number = tmp_addr_dec;
182
                                              }
183
                    else
184
                      {
185
                        fprintf(stderr,
186
                                "Error: Number of rows to pad to specified\n");
187
                        exit(1);
188
                      }
189
 
190
                    if (pad_addr_end)
191
                      {
192
                        fprintf(stderr, "Error: Can only specify one padding style\n");
193
                        exit(1);
194
                      }
195
                    pad_row_end = 1;
196
                    i++;
197
                  }
198
                else if (strcmp("--pad-to-addr", argv[i]) == 0)
199
                  {
200
                    // Get address
201
                    if (i+1 < argc)
202
                      {
203
                        uint32_t tmp_addr_hex, hex_used = 0, tmp_addr_dec, dec_used = 0;
204
                        if (sscanf(argv[i+1], "0x%x", &tmp_addr_hex) == 1)
205
                          hex_used = 1;
206
                        else if (sscanf(argv[i+1], "%d", &tmp_addr_dec) == 1)
207
                          dec_used = 1;
208
                        else
209
                          {
210
                            fprintf(stderr,
211
                                    "Error: No address to pad to specified. Use either hex with 0x prefixed, or decimal\n");
212
                            exit(1);
213
 
214
                          }
215
 
216
                        if (hex_used)
217
                          pad_addr_number = tmp_addr_hex;
218
                        else
219
                          pad_addr_number = tmp_addr_dec;
220
 
221
                      }
222
                    else
223
                      {
224
                        fprintf(stderr,
225
                                "Error: No address to pad to specified\n");
226
                        exit(1);
227
                      }
228
                    if (pad_addr_end)
229
                      {
230
                        fprintf(stderr, "Error: Can only specify one padding style\n");
231
                        exit(1);
232
                      }
233
                    pad_addr_end = 1;
234
                    i++;
235
                  }
236
                else
237
                  {
238
                    // File to open
239
                    fd = fopen( argv[i], "r" );
240
                    if (fd == NULL) {
241
                      fprintf(stderr,"failed to open input file: %s\n",argv[i]);
242
                      exit(1);
243 46 julius
                    }
244 67 julius
 
245
                  }
246
 
247 46 julius
              }
248
 
249 45 julius
          }
250 67 julius
 
251 6 julius
        if (fd == NULL) {
252 67 julius
          fprintf(stderr,"failed to open input file: %s\n",argv[i]);
253
          exit(1);
254 6 julius
        }
255
 
256 67 julius
 
257 6 julius
        fseek(fd, 0, SEEK_END);
258
        image_size = ftell(fd);
259
        fseek(fd,0,SEEK_SET);
260
 
261
        if (write_size_word)
262
          {
263 67 julius
            // or1200 startup method of determining size of boot image we're 
264
            // copying by reading out the very first word in flash is used. 
265
            // Determine the length of this file.
266 6 julius
            fseek(fd, 0, SEEK_END);
267
            image_size = ftell(fd);
268
            fseek(fd,0,SEEK_SET);
269
 
270
            // Now we should have the size of the file in bytes. Let's ensure it's a word multiple
271
            image_size+=3;
272
            image_size &= 0xfffffffc;
273
 
274
            // Sanity check on image size
275
            if (image_size < 8){
276
              fprintf(stderr, "Bad binary image. Size too small\n");
277
              return 1;
278
            }
279
 
280
            // Now write out the image size
281 67 julius
            printf("@%8x", current_word_addr);
282 6 julius
            printf("%8x", image_size);
283 67 julius
            current_word_addr += words_per_line * bytes_per_word;
284 6 julius
          }
285
 
286
 
287
        i=0;
288
        int starting_new_line  = 1;
289 45 julius
        // Now write out the binary data to specified format. Either
290
        // more complicated, addressed format:
291
        // VMEM format: @ADDRESSS XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
292
        // or simple, synplifyfriendly format which is just a list of
293
        // the words
294
 
295 67 julius
        while ((c = fgetc(fd)) != EOF)
296
          {
297
            if (starting_new_line)
298
              {
299
                // New line - print the current addr and then increment it
300
                if (printing_addr)
301
                  printf("@%.8x", current_word_addr);
302
                starting_new_line = 0;
303
              }
304
 
305
            if ( (byte_counter == 0) &&
306
                 ((words_per_line > 1) || (printing_addr)) )
307
              printf(" ");
308
 
309
            printf("%.2x", (unsigned int) c); // now print the actual char
310
 
311
            byte_counter++;
312
 
313 46 julius
              if (byte_counter == bytes_per_word)
314 45 julius
                {
315
                  word_counter++;
316 67 julius
                  total_word_counter++;
317 45 julius
                  byte_counter=0;
318
                }
319 67 julius
              if (word_counter == words_per_line)
320 45 julius
                {
321
                  printf("\n");
322
                  word_counter = 0;
323 67 julius
                  current_word_addr += words_per_line;
324 45 julius
                  starting_new_line = 1;
325 67 julius
                  row_counter++;
326 45 julius
                }
327 67 julius
          }
328
 
329
        /* Padding stuff */
330
        /* Pad until a set number of rows */
331
        if (pad_row_end)
332
          {
333
            // First see if we need to pad to the end of the current word 
334
            if (byte_counter > 0)
335
              {
336
                for(i=0;i<(bytes_per_word - byte_counter); i++)
337
                  {
338
                    printf("%.2x", (unsigned int) PAD_FILL);
339
                  }
340
                byte_counter = 0;
341
                word_counter++;
342
              }
343
 
344
            if (word_counter == words_per_line)
345
              {
346
                printf("\n");
347
                word_counter = 0;
348
                current_word_addr += words_per_line;
349
                starting_new_line = 1;
350
                row_counter++;
351
              }
352
 
353
            while (row_counter < pad_row_number + 1)
354
              {
355
                if (starting_new_line)
356
                  {
357
                    // New line - print the current addr and then increment it
358
                    if (printing_addr)
359
                      printf("@%.8x", current_word_addr);
360
                    starting_new_line = 0;
361
                  }
362
 
363
                if ( (byte_counter == 0) &&
364
                     ((words_per_line > 1) || (printing_addr)) )
365
                  printf(" ");
366
 
367
                printf("%.2x", (unsigned int) PAD_FILL); // PAD
368
 
369
                byte_counter++;
370
 
371
                if (byte_counter == bytes_per_word)
372
                  {
373
                  word_counter++;
374
                  total_word_counter++;
375 45 julius
                  byte_counter=0;
376
                }
377 67 julius
                if (word_counter == words_per_line)
378
                  {
379
                    printf("\n");
380
                    word_counter = 0;
381
                    current_word_addr += words_per_line;
382
                    starting_new_line = 1;
383
                    row_counter++;
384
                  }
385
              }
386
 
387
          }
388 45 julius
 
389 67 julius
        if (pad_addr_end || pad_row_end)
390
          {
391
            // Figure out where we are
392
            total_byte_counter = (current_word_addr * bytes_per_word) + (word_counter * bytes_per_word) + byte_counter;
393 45 julius
 
394 67 julius
            // Loop again, generating 0s this time instead
395
            while ( (pad_addr_end && (total_byte_counter < pad_addr_number)) ||
396
                    (pad_row_end && (row_counter < pad_row_number+1)) )
397
              {
398
                if (starting_new_line)
399
                  {
400
                    // New line - print the current addr and then increment it
401
                    if (printing_addr)
402
                      printf("@%.8x", current_word_addr);
403
                    starting_new_line = 0;
404
                  }
405
 
406
                if ( (byte_counter == 0) &&
407
                     ((words_per_line > 1) || (printing_addr)) )
408
                  printf(" ");
409
 
410
                printf("%.2x", (unsigned int) PAD_FILL); // PAD
411
 
412
                total_byte_counter++;
413
                byte_counter++;
414
 
415
                if (byte_counter == bytes_per_word)
416
                  {
417
                    word_counter++;
418
                    total_word_counter++;
419
                    byte_counter=0;
420
                  }
421
                if (word_counter == words_per_line)
422
                  {
423
                    printf("\n");
424
                    word_counter = 0;
425
                    current_word_addr += words_per_line;
426
                    starting_new_line = 1;
427
                    row_counter++;
428
                  }
429
              }
430
          }
431
 
432 6 julius
        return 0;
433
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.