OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [cpu/] [common/] [abstract.c] - Blame information for rev 1486

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 1486 nogj
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
4 2 cvs
 
5
This file is part of OpenRISC 1000 Architectural Simulator.
6
 
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
 
21 66 lampret
/* Abstract memory and routines that go with this. I need to
22 2 cvs
add all sorts of other abstract entities. Currently we have
23
only memory. */
24
 
25 221 markom
#include <stdlib.h>
26 2 cvs
#include <stdio.h>
27
#include <ctype.h>
28
#include <string.h>
29
 
30 6 lampret
#include "config.h"
31 1350 nogj
 
32
#ifdef HAVE_INTTYPES_H
33
#include <inttypes.h>
34
#endif
35
 
36
#include "port.h"
37 6 lampret
 
38 1350 nogj
#include "arch.h"
39 2 cvs
#include "parse.h"
40
#include "abstract.h"
41 1358 nogj
#include "sim-config.h"
42 261 markom
#include "labels.h"
43 32 lampret
#include "except.h"
44 123 markom
#include "debug_unit.h"
45 134 markom
#include "opcode/or32.h"
46 1432 nogj
#include "spr_defs.h"
47
#include "execute.h"
48
#include "sprs.h"
49 547 markom
#include "support/profile.h"
50 1308 phoenix
#include "dmmu.h"
51 1446 nogj
#include "immu.h"
52 1308 phoenix
#include "dcache_model.h"
53
#include "icache_model.h"
54
#include "debug.h"
55 1344 nogj
#include "stats.h"
56 2 cvs
 
57 1452 nogj
#if DYNAMIC_EXECUTION
58
#include "dyn_rec.h"
59
#endif
60
 
61 138 markom
extern char *disassembled;
62 2 cvs
 
63 30 lampret
/* Pointer to memory area descriptions that are assigned to individual
64
   peripheral devices. */
65
struct dev_memarea *dev_list;
66
 
67 221 markom
/* Temporary variable to increase speed.  */
68
struct dev_memarea *cur_area;
69
 
70 970 simons
/* Pointer to memory controller device descriptor.  */
71 1486 nogj
struct dev_memarea *mc_area = NULL;
72 970 simons
 
73 638 simons
/* These are set by mmu if cache inhibit bit is set for current acces.  */
74
int data_ci, insn_ci;
75
 
76 525 simons
/* Virtual address of current access. */
77 1486 nogj
static oraddr_t cur_vadd;
78 525 simons
 
79 1486 nogj
/* Read functions */
80
uint32_t eval_mem_32_inv(oraddr_t, void *);
81
uint16_t eval_mem_16_inv(oraddr_t, void *);
82
uint8_t eval_mem_8_inv(oraddr_t, void *);
83
uint32_t eval_mem_32_inv_direct(oraddr_t, void *);
84
uint16_t eval_mem_16_inv_direct(oraddr_t, void *);
85
uint8_t eval_mem_8_inv_direct(oraddr_t, void *);
86
 
87
/* Write functions */
88
void set_mem_32_inv(oraddr_t, uint32_t, void *);
89
void set_mem_16_inv(oraddr_t, uint16_t, void *);
90
void set_mem_8_inv(oraddr_t, uint8_t, void *);
91
void set_mem_32_inv_direct(oraddr_t, uint32_t, void *);
92
void set_mem_16_inv_direct(oraddr_t, uint16_t, void *);
93
void set_mem_8_inv_direct(oraddr_t, uint8_t, void *);
94
 
95 261 markom
/* Calculates bit mask to fit the data */
96 1486 nogj
static unsigned int bit_mask (uint32_t data) {
97 261 markom
  int i = 0;
98
  data--;
99 382 markom
  while (data >> i)
100 261 markom
    data |= 1 << i++;
101
  return data;
102
}
103
 
104
/* Register read and write function for a memory area.
105
   addr is inside the area, if addr & addr_mask == addr_compare
106
   (used also by peripheral devices like 16450 UART etc.) */
107 1486 nogj
struct dev_memarea *register_memoryarea_mask(oraddr_t addr_mask,
108
                                             oraddr_t addr_compare,
109
                                             uint32_t size, unsigned mc_dev)
