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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [m68k/] [mvme162/] [tools/] [sload.c] - Blame information for rev 173

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 *
3
 *        Copyright (c) 1994 by EISCAT Scientific Association.
4
 *                        All Rights Reserved.
5
 *                             M.Savitski
6
 *
7
 *     S-record code - courtesy of Kym Newbery
8
 *     8918927y@lux.levels.unisa.edu.au
9
 *
10
 *     Loading S-records into the VMEbus memory.
11
 *
12
 *  Loads an executable in s-record format into the MVME dual-ported
13
 *  memory and directs the MVME CPU to start execution.
14
 *  VMEbus access is done via the FORCE CPU-2CE vmeplus driver in
15
 *  read/write mode for loading and in mmap mode for accessing MVME registers.
16
 *  See mvme162.h for #define's dependent on the MVME162 setup.
17
 *
18
 *  $Id: sload.c,v 1.2 2001-09-27 12:00:19 chris Exp $
19
 *
20
 */
21
 
22
#include <stdio.h>
23
#include <string.h>
24
#include <ctype.h>
25
 
26
 
27
#include <sys/types.h>
28
#include <sys/fcntl.h>
29
#include <sys/resource.h>
30
#include <unistd.h>
31
#include <sys/vme.h>
32
#include <sys/mman.h>
33
 
34
#include "../include/bsp.h"
35
 
36
#define FALSE 0
37
#define TRUE 1
38
 
39
#define DATA19 0
40
#define DATA28 1
41
#define DATA37 3
42
#define HEADER 4
43
#define TERMINATOR 5
44
#define NONE 6
45
 
46
unsigned int ahdtoi(unsigned char digit);
47
int issrec(char *str);
48
int validrec(char *str);
49
void hdr2str(char *sstr, char *pstr);
50
unsigned long getaddr(char *str);
51
unsigned int datasize(char *str);
52
void usage (void);
53
int MVMEControl(u_long entry, int reset, int go);
54
 
55
unsigned int ahdtoi(unsigned char digit)
56
/*   converts a hexadecimal char to an integer
57
 *
58
 *   entry        : digit = character to convert
59
 *                        : 0..15 = result
60
 *                        : -1    = char is not a digit
61
 */
62
{
63
/* check digit */
64
  if (!isxdigit(digit))
65
    return(-1);
66
 
67
  switch (toupper(digit)) {
68
    case 'A' : return(0xA);
69
    case 'B' : return(0xB);
70
    case 'C' : return(0xC);
71
    case 'D' : return(0xD);
72
    case 'E' : return(0xE);
73
    case 'F' : return(0xF);
74
    default  : return(digit - 0x30);
75
  }
76
}
77
 
78
int issrec(char *str)
79
/*  attempts to identify the type of Srecord string passed
80
 *
81
 *   entry   : str =  pointer to null terminated string
82
 *   returns : 0,1,2,3,5,7,8,9 for S0..S9 except S6 & S4
83
 *           : -1 = invalid header or header not found
84
 *                   : -2 = invalid header number
85
 */
86
{
87
/* Check first character for S */
88
  if ((isupper(str[0]) && (str[0] == 'S')) || (islower(str[0]) && (str[0] == 's')))
89
  {
90
  /* check for valid header number */
91
    switch (str[1]) {
92
      case '0' : return 0;    /* header record */
93
      case '1' : return 1;    /* data record, 2byte addr */
94
      case '2' : return 2;    /*  "     "   , 3byte addr */
95
      case '3' : return 3;    /*  "     "   , 4byte addr */
96
      case '5' : return 5;    /* number of S1,S2,S3 blocks */
97
      case '7' : return 7;    /* S3 terminator */
98
      case '8' : return 8;    /* S2 terminator */
99
      case '9' : return 9;    /* S1 terminator */
100
      default  : return -2;   /* all others are invalid */
101
    }
102
  }
103
  return(-1);
104
}
105
 
