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 1244

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

powered by: WebSVN 2.1.0

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