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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [sim/] [m32c/] [mem.c] - Blame information for rev 297

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

Line No. Rev Author Line
1 227 jeremybenn
/* mem.c --- memory for M32C simulator.
2
 
3
Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4
Contributed by Red Hat, Inc.
5
 
6
This file is part of the GNU simulators.
7
 
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
12
 
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
GNU General Public License for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
 
22
#include "config.h"
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <ctype.h>
27
#include <sys/time.h>
28
#include <sys/types.h>
29
#include <unistd.h>
30
#ifdef HAVE_SYS_SELECT_H
31
#include <sys/select.h>
32
#endif
33
#ifdef HAVE_TERMIOS_H
34
#include <termios.h>
35
#endif
36
 
37
#include "mem.h"
38
#include "cpu.h"
39
#include "syscalls.h"
40
#include "misc.h"
41
#ifdef TIMER_A
42
#include "int.h"
43
#include "timer_a.h"
44
#endif
45
 
46
#define L1_BITS  (10)
47
#define L2_BITS  (10)
48
#define OFF_BITS (12)
49
 
50
#define L1_LEN  (1 << L1_BITS)
51
#define L2_LEN  (1 << L2_BITS)
52
#define OFF_LEN (1 << OFF_BITS)
53
 
54
static unsigned char **pt[L1_LEN];
55
 
56
#ifdef HAVE_TERMIOS_H
57
int m32c_console_ifd = 0;
58
#endif
59
int m32c_console_ofd = 1;
60
#ifdef HAVE_TERMIOS_H
61
int m32c_use_raw_console = 0;
62
#endif
63
 
64
#ifdef TIMER_A
65
Timer_A timer_a;
66
#endif
67
 
68
/* [ get=0/put=1 ][ byte size ] */
69
static unsigned int mem_counters[2][5];
70
 
71
#define COUNT(isput,bytes)                                      \
72
  if (verbose && enable_counting) mem_counters[isput][bytes]++
73
 
74
void
75
init_mem (void)
76
{
77
  int i, j;
78
 
79
  for (i = 0; i < L1_LEN; i++)
80
    if (pt[i])
81
      {
82
        for (j = 0; j < L2_LEN; j++)
83
          if (pt[i][j])
84
            free (pt[i][j]);
85
        free (pt[i]);
86
      }
87
  memset (pt, 0, sizeof (pt));
88
  memset (mem_counters, 0, sizeof (mem_counters));
89
}
90
 
91
static unsigned char *
92
mem_ptr (address)
93
{
94
  static int recursing = 0;
95
  int pt1 = (address >> (L2_BITS + OFF_BITS)) & ((1 << L1_BITS) - 1);
96
  int pt2 = (address >> OFF_BITS) & ((1 << L2_BITS) - 1);
97
  int pto = address & ((1 << OFF_BITS) - 1);
98
 
99
  if (address == 0 && !recursing)
100
    {
101
      recursing = 1;
102
      put_reg (pc, m32c_opcode_pc);
103
      printf ("NULL pointer dereference at pc=0x%x\n", get_reg (pc));
104
      step_result = M32C_MAKE_HIT_BREAK ();
105
#if 0
106
      /* This code can be re-enabled to help diagnose NULL pointer
107
         bugs that aren't debuggable in GDB.  */
108
      m32c_dump_all_registers ();
109
      exit (1);
110
#endif
111
    }
112
 
113
  if (pt[pt1] == 0)
114
    pt[pt1] = (unsigned char **) calloc (L2_LEN, sizeof (char **));
115
  if (pt[pt1][pt2] == 0)
116
    {
117
      pt[pt1][pt2] = (unsigned char *) malloc (OFF_LEN);
118
      memset (pt[pt1][pt2], 0, OFF_LEN);
119
    }
120
 
121
  return pt[pt1][pt2] + pto;
122
}
123
 
124
static void
125
used (int rstart, int i, int j)
126
{
127
  int rend = i << (L2_BITS + OFF_BITS);
128
  rend += j << OFF_BITS;
129
  if (rstart == 0xe0000 && rend == 0xe1000)
130
    return;
131
  printf ("mem:   %08x - %08x (%dk bytes)\n", rstart, rend - 1,
132
          (rend - rstart) / 1024);
133
}
134
 
135
static char *
136
mcs (int isput, int bytes)
137
{
138
  return comma (mem_counters[isput][bytes]);
139
}
140
 
