packaging: Add python3-base dependency
[platform/upstream/gdb.git] / sim / m32c / mem.c
1 /* mem.c --- memory for M32C simulator.
2
3 Copyright (C) 2005-2023 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 /* This must come before any other includes.  */
22 #include "defs.h"
23
24 #include <errno.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <ctype.h>
29 #include <sys/time.h>
30 #include <sys/types.h>
31 #include <unistd.h>
32 #include <sys/select.h>
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 (int 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 (void)
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 (void)
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 static 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             if (write (m32c_console_ofd, &value, 1) != 1)
298               printf ("write console failed: %s\n", strerror (errno));
299           }
300       }
301       break;
302
303     case 0x400:
304       m32c_syscall (value);
305       break;
306
307     case 0x401:
308       putchar (value);
309       break;
310
311     case 0x402:
312       printf ("SimTrace: %06lx %02x\n", regs.r_pc, value);
313       break;
314
315     case 0x403:
316       printf ("SimTrap: %06lx %02x\n", regs.r_pc, value);
317       abort ();
318     }
319 }
320
321 void
322 mem_put_qi (int address, unsigned char value)
323 {
324   S ("<=");
325   mem_put_byte (address, value & 0xff);
326   E ();
327   COUNT (1, 1);
328 }
329
330 void
331 mem_put_hi (int address, unsigned short value)
332 {
333   if (address == 0x402)
334     {
335       printf ("SimTrace: %06lx %04x\n", regs.r_pc, value);
336       return;
337     }
338   S ("<=");
339   mem_put_byte (address, value & 0xff);
340   mem_put_byte (address + 1, value >> 8);
341   E ();
342   COUNT (1, 2);
343 }
344
345 void
346 mem_put_psi (int address, unsigned long value)
347 {
348   S ("<=");
349   mem_put_byte (address, value & 0xff);
350   mem_put_byte (address + 1, (value >> 8) & 0xff);
351   mem_put_byte (address + 2, value >> 16);
352   E ();
353   COUNT (1, 3);
354 }
355
356 void
357 mem_put_si (int address, unsigned long value)
358 {
359   S ("<=");
360   mem_put_byte (address, value & 0xff);
361   mem_put_byte (address + 1, (value >> 8) & 0xff);
362   mem_put_byte (address + 2, (value >> 16) & 0xff);
363   mem_put_byte (address + 3, (value >> 24) & 0xff);
364   E ();
365   COUNT (1, 4);
366 }
367
368 void
369 mem_put_blk (int address, const void *bufptr, int nbytes)
370 {
371   const unsigned char *buf = bufptr;
372
373   S ("<=");
374   if (enable_counting)
375     mem_counters[1][1] += nbytes;
376   while (nbytes--)
377     mem_put_byte (address++, *buf++);
378   E ();
379 }
380
381 unsigned char
382 mem_get_pc (void)
383 {
384   unsigned char *m = mem_ptr (regs.r_pc & membus_mask);
385   COUNT (0, 0);
386   return *m;
387 }
388
389 #ifdef HAVE_TERMIOS_H
390 static int console_raw = 0;
391 static struct termios oattr;
392
393 static int
394 stdin_ready (void)
395 {
396   fd_set ifd;
397   int n;
398   struct timeval t;
399
400   t.tv_sec = 0;
401   t.tv_usec = 0;
402   FD_ZERO (&ifd);
403   FD_SET (m32c_console_ifd, &ifd);
404   n = select (1, &ifd, 0, 0, &t);
405   return n > 0;
406 }
407
408 void
409 m32c_sim_restore_console (void)
410 {
411   if (console_raw)
412     tcsetattr (m32c_console_ifd, TCSANOW, &oattr);
413   console_raw = 0;
414 }
415 #endif
416
417 static unsigned char
418 mem_get_byte (int address)
419 {
420   unsigned char *m;
421   address &= membus_mask;
422   m = mem_ptr (address);
423   switch (address)
424     {
425 #ifdef HAVE_TERMIOS_H
426     case 0x2ed:         /* m32c uart1c1 */
427     case 0x3ad:         /* m16c uart1c1 */
428
429       if (!console_raw && m32c_use_raw_console)
430         {
431           struct termios attr;
432           tcgetattr (m32c_console_ifd, &attr);
433           tcgetattr (m32c_console_ifd, &oattr);
434           /* We want each key to be sent as the user presses them.  */
435           attr.c_lflag &= ~(ICANON | ECHO | ECHOE);
436           tcsetattr (m32c_console_ifd, TCSANOW, &attr);
437           console_raw = 1;
438           atexit (m32c_sim_restore_console);
439         }
440
441       if (stdin_ready ())
442         return 0x02;            /* tx empty and rx full */
443       else
444         return 0x0a;            /* transmitter empty */
445
446     case 0x2ee:         /* m32c uart1 rx */
447       {
448         char c;
449         if (read (m32c_console_ifd, &c, 1) != 1)
450           return 0;
451         if (m32c_console_ifd == 0 && c == 3)    /* Ctrl-C */
452           {
453             printf ("Ctrl-C!\n");
454             exit (0);
455           }
456
457         if (m32c_console_ifd != 1)
458           {
459             if (isgraph (c))
460               printf ("\033[31m%c\033[0m", c);
461             else
462               printf ("\033[31m%02x\033[0m", c);
463           }
464         return c;
465       }
466 #endif
467
468 #ifdef TIMER_A
469     case 0x346:         /* TA0low */
470       return timer_a.count & 0xff;
471     case 0x347:         /* TA0high */
472       return (timer_a.count >> 8) & 0xff;
473     case 0x104:         /* TRA */
474       return timer_a.count;
475 #endif
476
477     default:
478       /* In case both cases above are not included.  */
479       ;
480     }
481
482   S ("=>");
483   if (trace)
484     printf (" %02x", *m);
485   E ();
486   return *m;
487 }
488
489 unsigned char
490 mem_get_qi (int address)
491 {
492   unsigned char rv;
493   S ("=>");
494   rv = mem_get_byte (address);
495   COUNT (0, 1);
496   E ();
497   return rv;
498 }
499
500 unsigned short
501 mem_get_hi (int address)
502 {
503   unsigned short rv;
504   S ("=>");
505   rv = mem_get_byte (address);
506   rv |= mem_get_byte (address + 1) * 256;
507   COUNT (0, 2);
508   E ();
509   return rv;
510 }
511
512 unsigned long
513 mem_get_psi (int address)
514 {
515   unsigned long rv;
516   S ("=>");
517   rv = mem_get_byte (address);
518   rv |= mem_get_byte (address + 1) * 256;
519   rv |= mem_get_byte (address + 2) * 65536;
520   COUNT (0, 3);
521   E ();
522   return rv;
523 }
524
525 unsigned long
526 mem_get_si (int address)
527 {
528   unsigned long rv;
529   S ("=>");
530   rv = mem_get_byte (address);
531   rv |= mem_get_byte (address + 1) << 8;
532   rv |= mem_get_byte (address + 2) << 16;
533   rv |= mem_get_byte (address + 3) << 24;
534   COUNT (0, 4);
535   E ();
536   return rv;
537 }
538
539 void
540 mem_get_blk (int address, void *bufptr, int nbytes)
541 {
542   char *buf = bufptr;
543
544   S ("=>");
545   if (enable_counting)
546     mem_counters[0][1] += nbytes;
547   while (nbytes--)
548     *buf++ = mem_get_byte (address++);
549   E ();
550 }
551
552 int
553 sign_ext (int v, int bits)
554 {
555   if (bits < 32)
556     {
557       v &= (1 << bits) - 1;
558       if (v & (1 << (bits - 1)))
559         v -= (1 << bits);
560     }
561   return v;
562 }
563
564 #if TIMER_A
565 void
566 update_timer_a (void)
567 {
568   if (timer_a.bsr & 1)
569     {
570       timer_a.prescale--;
571       if (timer_a.prescale < 0)
572         {
573           if (A24)
574             {
575               switch (timer_a.mode & 0xc0)
576                 {
577                 case 0x00:
578                   timer_a.prescale = 0;
579                   break;
580                 case 0x40:
581                   timer_a.prescale = 8;
582                   break;
583                 case 0x80:
584                   timer_a.prescale = timer_a.tcspr & 0x0f;
585                   break;
586                 case 0xc0:
587                   timer_a.prescale = 32;
588                   break;
589                 }
590             }
591           else
592             {
593               timer_a.prescale = timer_a.tcspr;
594             }
595           timer_a.count--;
596           if (timer_a.count < 0)
597             {
598               timer_a.count = timer_a.reload;
599               if (timer_a.ic & 7)
600                 {
601                   if (A24)
602                     mem_put_qi (0x6c, timer_a.ic | 0x08);
603                   else
604                     mem_put_qi (0x56, timer_a.ic | 0x08);
605                 }
606             }
607         }
608     }
609
610   if (regs.r_flags & FLAGBIT_I  /* interrupts enabled */
611       && timer_a.ic & 0x08      /* timer A interrupt triggered */
612       && (timer_a.ic & 0x07) > ((regs.r_flags >> 12) & 0x07))
613     {
614       if (A24)
615         trigger_peripheral_interrupt (12, 0x06c);
616       else
617         trigger_peripheral_interrupt (22, 0x056);
618     }
619 }
620 #endif