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 587

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
  } else {
273
    printf("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
274
    except_handle(EXCEPT_BUSERR, cur_vadd);
275
    temp = 0;
276
  }
277
  return temp;
278
}
279
 
280
unsigned short evalsim_mem16(unsigned long memaddr)
281
{
282
  unsigned long temp;
283
 
284
  if (verify_memoryarea(memaddr)) {
285
    switch(cur_area->granularity) {
286
    case 1:
287
      temp = cur_area->readfunc(memaddr) << 8;
288
      temp |= cur_area->readfunc(memaddr + 1);
289
      mem_cycles += cur_area->delayr * 2;
290
      break;
291
    case 2:
292
      temp = cur_area->readfunc(memaddr);
293
      mem_cycles += cur_area->delayr;
294
      break;
295
    case 4:
296
      temp = evalsim_mem32 (memaddr & ~3ul);
297
      if (memaddr & 2)
298
        temp &= 0xffff;
299
      else
300
        temp >>= 16;
301
      break;
302
    }
303
  } else {
304
    printf("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr);
305
    except_handle(EXCEPT_BUSERR, cur_vadd);
306
    temp = 0;
307
  }
308
  return temp;
309
}
310
 
311
unsigned char evalsim_mem8(unsigned long memaddr)
312
{
313
  unsigned long temp;
314
 
315
  if (verify_memoryarea(memaddr)) {
316
    switch(cur_area->granularity) {
317
    case 1:
318
      temp = cur_area->readfunc(memaddr);
319
      mem_cycles += cur_area->delayr;
320
      break;
321
    case 2:
322
      temp = evalsim_mem16 (memaddr & ~1ul);
323
      if (memaddr & 1)
324
        temp &= 0xff;
325
      else
326
        temp >>= 8;
327
      break;
328
    case 4:
329
      temp = evalsim_mem32 (memaddr & ~3ul);
330
      temp >>= 8 * (3 - (memaddr & 3));
331
      temp &= 0xff;
332
      break;
333
    }
334
  } else {
335
    printf("EXCEPTION: read out of memory (8-bit access to %.8lx)\n", memaddr);
336
    except_handle(EXCEPT_BUSERR, cur_vadd);
337
    temp = 0;
338
  }
339
  return temp;
340
}
341
 
342 2 cvs
/* Returns 32-bit values from mem array. Big endian version. */
343 349 simons
unsigned long read_mem(unsigned long memaddr,int* breakpoint)
344
{
345
  unsigned long temp;
346
  struct dev_memarea *dev;
347
 
348 525 simons
  cur_vadd = memaddr;
349 550 markom
  if (config.debug.enabled)
350 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
351
  temp = evalsim_mem32(memaddr);
352 587 markom
  if (cur_area->log)
353
    fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
354 550 markom
  if (config.debug.enabled)
355 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
356
  return temp;
357 537 markom
}
358 349 simons
 
359
/* Returns 32-bit values from mem array. Big endian version. */
360 123 markom
unsigned long eval_mem32(unsigned long memaddr,int* breakpoint)
361 2 cvs
{
362 6 lampret
 
363 239 markom
  unsigned long temp;
364
  struct dev_memarea *dev;
365 123 markom
 
366 547 markom
  if (config.sim.mprofile)
367
    mprofile (memaddr, MPROF_32 | MPROF_READ);
368
 
369 538 markom
  if (memaddr & 3) {
370
    except_handle (EXCEPT_ALIGN, memaddr);
371
    return 0;
372
  }
373 557 markom
 
374 574 markom
  cur_vadd = memaddr;
375
  memaddr = simulate_dc_mmu_load(memaddr);
376
  if (pending.valid)
377
    return 0;
378
 
379 550 markom
  if (config.debug.enabled)
380 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
381 239 markom
  temp = evalsim_mem32(memaddr);
382 587 markom
  if (cur_area->log)
383
    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 587 markom
  if (cur_area->log)
404
    fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
405 550 markom
  if (config.debug.enabled)
406 349 simons
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
407
  return temp;
408
}
409
 
410 2 cvs
/* Returns 16-bit values from mem array. Big endian version. */
411
 
412 123 markom
unsigned short eval_mem16(unsigned long memaddr,int* breakpoint)
413 2 cvs
{
414 239 markom
  unsigned short temp;
415 547 markom
 
416
  if (config.sim.mprofile)
417
    mprofile (memaddr, MPROF_16 | MPROF_READ);
418
 
419 538 markom
  if (memaddr & 1) {
420
    except_handle (EXCEPT_ALIGN, memaddr);
421
    return 0;
422
  }
423 574 markom
 
424
  cur_vadd = memaddr;
425
  memaddr = simulate_dc_mmu_load(memaddr);
426
  if (pending.valid)
427
    return 0;
428
 
429 550 markom
  if (config.debug.enabled)
430 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
431 66 lampret
 
432 239 markom
  temp = evalsim_mem16(memaddr);
433 587 markom
  if (cur_area->log)
434
    fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
435 550 markom
  if (config.debug.enabled)
436 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
437 239 markom
  return temp;
438 66 lampret
}
439
 
440 6 lampret
/* Returns 8-bit values from mem array. */
441 2 cvs
 
442 123 markom
unsigned char eval_mem8(unsigned long memaddr,int* breakpoint)
443 221 markom
{
444 538 markom
  unsigned long temp;
445 547 markom
 
446
  if (config.sim.mprofile)
447
    mprofile (memaddr, MPROF_8 | MPROF_READ);
448
 
449 525 simons
  cur_vadd = memaddr;
450 574 markom
  memaddr = simulate_dc_mmu_load(memaddr);
451 458 simons
  if (pending.valid)
452
    return 0;
453 574 markom
 
454 550 markom
  if (config.debug.enabled)
455 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr);  /* 28/05/01 CZ */
456 6 lampret
 
457 239 markom
  temp = evalsim_mem8(memaddr);
458 587 markom
  if (cur_area->log)
459
    fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
460 550 markom
  if (config.debug.enabled)
461 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
462 239 markom
  return temp;
463 66 lampret
}
464
 
