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 427

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 "trace.h"
37
#include "execute.h"
38 32 lampret
#include "sprs.h"
39 35 lampret
#include "stats.h"
40 32 lampret
#include "except.h"
41 123 markom
#include "debug_unit.h"
42 134 markom
#include "opcode/or32.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 221 markom
static struct mem_entry *simmem;
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 349 simons
/* It returns physical address. */
59
unsigned long translate_vrt_to_phy_add(unsigned long virtaddr)
60 77 lampret
{
61 239 markom
  if (config.ic.tagtype == NONE)
62
    return virtaddr;
63
  else
64
    if (config.ic.tagtype == VIRTUAL) {
65
      return immu_translate(virtaddr);
66
    }
67
    else if (config.dc.tagtype == PHYSICAL) {
68
      unsigned long phyaddr = immu_translate(virtaddr);
69
      return phyaddr;
70
    }
71
    else {
72
      printf("INTERNAL ERROR: Unknown insn cache type.\n");
73
      cont_run = 0;
74
    }
75 221 markom
 
76 239 markom
  return -1;
77 77 lampret
}
78
 
79 349 simons
/* Calls IMMU translation routines before simulating insn
80
cache for virtually indexed insn cache or after simulating insn cache
81
for physically indexed insn cache. It returns physical address. */
82
 
83
unsigned long simulate_ic_mmu_fetch(unsigned long virtaddr)
84
{
85
 
86
  unsigned long phyaddr;
87
 
88
  if ((phyaddr = translate_vrt_to_phy_add(virtaddr)) != -1) {
89
    ic_simulate_fetch(phyaddr);
90
    return phyaddr;
91
  }
92
  else {
93
    printf("INTERNAL ERROR: Unknown insn cache type.\n");
94
    cont_run = 0;
95
  }
96
  return -1;
97
}
98
 
99 77 lampret
/* Calls DMMU translation routines (load cycles) before simulating data
100 239 markom
   cache for virtually indexed data cache or after simulating data cache
101
   for physically indexed data cache. It returns physical address. */
102 6 lampret
 
103
unsigned long simulate_dc_mmu_load(unsigned long virtaddr)
104
{
105 239 markom
  if (config.dc.tagtype == NONE)
106
    return virtaddr;
107
  else
108 327 lampret
  if (config.dc.tagtype == VIRTUAL) {
109
    dc_simulate_read(virtaddr);
110
    return dmmu_translate(virtaddr);
111 239 markom
  }
112
  else if (config.dc.tagtype == PHYSICAL) {
113 327 lampret
    unsigned long phyaddr = dmmu_translate(virtaddr);
114
    dc_simulate_read(phyaddr);
115 239 markom
    return phyaddr;
116
  }
117
  else {
118 327 lampret
    printf("INTERNAL ERROR: Unknown data cache type.\n");
119 239 markom
    cont_run = 0;
120
  }
121 221 markom
 
122 239 markom
  return -1;
123 6 lampret
}
124
 
125 77 lampret
/* Calls DMMU translation routines (store cycles) before simulating data
126 6 lampret
cache for virtually indexed data cache or after simulating data cache
127
for physically indexed data cache. It returns physical address. */
128
 
129
unsigned long simulate_dc_mmu_store(unsigned long virtaddr)
130
{
131 239 markom
  if (config.dc.tagtype == NONE)
132
    return virtaddr;
133
  else
134
  if (config.dc.tagtype == VIRTUAL) {
135
    dc_simulate_write(virtaddr);
136
    return dmmu_translate(virtaddr);
137
  }
138
  else if (config.dc.tagtype == PHYSICAL) {
139
    unsigned long phyaddr = dmmu_translate(virtaddr);
140
    dc_simulate_write(phyaddr);
141
    return phyaddr;
142
  }
143
  else {
144
    printf("INTERNAL ERROR: Unknown data cache type.\n");
145
    cont_run = 0;
146
  }
147 221 markom
 
148 239 markom
  return -1;
149 6 lampret
}
150
 
151 261 markom
/* Calculates bit mask to fit the data */
152
unsigned long bit_mask (unsigned long data) {
153
  int i = 0;
154
  data--;
155 382 markom
  while (data >> i)
156 261 markom
    data |= 1 << i++;
157
  return data;
158
}
159
 
