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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [cpu/] [common/] [abstract.c] - Blame information for rev 1484

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

powered by: WebSVN 2.1.0

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