141
void
142
mem_usage_stats ()
143
{
144
  int i, j;
145
  int rstart = 0;
146
  int pending = 0;
147
 
148
  for (i = 0; i < L1_LEN; i++)
149
    if (pt[i])
150
      {
151
        for (j = 0; j < L2_LEN; j++)
152
          if (pt[i][j])
153
            {
154
              if (!pending)
155
                {
156
                  pending = 1;
157
                  rstart = (i << (L2_BITS + OFF_BITS)) + (j << OFF_BITS);
158
                }
159
            }
160
          else if (pending)
161
            {
162
              pending = 0;
163
              used (rstart, i, j);
164
            }
165
      }
166
    else
167
      {
168
        if (pending)
169
          {
170
            pending = 0;
171
            used (rstart, i, 0);
172
          }
173
      }
174
  /*       mem foo: 123456789012 123456789012 123456789012 123456789012
175
            123456789012 */
176
  printf ("                 byte        short      pointer         long"
177
          "        fetch\n");
178
  printf ("mem get: %12s %12s %12s %12s %12s\n", mcs (0, 1), mcs (0, 2),
179
          mcs (0, 3), mcs (0, 4), mcs (0, 0));
180
  printf ("mem put: %12s %12s %12s %12s\n", mcs (1, 1), mcs (1, 2),
181
          mcs (1, 3), mcs (1, 4));
182
}
183
 
184
static int tpr = 0;
185
static void
186
s (int address, char *dir)
187
{
188
  if (tpr == 0)
189
    printf ("MEM[%0*x] %s", membus_mask == 0xfffff ? 5 : 6, address, dir);
190
  tpr++;
191
}
192
 
193
#define S(d) if (trace) s(address, d)
194
static void
195
e ()
196
{
197
  if (!trace)
198
    return;
199
  tpr--;
200
  if (tpr == 0)
201
    printf ("\n");
202
}
203
 
204
#define E() if (trace) e()
205
 
206
extern int m32c_disassemble;
207
 
208
void
209
mem_put_byte (int address, unsigned char value)
210
{
211
  unsigned char *m;
212
  address &= membus_mask;
213
  m = mem_ptr (address);
214
  if (trace)
215
    printf (" %02x", value);
216
  *m = value;
217
  switch (address)
218
    {
219
    case 0x00e1:
220
      {
221
        static int old_led = -1;
222
        static char *led_on[] =
223
          { "\033[31m O ", "\033[32m O ", "\033[34m O " };
224
        static char *led_off[] = { "\033[0m · ", "\033[0m · ", "\033[0m · " };
225
        int i;
226
        if (old_led != value)
227
          {
228
            fputs ("  ", stdout);
229
            for (i = 0; i < 3; i++)
230
              if (value & (1 << i))
231
                fputs (led_off[i], stdout);
232
              else
233
                fputs (led_on[i], stdout);
234
            fputs ("\033[0m\r", stdout);
235
            fflush (stdout);
236
            old_led = value;
237
          }
238
      }
239
      break;
240
#ifdef TIMER_A
241
      /* M32C Timer A */
242
    case 0x346:         /* TA0low */
243
      timer_a.count = (timer_a.count & 0xff00) | value;
244
      timer_a.reload = timer_a.count;
245
      break;
246
    case 0x347:         /* TA0high */
247
      timer_a.count = (timer_a.count & 0x00ff) | (value << 8);
248
      timer_a.reload = timer_a.count;
249
      break;
250
    case 0x340:         /* TABSR */
251
      timer_a.bsr = value;
252
      break;
253
    case 0x356:         /* TA0MR */
254
      timer_a.mode = value;
255
      break;
256
    case 0x35f:         /* TCSPR */
257
      timer_a.tcspr = value;
258
      break;
259
    case 0x006c:                /* TA0IC */
260
      timer_a.ic = value;
261
      break;
262
 
263
      /* R8C Timer RA */
264
    case 0x100:         /* TRACR */
265
      timer_a.bsr = value;
266
      break;
267
    case 0x102:         /* TRAMR */
268
      timer_a.mode = value;
269
      break;
270
    case 0x104:         /* TRA */
271
      timer_a.count = value;
272
      timer_a.reload = value;
273
      break;
274
    case 0x103:         /* TRAPRE */
275
      timer_a.tcspr = value;
276
      break;
277
    case 0x0056:                /* TA0IC */
278
      timer_a.ic = value;
279
      break;
280
#endif
281
 
282
    case 0x2ea:         /* m32c uart1tx */
283
    case 0x3aa:         /* m16c uart1tx */
284
      {
285
        static int pending_exit = 0;
286
        if (value == 0)
287
          {
288
            if (pending_exit)
289
              {
290
                step_result = M32C_MAKE_EXITED (value);
291
                return;
292
              }
293
            pending_exit = 1;
294
          }
295
        else
296
          {
297
            write (m32c_console_ofd, &value, 1);
298
          }
299
      }
300
      break;
301
 
302
    case 0x400:
303
      m32c_syscall (value);
304
      break;
305
 
306
    case 0x401:
307
      putchar (value);
308
      break;
309
 
310
    case 0x402:
311
      printf ("SimTrace: %06lx %02x\n", regs.r_pc, value);
312
      break;
313
 
314
    case 0x403:
315
      printf ("SimTrap: %06lx %02x\n", regs.r_pc, value);
316
      abort ();
317
    }
318
}
319
 