110 30 lampret
{
111 239 markom
  struct dev_memarea **pptmp;
112 1350 nogj
  unsigned int size_mask = bit_mask (size);
113 261 markom
  int found_error = 0;
114
  addr_compare &= addr_mask;
115 221 markom
 
116 1486 nogj
  debug(5, "addr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR", size %08"PRIx32"\n",
117
        addr_mask, addr_compare, addr_compare | bit_mask (size), size);
118 239 markom
  /* Go to the end of the list. */
119 261 markom
  for(pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next)
120
    if ((addr_compare >= (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)
121
     || (addr_compare + size > (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)) {
122 262 markom
      if (!found_error) {
123 261 markom
        fprintf (stderr, "ERROR: Overlapping memory area(s):\n");
124 1350 nogj
        fprintf (stderr, "\taddr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR
125 1486 nogj
                         ", size %08"PRIx32"\n",
126
                 addr_mask, addr_compare, addr_compare | bit_mask (size), size);
127 262 markom
      }
128 261 markom
      found_error = 1;
129 1350 nogj
      fprintf (stderr, "and\taddr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR
130 1486 nogj
                       ", size %08"PRIx32"\n",
131 1308 phoenix
               (*pptmp)->addr_mask, (*pptmp)->addr_compare,
132 1486 nogj
               (*pptmp)->addr_compare | (*pptmp)->size_mask, (*pptmp)->size);
133 261 markom
    }
134
 
135
  if (found_error)
136
    exit (-1);
137 537 markom
 
138 239 markom
  cur_area = *pptmp = (struct dev_memarea *)malloc(sizeof(struct dev_memarea));
139 970 simons
 
140
  if (mc_dev)
141
    mc_area = *pptmp;
142
 
143 261 markom
  (*pptmp)->addr_mask = addr_mask;
144
  (*pptmp)->addr_compare = addr_compare;
145 239 markom
  (*pptmp)->size = size;
146 261 markom
  (*pptmp)->size_mask = size_mask;
147 1486 nogj
  (*pptmp)->log = NULL;
148
  (*pptmp)->valid = 1;
149 239 markom
  (*pptmp)->next = NULL;
150 1486 nogj
 
151
  return *pptmp;
152 261 markom
}
153 221 markom
 
154 261 markom
/* Register read and write function for a memory area.
155
   Memory areas should be aligned. Memory area is rounded up to
156
   fit the nearest 2^n aligment.
157 970 simons
   (used also by peripheral devices like 16450 UART etc.)
158 1486 nogj
   If mc_dev is 1, this device will be checked first for a match
159
   and will be accessed in case of overlaping memory areas.
160 970 simons
   Only one device can have this set to 1 (used for memory controller) */
161 1486 nogj
struct dev_memarea *reg_mem_area(oraddr_t addr, uint32_t size, unsigned mc_dev,
162
                                 struct mem_ops *ops)
163 261 markom
{
164 1350 nogj
  unsigned int size_mask = bit_mask (size);
165
  unsigned int addr_mask = ~size_mask;
166 1486 nogj
  struct dev_memarea *mem;
167
 
168
  mem = register_memoryarea_mask(addr_mask, addr & addr_mask, size_mask + 1,
169
                                 mc_dev);
170
 
171
  memcpy(&mem->ops, ops, sizeof(struct mem_ops));
172
  memcpy(&mem->direct_ops, ops, sizeof(struct mem_ops));
173
 
174
  if(!ops->readfunc32) {
175
    mem->ops.readfunc32 = eval_mem_32_inv;
176
    mem->direct_ops.readfunc32 = eval_mem_32_inv_direct;
177
    mem->direct_ops.read_dat32 = mem;
178
  }
179
  if(!ops->readfunc16) {
180
    mem->ops.readfunc16 = eval_mem_16_inv;
181
    mem->direct_ops.readfunc16 = eval_mem_16_inv_direct;
182
    mem->direct_ops.read_dat16 = mem;
183
  }
184
  if(!ops->readfunc8) {
185
    mem->ops.readfunc8 = eval_mem_8_inv;
186
    mem->direct_ops.readfunc8 = eval_mem_8_inv_direct;
187
    mem->direct_ops.read_dat8 = mem;
188
  }
189
 
190
  if(!ops->writefunc32) {
191
    mem->ops.writefunc32 = set_mem_32_inv;
192
    mem->direct_ops.writefunc32 = set_mem_32_inv_direct;
193
    mem->direct_ops.write_dat32 = mem;
194
  }
195
  if(!ops->writefunc16) {
196
    mem->ops.writefunc16 = set_mem_16_inv;
197
    mem->direct_ops.writefunc16 = set_mem_16_inv_direct;
198
    mem->direct_ops.write_dat16 = mem;
199
  }
200
  if(!ops->writefunc8) {
201
    mem->ops.writefunc8 = set_mem_8_inv;
202
    mem->direct_ops.writefunc8 = set_mem_8_inv_direct;
203
    mem->direct_ops.write_dat8 = mem;
204
  }
205
 
206
  if(!ops->writeprog) {
207
    mem->ops.writeprog = mem->ops.writefunc32;
208
    mem->ops.writeprog_dat = mem->ops.write_dat32;
209
  }
210
 
211
  if(ops->log) {
212
    if(!(mem->log = fopen(ops->log, "w")))
213
      PRINTF("ERR: Unable to open %s to log memory acesses to\n", ops->log);
214
  }
215
 
216
  return mem;
217 30 lampret
}
218
 
219
/* Check if access is to registered area of memory. */
220 1350 nogj
inline struct dev_memarea *verify_memoryarea(oraddr_t addr)
221 30 lampret
{
222 239 markom
  struct dev_memarea *ptmp;
223 221 markom
 
224 970 simons
  /* Check memory controller space first */
225
  if (mc_area && (addr & mc_area->addr_mask) == (mc_area->addr_compare & mc_area->addr_mask))
226
    return cur_area = mc_area;
227
 
228
  /* Check cached value */
229 560 markom
  if (cur_area && (addr & cur_area->addr_mask) == (cur_area->addr_compare & cur_area->addr_mask))
230
    return cur_area;
231
 
232
  /* When mc is enabled, we must check valid also, otherwise we assume it is nonzero */
233 1375 nogj
  /* Check list of registered devices. */
234
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next)
235
    if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask) && ptmp->valid)
236
      return cur_area = ptmp;
237 239 markom
  return cur_area = NULL;
238 30 lampret
}
239
 
240 1486 nogj
/* Sets the valid bit (Used only by memory controllers) */
241
void set_mem_valid(struct dev_memarea *mem, int valid)
242 882 simons
{
243 1486 nogj
  mem->valid = valid;
244 882 simons
}
245
 
246 1486 nogj
/* Adjusts the read and write delays for the memory area pointed to by mem. */
247
void adjust_rw_delay(struct dev_memarea *mem, int delayr, int delayw)
248 560 markom
{
249 1486 nogj
  mem->ops.delayr = delayr;
250
  mem->ops.delayw = delayw;
251 1319 phoenix
}
252 560 markom
 
253 1486 nogj
uint8_t eval_mem_8_inv(oraddr_t memaddr, void *dat)
254 1319 phoenix
{
255 1486 nogj
  except_handle(EXCEPT_BUSERR, cur_vadd);
256
  return 0;
257 1319 phoenix
}
258
 
