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 1240

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 550 markom
  if (config.debug.enabled)
366 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
367 631 simons
  if (config.ic.enabled)
368
    temp = ic_simulate_fetch(memaddr);
369 992 simons
  else {
370 631 simons
    temp = evalsim_mem32(memaddr);
371 992 simons
    if (!cur_area) {
372 997 markom
      PRINTF("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
373 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
374
      temp = 0;
375
    }
376 611 simons
  }
377
 
378 550 markom
  if (config.debug.enabled)
379 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
380
  return temp;
381
}
382
 
383 2 cvs
/* Returns 16-bit values from mem array. Big endian version. */
384
 
385 123 markom
unsigned short eval_mem16(unsigned long memaddr,int* breakpoint)
386 2 cvs
{
387 239 markom
  unsigned short temp;
388 547 markom
 
389
  if (config.sim.mprofile)
390
    mprofile (memaddr, MPROF_16 | MPROF_READ);
391
 
392 538 markom
  if (memaddr & 1) {
393
    except_handle (EXCEPT_ALIGN, memaddr);
394
    return 0;
395
  }
396 574 markom
 
397 631 simons
  if (config.debug.enabled)
398
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
399
 
400 574 markom
  cur_vadd = memaddr;
401 631 simons
 
402
  memaddr = dmmu_translate(memaddr, 0);
403 574 markom
  if (pending.valid)
404
    return 0;
405 66 lampret
 
406 992 simons
  if (config.dc.enabled)
407
    temp = (unsigned short)dc_simulate_read(memaddr, 2);
408
  else {
409
    temp = evalsim_mem16(memaddr);
410
    if (!cur_area) {
411 997 markom
      PRINTF("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr);
412 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
413
      temp = 0;
414
    }
415 611 simons
  }
416
 
417 550 markom
  if (config.debug.enabled)
418 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
419 239 markom
  return temp;
420 66 lampret
}
421
 
422 1240 phoenix
unsigned short eval_direct16(unsigned long memaddr, int *breakpoint,
423
                             int through_mmu, int through_dc)
424
{
425
  unsigned long temp;
426
 
427
  if (memaddr & 3) {
428
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
429
      return 0;
430
  }
431
 
432
  cur_vadd = memaddr;
433
 
434
  if (through_mmu)
435
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
436
 
437
  if (through_dc)
438
    temp = dc_simulate_read(memaddr, 2);
439
  else {
440
    temp = evalsim_mem16(memaddr);
441
    if (!cur_area) {
442
      PRINTF("EXCEPTION: read out of memory (16-bit access to %.8lx) in eval_direct16()\n", memaddr);
443
      except_handle(EXCEPT_BUSERR, cur_vadd);
444
      temp = 0;
445
    }
446
  }
447
 
448
  return temp;
449
}
450
 
451
 
452 6 lampret
/* Returns 8-bit values from mem array. */
453 2 cvs
 
454 123 markom
unsigned char eval_mem8(unsigned long memaddr,int* breakpoint)
455 221 markom
{
456 631 simons
  unsigned char temp;
457 547 markom
 
458
  if (config.sim.mprofile)
459
    mprofile (memaddr, MPROF_8 | MPROF_READ);
460
 
461 631 simons
  if (config.debug.enabled)
462
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr);  /* 28/05/01 CZ */
463
 
464 525 simons
  cur_vadd = memaddr;
465 631 simons
 
466
  memaddr = dmmu_translate(memaddr, 0);
467 458 simons
  if (pending.valid)
468
    return 0;
469 6 lampret
 
470 992 simons
  if (config.dc.enabled)
471
    temp = (unsigned char)dc_simulate_read(memaddr, 1);
472
  else {
473
    temp = evalsim_mem8(memaddr);
474
    if (!cur_area) {
475 997 markom
      PRINTF("EXCEPTION: read out of memory (8-bit access to %.8lx)\n", memaddr);
476 992 simons
      except_handle(EXCEPT_BUSERR, cur_vadd);
477
      temp = 0;
478
    }
479 611 simons
  }
480
 
481 550 markom
  if (config.debug.enabled)
482 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
483 239 markom
  return temp;
484 66 lampret
}
485
 
