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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_42/] [or1ksim/] [cpu/] [common/] [abstract.c] - Blame information for rev 611

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

powered by: WebSVN 2.1.0

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