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

Subversion Repositories or1k

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

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 1350 nogj
 
31
#ifdef HAVE_INTTYPES_H
32
#include <inttypes.h>
33
#endif
34
 
35
#include "port.h"
36 7 jrydberg
#include "sim-config.h"
37 6 lampret
 
38 1350 nogj
#include "arch.h"
39 2 cvs
#include "parse.h"
40
#include "abstract.h"
41 261 markom
#include "labels.h"
42 2 cvs
#include "execute.h"
43 32 lampret
#include "sprs.h"
44
#include "except.h"
45 123 markom
#include "debug_unit.h"
46 134 markom
#include "opcode/or32.h"
47 547 markom
#include "support/profile.h"
48 1308 phoenix
#include "dmmu.h"
49
#include "dcache_model.h"
50
#include "icache_model.h"
51
#include "debug.h"
52 1344 nogj
#include "stats.h"
53 2 cvs
 
54 1354 phoenix
extern uorreg_t reg[];
55 138 markom
extern char *disassembled;
56 2 cvs
 
57 28 lampret
/* This is an abstract+physical memory array rather than only physical
58
   memory array */
59 1350 nogj
static uint32_t *simmem32;
60 2 cvs
 
61 30 lampret
/* Pointer to memory area descriptions that are assigned to individual
62
   peripheral devices. */
63
struct dev_memarea *dev_list;
64
 
65 221 markom
/* Temporary variable to increase speed.  */
66
struct dev_memarea *cur_area;
67
 
68 970 simons
/* Pointer to memory controller device descriptor.  */
69
struct dev_memarea *mc_area = (struct dev_memarea *)0;
70
 
71 638 simons
/* These are set by mmu if cache inhibit bit is set for current acces.  */
72
int data_ci, insn_ci;
73
 
74 525 simons
/* Virtual address of current access. */
75 1350 nogj
oraddr_t cur_vadd;
76 525 simons
 
77 261 markom
/* Calculates bit mask to fit the data */
78 1350 nogj
unsigned int bit_mask (uint32_t data) {
79 261 markom
  int i = 0;
80
  data--;
81 382 markom
  while (data >> i)
82 261 markom
    data |= 1 << i++;
83
  return data;
84
}
85
 
86
/* Register read and write function for a memory area.
87
   addr is inside the area, if addr & addr_mask == addr_compare
88
   (used also by peripheral devices like 16450 UART etc.) */
89 1350 nogj
void register_memoryarea_mask(oraddr_t addr_mask, oraddr_t addr_compare,
90
                         uint32_t size, unsigned granularity, unsigned mc_dev,
91
                         uint32_t (readfunc)(oraddr_t),
92
                         void (writefunc)(oraddr_t, uint32_t))
93 30 lampret
{
94 239 markom
  struct dev_memarea **pptmp;
95 1350 nogj
  unsigned int size_mask = bit_mask (size);
96 261 markom
  int found_error = 0;
97
  addr_compare &= addr_mask;
98 221 markom
 
99 1350 nogj
  debug(5, "addr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR", size %08"PRIx32", gran %iB\n",
100
        addr_mask, addr_compare, addr_compare | bit_mask (size), size,
101
        granularity);
102 239 markom
  /* Go to the end of the list. */
103 261 markom
  for(pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next)
104
    if ((addr_compare >= (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)
105
     || (addr_compare + size > (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)) {
106 262 markom
      if (!found_error) {
107 261 markom
        fprintf (stderr, "ERROR: Overlapping memory area(s):\n");
108 1350 nogj
        fprintf (stderr, "\taddr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR
109
                         ", size %08"PRIx32", gran %iB\n",
110 1308 phoenix
                 addr_mask, addr_compare, addr_compare | bit_mask (size), size,
111
                 granularity);
112 262 markom
      }
113 261 markom
      found_error = 1;
114 1350 nogj
      fprintf (stderr, "and\taddr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR
115
                       ", size %08"PRIx32", gran %iB\n",
116 1308 phoenix
               (*pptmp)->addr_mask, (*pptmp)->addr_compare,
117
               (*pptmp)->addr_compare | (*pptmp)->size_mask,
118
               (*pptmp)->size, (*pptmp)->granularity);
119 261 markom
    }
120
 
121
  if (found_error)
122
    exit (-1);
123 537 markom
 
124 239 markom
  cur_area = *pptmp = (struct dev_memarea *)malloc(sizeof(struct dev_memarea));
125 970 simons
 
126
  if (mc_dev)
127
    mc_area = *pptmp;
128
 
129 261 markom
  (*pptmp)->addr_mask = addr_mask;
130
  (*pptmp)->addr_compare = addr_compare;
131 239 markom
  (*pptmp)->size = size;
132 261 markom
  (*pptmp)->size_mask = size_mask;
133 239 markom
  (*pptmp)->granularity = granularity;
134
  (*pptmp)->readfunc = readfunc;
135
  (*pptmp)->writefunc = writefunc;
136 479 markom
  (*pptmp)->log = 0;
137 882 simons
  (*pptmp)->delayr = 2;
138
  (*pptmp)->delayw = 2;
139 239 markom
  (*pptmp)->next = NULL;
140 261 markom
}
141 221 markom
 
142 261 markom
/* Register read and write function for a memory area.
143
   Memory areas should be aligned. Memory area is rounded up to
144
   fit the nearest 2^n aligment.
145 970 simons
   (used also by peripheral devices like 16450 UART etc.)
146
   If mc_dev is 1, this means that this device will be checked first for match
147
   and will be accessed in case in overlaping memory spaces.
148
   Only one device can have this set to 1 (used for memory controller) */
149 1350 nogj
void register_memoryarea(oraddr_t addr, uint32_t size, unsigned granularity,
150
                         unsigned mc_dev,
151
                         uint32_t (readfunc)(oraddr_t),
152
                         void (writefunc)(oraddr_t, uint32_t))
153 261 markom
{
154 1350 nogj
  unsigned int size_mask = bit_mask (size);
155
  unsigned int addr_mask = ~size_mask;
156 261 markom
  register_memoryarea_mask (addr_mask, addr & addr_mask,
157 970 simons
                      size_mask + 1, granularity, mc_dev,
158 261 markom
                      readfunc, writefunc);
159 30 lampret
}
160
 
161 261 markom
 
162 30 lampret
/* Check if access is to registered area of memory. */
163 1350 nogj
inline struct dev_memarea *verify_memoryarea(oraddr_t addr)
164 30 lampret
{
165 239 markom
  struct dev_memarea *ptmp;
166 221 markom
 
167 970 simons
  /* Check memory controller space first */
168
  if (mc_area && (addr & mc_area->addr_mask) == (mc_area->addr_compare & mc_area->addr_mask))
169
    return cur_area = mc_area;
170
 
171
  /* Check cached value */
172 560 markom
  if (cur_area && (addr & cur_area->addr_mask) == (cur_area->addr_compare & cur_area->addr_mask))
173
    return cur_area;
174
 
175
  /* When mc is enabled, we must check valid also, otherwise we assume it is nonzero */
176
  IFF (config.mc.enabled) {
177
    /* Check list of registered devices. */
178
    for(ptmp = dev_list; ptmp; ptmp = ptmp->next)
179
      if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask) && ptmp->valid)
180
        return cur_area = ptmp;
181
  } else {
182
    /* Check list of registered devices. */
183
    for(ptmp = dev_list; ptmp; ptmp = ptmp->next)
184
      if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask))
