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 572

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

powered by: WebSVN 2.1.0

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