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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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