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

Subversion Repositories openrisc_me

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

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 98 jeremybenn
    {
247
      return cur_area = mc_area;
248
    }
249 19 jeremybenn
 
250
  /* Check cached value */
251
  if (cur_area
252
      && (addr & cur_area->addr_mask) ==
253
      (cur_area->addr_compare & cur_area->addr_mask))
254 98 jeremybenn
    {
255
      return cur_area;
256
    }
257 19 jeremybenn
 
258
  /* When mc is enabled, we must check valid also, otherwise we assume it is
259
     nonzero */
260
  /* Check list of registered devices. */
261
  for (ptmp = dev_list; ptmp; ptmp = ptmp->next)
262 98 jeremybenn
    {
263
      if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask)
264
          && ptmp->valid)
265
        {
266
          return cur_area = ptmp;
267
        }
268
    }
269
 
270 19 jeremybenn
  return cur_area = NULL;
271
}
272
 
273
/* Sets the valid bit (Used only by memory controllers) */
274
void
275
set_mem_valid (struct dev_memarea *mem, int valid)
276
{
277
  mem->valid = valid;
278
}
279
 
280
/* Adjusts the read and write delays for the memory area pointed to by mem. */
281
void
282
adjust_rw_delay (struct dev_memarea *mem, int delayr, int delayw)
283
{
284
  mem->ops.delayr = delayr;
285
  mem->ops.delayw = delayw;
286
}
287
 
288
static uint8_t
289
eval_mem_8_inv (oraddr_t memaddr, void *dat)
290
{
291
  except_handle (EXCEPT_BUSERR, cur_vadd);
292
  return 0;
293
}
294
 
295
static uint16_t
296
eval_mem_16_inv (oraddr_t memaddr, void *dat)
297
{
298
  except_handle (EXCEPT_BUSERR, cur_vadd);
299
  return 0;
300
}
301
 
302
static uint32_t
303
eval_mem_32_inv (oraddr_t memaddr, void *dat)
304
{
305
  except_handle (EXCEPT_BUSERR, cur_vadd);
306
  return 0;
307
}
308
 
309
static void
310
set_mem_8_inv (oraddr_t memaddr, uint8_t val, void *dat)
311
{
312
  except_handle (EXCEPT_BUSERR, cur_vadd);
313
}
314
 
315
static void
316
set_mem_16_inv (oraddr_t memaddr, uint16_t val, void *dat)
317
{
318
  except_handle (EXCEPT_BUSERR, cur_vadd);
319
}
320
 
321
static void
322
set_mem_32_inv (oraddr_t memaddr, uint32_t val, void *dat)
323
{
324
  except_handle (EXCEPT_BUSERR, cur_vadd);
325
}
326
 
327
uint8_t
328
eval_mem_8_inv_direct (oraddr_t memaddr, void *dat)
329
{
330
  struct dev_memarea *mem = dat;
331
 
332
  PRINTF ("ERROR: Invalid 8-bit direct read from memory %" PRIxADDR "\n",
333
          mem->addr_compare | memaddr);
334
  return 0;
335
}
336
 
337
uint16_t
338
eval_mem_16_inv_direct (oraddr_t memaddr, void *dat)
339
{
340
  struct dev_memarea *mem = dat;
341
 
342
  PRINTF ("ERROR: Invalid 16-bit direct read from memory %" PRIxADDR "\n",
343
          mem->addr_compare | memaddr);
344
  return 0;
345
}
346
 
347
uint32_t
348
eval_mem_32_inv_direct (oraddr_t memaddr, void *dat)
349
{
350
  struct dev_memarea *mem = dat;
351
 
352
  PRINTF ("ERROR: Invalid 32-bit direct read from memory %" PRIxADDR "\n",
353
          mem->addr_compare | memaddr);
354
  return 0;
355
}
356
 
357
void
358
set_mem_8_inv_direct (oraddr_t memaddr, uint8_t val, void *dat)
359
{
360
  struct dev_memarea *mem = dat;
361
 
362
  PRINTF ("ERROR: Invalid 32-bit direct write to memory %" PRIxADDR "\n",
363
          mem->addr_compare | memaddr);
364
}
365
 
366
void
367
set_mem_16_inv_direct (oraddr_t memaddr, uint16_t val, void *dat)
368
{
369
  struct dev_memarea *mem = dat;
370
 
371
  PRINTF ("ERROR: Invalid 16-bit direct write to memory %" PRIxADDR "\n",
372
          mem->addr_compare | memaddr);
373
}
374
 
