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

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_1_x/] [or1ksim/] [cpu/] [common/] [abstract.c] - Blame information for rev 638

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

Line No. Rev Author Line
1 2 cvs
/* abstract.c -- Abstract entities
2
   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 66 lampret
/* Abstract memory and routines that go with this. I need to
21 2 cvs
add all sorts of other abstract entities. Currently we have
22
only memory. */
23
 
24 221 markom
#include <stdlib.h>
25 2 cvs
#include <stdio.h>
26
#include <ctype.h>
27
#include <string.h>
28
 
29 6 lampret
#include "config.h"
30 7 jrydberg
#include "sim-config.h"
31 6 lampret
 
32 2 cvs
#include "parse.h"
33
#include "abstract.h"
34 261 markom
#include "labels.h"
35 2 cvs
#include "arch.h"
36
#include "execute.h"
37 32 lampret
#include "sprs.h"
38 35 lampret
#include "stats.h"
39 32 lampret
#include "except.h"
40 123 markom
#include "debug_unit.h"
41 134 markom
#include "opcode/or32.h"
42 547 markom
#include "support/profile.h"
43 2 cvs
 
44
extern unsigned long reg[];
45 138 markom
extern char *disassembled;
46 2 cvs
 
47 28 lampret
/* This is an abstract+physical memory array rather than only physical
48
   memory array */
49 538 markom
static unsigned long *simmem32;
50 2 cvs
 
51 30 lampret
/* Pointer to memory area descriptions that are assigned to individual
52
   peripheral devices. */
53
struct dev_memarea *dev_list;
54
 
55 221 markom
/* Temporary variable to increase speed.  */
56
struct dev_memarea *cur_area;
57
 
58 638 simons
/* These are set by mmu if cache inhibit bit is set for current acces.  */
59
int data_ci, insn_ci;
60
 
61 525 simons
/* Virtual address of current access. */
62
unsigned long cur_vadd;
63
 
64 537 markom
/* Temporary variable, which specifies how many cycles did the memory acces require */
65
extern int mem_cycles;
66
 
67 261 markom
/* Calculates bit mask to fit the data */
68
unsigned long bit_mask (unsigned long data) {
69
  int i = 0;
70
  data--;
71 382 markom
  while (data >> i)
72 261 markom
    data |= 1 << i++;
73
  return data;
74
}
75
 
76
/* Register read and write function for a memory area.
77
   addr is inside the area, if addr & addr_mask == addr_compare
78
   (used also by peripheral devices like 16450 UART etc.) */
79
void register_memoryarea_mask(unsigned long addr_mask, unsigned long addr_compare,
80
                         unsigned long size, unsigned granularity,
81 239 markom
                         unsigned long (readfunc)(unsigned long),
82 261 markom
                         void (writefunc)(unsigned long, unsigned long))