465
void setsim_mem32(unsigned long memaddr, unsigned long value)
466
{
467 239 markom
  struct dev_memarea *dev;
468 66 lampret
 
469 239 markom
  if (verify_memoryarea(memaddr)) {
470
    switch(cur_area->granularity) {
471 538 markom
    case 4:
472
      cur_area->writefunc(memaddr, value);
473
      mem_cycles += cur_area->delayw;
474
      break;
475 239 markom
    case 1:
476 251 erez
      cur_area->writefunc(memaddr    , (value >> 24) & 0xFF);
477 239 markom
      cur_area->writefunc(memaddr + 1, (value >> 16) & 0xFF);
478 251 erez
      cur_area->writefunc(memaddr + 2, (value >>  8) & 0xFF);
479
      cur_area->writefunc(memaddr + 3, (value      ) & 0xFF);
480 537 markom
      mem_cycles += cur_area->delayw * 4;
481 239 markom
      break;
482
    case 2:
483
      cur_area->writefunc(memaddr, (value >> 16) & 0xFFFF);
484
      cur_area->writefunc(memaddr + 2, value & 0xFFFF);
485 537 markom
      mem_cycles += cur_area->delayw * 2;
486 239 markom
      break;
487 242 markom
    }
488 239 markom
  } else {
489
    printf("EXCEPTION: write out of memory (32-bit access to %.8lx)\n", memaddr);
490 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
491 239 markom
  }
492 2 cvs
}
493
 
494 66 lampret
void setsim_mem16(unsigned long memaddr, unsigned short value)
495
{
496 538 markom
  unsigned long temp;
497 239 markom
  if (verify_memoryarea(memaddr)) {
498
    switch(cur_area->granularity) {
499
    case 1:
500
      cur_area->writefunc(memaddr, (value >> 8) & 0xFF);
501
      cur_area->writefunc(memaddr + 1, value & 0xFF);
502 537 markom
      mem_cycles += cur_area->delayw * 2;
503 239 markom
      break;
504
    case 2:
505 251 erez
      cur_area->writefunc(memaddr, value & 0xFFFF);
506 537 markom
      mem_cycles += cur_area->delayw;
507 239 markom
      break;
508
    case 4:
509 538 markom
      temp = evalsim_mem32 (memaddr & ~3ul);
510 546 simons
      temp &= 0xffff << ((memaddr & 2) ? 16 : 0);
511
      temp |= (unsigned long)(value & 0xffff) << ((memaddr & 2) ? 0 : 16);
512 538 markom
      setsim_mem32 (memaddr & ~3ul, temp);
513 239 markom
      break;
514
    }
515
  } else {
516
    printf("EXCEPTION: write out of memory (16-bit access to %.8lx)\n", memaddr);
517 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
518 239 markom
  }
519 2 cvs
}
520
 