486 1240 phoenix
unsigned char eval_direct8(unsigned long memaddr, int *breakpoint,
487
                           int through_mmu, int through_dc)
488
{
489
  unsigned char temp;
490
 
491
  if (memaddr & 3) {
492
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
493
    return 0;
494
  }
495
 
496
  cur_vadd = memaddr;
497
 
498
  if (through_mmu)
499
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
500
 
501
  if (through_dc)
502
    temp = (unsigned char)dc_simulate_read(memaddr, 1);
503
  else {
504
    temp = evalsim_mem8(memaddr);
505
    if (!cur_area) {
506
      PRINTF("EXCEPTION: read out of memory (8-bit access to %.8lx) in eval_direct8()\n", memaddr);
507
      except_handle(EXCEPT_BUSERR, cur_vadd);
508
      temp = 0;
509
    }
510
  }
511
}
512
 
513
 
514 66 lampret
void setsim_mem32(unsigned long memaddr, unsigned long value)
515
{
516 239 markom
  struct dev_memarea *dev;
517 66 lampret
 
518 239 markom
  if (verify_memoryarea(memaddr)) {
519
    switch(cur_area->granularity) {
520 538 markom
    case 4:
521
      cur_area->writefunc(memaddr, value);
522 884 markom
      runtime.sim.mem_cycles += cur_area->delayw;
523 538 markom
      break;
524 239 markom
    case 1:
525 251 erez
      cur_area->writefunc(memaddr    , (value >> 24) & 0xFF);
526 239 markom
      cur_area->writefunc(memaddr + 1, (value >> 16) & 0xFF);
527 251 erez
      cur_area->writefunc(memaddr + 2, (value >>  8) & 0xFF);
528
      cur_area->writefunc(memaddr + 3, (value      ) & 0xFF);
529 884 markom
      runtime.sim.mem_cycles += cur_area->delayw * 4;
530 239 markom
      break;
531
    case 2:
532
      cur_area->writefunc(memaddr, (value >> 16) & 0xFFFF);
533
      cur_area->writefunc(memaddr + 2, value & 0xFFFF);
534 884 markom
      runtime.sim.mem_cycles += cur_area->delayw * 2;
535 239 markom
      break;
536 242 markom
    }
537 239 markom
  } else {
538 997 markom
    PRINTF("EXCEPTION: write out of memory (32-bit access to %.8lx)\n", memaddr);
539 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
540 239 markom
  }
541 2 cvs
}
542
 
543 66 lampret
void setsim_mem16(unsigned long memaddr, unsigned short value)
544
{
545 538 markom
  unsigned long temp;
546 239 markom
  if (verify_memoryarea(memaddr)) {
547
    switch(cur_area->granularity) {
548
    case 1:
549
      cur_area->writefunc(memaddr, (value >> 8) & 0xFF);
550
      cur_area->writefunc(memaddr + 1, value & 0xFF);
551 884 markom
      runtime.sim.mem_cycles += cur_area->delayw * 2;
552 239 markom
      break;
553
    case 2:
554 251 erez
      cur_area->writefunc(memaddr, value & 0xFFFF);
555 884 markom
      runtime.sim.mem_cycles += cur_area->delayw;
556 239 markom
      break;
557
    case 4:
558 538 markom
      temp = evalsim_mem32 (memaddr & ~3ul);
559 546 simons
      temp &= 0xffff << ((memaddr & 2) ? 16 : 0);
560
      temp |= (unsigned long)(value & 0xffff) << ((memaddr & 2) ? 0 : 16);
561 538 markom
      setsim_mem32 (memaddr & ~3ul, temp);
562 239 markom
      break;
563
    }
564
  } else {
565 997 markom
    PRINTF("EXCEPTION: write out of memory (16-bit access to %.8lx)\n", memaddr);
566 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
567 239 markom
  }
568 2 cvs
}
569
 