375
void
376
set_mem_32_inv_direct (oraddr_t memaddr, uint32_t val, void *dat)
377
{
378
  struct dev_memarea *mem = dat;
379
 
380
  PRINTF ("ERROR: Invalid 32-bit direct write to memory %" PRIxADDR "\n",
381
          mem->addr_compare | memaddr);
382
}
383
 
384
/* For cpu accesses
385
 *
386
 * NOTE: This function _is_ only called from eval_mem32 below and
387
 * {i,d}c_simulate_read.  _Don't_ call it from anywere else.
388
 */
389
uint32_t
390
evalsim_mem32 (oraddr_t memaddr, oraddr_t vaddr)
391
{
392
  struct dev_memarea *mem;
393
 
394
  if ((mem = verify_memoryarea (memaddr)))
395
    {
396
      runtime.sim.mem_cycles += mem->ops.delayr;
397
      return mem->ops.readfunc32 (memaddr & mem->size_mask,
398
                                  mem->ops.read_dat32);
399
    }
400
  else
401
    {
402
      PRINTF ("EXCEPTION: read out of memory (32-bit access to %" PRIxADDR
403
              ")\n", memaddr);
404
      except_handle (EXCEPT_BUSERR, vaddr);
405
    }
406
 
407
  return 0;
408
}
409
 
410
/* For cpu accesses
411
 *
412
 * NOTE: This function _is_ only called from eval_mem16 below and
413
 * {i,d}c_simulate_read.  _Don't_ call it from anywere else.
414
 */
415
uint16_t
416
evalsim_mem16 (oraddr_t memaddr, oraddr_t vaddr)
417
{
418
  struct dev_memarea *mem;
419
 
420
  if ((mem = verify_memoryarea (memaddr)))
421
    {
422
      runtime.sim.mem_cycles += mem->ops.delayr;
423
      return mem->ops.readfunc16 (memaddr & mem->size_mask,
424
                                  mem->ops.read_dat16);
425
    }
426
  else
427
    {
428
      PRINTF ("EXCEPTION: read out of memory (16-bit access to %" PRIxADDR
429
              ")\n", memaddr);
430
      except_handle (EXCEPT_BUSERR, vaddr);
431
    }
432
 
433
  return 0;
434
}
435
 
436
/* For cpu accesses
437
 *
438
 * NOTE: This function _is_ only called from eval_mem8 below and
439
 * {i,d}c_simulate_read.  _Don't_ call it from anywere else.
440
 */
441
uint8_t
442
evalsim_mem8 (oraddr_t memaddr, oraddr_t vaddr)
443
{
444
  struct dev_memarea *mem;
445
 
446
  if ((mem = verify_memoryarea (memaddr)))
447
    {
448
      runtime.sim.mem_cycles += mem->ops.delayr;
449
      return mem->ops.readfunc8 (memaddr & mem->size_mask,
450
                                 mem->ops.read_dat8);
451
    }
452
  else
453
    {
454
      PRINTF ("EXCEPTION: read out of memory (8-bit access to %" PRIxADDR
455
              ")\n", memaddr);
456
      except_handle (EXCEPT_BUSERR, vaddr);
457
    }
458
 
459
  return 0;
460
}
461
 
462
/* Returns 32-bit values from mem array. Big endian version.
463
 *
464
 * STATISTICS OK (only used for cpu_access, that is architectural access)
465
 */
466
uint32_t
467
eval_mem32 (oraddr_t memaddr, int *breakpoint)
468
{
469
  uint32_t temp;
470
  oraddr_t phys_memaddr;
471
 
472
  if (config.sim.mprofile)
473
    mprofile (memaddr, MPROF_32 | MPROF_READ);
474
 
475
  if (memaddr & 3)
476
    {
477
      except_handle (EXCEPT_ALIGN, memaddr);
478
      return 0;
479
    }
480
 
481
  if (config.debug.enabled)
482
    *breakpoint += check_debug_unit (DebugLoadAddress, memaddr);        /* 28/05/01 CZ */
483
 
484
  phys_memaddr = dmmu_translate (memaddr, 0);
485
  if (except_pending)
486
    return 0;
487
 
488
  if (config.dc.enabled)
489
    temp = dc_simulate_read (phys_memaddr, memaddr, 4);
490
  else
491
    temp = evalsim_mem32 (phys_memaddr, memaddr);
492
 
493
  if (config.debug.enabled)
494
    *breakpoint += check_debug_unit (DebugLoadData, temp);      /* MM170901 */
495
 
496
  return temp;
497
}
498
 
499
/* for simulator accesses, the ones that cpu wouldn't do
500
 *
501
 * STATISTICS OK
502
 */