521 66 lampret
void setsim_mem8(unsigned long memaddr, unsigned char value)
522
{
523 538 markom
  unsigned long temp;
524 239 markom
  if (verify_memoryarea(memaddr)) {
525 538 markom
    switch (cur_area->granularity) {
526
    case 1:
527 239 markom
      cur_area->writefunc(memaddr, value);
528 537 markom
      mem_cycles += cur_area->delayw;
529 538 markom
      break;
530
    case 2:
531
      temp = evalsim_mem16 (memaddr & ~1ul);
532 546 simons
      temp &= 0xff << ((memaddr & 1) ? 8 : 0);
533
      temp |= (unsigned short)(value & 0xff) << ((memaddr & 1) ? 0 : 8);
534 538 markom
      setsim_mem16 (memaddr & ~1ul, temp);
535
      break;
536
    case 4:
537
      temp = evalsim_mem32 (memaddr & ~3ul);
538
      temp &= ~(0xff << (8 * (3 - (memaddr & 3))));
539
      temp |= (unsigned long)(value & 0xff) << (8 * (3 - (memaddr & 3)));
540
      setsim_mem32 (memaddr & ~3ul, temp);
541
      break;
542 239 markom
    }
543
  } else {
544
    printf("EXCEPTION: write out of memory (8-bit access to %.8lx)\n", memaddr);
545 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
546 239 markom
  }
547 2 cvs
}
548 30 lampret
 
549 587 markom
/* Set mem, 32-bit. Big endian version. */
550
 
551
void set_mem32(unsigned long memaddr, unsigned long value,int* breakpoint)
552
{
553
  if (config.sim.mprofile)
554
    mprofile (memaddr, MPROF_32 | MPROF_WRITE);
555
 
556
  if (memaddr & 3) {
557
    except_handle (EXCEPT_ALIGN, memaddr);
558
    return;
559
  }
560
 
561
  cur_vadd = memaddr;
562
  memaddr = simulate_dc_mmu_store(memaddr);
563
  /* If we produced exception don't set anything */
564
  if (pending.valid)
565
    return;
566
 
567
  if (config.debug.enabled) {
568
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
569
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
570
  }
571
 
572
  if (cur_area->log)
573
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
574
 
575
  setsim_mem32(memaddr, value);
576
}
577
 
578
/* Set mem, 16-bit. Big endian version. */
579
 
580
void set_mem16(unsigned long memaddr, unsigned short value,int* breakpoint)
581
{
582
  if (config.sim.mprofile)
583
    mprofile (memaddr, MPROF_16 | MPROF_WRITE);
584
 
585
  if (memaddr & 1) {
586
    except_handle (EXCEPT_ALIGN, memaddr);
587
    return;
588
  }
589
 
590
  cur_vadd = memaddr;
591
  memaddr = simulate_dc_mmu_store(memaddr);
592
  /* If we produced exception don't set anything */
593
  if (pending.valid)
594
    return;
595
 
596
  if (config.debug.enabled) {
597
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
598
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
599
  }
600
 
601
  if (cur_area->log)
602
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
603
 
604
  setsim_mem16(memaddr, value);
605
}
606
 
607
/* Set mem, 8-bit. */
608
 