259 1486 nogj
uint16_t eval_mem_16_inv(oraddr_t memaddr, void *dat)
260 1319 phoenix
{
261 1486 nogj
  except_handle(EXCEPT_BUSERR, cur_vadd);
262
  return 0;
263
}
264 1319 phoenix
 
265 1486 nogj
uint32_t eval_mem_32_inv(oraddr_t memaddr, void *dat)
266
{
267
  except_handle(EXCEPT_BUSERR, cur_vadd);
268
  return 0;
269 560 markom
}
270
 
271 1486 nogj
void set_mem_8_inv(oraddr_t memaddr, uint8_t val, void *dat)
272 560 markom
{
273 1486 nogj
  except_handle(EXCEPT_BUSERR, cur_vadd);
274 1319 phoenix
}
275 560 markom
 
276 1486 nogj
void set_mem_16_inv(oraddr_t memaddr, uint16_t val, void *dat)
277 1319 phoenix
{
278 1486 nogj
  except_handle(EXCEPT_BUSERR, cur_vadd);
279 1319 phoenix
}
280
 
281 1486 nogj
void set_mem_32_inv(oraddr_t memaddr, uint32_t val, void *dat)
282 1319 phoenix
{
283 1486 nogj
  except_handle(EXCEPT_BUSERR, cur_vadd);
284
}
285 1319 phoenix
 
286 1486 nogj
uint8_t eval_mem_8_inv_direct(oraddr_t memaddr, void *dat)
287
{
288
  struct dev_memarea *mem = dat;
289
 
290
  PRINTF("ERROR: Invalid 8-bit direct read from memory %"PRIxADDR"\n",
291
         mem->addr_compare | memaddr);
292
  return 0;
293 560 markom
}
294
 
295 1486 nogj
uint16_t eval_mem_16_inv_direct(oraddr_t memaddr, void *dat)
296 560 markom
{
297 1486 nogj
  struct dev_memarea *mem = dat;
298
 
299
  PRINTF("ERROR: Invalid 16-bit direct read from memory %"PRIxADDR"\n",
300
         mem->addr_compare | memaddr);
301
  return 0;
302 1319 phoenix
}
303 560 markom
 
304 1486 nogj
uint32_t eval_mem_32_inv_direct(oraddr_t memaddr, void *dat)
305 1319 phoenix
{
306 1486 nogj
  struct dev_memarea *mem = dat;
307
 
308
  PRINTF("ERROR: Invalid 32-bit direct read from memory %"PRIxADDR"\n",
309
         mem->addr_compare | memaddr);
310
  return 0;
311 1319 phoenix
}
312
 
313 1486 nogj
void set_mem_8_inv_direct(oraddr_t memaddr, uint8_t val, void *dat)
314 1319 phoenix
{
315 1486 nogj
  struct dev_memarea *mem = dat;
316 1319 phoenix
 
317 1486 nogj
  PRINTF("ERROR: Invalid 32-bit direct write to memory %"PRIxADDR"\n",
318
         mem->addr_compare | memaddr);
319
}
320
 
321
void set_mem_16_inv_direct(oraddr_t memaddr, uint16_t val, void *dat)
322
{
323
  struct dev_memarea *mem = dat;
324
 
325
  PRINTF("ERROR: Invalid 16-bit direct write to memory %"PRIxADDR"\n",
326
         mem->addr_compare | memaddr);
327
}
328
 
329
void set_mem_32_inv_direct(oraddr_t memaddr, uint32_t val, void *dat)
330
{
331
  struct dev_memarea *mem = dat;
332
 
333
  PRINTF("ERROR: Invalid 32-bit direct write to memory %"PRIxADDR"\n",
334
         mem->addr_compare | memaddr);
335
}
336
 
337
/* For cpu accesses
338
 *
339
 * NOTE: This function _is_ only called from eval_mem32 below and
340
 * {i,d}c_simulate_read.  _Don't_ call it from anywere else.
341
 */
342
inline uint32_t evalsim_mem32(oraddr_t memaddr, oraddr_t vaddr)
343
{
344
  struct dev_memarea *mem;
345
 
346
  if((mem = verify_memoryarea(memaddr))) {
347
    runtime.sim.mem_cycles += mem->ops.delayr;
348
    return mem->ops.readfunc32(memaddr & mem->size_mask, mem->ops.read_dat32);
349
  } else {
350
    PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR")\n",
351
           memaddr);
352
    except_handle(EXCEPT_BUSERR, vaddr);
353 560 markom
  }
354 1486 nogj
 
355
  return 0;
356 560 markom
}
357
 
358 1486 nogj
/* For cpu accesses
359
 *
360
 * NOTE: This function _is_ only called from eval_mem16 below and
361
 * {i,d}c_simulate_read.  _Don't_ call it from anywere else.
362
 */
363
inline uint16_t evalsim_mem16(oraddr_t memaddr, oraddr_t vaddr)
364
{
365
  struct dev_memarea *mem;
366
 
367
  if((mem = verify_memoryarea(memaddr))) {
368
    runtime.sim.mem_cycles += mem->ops.delayr;
369
    return mem->ops.readfunc16(memaddr & mem->size_mask, mem->ops.read_dat16);
370
  } else {
371
    PRINTF("EXCEPTION: read out of memory (16-bit access to %"PRIxADDR")\n",
372
           memaddr);
373
    except_handle(EXCEPT_BUSERR, vaddr);
374
  }
375
 
376
  return 0;
377
}
378
 
379
/* For cpu accesses
380
 *
381
 * NOTE: This function _is_ only called from eval_mem8 below and
382
 * {i,d}c_simulate_read.  _Don't_ call it from anywere else.
383
 */