503
uint32_t
504
eval_direct32 (oraddr_t memaddr, int through_mmu, int through_dc)
505
{
506
  oraddr_t phys_memaddr;
507
  struct dev_memarea *mem;
508
 
509
  if (memaddr & 3)
510
    {
511
      PRINTF ("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__,
512
              __FUNCTION__);
513
      return 0;
514
    }
515
 
516
  phys_memaddr = memaddr;
517
 
518
  if (through_mmu)
519
    phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc);
520
 
521
  if (through_dc)
522
    return dc_simulate_read (phys_memaddr, memaddr, 4);
523
  else
524
    {
525
      if ((mem = verify_memoryarea (phys_memaddr)))
526
        return mem->direct_ops.readfunc32 (phys_memaddr & mem->size_mask,
527
                                           mem->direct_ops.read_dat32);
528
      else
529
        PRINTF ("ERR: 32-bit read out of memory area: %" PRIxADDR
530
                " (physical: %" PRIxADDR ")\n", memaddr, phys_memaddr);
531
    }
532
 
533
  return 0;
534
}
535
 
536
 
537
/* Returns 32-bit values from mem array. Big endian version.
538
 *
539
 * STATISTICS OK (only used for cpu_access, that is architectural access)
540
 */
541
uint32_t
542
eval_insn (oraddr_t memaddr, int *breakpoint)
543
{
544
  uint32_t temp;
545
  oraddr_t phys_memaddr;
546
 
547
  if (config.sim.mprofile)
548
    mprofile (memaddr, MPROF_32 | MPROF_FETCH);
549
 
550
  phys_memaddr = memaddr;
551
#if !(DYNAMIC_EXECUTION)
552
  phys_memaddr = immu_translate (memaddr);
553
 
554
  if (except_pending)
555
    return 0;
556
#endif
557
 
558
  if (config.debug.enabled)
559
    *breakpoint += check_debug_unit (DebugInstructionFetch, memaddr);
560
 
561
  if ((NULL != ic_state) && ic_state->enabled)
562
    temp = ic_simulate_fetch (phys_memaddr, memaddr);
563
  else
564
    temp = evalsim_mem32 (phys_memaddr, memaddr);
565
 
566
  if (config.debug.enabled)
567
    *breakpoint += check_debug_unit (DebugLoadData, temp);
568
  return temp;
569
}
570
 
571
/* Returns 16-bit values from mem array. Big endian version.
572
 *
573
 * STATISTICS OK (only used for cpu_access, that is architectural access)
574
 */
575
uint16_t
576
eval_mem16 (oraddr_t memaddr, int *breakpoint)
577
{
578
  uint16_t temp;
579
  oraddr_t phys_memaddr;
580
 
581
  if (config.sim.mprofile)
582
    mprofile (memaddr, MPROF_16 | MPROF_READ);
583
 
584
  if (memaddr & 1)
585
    {
586
      except_handle (EXCEPT_ALIGN, memaddr);
587
      return 0;
588
    }
589
 
590
  if (config.debug.enabled)
591
    *breakpoint += check_debug_unit (DebugLoadAddress, memaddr);        /* 28/05/01 CZ */
592
 
593
  phys_memaddr = dmmu_translate (memaddr, 0);
594
  if (except_pending)
595
    return 0;
596
 
597
  if (config.dc.enabled)
598
    temp = dc_simulate_read (phys_memaddr, memaddr, 2);
599
  else
600
    temp = evalsim_mem16 (phys_memaddr, memaddr);
601
 
602
  if (config.debug.enabled)
603
    *breakpoint += check_debug_unit (DebugLoadData, temp);      /* MM170901 */
604
 
605
  return temp;
606
}
607
 
608
/* for simulator accesses, the ones that cpu wouldn't do
609
 *
610
 * STATISTICS OK.
611
 */
612
uint16_t
613
eval_direct16 (oraddr_t memaddr, int through_mmu, int through_dc)
614
{
615
  oraddr_t phys_memaddr;
616
  struct dev_memarea *mem;
617
 
618
  if (memaddr & 1)
619
    {
620
      PRINTF ("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__,
621
              __FUNCTION__);
622
      return 0;
623
    }
624
 
625
  phys_memaddr = memaddr;
626
 
627
  if (through_mmu)
628
    phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc);
629
 
630
  if (through_dc)
631
    return dc_simulate_read (phys_memaddr, memaddr, 2);
632
  else