185
        return cur_area = ptmp;
186
  }
187 239 markom
  return cur_area = NULL;
188 30 lampret
}
189
 
190 882 simons
/* Finds the memory area for the address and adjust the read and write delays for it. */
191 1350 nogj
void adjust_rw_delay(oraddr_t memaddr, unsigned int delayr, unsigned int delayw)
192 882 simons
{
193
  if (verify_memoryarea(memaddr)) {
194
    cur_area->delayr = delayr;
195
    cur_area->delayw = delayw;
196
  }
197
}
198
 
199 1319 phoenix
/* for cpu accesses
200
 *
201
 * STATISTICS: check cpu/common/parse.c
202
 */
203 1350 nogj
inline uint32_t evalsim_mem32(oraddr_t memaddr)
204 560 markom
{
205 1319 phoenix
        return(evalsim_mem32_atomic(memaddr, 1));
206
}
207 560 markom
 
208 1319 phoenix
/* for simulator accesses, the ones that cpu wouldn't do */
209 1350 nogj
inline uint32_t evalsim_mem32_void(oraddr_t memaddr)
210 1319 phoenix
{
211
        return(evalsim_mem32_atomic(memaddr, 0));
212
}
213
 
214 1350 nogj
uint32_t evalsim_mem32_atomic(oraddr_t memaddr, int cpu_access)
215 1319 phoenix
{
216 1350 nogj
  uint32_t temp = 0;
217 1319 phoenix
 
218 560 markom
  if (verify_memoryarea(memaddr)) {
219
    switch(cur_area->granularity) {
220
    case 4:
221
      temp = cur_area->readfunc(memaddr);
222
      break;
223
    case 1:
224
      temp = cur_area->readfunc(memaddr) << 24;
225
      temp |= cur_area->readfunc(memaddr + 1) << 16;
226
      temp |= cur_area->readfunc(memaddr + 2) << 8;
227
      temp |= cur_area->readfunc(memaddr + 3);
228
      break;
229
    case 2:
230
      temp = cur_area->readfunc(memaddr) << 16;
231
      temp |= cur_area->readfunc(memaddr + 2);
232
      break;
233 1319 phoenix
    default:
234
      /* if you add new memory granularity be sure to check the formula
235
       * below for the read delay and fix it if necessery
236
       */
237
      PRINTF("unknown/unhandled memory granularuty\n");
238
      exit(-1);
239 560 markom
    }
240 1319 phoenix
    if (cpu_access)
241
      runtime.sim.mem_cycles += cur_area->delayr * (4 / cur_area->granularity);
242 560 markom
  }
243
  return temp;
244
}
245
 
246 1319 phoenix
/* for cpu accesses */
247 1350 nogj
inline uint16_t evalsim_mem16(oraddr_t memaddr)
248 560 markom
{
249 1319 phoenix
        return(evalsim_mem16_atomic(memaddr, 1));
250
}
251 560 markom
 
252 1319 phoenix
/* for simulator accesses, the ones that cpu wouldn't do */
253 1350 nogj
inline uint16_t evalsim_mem16_void(oraddr_t memaddr)
254 1319 phoenix
{
255
        return(evalsim_mem16_atomic(memaddr, 0));
256
}
257
 
258 1350 nogj
uint16_t evalsim_mem16_atomic(oraddr_t memaddr, int cpu_access)
259 1319 phoenix
{
260 1350 nogj
  uint32_t temp = 0;
261 1319 phoenix
 
262 560 markom
  if (verify_memoryarea(memaddr)) {
263
    switch(cur_area->granularity) {
264
    case 1:
265
      temp = cur_area->readfunc(memaddr) << 8;
266
      temp |= cur_area->readfunc(memaddr + 1);
267 1319 phoenix
      if (cpu_access)
268
        runtime.sim.mem_cycles += cur_area->delayr * 2;
269 560 markom
      break;
270
    case 2:
271
      temp = cur_area->readfunc(memaddr);
272 1319 phoenix
      if (cpu_access)
273
        runtime.sim.mem_cycles += cur_area->delayr;
274 560 markom
      break;
275
    case 4:
276 1350 nogj
      temp = evalsim_mem32_atomic (memaddr & ~UINT32_C(3), cpu_access);
277 560 markom
      if (memaddr & 2)
278
        temp &= 0xffff;
279
      else
280
        temp >>= 16;
281
      break;
282 1319 phoenix
    default:
283
      /* if you add new memory granularity be sure to check the formula
284
       * below for the read delay and fix it if necessery
285
       */
286
      PRINTF("unknown/unhandled memory granularuty\n");
287
      exit(-1);
288 560 markom
    }
289
  }
290
  return temp;
291
}
292
 
