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

Subversion Repositories or1k

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

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
int bcnt[33] = {0};
151
 
152
int bits (unsigned long val) {
153
  int i = 1;
154
  if (!val) return 0;
155
  while (val != 0 && val != 0xffffffff) {i++;val >>= 1;}
156
  return i;
157
}
158
 
159
void check_insn (unsigned long insn) {
160
  int insn_index = insn_decode (insn);
161
  struct insn_op_struct *opd = op_start[insn_index];
162
  unsigned long data = 0;
163
  int dis = 0;
164
  char *name;
165
  if (!insn || insn_index < 0) return;
166
  name = insn_name (insn_index);
167
  if (strcmp (name, "l.movhi") == 0 || strcmp (name, "l.nop") == 0 || strcmp (name, "l.sys") == 0) return;
168
 
169
  while (1)
170
    {
171
      unsigned long tmp = 0, nbits = 0;
172
      while (1)
173
        {
174
          tmp |= ((insn  >> (opd->type & OPTYPE_SHR)) & ((1 << opd->data) - 1)) << nbits;
175
          nbits += opd->data;
176
          if (opd->type & OPTYPE_OP)
177
            break;
178
          opd++;
179
        }
180
 
181
      /* Do we have to sign extend? */
182
      if (opd->type & OPTYPE_SIG)
183
        {
184
          int sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
185
          if (tmp & (1 << sbit))
186
            tmp |= 0xFFFFFFFF << sbit;
187
        }
188
      if (opd->type & OPTYPE_DIS) {
189
        /* We have to read register later.  */
190
        data += tmp;
191
        dis = 1;
192
      } else
193
        {
194
          if (!(opd->type & OPTYPE_REG) || dis) {
195
            if (!dis) data = tmp;
196
            //printf ("%08x %s\n", data, name);
197
            bcnt[bits(data)]++;
198
          }
199
          data = 0;
200
          dis = 0;
201
        }
202
      if(opd->type & OPTYPE_LAST) {
203
        return;
204
      }
205
      opd++;
206
    }
207
}
208
#endif
209
 
210 28 lampret
char null_str[1] = "\0";
211
 
212 123 markom
/* Replaced several calls to translate(freemem) with vaddr */
213
/* Added new mode execution code */
214
/* Changed parameters so address can be passed as argument */
215 138 markom
void addprogram(unsigned long address, unsigned long insn, int* breakpoint)
216 2 cvs
{
217 138 markom
  char insn_first2_char[3];
218 361 markom
  int vaddr = (!runtime.sim.filename) ? translate(address,breakpoint) : translate(freemem,breakpoint);
219 138 markom
 
220
  setsim_mem32 (vaddr, insn);
221 694 markom
#if IMM_STATS
222
  check_insn (insn);
223
#endif
224 361 markom
  if(runtime.sim.filename)
225 138 markom
    freemem += insn_len (insn_decode (insn));
226 2 cvs
}
227
 
228 694 markom
/* Load big-endian COFF file.  */
229 28 lampret
 