106
int validrec(char *str)
107
/*  Tests for a valid srecord. tests checksum & for nondigit characters
108
 *  doesn't rely on any other srecord routines.
109
 *
110
 *    entry   : str   =  pointer to null terminated string
111
 *    returns : -1        =  srecord contains invalid characters
112
 *                        : -2    =  srecord checksum is invalid
113
 *                    : -3    =  srecord record length is invalid
114
 *            : 0     =  srecord is valid
115
 */
116
{
117
  int         cn = 1, rlen=0;
118
  int         mchksum=0, rchksum=0;
119
 
120
/* first check if there are any non-digit characters except S */
121
  while (str[cn]!=0)
122
    if (!isxdigit(str[cn++]))
123
      return(-1);
124
 
125
/* test number of data bytes */
126
  rlen = ahdtoi(str[2])* 0x10 + ahdtoi(str[3]);
127
  if (((strlen(str)-4)/2U) != rlen) return(-3);
128
 
129
/* get checksum from string */
130
  rchksum = ahdtoi(str[rlen*2+2])*0x10 + ahdtoi(str[rlen*2+3]); /* string chksum */
131
 
132
/* now calculate my own checksum */
133
  for (cn=2; cn <= rlen*2; )
134
    mchksum += ahdtoi(str[cn++])*0x10 + ahdtoi(str[cn++]);
135
  mchksum = ~mchksum & 0xFF;
136
  if (mchksum != rchksum) return(-2); /* return -2 in not equal */
137
 
138
/* return OK if we didn't fail any of these tests */
139
  return(0);
140
}
141
 
142
void hdr2str(char *sstr, char *pstr)
143
/*  converts header record (S0) string into a plain string
144
 *
145
 *  entry        : sstr = pointer to S0 string record
146
 *  exit         : pstr = pointer to string long enough to hold string
147
 *                                (caller must allocate enough space for string)
148
 */
149
{
150
  int     rlen, cn, pn=0;
151
 
152
  rlen = ahdtoi(sstr[2])*0x10 + ahdtoi(sstr[3]);
153
  for (cn=8; cn <= rlen*2; )
154
    pstr[pn++] = ahdtoi(sstr[cn++])*0x10 + ahdtoi(sstr[cn++]);
155
  pstr[pn]=0;
156
}
157
 
158
unsigned long getaddr(char *str)
159
/*  returns the address of the srecord in str. assumes record is valid.
160
 *
161
 *  entry        : str = pointer to srecord string
162
 *  exit         : address of data, word or long.
163
 */
164
{
165
  unsigned long addr=0;
166
 
167
  switch (issrec(str)) {
168
    case 0 :
169
    case 1 :
170
    case 5 :
171
    case 9 :  addr = ahdtoi(str[4])*0x1000 + ahdtoi(str[5])*0x100
172
              + ahdtoi(str[6])*0x10 + ahdtoi(str[7]);
173
              return(addr);
174
    case 2 :
175
    case 8 :  addr = ahdtoi(str[4])*0x100000 + ahdtoi(str[5])*0x10000
176
              + ahdtoi(str[6])*0x1000 + ahdtoi(str[7])*0x100
177
              + ahdtoi(str[8])*0x10 + ahdtoi(str[9]);
178
              return(addr);
179
    case 3 :
180
    case 7 :  addr = ahdtoi(str[4])*0x10000000 + ahdtoi(str[5])*0x1000000
181
              + ahdtoi(str[6])*0x100000 + ahdtoi(str[7])*0x10000
182
              + ahdtoi(str[8])*0x1000 + ahdtoi(str[9])*0x100
183
              + ahdtoi(str[10])*0x10 + ahdtoi(str[11]);
184
              return(addr);
185
    default : return(-1);
186
  }
187
}
188
 
189
unsigned int datasize(char *str)
190
/*
191
 *  returns the number of data bytes in the srecord. assumes record is valid.
192
 *
193
 *  entry        : str = pointer to srecord string
194
 *  exit         : number of bytes of data in the data field.
195
 */
196
{
197
  unsigned int size=0;
198
 
199
  switch (issrec(str)) {
200
    case 0  :
201
    case 1  :
202
    case 5  :
203
    case 7  :
204
    case 8  :
205
    case 9  : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]);
206
              return(size-3);
207
    case 2  : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]);
208
              return(size-4);
209
    case 3  : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]);
