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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [cpu/] [common/] [abstract.c] - Blame information for rev 970

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

powered by: WebSVN 2.1.0

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