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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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