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 538

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

powered by: WebSVN 2.1.0

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