320
void
321
mem_put_qi (int address, unsigned char value)
322
{
323
  S ("<=");
324
  mem_put_byte (address, value & 0xff);
325
  E ();
326
  COUNT (1, 1);
327
}
328
 
329
void
330
mem_put_hi (int address, unsigned short value)
331
{
332
  if (address == 0x402)
333
    {
334
      printf ("SimTrace: %06lx %04x\n", regs.r_pc, value);
335
      return;
336
    }
337
  S ("<=");
338
  mem_put_byte (address, value & 0xff);
339
  mem_put_byte (address + 1, value >> 8);
340
  E ();
341
  COUNT (1, 2);
342
}
343
 
344
void
345
mem_put_psi (int address, unsigned long value)
346
{
347
  S ("<=");
348
  mem_put_byte (address, value & 0xff);
349
  mem_put_byte (address + 1, (value >> 8) & 0xff);
350
  mem_put_byte (address + 2, value >> 16);
351
  E ();
352
  COUNT (1, 3);
353
}
354
 
355
void
356
mem_put_si (int address, unsigned long value)
357
{
358
  S ("<=");
359
  mem_put_byte (address, value & 0xff);
360
  mem_put_byte (address + 1, (value >> 8) & 0xff);
361
  mem_put_byte (address + 2, (value >> 16) & 0xff);
362
  mem_put_byte (address + 3, (value >> 24) & 0xff);
363
  E ();
364
  COUNT (1, 4);
365
}
366
 
367
void
368
mem_put_blk (int address, void *bufptr, int nbytes)
369
{
370
  S ("<=");
371
  if (enable_counting)
372
    mem_counters[1][1] += nbytes;
373
  while (nbytes--)
374
    mem_put_byte (address++, *(unsigned char *) bufptr++);
375
  E ();
376
}
377
 
378
unsigned char
379
mem_get_pc ()
380
{
381
  unsigned char *m = mem_ptr (regs.r_pc & membus_mask);
382
  COUNT (0, 0);
383
  return *m;
384
}
385
 
386
#ifdef HAVE_TERMIOS_H
387
static int console_raw = 0;
388
static struct termios oattr;
389
 
390
static int
391
stdin_ready ()
392
{
393
  fd_set ifd;
394
  int n;
395
  struct timeval t;
396
 
397
  t.tv_sec = 0;
398
  t.tv_usec = 0;
399
  FD_ZERO (&ifd);
400
  FD_SET (m32c_console_ifd, &ifd);
401
  n = select (1, &ifd, 0, 0, &t);
402
  return n > 0;
403
}
404
 
405
void
406
m32c_sim_restore_console ()
407
{
408
  if (console_raw)
409
    tcsetattr (m32c_console_ifd, TCSANOW, &oattr);
410
  console_raw = 0;
411
}
412
#endif
413
 
414
static unsigned char
415
mem_get_byte (int address)
416
{
417
  unsigned char *m;
418
  address &= membus_mask;
419
  m = mem_ptr (address);
420
  switch (address)
421
    {
422
#ifdef HAVE_TERMIOS_H
423
    case 0x2ed:         /* m32c uart1c1 */
424
    case 0x3ad:         /* m16c uart1c1 */
425
 
426
      if (!console_raw && m32c_use_raw_console)
427
        {
428
          struct termios attr;
429
          tcgetattr (m32c_console_ifd, &attr);
430
          tcgetattr (m32c_console_ifd, &oattr);
431
          /* We want each key to be sent as the user presses them.  */
432
          attr.c_lflag &= ~(ICANON | ECHO | ECHOE);
433
          tcsetattr (m32c_console_ifd, TCSANOW, &attr);
434
          console_raw = 1;
435
          atexit (m32c_sim_restore_console);
436
        }
437
 
438
      if (stdin_ready ())
439
        return 0x02;            /* tx empty and rx full */
440
      else
441
        return 0x0a;            /* transmitter empty */
442
 
443
    case 0x2ee:         /* m32c uart1 rx */
444
      {
445
        char c;
446
        read (m32c_console_ifd, &c, 1);
447
        if (m32c_console_ifd == 0 && c == 3)     /* Ctrl-C */
448
          {
449
            printf ("Ctrl-C!\n");
450
            exit (0);
451
          }
452
 
453
        if (m32c_console_ifd != 1)
454
          {
455
            if (isgraph (c))
456
              printf ("\033[31m%c\033[0m", c);
457
            else
458
              printf ("\033[31m%02x\033[0m", c);
459
          }
460
        return c;
461
      }
462
#endif
463
 
464
#ifdef TIMER_A
465
    case 0x346:         /* TA0low */
466
      return timer_a.count & 0xff;
467
    case 0x347:         /* TA0high */
468
      return (timer_a.count >> 8) & 0xff;
469
    case 0x104:         /* TRA */
470
      return timer_a.count;
471
#endif
472
 
473
    default:
474
      /* In case both cases above are not included.  */
475
      ;
476
    }
477
 
478
  S ("=>");
479
  if (trace)
480
    printf (" %02x", *m);
481
  E ();
482
  return *m;
483
}
484
 