160
/* Register read and write function for a memory area.
161
   addr is inside the area, if addr & addr_mask == addr_compare
162
   (used also by peripheral devices like 16450 UART etc.) */
163
void register_memoryarea_mask(unsigned long addr_mask, unsigned long addr_compare,
164
                         unsigned long size, unsigned granularity,
165 239 markom
                         unsigned long (readfunc)(unsigned long),
166 261 markom
                         void (writefunc)(unsigned long, unsigned long))
167 30 lampret
{
168 239 markom
  struct dev_memarea **pptmp;
169 261 markom
  unsigned long size_mask = bit_mask (size);
170
  int found_error = 0;
171
  addr_compare &= addr_mask;
172 221 markom
 
173 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);
174 239 markom
  /* Go to the end of the list. */
175 261 markom
  for(pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next)
176
    if ((addr_compare >= (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)
177
     || (addr_compare + size > (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)) {
178 262 markom
      if (!found_error) {
179 261 markom
        fprintf (stderr, "ERROR: Overlapping memory area(s):\n");
180 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);
181
      }
182 261 markom
      found_error = 1;
183 424 markom
      fprintf (stderr, "and\taddr & %08x == %08x to %08x, size %08x, gran %iB\n", (*pptmp)->addr_mask, (*pptmp)->addr_compare,
184 261 markom
        (*pptmp)->addr_compare | (*pptmp)->size_mask, (*pptmp)->size, (*pptmp)->granularity);
185
    }
186
 
187
  if (found_error)
188
    exit (-1);
189
 
190 239 markom
  cur_area = *pptmp = (struct dev_memarea *)malloc(sizeof(struct dev_memarea));
191 261 markom
  (*pptmp)->addr_mask = addr_mask;
192
  (*pptmp)->addr_compare = addr_compare;
193 239 markom
  (*pptmp)->size = size;
194 261 markom
  (*pptmp)->size_mask = size_mask;
195 239 markom
  (*pptmp)->granularity = granularity;
196
  (*pptmp)->readfunc = readfunc;
197
  (*pptmp)->writefunc = writefunc;
198
  (*pptmp)->next = NULL;
199 261 markom
}
200 221 markom
 
201 261 markom
/* Register read and write function for a memory area.
202
   Memory areas should be aligned. Memory area is rounded up to
203
   fit the nearest 2^n aligment.
204
   (used also by peripheral devices like 16450 UART etc.) */
205
void register_memoryarea(unsigned long addr,
206
                         unsigned long size, unsigned granularity,
207
                         unsigned long (readfunc)(unsigned long),
208
                         void (writefunc)(unsigned long, unsigned long))
209
{
210
  unsigned long size_mask = bit_mask (size);
211
  unsigned long addr_mask = ~size_mask;
212
  register_memoryarea_mask (addr_mask, addr & addr_mask,
213
                      size_mask + 1, granularity,
214
                      readfunc, writefunc);
215 30 lampret
}
216
 
217 261 markom
 
218 30 lampret
/* Check if access is to registered area of memory. */
219
struct dev_memarea *verify_memoryarea(unsigned long addr)
220
{
221 239 markom
  struct dev_memarea *ptmp;
222 221 markom
 
223 239 markom
  /* Check list of registered devices. */
224
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next)
225 261 markom
    if ((addr & ptmp->addr_mask) == ptmp->addr_compare)
226 239 markom
      return cur_area = ptmp;
227
  return cur_area = NULL;
228 30 lampret
}
229
 
230 2 cvs
/* Returns 32-bit values from mem array. Big endian version. */
231 349 simons
unsigned long read_mem(unsigned long memaddr,int* breakpoint)
232
{
233
  unsigned long temp;
234
  struct dev_memarea *dev;
235
 
236
  slp_checkaccess(memaddr, SLP_MEMREAD);
237
  if (DEBUG_ENABLED)
238
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
239
  temp = evalsim_mem32(memaddr);
240
  if (DEBUG_ENABLED)
241
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
242
  return temp;
243
}
244
 