293 1319 phoenix
/* for cpu accesses */
294 1350 nogj
inline uint8_t evalsim_mem8(oraddr_t memaddr)
295 560 markom
{
296 1319 phoenix
        return(evalsim_mem8_atomic(memaddr, 1));
297
}
298 560 markom
 
299 1319 phoenix
/* for simulator accesses, the ones that cpu wouldn't do */
300 1350 nogj
inline uint8_t evalsim_mem8_void(oraddr_t memaddr)
301 1319 phoenix
{
302
        return(evalsim_mem8_atomic(memaddr, 0));
303
}
304
 
305 1350 nogj
uint8_t evalsim_mem8_atomic(oraddr_t memaddr, int cpu_access)
306 1319 phoenix
{
307 1350 nogj
  uint32_t temp = 0;
308 1319 phoenix
 
309 560 markom
  if (verify_memoryarea(memaddr)) {
310
    switch(cur_area->granularity) {
311
    case 1:
312
      temp = cur_area->readfunc(memaddr);
313 1319 phoenix
      if (cpu_access)
314
        runtime.sim.mem_cycles += cur_area->delayr;
315 560 markom
      break;
316
    case 2:
317 1350 nogj
      temp = evalsim_mem16_atomic (memaddr & ~ADDR_C(1), cpu_access);
318 560 markom
      if (memaddr & 1)
319
        temp &= 0xff;
320
      else
321
        temp >>= 8;
322
      break;
323
    case 4:
324 1350 nogj
      temp = evalsim_mem32_atomic (memaddr & ~ADDR_C(3), cpu_access);
325 560 markom
      temp >>= 8 * (3 - (memaddr & 3));
326
      temp &= 0xff;
327
      break;
328 1319 phoenix
    default:
329
      /* if you add new memory granularity be sure to check the formula
330
       * below for the read delay and fix it if necessery
331
       */
332
      PRINTF("unknown/unhandled memory granularuty\n");
333
      exit(-1);
334 560 markom
    }
335
  }
336
  return temp;
337
}
338
 
339 1319 phoenix
/* Returns 32-bit values from mem array. Big endian version.
340
 *
341 1350 nogj
 * this function is only used in dumpmemory() below, so it's
342 1319 phoenix
 * safe to asume it's for simulator purposes access only,
343
 * hence the use of eval_mem32_void()
344
 *
345
 * STATISTICS OK.
346
 */
347 1350 nogj
static uint32_t read_mem(oraddr_t memaddr, int* breakpoint)
348 349 simons
{
349 1350 nogj
  uint32_t temp;
350 349 simons
 
351 525 simons
  cur_vadd = memaddr;
352 550 markom
  if (config.debug.enabled)
353 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
354 1319 phoenix
  temp = evalsim_mem32_void(memaddr);
355 611 simons
  if (!cur_area) {
356 1350 nogj
    PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR")\n",
357
           memaddr);
358 611 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
359
    temp = 0;
360
  }
361
 
362 599 simons
  if (!pending.valid && cur_area->log)
363 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> read %08"PRIx32"\n", memaddr, temp);
364 550 markom
  if (config.debug.enabled)
365 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
366
  return temp;
367 537 markom
}
368 349 simons
 
369 1319 phoenix
/* Returns 32-bit values from mem array. Big endian version.
370
 *
371
 * STATISTICS OK (only used for cpu_access, that is architectural access)
372
 */
373 1350 nogj
uint32_t eval_mem32(oraddr_t memaddr,int* breakpoint)
374 2 cvs
{
375 1350 nogj
  uint32_t temp;
376 123 markom
 
377 547 markom
  if (config.sim.mprofile)
378
    mprofile (memaddr, MPROF_32 | MPROF_READ);
379
 
380 538 markom
  if (memaddr & 3) {
381
    except_handle (EXCEPT_ALIGN, memaddr);
382
    return 0;
383
  }
384 557 markom
 
385 631 simons
  if (config.debug.enabled)
386
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
387
 
388 574 markom
  cur_vadd = memaddr;
389 631 simons
 
390
  memaddr = dmmu_translate(memaddr, 0);
391 574 markom
  if (pending.valid)
392
    return 0;
393
 
394 992 simons
  if (config.dc.enabled)
395
    temp = dc_simulate_read(memaddr, 4);
396
  else {
397
    temp = evalsim_mem32(memaddr);
398
    if (!cur_area) {
399 1350 nogj
      PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR")\n",
400
             memaddr);
401 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
402
      temp = 0;
403
    }
404 611 simons
  }
405
 
406 550 markom
  if (config.debug.enabled)
407 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
408 239 markom
  return temp;
409 66 lampret
}
410
 
411 1319 phoenix
/* for simulator accesses, the ones that cpu wouldn't do
412
 *
413
 * STATISTICS OK
414
 */
415 1350 nogj
uint32_t eval_direct32(oraddr_t memaddr, int *breakpoint, int through_mmu,
416
                       int through_dc)
417 1240 phoenix
{
418 1350 nogj
  uint32_t temp;
419 1240 phoenix
 
420
  if (memaddr & 3) {
421
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
422
      return 0;
423
  }
424
 
425
  cur_vadd = memaddr;
426
 
427
  if (through_mmu)
428
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
429
 
430
  if (through_dc)
431
    temp = dc_simulate_read(memaddr, 4);
432
  else {
433 1319 phoenix
    temp = evalsim_mem32_void(memaddr);
434 1240 phoenix
    if (!cur_area) {
435 1350 nogj
      PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR
436
             ") in eval_direct32()\n", memaddr);
437 1240 phoenix
      except_handle(EXCEPT_BUSERR, cur_vadd);
438
      temp = 0;
439
    }
440
  }
441
 
442
  return temp;
443
}
444
 
445
 
446 1319 phoenix
/* Returns 32-bit values from mem array. Big endian version.
447
 *
448
 * STATISTICS OK (only used for cpu_access, that is architectural access)
449
 */