485
unsigned char
486
mem_get_qi (int address)
487
{
488
  unsigned char rv;
489
  S ("=>");
490
  rv = mem_get_byte (address);
491
  COUNT (0, 1);
492
  E ();
493
  return rv;
494
}
495
 
496
unsigned short
497
mem_get_hi (int address)
498
{
499
  unsigned short rv;
500
  S ("=>");
501
  rv = mem_get_byte (address);
502
  rv |= mem_get_byte (address + 1) * 256;
503
  COUNT (0, 2);
504
  E ();
505
  return rv;
506
}
507
 
508
unsigned long
509
mem_get_psi (int address)
510
{
511
  unsigned long rv;
512
  S ("=>");
513
  rv = mem_get_byte (address);
514
  rv |= mem_get_byte (address + 1) * 256;
515
  rv |= mem_get_byte (address + 2) * 65536;
516
  COUNT (0, 3);
517
  E ();
518
  return rv;
519
}
520
 
521
unsigned long
522
mem_get_si (int address)
523
{
524
  unsigned long rv;
525
  S ("=>");
526
  rv = mem_get_byte (address);
527
  rv |= mem_get_byte (address + 1) << 8;
528
  rv |= mem_get_byte (address + 2) << 16;
529
  rv |= mem_get_byte (address + 3) << 24;
530
  COUNT (0, 4);
531
  E ();
532
  return rv;
533
}
534
 
535
void
536
mem_get_blk (int address, void *bufptr, int nbytes)
537
{
538
  S ("=>");
539
  if (enable_counting)
540
    mem_counters[0][1] += nbytes;
541
  while (nbytes--)
542
    *(char *) bufptr++ = mem_get_byte (address++);
543
  E ();
544
}
545
 
546
int
547
sign_ext (int v, int bits)
548
{
549
  if (bits < 32)
550
    {
551
      v &= (1 << bits) - 1;
552
      if (v & (1 << (bits - 1)))
553
        v -= (1 << bits);
554
    }
555
  return v;
556
}
557
 
558
#if TIMER_A
559
void
560
update_timer_a ()
561
{
562
  if (timer_a.bsr & 1)
563
    {
564
      timer_a.prescale--;
565
      if (timer_a.prescale < 0)
566
        {
567
          if (A24)
568
            {
569
              switch (timer_a.mode & 0xc0)
570
                {
571
                case 0x00:
572
                  timer_a.prescale = 0;
573
                  break;
574
                case 0x40:
575
                  timer_a.prescale = 8;
576
                  break;
577
                case 0x80:
578
                  timer_a.prescale = timer_a.tcspr & 0x0f;
579
                  break;
580
                case 0xc0:
581
                  timer_a.prescale = 32;
582
                  break;
583
                }
584
            }
585
          else
586
            {
587
              timer_a.prescale = timer_a.tcspr;
588
            }
589
          timer_a.count--;
590
          if (timer_a.count < 0)
591
            {
592
              timer_a.count = timer_a.reload;
593
              if (timer_a.ic & 7)
594
                {
595
                  if (A24)
596
                    mem_put_qi (0x6c, timer_a.ic | 0x08);
597
                  else
598
                    mem_put_qi (0x56, timer_a.ic | 0x08);
599
                }
600
            }
601
        }
602
    }
603
 
604
  if (regs.r_flags & FLAGBIT_I  /* interrupts enabled */
605
      && timer_a.ic & 0x08      /* timer A interrupt triggered */
606
      && (timer_a.ic & 0x07) > ((regs.r_flags >> 12) & 0x07))
607
    {
608
      if (A24)
609
        trigger_peripheral_interrupt (12, 0x06c);
610
      else
611
        trigger_peripheral_interrupt (22, 0x056);
612
    }
613
}
614
#endif

powered by: WebSVN 2.1.0

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