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

Subversion Repositories or1k

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

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 1350 nogj
 * this function is only used in dumpmemory() below, so it's
340 1319 phoenix
 * safe to asume it's for simulator purposes access only,
341
 * hence the use of eval_mem32_void()
342
 *
343
 * STATISTICS OK.
344
 */
345 1350 nogj
static uint32_t read_mem(oraddr_t memaddr, int* breakpoint)
346 349 simons
{
347 1350 nogj
  uint32_t temp;
348 349 simons
 
349 525 simons
  cur_vadd = memaddr;
350 550 markom
  if (config.debug.enabled)
351 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
352 1319 phoenix
  temp = evalsim_mem32_void(memaddr);
353 611 simons
  if (!cur_area) {
354 1350 nogj
    PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR")\n",
355
           memaddr);
356 611 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
357
    temp = 0;
358 1386 nogj
  } else if (cur_area->log)
359
    fprintf (cur_area->log, "[%"PRIxADDR"] -> read %08"PRIx32"\n", memaddr, temp);
360 611 simons
 
361 550 markom
  if (config.debug.enabled)
362 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
363
  return temp;
364 537 markom
}
365 349 simons
 
366 1319 phoenix
/* Returns 32-bit values from mem array. Big endian version.
367
 *
368
 * STATISTICS OK (only used for cpu_access, that is architectural access)
369
 */
370 1350 nogj
uint32_t eval_mem32(oraddr_t memaddr,int* breakpoint)
371 2 cvs
{
372 1350 nogj
  uint32_t temp;
373 123 markom
 
374 547 markom
  if (config.sim.mprofile)
375
    mprofile (memaddr, MPROF_32 | MPROF_READ);
376
 
377 538 markom
  if (memaddr & 3) {
378
    except_handle (EXCEPT_ALIGN, memaddr);
379
    return 0;
380
  }
381 557 markom
 
382 631 simons
  if (config.debug.enabled)
383
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
384
 
385 574 markom
  cur_vadd = memaddr;
386 631 simons
 
387
  memaddr = dmmu_translate(memaddr, 0);
388 1386 nogj
  if (except_pending)
389 574 markom
    return 0;
390
 
391 992 simons
  if (config.dc.enabled)
392
    temp = dc_simulate_read(memaddr, 4);
393
  else {
394
    temp = evalsim_mem32(memaddr);
395
    if (!cur_area) {
396 1350 nogj
      PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR")\n",
397
             memaddr);
398 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
399
      temp = 0;
400
    }
401 611 simons
  }
402
 
403 550 markom
  if (config.debug.enabled)
404 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
405 239 markom
  return temp;
406 66 lampret
}
407
 
408 1319 phoenix
/* for simulator accesses, the ones that cpu wouldn't do
409
 *
410
 * STATISTICS OK
411
 */
412 1350 nogj
uint32_t eval_direct32(oraddr_t memaddr, int *breakpoint, int through_mmu,
413
                       int through_dc)
414 1240 phoenix
{
415 1350 nogj
  uint32_t temp;
416 1240 phoenix
 
417
  if (memaddr & 3) {
418
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
419
      return 0;
420
  }
421
 
422
  cur_vadd = memaddr;
423
 
424
  if (through_mmu)
425
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
426
 
427
  if (through_dc)
428
    temp = dc_simulate_read(memaddr, 4);
429
  else {
430 1319 phoenix
    temp = evalsim_mem32_void(memaddr);
431 1240 phoenix
    if (!cur_area) {
432 1350 nogj
      PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR
433
             ") in eval_direct32()\n", memaddr);
434 1240 phoenix
      except_handle(EXCEPT_BUSERR, cur_vadd);
435
      temp = 0;
436
    }
437
  }
438
 
439
  return temp;
440
}
441
 
442
 
443 1319 phoenix
/* Returns 32-bit values from mem array. Big endian version.
444
 *
445
 * STATISTICS OK (only used for cpu_access, that is architectural access)
446
 */
447 1386 nogj
uint32_t eval_insn(oraddr_t memaddr, int* breakpoint)
448 349 simons
{
449 1350 nogj
  uint32_t temp;
450 349 simons
 
451 547 markom
  if (config.sim.mprofile)
452
    mprofile (memaddr, MPROF_32 | MPROF_FETCH);
453 532 markom
//  memaddr = simulate_ic_mmu_fetch(memaddr);
454 1244 hpanther
 
455 1386 nogj
  cur_vadd = memaddr;
456 1244 hpanther
 
457 1452 nogj
#if !(DYNAMIC_EXECUTION)
458 1386 nogj
  memaddr = immu_translate(memaddr);
459
 
460
  if (except_pending)
461
    return 0;
462 1452 nogj
#endif
463 1386 nogj
 
464
  if (config.debug.enabled)
465
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr);
466
 
