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 550

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

powered by: WebSVN 2.1.0

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