633
    {
634
      if ((mem = verify_memoryarea (phys_memaddr)))
635
        return mem->direct_ops.readfunc16 (phys_memaddr & mem->size_mask,
636
                                           mem->direct_ops.read_dat16);
637
      else
638
        PRINTF ("ERR: 16-bit read out of memory area: %" PRIxADDR
639
                " (physical: %" PRIxADDR "\n", memaddr, phys_memaddr);
640
    }
641
 
642
  return 0;
643
}
644
 
645
/* Returns 8-bit values from mem array.
646
 *
647
 * STATISTICS OK (only used for cpu_access, that is architectural access)
648
 */
649
uint8_t
650
eval_mem8 (oraddr_t memaddr, int *breakpoint)
651
{
652
  uint8_t temp;
653
  oraddr_t phys_memaddr;
654
 
655
  if (config.sim.mprofile)
656
    mprofile (memaddr, MPROF_8 | MPROF_READ);
657
 
658
  if (config.debug.enabled)
659
    *breakpoint += check_debug_unit (DebugLoadAddress, memaddr);        /* 28/05/01 CZ */
660
 
661
  phys_memaddr = dmmu_translate (memaddr, 0);
662
  if (except_pending)
663
    return 0;
664
 
665
  if (config.dc.enabled)
666
    temp = dc_simulate_read (phys_memaddr, memaddr, 1);
667
  else
668
    temp = evalsim_mem8 (phys_memaddr, memaddr);
669
 
670
  if (config.debug.enabled)
671
    *breakpoint += check_debug_unit (DebugLoadData, temp);      /* MM170901 */
672
  return temp;
673
}
674
 
675
/* for simulator accesses, the ones that cpu wouldn't do
676
 *
677
 * STATISTICS OK.
678
 */
679
uint8_t
680
eval_direct8 (oraddr_t memaddr, int through_mmu, int through_dc)
681
{
682
  oraddr_t phys_memaddr;
683
  struct dev_memarea *mem;
684
 
685
  phys_memaddr = memaddr;
686
 
687
  if (through_mmu)
688
    phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc);
689
 
690
  if (through_dc)
691
    return dc_simulate_read (phys_memaddr, memaddr, 1);
692
  else
693
    {
694
      if ((mem = verify_memoryarea (phys_memaddr)))
695
        return mem->direct_ops.readfunc8 (phys_memaddr & mem->size_mask,
696
                                          mem->direct_ops.read_dat8);
697
      else
698
        PRINTF ("ERR: 8-bit read out of memory area: %" PRIxADDR
699
                " (physical: %" PRIxADDR "\n", memaddr, phys_memaddr);
700
    }
701
 
702
  return 0;
703
}
704
 
705
/* For cpu accesses
706
 *
707
 * NOTE: This function _is_ only called from set_mem32 below and
708
 * dc_simulate_write.  _Don't_ call it from anywere else.
709
 */
710
void
711
setsim_mem32 (oraddr_t memaddr, oraddr_t vaddr, uint32_t value)
712
{
713
  struct dev_memarea *mem;
714
 
715
  if ((mem = verify_memoryarea (memaddr)))
716
    {
717
      cur_vadd = vaddr;
718
      runtime.sim.mem_cycles += mem->ops.delayw;
719
      mem->ops.writefunc32 (memaddr & mem->size_mask, value,
720
                            mem->ops.write_dat32);
721
#if DYNAMIC_EXECUTION
722
      dyn_checkwrite (memaddr);
723
#endif
724
    }
725
  else
726
    {
727
      PRINTF ("EXCEPTION: write out of memory (32-bit access to %" PRIxADDR
728
              ")\n", memaddr);
729
      except_handle (EXCEPT_BUSERR, vaddr);
730
    }
731
}
732
 
733
/* For cpu accesses
734
 *
735
 * NOTE: This function _is_ only called from set_mem16 below and
736
 * dc_simulate_write.  _Don't_ call it from anywere else.
737
 */
738
void
739
setsim_mem16 (oraddr_t memaddr, oraddr_t vaddr, uint16_t value)
740
{
741
  struct dev_memarea *mem;
742
 
743
  if ((mem = verify_memoryarea (memaddr)))
744
    {
745
      cur_vadd = vaddr;
746
      runtime.sim.mem_cycles += mem->ops.delayw;
747
      mem->ops.writefunc16 (memaddr & mem->size_mask, value,
748
                            mem->ops.write_dat16);
749
#if DYNAMIC_EXECUTION
750
      dyn_checkwrite (memaddr);
751
#endif
752
    }
753
  else
754
    {
755
      PRINTF ("EXCEPTION: write out of memory (16-bit access to %" PRIxADDR
756
              ")\n", memaddr);
757
      except_handle (EXCEPT_BUSERR, vaddr);
758
    }
759
}
760
 