450 1350 nogj
uint32_t eval_insn(oraddr_t memaddr,int* breakpoint)
451 349 simons
{
452 1350 nogj
  uint32_t temp;
453 349 simons
 
454 547 markom
  if (config.sim.mprofile)
455
    mprofile (memaddr, MPROF_32 | MPROF_FETCH);
456 532 markom
//  memaddr = simulate_ic_mmu_fetch(memaddr);
457 525 simons
  cur_vadd = pc;
458 1244 hpanther
 
459
  // I think this does not belong into eval_insn() 2004-01-30 HP
460
//  if (config.debug.enabled)
461
//    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
462
 
463
  // We could place the CheckDebugUnit(DebugInstructionFetch) here, but it is currently done
464
  // in decode_execute_wrapper, so I leave it like this. 2004-01-30 HP
465
 
466 631 simons
  if (config.ic.enabled)
467
    temp = ic_simulate_fetch(memaddr);
468 992 simons
  else {
469 631 simons
    temp = evalsim_mem32(memaddr);
470 992 simons
    if (!cur_area) {
471 1350 nogj
      PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR")\n",
472
             memaddr);
473 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
474
      temp = 0;
475
    }
476 611 simons
  }
477
 
478 1244 hpanther
  // I think this does not belong into eval_insn() 2004-01-30 HP
479
//  if (config.debug.enabled)
480
//    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
481 349 simons
  return temp;
482
}
483
 
484 1319 phoenix
/* Returns 16-bit values from mem array. Big endian version.
485
 *
486
 * STATISTICS OK (only used for cpu_access, that is architectural access)
487
 */
488 1350 nogj
uint16_t eval_mem16(oraddr_t memaddr,int* breakpoint)
489 2 cvs
{
490 1350 nogj
  uint16_t temp;
491 547 markom
 
492
  if (config.sim.mprofile)
493
    mprofile (memaddr, MPROF_16 | MPROF_READ);
494
 
495 538 markom
  if (memaddr & 1) {
496
    except_handle (EXCEPT_ALIGN, memaddr);
497
    return 0;
498
  }
499 574 markom
 
500 631 simons
  if (config.debug.enabled)
501
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
502
 
503 574 markom
  cur_vadd = memaddr;
504 631 simons
 
505
  memaddr = dmmu_translate(memaddr, 0);
506 574 markom
  if (pending.valid)
507
    return 0;
508 66 lampret
 
509 992 simons
  if (config.dc.enabled)
510
    temp = (unsigned short)dc_simulate_read(memaddr, 2);
511
  else {
512
    temp = evalsim_mem16(memaddr);
513
    if (!cur_area) {
514 1350 nogj
      PRINTF("EXCEPTION: read out of memory (16-bit access to %"PRIxADDR")\n",
515
             memaddr);
516 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
517
      temp = 0;
518
    }
519 611 simons
  }
520
 
521 550 markom
  if (config.debug.enabled)
522 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
523 239 markom
  return temp;
524 66 lampret
}
525
 
526 1319 phoenix
/* for simulator accesses, the ones that cpu wouldn't do
527
 *
528
 * STATISTICS OK.
529
 */
530 1350 nogj
uint16_t eval_direct16(oraddr_t memaddr, int *breakpoint, int through_mmu,
531
                       int through_dc)
532 1240 phoenix
{
533 1350 nogj
  uint32_t temp;
534 1240 phoenix
 
535 1324 phoenix
  if (memaddr & 1) {
536 1240 phoenix
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
537
      return 0;
538
  }
539
 
540
  cur_vadd = memaddr;
541
 
542
  if (through_mmu)
543
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
544
 
545
  if (through_dc)
546
    temp = dc_simulate_read(memaddr, 2);
547
  else {
548 1319 phoenix
    temp = evalsim_mem16_void(memaddr);
549 1240 phoenix
    if (!cur_area) {
550 1350 nogj
      PRINTF("EXCEPTION: read out of memory (16-bit access to %"PRIxADDR
551
             ") in eval_direct16()\n", memaddr);
552 1240 phoenix
      except_handle(EXCEPT_BUSERR, cur_vadd);
553
      temp = 0;
554
    }
555
  }
556
 
557
  return temp;
558
}
559
 
560
 
561 1319 phoenix
/* Returns 8-bit values from mem array.
562
 *
563
 * STATISTICS OK (only used for cpu_access, that is architectural access)
564
 */
565 1350 nogj
uint8_t eval_mem8(oraddr_t memaddr,int* breakpoint)
566 221 markom
{
567 1350 nogj
  uint8_t temp;
568 547 markom
 
569
  if (config.sim.mprofile)
570
    mprofile (memaddr, MPROF_8 | MPROF_READ);
571
 
572 631 simons
  if (config.debug.enabled)
573
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr);  /* 28/05/01 CZ */
574
 
575 525 simons
  cur_vadd = memaddr;
576 631 simons
 
577
  memaddr = dmmu_translate(memaddr, 0);
578 458 simons
  if (pending.valid)
579
    return 0;
580 6 lampret
 
581 992 simons
  if (config.dc.enabled)
582
    temp = (unsigned char)dc_simulate_read(memaddr, 1);
583
  else {
584
    temp = evalsim_mem8(memaddr);
585
    if (!cur_area) {
586 1350 nogj
      PRINTF("EXCEPTION: read out of memory (8-bit access to %"PRIxADDR")\n",
587
             memaddr);
588 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
589
      temp = 0;
590
    }
591 611 simons
  }
592
 
593 550 markom
  if (config.debug.enabled)
594 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
595 239 markom
  return temp;
596 66 lampret
}
597
 
598 1319 phoenix
/* for simulator accesses, the ones that cpu wouldn't do
599
 *
600
 * STATISTICS OK.
601
 */
602 1350 nogj
uint8_t eval_direct8(oraddr_t memaddr, int *breakpoint, int through_mmu,
603
                     int through_dc)