570 66 lampret
void setsim_mem8(unsigned long memaddr, unsigned char value)
571
{
572 538 markom
  unsigned long temp;
573 239 markom
  if (verify_memoryarea(memaddr)) {
574 538 markom
    switch (cur_area->granularity) {
575
    case 1:
576 239 markom
      cur_area->writefunc(memaddr, value);
577 884 markom
      runtime.sim.mem_cycles += cur_area->delayw;
578 538 markom
      break;
579
    case 2:
580
      temp = evalsim_mem16 (memaddr & ~1ul);
581 546 simons
      temp &= 0xff << ((memaddr & 1) ? 8 : 0);
582
      temp |= (unsigned short)(value & 0xff) << ((memaddr & 1) ? 0 : 8);
583 538 markom
      setsim_mem16 (memaddr & ~1ul, temp);
584
      break;
585
    case 4:
586
      temp = evalsim_mem32 (memaddr & ~3ul);
587
      temp &= ~(0xff << (8 * (3 - (memaddr & 3))));
588
      temp |= (unsigned long)(value & 0xff) << (8 * (3 - (memaddr & 3)));
589
      setsim_mem32 (memaddr & ~3ul, temp);
590
      break;
591 239 markom
    }
592
  } else {
593 997 markom
    PRINTF("EXCEPTION: write out of memory (8-bit access to %.8lx)\n", memaddr);
594 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
595 239 markom
  }
596 2 cvs
}
597 30 lampret
 
598 587 markom
/* Set mem, 32-bit. Big endian version. */
599
 
600
void set_mem32(unsigned long memaddr, unsigned long value,int* breakpoint)
601
{
602
  if (config.sim.mprofile)
603
    mprofile (memaddr, MPROF_32 | MPROF_WRITE);
604
 
605
  if (memaddr & 3) {
606
    except_handle (EXCEPT_ALIGN, memaddr);
607
    return;
608
  }
609
 
610
  cur_vadd = memaddr;
611 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
612 587 markom
  /* If we produced exception don't set anything */
613
  if (pending.valid)
614
    return;
615
 
616
  if (config.debug.enabled) {
617
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
618
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
619
  }
620
 
621 992 simons
  dc_simulate_write(memaddr, value, 4);
622
 
623 1218 phoenix
  if (cur_area && cur_area->log)
624 587 markom
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
625
}
626
 
627 1240 phoenix
void set_direct32(unsigned long memaddr, unsigned long value,int* breakpoint,
628
                  int through_mmu, int through_dc)
629
{
630
 
631
  if (memaddr & 3) {
632
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
633
    return;
634
  }
635
 
636
  cur_vadd = memaddr;
637
 
638
  if (through_mmu) {
639
    /* 0 - no write access, we do not want a DPF exception do we ;)
640
     */
641
    memaddr = peek_into_dtlb(memaddr, 1, through_dc);
642
  }
643
 
644
 
645
  /* __PHX__ fixme: in principle we should write around the cache if
646
   *                through_dc is set, but i believe we this will work
647
   *                just fine anyway
648
   */
649
  dc_simulate_write(memaddr, value, 4);
650
 
651
  if (cur_area && cur_area->log)
652
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
653
}
654
 
655
 
656 587 markom
/* Set mem, 16-bit. Big endian version. */
657
 