230
void readfile_coff(char *filename, short sections)
231
{
232 361 markom
  FILE *inputfs;
233
  char inputbuf[4];
234
  unsigned long insn;
235
  signed long sectsize;
236
  COFF_AOUTHDR coffaouthdr;
237
  struct COFF_scnhdr coffscnhdr;
238
  int  len;
239
  char item[MAXLINE_LEN];
240
  char item2[MAXLINE_LEN];
241
  int  firstthree = 0;
242
  int breakpoint = 0;
243 123 markom
 
244 361 markom
  if (!(inputfs = fopen(filename, "r"))) {
245
    perror("readfile_coff");
246
    exit(1);
247
  }
248 28 lampret
 
249 361 markom
  if (fseek(inputfs, sizeof(struct COFF_filehdr), SEEK_SET) == -1) {
250
    fclose(inputfs);
251
    perror("readfile_coff");
252
    exit(1);
253
  }
254 28 lampret
 
255 361 markom
  if (fread(&coffaouthdr, sizeof(coffaouthdr), 1, inputfs) != 1) {
256
    fclose(inputfs);
257
    perror("readfile_coff");
258
    exit(1);
259
  }
260
 
261
  while(sections--) {
262
    long scnhdr_pos = sizeof(struct COFF_filehdr) + sizeof(coffaouthdr)
263
        + sizeof(struct COFF_scnhdr) * firstthree;
264
    if (fseek(inputfs, scnhdr_pos, SEEK_SET) == -1) {
265
      fclose(inputfs);
266
      perror("readfile_coff");
267
      exit(1);
268
    }
269
    if (fread(&coffscnhdr, sizeof(struct COFF_scnhdr), 1, inputfs) != 1) {
270
      fclose(inputfs);
271
      perror("readfile_coff");
272
      exit(1);
273
    }
274
    printf("Section: %s,", coffscnhdr.s_name);
275
    printf(" paddr: 0x%.8x,", COFF_LONG_H(coffscnhdr.s_paddr));
276
    printf(" vaddr: 0x%.8x,", COFF_LONG_H(coffscnhdr.s_vaddr));
277
    printf(" size: 0x%.8x,", COFF_LONG_H(coffscnhdr.s_size));
278
    printf(" scnptr: 0x%.8x\n", COFF_LONG_H(coffscnhdr.s_scnptr));
279
 
280
    sectsize = COFF_LONG_H(coffscnhdr.s_size);
281 221 markom
#if 0
282 361 markom
    /* A couple of sanity checks. */
283
    if (translate(COFF_LONG_H(coffscnhdr.s_vaddr),&breakpoint) < MEMORY_START) {
284
      printf("Section %s starts out of ", coffscnhdr.s_name);
285
      printf("memory (at %x)\n", COFF_LONG_H(coffscnhdr.s_vaddr));
286
      exit(1);
287
    }
288
    if (translate(COFF_LONG_H(coffscnhdr.s_vaddr) + sectsize,&breakpoint) >
289
        MEMORY_START + MEMORY_LEN) {
290
      printf("Section %s ends out of ", coffscnhdr.s_name);
291
      printf("memory.\n");
292
      exit(1);
293
    }
294 221 markom
#endif
295 167 markom
#if 0
296 361 markom
    if (++firstthree == 1 && strcmp(coffscnhdr.s_name, ".text") != 0) {
297
      printf("First section should be .text (%s instead)\n", coffscnhdr.s_name);
298
      exit(1);
299
    }
300
    if (firstthree == 2 && strcmp(coffscnhdr.s_name, ".data") != 0) {
301
      printf("Second section should be .data (%s instead)\n", coffscnhdr.s_name);
302
      exit(1);
303
    }
304
    if (firstthree == 3 && strcmp(coffscnhdr.s_name, ".bss") != 0) {
305
      printf("Third section should be .bss (%s instead)\n", coffscnhdr.s_name);
306
      exit(1);
307
    }
308 167 markom
#else
309 361 markom
    ++firstthree;
310 167 markom
#endif
311 28 lampret
 
312 361 markom
    /* loading section */
313
    freemem = COFF_LONG_H(coffscnhdr.s_paddr);
314
    debug(2,"Starting to load at 0x%x\n", freemem);
315
    if (fseek(inputfs, COFF_LONG_H(coffscnhdr.s_scnptr), SEEK_SET) == -1) {
316
      fclose(inputfs);
317
      perror("readfile_coff");
318
      exit(1);
319
    }
320
    while (sectsize > 0 && (len = fread(&inputbuf, sizeof(inputbuf), 1, inputfs))) {
321
      insn = COFF_LONG_H(inputbuf);
322
      len = insn_len (insn_decode (insn));
323
      if (len == 2)
324
        {
325
          fseek(inputfs, -2, SEEK_CUR);
326
          debug(8,"readfile_coff: %x 0x%x   \n", sectsize, insn >> 16);
327
        }
328
      else
329
        debug(8,"readfile_coff: %x 0x%x   \n", sectsize, insn);
330
      addprogram (freemem, insn, &breakpoint);
331
      sectsize -= len;
332
    }
333
  }
334
  if (firstthree < 3) {
335
    printf("One or more missing sections. At least");
336
    printf(" three sections expected (.text, .data, .bss).\n");
337
    exit(1);
338
  }
339
  if (firstthree > 3) {
340
    printf("Warning: one or more extra sections. These");
341
    printf(" sections were handled as .data sections.\n");
342
  }
343 41 lampret
 
344 361 markom
  fclose(inputfs);
345
  printf("Finished loading COFF.\n");
346
  return;
347 28 lampret
}
348
 
349
/* Load symbols from big-endian COFF file. */
350
 
