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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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