761
/* For cpu accesses
762
 *
763
 * NOTE: This function _is_ only called from set_mem8 below and
764
 * dc_simulate_write.  _Don't_ call it from anywere else.
765
 */
766
void
767
setsim_mem8 (oraddr_t memaddr, oraddr_t vaddr, uint8_t value)
768
{
769
  struct dev_memarea *mem;
770
 
771
  if ((mem = verify_memoryarea (memaddr)))
772
    {
773
      cur_vadd = vaddr;
774
      runtime.sim.mem_cycles += mem->ops.delayw;
775
      mem->ops.writefunc8 (memaddr & mem->size_mask, value,
776
                           mem->ops.write_dat8);
777
#if DYNAMIC_EXECUTION
778
      dyn_checkwrite (memaddr);
779
#endif
780
    }
781
  else
782
    {
783
      PRINTF ("EXCEPTION: write out of memory (8-bit access to %" PRIxADDR
784
              ")\n", memaddr);
785
      except_handle (EXCEPT_BUSERR, vaddr);
786
    }
787
}
788
 
789
/* Set mem, 32-bit. Big endian version.
790
 *
791
 * STATISTICS OK. (the only suspicious usage is in sim-cmd.c,
792
 *                 where this instruction is used for patching memory,
793
 *                 wether this is cpu or architectual access is yet to
794
 *                 be decided)
795
 */
796
void
797
set_mem32 (oraddr_t memaddr, uint32_t value, int *breakpoint)
798
{
799
  oraddr_t phys_memaddr;
800
 
801
  if (config.sim.mprofile)
802
    mprofile (memaddr, MPROF_32 | MPROF_WRITE);
803
 
804
  if (memaddr & 3)
805
    {
806
      except_handle (EXCEPT_ALIGN, memaddr);
807
      return;
808
    }
809
 
810
  phys_memaddr = dmmu_translate (memaddr, 1);;
811
  /* If we produced exception don't set anything */
812
  if (except_pending)
813
    return;
814
 
815
  if (config.debug.enabled)
816
    {
817
      *breakpoint += check_debug_unit (DebugStoreAddress, memaddr);     /* 28/05/01 CZ */
818
      *breakpoint += check_debug_unit (DebugStoreData, value);
819
    }
820
 
821
  if (config.dc.enabled)
822
    dc_simulate_write (phys_memaddr, memaddr, value, 4);
823
  else
824
    setsim_mem32 (phys_memaddr, memaddr, value);
825
 
826
  if (cur_area && cur_area->log)
827
    fprintf (cur_area->log, "[%" PRIxADDR "] -> write %08" PRIx32 "\n",
828
             memaddr, value);
829
}
830
 
831
/*
832
 * STATISTICS NOT OK.
833
 */
834
void
835
set_direct32 (oraddr_t memaddr, uint32_t value, int through_mmu,
836
              int through_dc)
837
{
838
  oraddr_t phys_memaddr;
839
  struct dev_memarea *mem;
840
 
841
  if (memaddr & 3)
842
    {
843
      PRINTF ("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__,
844
              __FUNCTION__);
845
      return;
846
    }
847
 
848
  phys_memaddr = memaddr;
849
 
850
  if (through_mmu)
851
    {
852
      /* 0 - no write access, we do not want a DPF exception do we ;)
853
       */
854
      phys_memaddr = peek_into_dtlb (memaddr, 1, through_dc);
855
    }
856
 
857
  if (through_dc)
858
    dc_simulate_write (memaddr, memaddr, value, 4);
859
  else
860
    {
861
      if ((mem = verify_memoryarea (phys_memaddr)))
862
        mem->direct_ops.writefunc32 (phys_memaddr & mem->size_mask, value,
863
                                     mem->direct_ops.write_dat32);
864
      else
865
        PRINTF ("ERR: 32-bit write out of memory area: %" PRIxADDR
866
                " (physical: %" PRIxADDR ")\n", memaddr, phys_memaddr);
867
    }
868
 
869
  if (cur_area && cur_area->log)
870
    fprintf (cur_area->log, "[%" PRIxADDR "] -> DIRECT write %08" PRIx32 "\n",
871
             memaddr, value);
872
}
873
 
874
 
875
/* Set mem, 16-bit. Big endian version. */
876
 
