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 542

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
      temp &= ~(0xff << (8 * (3 - (memaddr & 3))));
582
      temp |= (unsigned long)(value & 0xff) << (8 * (3 - (memaddr & 3)));
583
      setsim_mem32 (memaddr & ~3ul, temp);
584
      break;
585 239 markom
    }
586
  } else {
587
    printf("EXCEPTION: write out of memory (8-bit access to %.8lx)\n", memaddr);
588 525 simons
    except_handle(EXCEPT_BUSERR, cur_vadd);
589 239 markom
  }
590 2 cvs
}
591 30 lampret
 
592 361 markom
void dumpmemory(unsigned int from, unsigned int to, int disasm, int nl)
593
{
594
  unsigned int i, j;
595
  struct label_entry *tmp;
596
  int breakpoint = 0;
597
  int ilen = disasm ? 4 : 16;
598
 
599
  for(i = from; i < to; i += ilen) {
600
    printf("%.8x: ", i);
601
    for (j = 0; j < ilen;) {
602
      int data = -1;
603
      if (!disasm) {
604
        tmp = NULL;
605
        if (verify_memoryarea(i+j)) {
606
          struct label_entry *entry;
607
          entry = get_label(i + j);
608
          if (entry)
609
            printf("(%s)", entry->name);
610
          printf("%02x ", data = evalsim_mem8(i+j));
611
        } else printf("XX ");
612
        j++;
613
      } else {
614
        int breakpoint;
615
        unsigned int _insn = read_mem(i, &breakpoint);
616
        int index = insn_decode (_insn);
617
        int len = insn_len (index);
618
 
619
        tmp = NULL;
620
        if (verify_memoryarea(i+j)) {
621
          struct label_entry *entry;
622
          entry = get_label(i + j);
623
          if (entry)
624
            printf("(%s)", entry->name);
625
 
626
          printf(": %08x ", (unsigned long)_insn);
627
          if (index >= 0) {
628
            disassemble_insn (_insn);
629
            printf(" %s", disassembled);
630
          } else
631
            printf("<invalid>");
632
        } else printf("XXXXXXXX");
633
        j += len;
634
      }
635
    }
636
    if (nl)
637
      printf ("\n");
638
  }
639
}
640
 
641 538 markom
unsigned long simmem_read_word(unsigned long addr) {
642
  return simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2];
643 221 markom
}
644
 
645 538 markom
void simmem_write_word(unsigned long addr, unsigned long value) {
646
  simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2] = value;
647 221 markom
}
648
 
649 424 markom
unsigned long simmem_read_zero(unsigned long addr) {
650
  if (config.sim.verbose)
651
    fprintf (stderr, "WARNING: memory read from non-read memory area 0x%08x.\n", addr);
652
  return 0;
653
}
654
 
655
void simmem_write_null(unsigned long addr, unsigned long value) {
656
  if (config.sim.verbose)
657
    fprintf (stderr, "WARNING: memory write to 0x%08x, non-write memory area (value 0x%08x).\n", addr, value);
658
}
659
 
660
/* Initialize memory table from a config struct */
661
 