658 1240 phoenix
void set_mem16(unsigned long memaddr, unsigned short value, int* breakpoint)
659 587 markom
{
660
  if (config.sim.mprofile)
661
    mprofile (memaddr, MPROF_16 | MPROF_WRITE);
662
 
663
  if (memaddr & 1) {
664
    except_handle (EXCEPT_ALIGN, memaddr);
665
    return;
666
  }
667
 
668
  cur_vadd = memaddr;
669 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
670 587 markom
  /* If we produced exception don't set anything */
671
  if (pending.valid)
672
    return;
673
 
674
  if (config.debug.enabled) {
675
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
676
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
677
  }
678
 
679 992 simons
  dc_simulate_write(memaddr, (unsigned long)value, 2);
680
 
681 1218 phoenix
  if (cur_area && cur_area->log)
682 587 markom
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
683
}
684
 
685 1240 phoenix
void set_direct16(unsigned long memaddr, unsigned short value, int* breakpoint,
686
                  int through_mmu, int through_dc)
687
{
688
 
689
  if (memaddr & 3) {
690
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
691
    return;
692
  }
693
 
694
  cur_vadd = memaddr;
695
 
696
  if (through_mmu) {
697
    /* 0 - no write access, we do not want a DPF exception do we ;)
698
     */
699
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
700
  }
701
 
702
  /* __PHX__ fixme: in principle we should write around the cache if
703
   *                through_dc is set, but i believe we this will work
704
   *                just fine anyway
705
   */
706
  dc_simulate_write(memaddr, value, 2);
707
 
708
  if (cur_area && cur_area->log)
709
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
710
}
711
 
712 587 markom
/* Set mem, 8-bit. */
713
 
714 1240 phoenix
void set_mem8(unsigned long memaddr, unsigned char value, int* breakpoint)
715 587 markom
{
716
  if (config.sim.mprofile)
717
    mprofile (memaddr, MPROF_8 | MPROF_WRITE);
718
 
719
  cur_vadd = memaddr;
720 631 simons
  memaddr = dmmu_translate(memaddr, 1);;
721 587 markom
  /* If we produced exception don't set anything */
722
  if (pending.valid) return;
723
 
724
  if (config.debug.enabled) {
725
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
726
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
727
  }
728
 
729 992 simons
  dc_simulate_write(memaddr, (unsigned long)value, 1);
730
 
731 1218 phoenix
  if (cur_area && cur_area->log)
732 587 markom
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
733
}
734
 
735 1240 phoenix
void set_direct8(unsigned long memaddr, unsigned char value, int* breakpoint,
736
                 int through_mmu, int through_dc)
737
{
738
 
739
  if (memaddr & 3) {
740
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
741
    return;
742
  }
743
 
744
  cur_vadd = memaddr;
745
 
746
  if (through_mmu) {
747
    /* 0 - no write access, we do not want a DPF exception do we ;)
748
     */
749
    memaddr = peek_into_dtlb(memaddr, 0, through_dc);
750
  }
751
 
752
  /* __PHX__ fixme: in principle we should write around the cache if
753
   *                through_dc is set, but i believe we this will work
754
   *                just fine anyway
755
   */
756
  dc_simulate_write(memaddr, value, 1);
757
 
758
  if (cur_area && cur_area->log)
759
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
760
}
761
 
762
 
763
 