384
inline uint8_t evalsim_mem8(oraddr_t memaddr, oraddr_t vaddr)
385
{
386
  struct dev_memarea *mem;
387
 
388
  if((mem = verify_memoryarea(memaddr))) {
389
    runtime.sim.mem_cycles += mem->ops.delayr;
390
    return mem->ops.readfunc8(memaddr & mem->size_mask, mem->ops.read_dat8);
391
  } else {
392
    PRINTF("EXCEPTION: read out of memory (8-bit access to %"PRIxADDR")\n",
393
           memaddr);
394
    except_handle(EXCEPT_BUSERR, vaddr);
395
  }
396
 
397
  return 0;
398
}
399
 
400 1319 phoenix
/* Returns 32-bit values from mem array. Big endian version.
401
 *
402
 * STATISTICS OK (only used for cpu_access, that is architectural access)
403
 */
404 1350 nogj
uint32_t eval_mem32(oraddr_t memaddr,int* breakpoint)
405 2 cvs
{
406 1350 nogj
  uint32_t temp;
407 1486 nogj
  oraddr_t phys_memaddr;
408 123 markom
 
409 547 markom
  if (config.sim.mprofile)
410
    mprofile (memaddr, MPROF_32 | MPROF_READ);
411
 
412 538 markom
  if (memaddr & 3) {
413
    except_handle (EXCEPT_ALIGN, memaddr);
414
    return 0;
415
  }
416 557 markom
 
417 631 simons
  if (config.debug.enabled)
418
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
419
 
420 1486 nogj
  phys_memaddr = dmmu_translate(memaddr, 0);
421 1386 nogj
  if (except_pending)
422 574 markom
    return 0;
423
 
424 992 simons
  if (config.dc.enabled)
425 1486 nogj
    temp = dc_simulate_read(phys_memaddr, memaddr, 4);
426
  else
427
    temp = evalsim_mem32(phys_memaddr, memaddr);
428 611 simons
 
429 550 markom
  if (config.debug.enabled)
430 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
431 1486 nogj
 
432 239 markom
  return temp;
433 66 lampret
}
434
 
435 1319 phoenix
/* for simulator accesses, the ones that cpu wouldn't do
436
 *
437
 * STATISTICS OK
438
 */
439 1350 nogj
uint32_t eval_direct32(oraddr_t memaddr, int *breakpoint, int through_mmu,
440
                       int through_dc)
441 1240 phoenix
{
442 1486 nogj
  oraddr_t phys_memaddr;
443
  struct dev_memarea *mem;
444 1240 phoenix
 
445
  if (memaddr & 3) {
446
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
447 1486 nogj
    return 0;
448 1240 phoenix
  }
449
 
450 1486 nogj
  phys_memaddr = memaddr;
451 1240 phoenix
 
452
  if (through_mmu)
453 1486 nogj
    phys_memaddr = peek_into_dtlb(memaddr, 0, through_dc);
454 1240 phoenix
 
455
  if (through_dc)
456 1486 nogj
    return dc_simulate_read(phys_memaddr, memaddr, 4);
457 1240 phoenix
  else {
458 1486 nogj
    if((mem = verify_memoryarea(phys_memaddr)))
459
      return mem->direct_ops.readfunc32(phys_memaddr & mem->size_mask,
460
                                        mem->direct_ops.read_dat32);
461
    else
462
      PRINTF("ERR: 32-bit read out of memory area: %"PRIxADDR" (physical: %"
463
             PRIxADDR"\n", memaddr, phys_memaddr);
464 1240 phoenix
  }
465
 
466 1486 nogj
  return 0;
467 1240 phoenix
}
468
 
469
 
470 1319 phoenix
/* Returns 32-bit values from mem array. Big endian version.
471
 *
472
 * STATISTICS OK (only used for cpu_access, that is architectural access)
473
 */
474 1386 nogj
uint32_t eval_insn(oraddr_t memaddr, int* breakpoint)
475 349 simons
{
476 1350 nogj
  uint32_t temp;
477 1486 nogj
  oraddr_t phys_memaddr;
478 349 simons
 
479 547 markom
  if (config.sim.mprofile)
480
    mprofile (memaddr, MPROF_32 | MPROF_FETCH);
481 532 markom
//  memaddr = simulate_ic_mmu_fetch(memaddr);
482 1244 hpanther
 
483 1486 nogj
  phys_memaddr = memaddr;
484 1452 nogj
#if !(DYNAMIC_EXECUTION)
485 1486 nogj
  phys_memaddr = immu_translate(memaddr);
486 1386 nogj
 
487
  if (except_pending)
488
    return 0;
489 1452 nogj
#endif
490 1386 nogj
 
491
  if (config.debug.enabled)
492
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr);
493
 
494 631 simons
  if (config.ic.enabled)
495 1486 nogj
    temp = ic_simulate_fetch(phys_memaddr, memaddr);
496
  else
497
    temp = evalsim_mem32(phys_memaddr, memaddr);
498 611 simons
 
499 1386 nogj
  if (config.debug.enabled)
500
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);
501 349 simons
  return temp;
502
}
503
 
504 1452 nogj
/* Returns 32-bit values from mem array. Big endian version.
505
 *
506
 * STATISTICS OK
507
 */
508
uint32_t eval_insn_direct(oraddr_t memaddr, int* breakpoint, int through_mmu)
509
{
510
  uint32_t temp;
511
  int brk;
512
 
513
  if(through_mmu)
514
    memaddr = peek_into_itlb(memaddr);
515
 
516
  if (config.debug.enabled)
517
    *breakpoint += CheckDebugUnit(DebugLoadAddress, memaddr);
518
 
519
  temp = eval_direct32(memaddr, &brk, 0, 0);
520
 
521
  if (config.debug.enabled)
522
    *breakpoint += CheckDebugUnit(DebugLoadData, temp);
523
 
524
  return temp;
525
}
526
 
527
 