83 30 lampret
{
84 239 markom
  struct dev_memarea **pptmp;
85 261 markom
  unsigned long size_mask = bit_mask (size);
86
  int found_error = 0;
87
  addr_compare &= addr_mask;
88 221 markom
 
89 382 markom
  debug(5, "addr & %08x == %08x to %08x, size %08x, gran %iB\n", addr_mask, addr_compare, addr_compare | bit_mask (size), size, granularity);
90 239 markom
  /* Go to the end of the list. */
91 261 markom
  for(pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next)
92
    if ((addr_compare >= (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)
93
     || (addr_compare + size > (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)) {
94 262 markom
      if (!found_error) {
95 261 markom
        fprintf (stderr, "ERROR: Overlapping memory area(s):\n");
96 262 markom
        fprintf (stderr, "\taddr & %08x == %08x to %08x, size %08x, gran %iB\n", addr_mask, addr_compare, addr_compare | bit_mask (size), size, granularity);
97
      }
98 261 markom
      found_error = 1;
99 424 markom
      fprintf (stderr, "and\taddr & %08x == %08x to %08x, size %08x, gran %iB\n", (*pptmp)->addr_mask, (*pptmp)->addr_compare,
100 261 markom
        (*pptmp)->addr_compare | (*pptmp)->size_mask, (*pptmp)->size, (*pptmp)->granularity);
101
    }
102
 
103
  if (found_error)
104
    exit (-1);
105 537 markom
 
106 239 markom
  cur_area = *pptmp = (struct dev_memarea *)malloc(sizeof(struct dev_memarea));
107 261 markom
  (*pptmp)->addr_mask = addr_mask;
108
  (*pptmp)->addr_compare = addr_compare;
109 239 markom
  (*pptmp)->size = size;
110 261 markom
  (*pptmp)->size_mask = size_mask;
111 239 markom
  (*pptmp)->granularity = granularity;
112
  (*pptmp)->readfunc = readfunc;
113
  (*pptmp)->writefunc = writefunc;
114 479 markom
  (*pptmp)->log = 0;
115 239 markom
  (*pptmp)->next = NULL;
116 261 markom
}
117 221 markom
 
118 261 markom
/* Register read and write function for a memory area.
119
   Memory areas should be aligned. Memory area is rounded up to
120
   fit the nearest 2^n aligment.
121
   (used also by peripheral devices like 16450 UART etc.) */
122
void register_memoryarea(unsigned long addr,
123
                         unsigned long size, unsigned granularity,
124
                         unsigned long (readfunc)(unsigned long),
125
                         void (writefunc)(unsigned long, unsigned long))
126
{
127
  unsigned long size_mask = bit_mask (size);
128
  unsigned long addr_mask = ~size_mask;
129
  register_memoryarea_mask (addr_mask, addr & addr_mask,
130
                      size_mask + 1, granularity,
131
                      readfunc, writefunc);
132 30 lampret
}
133
 
134 261 markom
 
135 30 lampret
/* Check if access is to registered area of memory. */
136 560 markom
inline struct dev_memarea *verify_memoryarea(unsigned long addr)
137 30 lampret
{
138 239 markom
  struct dev_memarea *ptmp;
139 221 markom
 
140 560 markom
  /* Check cached value first */
141
  if (cur_area && (addr & cur_area->addr_mask) == (cur_area->addr_compare & cur_area->addr_mask))
142
    return cur_area;
143
 
144
  /* When mc is enabled, we must check valid also, otherwise we assume it is nonzero */
145
  IFF (config.mc.enabled) {
146
    /* Check list of registered devices. */
147
    for(ptmp = dev_list; ptmp; ptmp = ptmp->next)
148
      if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask) && ptmp->valid)
149
        return cur_area = ptmp;
150
  } else {
151
    /* Check list of registered devices. */
152
    for(ptmp = dev_list; ptmp; ptmp = ptmp->next)
153
      if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask))
154
        return cur_area = ptmp;
155
  }
156 239 markom
  return cur_area = NULL;
157 30 lampret
}
158
 
159 560 markom
inline unsigned long evalsim_mem32(unsigned long memaddr)
160
{
161
  unsigned long temp;
162
 
163
  if (verify_memoryarea(memaddr)) {
164
    switch(cur_area->granularity) {
165
    case 4:
166
      temp = cur_area->readfunc(memaddr);
167
      mem_cycles += cur_area->delayr;
168
      break;
169
    case 1:
170
      temp = cur_area->readfunc(memaddr) << 24;
171
      temp |= cur_area->readfunc(memaddr + 1) << 16;
172
      temp |= cur_area->readfunc(memaddr + 2) << 8;
173
      temp |= cur_area->readfunc(memaddr + 3);
174
      mem_cycles += cur_area->delayr * 4;
175
      break;
176
    case 2:
177
      temp = cur_area->readfunc(memaddr) << 16;
178
      temp |= cur_area->readfunc(memaddr + 2);
179
      mem_cycles += cur_area->delayr * 2;
180
      break;
181
    }
182
  }
183
  return temp;
184
}
185
 
186
unsigned short evalsim_mem16(unsigned long memaddr)
187
{
188
  unsigned long temp;
189
 
190
  if (verify_memoryarea(memaddr)) {
191
    switch(cur_area->granularity) {
192
    case 1:
193
      temp = cur_area->readfunc(memaddr) << 8;
194
      temp |= cur_area->readfunc(memaddr + 1);
195
      mem_cycles += cur_area->delayr * 2;
196
      break;
197
    case 2:
198
      temp = cur_area->readfunc(memaddr);
199
      mem_cycles += cur_area->delayr;
200
      break;
201
    case 4:
202
      temp = evalsim_mem32 (memaddr & ~3ul);
203
      if (memaddr & 2)
204
        temp &= 0xffff;
205
      else
206
        temp >>= 16;
207
      break;
208
    }
209
  }
210
  return temp;
211
}
212
 
