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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_42/] [or1ksim/] [cpu/] [common/] [parse.c] - Blame information for rev 703

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

Line No. Rev Author Line
1 138 markom
/* parce.c -- Architecture independent load
2 2 cvs
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
#include <stdio.h>
21
#include <ctype.h>
22
#include <string.h>
23
#include <stdlib.h>
24
 
25
#include "abstract.h"
26 18 lampret
#include "arch.h"
27 67 lampret
#include "dmmu.h"
28 28 lampret
#include "coff.h"
29 138 markom
#include "debug_unit.h"
30 134 markom
#include "opcode/or32.h"
31 138 markom
#include "parse.h"
32 242 markom
#include "sim-config.h"
33 2 cvs
 
34 221 markom
#define MEMORY_LEN 0x100000000
35 361 markom
#define MAXLINE_LEN 18000
36 2 cvs
 
37 694 markom
/* Whether to do immediate statistics */
38
#define IMM_STATS 0
39
 
40 28 lampret
extern char *disassembled;
41
 
42 2 cvs
/* Unused mem memory marker. It is used when allocating program and data memory
43
   during parsing */
44
unsigned int freemem;
45
 
46 67 lampret
/* Translation table provided by microkernel. Only used if simulating microkernel. */
47
static unsigned long transl_table;
48
 
49
/* Used to signal whether during loading of programs a translation fault occured. */
50
static unsigned long transl_error;
51
 
52
 
53 2 cvs
char *strtoken(char *in, char *out, int which)
54
{
55 361 markom
  char  *super;
56
  char  *sub;
57
  char  *newline;
58
 
59
  super = strdup(in);
60
  sub = strtok(super, " \t");
61
  while (sub && --which)
62
    sub = strtok(NULL, " \t");
63
  if (sub && !which) {
64
    if ((newline = strchr(sub, '\n')))
65
      newline[0] = '\0';
66
    strcpy(out, sub);
67
  } else
68
    out[0] = '\0';
69
  free(super);
70
  if ((newline = strchr(out, '\r')))  /* get rid of CR */
71
    newline[0] = '\0';
72
  return(out);
73 2 cvs
}
74
 
75 304 markom
char *
76
stripwhite (string)
77
     char *string;
78
{
79
  register char *s, *t;
80
 
81
  for (s = string; whitespace (*s); s++)
82
    ;
83
 
84
  if (*s == 0)
85
    return (s);
86
 
87
  t = s + strlen (s) - 1;
88
  while (t > s && whitespace (*t))
89
    t--;
90
  *++t = '\0';
91
 
92
  return s;
93
}
94
 
95
char *
96
dupstr (s)
97
     char *s;
98
{
99
  char *r;
100
 
101 306 markom
  r = (char *)malloc (strlen (s) + 1);
102 304 markom
  strcpy (r, s);
103
  return (r);
104
}
105
 
106 221 markom
/* Used only by the simulator loader to translate logical addresses into physical.
107 67 lampret
   If loadcode() is called with valid virtphy_transl pointer to a table of
108
   translations then translate() performs translation otherwise phy address is
109
   equal to logical. */