604 1240 phoenix
{
605 1350 nogj
  uint8_t temp;
606 1240 phoenix
 
607
  cur_vadd = memaddr;
608
 
609
  if (through_mmu)
610
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
611
 
612
  if (through_dc)
613
    temp = (unsigned char)dc_simulate_read(memaddr, 1);
614
  else {
615 1319 phoenix
    temp = evalsim_mem8_void(memaddr);
616 1240 phoenix
    if (!cur_area) {
617 1350 nogj
      PRINTF("EXCEPTION: read out of memory (8-bit access to %"PRIxADDR
618
             ") in eval_direct8()\n", memaddr);
619 1240 phoenix
      except_handle(EXCEPT_BUSERR, cur_vadd);
620
      temp = 0;
621
    }
622
  }
623 1308 phoenix
  return temp;
624 1240 phoenix
}
625
 
626 1319 phoenix
/* for cpu accesses */
627 1350 nogj
inline void setsim_mem32(oraddr_t memaddr, uint32_t value)
628 1319 phoenix
{
629
  return(setsim_mem32_atomic(memaddr, value, 1));
630
}
631 1240 phoenix
 
632 1319 phoenix
/* for simulator accesses, the ones that cpu wouldn't do */
633 1350 nogj
inline void setsim_mem32_void(oraddr_t memaddr, uint32_t value)
634 66 lampret
{
635 1319 phoenix
  return(setsim_mem32_atomic(memaddr, value, 0));
636
}
637
 
638 1350 nogj
void setsim_mem32_atomic(oraddr_t memaddr, uint32_t value, int cpu_access)
639 1319 phoenix
{
640 239 markom
  if (verify_memoryarea(memaddr)) {
641
    switch(cur_area->granularity) {
642 538 markom
    case 4:
643
      cur_area->writefunc(memaddr, value);
644 1319 phoenix
      if (cpu_access)
645
        runtime.sim.mem_cycles += cur_area->delayw;
646 538 markom
      break;
647 239 markom
    case 1:
648 251 erez
      cur_area->writefunc(memaddr    , (value >> 24) & 0xFF);
649 239 markom
      cur_area->writefunc(memaddr + 1, (value >> 16) & 0xFF);
650 251 erez
      cur_area->writefunc(memaddr + 2, (value >>  8) & 0xFF);
651
      cur_area->writefunc(memaddr + 3, (value      ) & 0xFF);
652 1319 phoenix
      if (cpu_access)
653
        runtime.sim.mem_cycles += cur_area->delayw * 4;
654 239 markom
      break;
655
    case 2:
656
      cur_area->writefunc(memaddr, (value >> 16) & 0xFFFF);
657
      cur_area->writefunc(memaddr + 2, value & 0xFFFF);
658 1319 phoenix
      if (cpu_access)
659
        runtime.sim.mem_cycles += cur_area->delayw * 2;
660 239 markom
      break;
661 1319 phoenix
    default:
662
      /* if you add new memory granularity be sure to check the formula
663
       * below for the read delay and fix it if necessery
664
       */
665
      PRINTF("unknown/unhandled memory granularuty\n");
666
      exit(-1);
667 242 markom
    }
668 239 markom
  } else {
669 1350 nogj
    PRINTF("EXCEPTION: write out of memory (32-bit access to %"PRIxADDR")\n",
670
           memaddr);
671 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
672 239 markom
  }
673 2 cvs
}
674
 
675 1319 phoenix
/* for cpu accesses */
676 1350 nogj
inline void setsim_mem16(oraddr_t memaddr, uint16_t value)
677 66 lampret
{
678 1319 phoenix
  return(setsim_mem16_atomic(memaddr, value, 1));
679
}
680
 
681
/* for simulator accesses, the ones that cpu wouldn't do */
682 1350 nogj
inline void setsim_mem16_void(oraddr_t memaddr, uint16_t value)
683 1319 phoenix
{
684
  return(setsim_mem16_atomic(memaddr, value, 0));
685
}
686
 
687 1350 nogj
void setsim_mem16_atomic(oraddr_t memaddr, uint16_t value, int cpu_access)
688 1319 phoenix
{
689 1350 nogj
  uint32_t temp;
690 239 markom
  if (verify_memoryarea(memaddr)) {
691
    switch(cur_area->granularity) {
692
    case 1:
693
      cur_area->writefunc(memaddr, (value >> 8) & 0xFF);
694
      cur_area->writefunc(memaddr + 1, value & 0xFF);
695 1319 phoenix
      if (cpu_access)
696
        runtime.sim.mem_cycles += cur_area->delayw * 2;
697 239 markom
      break;
698
    case 2:
699 251 erez
      cur_area->writefunc(memaddr, value & 0xFFFF);
700 1319 phoenix
      if (cpu_access)
701
        runtime.sim.mem_cycles += cur_area->delayw;
702 239 markom
      break;
703
    case 4:
704 1350 nogj
      temp = evalsim_mem32_void(memaddr & ~ADDR_C(3));
705 546 simons
      temp &= 0xffff << ((memaddr & 2) ? 16 : 0);
706
      temp |= (unsigned long)(value & 0xffff) << ((memaddr & 2) ? 0 : 16);
707 1350 nogj
      setsim_mem32_atomic(memaddr & ~ADDR_C(3), temp, cpu_access);
708 239 markom
      break;
709 1319 phoenix
    default:
710
      /* if you add new memory granularity be sure to check the formula
711
       * below for the read delay and fix it if necessery
712
       */
713
      PRINTF("unknown/unhandled memory granularuty\n");
714
      exit(-1);
715 239 markom
    }
716
  } else {
717 1350 nogj
    PRINTF("EXCEPTION: write out of memory (16-bit access to %"PRIxADDR")\n",
718
           memaddr);
719 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
720 239 markom
  }
721 2 cvs
}
722
 
723 1319 phoenix
/* for cpu accesses */
724 1350 nogj
inline void setsim_mem8(oraddr_t memaddr, uint8_t value)
725 66 lampret
{
726 1319 phoenix
  return(setsim_mem8_atomic(memaddr, value, 1));
727
}
728
 