245
/* Returns 32-bit values from mem array. Big endian version. */
246 123 markom
unsigned long eval_mem32(unsigned long memaddr,int* breakpoint)
247 2 cvs
{
248 6 lampret
 
249 239 markom
  unsigned long temp;
250
  struct dev_memarea *dev;
251 123 markom
 
252 239 markom
  slp_checkaccess(memaddr, SLP_MEMREAD);
253
  memaddr = simulate_dc_mmu_load(memaddr);
254 270 markom
  if (DEBUG_ENABLED)
255
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
256 239 markom
  temp = evalsim_mem32(memaddr);
257 270 markom
  if (DEBUG_ENABLED)
258
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
259 239 markom
  return temp;
260 66 lampret
}
261
 
262 349 simons
/* Returns 32-bit values from mem array. Big endian version. */
263
unsigned long eval_insn(unsigned long memaddr,int* breakpoint)
264
{
265
 
266
  unsigned long temp;
267
  struct dev_memarea *dev;
268
 
269
  slp_checkaccess(memaddr, SLP_MEMREAD);
270 416 simons
//  memaddr = simulate_ic_mmu_fetch(memaddr);
271
  ic_simulate_fetch(memaddr);
272 349 simons
  if (DEBUG_ENABLED)
273
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
274
  temp = evalsim_mem32(memaddr);
275
  if (DEBUG_ENABLED)
276
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
277
  return temp;
278
}
279
 