467 631 simons
  if (config.ic.enabled)
468
    temp = ic_simulate_fetch(memaddr);
469 992 simons
  else {
470 631 simons
    temp = evalsim_mem32(memaddr);
471 992 simons
    if (!cur_area) {
472 1350 nogj
      PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR")\n",
473
             memaddr);
474 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
475
      temp = 0;
476
    }
477 611 simons
  }
478
 
479 1386 nogj
  if (config.debug.enabled)
480
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);
481 349 simons
  return temp;
482
}
483
 
484 1452 nogj
/* Returns 32-bit values from mem array. Big endian version.
485
 *
486
 * STATISTICS OK
487
 */
488
uint32_t eval_insn_direct(oraddr_t memaddr, int* breakpoint, int through_mmu)
489
{
490
  uint32_t temp;
491
  int brk;
492
 
493
  cur_vadd = memaddr;
494
 
495
  if(through_mmu)
496
    memaddr = peek_into_itlb(memaddr);
497
 
498
  if (config.debug.enabled)
499
    *breakpoint += CheckDebugUnit(DebugLoadAddress, memaddr);
500
 
501
  temp = eval_direct32(memaddr, &brk, 0, 0);
502
 
503
  if (config.debug.enabled)
504
    *breakpoint += CheckDebugUnit(DebugLoadData, temp);
505
 
506
  return temp;
507
}
508
 
509
 
510 1319 phoenix
/* Returns 16-bit values from mem array. Big endian version.
511
 *
512
 * STATISTICS OK (only used for cpu_access, that is architectural access)
513
 */
514 1350 nogj
uint16_t eval_mem16(oraddr_t memaddr,int* breakpoint)
515 2 cvs
{
516 1350 nogj
  uint16_t temp;
517 547 markom
 
518
  if (config.sim.mprofile)
519
    mprofile (memaddr, MPROF_16 | MPROF_READ);
520
 
521 538 markom
  if (memaddr & 1) {
522
    except_handle (EXCEPT_ALIGN, memaddr);
523
    return 0;
524
  }
525 574 markom
 
526 631 simons
  if (config.debug.enabled)
527
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
528
 
529 574 markom
  cur_vadd = memaddr;
530 631 simons
 
531
  memaddr = dmmu_translate(memaddr, 0);
532 1386 nogj
  if (except_pending)
533 574 markom
    return 0;
534 66 lampret
 
535 992 simons
  if (config.dc.enabled)
536 1386 nogj
    temp = (uint16_t)dc_simulate_read(memaddr, 2);
537 992 simons
  else {
538
    temp = evalsim_mem16(memaddr);
539
    if (!cur_area) {
540 1350 nogj
      PRINTF("EXCEPTION: read out of memory (16-bit access to %"PRIxADDR")\n",
541
             memaddr);
542 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
543
      temp = 0;
544
    }
545 611 simons
  }
546
 
547 550 markom
  if (config.debug.enabled)
548 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
549 239 markom
  return temp;
550 66 lampret
}
551
 
552 1319 phoenix
/* for simulator accesses, the ones that cpu wouldn't do
553
 *
554
 * STATISTICS OK.
555
 */
556 1350 nogj
uint16_t eval_direct16(oraddr_t memaddr, int *breakpoint, int through_mmu,
557
                       int through_dc)
558 1240 phoenix
{
559 1350 nogj
  uint32_t temp;
560 1240 phoenix
 
561 1324 phoenix
  if (memaddr & 1) {
562 1240 phoenix
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
563
      return 0;
564
  }
565
 
566
  cur_vadd = memaddr;
567
 
568
  if (through_mmu)
569
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
570
 
571
  if (through_dc)
572
    temp = dc_simulate_read(memaddr, 2);
573
  else {
574 1319 phoenix
    temp = evalsim_mem16_void(memaddr);
575 1240 phoenix
    if (!cur_area) {
576 1350 nogj
      PRINTF("EXCEPTION: read out of memory (16-bit access to %"PRIxADDR
577
             ") in eval_direct16()\n", memaddr);
578 1240 phoenix
      except_handle(EXCEPT_BUSERR, cur_vadd);
579
      temp = 0;
580
    }
581
  }
582
 
583
  return temp;
584
}
585
 
586
 
587 1319 phoenix
/* Returns 8-bit values from mem array.
588
 *
589
 * STATISTICS OK (only used for cpu_access, that is architectural access)
590
 */