877
void
878
set_mem16 (oraddr_t memaddr, uint16_t value, int *breakpoint)
879
{
880
  oraddr_t phys_memaddr;
881
 
882
  if (config.sim.mprofile)
883
    mprofile (memaddr, MPROF_16 | MPROF_WRITE);
884
 
885
  if (memaddr & 1)
886
    {
887
      except_handle (EXCEPT_ALIGN, memaddr);
888
      return;
889
    }
890
 
891
  phys_memaddr = dmmu_translate (memaddr, 1);;
892
  /* If we produced exception don't set anything */
893
  if (except_pending)
894
    return;
895
 
896
  if (config.debug.enabled)
897
    {
898
      *breakpoint += check_debug_unit (DebugStoreAddress, memaddr);     /* 28/05/01 CZ */
899
      *breakpoint += check_debug_unit (DebugStoreData, value);
900
    }
901
 
902
  if (config.dc.enabled)
903
    dc_simulate_write (phys_memaddr, memaddr, value, 2);
904
  else
905
    setsim_mem16 (phys_memaddr, memaddr, value);
906
 
907
  if (cur_area && cur_area->log)
908
    fprintf (cur_area->log, "[%" PRIxADDR "] -> write %04" PRIx16 "\n",
909
             memaddr, value);
910
}
911
 
912
/*
913
 * STATISTICS NOT OK.
914
 */
915
void
916
set_direct16 (oraddr_t memaddr, uint16_t value, int through_mmu,
917
              int through_dc)
918
{
919
  oraddr_t phys_memaddr;
920
  struct dev_memarea *mem;
921
 
922
  if (memaddr & 1)
923
    {
924
      PRINTF ("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__,
925
              __FUNCTION__);
926
      return;
927
    }
928
 
929
  phys_memaddr = memaddr;
930
 
931
  if (through_mmu)
932
    {
933
      /* 0 - no write access, we do not want a DPF exception do we ;)
934
       */
935
      phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc);
936
    }
937
 
938
  if (through_dc)
939
    dc_simulate_write (memaddr, memaddr, value, 2);
940
  else
941
    {
942
      if ((mem = verify_memoryarea (phys_memaddr)))
943
        mem->direct_ops.writefunc16 (phys_memaddr & mem->size_mask, value,
944
                                     mem->direct_ops.write_dat16);
945
      else
946
        PRINTF ("ERR: 16-bit write out of memory area: %" PRIxADDR
947
                " (physical: %" PRIxADDR "\n", memaddr, phys_memaddr);
948
    }
949
 
950
  if (cur_area && cur_area->log)
951
    fprintf (cur_area->log, "[%" PRIxADDR "] -> DIRECT write %04" PRIx16 "\n",
952
             memaddr, value);
953
}
954
 
955
/* Set mem, 8-bit. */
956
void
957
set_mem8 (oraddr_t memaddr, uint8_t value, int *breakpoint)
958
{
959
  oraddr_t phys_memaddr;
960
 
961
  if (config.sim.mprofile)
962
    mprofile (memaddr, MPROF_8 | MPROF_WRITE);
963
 
964
  phys_memaddr = memaddr;
965
 
966
  phys_memaddr = dmmu_translate (memaddr, 1);;
967
  /* If we produced exception don't set anything */
968
  if (except_pending)
969
    return;
970
 
971
  if (config.debug.enabled)
972
    {
973
      *breakpoint += check_debug_unit (DebugStoreAddress, memaddr);     /* 28/05/01 CZ */
974
      *breakpoint += check_debug_unit (DebugStoreData, value);
975
    }
976
 
977
  if (config.dc.enabled)
978
    dc_simulate_write (phys_memaddr, memaddr, value, 1);
979
  else
980
    setsim_mem8 (phys_memaddr, memaddr, value);
981
 
982
  if (cur_area && cur_area->log)
983
    fprintf (cur_area->log, "[%" PRIxADDR "] -> write %02" PRIx8 "\n",
984
             memaddr, value);
985
}
986
 
987
/*
988
 * STATISTICS NOT OK.
989
 */
990
void
991
set_direct8 (oraddr_t memaddr, uint8_t value, int through_mmu, int through_dc)
992
{
993
  oraddr_t phys_memaddr;
994
  struct dev_memarea *mem;
995
 
996
  phys_memaddr = memaddr;
997
 
998
  if (through_mmu)
999
    {
1000
      /* 0 - no write access, we do not want a DPF exception do we ;)
1001
       */
1002
      phys_memaddr = peek_into_dtlb (memaddr, 0, through_dc);
1003
    }
1004
 
1005
  if (through_dc)
1006
    dc_simulate_write (phys_memaddr, memaddr, value, 1);
1007
  else
1008
    {
1009
      if ((mem = verify_memoryarea (phys_memaddr)))
1010
        mem->direct_ops.writefunc8 (phys_memaddr & mem->size_mask, value,
1011
                                    mem->direct_ops.write_dat8);
1012
      else
1013
        PRINTF ("ERR: 8-bit write out of memory area: %" PRIxADDR
1014
                " (physical: %" PRIxADDR "\n", memaddr, phys_memaddr);
1015
    }
1016
 
1017
  if (cur_area && cur_area->log)
1018
    fprintf (cur_area->log, "[%" PRIxADDR "] -> DIRECT write %02" PRIx8 "\n",
1019
             memaddr, value);
1020
}
1021
 