729
/* for simulator accesses, the ones that cpu wouldn't do */
730 1350 nogj
inline void setsim_mem8_void(oraddr_t memaddr, uint8_t value)
731 1319 phoenix
{
732
  return(setsim_mem8_atomic(memaddr, value, 0));
733
}
734
 
735 1350 nogj
void setsim_mem8_atomic(oraddr_t memaddr, uint8_t value, int cpu_access)
736 1319 phoenix
{
737 1350 nogj
  uint32_t temp;
738 239 markom
  if (verify_memoryarea(memaddr)) {
739 538 markom
    switch (cur_area->granularity) {
740
    case 1:
741 239 markom
      cur_area->writefunc(memaddr, value);
742 1319 phoenix
      if (cpu_access)
743
        runtime.sim.mem_cycles += cur_area->delayw;
744 538 markom
      break;
745
    case 2:
746 1350 nogj
      temp = evalsim_mem16_void (memaddr & ~ADDR_C(1));
747 546 simons
      temp &= 0xff << ((memaddr & 1) ? 8 : 0);
748
      temp |= (unsigned short)(value & 0xff) << ((memaddr & 1) ? 0 : 8);
749 1350 nogj
      setsim_mem16_atomic (memaddr & ~ADDR_C(1), temp, cpu_access);
750 538 markom
      break;
751
    case 4:
752 1350 nogj
      temp = evalsim_mem32_void (memaddr & ~ADDR_C(3));
753 538 markom
      temp &= ~(0xff << (8 * (3 - (memaddr & 3))));
754
      temp |= (unsigned long)(value & 0xff) << (8 * (3 - (memaddr & 3)));
755 1350 nogj
      setsim_mem32_atomic (memaddr & ~ADDR_C(3), temp, cpu_access);
756 538 markom
      break;
757 239 markom
    }
758
  } else {
759 1350 nogj
    PRINTF("EXCEPTION: write out of memory (8-bit access to %"PRIxADDR")\n",
760
           memaddr);
761 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
762 239 markom
  }
763 2 cvs
}
764 30 lampret
 
765 1319 phoenix
/* Set mem, 32-bit. Big endian version.
766
 *
767
 * STATISTICS OK. (the only suspicious usage is in toplevel.c,
768
 *                 where this instruction is used for patching memory,
769
 *                 wether this is cpu or architectual access is yet to
770
 *                 be decided)
771
 */
772 1350 nogj
void set_mem32(oraddr_t memaddr, uint32_t value, int* breakpoint)
773 587 markom
{
774
  if (config.sim.mprofile)
775
    mprofile (memaddr, MPROF_32 | MPROF_WRITE);
776
 
777
  if (memaddr & 3) {
778
    except_handle (EXCEPT_ALIGN, memaddr);
779
    return;
780
  }
781
 
782
  cur_vadd = memaddr;
783 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
784 587 markom
  /* If we produced exception don't set anything */
785
  if (pending.valid)
786
    return;
787
 
788
  if (config.debug.enabled) {
789
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
790
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
791
  }
792
 
793 992 simons
  dc_simulate_write(memaddr, value, 4);
794
 
795 1218 phoenix
  if (cur_area && cur_area->log)
796 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> write %08"PRIx32"\n", memaddr,
797
             value);
798 587 markom
}
799
 
800 1319 phoenix
/*
801
 * STATISTICS NOT OK.
802
 */
803 1350 nogj
void set_direct32(oraddr_t memaddr, uint32_t value,int* breakpoint,
804 1240 phoenix
                  int through_mmu, int through_dc)
805
{
806
 
807
  if (memaddr & 3) {
808
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
809
    return;
810
  }
811
 
812
  cur_vadd = memaddr;
813
 
814
  if (through_mmu) {
815
    /* 0 - no write access, we do not want a DPF exception do we ;)
816
     */
817
    memaddr = peek_into_dtlb(memaddr, 1, through_dc);
818
  }
819
 
820
 
821 1319 phoenix
  /* __PHX__ fixme: we'll get cache hit/miss delay added to cycles count,
822
   *                and possibly also memory access times.
823 1240 phoenix
   */
824 1319 phoenix
  if (!through_dc)
825
    PRINTF("WARNING: statistics might not be OK\n");
826 1240 phoenix
  dc_simulate_write(memaddr, value, 4);
827
 
828
  if (cur_area && cur_area->log)
829 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %08"PRIx32"\n",
830
             memaddr, value);
831 1240 phoenix
}
832
 
833
 
834 587 markom
/* Set mem, 16-bit. Big endian version. */
835
 
836 1350 nogj
void set_mem16(oraddr_t memaddr, uint16_t value, int* breakpoint)
837 587 markom
{
838
  if (config.sim.mprofile)
839
    mprofile (memaddr, MPROF_16 | MPROF_WRITE);
840
 
841
  if (memaddr & 1) {
842
    except_handle (EXCEPT_ALIGN, memaddr);
843
    return;
844
  }
845
 
846
  cur_vadd = memaddr;
847 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
848 587 markom
  /* If we produced exception don't set anything */
849
  if (pending.valid)
850
    return;
851
 
852
  if (config.debug.enabled) {
853
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
854
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
855
  }
856
 
857 992 simons
  dc_simulate_write(memaddr, (unsigned long)value, 2);
858
 
859 1218 phoenix
  if (cur_area && cur_area->log)
860 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> write %04"PRIx16"\n", memaddr,
861
             value);
862 587 markom
}
863
 
864 1319 phoenix
/*
865
 * STATISTICS NOT OK.
866
 */
867 1350 nogj
void set_direct16(oraddr_t memaddr, uint16_t value, int* breakpoint,
868 1240 phoenix
                  int through_mmu, int through_dc)