591 1350 nogj
uint8_t eval_mem8(oraddr_t memaddr,int* breakpoint)
592 221 markom
{
593 1350 nogj
  uint8_t temp;
594 547 markom
 
595
  if (config.sim.mprofile)
596
    mprofile (memaddr, MPROF_8 | MPROF_READ);
597
 
598 631 simons
  if (config.debug.enabled)
599
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr);  /* 28/05/01 CZ */
600
 
601 525 simons
  cur_vadd = memaddr;
602 631 simons
 
603
  memaddr = dmmu_translate(memaddr, 0);
604 1386 nogj
  if (except_pending)
605 458 simons
    return 0;
606 6 lampret
 
607 992 simons
  if (config.dc.enabled)
608 1386 nogj
    temp = (uint8_t)dc_simulate_read(memaddr, 1);
609 992 simons
  else {
610
    temp = evalsim_mem8(memaddr);
611
    if (!cur_area) {
612 1350 nogj
      PRINTF("EXCEPTION: read out of memory (8-bit access to %"PRIxADDR")\n",
613
             memaddr);
614 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
615
      temp = 0;
616
    }
617 611 simons
  }
618
 
619 550 markom
  if (config.debug.enabled)
620 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
621 239 markom
  return temp;
622 66 lampret
}
623
 
624 1319 phoenix
/* for simulator accesses, the ones that cpu wouldn't do
625
 *
626
 * STATISTICS OK.
627
 */
628 1350 nogj
uint8_t eval_direct8(oraddr_t memaddr, int *breakpoint, int through_mmu,
629
                     int through_dc)
630 1240 phoenix
{
631 1350 nogj
  uint8_t temp;
632 1240 phoenix
 
633
  cur_vadd = memaddr;
634
 
635
  if (through_mmu)
636
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
637
 
638
  if (through_dc)
639
    temp = (unsigned char)dc_simulate_read(memaddr, 1);
640
  else {
641 1319 phoenix
    temp = evalsim_mem8_void(memaddr);
642 1240 phoenix
    if (!cur_area) {
643 1350 nogj
      PRINTF("EXCEPTION: read out of memory (8-bit access to %"PRIxADDR
644
             ") in eval_direct8()\n", memaddr);
645 1240 phoenix
      except_handle(EXCEPT_BUSERR, cur_vadd);
646
      temp = 0;
647
    }
648
  }
649 1308 phoenix
  return temp;
650 1240 phoenix
}
651
 
652 1319 phoenix
/* for cpu accesses */
653 1350 nogj
inline void setsim_mem32(oraddr_t memaddr, uint32_t value)
654 1319 phoenix
{
655
  return(setsim_mem32_atomic(memaddr, value, 1));
656
}
657 1240 phoenix
 
658 1319 phoenix
/* for simulator accesses, the ones that cpu wouldn't do */
659 1350 nogj
inline void setsim_mem32_void(oraddr_t memaddr, uint32_t value)
660 66 lampret
{
661 1319 phoenix
  return(setsim_mem32_atomic(memaddr, value, 0));
662
}
663
 
664 1350 nogj
void setsim_mem32_atomic(oraddr_t memaddr, uint32_t value, int cpu_access)
665 1319 phoenix
{
666 239 markom
  if (verify_memoryarea(memaddr)) {
667
    switch(cur_area->granularity) {
668 538 markom
    case 4:
669 1359 nogj
      cur_area->writefunc(memaddr, value, cur_area->priv_dat);
670 1319 phoenix
      if (cpu_access)
671
        runtime.sim.mem_cycles += cur_area->delayw;
672 538 markom
      break;
673 239 markom
    case 1:
674 1359 nogj
      cur_area->writefunc(memaddr    , (value >> 24) & 0xFF, cur_area->priv_dat);
675
      cur_area->writefunc(memaddr + 1, (value >> 16) & 0xFF, cur_area->priv_dat);
676
      cur_area->writefunc(memaddr + 2, (value >>  8) & 0xFF, cur_area->priv_dat);
677
      cur_area->writefunc(memaddr + 3, (value      ) & 0xFF, cur_area->priv_dat);
678 1319 phoenix
      if (cpu_access)
679
        runtime.sim.mem_cycles += cur_area->delayw * 4;
680 239 markom
      break;
681
    case 2:
682 1359 nogj
      cur_area->writefunc(memaddr, (value >> 16) & 0xFFFF, cur_area->priv_dat);
683
      cur_area->writefunc(memaddr + 2, value & 0xFFFF, cur_area->priv_dat);
684 1319 phoenix
      if (cpu_access)
685
        runtime.sim.mem_cycles += cur_area->delayw * 2;
686 239 markom
      break;
687 1319 phoenix
    default:
688
      /* if you add new memory granularity be sure to check the formula
689
       * below for the read delay and fix it if necessery
690
       */
691
      PRINTF("unknown/unhandled memory granularuty\n");
692
      exit(-1);
693 242 markom
    }
694 1452 nogj
#if DYNAMIC_EXECUTION
695
    /* FIXME: Do this with mprotect() */
696
    struct dyn_page *dp;
697
 
698
    /* Since the locations 0x0-0xff are nearly always written to in an exception
699
     * handler, ignore any writes to these locations.  If code ends up jumping
700
     * out there, we'll recompile when the jump actually happens. */
701
    if((memaddr > 0x100) && (dp = find_dynd_page(memaddr)) && !dp->dirty)
702
      dirtyfy_page(dp);
703
#endif
704 239 markom
  } else {
705 1350 nogj
    PRINTF("EXCEPTION: write out of memory (32-bit access to %"PRIxADDR")\n",
706
           memaddr);
707 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
708 239 markom
  }
709 2 cvs
}
710
 