609
void set_mem8(unsigned long memaddr, unsigned char value,int* breakpoint)
610
{
611
  if (config.sim.mprofile)
612
    mprofile (memaddr, MPROF_8 | MPROF_WRITE);
613
 
614
  cur_vadd = memaddr;
615
  memaddr = simulate_dc_mmu_store(memaddr);
616
  /* If we produced exception don't set anything */
617
  if (pending.valid) return;
618
 
619
  if (config.debug.enabled) {
620
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
621
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
622
  }
623
 
624
  if (cur_area->log)
625
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
626
 
627
  setsim_mem8(memaddr, value);
628
}
629
 
630 361 markom
void dumpmemory(unsigned int from, unsigned int to, int disasm, int nl)
631
{
632
  unsigned int i, j;
633
  struct label_entry *tmp;
634
  int breakpoint = 0;
635
  int ilen = disasm ? 4 : 16;
636
 
637
  for(i = from; i < to; i += ilen) {
638
    printf("%.8x: ", i);
639
    for (j = 0; j < ilen;) {
640
      int data = -1;
641
      if (!disasm) {
642
        tmp = NULL;
643
        if (verify_memoryarea(i+j)) {
644
          struct label_entry *entry;
645
          entry = get_label(i + j);
646
          if (entry)
647
            printf("(%s)", entry->name);
648
          printf("%02x ", data = evalsim_mem8(i+j));
649
        } else printf("XX ");
650
        j++;
651
      } else {
652
        int breakpoint;
653
        unsigned int _insn = read_mem(i, &breakpoint);
654
        int index = insn_decode (_insn);
655
        int len = insn_len (index);
656
 
657
        tmp = NULL;
658
        if (verify_memoryarea(i+j)) {
659
          struct label_entry *entry;
660
          entry = get_label(i + j);
661
          if (entry)
662
            printf("(%s)", entry->name);
663
 
664
          printf(": %08x ", (unsigned long)_insn);
665
          if (index >= 0) {
666
            disassemble_insn (_insn);
667
            printf(" %s", disassembled);
668
          } else
669
            printf("<invalid>");
670
        } else printf("XXXXXXXX");
671
        j += len;
672
      }
673
    }
674
    if (nl)
675
      printf ("\n");
676
  }
677
}
678
 
679 538 markom
unsigned long simmem_read_word(unsigned long addr) {
680
  return simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2];
681 221 markom
}
682
 
683 538 markom
void simmem_write_word(unsigned long addr, unsigned long value) {
684
  simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2] = value;
685 221 markom
}
686
 
687 424 markom
unsigned long simmem_read_zero(unsigned long addr) {
688
  if (config.sim.verbose)
689
    fprintf (stderr, "WARNING: memory read from non-read memory area 0x%08x.\n", addr);
690
  return 0;
691
}
692
 
693
void simmem_write_null(unsigned long addr, unsigned long value) {
694
  if (config.sim.verbose)
695
    fprintf (stderr, "WARNING: memory write to 0x%08x, non-write memory area (value 0x%08x).\n", addr, value);
696
}
697
 
698
/* Initialize memory table from a config struct */
699
 