280 221 markom
unsigned long evalsim_mem32(unsigned long memaddr)
281 66 lampret
{
282 239 markom
  unsigned long temp;
283 221 markom
 
284 239 markom
  if (verify_memoryarea(memaddr)) {
285
    switch(cur_area->granularity) {
286
    case 1:
287
      temp = cur_area->readfunc(memaddr) << 24;
288
      temp |= cur_area->readfunc(memaddr + 1) << 16;
289
      temp |= cur_area->readfunc(memaddr + 2) << 8;
290
      temp |= cur_area->readfunc(memaddr + 3);
291
      break;
292
    case 2:
293
      temp = cur_area->readfunc(memaddr) << 16;
294
      temp |= cur_area->readfunc(memaddr + 2);
295
      break;
296
    case 4:
297
      temp = cur_area->readfunc(memaddr);
298
      break;
299 426 markom
    }
300
    if (cur_area->log)
301
      fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
302 239 markom
  } else {
303
    printf("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
304
    cont_run = 0;
305
    temp = 0;
306
  }
307
  return temp;
308 2 cvs
}
309
 
310
/* Returns 16-bit values from mem array. Big endian version. */
311
 
312 123 markom
unsigned short eval_mem16(unsigned long memaddr,int* breakpoint)
313 2 cvs
{
314 239 markom
  unsigned short temp;
315
  memaddr = simulate_dc_mmu_load(memaddr);
316 270 markom
  if (DEBUG_ENABLED)
317
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
318 66 lampret
 
319 239 markom
  temp = evalsim_mem16(memaddr);
320 270 markom
  if (DEBUG_ENABLED)
321
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
322 239 markom
  return temp;
323 66 lampret
}
324
 
325 221 markom
unsigned short evalsim_mem16(unsigned long memaddr)
326 66 lampret
{
327 239 markom
  unsigned short temp;
328 221 markom
 
329 239 markom
  if (verify_memoryarea(memaddr)) {
330
    switch(cur_area->granularity) {
331
    case 1:
332
      temp = cur_area->readfunc(memaddr) << 8;
333
      temp |= cur_area->readfunc(memaddr + 1);
334
      break;
335
    case 2:
336
      temp = cur_area->readfunc(memaddr);
337
      break;
338
    case 4:
339
      printf("EXCEPTION: read 16-bit value from 32-bit region (address 0x%08lX)\n", cur_area->granularity * 8, memaddr);
340
      cont_run = 0;
341
      break;
342
    }
343 426 markom
    if (cur_area->log)
344
      fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
345 239 markom
  } else {
346
    printf("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr);
347
    cont_run = 0;
348
    temp = 0;
349
  }
350
  return temp;
351 2 cvs
}
352
 
353
 
354 6 lampret
/* Returns 8-bit values from mem array. */
355 2 cvs
 
356 123 markom
unsigned char eval_mem8(unsigned long memaddr,int* breakpoint)
357 221 markom
{
358 239 markom
  unsigned char temp;
359
  memaddr = simulate_dc_mmu_load(memaddr);
360 270 markom
  if (DEBUG_ENABLED)
361
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr);  /* 28/05/01 CZ */
362 6 lampret
 
363 239 markom
  temp = evalsim_mem8(memaddr);
364 270 markom
  if (DEBUG_ENABLED)
365
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
366 239 markom
  return temp;
367 66 lampret
}
368
 
369 221 markom
unsigned char evalsim_mem8(unsigned long memaddr)
370
{
371 239 markom
  unsigned char temp;
372 123 markom
 
373 239 markom
  if (verify_memoryarea(memaddr)) {
374
    switch(cur_area->granularity) {
375
    case 1:
376
      temp = cur_area->readfunc(memaddr);
377
      break;
378
    case 2:
379
    case 4:
380
      printf("EXCEPTION: read 8-bit value from %u-bit region (address 0x%08lX)\n", cur_area->granularity * 8, memaddr);
381
      cont_run = 0;
382
      break;
383
    }
384 426 markom
    if (cur_area->log)
385
      fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
386 239 markom
  } else {
387
    printf("EXCEPTION: read out of memory (8-bit access to %.8lx)\n", memaddr);
388
    cont_run = 0;
389
    temp = 0;
390
  }
391
  return temp;
392 2 cvs
}
393
 
394
/* Set mem, 32-bit. Big endian version. */
395
 
396 123 markom
void set_mem32(unsigned long memaddr, unsigned long value,int* breakpoint)
397 2 cvs
{
398 239 markom
  slp_checkaccess(memaddr, SLP_MEMWRITE);
399
  memaddr = simulate_dc_mmu_store(memaddr);
400 221 markom
 
401 270 markom
  if (DEBUG_ENABLED) {
402
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
403
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
404
  }
405 123 markom
 
406 239 markom
  setsim_mem32(memaddr, value);
407 66 lampret
}
408
 
409
void setsim_mem32(unsigned long memaddr, unsigned long value)
410
{
411 239 markom
  struct dev_memarea *dev;
412 66 lampret
 
413 239 markom
  if (verify_memoryarea(memaddr)) {
414 426 markom
    if (cur_area->log)
415
      fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
416 239 markom
    switch(cur_area->granularity) {
417
    case 1:
418 251 erez
      cur_area->writefunc(memaddr    , (value >> 24) & 0xFF);
419 239 markom
      cur_area->writefunc(memaddr + 1, (value >> 16) & 0xFF);
420 251 erez
      cur_area->writefunc(memaddr + 2, (value >>  8) & 0xFF);
421
      cur_area->writefunc(memaddr + 3, (value      ) & 0xFF);
422 239 markom
      break;
423
    case 2:
424
      cur_area->writefunc(memaddr, (value >> 16) & 0xFFFF);
425
      cur_area->writefunc(memaddr + 2, value & 0xFFFF);
426
      break;
427
    case 4:
428
      cur_area->writefunc(memaddr, value);
429
      break;
430 242 markom
    }
431 239 markom
  } else {
432
    printf("EXCEPTION: write out of memory (32-bit access to %.8lx)\n", memaddr);
433
    cont_run = 0;
434
  }
435 2 cvs
}
436
 
437
/* Set mem, 16-bit. Big endian version. */
438
 
439 123 markom
void set_mem16(unsigned long memaddr, unsigned short value,int* breakpoint)
440 2 cvs
{
441 239 markom
  memaddr = simulate_dc_mmu_store(memaddr);
442 221 markom
 
443 270 markom
  if (DEBUG_ENABLED) {
444
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
445
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
446
  }
447 123 markom
 
448 239 markom
  setsim_mem16(memaddr, value);
449 66 lampret
}
450
 
451
void setsim_mem16(unsigned long memaddr, unsigned short value)
452
{
453 239 markom
  if (verify_memoryarea(memaddr)) {
454 426 markom
    if (cur_area->log)
455
      fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
456 239 markom
    switch(cur_area->granularity) {
457
    case 1:
458
      cur_area->writefunc(memaddr, (value >> 8) & 0xFF);
459
      cur_area->writefunc(memaddr + 1, value & 0xFF);
460
      break;
461
    case 2:
462 251 erez
      cur_area->writefunc(memaddr, value & 0xFFFF);
463 239 markom
      break;
464
    case 4:
465
      printf("EXCEPTION: write 16-bit value to 32-bit region (address 0x%08lX)\n", memaddr);
466
      cont_run = 0;
467
      break;
468
    }
469
  } else {
470
    printf("EXCEPTION: write out of memory (16-bit access to %.8lx)\n", memaddr);
471
    cont_run = 0;
472
  }
473 2 cvs
}
474
 
475 6 lampret
/* Set mem, 8-bit. */
476 2 cvs
 
477 123 markom
void set_mem8(unsigned long memaddr, unsigned char value,int* breakpoint)
478 2 cvs
{
479 239 markom
  memaddr = simulate_dc_mmu_store(memaddr);
480 221 markom
 
481 270 markom
  if (DEBUG_ENABLED) {
482
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
483
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
484
  }
485 123 markom
 
486 239 markom
  setsim_mem8(memaddr, value);
487 66 lampret
}
488
 
489
void setsim_mem8(unsigned long memaddr, unsigned char value)
490
{
491 239 markom
  if (verify_memoryarea(memaddr)) {
492 426 markom
    if (cur_area->log)
493
      fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
494 239 markom
    if (cur_area->granularity == 1)
495
      cur_area->writefunc(memaddr, value);
496
    else {
497
      printf("EXCEPTION: write 8-bit value to %u-bit region (address 0x%08lX)\n", cur_area->granularity * 8, memaddr);
498
      cont_run = 0;
499
    }
500
  } else {
501
    printf("EXCEPTION: write out of memory (8-bit access to %.8lx)\n", memaddr);
502
    cont_run = 0;
503
  }
504 2 cvs
}
505 30 lampret
 
506 361 markom
void dumpmemory(unsigned int from, unsigned int to, int disasm, int nl)
507
{
508
  unsigned int i, j;
509
  struct label_entry *tmp;
510
  int breakpoint = 0;
511
  int ilen = disasm ? 4 : 16;
512
 
513
  for(i = from; i < to; i += ilen) {
514
    printf("%.8x: ", i);
515
    for (j = 0; j < ilen;) {
516
      int data = -1;
517
      if (!disasm) {
518
        tmp = NULL;
519
        if (verify_memoryarea(i+j)) {
520
          struct label_entry *entry;
521
          entry = get_label(i + j);
522
          if (entry)
523
            printf("(%s)", entry->name);
524
          printf("%02x ", data = evalsim_mem8(i+j));
525
        } else printf("XX ");
526
        j++;
527
      } else {
528
        int breakpoint;
529
        unsigned int _insn = read_mem(i, &breakpoint);
530
        int index = insn_decode (_insn);
531
        int len = insn_len (index);
532
 
533
        tmp = NULL;
534
        if (verify_memoryarea(i+j)) {
535
          struct label_entry *entry;
536
          entry = get_label(i + j);
537
          if (entry)
538
            printf("(%s)", entry->name);
539
 
540
          printf(": %08x ", (unsigned long)_insn);
541
          if (index >= 0) {
542
            disassemble_insn (_insn);
543
            printf(" %s", disassembled);
544
          } else
545
            printf("<invalid>");
546
        } else printf("XXXXXXXX");
547
        j += len;
548
      }
549
    }
550
    if (nl)
551
      printf ("\n");
552
  }
553
}
554
 
555
 
556 235 erez
unsigned long simmem_read_byte(unsigned long addr) {
557 297 markom
  return simmem[cur_area->misc + (addr & cur_area->size_mask)].data;
558 221 markom
}
559
 
560 235 erez
void simmem_write_byte(unsigned long addr, unsigned long value) {
561 297 markom
  simmem[cur_area->misc + (addr & cur_area->size_mask)].data = (unsigned char)value;
562 221 markom
}
563
 
564 424 markom
unsigned long simmem_read_zero(unsigned long addr) {
565
  if (config.sim.verbose)
566
    fprintf (stderr, "WARNING: memory read from non-read memory area 0x%08x.\n", addr);
567
  return 0;
568
}
569
 
570
void simmem_write_null(unsigned long addr, unsigned long value) {
571
  if (config.sim.verbose)
572
    fprintf (stderr, "WARNING: memory write to 0x%08x, non-write memory area (value 0x%08x).\n", addr, value);
573
}
574
 
575
/* Initialize memory table from a config struct */
576
 
577
void init_memory_table ()
578 221 markom
{
579 239 markom
  unsigned long memory_needed = 0;
580 426 markom
 
581 424 markom
  /* If nothing was defined, use default memory block */
582
  if (config.memory.nmemories) {
583
    int i;
584
    for (i = 0; i < config.memory.nmemories; i++) {
585
      unsigned long start = config.memory.table[i].baseaddr;
586
      unsigned long length = config.memory.table[i].size;
587
      char *type = config.memory.table[i].name;
588
      int rd = config.memory.table[i].delayr;
589
      int wd = config.memory.table[i].delayw;
590
      int ce = config.memory.table[i].ce;
591
      if (config.sim.verbose)
592
        debug (1, "%08X %08X (%i KB): %s (activated by CE%i; read delay = %icyc, write delay = %icyc)\n",
593
          start, length, length >> 10, type, ce, rd, wd);
594 261 markom
      register_memoryarea(start, length, 1, &simmem_read_byte, &simmem_write_byte);
595 239 markom
      cur_area->misc = memory_needed;
596 424 markom
      cur_area->delayw = wd;
597
      cur_area->delayr = rd;
598 426 markom
      if (config.memory.table[i].log[0] != '\0') {
599
        if ((cur_area->log = fopen (config.memory.table[i].log, "wt+")) == NULL)
600
          fprintf (stderr, "WARNING: Cannot open '%s'.\n", config.memory.table[i].log);
601
      } else
602
        cur_area->log = 0;
603 261 markom
      memory_needed += cur_area->size;
604 239 markom
    }
605
    printf ("\n");
606
  } else {
607 308 markom
    if (config.sim.verbose)
608 424 markom
      fprintf (stderr, "WARNING: Memory not defined, assuming standard configuration.\n");
609 261 markom
    register_memoryarea(DEFAULT_MEMORY_START, DEFAULT_MEMORY_LEN, 1, &simmem_read_byte, &simmem_write_byte);
610
    memory_needed += cur_area->size;
611 239 markom
  }
612 424 markom
 
613 239 markom
  simmem = (struct mem_entry *) malloc (sizeof (struct mem_entry) * memory_needed);
614
  if (!simmem) {
615
    fprintf (stderr, "Failed to allocate sim memory. Aborting\n");
616
    exit (-1);
617
  }
618 221 markom
}
619 424 markom
 
620
/* Changes read/write memory in read/write only */
621
 
622
void lock_memory_table ()
623
{
624
  struct dev_memarea *ptmp;
625
 
626
  /* Check list of registered devices. */
627
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
628
    if (ptmp->delayr < 0 && ptmp->readfunc == &simmem_read_byte)
629
      ptmp->readfunc = &simmem_read_zero;
630
    if (ptmp->delayw < 0 && ptmp->writefunc == &simmem_write_byte)
631
      ptmp->writefunc = &simmem_write_null;
632
  }
633
}
634 426 markom
 