1022
 
1023
/* set_program32 - same as set_direct32, but it also writes to memory that is
1024
 *                 non-writeable to the rest of the sim.  Used to do program
1025
 *                 loading.
1026
 */
1027
void
1028
set_program32 (oraddr_t memaddr, uint32_t value)
1029
{
1030
  struct dev_memarea *mem;
1031
 
1032
  if (memaddr & 3)
1033
    {
1034
      PRINTF ("%s(): ERR unaligned 32-bit program write\n", __FUNCTION__);
1035
      return;
1036
    }
1037
 
1038
  if ((mem = verify_memoryarea (memaddr)))
1039
    {
1040
      mem->ops.writeprog32 (memaddr & mem->size_mask, value,
1041
                            mem->ops.writeprog32_dat);
1042
    }
1043
  else
1044
    PRINTF ("ERR: 32-bit program load out of memory area: %" PRIxADDR "\n",
1045
            memaddr);
1046
}
1047
 
1048
/* set_program8 - same as set_direct8, but it also writes to memory that is
1049
 *                non-writeable to the rest of the sim.  Used to do program
1050
 *                loading.
1051
 */
1052
void
1053
set_program8 (oraddr_t memaddr, uint8_t value)
1054
{
1055
  struct dev_memarea *mem;
1056
 
1057
  if ((mem = verify_memoryarea (memaddr)))
1058
    {
1059
      mem->ops.writeprog8 (memaddr & mem->size_mask, value,
1060
                           mem->ops.writeprog8_dat);
1061
    }
1062
  else
1063
    PRINTF ("ERR: 8-bit program load out of memory area: %" PRIxADDR "\n",
1064
            memaddr);
1065
}
1066
 
1067
 
1068
/*---------------------------------------------------------------------------*/
1069
/*!Dump memory to the current output
1070
 
1071
   Output format is hex bytes, 16 bytes per line. Start each line with its
1072
   address and (optionally) its symbolic name. Always end with a newline.
1073
 
1074
   There are all sorts of ways to trip this up, but they are unlikely. The
1075
   validity of a memory area is taken from the address of the start of a line
1076
   to be printed, so assumes the following 15 bytes are present. This could be
1077
   fooled by ridiculous memory declarations.
1078
 
1079
   @param[in] from    Start address of the area of memory
1080
   @param[in] to      End address of the area of memory                      */
1081
/*---------------------------------------------------------------------------*/
1082
void
1083
dump_memory (oraddr_t from, oraddr_t to)
1084
{
1085
  const int ROW_LEN = 16;
1086
  oraddr_t i;                   /* Row counter */
1087
 
1088
  for (i = from; i < to; i += ROW_LEN)
1089
    {
1090
      struct label_entry *entry = get_label (i);
1091
      oraddr_t j;               /* Index in row */
1092
 
1093
      PRINTF ("%" PRIxADDR, i);
1094
 
1095
      if (NULL != entry)
1096
        {
1097
          int padding = 11 - strlen (entry->name);
1098
 
1099
          PRINTF (" <%s>: ", entry->name);
1100
          PRINTF ("%*s ", padding < 0 ? 0 : padding, " ");
1101
        }
1102
      else
1103
        {
1104
          PRINTF (":                ");
1105
        }
1106
 
1107
 
1108
      for (j = 0; j < ROW_LEN; j++)
1109
        {
1110
          if (verify_memoryarea (i + j))
1111
            {
1112
              PRINTF ("%02" PRIx8 " ", eval_direct8 (i + j, 0, 0));
1113
            }
1114
          else
1115
            {
1116
              /* Not a valid memory area. Print Xs as required */
1117
              PRINTF ("XX ");
1118
            }
1119
        }
1120
 
1121
      PRINTF ("\n");
1122
    }
1123
}                               /* dump_memory() */
1124
 
1125
 
