OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [or1ksim/] [cpu/] [common/] [abstract.c] - Blame information for rev 30

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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