210
              return(size-5);
211
    default : return(-1);
212
  }
213
}
214
 
215
void usage (void)
216
/*
217
 *  prints correct usage on stdout
218
 */
219
{
220
   printf("\nUSAGE :  sload [-v][-g][-r] [file]\n");
221
   printf("  file is an s-record file\n");
222
   printf("  -v for verbose summary of s-records loaded\n");
223
   printf("  -g to start execution\n");
224
   printf("  -r to reset MVME162\n\n");
225
}
226
 
227
int MVMEControl(u_long entry, int reset, int go)
228
/*  Controls MVME-162 from other VME master:
229
 *  if entry != 0, loads it as start address
230
 *  if go != 0, starts program execution from entry
231
 *  if reset != 0, resets mvme162's local bus
232
 *  Depends upon #define'ed GROUP_BASE_ADDRESS and BOARD_BASE_ADDRESS
233
 *  which in turn are set by the 162-BUG's ENV command.
234
 */
235
{
236
  int         vme;
237
  char        vmedev[32] = "/dev/vme16d32";   /* d32 is important !!!  */
238
  u_long      pagesize;
239
  struct gcsr *gcsr_map;
240
 
241
  pagesize = sysconf(_SC_PAGESIZE);   /* mmap likes to be page-aligned */
242
 
243
  if ((vme = open(vmedev, O_RDWR)) == -1) {
244
    perror("open");
245
    fprintf(stderr, "Cannot open vme as %s to access GCSR\n", vmedev);
246
    return 1;
247
  }
248
 
249
/* "MAP_SHARED" is important here */
250
  gcsr_map = (struct gcsr *) mmap(0, 0x1000, PROT_WRITE|PROT_READ, MAP_SHARED,
251
                          vme, (u_long)gcsr_vme / pagesize * pagesize);
252
  if (gcsr_map == (struct gcsr *) - 1) {
253
    perror("mmap");
254
    fprintf(stderr, "Cannot mmap() to remote bus address 0x%08X\n",
255
                 (u_long)gcsr_vme / pagesize * pagesize);
256
    return 1;
257
  }
258
 
259
/*
260
 * use GCSR to start execution in MVME162
261
 * adjust pointer to compensate for page alignement
262
 */
263
  gcsr_map = (struct gcsr *)((u_long)gcsr_map + (u_long)gcsr_vme % pagesize);
264
 
265
  if (reset) {                /* reset the local bus... */
266
    gcsr_map->board_scr |= 0x80;
267
  }
268
  if (entry) {                /* ...load start address... */
269
    gcsr_map->gpr[0] = entry >> 16U;
270
    gcsr_map->gpr[1] = entry & 0x0000FFFF;
271
  }
272
  if (go) {                   /* ... and kick it in the ass! */
273
    gcsr_map->lmsig = 0x1;
274
  }
275
}
276
 