764 361 markom
void dumpmemory(unsigned int from, unsigned int to, int disasm, int nl)
765
{
766
  unsigned int i, j;
767
  struct label_entry *tmp;
768
  int breakpoint = 0;
769
  int ilen = disasm ? 4 : 16;
770
 
771
  for(i = from; i < to; i += ilen) {
772 997 markom
    PRINTF("%.8x: ", i);
773 361 markom
    for (j = 0; j < ilen;) {
774
      int data = -1;
775
      if (!disasm) {
776
        tmp = NULL;
777
        if (verify_memoryarea(i+j)) {
778
          struct label_entry *entry;
779
          entry = get_label(i + j);
780
          if (entry)
781 997 markom
            PRINTF("(%s)", entry->name);
782
          PRINTF("%02x ", data = evalsim_mem8(i+j));
783
        } else PRINTF("XX ");
784 361 markom
        j++;
785
      } else {
786
        int breakpoint;
787
        unsigned int _insn = read_mem(i, &breakpoint);
788
        int index = insn_decode (_insn);
789
        int len = insn_len (index);
790
 
791
        tmp = NULL;
792
        if (verify_memoryarea(i+j)) {
793
          struct label_entry *entry;
794
          entry = get_label(i + j);
795
          if (entry)
796 997 markom
            PRINTF("(%s)", entry->name);
797 361 markom
 
798 997 markom
          PRINTF(": %08x ", (unsigned long)_insn);
799 361 markom
          if (index >= 0) {
800
            disassemble_insn (_insn);
801 997 markom
            PRINTF(" %s", disassembled);
802 361 markom
          } else
803 997 markom
            PRINTF("<invalid>");
804
        } else PRINTF("XXXXXXXX");
805 361 markom
        j += len;
806
      }
807
    }
808
    if (nl)
809 997 markom
      PRINTF ("\n");
810 361 markom
  }
811
}
812
 
813 538 markom
unsigned long simmem_read_word(unsigned long addr) {
814
  return simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2];
815 221 markom
}
816
 
817 538 markom
void simmem_write_word(unsigned long addr, unsigned long value) {
818
  simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2] = value;
819 221 markom
}
820
 
821 424 markom
unsigned long simmem_read_zero(unsigned long addr) {
822
  if (config.sim.verbose)
823
    fprintf (stderr, "WARNING: memory read from non-read memory area 0x%08x.\n", addr);
824
  return 0;
825
}
826
 
827
void simmem_write_null(unsigned long addr, unsigned long value) {
828
  if (config.sim.verbose)
829
    fprintf (stderr, "WARNING: memory write to 0x%08x, non-write memory area (value 0x%08x).\n", addr, value);
830
}
831
 
832
/* Initialize memory table from a config struct */
833
 
834
void init_memory_table ()
835 221 markom
{
836 239 markom
  unsigned long memory_needed = 0;
837 426 markom
 
838 424 markom
  /* If nothing was defined, use default memory block */
839
  if (config.memory.nmemories) {
840
    int i;
841
    for (i = 0; i < config.memory.nmemories; i++) {
842
      unsigned long start = config.memory.table[i].baseaddr;
843
      unsigned long length = config.memory.table[i].size;
844
      char *type = config.memory.table[i].name;
845
      int rd = config.memory.table[i].delayr;
846
      int wd = config.memory.table[i].delayw;
847
      int ce = config.memory.table[i].ce;
848
      if (config.sim.verbose)
849
        debug (1, "%08X %08X (%i KB): %s (activated by CE%i; read delay = %icyc, write delay = %icyc)\n",
850
          start, length, length >> 10, type, ce, rd, wd);
851 970 simons
      register_memoryarea(start, length, 4, 0, &simmem_read_word, &simmem_write_word);
852 239 markom
      cur_area->misc = memory_needed;
853 540 simons
      cur_area->chip_select = ce;
854 543 simons
      cur_area->valid = 1;
855 424 markom
      cur_area->delayw = wd;
856
      cur_area->delayr = rd;
857 426 markom
      if (config.memory.table[i].log[0] != '\0') {
858
        if ((cur_area->log = fopen (config.memory.table[i].log, "wt+")) == NULL)
859
          fprintf (stderr, "WARNING: Cannot open '%s'.\n", config.memory.table[i].log);
860
      } else
861 554 markom
        cur_area->log = NULL;
862 261 markom
      memory_needed += cur_area->size;
863 239 markom
    }
864 997 markom
    PRINTF ("\n");
865 239 markom
  } else {
866 308 markom
    if (config.sim.verbose)
867 424 markom
      fprintf (stderr, "WARNING: Memory not defined, assuming standard configuration.\n");
868 970 simons
    register_memoryarea(DEFAULT_MEMORY_START, DEFAULT_MEMORY_LEN, 4, 0, &simmem_read_word, &simmem_write_word);
869 554 markom
    cur_area->misc = memory_needed;
870
    cur_area->chip_select = 0;
871
    cur_area->valid = 1;
872
    cur_area->delayw = 1;
873
    cur_area->delayr = 1;
874
    cur_area->log = NULL;
875 261 markom
    memory_needed += cur_area->size;
876 239 markom
  }
877 424 markom
 
878 538 markom
  simmem32 = (unsigned long *) malloc (sizeof (unsigned long) * ((memory_needed + 3) / 4));
879
  if (!simmem32) {
880 239 markom
    fprintf (stderr, "Failed to allocate sim memory. Aborting\n");
881
    exit (-1);
882
  }
883 221 markom
}
884 424 markom
 
