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 1308

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 7 jrydberg
#include "sim-config.h"
31 6 lampret
 
32 2 cvs
#include "parse.h"
33
#include "abstract.h"
34 261 markom
#include "labels.h"
35 2 cvs
#include "arch.h"
36
#include "execute.h"
37 32 lampret
#include "sprs.h"
38 35 lampret
#include "stats.h"
39 32 lampret
#include "except.h"
40 123 markom
#include "debug_unit.h"
41 134 markom
#include "opcode/or32.h"
42 547 markom
#include "support/profile.h"
43 1308 phoenix
#include "dmmu.h"
44
#include "dcache_model.h"
45
#include "icache_model.h"
46
#include "debug.h"
47 2 cvs
 
48
extern unsigned long reg[];
49 138 markom
extern char *disassembled;
50 2 cvs
 
51 28 lampret
/* This is an abstract+physical memory array rather than only physical
52
   memory array */
53 538 markom
static unsigned long *simmem32;
54 2 cvs
 
55 30 lampret
/* Pointer to memory area descriptions that are assigned to individual
56
   peripheral devices. */
57
struct dev_memarea *dev_list;
58
 
59 221 markom
/* Temporary variable to increase speed.  */
60
struct dev_memarea *cur_area;
61
 
62 970 simons
/* Pointer to memory controller device descriptor.  */
63
struct dev_memarea *mc_area = (struct dev_memarea *)0;
64
 
65 638 simons
/* These are set by mmu if cache inhibit bit is set for current acces.  */
66
int data_ci, insn_ci;
67
 
68 525 simons
/* Virtual address of current access. */
69
unsigned long cur_vadd;
70
 
71 261 markom
/* Calculates bit mask to fit the data */
72
unsigned long bit_mask (unsigned long data) {
73
  int i = 0;
74
  data--;
75 382 markom
  while (data >> i)
76 261 markom
    data |= 1 << i++;
77
  return data;
78
}
79
 
80
/* Register read and write function for a memory area.
81
   addr is inside the area, if addr & addr_mask == addr_compare
82
   (used also by peripheral devices like 16450 UART etc.) */
83
void register_memoryarea_mask(unsigned long addr_mask, unsigned long addr_compare,
84 970 simons
                         unsigned long size, unsigned granularity, unsigned mc_dev,
85 239 markom
                         unsigned long (readfunc)(unsigned long),
86 261 markom
                         void (writefunc)(unsigned long, unsigned long))