277
/*=================================================================== */
278
main(int argc, char *argv[])
279
{
280
  char        inpstr[256];
281
  u_char      image[256];
282
  char        hdrstr[64];
283
  int         i, j, k, result, size, line=0, lastrec=0;
284
  long        addr, tsize=0, naddr=0, blksize=0, blknum=1;
285
  FILE        *in;
286
  char        infile[256] = "";
287
  char        vmedev[32] = "/dev/vme32d32";   /* Assume "/dev/vme32d32"  */
288
  int         vme, verbose = 0, go = 0, reset = 0, havefile = 0;
289
 
290
/*  Parse the command line */
291
 
292
  --argc;
293
 
294
  while (argv++, argc--) {
295
    if (**argv != '-') {
296
      strcpy(infile, *argv);
297
      havefile = 1;
298
    } else if (!strcmp(*argv, "-v")) {
299
      verbose = 1;
300
    } else if (!strcmp(*argv, "-g")) {
301
      go = 1;
302
    } else if (!strcmp(*argv, "-r")) {
303
      reset = 1;
304
/*    } else if (!strcmp(*argv, "-vme32")) { */
305
/*      strcpy(vmedev, "/dev/vme32d32"); */
306
/*    } else if (!strcmp(*argv, "-vme24")) { */
307
/*      strcpy(vmedev, "/dev/vme24d32"); */
308
/*    } else if (!strcmp(*argv, "-vme16")) { */
309
/*      strcpy(vmedev, "/dev/vme16d32"); */
310
    } else if (!strcmp(*argv, "-")) {
311
        usage();
312
        exit(0);
313
    } else {
314
        usage();
315
        exit(0);
316
    }
317
  }
318
 
319
  if (!havefile) {
320
    if (!reset && !go) {
321
        usage();
322
    }
323
    else {
324
      MVMEControl(0, reset, go);
325
    }
326
    exit(0);
327
  }
328
 
329
  if ((in = fopen(infile, "r")) == NULL) {
330
    perror("open");
331
    fprintf(stderr, "Cannot open input file %s\n", infile);
332
    exit(1);
333
  }
334
 
335
  if ((vme = open(vmedev, O_RDWR)) == -1) {
336
    fprintf(stderr, "Cannot open vme as %s\n", vmedev);
337
  }
338
 
339
  while (fscanf(in, "%s", &inpstr) != EOF) {
340
    line++;
341
    if (validrec(inpstr) == 0) {
342
      switch (issrec(inpstr)) {
343
      case 0 :
344
        hdr2str(inpstr, hdrstr);
345
        if (verbose) printf("HEADER string = `%s'\n", hdrstr);
346
        lastrec=HEADER;
347
        break;
348
      case 1 :
349
        addr = getaddr(inpstr);
350
        size = datasize(inpstr);
351
        if (blksize == 0) {
352
          blksize+=size;
353
          naddr=addr+size;
354
          if (verbose) printf("DATA\tS19\t$%04lX", addr);
355
          lastrec=DATA19;
356
        }
357
        else if ((blksize!=0) && (addr==naddr)) {
358
          blksize+=size;
359
          naddr=addr+size;
360
        }
361
        else {
362
          if (verbose) printf("\t$%04lX\t%lu", naddr-1, blksize);
363
          if (verbose) printf("\t%d\n", blknum);
364
          blknum+=1;
365
          naddr=addr+size;
366
          blksize=size;
367
          if (verbose) printf("DATA\tS19\t$%04lX", addr);
368
          lastrec=DATA19;
369
        }
370
        tsize += size;
371
        if (vme == -1) break;
372
        for (i = 0, j = 8, k = size; k-- > 0; i += 1, j += 2) {
373
          image[i] = ahdtoi(inpstr[j])*0x10 + ahdtoi(inpstr[j+1]);
374
        }
375
        if (lseek(vme, addr, SEEK_SET) == -1) {
376
          fprintf(stderr, "lseek() to vme address %08X failed\n", addr);
377
        }
378
        else {
379
          if (write(vme, (u_char *)image, size) != size) {
380
            fprintf(stderr, "Write to vme address %08X failed\n", addr);
381
          }
382
        }
383
        break;
384
      case 2 :
385
        addr = getaddr(inpstr);
386
        size = datasize(inpstr);
387
        if (blksize == 0) {
388
          blksize+=size;
389
          naddr=addr+size;
390
          if (verbose) printf("DATA\tS28\t$%06lX",addr);
391
          lastrec=DATA28;
392
        }
393
        else if ((blksize!=0) && (addr==naddr)) {
394
          blksize+=size;
395
          naddr=addr+size;
396
        }
397
        else {
398
          if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize);
399
          if (verbose) printf("\t%d\n",blknum);
400
          blknum+=1;
401
          naddr=addr+size;
402
          blksize=size;
403
          if (verbose) printf("DATA\tS28\t$%06lX",addr);
404
          lastrec=DATA28;
405
        }
406
        tsize += size;
407
        if (vme == -1) break;
408
        for (i = 0, j = 10, k = size; k-- > 0; i += 1, j += 2) {
409
          image[i] = ahdtoi(inpstr[j])*0x10 + ahdtoi(inpstr[j+1]);
410
        }
411
        if (lseek(vme, addr, SEEK_SET) == -1) {
412
          fprintf(stderr, "lseek() to vme address %08X failed\n", addr);
413
        }
414
        else {
415
          if (write(vme, (u_char *)image, size) != size) {
416
            fprintf(stderr, "Write to vme address %08X failed\n", addr);
417
          }
418
        }
419
        break;
420
      case 3 :
421
        addr = getaddr(inpstr);
422
        size = datasize(inpstr);
423
        if (blksize == 0) {
424
          blksize+=size;
425
          naddr=addr+size;
426
          if (verbose) printf("DATA\tS37\t$%08lX",addr);
427
          lastrec=DATA37;
428
        }
429
        else if ((blksize!=0) && (addr==naddr)) {
430
          blksize+=size;
431
          naddr=addr+size;
432
        }
433
        else {
434
          if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize);
435
          if (verbose) printf("\t%d\n",blknum);
436
          blknum+=1;
437
          naddr=addr+size;
438
          blksize=size;
439
          if (verbose) printf("DATA\tS37\t$%08lX",addr);
440
          lastrec=DATA37;
441
        }
442
        tsize += size;
443
        if (vme == -1) break;
444
        for (i = 0, j = 12, k = size; k-- > 0; i += 1, j += 2) {
445
          image[i] = ahdtoi(inpstr[j])*0x10 + ahdtoi(inpstr[j+1]);
446
        }
447
        if (lseek(vme, addr, SEEK_SET) == -1) {
448
          fprintf(stderr, "lseek() to vme address %08X failed\n", addr);
449
        }
450
        else {
451
          if (write(vme, (u_char *)image, size) != size) {
452
            fprintf(stderr, "Write to vme address %08X failed\n", addr);
453
          }
454
        }
455
        break;
456
      case 7 :
457
        if (lastrec==DATA19){if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize);}
458
        if (lastrec==DATA28){if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize);}
