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

Subversion Repositories or1k

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

powered by: WebSVN 2.1.0

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