528 1319 phoenix
/* Returns 16-bit values from mem array. Big endian version.
529
 *
530
 * STATISTICS OK (only used for cpu_access, that is architectural access)
531
 */
532 1350 nogj
uint16_t eval_mem16(oraddr_t memaddr,int* breakpoint)
533 2 cvs
{
534 1350 nogj
  uint16_t temp;
535 1486 nogj
  oraddr_t phys_memaddr;
536 547 markom
 
537
  if (config.sim.mprofile)
538
    mprofile (memaddr, MPROF_16 | MPROF_READ);
539
 
540 538 markom
  if (memaddr & 1) {
541
    except_handle (EXCEPT_ALIGN, memaddr);
542
    return 0;
543
  }
544 574 markom
 
545 631 simons
  if (config.debug.enabled)
546
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
547
 
548 1486 nogj
  phys_memaddr = dmmu_translate(memaddr, 0);
549 1386 nogj
  if (except_pending)
550 574 markom
    return 0;
551 66 lampret
 
552 992 simons
  if (config.dc.enabled)
553 1486 nogj
    temp = dc_simulate_read(phys_memaddr, memaddr, 2);
554
  else
555
    temp = evalsim_mem16(phys_memaddr, memaddr);
556 611 simons
 
557 550 markom
  if (config.debug.enabled)
558 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
559 1486 nogj
 
560 239 markom
  return temp;
561 66 lampret
}
562
 
563 1319 phoenix
/* for simulator accesses, the ones that cpu wouldn't do
564
 *
565
 * STATISTICS OK.
566
 */
567 1350 nogj
uint16_t eval_direct16(oraddr_t memaddr, int *breakpoint, int through_mmu,
568
                       int through_dc)
569 1240 phoenix
{
570 1486 nogj
  oraddr_t phys_memaddr;
571
  struct dev_memarea *mem;
572 1240 phoenix
 
573 1324 phoenix
  if (memaddr & 1) {
574 1240 phoenix
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
575 1486 nogj
    return 0;
576 1240 phoenix
  }
577
 
578 1486 nogj
  phys_memaddr = memaddr;
579 1240 phoenix
 
580
  if (through_mmu)
581 1486 nogj
    phys_memaddr = peek_into_dtlb(memaddr, 0, through_dc);
582 1240 phoenix
 
583
  if (through_dc)
584 1486 nogj
    return dc_simulate_read(phys_memaddr, memaddr, 2);
585 1240 phoenix
  else {
586 1486 nogj
    if((mem = verify_memoryarea(phys_memaddr)))
587
      return mem->direct_ops.readfunc16(phys_memaddr & mem->size_mask,
588
                                        mem->direct_ops.read_dat16);
589
    else
590
      PRINTF("ERR: 16-bit read out of memory area: %"PRIxADDR" (physical: %"
591
             PRIxADDR"\n", memaddr, phys_memaddr);
592 1240 phoenix
  }
593
 
594 1486 nogj
  return 0;
595 1240 phoenix
}
596
 
597 1319 phoenix
/* Returns 8-bit values from mem array.
598
 *
599
 * STATISTICS OK (only used for cpu_access, that is architectural access)
600
 */
601 1350 nogj
uint8_t eval_mem8(oraddr_t memaddr,int* breakpoint)
602 221 markom
{
603 1350 nogj
  uint8_t temp;
604 1486 nogj
  oraddr_t phys_memaddr;
605 547 markom
 
606
  if (config.sim.mprofile)
607
    mprofile (memaddr, MPROF_8 | MPROF_READ);
608
 
609 631 simons
  if (config.debug.enabled)
610
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr);  /* 28/05/01 CZ */
611
 
612 1486 nogj
  phys_memaddr = dmmu_translate(memaddr, 0);
613 1386 nogj
  if (except_pending)
614 458 simons
    return 0;
615 6 lampret
 
616 992 simons
  if (config.dc.enabled)
617 1486 nogj
    temp = dc_simulate_read(phys_memaddr, memaddr, 1);
618
  else
619
    temp = evalsim_mem8(phys_memaddr, memaddr);
620 611 simons
 
621 550 markom
  if (config.debug.enabled)
622 270 markom
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
623 239 markom
  return temp;
624 66 lampret
}
625
 
626 1319 phoenix
/* for simulator accesses, the ones that cpu wouldn't do
627
 *
628
 * STATISTICS OK.
629
 */
630 1350 nogj
uint8_t eval_direct8(oraddr_t memaddr, int *breakpoint, int through_mmu,
631
                     int through_dc)
632 1240 phoenix
{
633 1486 nogj
  oraddr_t phys_memaddr;
634
  struct dev_memarea *mem;
635 1240 phoenix
 
636 1486 nogj
  phys_memaddr = memaddr;
637 1240 phoenix
 
638
  if (through_mmu)
639 1486 nogj
    phys_memaddr = peek_into_dtlb(memaddr, 0, through_dc);
640 1240 phoenix
 
641
  if (through_dc)
642 1486 nogj
    return dc_simulate_read(phys_memaddr, memaddr, 1);
643 1240 phoenix
  else {
644 1486 nogj
    if((mem = verify_memoryarea(phys_memaddr)))
645
      return mem->direct_ops.readfunc8(phys_memaddr & mem->size_mask,
646
                                       mem->direct_ops.read_dat8);
647
    else
648
      PRINTF("ERR: 8-bit read out of memory area: %"PRIxADDR" (physical: %"
649
             PRIxADDR"\n", memaddr, phys_memaddr);
650 1240 phoenix
  }
651
 
652 1486 nogj
  return 0;
653 1319 phoenix
}
654 1240 phoenix
 
655 1486 nogj
/* For cpu accesses
656
 *
657
 * NOTE: This function _is_ only called from set_mem32 below and
658
 * dc_simulate_write.  _Don't_ call it from anywere else.
659
 */