711 1319 phoenix
/* for cpu accesses */
712 1350 nogj
inline void setsim_mem16(oraddr_t memaddr, uint16_t value)
713 66 lampret
{
714 1319 phoenix
  return(setsim_mem16_atomic(memaddr, value, 1));
715
}
716
 
717
/* for simulator accesses, the ones that cpu wouldn't do */
718 1350 nogj
inline void setsim_mem16_void(oraddr_t memaddr, uint16_t value)
719 1319 phoenix
{
720
  return(setsim_mem16_atomic(memaddr, value, 0));
721
}
722
 
723 1350 nogj
void setsim_mem16_atomic(oraddr_t memaddr, uint16_t value, int cpu_access)
724 1319 phoenix
{
725 1350 nogj
  uint32_t temp;
726 239 markom
  if (verify_memoryarea(memaddr)) {
727
    switch(cur_area->granularity) {
728
    case 1:
729 1359 nogj
      cur_area->writefunc(memaddr, (value >> 8) & 0xFF, cur_area->priv_dat);
730
      cur_area->writefunc(memaddr + 1, value & 0xFF, cur_area->priv_dat);
731 1319 phoenix
      if (cpu_access)
732
        runtime.sim.mem_cycles += cur_area->delayw * 2;
733 239 markom
      break;
734
    case 2:
735 1359 nogj
      cur_area->writefunc(memaddr, value & 0xFFFF, cur_area->priv_dat);
736 1319 phoenix
      if (cpu_access)
737
        runtime.sim.mem_cycles += cur_area->delayw;
738 239 markom
      break;
739
    case 4:
740 1350 nogj
      temp = evalsim_mem32_void(memaddr & ~ADDR_C(3));
741 546 simons
      temp &= 0xffff << ((memaddr & 2) ? 16 : 0);
742
      temp |= (unsigned long)(value & 0xffff) << ((memaddr & 2) ? 0 : 16);
743 1350 nogj
      setsim_mem32_atomic(memaddr & ~ADDR_C(3), temp, cpu_access);
744 239 markom
      break;
745 1319 phoenix
    default:
746
      /* if you add new memory granularity be sure to check the formula
747
       * below for the read delay and fix it if necessery
748
       */
749
      PRINTF("unknown/unhandled memory granularuty\n");
750
      exit(-1);
751 239 markom
    }
752 1452 nogj
#if DYNAMIC_EXECUTION
753
    /* FIXME: Do this with mprotect() */
754
    struct dyn_page *dp;
755
 
756
    /* Since the locations 0x0-0xff are nearly always written to in an exception
757
     * handler, ignore any writes to these locations.  If code ends up jumping
758
     * out there, we'll recompile when the jump actually happens. */
759
 
760
    if((memaddr > 0x100) && (dp = find_dynd_page(memaddr)) && !dp->dirty)
761
      dirtyfy_page(dp);
762
#endif
763 239 markom
  } else {
764 1350 nogj
    PRINTF("EXCEPTION: write out of memory (16-bit access to %"PRIxADDR")\n",
765
           memaddr);
766 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
767 239 markom
  }
768 2 cvs
}
769
 
770 1319 phoenix
/* for cpu accesses */
771 1350 nogj
inline void setsim_mem8(oraddr_t memaddr, uint8_t value)
772 66 lampret
{
773 1319 phoenix
  return(setsim_mem8_atomic(memaddr, value, 1));
774
}
775
 
776
/* for simulator accesses, the ones that cpu wouldn't do */
777 1350 nogj
inline void setsim_mem8_void(oraddr_t memaddr, uint8_t value)
778 1319 phoenix
{
779
  return(setsim_mem8_atomic(memaddr, value, 0));
780
}
781
 