1126
/*---------------------------------------------------------------------------*/
1127
/*!Disassemble memory to the current output
1128
 
1129
   Output format is symbolic disassembly, one instruction per line. Start each
1130
   line with its address and (optionally) its symbolic name.
1131
 
1132
   There are all sorts of ways to trip this up, but they are unlikely. The
1133
   validity of a memory area is taken from the address of the start of a line
1134
   to be printed, so assumes the following 3 bytes are present. This could be
1135
   fooled by ridiculous memory declarations.
1136
 
1137
   @param[in] from    Start address of the area of memory
1138
   @param[in] to      End address of the area of memory
1139
   @param[in] nl      If non-zero (true) print a newline at the end of each
1140
                      line                                                   */
1141
/*---------------------------------------------------------------------------*/
1142
void
1143
disassemble_memory (oraddr_t from, oraddr_t to, int nl)
1144
{
1145
  const int INSTR_LEN = 4;
1146
  oraddr_t i;                   /* Row counter */
1147
 
1148
  for (i = from; i < to; i += INSTR_LEN)
1149
    {
1150
      struct label_entry *entry = get_label (i);
1151
 
1152
      PRINTF ("%" PRIxADDR, i);
1153
 
1154
      if (NULL != entry)
1155
        {
1156
          int padding = 11 - strlen (entry->name);
1157
 
1158
          PRINTF (" <%s>: ", entry->name);
1159
          PRINTF ("%*s ", padding < 0 ? 0 : padding, " ");
1160
        }
1161
      else
1162
        {
1163
          PRINTF (":                ");
1164
        }
1165
 
1166
      if (verify_memoryarea (i))
1167
        {
1168
          uint32_t insn = eval_direct32 (i, 0, 0);
1169
          int index = insn_decode (insn);
1170
 
1171
          PRINTF ("%08" PRIx32 " ", insn);
1172
 
1173
          if (index >= 0)
1174
            {
1175
              disassemble_insn (insn);
1176
              PRINTF (" %s", disassembled);
1177
            }
1178
          else
1179
            {
1180
              PRINTF ("<invalid>");
1181
            }
1182
 
1183
        }
1184
      else
1185
        {
1186
          /* Not a valid memory area. Print Xs as required */
1187
          PRINTF ("XXXXXXXX");
1188
        }
1189
 
1190
      if (nl)
1191
        {
1192
          PRINTF ("\n");
1193
        }
1194
    }
1195
}                               /* disassemble_memory() */
1196
 
1197
 
1198
/* Closes files, etc. */
1199
 
1200
void
1201
done_memory_table ()
1202
{
1203
  struct dev_memarea *ptmp;
1204
 
1205
  /* Check list of registered devices. */
1206
  for (ptmp = dev_list; ptmp; ptmp = ptmp->next)
1207
    {
1208
      if (ptmp->log)
1209
        fclose (ptmp->log);
1210
    }
1211
}
1212
 
1213
/* Displays current memory configuration */
1214
 
1215
void
1216
memory_table_status (void)
1217
{
1218
  struct dev_memarea *ptmp;
1219
 
1220
  /* Check list of registered devices. */
1221
  for (ptmp = dev_list; ptmp; ptmp = ptmp->next)
1222
    {
1223
      PRINTF ("addr & %" PRIxADDR " == %" PRIxADDR " to %" PRIxADDR ", size %"
1224
              PRIx32 "\n", ptmp->addr_mask, ptmp->addr_compare,
1225
              ptmp->addr_compare | bit_mask (ptmp->size), ptmp->size);
1226
      PRINTF ("\t");
1227
      if (ptmp->ops.delayr >= 0)
1228
        PRINTF ("read delay = %i cycles, ", ptmp->ops.delayr);
1229
      else
1230
        PRINTF ("reads not possible, ");
1231
 
1232
      if (ptmp->ops.delayw >= 0)
1233
        PRINTF ("write delay = %i cycles", ptmp->ops.delayw);
1234
      else
1235
        PRINTF ("writes not possible");
1236
 
1237
      if (ptmp->log)
1238
        PRINTF (", (logged)\n");
1239
      else
1240
        PRINTF ("\n");
1241
    }
1242
}
1243
 
1244
/* Outputs time in pretty form to dest string */
1245
 
1246
char *
1247
generate_time_pretty (char *dest, long time_ps)
1248
{
1249
  int exp3 = 0;
1250
  if (time_ps)
1251
    {
1252
      while ((time_ps % 1000) == 0)
1253
        {
1254
          time_ps /= 1000;
1255
          exp3++;
1256
        }
1257
    }
1258
  sprintf (dest, "%li%cs", time_ps, "pnum"[exp3]);
1259
  return dest;
1260
}

powered by: WebSVN 2.1.0

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