635
/* Closes files, etc. */
636
 
637
void done_memory_table ()
638
{
639
  struct dev_memarea *ptmp;
640
 
641
  /* Check list of registered devices. */
642
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
643
    if (ptmp->log)
644
      fclose (ptmp->log);
645
  }
646
}
647 427 markom
 
648
/* Displays current memory configuration */
649
 
650
void memory_table_status ()
651
{
652
  struct dev_memarea *ptmp;
653
 
654
  /* Check list of registered devices. */
655
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
656
    printf ("addr & %08x == %08x to %08x, size %08x, gran %iB\n",
657
      ptmp->addr_mask, ptmp->addr_compare, ptmp->addr_compare | bit_mask (ptmp->size),
658
      ptmp->size, ptmp->granularity);
659
    printf ("\t");
660
    if (ptmp->delayr >= 0)
661
      printf ("read delay = %i cycles, ", ptmp->delayr);
662
    else
663
      printf ("reads not possible, ");
664
 
665
    if (ptmp->delayw >= 0)
666
      printf ("write delay = %i cycles", ptmp->delayw);
667
    else
668
      printf ("writes not possible");
669
 
670
    if (ptmp->log)
671
      printf (", (logged)\n");
672
    else
673
      printf ("\n");
674
  }
675
}

powered by: WebSVN 2.1.0

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