660
inline void setsim_mem32(oraddr_t memaddr, oraddr_t vaddr, uint32_t value)
661 66 lampret
{
662 1486 nogj
  struct dev_memarea *mem;
663 1319 phoenix
 
664 1486 nogj
  if((mem = verify_memoryarea(memaddr))) {
665
    cur_vadd = vaddr;
666
    runtime.sim.mem_cycles += mem->ops.delayw;
667
    mem->ops.writefunc32(memaddr & mem->size_mask, value, mem->ops.write_dat32);
668 1452 nogj
#if DYNAMIC_EXECUTION
669 1486 nogj
    dyn_checkwrite(memaddr);
670 1452 nogj
#endif
671 239 markom
  } else {
672 1350 nogj
    PRINTF("EXCEPTION: write out of memory (32-bit access to %"PRIxADDR")\n",
673
           memaddr);
674 1486 nogj
    except_handle(EXCEPT_BUSERR, vaddr);
675 239 markom
  }
676 2 cvs
}
677
 
678 1486 nogj
/* For cpu accesses
679
 *
680
 * NOTE: This function _is_ only called from set_mem16 below and
681
 * dc_simulate_write.  _Don't_ call it from anywere else.
682
 */
683
inline void setsim_mem16(oraddr_t memaddr, oraddr_t vaddr, uint16_t value)
684 66 lampret
{
685 1486 nogj
  struct dev_memarea *mem;
686 1319 phoenix
 
687 1486 nogj
  if((mem = verify_memoryarea(memaddr))) {
688
    cur_vadd = vaddr;
689
    runtime.sim.mem_cycles += mem->ops.delayw;
690
    mem->ops.writefunc16(memaddr & mem->size_mask, value, mem->ops.write_dat16);
691 1452 nogj
#if DYNAMIC_EXECUTION
692 1486 nogj
    dyn_checkwrite(memaddr);
693 1452 nogj
#endif
694 239 markom
  } else {
695 1350 nogj
    PRINTF("EXCEPTION: write out of memory (16-bit access to %"PRIxADDR")\n",
696
           memaddr);
697 1486 nogj
    except_handle(EXCEPT_BUSERR, vaddr);
698 239 markom
  }
699 2 cvs
}
700
 
701 1486 nogj
/* For cpu accesses
702
 *
703
 * NOTE: This function _is_ only called from set_mem8 below and
704
 * dc_simulate_write.  _Don't_ call it from anywere else.
705
 */
706
inline void setsim_mem8(oraddr_t memaddr, oraddr_t vaddr, uint8_t value)
707 66 lampret
{
708 1486 nogj
  struct dev_memarea *mem;
709 1319 phoenix
 
710 1486 nogj
  if((mem = verify_memoryarea(memaddr))) {
711
    cur_vadd = vaddr;
712
    runtime.sim.mem_cycles += mem->ops.delayw;
713
    mem->ops.writefunc8(memaddr & mem->size_mask, value, mem->ops.write_dat8);
714 1452 nogj
#if DYNAMIC_EXECUTION
715 1486 nogj
    dyn_checkwrite(memaddr);
716 1452 nogj
#endif
717 239 markom
  } else {
718 1350 nogj
    PRINTF("EXCEPTION: write out of memory (8-bit access to %"PRIxADDR")\n",
719
           memaddr);
720 1486 nogj
    except_handle(EXCEPT_BUSERR, vaddr);
721 239 markom
  }
722 2 cvs
}
723 30 lampret
 
724 1319 phoenix
/* Set mem, 32-bit. Big endian version.
725
 *
726 1446 nogj
 * STATISTICS OK. (the only suspicious usage is in sim-cmd.c,
727 1319 phoenix
 *                 where this instruction is used for patching memory,
728
 *                 wether this is cpu or architectual access is yet to
729
 *                 be decided)
730
 */
731 1350 nogj
void set_mem32(oraddr_t memaddr, uint32_t value, int* breakpoint)
732 587 markom
{
733 1486 nogj
  oraddr_t phys_memaddr;
734
 
735 587 markom
  if (config.sim.mprofile)
736
    mprofile (memaddr, MPROF_32 | MPROF_WRITE);
737
 
738
  if (memaddr & 3) {
739
    except_handle (EXCEPT_ALIGN, memaddr);
740
    return;
741
  }
742
 
743 1486 nogj
  phys_memaddr = dmmu_translate(memaddr, 1);;
744 587 markom
  /* If we produced exception don't set anything */
745 1386 nogj
  if (except_pending)
746 587 markom
    return;
747
 
748
  if (config.debug.enabled) {
749
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
750
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
751
  }
752
 
753 1486 nogj
  if(config.dc.enabled)
754
    dc_simulate_write(phys_memaddr, memaddr, value, 4);
755
  else
756
    setsim_mem32(phys_memaddr, memaddr, value);
757 992 simons
 
758 1218 phoenix
  if (cur_area && cur_area->log)
759 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> write %08"PRIx32"\n", memaddr,
760
             value);
761 587 markom
}
762
 
763 1319 phoenix
/*
764
 * STATISTICS NOT OK.
765
 */
766 1350 nogj
void set_direct32(oraddr_t memaddr, uint32_t value,int* breakpoint,
767 1240 phoenix
                  int through_mmu, int through_dc)