782 1350 nogj
void setsim_mem8_atomic(oraddr_t memaddr, uint8_t value, int cpu_access)
783 1319 phoenix
{
784 1350 nogj
  uint32_t temp;
785 239 markom
  if (verify_memoryarea(memaddr)) {
786 538 markom
    switch (cur_area->granularity) {
787
    case 1:
788 1359 nogj
      cur_area->writefunc(memaddr, value, cur_area->priv_dat);
789 1319 phoenix
      if (cpu_access)
790
        runtime.sim.mem_cycles += cur_area->delayw;
791 538 markom
      break;
792
    case 2:
793 1350 nogj
      temp = evalsim_mem16_void (memaddr & ~ADDR_C(1));
794 546 simons
      temp &= 0xff << ((memaddr & 1) ? 8 : 0);
795
      temp |= (unsigned short)(value & 0xff) << ((memaddr & 1) ? 0 : 8);
796 1350 nogj
      setsim_mem16_atomic (memaddr & ~ADDR_C(1), temp, cpu_access);
797 538 markom
      break;
798
    case 4:
799 1350 nogj
      temp = evalsim_mem32_void (memaddr & ~ADDR_C(3));
800 538 markom
      temp &= ~(0xff << (8 * (3 - (memaddr & 3))));
801
      temp |= (unsigned long)(value & 0xff) << (8 * (3 - (memaddr & 3)));
802 1350 nogj
      setsim_mem32_atomic (memaddr & ~ADDR_C(3), temp, cpu_access);
803 538 markom
      break;
804 239 markom
    }
805 1452 nogj
#if DYNAMIC_EXECUTION
806
    /* FIXME: Do this with mprotect() */
807
    struct dyn_page *dp;
808
 
809
    /* Since the locations 0x0-0xff are nearly always written to in an exception
810
     * handler, ignore any writes to these locations.  If code ends up jumping
811
     * out there, we'll recompile when the jump actually happens. */
812
 
813
    if((memaddr > 0x100) && (dp = find_dynd_page(memaddr)) && !dp->dirty)
814
      dirtyfy_page(dp);
815
#endif
816 239 markom
  } else {
817 1350 nogj
    PRINTF("EXCEPTION: write out of memory (8-bit access to %"PRIxADDR")\n",
818
           memaddr);
819 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
820 239 markom
  }
821 2 cvs
}
822 30 lampret
 
823 1319 phoenix
/* Set mem, 32-bit. Big endian version.
824
 *
825 1446 nogj
 * STATISTICS OK. (the only suspicious usage is in sim-cmd.c,
826 1319 phoenix
 *                 where this instruction is used for patching memory,
827
 *                 wether this is cpu or architectual access is yet to
828
 *                 be decided)
829
 */
830 1350 nogj
void set_mem32(oraddr_t memaddr, uint32_t value, int* breakpoint)
831 587 markom
{
832
  if (config.sim.mprofile)
833
    mprofile (memaddr, MPROF_32 | MPROF_WRITE);
834
 
835
  if (memaddr & 3) {
836
    except_handle (EXCEPT_ALIGN, memaddr);
837
    return;
838
  }
839
 
840
  cur_vadd = memaddr;
841 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
842 587 markom
  /* If we produced exception don't set anything */
843 1386 nogj
  if (except_pending)
844 587 markom
    return;
845
 
846
  if (config.debug.enabled) {
847
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
848
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
849
  }
850
 
851 992 simons
  dc_simulate_write(memaddr, value, 4);
852
 
853 1218 phoenix
  if (cur_area && cur_area->log)
854 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> write %08"PRIx32"\n", memaddr,
855
             value);
856 587 markom
}
857
 
858 1319 phoenix
/*
859
 * STATISTICS NOT OK.
860
 */
861 1350 nogj
void set_direct32(oraddr_t memaddr, uint32_t value,int* breakpoint,
862 1240 phoenix
                  int through_mmu, int through_dc)
863
{
864
 
865
  if (memaddr & 3) {
866
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
867
    return;
868
  }
869
 
870
  cur_vadd = memaddr;
871
 
872
  if (through_mmu) {
873
    /* 0 - no write access, we do not want a DPF exception do we ;)
874
     */
875
    memaddr = peek_into_dtlb(memaddr, 1, through_dc);
876
  }
877
 
878
 
879 1319 phoenix
  /* __PHX__ fixme: we'll get cache hit/miss delay added to cycles count,
880
   *                and possibly also memory access times.
881 1240 phoenix
   */
882 1319 phoenix
  if (!through_dc)
883
    PRINTF("WARNING: statistics might not be OK\n");
884 1240 phoenix
  dc_simulate_write(memaddr, value, 4);
885
 
886
  if (cur_area && cur_area->log)
887 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %08"PRIx32"\n",
888
             memaddr, value);