110 123 markom
static unsigned int translate(unsigned int laddr,int* breakpoint)
111 67 lampret
{
112 361 markom
  int i;
113
 
114
  /* No translation (i.e. when loading kernel into simulator)
115
/*  printf("transl_table=%x  laddr=%x\n", transl_table, laddr);
116
  printf("laddr=%x\n", laddr);*/
117
  if (transl_table == 0)
118
    return laddr;
119
 
120
  /* Try to find our translation in the table. */
121
  for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
122
    if ((laddr & ~(PAGE_SIZE - 1)) == evalsim_mem32(transl_table + i)) {
123
      setsim_mem32(transl_table + i + 8, -2); /* Page modified */
124
      printf("found paddr=%x\n", evalsim_mem32(transl_table + i + 4) | (laddr & (PAGE_SIZE - 1)));
125
      return (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (unsigned long)(PAGE_SIZE - 1));
126
    }
127 67 lampret
 
128 361 markom
  /* Allocate new phy page for us. */
129
  for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
130
    if (evalsim_mem32(transl_table + i + 8) == 0) {
131
      setsim_mem32(transl_table + i, laddr & ~(PAGE_SIZE - 1)); /* VPN */
132
      setsim_mem32(transl_table + i + 4, (i/16) * PAGE_SIZE); /* PPN */
133
      setsim_mem32(transl_table + i + 8, -2); /* Page modified */
134
      printf("newly allocated ppn=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4));
135
      printf("newly allocated .ppn=%x\n", (unsigned long)transl_table + i + 4);
136
      printf("newly allocated ofs=%x\n", (unsigned long)(laddr & (PAGE_SIZE - 1)));
137
      printf("newly allocated paddr=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (PAGE_SIZE - 1)));
138
      return (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (unsigned long)(PAGE_SIZE - 1));
139
    }
140
  /* If we come this far then all phy memory is used and we can't find our page
141
     nor allocate new page. */
142
  transl_error = 1;
143
 
144
  printf("can't translate\n", laddr);
145
  exit(1);
146
  return -1;
147 67 lampret
}
148
 
149 694 markom
#if IMM_STATS
150 703 markom
int bcnt[33][3] = {0};
151
int bsum[3] = {0};
152
unsigned long movhi = 0;
153 694 markom
 
154
int bits (unsigned long val) {
155
  int i = 1;
156
  if (!val) return 0;
157 703 markom
  while (val != 0 && (signed long)val != -1) {i++; val = (signed long)val >> 1;}
158 694 markom
  return i;
159
}
160
 
161
void check_insn (unsigned long insn) {
162
  int insn_index = insn_decode (insn);
163
  struct insn_op_struct *opd = op_start[insn_index];
164
  unsigned long data = 0;
165
  int dis = 0;
166 703 markom
  const char *name;
167 694 markom
  if (!insn || insn_index < 0) return;
168
  name = insn_name (insn_index);
169 703 markom
  if (strcmp (name, "l.nop") == 0 || strcmp (name, "l.sys") == 0) return;
170 694 markom
 
171
  while (1)
172
    {
173
      unsigned long tmp = 0, nbits = 0;
174
      while (1)
175
        {
176
          tmp |= ((insn  >> (opd->type & OPTYPE_SHR)) & ((1 << opd->data) - 1)) << nbits;
177
          nbits += opd->data;
178
          if (opd->type & OPTYPE_OP)
179
            break;
180
          opd++;
181
        }
182
 
183
      /* Do we have to sign extend? */
184
      if (opd->type & OPTYPE_SIG)
185
        {
186
          int sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
187
          if (tmp & (1 << sbit))
188
            tmp |= 0xFFFFFFFF << sbit;
189
        }
190
      if (opd->type & OPTYPE_DIS) {
191
        /* We have to read register later.  */
192
        data += tmp;
193
        dis = 1;
194
      } else
195
        {
196
          if (!(opd->type & OPTYPE_REG) || dis) {
197
            if (!dis) data = tmp;
198 703 markom
            if (strcmp (name, "l.movhi") == 0) {
199
              movhi = data << 16;
200
            } else {
201
              data |= movhi;
202
              //printf ("%08x %s\n", data, name);
203
              if (!(or32_opcodes[insn_index].flags & OR32_IF_DELAY)) {
204
                bcnt[bits(data)][0]++; bsum[0]++;
205
              } else {
206
                if (strcmp (name, "l.bf") == 0 || strcmp (name, "l.bnf") == 0) {
207
                  bcnt[bits(data)][1]++; bsum[1]++;
208
                } else {
209
                  bcnt[bits(data)][2]++; bsum[2]++;
210
                }
211
              }
212
            }
213 694 markom
          }
214
          data = 0;
215
          dis = 0;
216
        }
217
      if(opd->type & OPTYPE_LAST) {
218
        return;
219
      }
220
      opd++;
221
    }
222
}
223
#endif
224
 
225 28 lampret
char null_str[1] = "\0";
226
 
227 123 markom
/* Replaced several calls to translate(freemem) with vaddr */
228
/* Added new mode execution code */
229
/* Changed parameters so address can be passed as argument */
230 138 markom
void addprogram(unsigned long address, unsigned long insn, int* breakpoint)
231 2 cvs
{
232 138 markom
  char insn_first2_char[3];
233 361 markom
  int vaddr = (!runtime.sim.filename) ? translate(address,breakpoint) : translate(freemem,breakpoint);
234 138 markom
 
235
  setsim_mem32 (vaddr, insn);
236 694 markom
#if IMM_STATS
237
  check_insn (insn);
238
#endif
239 361 markom
  if(runtime.sim.filename)
240 138 markom
    freemem += insn_len (insn_decode (insn));
241 2 cvs
}
242
 
243 694 markom
/* Load big-endian COFF file.  */
244 28 lampret
 
245
void readfile_coff(char *filename, short sections)
246
{
247 361 markom
  FILE *inputfs;
248
  char inputbuf[4];
249
  unsigned long insn;
250
  signed long sectsize;
251
  COFF_AOUTHDR coffaouthdr;
252
  struct COFF_scnhdr coffscnhdr;
253
  int  len;
254
  char item[MAXLINE_LEN];
255
  char item2[MAXLINE_LEN];
256
  int  firstthree = 0;
257
  int breakpoint = 0;
258 123 markom
 
259 361 markom
  if (!(inputfs = fopen(filename, "r"))) {
260
    perror("readfile_coff");
261
    exit(1);
262
  }
263 28 lampret
 
264 361 markom
  if (fseek(inputfs, sizeof(struct COFF_filehdr), SEEK_SET) == -1) {
265
    fclose(inputfs);
266
    perror("readfile_coff");
267
    exit(1);
268
  }
269 28 lampret
 
270 361 markom
  if (fread(&coffaouthdr, sizeof(coffaouthdr), 1, inputfs) != 1) {
271
    fclose(inputfs);
272
    perror("readfile_coff");
273
    exit(1);
274
  }
275
 
276
  while(sections--) {
277
    long scnhdr_pos = sizeof(struct COFF_filehdr) + sizeof(coffaouthdr)
278
        + sizeof(struct COFF_scnhdr) * firstthree;
279
    if (fseek(inputfs, scnhdr_pos, SEEK_SET) == -1) {
280
      fclose(inputfs);
281
      perror("readfile_coff");
282
      exit(1);
283
    }
284
    if (fread(&coffscnhdr, sizeof(struct COFF_scnhdr), 1, inputfs) != 1) {
285
      fclose(inputfs);
286
      perror("readfile_coff");
287
      exit(1);
288
    }
289
    printf("Section: %s,", coffscnhdr.s_name);
290
    printf(" paddr: 0x%.8x,", COFF_LONG_H(coffscnhdr.s_paddr));
291
    printf(" vaddr: 0x%.8x,", COFF_LONG_H(coffscnhdr.s_vaddr));
292
    printf(" size: 0x%.8x,", COFF_LONG_H(coffscnhdr.s_size));
293
    printf(" scnptr: 0x%.8x\n", COFF_LONG_H(coffscnhdr.s_scnptr));
294
 
295
    sectsize = COFF_LONG_H(coffscnhdr.s_size);
296 221 markom
#if 0
297 361 markom
    /* A couple of sanity checks. */
298
    if (translate(COFF_LONG_H(coffscnhdr.s_vaddr),&breakpoint) < MEMORY_START) {
299
      printf("Section %s starts out of ", coffscnhdr.s_name);
300
      printf("memory (at %x)\n", COFF_LONG_H(coffscnhdr.s_vaddr));
301
      exit(1);
302
    }
303
    if (translate(COFF_LONG_H(coffscnhdr.s_vaddr) + sectsize,&breakpoint) >
304
        MEMORY_START + MEMORY_LEN) {
305
      printf("Section %s ends out of ", coffscnhdr.s_name);
306
      printf("memory.\n");
307
      exit(1);
308
    }
309 221 markom
#endif
310 167 markom
#if 0
311 361 markom
    if (++firstthree == 1 && strcmp(coffscnhdr.s_name, ".text") != 0) {
312
      printf("First section should be .text (%s instead)\n", coffscnhdr.s_name);
313
      exit(1);
314
    }
315
    if (firstthree == 2 && strcmp(coffscnhdr.s_name, ".data") != 0) {
316
      printf("Second section should be .data (%s instead)\n", coffscnhdr.s_name);
317
      exit(1);
318
    }
319
    if (firstthree == 3 && strcmp(coffscnhdr.s_name, ".bss") != 0) {
320
      printf("Third section should be .bss (%s instead)\n", coffscnhdr.s_name);
321
      exit(1);
322
    }
323 167 markom
#else
324 361 markom
    ++firstthree;
325 167 markom
#endif
326 28 lampret
 
327 361 markom
    /* loading section */
328
    freemem = COFF_LONG_H(coffscnhdr.s_paddr);
329
    debug(2,"Starting to load at 0x%x\n", freemem);
330
    if (fseek(inputfs, COFF_LONG_H(coffscnhdr.s_scnptr), SEEK_SET) == -1) {
331
      fclose(inputfs);
332
      perror("readfile_coff");
333
      exit(1);
334
    }
335
    while (sectsize > 0 && (len = fread(&inputbuf, sizeof(inputbuf), 1, inputfs))) {
336
      insn = COFF_LONG_H(inputbuf);
337
      len = insn_len (insn_decode (insn));
338
      if (len == 2)
339
        {
340
          fseek(inputfs, -2, SEEK_CUR);
341
          debug(8,"readfile_coff: %x 0x%x   \n", sectsize, insn >> 16);
342
        }
343
      else
344
        debug(8,"readfile_coff: %x 0x%x   \n", sectsize, insn);
345
      addprogram (freemem, insn, &breakpoint);
346
      sectsize -= len;
347
    }
348
  }
349
  if (firstthree < 3) {
350
    printf("One or more missing sections. At least");
351
    printf(" three sections expected (.text, .data, .bss).\n");
352
    exit(1);
353
  }
354
  if (firstthree > 3) {
355
    printf("Warning: one or more extra sections. These");
356
    printf(" sections were handled as .data sections.\n");
357
  }
358 41 lampret
 
359 361 markom
  fclose(inputfs);
360
  printf("Finished loading COFF.\n");
361
  return;
362 28 lampret
}
363
 
364
/* Load symbols from big-endian COFF file. */
365
 
366
void readsyms_coff(char *filename, unsigned long symptr, long syms)
367
{
368 173 markom
  FILE *inputfs;
369
  struct COFF_syment coffsymhdr;
370
  int breakpoint = 0;
371
  int count = 0;
372
  long nsyms = syms;
373
  if (!(inputfs = fopen(filename, "r"))) {
374
    perror("readsyms_coff");
375
    exit(1);
376
  }
377
 
378
  if (fseek(inputfs, symptr, SEEK_SET) == -1) {
379
    fclose(inputfs);
380
    perror("readsyms_coff");
381
    exit(1);
382
  }
383
 
384
  while(syms--) {
385
    int i, n;
386
    if (fread(&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) {
387
      fclose(inputfs);
388
      perror("readsyms_coff");
389
      exit(1);
390
    }
391
 
392
    n = (unsigned char)coffsymhdr.e_numaux[0];
393 513 markom
 
394
    /* check whether this symbol belongs to a section and is external symbol; ignore all others */
395
    if (COFF_SHORT_H(coffsymhdr.e_scnum) >= 0 && coffsymhdr.e_sclass[0] == C_EXT) {
396
#if 0
397 173 markom
    /* If not important or not in text, skip. */
398 513 markom
    if(COFF_SHORT_H(coffsymhdr.e_type) & COFF_N_TMASK & COFF_STYP_TEXT) {
399
#endif
400
 
401 173 markom
      if (*((unsigned long *)coffsymhdr.e.e.e_zeroes)) {
402 513 markom
        if (strlen(coffsymhdr.e.e_name) && strlen(coffsymhdr.e.e_name) < 9)
403
          add_label(COFF_LONG_H(coffsymhdr.e_value), coffsymhdr.e.e_name);
404
        debug(8, "[%i] Symbol: %s,", count++, coffsymhdr.e.e_name);
405 173 markom
      } else {
406 513 markom
        long fpos = ftell (inputfs);
407 361 markom
 
408 513 markom
        if (fseek(inputfs, symptr + nsyms * COFF_SYMESZ + COFF_LONG_H(coffsymhdr.e.e.e_offset), SEEK_SET) == 0) {
409
          char tmp[33], *s = &tmp[0];
410
          while (s != &tmp[32])
411
            if ((*(s++) = fgetc(inputfs)) == 0) break;
412
          tmp[32] = 0;
413
          add_label(COFF_LONG_H(coffsymhdr.e_value), &tmp[0]);
414
          debug(8, "[%i] Symbol: %s,", count++, &tmp[0]);
415
        }
416
        fseek(inputfs, fpos, SEEK_SET);
417 173 markom
      }
418
 
419 344 markom
      debug(9, " val: 0x%.8x,", COFF_LONG_H(coffsymhdr.e_value));
420
      debug(9, " type: %x, %x, auxs: %i\n", COFF_SHORT_H(coffsymhdr.e_type), *((unsigned short *)coffsymhdr.e_type), n);
421 173 markom
    }
422 28 lampret
 
423 173 markom
    for (i = 0; i < n; i++)
424
      if (fread(&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) {
425 513 markom
        fclose(inputfs);
426
        perror("readsyms_coff3");
427
        exit(1);
428 173 markom
      }
429
    syms -= n;
430
    count += n;
431
  }
432 28 lampret
 
433 173 markom
  fclose(inputfs);
434
  printf("Finished loading symbols.\n");
435
  return;
436 28 lampret
}
437
 
438
/* Identify file type and call appropriate readfile_X routine. It only
439
handles orX-coff-big executables at the moment. */
440
 
441
void identifyfile(char *filename)
442
{
443 361 markom
  FILE *inputfs;
444
  struct COFF_filehdr coffhdr;
445
  size_t len;
446
 
447
  if (!(inputfs = fopen(filename, "r"))) {
448
    fprintf(stderr, "xx %s", filename);
449
    perror("identifyfile1");
450
    fflush(stdout);
451
    fflush(stderr);
452
    exit(1);
453
  }
454
 
455
  if (fread(&coffhdr, sizeof(coffhdr), 1, inputfs) == 1) {
456
    if (COFF_SHORT_H(coffhdr.f_magic) == 0x17a) {
457
          unsigned long opthdr_size;
458
      printf("COFF magic: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_magic));
459
      printf("COFF flags: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_flags));
460
      printf("COFF symptr: 0x%.8x\n", COFF_LONG_H(coffhdr.f_symptr));
461
      if ((COFF_SHORT_H(coffhdr.f_flags) & COFF_F_EXEC) != COFF_F_EXEC) {
462
        printf("This COFF is not an executable.\n");
463
        exit(1);
464
      }
465
      opthdr_size = COFF_SHORT_H(coffhdr.f_opthdr);
466
      if (opthdr_size != sizeof(COFF_AOUTHDR)) {
467
        printf("COFF optional header is missing or not recognized.\n");
468
        printf("COFF f_opthdr: 0x%.2x\n", opthdr_size);
469
        exit(1);
470
      }
471
      fclose(inputfs);
472
      readfile_coff(filename, COFF_SHORT_H(coffhdr.f_nscns));
473
      readsyms_coff(filename, COFF_LONG_H(coffhdr.f_symptr), COFF_LONG_H(coffhdr.f_nsyms));
474
      return;
475
    }
476
    else {
477
      printf("Not COFF, quiting.\n");
478
      fclose(inputfs);
479
      exit (1);
480
    }
481
  }
482
  else {
483
    printf("yy %s", filename);
484
    perror("identifyfile2");
485
  }
486
 
487
  fclose(inputfs);
488 28 lampret
 
489 361 markom
  return;
490 2 cvs
}
491
 
492 67 lampret
 
493
/* Loads file to memory starting at address startaddr and returns freemem. */
494
unsigned long loadcode(char *filename, unsigned long startaddr, unsigned long virtphy_transl)
495 2 cvs
{
496 123 markom
  int breakpoint = 0;
497
 
498 361 markom
  transl_error = 0;
499
  transl_table = virtphy_transl;
500
  freemem = startaddr;
501
  printf("loadcode: filename %s  startaddr=%x  virtphy_transl=%x", filename, startaddr, virtphy_transl);
502
  identifyfile(filename);
503 694 markom
 
504
#if IMM_STATS  
505
  {
506 703 markom
    int i = 0, a = 0, b = 0, c = 0;
507
    printf ("index:arith/branch/jump\n");
508
    for (i = 0; i < 33; i++) printf ("%2i:\t%3.0f%% / %3.0f%%/ %3.0f%%\t%5i / %5i / %5i\n", i, 100.* (a += bcnt[i][0])/bsum[0],
509
        100.* (b += bcnt[i][1])/bsum[1], 100.* (c += bcnt[i][2])/bsum[2], bcnt[i][0], bcnt[i][1], bcnt[i][2]);
510
    printf ("\nsum %i %i %i\n", bsum[0], bsum[1], bsum[2]);
511 694 markom
  }
512
#endif
513
 
514 361 markom
  if (transl_error)
515
    return -1;
516
  else
517
    return translate(freemem,&breakpoint);
518 694 markom
 
519 2 cvs
}

powered by: WebSVN 2.1.0

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