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 574

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

powered by: WebSVN 2.1.0

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