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 1362

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

powered by: WebSVN 2.1.0

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