87 30 lampret
{
88 239 markom
  struct dev_memarea **pptmp;
89 261 markom
  unsigned long size_mask = bit_mask (size);
90
  int found_error = 0;
91
  addr_compare &= addr_mask;
92 221 markom
 
93 382 markom
  debug(5, "addr & %08x == %08x to %08x, size %08x, gran %iB\n", addr_mask, addr_compare, addr_compare | bit_mask (size), size, granularity);
94 239 markom
  /* Go to the end of the list. */
95 261 markom
  for(pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next)
96
    if ((addr_compare >= (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)
97
     || (addr_compare + size > (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)) {
98 262 markom
      if (!found_error) {
99 261 markom
        fprintf (stderr, "ERROR: Overlapping memory area(s):\n");
100 1308 phoenix
        fprintf (stderr, "\taddr & %08lx == %08lx to %08lx, size %08lx, gran %iB\n",
101
                 addr_mask, addr_compare, addr_compare | bit_mask (size), size,
102
                 granularity);
103 262 markom
      }
104 261 markom
      found_error = 1;
105 1308 phoenix
      fprintf (stderr, "and\taddr & %08lx == %08lx to %08lx, size %08lx, gran %liB\n",
106
               (*pptmp)->addr_mask, (*pptmp)->addr_compare,
107
               (*pptmp)->addr_compare | (*pptmp)->size_mask,
108
               (*pptmp)->size, (*pptmp)->granularity);
109 261 markom
    }
110
 
111
  if (found_error)
112
    exit (-1);
113 537 markom
 
114 239 markom
  cur_area = *pptmp = (struct dev_memarea *)malloc(sizeof(struct dev_memarea));
115 970 simons
 
116
  if (mc_dev)
117
    mc_area = *pptmp;
118
 
119 261 markom
  (*pptmp)->addr_mask = addr_mask;
120
  (*pptmp)->addr_compare = addr_compare;
121 239 markom
  (*pptmp)->size = size;
122 261 markom
  (*pptmp)->size_mask = size_mask;
123 239 markom
  (*pptmp)->granularity = granularity;
124
  (*pptmp)->readfunc = readfunc;
125
  (*pptmp)->writefunc = writefunc;
126 479 markom
  (*pptmp)->log = 0;
127 882 simons
  (*pptmp)->delayr = 2;
128
  (*pptmp)->delayw = 2;
129 239 markom
  (*pptmp)->next = NULL;
130 261 markom
}
131 221 markom
 
132 261 markom
/* Register read and write function for a memory area.
133
   Memory areas should be aligned. Memory area is rounded up to
134
   fit the nearest 2^n aligment.
135 970 simons
   (used also by peripheral devices like 16450 UART etc.)
136
   If mc_dev is 1, this means that this device will be checked first for match
137
   and will be accessed in case in overlaping memory spaces.
138
   Only one device can have this set to 1 (used for memory controller) */
139 261 markom
void register_memoryarea(unsigned long addr,
140 970 simons
                         unsigned long size, unsigned granularity, unsigned mc_dev,
141 261 markom
                         unsigned long (readfunc)(unsigned long),
142
                         void (writefunc)(unsigned long, unsigned long))
143
{
144
  unsigned long size_mask = bit_mask (size);
145
  unsigned long addr_mask = ~size_mask;
146
  register_memoryarea_mask (addr_mask, addr & addr_mask,
147 970 simons
                      size_mask + 1, granularity, mc_dev,
148 261 markom
                      readfunc, writefunc);
149 30 lampret
}
150
 
151 261 markom
 
152 30 lampret
/* Check if access is to registered area of memory. */
153 560 markom
inline struct dev_memarea *verify_memoryarea(unsigned long addr)
154 30 lampret
{
155 239 markom
  struct dev_memarea *ptmp;
156 221 markom
 
157 970 simons
  /* Check memory controller space first */
158
  if (mc_area && (addr & mc_area->addr_mask) == (mc_area->addr_compare & mc_area->addr_mask))
159
    return cur_area = mc_area;
160
 
161
  /* Check cached value */
162 560 markom
  if (cur_area && (addr & cur_area->addr_mask) == (cur_area->addr_compare & cur_area->addr_mask))
163
    return cur_area;
164
 
165
  /* When mc is enabled, we must check valid also, otherwise we assume it is nonzero */
166
  IFF (config.mc.enabled) {
167
    /* Check list of registered devices. */
168
    for(ptmp = dev_list; ptmp; ptmp = ptmp->next)
169
      if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask) && ptmp->valid)
170
        return cur_area = ptmp;
171
  } else {
172
    /* Check list of registered devices. */
173
    for(ptmp = dev_list; ptmp; ptmp = ptmp->next)
174
      if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask))
175
        return cur_area = ptmp;
176
  }
177 239 markom
  return cur_area = NULL;
178 30 lampret
}
179
 
180 882 simons
/* Finds the memory area for the address and adjust the read and write delays for it. */
181
void adjust_rw_delay(unsigned long memaddr, unsigned long delayr, unsigned long delayw)
182
{
183
  if (verify_memoryarea(memaddr)) {
184
    cur_area->delayr = delayr;
185
    cur_area->delayw = delayw;
186
  }
187
}
188
 
189 560 markom
inline unsigned long evalsim_mem32(unsigned long memaddr)
190
{
191
  unsigned long temp;
192
 
193
  if (verify_memoryarea(memaddr)) {
194
    switch(cur_area->granularity) {
195
    case 4:
196
      temp = cur_area->readfunc(memaddr);
197 884 markom
      runtime.sim.mem_cycles += cur_area->delayr;
198 560 markom
      break;
199
    case 1:
200
      temp = cur_area->readfunc(memaddr) << 24;
201
      temp |= cur_area->readfunc(memaddr + 1) << 16;
202
      temp |= cur_area->readfunc(memaddr + 2) << 8;
203
      temp |= cur_area->readfunc(memaddr + 3);
204 884 markom
      runtime.sim.mem_cycles += cur_area->delayr * 4;
205 560 markom
      break;
206
    case 2:
207
      temp = cur_area->readfunc(memaddr) << 16;
208
      temp |= cur_area->readfunc(memaddr + 2);
209 884 markom
      runtime.sim.mem_cycles += cur_area->delayr * 2;
210 560 markom
      break;
211
    }
212
  }
213
  return temp;
214
}
215
 
216
unsigned short evalsim_mem16(unsigned long memaddr)
217
{
218
  unsigned long temp;
219
 
220
  if (verify_memoryarea(memaddr)) {
221
    switch(cur_area->granularity) {
222
    case 1:
223
      temp = cur_area->readfunc(memaddr) << 8;
224
      temp |= cur_area->readfunc(memaddr + 1);
225 884 markom
      runtime.sim.mem_cycles += cur_area->delayr * 2;
226 560 markom
      break;
227
    case 2:
228
      temp = cur_area->readfunc(memaddr);
229 884 markom
      runtime.sim.mem_cycles += cur_area->delayr;
230 560 markom
      break;
231
    case 4:
232
      temp = evalsim_mem32 (memaddr & ~3ul);
233
      if (memaddr & 2)
234
        temp &= 0xffff;
235
      else
236
        temp >>= 16;
237
      break;
238
    }
239
  }
240
  return temp;
241
}
242
 
