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 1359

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

powered by: WebSVN 2.1.0

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