885
/* Changes read/write memory in read/write only */
886
 
887
void lock_memory_table ()
888
{
889
  struct dev_memarea *ptmp;
890
 
891
  /* Check list of registered devices. */
892
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
893 538 markom
    if (ptmp->delayr < 0 && ptmp->readfunc == &simmem_read_word)
894 424 markom
      ptmp->readfunc = &simmem_read_zero;
895 538 markom
    if (ptmp->delayw < 0 && ptmp->writefunc == &simmem_write_word)
896 424 markom
      ptmp->writefunc = &simmem_write_null;
897 543 simons
 
898
    /* If this mem area is not for memory chip under MC control
899
       then this area is valid all the time */
900
    if (ptmp->readfunc != &simmem_read_word) {
901
      ptmp->valid = 1;
902
      ptmp->chip_select = -1;
903
    }
904 424 markom
  }
905
}
906 426 markom
 
907
/* Closes files, etc. */
908
 
909
void done_memory_table ()
910
{
911
  struct dev_memarea *ptmp;
912
 
913
  /* Check list of registered devices. */
914
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
915
    if (ptmp->log)
916
      fclose (ptmp->log);
917
  }
918
}
919 427 markom
 
920
/* Displays current memory configuration */
921
 
922
void memory_table_status ()
923
{
924
  struct dev_memarea *ptmp;
925
 
926
  /* Check list of registered devices. */
927
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
928 997 markom
    PRINTF ("addr & %08x == %08x to %08x, size %08x, gran %iB\n",
929 427 markom
      ptmp->addr_mask, ptmp->addr_compare, ptmp->addr_compare | bit_mask (ptmp->size),
930
      ptmp->size, ptmp->granularity);
931 997 markom
    PRINTF ("\t");
932 427 markom
    if (ptmp->delayr >= 0)
933 997 markom
      PRINTF ("read delay = %i cycles, ", ptmp->delayr);
934 427 markom
    else
935 997 markom
      PRINTF ("reads not possible, ");
936 427 markom
 
937
    if (ptmp->delayw >= 0)
938 997 markom
      PRINTF ("write delay = %i cycles", ptmp->delayw);
939 427 markom
    else
940 997 markom
      PRINTF ("writes not possible");
941 427 markom
 
942
    if (ptmp->log)
943 997 markom
      PRINTF (", (logged)\n");
944 427 markom
    else
945 997 markom
      PRINTF ("\n");
946 427 markom
  }
947
}
948 433 markom
 
949
/* Outputs time in pretty form to dest string */
950
 
951 897 markom
char *generate_time_pretty (char *dest, long time_ps)
952 433 markom
{
953
  int exp3 = 0;
954
  if (time_ps) {
955
    while ((time_ps % 1000) == 0) {
956
      time_ps /= 1000;
957
      exp3++;
958
    }
959
  }
960
  sprintf (dest, "%i%cs", time_ps, "pnum"[exp3]);
961 897 markom
  return dest;
962 433 markom
}

powered by: WebSVN 2.1.0

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