768
{
769 1486 nogj
  oraddr_t phys_memaddr;
770
  struct dev_memarea *mem;
771 1240 phoenix
 
772
  if (memaddr & 3) {
773
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
774
    return;
775
  }
776
 
777 1486 nogj
  phys_memaddr = memaddr;
778 1240 phoenix
 
779
  if (through_mmu) {
780
    /* 0 - no write access, we do not want a DPF exception do we ;)
781
     */
782 1486 nogj
    phys_memaddr = peek_into_dtlb(memaddr, 1, through_dc);
783 1240 phoenix
  }
784
 
785 1486 nogj
  if(through_dc)
786
    dc_simulate_write(memaddr, memaddr, value, 4);
787
  else {
788
    if((mem = verify_memoryarea(phys_memaddr)))
789
      mem->direct_ops.writefunc32(phys_memaddr & mem->size_mask, value,
790
                                  mem->direct_ops.write_dat32);
791
    else
792
      PRINTF("ERR: 32-bit write out of memory area: %"PRIxADDR" (physical: %"
793
             PRIxADDR")\n", memaddr, phys_memaddr);
794
  }
795 1240 phoenix
 
796
  if (cur_area && cur_area->log)
797 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %08"PRIx32"\n",
798
             memaddr, value);
799 1240 phoenix
}
800
 
801
 
802 587 markom
/* Set mem, 16-bit. Big endian version. */
803
 
804 1350 nogj
void set_mem16(oraddr_t memaddr, uint16_t value, int* breakpoint)
805 587 markom
{
806 1486 nogj
  oraddr_t phys_memaddr;
807
 
808 587 markom
  if (config.sim.mprofile)
809
    mprofile (memaddr, MPROF_16 | MPROF_WRITE);
810
 
811
  if (memaddr & 1) {
812
    except_handle (EXCEPT_ALIGN, memaddr);
813
    return;
814
  }
815
 
816 1486 nogj
  phys_memaddr = dmmu_translate(memaddr, 1);;
817 587 markom
  /* If we produced exception don't set anything */
818 1386 nogj
  if (except_pending)
819 587 markom
    return;
820
 
821
  if (config.debug.enabled) {
822
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
823
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
824
  }
825
 
826 1486 nogj
  if(config.dc.enabled)
827
    dc_simulate_write(phys_memaddr, memaddr, value, 2);
828
  else
829
    setsim_mem16(phys_memaddr, memaddr, value);
830 992 simons
 
831 1218 phoenix
  if (cur_area && cur_area->log)
832 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> write %04"PRIx16"\n", memaddr,
833
             value);
834 587 markom
}
835
 
836 1319 phoenix
/*
837
 * STATISTICS NOT OK.
838
 */
839 1350 nogj
void set_direct16(oraddr_t memaddr, uint16_t value, int* breakpoint,
840 1240 phoenix
                  int through_mmu, int through_dc)
841
{
842 1486 nogj
  oraddr_t phys_memaddr;
843
  struct dev_memarea *mem;
844 1240 phoenix
 
845 1324 phoenix
  if (memaddr & 1) {
846 1240 phoenix
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
847
    return;
848
  }
849
 
850 1486 nogj
  phys_memaddr = memaddr;
851 1240 phoenix
 
852
  if (through_mmu) {
853
    /* 0 - no write access, we do not want a DPF exception do we ;)
854
     */
855 1486 nogj
    phys_memaddr = peek_into_dtlb(memaddr, 0, through_dc);
856 1240 phoenix
  }
857
 
858 1486 nogj
  if(through_dc)
859
    dc_simulate_write(memaddr, memaddr, value, 2);
860
  else {
861
    if((mem = verify_memoryarea(phys_memaddr)))
862
      mem->direct_ops.writefunc16(phys_memaddr & mem->size_mask, value,
863
                                  mem->direct_ops.write_dat16);
864
    else
865
      PRINTF("ERR: 16-bit write out of memory area: %"PRIxADDR" (physical: %"
866
             PRIxADDR"\n", memaddr, phys_memaddr);
867
  }
868 1240 phoenix
 
869
  if (cur_area && cur_area->log)
870 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %04"PRIx16"\n",
871
             memaddr, value);
872 1240 phoenix
}
873
 
874 587 markom
/* Set mem, 8-bit. */
875 1350 nogj
void set_mem8(oraddr_t memaddr, uint8_t value, int* breakpoint)
876 587 markom
{
877 1486 nogj
  oraddr_t phys_memaddr;
878
 
879 587 markom
  if (config.sim.mprofile)
880
    mprofile (memaddr, MPROF_8 | MPROF_WRITE);
881
 
882 1486 nogj
  phys_memaddr = memaddr;
883
 
884
  phys_memaddr = dmmu_translate(memaddr, 1);;
885 587 markom
  /* If we produced exception don't set anything */
886 1386 nogj
  if (except_pending) return;
887 587 markom
 
888
  if (config.debug.enabled) {
889
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
890
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
891
  }
892
 
893 1486 nogj
  if(config.dc.enabled)
894
    dc_simulate_write(phys_memaddr, memaddr, value, 1);
895
  else
896
    setsim_mem8(phys_memaddr, memaddr, value);
897 992 simons
 
898 1218 phoenix
  if (cur_area && cur_area->log)
899 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> write %02"PRIx8"\n", memaddr,
900
             value);
901 587 markom
}
902
 
903 1319 phoenix
/*
904
 * STATISTICS NOT OK.
905
 */
906 1350 nogj
void set_direct8(oraddr_t memaddr, uint8_t value, int* breakpoint,
907 1240 phoenix
                 int through_mmu, int through_dc)
908
{
909 1486 nogj
  oraddr_t phys_memaddr;
910
  struct dev_memarea *mem;
911 1240 phoenix
 
912 1486 nogj
  phys_memaddr = memaddr;
913 1240 phoenix
 
914
  if (through_mmu) {
915
    /* 0 - no write access, we do not want a DPF exception do we ;)
916
     */
917 1486 nogj
    phys_memaddr = peek_into_dtlb(memaddr, 0, through_dc);
918 1240 phoenix
  }
919
 
920 1486 nogj
  if(through_dc)
921
    dc_simulate_write(phys_memaddr, memaddr, value, 1);
922
  else {
923
    if((mem = verify_memoryarea(phys_memaddr)))
924
      mem->direct_ops.writefunc8(phys_memaddr & mem->size_mask, value,
925
                                 mem->direct_ops.write_dat8);
926
    else
927
      PRINTF("ERR: 8-bit write out of memory area: %"PRIxADDR" (physical: %"
928
             PRIxADDR"\n", memaddr, phys_memaddr);
929
  }
930 1240 phoenix
 
931
  if (cur_area && cur_area->log)
932 1350 nogj
    fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %02"PRIx8"\n",
933
             memaddr, value);
