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 882

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

powered by: WebSVN 2.1.0

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