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

Subversion Repositories or1k

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

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

powered by: WebSVN 2.1.0

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