869
{
870
 
871 1324 phoenix
  if (memaddr & 1) {
872 1240 phoenix
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
873
    return;
874
  }
875
 
876
  cur_vadd = memaddr;
877
 
878
  if (through_mmu) {
879
    /* 0 - no write access, we do not want a DPF exception do we ;)
880
     */
881
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
882
  }
883
 
884 1319 phoenix
  /* __PHX__ fixme: we'll get cache hit/miss delay added to cycles count,
885
   *                and possibly also memory access times.
886 1240 phoenix
   */
887 1319 phoenix
  if (!through_dc)
888
    PRINTF("WARNING: statistics might not be OK\n");
889 1240 phoenix
  dc_simulate_write(memaddr, value, 2);
890
 
891
  if (cur_area && cur_area->log)
892 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %04"PRIx16"\n",
893
             memaddr, value);
894 1240 phoenix
}
895
 
896 587 markom
/* Set mem, 8-bit. */
897
 
898 1350 nogj
void set_mem8(oraddr_t memaddr, uint8_t value, int* breakpoint)
899 587 markom
{
900
  if (config.sim.mprofile)
901
    mprofile (memaddr, MPROF_8 | MPROF_WRITE);
902
 
903
  cur_vadd = memaddr;
904 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
905 587 markom
  /* If we produced exception don't set anything */
906
  if (pending.valid) return;
907
 
908
  if (config.debug.enabled) {
909
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
910
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
911
  }
912
 
913 992 simons
  dc_simulate_write(memaddr, (unsigned long)value, 1);
914
 
915 1218 phoenix
  if (cur_area && cur_area->log)
916 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> write %02"PRIx8"\n", memaddr,
917
             value);
918 587 markom
}
919
 
920 1319 phoenix
/*
921
 * STATISTICS NOT OK.
922
 */
923 1350 nogj
void set_direct8(oraddr_t memaddr, uint8_t value, int* breakpoint,
924 1240 phoenix
                 int through_mmu, int through_dc)
925
{
926
 
927
  cur_vadd = memaddr;
928
 
929
  if (through_mmu) {
930
    /* 0 - no write access, we do not want a DPF exception do we ;)
931
     */
932
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
933
  }
934
 
935 1319 phoenix
  /* __PHX__ fixme: we'll get cache hit/miss delay added to cycles count,
936
   *                and possibly also memory access times.
937 1240 phoenix
   */
938 1319 phoenix
  if (!through_dc)
939
    PRINTF("WARNING: statistics might not be OK\n");
940 1240 phoenix
  dc_simulate_write(memaddr, value, 1);
941
 
942
  if (cur_area && cur_area->log)
943 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %02"PRIx8"\n",
944
             memaddr, value);
945 1240 phoenix
}
946
 
947
 
948 1350 nogj
void dumpmemory(oraddr_t from, oraddr_t to, int disasm, int nl)
949 361 markom
{
950 1350 nogj
  oraddr_t i, j;
951 361 markom
  struct label_entry *tmp;
952
  int ilen = disasm ? 4 : 16;
953
 
954
  for(i = from; i < to; i += ilen) {
955 1350 nogj
    PRINTF("%"PRIxADDR": ", i);
956 361 markom
    for (j = 0; j < ilen;) {
957
      if (!disasm) {
958
        tmp = NULL;
959 1350 nogj
        if (verify_memoryarea(i + j)) {
960 361 markom
          struct label_entry *entry;
961
          entry = get_label(i + j);
962
          if (entry)
963 997 markom
            PRINTF("(%s)", entry->name);
964 1350 nogj
          PRINTF("%02"PRIx8" ", evalsim_mem8(i + j));
965 997 markom
        } else PRINTF("XX ");
966 361 markom
        j++;
967
      } else {
968
        int breakpoint;
969 1350 nogj
        uint32_t _insn = read_mem(i, &breakpoint);
970 361 markom
        int index = insn_decode (_insn);
971
        int len = insn_len (index);
972
 
973
        tmp = NULL;
974 1350 nogj
        if (verify_memoryarea(i + j)) {
975 361 markom
          struct label_entry *entry;
976
          entry = get_label(i + j);
977
          if (entry)
978 997 markom
            PRINTF("(%s)", entry->name);
979 361 markom
 
980 1350 nogj
          PRINTF(": %08"PRIx32" ", _insn);
981 361 markom
          if (index >= 0) {
982
            disassemble_insn (_insn);
983 997 markom
            PRINTF(" %s", disassembled);
984 361 markom
          } else
985 997 markom
            PRINTF("<invalid>");
986
        } else PRINTF("XXXXXXXX");
987 361 markom
        j += len;
988
      }
989
    }
990
    if (nl)
991 997 markom
      PRINTF ("\n");
992 361 markom
  }
993
}
994
 
995 1350 nogj
uint32_t simmem_read_word(oraddr_t addr) {
996 538 markom
  return simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2];
997 221 markom
}
998
 
999 1350 nogj
void simmem_write_word(oraddr_t addr, uint32_t value) {
1000 538 markom
  simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2] = value;
1001 221 markom
}
1002
 
1003 1350 nogj
uint32_t simmem_read_zero(oraddr_t addr) {
1004 424 markom
  if (config.sim.verbose)
1005 1350 nogj
    fprintf (stderr, "WARNING: memory read from non-read memory area 0x%"
1006
                     PRIxADDR".\n", addr);
1007 424 markom
  return 0;
1008
}
1009
 
1010 1350 nogj
void simmem_write_null(oraddr_t addr, uint32_t value) {
1011 424 markom
  if (config.sim.verbose)
1012 1350 nogj
    fprintf (stderr, "WARNING: memory write to 0x%"PRIxADDR", non-write memory area (value 0x%08"PRIx32").\n", addr, value);
1013 424 markom
}
1014
 
1015
/* Initialize memory table from a config struct */
1016
 