889 1240 phoenix
}
890
 
891
 
892 587 markom
/* Set mem, 16-bit. Big endian version. */
893
 
894 1350 nogj
void set_mem16(oraddr_t memaddr, uint16_t value, int* breakpoint)
895 587 markom
{
896
  if (config.sim.mprofile)
897
    mprofile (memaddr, MPROF_16 | MPROF_WRITE);
898
 
899
  if (memaddr & 1) {
900
    except_handle (EXCEPT_ALIGN, memaddr);
901
    return;
902
  }
903
 
904
  cur_vadd = memaddr;
905 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
906 587 markom
  /* If we produced exception don't set anything */
907 1386 nogj
  if (except_pending)
908 587 markom
    return;
909
 
910
  if (config.debug.enabled) {
911
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
912
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
913
  }
914
 
915 1446 nogj
  dc_simulate_write(memaddr, value, 2);
916 992 simons
 
917 1218 phoenix
  if (cur_area && cur_area->log)
918 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> write %04"PRIx16"\n", memaddr,
919
             value);
920 587 markom
}
921
 
922 1319 phoenix
/*
923
 * STATISTICS NOT OK.
924
 */
925 1350 nogj
void set_direct16(oraddr_t memaddr, uint16_t value, int* breakpoint,
926 1240 phoenix
                  int through_mmu, int through_dc)
927
{
928
 
929 1324 phoenix
  if (memaddr & 1) {
930 1240 phoenix
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
931
    return;
932
  }
933
 
934
  cur_vadd = memaddr;
935
 
936
  if (through_mmu) {
937
    /* 0 - no write access, we do not want a DPF exception do we ;)
938
     */
939
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
940
  }
941
 
942 1319 phoenix
  /* __PHX__ fixme: we'll get cache hit/miss delay added to cycles count,
943
   *                and possibly also memory access times.
944 1240 phoenix
   */
945 1319 phoenix
  if (!through_dc)
946
    PRINTF("WARNING: statistics might not be OK\n");
947 1240 phoenix
  dc_simulate_write(memaddr, value, 2);
948
 
949
  if (cur_area && cur_area->log)
950 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %04"PRIx16"\n",
951
             memaddr, value);
952 1240 phoenix
}
953
 
954 587 markom
/* Set mem, 8-bit. */
955
 
956 1350 nogj
void set_mem8(oraddr_t memaddr, uint8_t value, int* breakpoint)
957 587 markom
{
958
  if (config.sim.mprofile)
959
    mprofile (memaddr, MPROF_8 | MPROF_WRITE);
960
 
961
  cur_vadd = memaddr;
962 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
963 587 markom
  /* If we produced exception don't set anything */
964 1386 nogj
  if (except_pending) return;
965 587 markom
 
966
  if (config.debug.enabled) {
967
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
968
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
969
  }
970
 
971 1386 nogj
  dc_simulate_write(memaddr, value, 1);
972 992 simons
 
973 1218 phoenix
  if (cur_area && cur_area->log)
974 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> write %02"PRIx8"\n", memaddr,
975
             value);
976 587 markom
}
977
 
978 1319 phoenix
/*
979
 * STATISTICS NOT OK.
980
 */
981 1350 nogj
void set_direct8(oraddr_t memaddr, uint8_t value, int* breakpoint,
982 1240 phoenix
                 int through_mmu, int through_dc)
983
{
984
 
985
  cur_vadd = memaddr;
986
 
987
  if (through_mmu) {
988
    /* 0 - no write access, we do not want a DPF exception do we ;)
989
     */
990
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
991
  }
992
 
993 1319 phoenix
  /* __PHX__ fixme: we'll get cache hit/miss delay added to cycles count,
994
   *                and possibly also memory access times.
995 1240 phoenix
   */
996 1319 phoenix
  if (!through_dc)
997
    PRINTF("WARNING: statistics might not be OK\n");
998 1240 phoenix
  dc_simulate_write(memaddr, value, 1);
999
 
1000
  if (cur_area && cur_area->log)
1001 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %02"PRIx8"\n",
1002
             memaddr, value);
1003 1240 phoenix
}
1004
 
1005
 
