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 1782

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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