662
void init_memory_table ()
663 221 markom
{
664 239 markom
  unsigned long memory_needed = 0;
665 426 markom
 
666 424 markom
  /* If nothing was defined, use default memory block */
667
  if (config.memory.nmemories) {
668
    int i;
669
    for (i = 0; i < config.memory.nmemories; i++) {
670
      unsigned long start = config.memory.table[i].baseaddr;
671
      unsigned long length = config.memory.table[i].size;
672
      char *type = config.memory.table[i].name;
673
      int rd = config.memory.table[i].delayr;
674
      int wd = config.memory.table[i].delayw;
675
      int ce = config.memory.table[i].ce;
676
      if (config.sim.verbose)
677
        debug (1, "%08X %08X (%i KB): %s (activated by CE%i; read delay = %icyc, write delay = %icyc)\n",
678
          start, length, length >> 10, type, ce, rd, wd);
679 538 markom
      register_memoryarea(start, length, 4, &simmem_read_word, &simmem_write_word);
680 239 markom
      cur_area->misc = memory_needed;
681 540 simons
      cur_area->chip_select = ce;
682 424 markom
      cur_area->delayw = wd;
683
      cur_area->delayr = rd;
684 426 markom
      if (config.memory.table[i].log[0] != '\0') {
685
        if ((cur_area->log = fopen (config.memory.table[i].log, "wt+")) == NULL)
686
          fprintf (stderr, "WARNING: Cannot open '%s'.\n", config.memory.table[i].log);
687
      } else
688
        cur_area->log = 0;
689 261 markom
      memory_needed += cur_area->size;
690 239 markom
    }
691
    printf ("\n");
692
  } else {
693 308 markom
    if (config.sim.verbose)
694 424 markom
      fprintf (stderr, "WARNING: Memory not defined, assuming standard configuration.\n");
695 538 markom
    register_memoryarea(DEFAULT_MEMORY_START, DEFAULT_MEMORY_LEN, 4, &simmem_read_word, &simmem_write_word);
696 261 markom
    memory_needed += cur_area->size;
697 239 markom
  }
698 424 markom
 
699 538 markom
  simmem32 = (unsigned long *) malloc (sizeof (unsigned long) * ((memory_needed + 3) / 4));
700
  if (!simmem32) {
701 239 markom
    fprintf (stderr, "Failed to allocate sim memory. Aborting\n");
702
    exit (-1);
703
  }
704 221 markom
}
705 424 markom
 
706
/* Changes read/write memory in read/write only */
707
 
708
void lock_memory_table ()
709
{
710
  struct dev_memarea *ptmp;
711
 
712
  /* Check list of registered devices. */
713
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
714 538 markom
    if (ptmp->delayr < 0 && ptmp->readfunc == &simmem_read_word)
715 424 markom
      ptmp->readfunc = &simmem_read_zero;
716 538 markom
    if (ptmp->delayw < 0 && ptmp->writefunc == &simmem_write_word)
717 424 markom
      ptmp->writefunc = &simmem_write_null;
718
  }
719
}
720 426 markom
 
721
/* Closes files, etc. */
722
 
723
void done_memory_table ()
724
{
725
  struct dev_memarea *ptmp;
726
 
727
  /* Check list of registered devices. */
728
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
729
    if (ptmp->log)
730
      fclose (ptmp->log);
731
  }
732
}
733 427 markom
 
734
/* Displays current memory configuration */
735
 
736
void memory_table_status ()
737
{
738
  struct dev_memarea *ptmp;
739
 
740
  /* Check list of registered devices. */
741
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
742
    printf ("addr & %08x == %08x to %08x, size %08x, gran %iB\n",
743
      ptmp->addr_mask, ptmp->addr_compare, ptmp->addr_compare | bit_mask (ptmp->size),
744
      ptmp->size, ptmp->granularity);
745
    printf ("\t");
746
    if (ptmp->delayr >= 0)
747
      printf ("read delay = %i cycles, ", ptmp->delayr);
748
    else
749
      printf ("reads not possible, ");
750
 
751
    if (ptmp->delayw >= 0)
752
      printf ("write delay = %i cycles", ptmp->delayw);
753
    else
754
      printf ("writes not possible");
755
 
756
    if (ptmp->log)
757
      printf (", (logged)\n");
758
    else
759
      printf ("\n");
760
  }
761
}
762 433 markom
 
763
/* Outputs time in pretty form to dest string */
764
 
765
void generate_time_pretty (char *dest, long time_ps)
766
{
767
  int exp3 = 0;
768
  if (time_ps) {
769
    while ((time_ps % 1000) == 0) {
770
      time_ps /= 1000;
771
      exp3++;
772
    }
773
  }
774
  sprintf (dest, "%i%cs", time_ps, "pnum"[exp3]);
775
}

powered by: WebSVN 2.1.0

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