213
unsigned char evalsim_mem8(unsigned long memaddr)
214
{
215
  unsigned long temp;
216
 
217
  if (verify_memoryarea(memaddr)) {
218
    switch(cur_area->granularity) {
219
    case 1:
220
      temp = cur_area->readfunc(memaddr);
221
      mem_cycles += cur_area->delayr;
222
      break;
223
    case 2:
224
      temp = evalsim_mem16 (memaddr & ~1ul);
225
      if (memaddr & 1)
226
        temp &= 0xff;
227
      else
228
        temp >>= 8;
229
      break;
230
    case 4:
231
      temp = evalsim_mem32 (memaddr & ~3ul);
232
      temp >>= 8 * (3 - (memaddr & 3));
233
      temp &= 0xff;
234
      break;
235
    }
236
  }
237
  return temp;
238
}
239
 
240 2 cvs
/* Returns 32-bit values from mem array. Big endian version. */
241 349 simons
unsigned long read_mem(unsigned long memaddr,int* breakpoint)
242
{
243
  unsigned long temp;
244
  struct dev_memarea *dev;
245
 
246 525 simons
  cur_vadd = memaddr;
247 550 markom
  if (config.debug.enabled)
248 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
249
  temp = evalsim_mem32(memaddr);
250 611 simons
  if (!cur_area) {
251
    printf("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr);
252
    except_handle(EXCEPT_BUSERR, cur_vadd);
253
    temp = 0;
254
  }
255
 
256 599 simons
  if (!pending.valid && cur_area->log)
257 587 markom
    fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
258 550 markom
  if (config.debug.enabled)
259 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
260
  return temp;
261 537 markom
}
262 349 simons
 
263
/* Returns 32-bit values from mem array. Big endian version. */
264 123 markom
unsigned long eval_mem32(unsigned long memaddr,int* breakpoint)
265 2 cvs
{
266 6 lampret
 
267 239 markom
  unsigned long temp;
268
  struct dev_memarea *dev;
269 123 markom
 
270 547 markom
  if (config.sim.mprofile)
271
    mprofile (memaddr, MPROF_32 | MPROF_READ);
272
 
273 538 markom
  if (memaddr & 3) {
274
    except_handle (EXCEPT_ALIGN, memaddr);
275
    return 0;
276
  }
277 557 markom
 
278 631 simons
  if (config.debug.enabled)
279
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
280
 
281 574 markom
  cur_vadd = memaddr;
282 631 simons
 
283
  memaddr = dmmu_translate(memaddr, 0);
284 574 markom
  if (pending.valid)
285
    return 0;
286
 
287 631 simons
  temp = dc_simulate_read(memaddr, 4);
288 611 simons
  if (!cur_area) {
289
    printf("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
290
    except_handle(EXCEPT_BUSERR, cur_vadd);
291
    temp = 0;
292
  }
293
 
294 599 simons
  if (!pending.valid && cur_area->log)
295 587 markom
    fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
296 550 markom
  if (config.debug.enabled)
297 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
298 239 markom
  return temp;
299 66 lampret
}
300
 
301 349 simons
/* Returns 32-bit values from mem array. Big endian version. */
302
unsigned long eval_insn(unsigned long memaddr,int* breakpoint)
303
{
304
  unsigned long temp;
305
  struct dev_memarea *dev;
306
 
307 547 markom
  if (config.sim.mprofile)
308
    mprofile (memaddr, MPROF_32 | MPROF_FETCH);
309 532 markom
//  memaddr = simulate_ic_mmu_fetch(memaddr);
310 525 simons
  cur_vadd = pc;
311 550 markom
  if (config.debug.enabled)
312 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
313 631 simons
  if (config.ic.enabled)
314
    temp = ic_simulate_fetch(memaddr);
315
  else
316
    temp = evalsim_mem32(memaddr);
317 611 simons
  if (!cur_area) {
318
    printf("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
319
    except_handle(EXCEPT_BUSERR, cur_vadd);
320
    temp = 0;
321
  }
322
 
323 599 simons
  if (!pending.valid && cur_area->log)
324 587 markom
    fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
325 550 markom
  if (config.debug.enabled)
326 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
327
  return temp;
328
}
329
 
330 2 cvs
/* Returns 16-bit values from mem array. Big endian version. */
331
 
332 123 markom
unsigned short eval_mem16(unsigned long memaddr,int* breakpoint)
333 2 cvs
{
334 239 markom
  unsigned short temp;
335 547 markom
 
336
  if (config.sim.mprofile)
337
    mprofile (memaddr, MPROF_16 | MPROF_READ);
338
 
339 538 markom
  if (memaddr & 1) {
340
    except_handle (EXCEPT_ALIGN, memaddr);
341
    return 0;
342
  }
343 574 markom
 
344 631 simons
  if (config.debug.enabled)
345
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
346
 
347 574 markom
  cur_vadd = memaddr;
348 631 simons
 
349
  memaddr = dmmu_translate(memaddr, 0);
350 574 markom
  if (pending.valid)
351
    return 0;
352 66 lampret
 
353 631 simons
  temp = (unsigned short)dc_simulate_read(memaddr, 2);
354 611 simons
  if (!cur_area) {
355
    printf("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr);
356
    except_handle(EXCEPT_BUSERR, cur_vadd);
357
    temp = 0;
358
  }
359
 
360 599 simons
  if (!pending.valid && cur_area->log)
361 587 markom
    fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
362 550 markom
  if (config.debug.enabled)
363 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
364 239 markom
  return temp;
365 66 lampret
}
366
 
367 6 lampret
/* Returns 8-bit values from mem array. */
368 2 cvs
 
369 123 markom
unsigned char eval_mem8(unsigned long memaddr,int* breakpoint)
370 221 markom
{
371 631 simons
  unsigned char temp;
372 547 markom
 
373
  if (config.sim.mprofile)
374
    mprofile (memaddr, MPROF_8 | MPROF_READ);
375
 
376 631 simons
  if (config.debug.enabled)
377
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr);  /* 28/05/01 CZ */
378
 
379 525 simons
  cur_vadd = memaddr;
380 631 simons
 
381
  memaddr = dmmu_translate(memaddr, 0);
382 458 simons
  if (pending.valid)
383
    return 0;
384 6 lampret
 
385 631 simons
  temp = (unsigned char)dc_simulate_read(memaddr, 1);
386 611 simons
  if (!cur_area) {
387
    printf("EXCEPTION: read out of memory (8-bit access to %.8lx)\n", memaddr);
388
    except_handle(EXCEPT_BUSERR, cur_vadd);
389
    temp = 0;
390
  }
391
 
392 599 simons
  if (!pending.valid && cur_area->log)
393 587 markom
    fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
394 550 markom
  if (config.debug.enabled)
395 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
396 239 markom
  return temp;
397 66 lampret
}
398
 
399
void setsim_mem32(unsigned long memaddr, unsigned long value)
400
{
401 239 markom
  struct dev_memarea *dev;
402 66 lampret
 
403 239 markom
  if (verify_memoryarea(memaddr)) {
404
    switch(cur_area->granularity) {
405 538 markom
    case 4:
406
      cur_area->writefunc(memaddr, value);
407
      mem_cycles += cur_area->delayw;
408
      break;
409 239 markom
    case 1:
410 251 erez
      cur_area->writefunc(memaddr    , (value >> 24) & 0xFF);
411 239 markom
      cur_area->writefunc(memaddr + 1, (value >> 16) & 0xFF);
412 251 erez
      cur_area->writefunc(memaddr + 2, (value >>  8) & 0xFF);
413
      cur_area->writefunc(memaddr + 3, (value      ) & 0xFF);
414 537 markom
      mem_cycles += cur_area->delayw * 4;
415 239 markom
      break;
416
    case 2:
417
      cur_area->writefunc(memaddr, (value >> 16) & 0xFFFF);
418
      cur_area->writefunc(memaddr + 2, value & 0xFFFF);
419 537 markom
      mem_cycles += cur_area->delayw * 2;
420 239 markom
      break;
421 242 markom
    }
422 239 markom
  } else {
423
    printf("EXCEPTION: write out of memory (32-bit access to %.8lx)\n", memaddr);
424 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
425 239 markom
  }
426 2 cvs
}
427
 
428 66 lampret
void setsim_mem16(unsigned long memaddr, unsigned short value)
429
{
430 538 markom
  unsigned long temp;
431 239 markom
  if (verify_memoryarea(memaddr)) {
432
    switch(cur_area->granularity) {
433
    case 1:
434
      cur_area->writefunc(memaddr, (value >> 8) & 0xFF);
435
      cur_area->writefunc(memaddr + 1, value & 0xFF);
436 537 markom
      mem_cycles += cur_area->delayw * 2;
437 239 markom
      break;
438
    case 2:
439 251 erez
      cur_area->writefunc(memaddr, value & 0xFFFF);
440 537 markom
      mem_cycles += cur_area->delayw;
441 239 markom
      break;
442
    case 4:
443 538 markom
      temp = evalsim_mem32 (memaddr & ~3ul);
444 546 simons
      temp &= 0xffff << ((memaddr & 2) ? 16 : 0);
445
      temp |= (unsigned long)(value & 0xffff) << ((memaddr & 2) ? 0 : 16);
446 538 markom
      setsim_mem32 (memaddr & ~3ul, temp);
447 239 markom
      break;
448
    }
449
  } else {
450
    printf("EXCEPTION: write out of memory (16-bit access to %.8lx)\n", memaddr);
451 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
452 239 markom
  }
453 2 cvs
}
454
 
455 66 lampret
void setsim_mem8(unsigned long memaddr, unsigned char value)
456
{
457 538 markom
  unsigned long temp;
458 239 markom
  if (verify_memoryarea(memaddr)) {
459 538 markom
    switch (cur_area->granularity) {
460
    case 1:
461 239 markom
      cur_area->writefunc(memaddr, value);
462 537 markom
      mem_cycles += cur_area->delayw;
463 538 markom
      break;
464
    case 2:
465
      temp = evalsim_mem16 (memaddr & ~1ul);
466 546 simons
      temp &= 0xff << ((memaddr & 1) ? 8 : 0);
467
      temp |= (unsigned short)(value & 0xff) << ((memaddr & 1) ? 0 : 8);
468 538 markom
      setsim_mem16 (memaddr & ~1ul, temp);
469
      break;
470
    case 4:
471
      temp = evalsim_mem32 (memaddr & ~3ul);
472
      temp &= ~(0xff << (8 * (3 - (memaddr & 3))));
473
      temp |= (unsigned long)(value & 0xff) << (8 * (3 - (memaddr & 3)));
474
      setsim_mem32 (memaddr & ~3ul, temp);
475
      break;
476 239 markom
    }
477
  } else {
478
    printf("EXCEPTION: write out of memory (8-bit access to %.8lx)\n", memaddr);
479 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
480 239 markom
  }
481 2 cvs
}
482 30 lampret
 
483 587 markom
/* Set mem, 32-bit. Big endian version. */
484
 
485
void set_mem32(unsigned long memaddr, unsigned long value,int* breakpoint)
486
{
487
  if (config.sim.mprofile)
488
    mprofile (memaddr, MPROF_32 | MPROF_WRITE);
489
 
490
  if (memaddr & 3) {
491
    except_handle (EXCEPT_ALIGN, memaddr);
492
    return;
493
  }
494
 
495
  cur_vadd = memaddr;
496 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
497 587 markom
  /* If we produced exception don't set anything */
498
  if (pending.valid)
499
    return;
500
 
501
  if (config.debug.enabled) {
502
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
503
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
504
  }
505
 
506
  if (cur_area->log)
507
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
508
 
509 631 simons
  dc_simulate_write(memaddr, value, 4);
510 587 markom
}
511
 
512
/* Set mem, 16-bit. Big endian version. */
513
 
514
void set_mem16(unsigned long memaddr, unsigned short value,int* breakpoint)
515
{
516
  if (config.sim.mprofile)
517
    mprofile (memaddr, MPROF_16 | MPROF_WRITE);
518
 
519
  if (memaddr & 1) {
520
    except_handle (EXCEPT_ALIGN, memaddr);
521
    return;
522
  }
523
 
524
  cur_vadd = memaddr;
525 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
526 587 markom
  /* If we produced exception don't set anything */
527
  if (pending.valid)
528
    return;
529
 
530
  if (config.debug.enabled) {
531
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
532
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
533
  }
534
 
535
  if (cur_area->log)
536
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
537
 
538 631 simons
  dc_simulate_write(memaddr, (unsigned long)value, 2);
539 587 markom
}
540
 
541
/* Set mem, 8-bit. */
542
 
543
void set_mem8(unsigned long memaddr, unsigned char value,int* breakpoint)
544
{
545
  if (config.sim.mprofile)
546
    mprofile (memaddr, MPROF_8 | MPROF_WRITE);
547
 
548
  cur_vadd = memaddr;
549 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
550 587 markom
  /* If we produced exception don't set anything */
551
  if (pending.valid) return;
552
 
553
  if (config.debug.enabled) {
554
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
555
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
556
  }
557
 
558
  if (cur_area->log)
559
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
560
 
561 631 simons
  dc_simulate_write(memaddr, (unsigned long)value, 1);
562 587 markom
}
563
 
564 361 markom
void dumpmemory(unsigned int from, unsigned int to, int disasm, int nl)
565
{
566
  unsigned int i, j;
567
  struct label_entry *tmp;
568
  int breakpoint = 0;
569
  int ilen = disasm ? 4 : 16;
570
 
571
  for(i = from; i < to; i += ilen) {
572
    printf("%.8x: ", i);
573
    for (j = 0; j < ilen;) {
574
      int data = -1;
575
      if (!disasm) {
576
        tmp = NULL;
577
        if (verify_memoryarea(i+j)) {
578
          struct label_entry *entry;
579
          entry = get_label(i + j);
580
          if (entry)
581
            printf("(%s)", entry->name);
582
          printf("%02x ", data = evalsim_mem8(i+j));
583
        } else printf("XX ");
584
        j++;
585
      } else {
586
        int breakpoint;
587
        unsigned int _insn = read_mem(i, &breakpoint);
588
        int index = insn_decode (_insn);
589
        int len = insn_len (index);
590
 
591
        tmp = NULL;
592
        if (verify_memoryarea(i+j)) {
593
          struct label_entry *entry;
594
          entry = get_label(i + j);
595
          if (entry)
596
            printf("(%s)", entry->name);
597
 
598
          printf(": %08x ", (unsigned long)_insn);
599
          if (index >= 0) {
600
            disassemble_insn (_insn);
601
            printf(" %s", disassembled);
602
          } else
603
            printf("<invalid>");
604
        } else printf("XXXXXXXX");
605
        j += len;
606
      }
607
    }
608
    if (nl)
609
      printf ("\n");
610
  }
611
}
612
 
613 538 markom
unsigned long simmem_read_word(unsigned long addr) {
614
  return simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2];
615 221 markom
}
616
 
617 538 markom
void simmem_write_word(unsigned long addr, unsigned long value) {
618
  simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2] = value;
619 221 markom
}
620
 
621 424 markom
unsigned long simmem_read_zero(unsigned long addr) {
622
  if (config.sim.verbose)
623
    fprintf (stderr, "WARNING: memory read from non-read memory area 0x%08x.\n", addr);
624
  return 0;
625
}
626
 
627
void simmem_write_null(unsigned long addr, unsigned long value) {
628
  if (config.sim.verbose)
629
    fprintf (stderr, "WARNING: memory write to 0x%08x, non-write memory area (value 0x%08x).\n", addr, value);
630
}
631
 
632
/* Initialize memory table from a config struct */
633
 
634
void init_memory_table ()
635 221 markom
{
636 239 markom
  unsigned long memory_needed = 0;
637 426 markom
 
638 424 markom
  /* If nothing was defined, use default memory block */
639
  if (config.memory.nmemories) {
640
    int i;
641
    for (i = 0; i < config.memory.nmemories; i++) {
642
      unsigned long start = config.memory.table[i].baseaddr;
643
      unsigned long length = config.memory.table[i].size;
644
      char *type = config.memory.table[i].name;
645
      int rd = config.memory.table[i].delayr;
646
      int wd = config.memory.table[i].delayw;
647
      int ce = config.memory.table[i].ce;
648
      if (config.sim.verbose)
649
        debug (1, "%08X %08X (%i KB): %s (activated by CE%i; read delay = %icyc, write delay = %icyc)\n",
650
          start, length, length >> 10, type, ce, rd, wd);
651 538 markom
      register_memoryarea(start, length, 4, &simmem_read_word, &simmem_write_word);
652 239 markom
      cur_area->misc = memory_needed;
653 540 simons
      cur_area->chip_select = ce;
654 543 simons
      cur_area->valid = 1;
655 424 markom
      cur_area->delayw = wd;
656
      cur_area->delayr = rd;
657 426 markom
      if (config.memory.table[i].log[0] != '\0') {
658
        if ((cur_area->log = fopen (config.memory.table[i].log, "wt+")) == NULL)
659
          fprintf (stderr, "WARNING: Cannot open '%s'.\n", config.memory.table[i].log);
660
      } else
661 554 markom
        cur_area->log = NULL;
662 261 markom
      memory_needed += cur_area->size;
663 239 markom
    }
664
    printf ("\n");
665
  } else {
666 308 markom
    if (config.sim.verbose)
667 424 markom
      fprintf (stderr, "WARNING: Memory not defined, assuming standard configuration.\n");
668 538 markom
    register_memoryarea(DEFAULT_MEMORY_START, DEFAULT_MEMORY_LEN, 4, &simmem_read_word, &simmem_write_word);
669 554 markom
    cur_area->misc = memory_needed;
670
    cur_area->chip_select = 0;
671
    cur_area->valid = 1;
672
    cur_area->delayw = 1;
673
    cur_area->delayr = 1;
674
    cur_area->log = NULL;
675 261 markom
    memory_needed += cur_area->size;
676 239 markom
  }
677 424 markom
 
678 538 markom
  simmem32 = (unsigned long *) malloc (sizeof (unsigned long) * ((memory_needed + 3) / 4));
679
  if (!simmem32) {
680 239 markom
    fprintf (stderr, "Failed to allocate sim memory. Aborting\n");
681
    exit (-1);
682
  }
683 221 markom
}
684 424 markom
 
685
/* Changes read/write memory in read/write only */
686
 
687
void lock_memory_table ()
688
{
689
  struct dev_memarea *ptmp;
690
 
691
  /* Check list of registered devices. */
692
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
693 538 markom
    if (ptmp->delayr < 0 && ptmp->readfunc == &simmem_read_word)
694 424 markom
      ptmp->readfunc = &simmem_read_zero;
695 538 markom
    if (ptmp->delayw < 0 && ptmp->writefunc == &simmem_write_word)
696 424 markom
      ptmp->writefunc = &simmem_write_null;
697 543 simons
 
698
    /* If this mem area is not for memory chip under MC control
699
       then this area is valid all the time */
700
    if (ptmp->readfunc != &simmem_read_word) {
701
      ptmp->valid = 1;
702
      ptmp->chip_select = -1;
703
    }
704 424 markom
  }
705
}
706 426 markom
 