243
unsigned char evalsim_mem8(unsigned long memaddr)
244
{
245
  unsigned long temp;
246
 
247
  if (verify_memoryarea(memaddr)) {
248
    switch(cur_area->granularity) {
249
    case 1:
250
      temp = cur_area->readfunc(memaddr);
251 884 markom
      runtime.sim.mem_cycles += cur_area->delayr;
252 560 markom
      break;
253
    case 2:
254
      temp = evalsim_mem16 (memaddr & ~1ul);
255
      if (memaddr & 1)
256
        temp &= 0xff;
257
      else
258
        temp >>= 8;
259
      break;
260
    case 4:
261
      temp = evalsim_mem32 (memaddr & ~3ul);
262
      temp >>= 8 * (3 - (memaddr & 3));
263
      temp &= 0xff;
264
      break;
265
    }
266
  }
267
  return temp;
268
}
269
 
270 2 cvs
/* Returns 32-bit values from mem array. Big endian version. */
271 349 simons
unsigned long read_mem(unsigned long memaddr,int* breakpoint)
272
{
273
  unsigned long temp;
274
 
275 525 simons
  cur_vadd = memaddr;
276 550 markom
  if (config.debug.enabled)
277 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
278
  temp = evalsim_mem32(memaddr);
279 611 simons
  if (!cur_area) {
280 997 markom
    PRINTF("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr);
281 611 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
282
    temp = 0;
283
  }
284
 
285 599 simons
  if (!pending.valid && cur_area->log)
286 1308 phoenix
    fprintf (cur_area->log, "[%08lx] -> read %08lx\n", memaddr, temp);
287 550 markom
  if (config.debug.enabled)
288 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
289
  return temp;
290 537 markom
}
291 349 simons
 
292
/* Returns 32-bit values from mem array. Big endian version. */
293 123 markom
unsigned long eval_mem32(unsigned long memaddr,int* breakpoint)
294 2 cvs
{
295 6 lampret
 
296 239 markom
  unsigned long temp;
297 123 markom
 
298 547 markom
  if (config.sim.mprofile)
299
    mprofile (memaddr, MPROF_32 | MPROF_READ);
300
 
301 538 markom
  if (memaddr & 3) {
302
    except_handle (EXCEPT_ALIGN, memaddr);
303
    return 0;
304
  }
305 557 markom
 
306 631 simons
  if (config.debug.enabled)
307
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
308
 
309 574 markom
  cur_vadd = memaddr;
310 631 simons
 
311
  memaddr = dmmu_translate(memaddr, 0);
312 574 markom
  if (pending.valid)
313
    return 0;
314
 
315 992 simons
  if (config.dc.enabled)
316
    temp = dc_simulate_read(memaddr, 4);
317
  else {
318
    temp = evalsim_mem32(memaddr);
319
    if (!cur_area) {
320 997 markom
      PRINTF("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
321 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
322
      temp = 0;
323
    }
324 611 simons
  }
325
 
326 550 markom
  if (config.debug.enabled)
327 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
328 239 markom
  return temp;
329 66 lampret
}
330
 
331 1240 phoenix
unsigned long eval_direct32(unsigned long memaddr, int *breakpoint,
332
                            int through_mmu, int through_dc)
333
{
334
  unsigned long temp;
335
 
336
  if (memaddr & 3) {
337
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
338
      return 0;
339
  }
340
 
341
  cur_vadd = memaddr;
342
 
343
  if (through_mmu)
344
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
345
 
346
  if (through_dc)
347
    temp = dc_simulate_read(memaddr, 4);
348
  else {
349
    temp = evalsim_mem32(memaddr);
350
    if (!cur_area) {
351
      PRINTF("EXCEPTION: read out of memory (32-bit access to %.8lx) in eval_direct32()\n", memaddr);
352
      except_handle(EXCEPT_BUSERR, cur_vadd);
353
      temp = 0;
354
    }
355
  }
356
 
357
  return temp;
358
}
359
 
360
 
361 349 simons
/* Returns 32-bit values from mem array. Big endian version. */
362
unsigned long eval_insn(unsigned long memaddr,int* breakpoint)
363
{
364
  unsigned long temp;
365
 
366 547 markom
  if (config.sim.mprofile)
367
    mprofile (memaddr, MPROF_32 | MPROF_FETCH);
368 532 markom
//  memaddr = simulate_ic_mmu_fetch(memaddr);
369 525 simons
  cur_vadd = pc;
370 1244 hpanther
 
371
  // I think this does not belong into eval_insn() 2004-01-30 HP
372
//  if (config.debug.enabled)
373
//    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
374
 
375
  // We could place the CheckDebugUnit(DebugInstructionFetch) here, but it is currently done
376
  // in decode_execute_wrapper, so I leave it like this. 2004-01-30 HP
377
 
378 631 simons
  if (config.ic.enabled)
379
    temp = ic_simulate_fetch(memaddr);
380 992 simons
  else {
381 631 simons
    temp = evalsim_mem32(memaddr);
382 992 simons
    if (!cur_area) {
383 997 markom
      PRINTF("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
384 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
385
      temp = 0;
386
    }
387 611 simons
  }
388
 
389 1244 hpanther
  // I think this does not belong into eval_insn() 2004-01-30 HP
390
//  if (config.debug.enabled)
391
//    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
392 349 simons
  return temp;
393
}
394
 
395 2 cvs
/* Returns 16-bit values from mem array. Big endian version. */
396
 
397 123 markom
unsigned short eval_mem16(unsigned long memaddr,int* breakpoint)
398 2 cvs
{
399 239 markom
  unsigned short temp;
400 547 markom
 
401
  if (config.sim.mprofile)
402
    mprofile (memaddr, MPROF_16 | MPROF_READ);
403
 
404 538 markom
  if (memaddr & 1) {
405
    except_handle (EXCEPT_ALIGN, memaddr);
406
    return 0;
407
  }
408 574 markom
 
409 631 simons
  if (config.debug.enabled)
410
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
411
 
412 574 markom
  cur_vadd = memaddr;
413 631 simons
 
414
  memaddr = dmmu_translate(memaddr, 0);
415 574 markom
  if (pending.valid)
416
    return 0;
417 66 lampret
 
418 992 simons
  if (config.dc.enabled)
419
    temp = (unsigned short)dc_simulate_read(memaddr, 2);
420
  else {
421
    temp = evalsim_mem16(memaddr);
422
    if (!cur_area) {
423 997 markom
      PRINTF("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr);
424 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
425
      temp = 0;
426
    }
427 611 simons
  }
428
 
429 550 markom
  if (config.debug.enabled)
430 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
431 239 markom
  return temp;
432 66 lampret
}
433
 
434 1240 phoenix
unsigned short eval_direct16(unsigned long memaddr, int *breakpoint,
435
                             int through_mmu, int through_dc)
436
{
437
  unsigned long temp;
438
 
439
  if (memaddr & 3) {
440
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
441
      return 0;
442
  }
443
 
444
  cur_vadd = memaddr;
445
 
446
  if (through_mmu)
447
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
448
 
449
  if (through_dc)
450
    temp = dc_simulate_read(memaddr, 2);
451
  else {
452
    temp = evalsim_mem16(memaddr);
453
    if (!cur_area) {
454
      PRINTF("EXCEPTION: read out of memory (16-bit access to %.8lx) in eval_direct16()\n", memaddr);
455
      except_handle(EXCEPT_BUSERR, cur_vadd);
456
      temp = 0;
457
    }
458
  }
459
 
460
  return temp;
461
}
462
 
463
 
464 6 lampret
/* Returns 8-bit values from mem array. */
465 2 cvs
 
466 123 markom
unsigned char eval_mem8(unsigned long memaddr,int* breakpoint)
467 221 markom
{
468 631 simons
  unsigned char temp;
469 547 markom
 
470
  if (config.sim.mprofile)
471
    mprofile (memaddr, MPROF_8 | MPROF_READ);
472
 
473 631 simons
  if (config.debug.enabled)
474
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr);  /* 28/05/01 CZ */
475
 
476 525 simons
  cur_vadd = memaddr;
477 631 simons
 
478
  memaddr = dmmu_translate(memaddr, 0);
479 458 simons
  if (pending.valid)
480
    return 0;
481 6 lampret
 
482 992 simons
  if (config.dc.enabled)
483
    temp = (unsigned char)dc_simulate_read(memaddr, 1);
484
  else {
485
    temp = evalsim_mem8(memaddr);
486
    if (!cur_area) {
487 997 markom
      PRINTF("EXCEPTION: read out of memory (8-bit access to %.8lx)\n", memaddr);
488 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
489
      temp = 0;
490
    }
491 611 simons
  }
492
 
493 550 markom
  if (config.debug.enabled)
494 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
495 239 markom
  return temp;
496 66 lampret
}
497
 
498 1240 phoenix
unsigned char eval_direct8(unsigned long memaddr, int *breakpoint,
499
                           int through_mmu, int through_dc)
500
{
501
  unsigned char temp;
502
 
503
  if (memaddr & 3) {
504
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
505
    return 0;
506
  }
507
 
508
  cur_vadd = memaddr;
509
 
510
  if (through_mmu)
511
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
512
 
513
  if (through_dc)
514
    temp = (unsigned char)dc_simulate_read(memaddr, 1);
515
  else {
516
    temp = evalsim_mem8(memaddr);
517
    if (!cur_area) {
518
      PRINTF("EXCEPTION: read out of memory (8-bit access to %.8lx) in eval_direct8()\n", memaddr);
519
      except_handle(EXCEPT_BUSERR, cur_vadd);
520
      temp = 0;
521
    }
522
  }
523 1308 phoenix
  return temp;
524 1240 phoenix
}
525
 
526
 
527 66 lampret
void setsim_mem32(unsigned long memaddr, unsigned long value)
528
{
529 239 markom
  if (verify_memoryarea(memaddr)) {
530
    switch(cur_area->granularity) {
531 538 markom
    case 4:
532
      cur_area->writefunc(memaddr, value);
533 884 markom
      runtime.sim.mem_cycles += cur_area->delayw;
534 538 markom
      break;
535 239 markom
    case 1:
536 251 erez
      cur_area->writefunc(memaddr    , (value >> 24) & 0xFF);
537 239 markom
      cur_area->writefunc(memaddr + 1, (value >> 16) & 0xFF);
538 251 erez
      cur_area->writefunc(memaddr + 2, (value >>  8) & 0xFF);
539
      cur_area->writefunc(memaddr + 3, (value      ) & 0xFF);
540 884 markom
      runtime.sim.mem_cycles += cur_area->delayw * 4;
541 239 markom
      break;
542
    case 2:
543
      cur_area->writefunc(memaddr, (value >> 16) & 0xFFFF);
544
      cur_area->writefunc(memaddr + 2, value & 0xFFFF);
545 884 markom
      runtime.sim.mem_cycles += cur_area->delayw * 2;
546 239 markom
      break;
547 242 markom
    }
548 239 markom
  } else {
549 997 markom
    PRINTF("EXCEPTION: write out of memory (32-bit access to %.8lx)\n", memaddr);
550 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
551 239 markom
  }
552 2 cvs
}
553
 
554 66 lampret
void setsim_mem16(unsigned long memaddr, unsigned short value)
555
{
556 538 markom
  unsigned long temp;
557 239 markom
  if (verify_memoryarea(memaddr)) {
558
    switch(cur_area->granularity) {
559
    case 1:
560
      cur_area->writefunc(memaddr, (value >> 8) & 0xFF);
561
      cur_area->writefunc(memaddr + 1, value & 0xFF);
562 884 markom
      runtime.sim.mem_cycles += cur_area->delayw * 2;
563 239 markom
      break;
564
    case 2:
565 251 erez
      cur_area->writefunc(memaddr, value & 0xFFFF);
566 884 markom
      runtime.sim.mem_cycles += cur_area->delayw;
567 239 markom
      break;
568
    case 4:
569 538 markom
      temp = evalsim_mem32 (memaddr & ~3ul);
570 546 simons
      temp &= 0xffff << ((memaddr & 2) ? 16 : 0);
571
      temp |= (unsigned long)(value & 0xffff) << ((memaddr & 2) ? 0 : 16);
572 538 markom
      setsim_mem32 (memaddr & ~3ul, temp);
573 239 markom
      break;
574
    }
575
  } else {
576 997 markom
    PRINTF("EXCEPTION: write out of memory (16-bit access to %.8lx)\n", memaddr);
577 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
578 239 markom
  }
579 2 cvs
}
580
 
581 66 lampret
void setsim_mem8(unsigned long memaddr, unsigned char value)
582
{
583 538 markom
  unsigned long temp;
584 239 markom
  if (verify_memoryarea(memaddr)) {
585 538 markom
    switch (cur_area->granularity) {
586
    case 1:
587 239 markom
      cur_area->writefunc(memaddr, value);
588 884 markom
      runtime.sim.mem_cycles += cur_area->delayw;
589 538 markom
      break;
590
    case 2:
591
      temp = evalsim_mem16 (memaddr & ~1ul);
592 546 simons
      temp &= 0xff << ((memaddr & 1) ? 8 : 0);
593
      temp |= (unsigned short)(value & 0xff) << ((memaddr & 1) ? 0 : 8);
594 538 markom
      setsim_mem16 (memaddr & ~1ul, temp);
595
      break;
596
    case 4:
597
      temp = evalsim_mem32 (memaddr & ~3ul);
598
      temp &= ~(0xff << (8 * (3 - (memaddr & 3))));
599
      temp |= (unsigned long)(value & 0xff) << (8 * (3 - (memaddr & 3)));
600
      setsim_mem32 (memaddr & ~3ul, temp);
601
      break;
602 239 markom
    }
603
  } else {
604 997 markom
    PRINTF("EXCEPTION: write out of memory (8-bit access to %.8lx)\n", memaddr);
605 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
606 239 markom
  }
607 2 cvs
}
608 30 lampret
 
609 587 markom
/* Set mem, 32-bit. Big endian version. */
610
 
611
void set_mem32(unsigned long memaddr, unsigned long value,int* breakpoint)
612
{
613
  if (config.sim.mprofile)
614
    mprofile (memaddr, MPROF_32 | MPROF_WRITE);
615
 
616
  if (memaddr & 3) {
617
    except_handle (EXCEPT_ALIGN, memaddr);
618
    return;
619
  }
620
 
621
  cur_vadd = memaddr;
622 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
623 587 markom
  /* If we produced exception don't set anything */
624
  if (pending.valid)
625
    return;
626
 
627
  if (config.debug.enabled) {
628
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
629
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
630
  }
631
 
632 992 simons
  dc_simulate_write(memaddr, value, 4);
633
 
634 1218 phoenix
  if (cur_area && cur_area->log)
635 1308 phoenix
    fprintf (cur_area->log, "[%08lx] -> write %08lx\n", memaddr, value);
636 587 markom
}
637
 
638 1240 phoenix
void set_direct32(unsigned long memaddr, unsigned long value,int* breakpoint,
639
                  int through_mmu, int through_dc)
640
{
641
 
642
  if (memaddr & 3) {
643
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
644
    return;
645
  }
646
 
647
  cur_vadd = memaddr;
648
 
649
  if (through_mmu) {
650
    /* 0 - no write access, we do not want a DPF exception do we ;)
651
     */
652
    memaddr = peek_into_dtlb(memaddr, 1, through_dc);
653
  }
654
 
655
 
656
  /* __PHX__ fixme: in principle we should write around the cache if
657
   *                through_dc is set, but i believe we this will work
658
   *                just fine anyway
659
   */
660
  dc_simulate_write(memaddr, value, 4);
661
 
662
  if (cur_area && cur_area->log)
663 1308 phoenix
    fprintf (cur_area->log, "[%08lx] -> write %08lx\n", memaddr, value);
664 1240 phoenix
}
665
 
666
 
667 587 markom
/* Set mem, 16-bit. Big endian version. */
668
 
669 1240 phoenix
void set_mem16(unsigned long memaddr, unsigned short value, int* breakpoint)
670 587 markom
{
671
  if (config.sim.mprofile)
672
    mprofile (memaddr, MPROF_16 | MPROF_WRITE);
673
 
674
  if (memaddr & 1) {
675
    except_handle (EXCEPT_ALIGN, memaddr);
676
    return;
677
  }
678
 
679
  cur_vadd = memaddr;
680 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
681 587 markom
  /* If we produced exception don't set anything */
682
  if (pending.valid)
683
    return;
684
 
685
  if (config.debug.enabled) {
686
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
687
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
688
  }
689
 
690 992 simons
  dc_simulate_write(memaddr, (unsigned long)value, 2);
691
 
692 1218 phoenix
  if (cur_area && cur_area->log)
693 1308 phoenix
    fprintf (cur_area->log, "[%08lx] -> write %08x\n", memaddr, value);
694 587 markom
}
695
 
696 1240 phoenix
void set_direct16(unsigned long memaddr, unsigned short value, int* breakpoint,
697
                  int through_mmu, int through_dc)
698
{
699
 
700
  if (memaddr & 3) {
701
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
702
    return;
703
  }
704
 
705
  cur_vadd = memaddr;
706
 
707
  if (through_mmu) {
708
    /* 0 - no write access, we do not want a DPF exception do we ;)
709
     */
710
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
711
  }
712
 
713
  /* __PHX__ fixme: in principle we should write around the cache if
714
   *                through_dc is set, but i believe we this will work
715
   *                just fine anyway
716
   */
717
  dc_simulate_write(memaddr, value, 2);
718
 
719
  if (cur_area && cur_area->log)
720 1308 phoenix
    fprintf (cur_area->log, "[%08lx] -> write %08x\n", memaddr, value);
721 1240 phoenix
}
722
 
723 587 markom
/* Set mem, 8-bit. */
724
 
725 1240 phoenix
void set_mem8(unsigned long memaddr, unsigned char value, int* breakpoint)
726 587 markom
{
727
  if (config.sim.mprofile)
728
    mprofile (memaddr, MPROF_8 | MPROF_WRITE);
729
 
730
  cur_vadd = memaddr;
731 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
732 587 markom
  /* If we produced exception don't set anything */
733
  if (pending.valid) return;
734
 
735
  if (config.debug.enabled) {
736
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
737
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
738
  }
739
 
740 992 simons
  dc_simulate_write(memaddr, (unsigned long)value, 1);
741
 
742 1218 phoenix
  if (cur_area && cur_area->log)
743 1308 phoenix
    fprintf (cur_area->log, "[%08lx] -> write %08x\n", memaddr, value);
744 587 markom
}
745
 
746 1240 phoenix
void set_direct8(unsigned long memaddr, unsigned char value, int* breakpoint,
747
                 int through_mmu, int through_dc)
748
{
749
 
750
  if (memaddr & 3) {
751
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
752
    return;
753
  }
754
 
755
  cur_vadd = memaddr;
756
 
757
  if (through_mmu) {
758
    /* 0 - no write access, we do not want a DPF exception do we ;)
759
     */
760
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
761
  }
762
 
763
  /* __PHX__ fixme: in principle we should write around the cache if
764
   *                through_dc is set, but i believe we this will work
765
   *                just fine anyway
766
   */
767
  dc_simulate_write(memaddr, value, 1);
768
 
769
  if (cur_area && cur_area->log)
770
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
771
}
772
 
773
 
774
 
775 361 markom
void dumpmemory(unsigned int from, unsigned int to, int disasm, int nl)
776
{
777
  unsigned int i, j;
778
  struct label_entry *tmp;
779
  int ilen = disasm ? 4 : 16;
780
 
781
  for(i = from; i < to; i += ilen) {
782 997 markom
    PRINTF("%.8x: ", i);
783 361 markom
    for (j = 0; j < ilen;) {
784
      int data = -1;
785
      if (!disasm) {
786
        tmp = NULL;
787
        if (verify_memoryarea(i+j)) {
788
          struct label_entry *entry;
789
          entry = get_label(i + j);
790
          if (entry)
791 997 markom
            PRINTF("(%s)", entry->name);
792
          PRINTF("%02x ", data = evalsim_mem8(i+j));
793
        } else PRINTF("XX ");
794 361 markom
        j++;
795
      } else {
796
        int breakpoint;
797
        unsigned int _insn = read_mem(i, &breakpoint);
798
        int index = insn_decode (_insn);
799
        int len = insn_len (index);
800
 
801
        tmp = NULL;
802
        if (verify_memoryarea(i+j)) {
803
          struct label_entry *entry;
804
          entry = get_label(i + j);
805
          if (entry)
806 997 markom
            PRINTF("(%s)", entry->name);
807 361 markom
 
808 1308 phoenix
          PRINTF(": %08lx ", (unsigned long)_insn);
809 361 markom
          if (index >= 0) {
810
            disassemble_insn (_insn);
811 997 markom
            PRINTF(" %s", disassembled);
812 361 markom
          } else
813 997 markom
            PRINTF("<invalid>");
814
        } else PRINTF("XXXXXXXX");
815 361 markom
        j += len;
816
      }
817
    }
818
    if (nl)
819 997 markom
      PRINTF ("\n");
820 361 markom
  }
821
}
822
 
823 538 markom
unsigned long simmem_read_word(unsigned long addr) {
824
  return simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2];
825 221 markom
}
826
 
827 538 markom
void simmem_write_word(unsigned long addr, unsigned long value) {
828
  simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2] = value;
829 221 markom
}
830
 
831 424 markom
unsigned long simmem_read_zero(unsigned long addr) {
832
  if (config.sim.verbose)
833
    fprintf (stderr, "WARNING: memory read from non-read memory area 0x%08x.\n", addr);
834
  return 0;
835
}
836
 
837
void simmem_write_null(unsigned long addr, unsigned long value) {
838
  if (config.sim.verbose)
839 1308 phoenix
    fprintf (stderr, "WARNING: memory write to 0x%08lx, non-write memory area (value 0x%08lx).\n", addr, value);
840 424 markom
}
841
 
842
/* Initialize memory table from a config struct */
843
 
844
void init_memory_table ()
845 221 markom
{
846 239 markom
  unsigned long memory_needed = 0;
847 426 markom
 
848 424 markom
  /* If nothing was defined, use default memory block */
849
  if (config.memory.nmemories) {
850
    int i;
851
    for (i = 0; i < config.memory.nmemories; i++) {
852
      unsigned long start = config.memory.table[i].baseaddr;
853
      unsigned long length = config.memory.table[i].size;
854
      char *type = config.memory.table[i].name;
855
      int rd = config.memory.table[i].delayr;
856
      int wd = config.memory.table[i].delayw;
857
      int ce = config.memory.table[i].ce;
858
      if (config.sim.verbose)
859
        debug (1, "%08X %08X (%i KB): %s (activated by CE%i; read delay = %icyc, write delay = %icyc)\n",
860
          start, length, length >> 10, type, ce, rd, wd);
861 970 simons
      register_memoryarea(start, length, 4, 0, &simmem_read_word, &simmem_write_word);
862 239 markom
      cur_area->misc = memory_needed;
863 540 simons
      cur_area->chip_select = ce;
864 543 simons
      cur_area->valid = 1;
865 424 markom
      cur_area->delayw = wd;
866
      cur_area->delayr = rd;
867 426 markom
      if (config.memory.table[i].log[0] != '\0') {
868
        if ((cur_area->log = fopen (config.memory.table[i].log, "wt+")) == NULL)
869
          fprintf (stderr, "WARNING: Cannot open '%s'.\n", config.memory.table[i].log);
870
      } else
871 554 markom
        cur_area->log = NULL;
872 261 markom
      memory_needed += cur_area->size;
873 239 markom
    }
874 997 markom
    PRINTF ("\n");
875 239 markom
  } else {
876 308 markom
    if (config.sim.verbose)
877 424 markom
      fprintf (stderr, "WARNING: Memory not defined, assuming standard configuration.\n");
878 970 simons
    register_memoryarea(DEFAULT_MEMORY_START, DEFAULT_MEMORY_LEN, 4, 0, &simmem_read_word, &simmem_write_word);
879 554 markom
    cur_area->misc = memory_needed;
880
    cur_area->chip_select = 0;
881
    cur_area->valid = 1;
882
    cur_area->delayw = 1;
883
    cur_area->delayr = 1;
884
    cur_area->log = NULL;
885 261 markom
    memory_needed += cur_area->size;
886 239 markom
  }
887 424 markom
 
888 538 markom
  simmem32 = (unsigned long *) malloc (sizeof (unsigned long) * ((memory_needed + 3) / 4));
889
  if (!simmem32) {
890 239 markom
    fprintf (stderr, "Failed to allocate sim memory. Aborting\n");
891
    exit (-1);
892
  }
893 221 markom
}
894 424 markom
 
895
/* Changes read/write memory in read/write only */
896
 
897
void lock_memory_table ()
898
{
899
  struct dev_memarea *ptmp;
900
 
901
  /* Check list of registered devices. */
902
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
903 538 markom
    if (ptmp->delayr < 0 && ptmp->readfunc == &simmem_read_word)
904 424 markom
      ptmp->readfunc = &simmem_read_zero;
905 538 markom
    if (ptmp->delayw < 0 && ptmp->writefunc == &simmem_write_word)
906 424 markom
      ptmp->writefunc = &simmem_write_null;
907 543 simons
 
908
    /* If this mem area is not for memory chip under MC control
909
       then this area is valid all the time */
910
    if (ptmp->readfunc != &simmem_read_word) {
911
      ptmp->valid = 1;
912
      ptmp->chip_select = -1;
913
    }
914 424 markom
  }
915
}
916 426 markom
 