1017
void init_memory_table ()
1018 221 markom
{
1019 1350 nogj
  uint32_t memory_needed = 0;
1020 426 markom
 
1021 424 markom
  /* If nothing was defined, use default memory block */
1022
  if (config.memory.nmemories) {
1023
    int i;
1024
    for (i = 0; i < config.memory.nmemories; i++) {
1025 1350 nogj
      oraddr_t start = config.memory.table[i].baseaddr;
1026
      uint32_t length = config.memory.table[i].size;
1027 424 markom
      char *type = config.memory.table[i].name;
1028
      int rd = config.memory.table[i].delayr;
1029
      int wd = config.memory.table[i].delayw;
1030
      int ce = config.memory.table[i].ce;
1031
      if (config.sim.verbose)
1032 1350 nogj
        debug (1, "%"PRIxADDR" %08"PRIx32" (%"PRIi32" KB): %s (activated by CE%i; read delay = %icyc, write delay = %icyc)\n",
1033 424 markom
          start, length, length >> 10, type, ce, rd, wd);
1034 1350 nogj
      register_memoryarea(start, length, 4, 0, &simmem_read_word,
1035
                          &simmem_write_word);
1036 239 markom
      cur_area->misc = memory_needed;
1037 540 simons
      cur_area->chip_select = ce;
1038 543 simons
      cur_area->valid = 1;
1039 424 markom
      cur_area->delayw = wd;
1040
      cur_area->delayr = rd;
1041 426 markom
      if (config.memory.table[i].log[0] != '\0') {
1042
        if ((cur_area->log = fopen (config.memory.table[i].log, "wt+")) == NULL)
1043 1350 nogj
          fprintf (stderr, "WARNING: Cannot open '%s'.\n",
1044
                   config.memory.table[i].log);
1045 426 markom
      } else
1046 554 markom
        cur_area->log = NULL;
1047 261 markom
      memory_needed += cur_area->size;
1048 239 markom
    }
1049 997 markom
    PRINTF ("\n");
1050 239 markom
  } else {
1051 308 markom
    if (config.sim.verbose)
1052 424 markom
      fprintf (stderr, "WARNING: Memory not defined, assuming standard configuration.\n");
1053 1350 nogj
    register_memoryarea(DEFAULT_MEMORY_START, DEFAULT_MEMORY_LEN, 4, 0,
1054
                        &simmem_read_word, &simmem_write_word);
1055 554 markom
    cur_area->misc = memory_needed;
1056
    cur_area->chip_select = 0;
1057
    cur_area->valid = 1;
1058
    cur_area->delayw = 1;
1059
    cur_area->delayr = 1;
1060
    cur_area->log = NULL;
1061 261 markom
    memory_needed += cur_area->size;
1062 239 markom
  }
1063 424 markom
 
1064 1350 nogj
  simmem32 = (uint32_t *) malloc (sizeof (uint32_t) * ((memory_needed + 3) / 4));
1065 538 markom
  if (!simmem32) {
1066 239 markom
    fprintf (stderr, "Failed to allocate sim memory. Aborting\n");
1067
    exit (-1);
1068
  }
1069 221 markom
}
1070 424 markom
 
1071
/* Changes read/write memory in read/write only */
1072
 
1073
void lock_memory_table ()
1074
{
1075
  struct dev_memarea *ptmp;
1076
 
1077
  /* Check list of registered devices. */
1078
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
1079 538 markom
    if (ptmp->delayr < 0 && ptmp->readfunc == &simmem_read_word)
1080 424 markom
      ptmp->readfunc = &simmem_read_zero;
1081 538 markom
    if (ptmp->delayw < 0 && ptmp->writefunc == &simmem_write_word)
1082 424 markom
      ptmp->writefunc = &simmem_write_null;
1083 543 simons
 
1084
    /* If this mem area is not for memory chip under MC control
1085
       then this area is valid all the time */
1086
    if (ptmp->readfunc != &simmem_read_word) {
1087
      ptmp->valid = 1;
1088
      ptmp->chip_select = -1;
1089
    }
1090 424 markom
  }
1091
}
1092 426 markom
 
1093
/* Closes files, etc. */
1094
 
1095
void done_memory_table ()
1096
{
1097
  struct dev_memarea *ptmp;
1098
 
1099
  /* Check list of registered devices. */
1100
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
1101
    if (ptmp->log)
1102
      fclose (ptmp->log);
1103
  }
1104
}
1105 427 markom
 
1106
/* Displays current memory configuration */
1107
 
1108
void memory_table_status ()
1109
{
1110
  struct dev_memarea *ptmp;
1111
 
1112
  /* Check list of registered devices. */
1113
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
1114 1350 nogj
    PRINTF ("addr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR", size %"PRIx32
1115
            ", gran %iB\n",
1116 427 markom
      ptmp->addr_mask, ptmp->addr_compare, ptmp->addr_compare | bit_mask (ptmp->size),
1117
      ptmp->size, ptmp->granularity);
1118 997 markom
    PRINTF ("\t");
1119 427 markom
    if (ptmp->delayr >= 0)
1120 997 markom
      PRINTF ("read delay = %i cycles, ", ptmp->delayr);
1121 427 markom
    else
1122 997 markom
      PRINTF ("reads not possible, ");
1123 427 markom
 
1124
    if (ptmp->delayw >= 0)
1125 997 markom
      PRINTF ("write delay = %i cycles", ptmp->delayw);
1126 427 markom
    else
1127 997 markom
      PRINTF ("writes not possible");
1128 427 markom
 
1129
    if (ptmp->log)
1130 997 markom
      PRINTF (", (logged)\n");
1131 427 markom
    else
1132 997 markom
      PRINTF ("\n");
1133 427 markom
  }
1134
}
1135 433 markom
 
1136
/* Outputs time in pretty form to dest string */
1137
 
1138 897 markom
char *generate_time_pretty (char *dest, long time_ps)
1139 433 markom
{
1140
  int exp3 = 0;
1141
  if (time_ps) {
1142
    while ((time_ps % 1000) == 0) {
1143
      time_ps /= 1000;
1144
      exp3++;
1145
    }
1146
  }
1147 1308 phoenix
  sprintf (dest, "%li%cs", time_ps, "pnum"[exp3]);
1148 897 markom
  return dest;
1149 433 markom
}

powered by: WebSVN 2.1.0

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