459
        if (lastrec==DATA37){if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize);}
460
        if (verbose) printf("\t%d\n",blknum);
461
        addr = getaddr(inpstr);
462
        if (verbose) printf("TERM\tS37");
463
        printf("\nExecution address = $%08lX\n", addr);
464
        lastrec=TERMINATOR;
465
        break;
466
      case 8 :
467
        if (lastrec==DATA19){if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize);}
468
        if (lastrec==DATA28){if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize);}
469
        if (lastrec==DATA37){if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize);}
470
        if (verbose) printf("\t%d\n",blknum);
471
        addr = getaddr(inpstr);
472
        if (verbose) printf("TERM\tS28");
473
        printf("\nExecution address = $%06lX\n", addr);
474
        lastrec=TERMINATOR;
475
        break;
476
      case 9 :
477
        if (lastrec==DATA19){if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize);}
478
        if (lastrec==DATA28){if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize);}
479
        if (lastrec==DATA37){if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize);}
480
        if (verbose) printf("\t%d\n",blknum);
481
        addr = getaddr(inpstr);
482
        if (verbose) printf("TERM\tS19");
483
        printf("\nExecution address = $%04lX\n", addr);
484
        lastrec=TERMINATOR;
485
        break;
486
      }
487
    }
488
    else {
489
      printf("\nError on line %d. ",line);
490
      switch (validrec(inpstr)) {
491
      case -1 : {printf("SRecord contains invalid characters.\n"); break; }
492
      case -2 : {printf("SRecord checksum is invalid.\n"); break;}
493
      case -3 : {printf("SRecord length is invalid.\n"); break;}
494
      }
495
      exit(1);
496
    }
497
  }
498
 
499
  if ((lastrec==DATA19) || (lastrec==DATA28) || (lastrec==DATA37)) {
500
    if (lastrec==DATA19){if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize);}
501
    if (lastrec==DATA28){if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize);}
502
    if (lastrec==DATA37){if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize);}
503
    if (verbose) printf("\t%d\n",blknum);
504
    printf("ERROR: terminator record not found.\n");
505
  }
506
  else {
507
    for (i = 0x000FFFF; i-- > 0;) ;           /* mystique delay... */
508
    MVMEControl(addr, reset, go);
509
  }
510
  if (verbose) printf("total data size = %lu bytes\n", tsize);
511
}

powered by: WebSVN 2.1.0

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