707
/* Closes files, etc. */
708
 
709
void done_memory_table ()
710
{
711
  struct dev_memarea *ptmp;
712
 
713
  /* Check list of registered devices. */
714
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
715
    if (ptmp->log)
716
      fclose (ptmp->log);
717
  }
718
}
719 427 markom
 
720
/* Displays current memory configuration */
721
 
722
void memory_table_status ()
723
{
724
  struct dev_memarea *ptmp;
725
 
726
  /* Check list of registered devices. */
727
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
728
    printf ("addr & %08x == %08x to %08x, size %08x, gran %iB\n",
729
      ptmp->addr_mask, ptmp->addr_compare, ptmp->addr_compare | bit_mask (ptmp->size),
730
      ptmp->size, ptmp->granularity);
731
    printf ("\t");
732
    if (ptmp->delayr >= 0)
733
      printf ("read delay = %i cycles, ", ptmp->delayr);
734
    else
735
      printf ("reads not possible, ");
736
 
737
    if (ptmp->delayw >= 0)
738
      printf ("write delay = %i cycles", ptmp->delayw);
739
    else
740
      printf ("writes not possible");
741
 
742
    if (ptmp->log)
743
      printf (", (logged)\n");
744
    else
745
      printf ("\n");
746
  }
747
}
748 433 markom
 
749
/* Outputs time in pretty form to dest string */
750
 
751
void generate_time_pretty (char *dest, long time_ps)
752
{
753
  int exp3 = 0;
754
  if (time_ps) {
755
    while ((time_ps % 1000) == 0) {
756
      time_ps /= 1000;
757
      exp3++;
758
    }
759
  }
760
  sprintf (dest, "%i%cs", time_ps, "pnum"[exp3]);
761
}

powered by: WebSVN 2.1.0

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