700
void init_memory_table ()
701 221 markom
{
702 239 markom
  unsigned long memory_needed = 0;
703 426 markom
 
704 424 markom
  /* If nothing was defined, use default memory block */
705
  if (config.memory.nmemories) {
706
    int i;
707
    for (i = 0; i < config.memory.nmemories; i++) {
708
      unsigned long start = config.memory.table[i].baseaddr;
709
      unsigned long length = config.memory.table[i].size;
710
      char *type = config.memory.table[i].name;
711
      int rd = config.memory.table[i].delayr;
712
      int wd = config.memory.table[i].delayw;
713
      int ce = config.memory.table[i].ce;
714
      if (config.sim.verbose)
715
        debug (1, "%08X %08X (%i KB): %s (activated by CE%i; read delay = %icyc, write delay = %icyc)\n",
716
          start, length, length >> 10, type, ce, rd, wd);
717 538 markom
      register_memoryarea(start, length, 4, &simmem_read_word, &simmem_write_word);
718 239 markom
      cur_area->misc = memory_needed;
719 540 simons
      cur_area->chip_select = ce;
720 543 simons
      cur_area->valid = 1;
721 424 markom
      cur_area->delayw = wd;
722
      cur_area->delayr = rd;
723 426 markom
      if (config.memory.table[i].log[0] != '\0') {
724
        if ((cur_area->log = fopen (config.memory.table[i].log, "wt+")) == NULL)
725
          fprintf (stderr, "WARNING: Cannot open '%s'.\n", config.memory.table[i].log);
726
      } else
727 554 markom
        cur_area->log = NULL;
728 261 markom
      memory_needed += cur_area->size;
729 239 markom
    }
730
    printf ("\n");
731
  } else {
732 308 markom
    if (config.sim.verbose)
733 424 markom
      fprintf (stderr, "WARNING: Memory not defined, assuming standard configuration.\n");
734 538 markom
    register_memoryarea(DEFAULT_MEMORY_START, DEFAULT_MEMORY_LEN, 4, &simmem_read_word, &simmem_write_word);
735 554 markom
    cur_area->misc = memory_needed;
736
    cur_area->chip_select = 0;
737
    cur_area->valid = 1;
738
    cur_area->delayw = 1;
739
    cur_area->delayr = 1;
740
    cur_area->log = NULL;
741 261 markom
    memory_needed += cur_area->size;
742 239 markom
  }
743 424 markom
 
744 538 markom
  simmem32 = (unsigned long *) malloc (sizeof (unsigned long) * ((memory_needed + 3) / 4));
745
  if (!simmem32) {
746 239 markom
    fprintf (stderr, "Failed to allocate sim memory. Aborting\n");
747
    exit (-1);
748
  }
749 221 markom
}
750 424 markom
 
751
/* Changes read/write memory in read/write only */
752
 
753
void lock_memory_table ()
754
{
755
  struct dev_memarea *ptmp;
756
 
757
  /* Check list of registered devices. */
758
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
759 538 markom
    if (ptmp->delayr < 0 && ptmp->readfunc == &simmem_read_word)
760 424 markom
      ptmp->readfunc = &simmem_read_zero;
761 538 markom
    if (ptmp->delayw < 0 && ptmp->writefunc == &simmem_write_word)
762 424 markom
      ptmp->writefunc = &simmem_write_null;
763 543 simons
 
764
    /* If this mem area is not for memory chip under MC control
765
       then this area is valid all the time */
766
    if (ptmp->readfunc != &simmem_read_word) {
767
      ptmp->valid = 1;
768
      ptmp->chip_select = -1;
769
    }
770 424 markom
  }
771
}
772 426 markom
 
773
/* Closes files, etc. */
774
 
775
void done_memory_table ()
776
{
777
  struct dev_memarea *ptmp;
778
 
779
  /* Check list of registered devices. */
780
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
781
    if (ptmp->log)
782
      fclose (ptmp->log);
783
  }
784
}
785 427 markom
 
786
/* Displays current memory configuration */
787
 
788
void memory_table_status ()
789
{
790
  struct dev_memarea *ptmp;
791
 
792
  /* Check list of registered devices. */
793
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
794
    printf ("addr & %08x == %08x to %08x, size %08x, gran %iB\n",
795
      ptmp->addr_mask, ptmp->addr_compare, ptmp->addr_compare | bit_mask (ptmp->size),
796
      ptmp->size, ptmp->granularity);
797
    printf ("\t");
798
    if (ptmp->delayr >= 0)
799
      printf ("read delay = %i cycles, ", ptmp->delayr);
800
    else
801
      printf ("reads not possible, ");
802
 
803
    if (ptmp->delayw >= 0)
804
      printf ("write delay = %i cycles", ptmp->delayw);
805
    else
806
      printf ("writes not possible");
807
 
808
    if (ptmp->log)
809
      printf (", (logged)\n");
810
    else
811
      printf ("\n");
812
  }
813
}
814 433 markom
 
815
/* Outputs time in pretty form to dest string */
816
 
817
void generate_time_pretty (char *dest, long time_ps)
818
{
819
  int exp3 = 0;
820
  if (time_ps) {
821
    while ((time_ps % 1000) == 0) {
822
      time_ps /= 1000;
823
      exp3++;
824
    }
825
  }
826
  sprintf (dest, "%i%cs", time_ps, "pnum"[exp3]);
827
}

powered by: WebSVN 2.1.0

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