351
void readsyms_coff(char *filename, unsigned long symptr, long syms)
352
{
353 173 markom
  FILE *inputfs;
354
  struct COFF_syment coffsymhdr;
355
  int breakpoint = 0;
356
  int count = 0;
357
  long nsyms = syms;
358
  if (!(inputfs = fopen(filename, "r"))) {
359
    perror("readsyms_coff");
360
    exit(1);
361
  }
362
 
363
  if (fseek(inputfs, symptr, SEEK_SET) == -1) {
364
    fclose(inputfs);
365
    perror("readsyms_coff");
366
    exit(1);
367
  }
368
 
369
  while(syms--) {
370
    int i, n;
371
    if (fread(&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) {
372
      fclose(inputfs);
373
      perror("readsyms_coff");
374
      exit(1);
375
    }
376
 
377
    n = (unsigned char)coffsymhdr.e_numaux[0];
378 513 markom
 
379
    /* check whether this symbol belongs to a section and is external symbol; ignore all others */
380
    if (COFF_SHORT_H(coffsymhdr.e_scnum) >= 0 && coffsymhdr.e_sclass[0] == C_EXT) {
381
#if 0
382 173 markom
    /* If not important or not in text, skip. */
383 513 markom
    if(COFF_SHORT_H(coffsymhdr.e_type) & COFF_N_TMASK & COFF_STYP_TEXT) {
384
#endif
385
 
386 173 markom
      if (*((unsigned long *)coffsymhdr.e.e.e_zeroes)) {
387 513 markom
        if (strlen(coffsymhdr.e.e_name) && strlen(coffsymhdr.e.e_name) < 9)
388
          add_label(COFF_LONG_H(coffsymhdr.e_value), coffsymhdr.e.e_name);
389
        debug(8, "[%i] Symbol: %s,", count++, coffsymhdr.e.e_name);
390 173 markom
      } else {
391 513 markom
        long fpos = ftell (inputfs);
392 361 markom
 
393 513 markom
        if (fseek(inputfs, symptr + nsyms * COFF_SYMESZ + COFF_LONG_H(coffsymhdr.e.e.e_offset), SEEK_SET) == 0) {
394
          char tmp[33], *s = &tmp[0];
395
          while (s != &tmp[32])
396
            if ((*(s++) = fgetc(inputfs)) == 0) break;
397
          tmp[32] = 0;
398
          add_label(COFF_LONG_H(coffsymhdr.e_value), &tmp[0]);
399
          debug(8, "[%i] Symbol: %s,", count++, &tmp[0]);
400
        }
401
        fseek(inputfs, fpos, SEEK_SET);
402 173 markom
      }
403
 
404 344 markom
      debug(9, " val: 0x%.8x,", COFF_LONG_H(coffsymhdr.e_value));
405
      debug(9, " type: %x, %x, auxs: %i\n", COFF_SHORT_H(coffsymhdr.e_type), *((unsigned short *)coffsymhdr.e_type), n);
406 173 markom
    }
407 28 lampret
 
408 173 markom
    for (i = 0; i < n; i++)
409
      if (fread(&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) {
410 513 markom
        fclose(inputfs);
411
        perror("readsyms_coff3");
412
        exit(1);
413 173 markom
      }
414
    syms -= n;
415
    count += n;
416
  }
417 28 lampret
 
418 173 markom
  fclose(inputfs);
419
  printf("Finished loading symbols.\n");
420
  return;
421 28 lampret
}
422
 
423
/* Identify file type and call appropriate readfile_X routine. It only
424
handles orX-coff-big executables at the moment. */
425
 
426
void identifyfile(char *filename)
427
{
428 361 markom
  FILE *inputfs;
429
  struct COFF_filehdr coffhdr;
430
  size_t len;
431
 
432
  if (!(inputfs = fopen(filename, "r"))) {
433
    fprintf(stderr, "xx %s", filename);
434
    perror("identifyfile1");
435
    fflush(stdout);
436
    fflush(stderr);
437
    exit(1);
438
  }
439
 
440
  if (fread(&coffhdr, sizeof(coffhdr), 1, inputfs) == 1) {
441
    if (COFF_SHORT_H(coffhdr.f_magic) == 0x17a) {
442
          unsigned long opthdr_size;
443
      printf("COFF magic: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_magic));
444
      printf("COFF flags: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_flags));
445
      printf("COFF symptr: 0x%.8x\n", COFF_LONG_H(coffhdr.f_symptr));
446
      if ((COFF_SHORT_H(coffhdr.f_flags) & COFF_F_EXEC) != COFF_F_EXEC) {
447
        printf("This COFF is not an executable.\n");
448
        exit(1);
449
      }
450
      opthdr_size = COFF_SHORT_H(coffhdr.f_opthdr);
451
      if (opthdr_size != sizeof(COFF_AOUTHDR)) {
452
        printf("COFF optional header is missing or not recognized.\n");
453
        printf("COFF f_opthdr: 0x%.2x\n", opthdr_size);
454
        exit(1);
455
      }
456
      fclose(inputfs);
457
      readfile_coff(filename, COFF_SHORT_H(coffhdr.f_nscns));
458
      readsyms_coff(filename, COFF_LONG_H(coffhdr.f_symptr), COFF_LONG_H(coffhdr.f_nsyms));
459
      return;
460
    }
461
    else {
462
      printf("Not COFF, quiting.\n");
463
      fclose(inputfs);
464
      exit (1);
465
    }
466
  }
467
  else {
468
    printf("yy %s", filename);
469
    perror("identifyfile2");
470
  }
471
 
472
  fclose(inputfs);
473 28 lampret
 
474 361 markom
  return;
475 2 cvs
}
476
 
477 67 lampret
 
478
/* Loads file to memory starting at address startaddr and returns freemem. */
479
unsigned long loadcode(char *filename, unsigned long startaddr, unsigned long virtphy_transl)
480 2 cvs
{
481 123 markom
  int breakpoint = 0;
482
 
483 361 markom
  transl_error = 0;
484
  transl_table = virtphy_transl;
485
  freemem = startaddr;
486
  printf("loadcode: filename %s  startaddr=%x  virtphy_transl=%x", filename, startaddr, virtphy_transl);
487
  identifyfile(filename);
488 694 markom
 
489
#if IMM_STATS  
490
  {
491
    int i = 0;
492
    for (i = 0; i < 33; i++) printf ("%i:%i\t", i, bcnt[i]);
493
    printf ("\n");
494
  }
495
#endif
496
 
497 361 markom
  if (transl_error)
498
    return -1;
499
  else
500
    return translate(freemem,&breakpoint);
501 694 markom
 
502 2 cvs
}

powered by: WebSVN 2.1.0

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