934 1240 phoenix
}
935
 
936
 
937 1486 nogj
/* set_program32 - same as set_direct32, but it also writes to memory that is
938
 *                 non-writeable to the rest of the sim.  Used to do program
939
 *                 loading.
940
 */
941
void set_program32(oraddr_t memaddr, uint32_t value)
942
{
943
  struct dev_memarea *mem;
944
 
945
  if (memaddr & 3) {
946
    PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
947
    return;
948
  }
949
 
950
  if((mem = verify_memoryarea(memaddr))) {
951
    mem->ops.writeprog(memaddr & mem->size_mask, value, mem->ops.writeprog_dat);
952
  } else
953
    PRINTF("ERR: 32-bit program load out of memory area: %"PRIxADDR"\n",
954
           memaddr);
955
}
956
 
957 1350 nogj
void dumpmemory(oraddr_t from, oraddr_t to, int disasm, int nl)
958 361 markom
{
959 1350 nogj
  oraddr_t i, j;
960 361 markom
  struct label_entry *tmp;
961
  int ilen = disasm ? 4 : 16;
962 1484 nogj
  int breakpoint;
963 361 markom
 
964
  for(i = from; i < to; i += ilen) {
965 1350 nogj
    PRINTF("%"PRIxADDR": ", i);
966 361 markom
    for (j = 0; j < ilen;) {
967
      if (!disasm) {
968
        tmp = NULL;
969 1350 nogj
        if (verify_memoryarea(i + j)) {
970 361 markom
          struct label_entry *entry;
971
          entry = get_label(i + j);
972
          if (entry)
973 997 markom
            PRINTF("(%s)", entry->name);
974 1484 nogj
          PRINTF("%02"PRIx8" ", eval_direct8(i + j, &breakpoint, 0, 0));
975 997 markom
        } else PRINTF("XX ");
976 361 markom
        j++;
977
      } else {
978 1484 nogj
        uint32_t _insn = eval_direct32(i, &breakpoint, 0, 0);
979 361 markom
        int index = insn_decode (_insn);
980
        int len = insn_len (index);
981
 
982
        tmp = NULL;
983 1350 nogj
        if (verify_memoryarea(i + j)) {
984 361 markom
          struct label_entry *entry;
985
          entry = get_label(i + j);
986
          if (entry)
987 997 markom
            PRINTF("(%s)", entry->name);
988 361 markom
 
989 1350 nogj
          PRINTF(": %08"PRIx32" ", _insn);
990 361 markom
          if (index >= 0) {
991
            disassemble_insn (_insn);
992 997 markom
            PRINTF(" %s", disassembled);
993 361 markom
          } else
994 997 markom
            PRINTF("<invalid>");
995
        } else PRINTF("XXXXXXXX");
996 361 markom
        j += len;
997
      }
998
    }
999
    if (nl)
1000 997 markom
      PRINTF ("\n");
1001 361 markom
  }
1002
}
1003
 
1004 426 markom
/* Closes files, etc. */
1005
 
1006 1486 nogj
void done_memory_table (void)
1007 426 markom
{
1008
  struct dev_memarea *ptmp;
1009
 
1010
  /* Check list of registered devices. */
1011
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
1012
    if (ptmp->log)
1013
      fclose (ptmp->log);
1014
  }
1015
}
1016 427 markom
 
1017
/* Displays current memory configuration */
1018
 
1019 1486 nogj
void memory_table_status (void)
1020 427 markom
{
1021
  struct dev_memarea *ptmp;
1022
 
1023
  /* Check list of registered devices. */
1024
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
1025 1486 nogj
    PRINTF ("addr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR", size %"PRIx32"\n",
1026 427 markom
      ptmp->addr_mask, ptmp->addr_compare, ptmp->addr_compare | bit_mask (ptmp->size),
1027 1486 nogj
      ptmp->size);
1028 997 markom
    PRINTF ("\t");
1029 1486 nogj
    if (ptmp->ops.delayr >= 0)
1030
      PRINTF ("read delay = %i cycles, ", ptmp->ops.delayr);
1031 427 markom
    else
1032 997 markom
      PRINTF ("reads not possible, ");
1033 427 markom
 
1034 1486 nogj
    if (ptmp->ops.delayw >= 0)
1035
      PRINTF ("write delay = %i cycles", ptmp->ops.delayw);
1036 427 markom
    else
1037 997 markom
      PRINTF ("writes not possible");
1038 427 markom
 
1039
    if (ptmp->log)
1040 997 markom
      PRINTF (", (logged)\n");
1041 427 markom
    else
1042 997 markom
      PRINTF ("\n");
1043 427 markom
  }
1044
}
1045 433 markom
 
1046
/* Outputs time in pretty form to dest string */
1047
 
1048 897 markom
char *generate_time_pretty (char *dest, long time_ps)
1049 433 markom
{
1050
  int exp3 = 0;
1051
  if (time_ps) {
1052
    while ((time_ps % 1000) == 0) {
1053
      time_ps /= 1000;
1054
      exp3++;
1055
    }
1056
  }
1057 1308 phoenix
  sprintf (dest, "%li%cs", time_ps, "pnum"[exp3]);
1058 897 markom
  return dest;
1059 433 markom
}

powered by: WebSVN 2.1.0

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