917
/* Closes files, etc. */
918
 
919
void done_memory_table ()
920
{
921
  struct dev_memarea *ptmp;
922
 
923
  /* Check list of registered devices. */
924
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
925
    if (ptmp->log)
926
      fclose (ptmp->log);
927
  }
928
}
929 427 markom
 
930
/* Displays current memory configuration */
931
 
932
void memory_table_status ()
933
{
934
  struct dev_memarea *ptmp;
935
 
936
  /* Check list of registered devices. */
937
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
938 1308 phoenix
    PRINTF ("addr & %08lx == %08lx to %08lx, size %08lx, gran %liB\n",
939 427 markom
      ptmp->addr_mask, ptmp->addr_compare, ptmp->addr_compare | bit_mask (ptmp->size),
940
      ptmp->size, ptmp->granularity);
941 997 markom
    PRINTF ("\t");
942 427 markom
    if (ptmp->delayr >= 0)
943 997 markom
      PRINTF ("read delay = %i cycles, ", ptmp->delayr);
944 427 markom
    else
945 997 markom
      PRINTF ("reads not possible, ");
946 427 markom
 
947
    if (ptmp->delayw >= 0)
948 997 markom
      PRINTF ("write delay = %i cycles", ptmp->delayw);
949 427 markom
    else
950 997 markom
      PRINTF ("writes not possible");
951 427 markom
 
952
    if (ptmp->log)
953 997 markom
      PRINTF (", (logged)\n");
954 427 markom
    else
955 997 markom
      PRINTF ("\n");
956 427 markom
  }
957
}
958 433 markom
 
959
/* Outputs time in pretty form to dest string */
960
 
961 897 markom
char *generate_time_pretty (char *dest, long time_ps)
962 433 markom
{
963
  int exp3 = 0;
964
  if (time_ps) {
965
    while ((time_ps % 1000) == 0) {
966
      time_ps /= 1000;
967
      exp3++;
968
    }
969
  }
970 1308 phoenix
  sprintf (dest, "%li%cs", time_ps, "pnum"[exp3]);
971 897 markom
  return dest;
972 433 markom
}

powered by: WebSVN 2.1.0

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