1006 1350 nogj
void dumpmemory(oraddr_t from, oraddr_t to, int disasm, int nl)
1007 361 markom
{
1008 1350 nogj
  oraddr_t i, j;
1009 361 markom
  struct label_entry *tmp;
1010
  int ilen = disasm ? 4 : 16;
1011
 
1012
  for(i = from; i < to; i += ilen) {
1013 1350 nogj
    PRINTF("%"PRIxADDR": ", i);
1014 361 markom
    for (j = 0; j < ilen;) {
1015
      if (!disasm) {
1016
        tmp = NULL;
1017 1350 nogj
        if (verify_memoryarea(i + j)) {
1018 361 markom
          struct label_entry *entry;
1019
          entry = get_label(i + j);
1020
          if (entry)
1021 997 markom
            PRINTF("(%s)", entry->name);
1022 1350 nogj
          PRINTF("%02"PRIx8" ", evalsim_mem8(i + j));
1023 997 markom
        } else PRINTF("XX ");
1024 361 markom
        j++;
1025
      } else {
1026
        int breakpoint;
1027 1350 nogj
        uint32_t _insn = read_mem(i, &breakpoint);
1028 361 markom
        int index = insn_decode (_insn);
1029
        int len = insn_len (index);
1030
 
1031
        tmp = NULL;
1032 1350 nogj
        if (verify_memoryarea(i + j)) {
1033 361 markom
          struct label_entry *entry;
1034
          entry = get_label(i + j);
1035
          if (entry)
1036 997 markom
            PRINTF("(%s)", entry->name);
1037 361 markom
 
1038 1350 nogj
          PRINTF(": %08"PRIx32" ", _insn);
1039 361 markom
          if (index >= 0) {
1040
            disassemble_insn (_insn);
1041 997 markom
            PRINTF(" %s", disassembled);
1042 361 markom
          } else
1043 997 markom
            PRINTF("<invalid>");
1044
        } else PRINTF("XXXXXXXX");
1045 361 markom
        j += len;
1046
      }
1047
    }
1048
    if (nl)
1049 997 markom
      PRINTF ("\n");
1050 361 markom
  }
1051
}
1052
 
1053 1359 nogj
uint32_t simmem_read_word(oraddr_t addr, void *priv_dat) {
1054
  return *(uint32_t *)(priv_dat + (addr & cur_area->size_mask));
1055 221 markom
}
1056
 
1057 1359 nogj
void simmem_write_word(oraddr_t addr, uint32_t value, void *priv_dat) {
1058
  *(uint32_t *)(priv_dat + (addr & cur_area->size_mask)) = value;
1059 221 markom
}
1060
 
1061 1359 nogj
uint32_t simmem_read_zero(oraddr_t addr, void *dat) {
1062 424 markom
  if (config.sim.verbose)
1063 1350 nogj
    fprintf (stderr, "WARNING: memory read from non-read memory area 0x%"
1064
                     PRIxADDR".\n", addr);
1065 424 markom
  return 0;
1066
}
1067
 
1068 1359 nogj
void simmem_write_null(oraddr_t addr, uint32_t value, void *dat) {
1069 424 markom
  if (config.sim.verbose)
1070 1350 nogj
    fprintf (stderr, "WARNING: memory write to 0x%"PRIxADDR", non-write memory area (value 0x%08"PRIx32").\n", addr, value);
1071 424 markom
}
1072
 
1073
/* Initialize memory table from a config struct */
1074
 
1075
void init_memory_table ()
1076 221 markom
{
1077 424 markom
  /* If nothing was defined, use default memory block */
1078
  if (config.memory.nmemories) {
1079
    int i;
1080
    for (i = 0; i < config.memory.nmemories; i++) {
1081 1350 nogj
      oraddr_t start = config.memory.table[i].baseaddr;
1082
      uint32_t length = config.memory.table[i].size;
1083 424 markom
      char *type = config.memory.table[i].name;
1084
      int rd = config.memory.table[i].delayr;
1085
      int wd = config.memory.table[i].delayw;
1086
      int ce = config.memory.table[i].ce;
1087 1359 nogj
      void *mem = malloc (length);
1088
 
1089 424 markom
      if (config.sim.verbose)
1090 1350 nogj
        debug (1, "%"PRIxADDR" %08"PRIx32" (%"PRIi32" KB): %s (activated by CE%i; read delay = %icyc, write delay = %icyc)\n",
1091 424 markom
          start, length, length >> 10, type, ce, rd, wd);
1092 1359 nogj
 
1093
      if (!mem) {
1094
        fprintf (stderr, "Failed to allocate sim memory. Aborting\n");
1095
        exit (-1);
1096
      }
1097
 
1098 1350 nogj
      register_memoryarea(start, length, 4, 0, &simmem_read_word,
1099 1359 nogj
                          &simmem_write_word, mem);
1100 540 simons
      cur_area->chip_select = ce;
1101 543 simons
      cur_area->valid = 1;
1102 424 markom
      cur_area->delayw = wd;
1103
      cur_area->delayr = rd;
1104 426 markom
      if (config.memory.table[i].log[0] != '\0') {
1105
        if ((cur_area->log = fopen (config.memory.table[i].log, "wt+")) == NULL)
1106 1350 nogj
          fprintf (stderr, "WARNING: Cannot open '%s'.\n",
1107
                   config.memory.table[i].log);
1108 426 markom
      } else
1109 554 markom
        cur_area->log = NULL;
1110 239 markom
    }
1111 997 markom
    PRINTF ("\n");
1112 239 markom
  } else {
1113 1359 nogj
    void *mem = malloc (DEFAULT_MEMORY_LEN);
1114 308 markom
    if (config.sim.verbose)
1115 424 markom
      fprintf (stderr, "WARNING: Memory not defined, assuming standard configuration.\n");
1116 1359 nogj
 
1117
    if (!mem) {
1118
      fprintf (stderr, "Failed to allocate sim memory. Aborting\n");
1119
      exit (-1);
1120
    }
1121
 
1122 1350 nogj
    register_memoryarea(DEFAULT_MEMORY_START, DEFAULT_MEMORY_LEN, 4, 0,
1123 1359 nogj
                        &simmem_read_word, &simmem_write_word, mem);
1124 554 markom
    cur_area->chip_select = 0;
1125
    cur_area->valid = 1;
1126
    cur_area->delayw = 1;
1127
    cur_area->delayr = 1;
1128
    cur_area->log = NULL;
1129 239 markom
  }
1130 221 markom
}
1131 424 markom
 
1132
/* Changes read/write memory in read/write only */
1133
 
1134
void lock_memory_table ()
1135
{
1136
  struct dev_memarea *ptmp;
1137
 
1138
  /* Check list of registered devices. */
1139
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
1140 538 markom
    if (ptmp->delayr < 0 && ptmp->readfunc == &simmem_read_word)
1141 424 markom
      ptmp->readfunc = &simmem_read_zero;
1142 538 markom
    if (ptmp->delayw < 0 && ptmp->writefunc == &simmem_write_word)
1143 424 markom
      ptmp->writefunc = &simmem_write_null;
1144 543 simons
 
1145
    /* If this mem area is not for memory chip under MC control
1146
       then this area is valid all the time */
1147
    if (ptmp->readfunc != &simmem_read_word) {
1148
      ptmp->valid = 1;
1149
      ptmp->chip_select = -1;
1150
    }
1151 424 markom
  }
1152
}
1153 426 markom
 
1154
/* Closes files, etc. */
1155
 
1156
void done_memory_table ()
1157
{
1158
  struct dev_memarea *ptmp;
1159
 
1160
  /* Check list of registered devices. */
1161
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
1162
    if (ptmp->log)
1163
      fclose (ptmp->log);
1164
  }
1165
}
1166 427 markom
 
1167
/* Displays current memory configuration */
1168
 
1169
void memory_table_status ()
1170
{
1171
  struct dev_memarea *ptmp;
1172
 
1173
  /* Check list of registered devices. */
1174
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
1175 1350 nogj
    PRINTF ("addr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR", size %"PRIx32
1176
            ", gran %iB\n",
1177 427 markom
      ptmp->addr_mask, ptmp->addr_compare, ptmp->addr_compare | bit_mask (ptmp->size),
1178
      ptmp->size, ptmp->granularity);
1179 997 markom
    PRINTF ("\t");
1180 427 markom
    if (ptmp->delayr >= 0)
1181 997 markom
      PRINTF ("read delay = %i cycles, ", ptmp->delayr);
1182 427 markom
    else
1183 997 markom
      PRINTF ("reads not possible, ");
1184 427 markom
 
1185
    if (ptmp->delayw >= 0)
1186 997 markom
      PRINTF ("write delay = %i cycles", ptmp->delayw);
1187 427 markom
    else
1188 997 markom
      PRINTF ("writes not possible");
1189 427 markom
 
1190
    if (ptmp->log)
1191 997 markom
      PRINTF (", (logged)\n");
1192 427 markom
    else
1193 997 markom
      PRINTF ("\n");
1194 427 markom
  }
1195
}
1196 433 markom
 
1197
/* Outputs time in pretty form to dest string */
1198
 
1199 897 markom
char *generate_time_pretty (char *dest, long time_ps)
1200 433 markom
{
1201
  int exp3 = 0;
1202
  if (time_ps) {
1203
    while ((time_ps % 1000) == 0) {
1204
      time_ps /= 1000;
1205
      exp3++;
1206
    }
1207
  }
1208 1308 phoenix
  sprintf (dest, "%li%cs", time_ps, "pnum"[exp3]);
1209 897 markom
  return dest;
1210 433 markom
}

powered by: WebSVN 2.1.0

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