14e98e3e1Schristos /* gdb.c --- sim interface to GDB. 24e98e3e1Schristos 3*71f62182Schristos Copyright (C) 2005-2024 Free Software Foundation, Inc. 44e98e3e1Schristos Contributed by Red Hat, Inc. 54e98e3e1Schristos 64e98e3e1Schristos This file is part of the GNU simulators. 74e98e3e1Schristos 84e98e3e1Schristos This program is free software; you can redistribute it and/or modify 94e98e3e1Schristos it under the terms of the GNU General Public License as published by 104e98e3e1Schristos the Free Software Foundation; either version 3 of the License, or 114e98e3e1Schristos (at your option) any later version. 124e98e3e1Schristos 134e98e3e1Schristos This program is distributed in the hope that it will be useful, 144e98e3e1Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 154e98e3e1Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 164e98e3e1Schristos GNU General Public License for more details. 174e98e3e1Schristos 184e98e3e1Schristos You should have received a copy of the GNU General Public License 194e98e3e1Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 204e98e3e1Schristos 214b169a6bSchristos /* This must come before any other includes. */ 224b169a6bSchristos #include "defs.h" 234b169a6bSchristos 244e98e3e1Schristos #include <stdio.h> 254e98e3e1Schristos #include <assert.h> 264e98e3e1Schristos #include <signal.h> 27212397c6Schristos #include <stdlib.h> 284e98e3e1Schristos #include <string.h> 294e98e3e1Schristos #include <ctype.h> 304e98e3e1Schristos 314e98e3e1Schristos #include "ansidecl.h" 324b169a6bSchristos #include "libiberty.h" 334b169a6bSchristos #include "sim/callback.h" 344b169a6bSchristos #include "sim/sim.h" 354e98e3e1Schristos #include "gdb/signals.h" 36*71f62182Schristos #include "sim/sim-m32c.h" 374e98e3e1Schristos 384e98e3e1Schristos #include "cpu.h" 394e98e3e1Schristos #include "mem.h" 404e98e3e1Schristos #include "load.h" 414e98e3e1Schristos #include "syscalls.h" 424e98e3e1Schristos #ifdef TIMER_A 434e98e3e1Schristos #include "timer_a.h" 444e98e3e1Schristos #endif 454e98e3e1Schristos 464e98e3e1Schristos /* I don't want to wrap up all the minisim's data structures in an 474e98e3e1Schristos object and pass that around. That'd be a big change, and neither 484e98e3e1Schristos GDB nor run needs that ability. 494e98e3e1Schristos 504e98e3e1Schristos So we just have one instance, that lives in global variables, and 514e98e3e1Schristos each time we open it, we re-initialize it. */ 524e98e3e1Schristos struct sim_state 534e98e3e1Schristos { 544e98e3e1Schristos const char *message; 554e98e3e1Schristos }; 564e98e3e1Schristos 574e98e3e1Schristos static struct sim_state the_minisim = { 584e98e3e1Schristos "This is the sole m32c minisim instance. See libsim.a's global variables." 594e98e3e1Schristos }; 604e98e3e1Schristos 614b169a6bSchristos static int is_open; 624e98e3e1Schristos 634e98e3e1Schristos SIM_DESC 644e98e3e1Schristos sim_open (SIM_OPEN_KIND kind, 654e98e3e1Schristos struct host_callback_struct *callback, 66ba340e45Schristos struct bfd *abfd, char * const *argv) 674e98e3e1Schristos { 684e98e3e1Schristos setbuf (stdout, 0); 694b169a6bSchristos if (is_open) 704e98e3e1Schristos fprintf (stderr, "m32c minisim: re-opened sim\n"); 714e98e3e1Schristos 724e98e3e1Schristos /* The 'run' interface doesn't use this function, so we don't care 734e98e3e1Schristos about KIND; it's always SIM_OPEN_DEBUG. */ 744e98e3e1Schristos if (kind != SIM_OPEN_DEBUG) 754e98e3e1Schristos fprintf (stderr, "m32c minisim: sim_open KIND != SIM_OPEN_DEBUG: %d\n", 764e98e3e1Schristos kind); 774e98e3e1Schristos 784e98e3e1Schristos if (abfd) 794e98e3e1Schristos m32c_set_mach (bfd_get_mach (abfd)); 804e98e3e1Schristos 814e98e3e1Schristos /* We can use ABFD, if non-NULL to select the appropriate 824e98e3e1Schristos architecture. But we only support the r8c right now. */ 834e98e3e1Schristos 844e98e3e1Schristos set_callbacks (callback); 854e98e3e1Schristos 864e98e3e1Schristos /* We don't expect any command-line arguments. */ 874e98e3e1Schristos 884e98e3e1Schristos init_mem (); 894e98e3e1Schristos init_regs (); 904e98e3e1Schristos 914b169a6bSchristos is_open = 1; 924e98e3e1Schristos return &the_minisim; 934e98e3e1Schristos } 944e98e3e1Schristos 954e98e3e1Schristos static void 964e98e3e1Schristos check_desc (SIM_DESC sd) 974e98e3e1Schristos { 984e98e3e1Schristos if (sd != &the_minisim) 994e98e3e1Schristos fprintf (stderr, "m32c minisim: desc != &the_minisim\n"); 1004e98e3e1Schristos } 1014e98e3e1Schristos 1024e98e3e1Schristos void 1034e98e3e1Schristos sim_close (SIM_DESC sd, int quitting) 1044e98e3e1Schristos { 1054e98e3e1Schristos check_desc (sd); 1064e98e3e1Schristos 1074e98e3e1Schristos /* Not much to do. At least free up our memory. */ 1084e98e3e1Schristos init_mem (); 1094e98e3e1Schristos 1104b169a6bSchristos is_open = 0; 1114e98e3e1Schristos } 1124e98e3e1Schristos 1134e98e3e1Schristos static bfd * 1144e98e3e1Schristos open_objfile (const char *filename) 1154e98e3e1Schristos { 1164e98e3e1Schristos bfd *prog = bfd_openr (filename, 0); 1174e98e3e1Schristos 1184e98e3e1Schristos if (!prog) 1194e98e3e1Schristos { 1204e98e3e1Schristos fprintf (stderr, "Can't read %s\n", filename); 1214e98e3e1Schristos return 0; 1224e98e3e1Schristos } 1234e98e3e1Schristos 1244e98e3e1Schristos if (!bfd_check_format (prog, bfd_object)) 1254e98e3e1Schristos { 1264e98e3e1Schristos fprintf (stderr, "%s not a m32c program\n", filename); 1274e98e3e1Schristos return 0; 1284e98e3e1Schristos } 1294e98e3e1Schristos 1304e98e3e1Schristos return prog; 1314e98e3e1Schristos } 1324e98e3e1Schristos 1334e98e3e1Schristos 1344e98e3e1Schristos SIM_RC 135b23b2582Schristos sim_load (SIM_DESC sd, const char *prog, struct bfd * abfd, int from_tty) 1364e98e3e1Schristos { 1374e98e3e1Schristos check_desc (sd); 1384e98e3e1Schristos 1394e98e3e1Schristos if (!abfd) 1404e98e3e1Schristos abfd = open_objfile (prog); 1414e98e3e1Schristos if (!abfd) 1424e98e3e1Schristos return SIM_RC_FAIL; 1434e98e3e1Schristos 1444e98e3e1Schristos m32c_load (abfd); 1454e98e3e1Schristos 1464e98e3e1Schristos return SIM_RC_OK; 1474e98e3e1Schristos } 1484e98e3e1Schristos 1494e98e3e1Schristos SIM_RC 150ba340e45Schristos sim_create_inferior (SIM_DESC sd, struct bfd * abfd, 151ba340e45Schristos char * const *argv, char * const *env) 1524e98e3e1Schristos { 1534e98e3e1Schristos check_desc (sd); 1544e98e3e1Schristos 1554e98e3e1Schristos if (abfd) 1564e98e3e1Schristos m32c_load (abfd); 1574e98e3e1Schristos 1584e98e3e1Schristos return SIM_RC_OK; 1594e98e3e1Schristos } 1604e98e3e1Schristos 161*71f62182Schristos uint64_t 162*71f62182Schristos sim_read (SIM_DESC sd, uint64_t addr, void *buf, uint64_t length) 1634e98e3e1Schristos { 1644e98e3e1Schristos check_desc (sd); 1654e98e3e1Schristos 166*71f62182Schristos if (addr == 0) 1674e98e3e1Schristos return 0; 1684e98e3e1Schristos 169*71f62182Schristos mem_get_blk ((int) addr, buf, length); 1704e98e3e1Schristos 1714e98e3e1Schristos return length; 1724e98e3e1Schristos } 1734e98e3e1Schristos 174*71f62182Schristos uint64_t 175*71f62182Schristos sim_write (SIM_DESC sd, uint64_t addr, const void *buf, uint64_t length) 1764e98e3e1Schristos { 1774e98e3e1Schristos check_desc (sd); 1784e98e3e1Schristos 179*71f62182Schristos mem_put_blk ((int) addr, buf, length); 1804e98e3e1Schristos 1814e98e3e1Schristos return length; 1824e98e3e1Schristos } 1834e98e3e1Schristos 1844e98e3e1Schristos 1854e98e3e1Schristos /* Read the LENGTH bytes at BUF as an little-endian value. */ 1864e98e3e1Schristos static DI 1874b169a6bSchristos get_le (const unsigned char *buf, int length) 1884e98e3e1Schristos { 1894e98e3e1Schristos DI acc = 0; 1904e98e3e1Schristos while (--length >= 0) 1914e98e3e1Schristos acc = (acc << 8) + buf[length]; 1924e98e3e1Schristos 1934e98e3e1Schristos return acc; 1944e98e3e1Schristos } 1954e98e3e1Schristos 1964e98e3e1Schristos /* Store VAL as a little-endian value in the LENGTH bytes at BUF. */ 1974e98e3e1Schristos static void 1984e98e3e1Schristos put_le (unsigned char *buf, int length, DI val) 1994e98e3e1Schristos { 2004e98e3e1Schristos int i; 2014e98e3e1Schristos 2024e98e3e1Schristos for (i = 0; i < length; i++) 2034e98e3e1Schristos { 2044e98e3e1Schristos buf[i] = val & 0xff; 2054e98e3e1Schristos val >>= 8; 2064e98e3e1Schristos } 2074e98e3e1Schristos } 2084e98e3e1Schristos 2094e98e3e1Schristos static int 2104e98e3e1Schristos check_regno (enum m32c_sim_reg regno) 2114e98e3e1Schristos { 2124e98e3e1Schristos return 0 <= regno && regno < m32c_sim_reg_num_regs; 2134e98e3e1Schristos } 2144e98e3e1Schristos 2154e98e3e1Schristos static size_t 2164e98e3e1Schristos mask_size (int addr_mask) 2174e98e3e1Schristos { 2184e98e3e1Schristos switch (addr_mask) 2194e98e3e1Schristos { 2204e98e3e1Schristos case 0xffff: 2214e98e3e1Schristos return 2; 2224e98e3e1Schristos case 0xfffff: 2234e98e3e1Schristos case 0xffffff: 2244e98e3e1Schristos return 3; 2254e98e3e1Schristos default: 2264e98e3e1Schristos fprintf (stderr, 2274e98e3e1Schristos "m32c minisim: addr_mask_size: unexpected mask 0x%x\n", 2284e98e3e1Schristos addr_mask); 2294e98e3e1Schristos return sizeof (addr_mask); 2304e98e3e1Schristos } 2314e98e3e1Schristos } 2324e98e3e1Schristos 2334e98e3e1Schristos static size_t 2344e98e3e1Schristos reg_size (enum m32c_sim_reg regno) 2354e98e3e1Schristos { 2364e98e3e1Schristos switch (regno) 2374e98e3e1Schristos { 2384e98e3e1Schristos case m32c_sim_reg_r0_bank0: 2394e98e3e1Schristos case m32c_sim_reg_r1_bank0: 2404e98e3e1Schristos case m32c_sim_reg_r2_bank0: 2414e98e3e1Schristos case m32c_sim_reg_r3_bank0: 2424e98e3e1Schristos case m32c_sim_reg_r0_bank1: 2434e98e3e1Schristos case m32c_sim_reg_r1_bank1: 2444e98e3e1Schristos case m32c_sim_reg_r2_bank1: 2454e98e3e1Schristos case m32c_sim_reg_r3_bank1: 2464e98e3e1Schristos case m32c_sim_reg_flg: 2474e98e3e1Schristos case m32c_sim_reg_svf: 2484e98e3e1Schristos return 2; 2494e98e3e1Schristos 2504e98e3e1Schristos case m32c_sim_reg_a0_bank0: 2514e98e3e1Schristos case m32c_sim_reg_a1_bank0: 2524e98e3e1Schristos case m32c_sim_reg_fb_bank0: 2534e98e3e1Schristos case m32c_sim_reg_sb_bank0: 2544e98e3e1Schristos case m32c_sim_reg_a0_bank1: 2554e98e3e1Schristos case m32c_sim_reg_a1_bank1: 2564e98e3e1Schristos case m32c_sim_reg_fb_bank1: 2574e98e3e1Schristos case m32c_sim_reg_sb_bank1: 2584e98e3e1Schristos case m32c_sim_reg_usp: 2594e98e3e1Schristos case m32c_sim_reg_isp: 2604e98e3e1Schristos return mask_size (addr_mask); 2614e98e3e1Schristos 2624e98e3e1Schristos case m32c_sim_reg_pc: 2634e98e3e1Schristos case m32c_sim_reg_intb: 2644e98e3e1Schristos case m32c_sim_reg_svp: 2654e98e3e1Schristos case m32c_sim_reg_vct: 2664e98e3e1Schristos return mask_size (membus_mask); 2674e98e3e1Schristos 2684e98e3e1Schristos case m32c_sim_reg_dmd0: 2694e98e3e1Schristos case m32c_sim_reg_dmd1: 2704e98e3e1Schristos return 1; 2714e98e3e1Schristos 2724e98e3e1Schristos case m32c_sim_reg_dct0: 2734e98e3e1Schristos case m32c_sim_reg_dct1: 2744e98e3e1Schristos case m32c_sim_reg_drc0: 2754e98e3e1Schristos case m32c_sim_reg_drc1: 2764e98e3e1Schristos return 2; 2774e98e3e1Schristos 2784e98e3e1Schristos case m32c_sim_reg_dma0: 2794e98e3e1Schristos case m32c_sim_reg_dma1: 2804e98e3e1Schristos case m32c_sim_reg_dsa0: 2814e98e3e1Schristos case m32c_sim_reg_dsa1: 2824e98e3e1Schristos case m32c_sim_reg_dra0: 2834e98e3e1Schristos case m32c_sim_reg_dra1: 2844e98e3e1Schristos return 3; 2854e98e3e1Schristos 2864e98e3e1Schristos default: 2874e98e3e1Schristos fprintf (stderr, "m32c minisim: unrecognized register number: %d\n", 2884e98e3e1Schristos regno); 2894e98e3e1Schristos return -1; 2904e98e3e1Schristos } 2914e98e3e1Schristos } 2924e98e3e1Schristos 2934e98e3e1Schristos int 2944b169a6bSchristos sim_fetch_register (SIM_DESC sd, int regno, void *buf, int length) 2954e98e3e1Schristos { 2964e98e3e1Schristos size_t size; 2974e98e3e1Schristos 2984e98e3e1Schristos check_desc (sd); 2994e98e3e1Schristos 3004e98e3e1Schristos if (!check_regno (regno)) 3014e98e3e1Schristos return 0; 3024e98e3e1Schristos 3034e98e3e1Schristos size = reg_size (regno); 3044e98e3e1Schristos if (length == size) 3054e98e3e1Schristos { 3064e98e3e1Schristos DI val; 3074e98e3e1Schristos 3084e98e3e1Schristos switch (regno) 3094e98e3e1Schristos { 3104e98e3e1Schristos case m32c_sim_reg_r0_bank0: 3114e98e3e1Schristos val = regs.r[0].r_r0; 3124e98e3e1Schristos break; 3134e98e3e1Schristos case m32c_sim_reg_r1_bank0: 3144e98e3e1Schristos val = regs.r[0].r_r1; 3154e98e3e1Schristos break; 3164e98e3e1Schristos case m32c_sim_reg_r2_bank0: 3174e98e3e1Schristos val = regs.r[0].r_r2; 3184e98e3e1Schristos break; 3194e98e3e1Schristos case m32c_sim_reg_r3_bank0: 3204e98e3e1Schristos val = regs.r[0].r_r3; 3214e98e3e1Schristos break; 3224e98e3e1Schristos case m32c_sim_reg_a0_bank0: 3234e98e3e1Schristos val = regs.r[0].r_a0; 3244e98e3e1Schristos break; 3254e98e3e1Schristos case m32c_sim_reg_a1_bank0: 3264e98e3e1Schristos val = regs.r[0].r_a1; 3274e98e3e1Schristos break; 3284e98e3e1Schristos case m32c_sim_reg_fb_bank0: 3294e98e3e1Schristos val = regs.r[0].r_fb; 3304e98e3e1Schristos break; 3314e98e3e1Schristos case m32c_sim_reg_sb_bank0: 3324e98e3e1Schristos val = regs.r[0].r_sb; 3334e98e3e1Schristos break; 3344e98e3e1Schristos case m32c_sim_reg_r0_bank1: 3354e98e3e1Schristos val = regs.r[1].r_r0; 3364e98e3e1Schristos break; 3374e98e3e1Schristos case m32c_sim_reg_r1_bank1: 3384e98e3e1Schristos val = regs.r[1].r_r1; 3394e98e3e1Schristos break; 3404e98e3e1Schristos case m32c_sim_reg_r2_bank1: 3414e98e3e1Schristos val = regs.r[1].r_r2; 3424e98e3e1Schristos break; 3434e98e3e1Schristos case m32c_sim_reg_r3_bank1: 3444e98e3e1Schristos val = regs.r[1].r_r3; 3454e98e3e1Schristos break; 3464e98e3e1Schristos case m32c_sim_reg_a0_bank1: 3474e98e3e1Schristos val = regs.r[1].r_a0; 3484e98e3e1Schristos break; 3494e98e3e1Schristos case m32c_sim_reg_a1_bank1: 3504e98e3e1Schristos val = regs.r[1].r_a1; 3514e98e3e1Schristos break; 3524e98e3e1Schristos case m32c_sim_reg_fb_bank1: 3534e98e3e1Schristos val = regs.r[1].r_fb; 3544e98e3e1Schristos break; 3554e98e3e1Schristos case m32c_sim_reg_sb_bank1: 3564e98e3e1Schristos val = regs.r[1].r_sb; 3574e98e3e1Schristos break; 3584e98e3e1Schristos 3594e98e3e1Schristos case m32c_sim_reg_usp: 3604e98e3e1Schristos val = regs.r_usp; 3614e98e3e1Schristos break; 3624e98e3e1Schristos case m32c_sim_reg_isp: 3634e98e3e1Schristos val = regs.r_isp; 3644e98e3e1Schristos break; 3654e98e3e1Schristos case m32c_sim_reg_pc: 3664e98e3e1Schristos val = regs.r_pc; 3674e98e3e1Schristos break; 3684e98e3e1Schristos case m32c_sim_reg_intb: 3694e98e3e1Schristos val = regs.r_intbl * 65536 + regs.r_intbl; 3704e98e3e1Schristos break; 3714e98e3e1Schristos case m32c_sim_reg_flg: 3724e98e3e1Schristos val = regs.r_flags; 3734e98e3e1Schristos break; 3744e98e3e1Schristos 3754e98e3e1Schristos /* These registers aren't implemented by the minisim. */ 3764e98e3e1Schristos case m32c_sim_reg_svf: 3774e98e3e1Schristos case m32c_sim_reg_svp: 3784e98e3e1Schristos case m32c_sim_reg_vct: 3794e98e3e1Schristos case m32c_sim_reg_dmd0: 3804e98e3e1Schristos case m32c_sim_reg_dmd1: 3814e98e3e1Schristos case m32c_sim_reg_dct0: 3824e98e3e1Schristos case m32c_sim_reg_dct1: 3834e98e3e1Schristos case m32c_sim_reg_drc0: 3844e98e3e1Schristos case m32c_sim_reg_drc1: 3854e98e3e1Schristos case m32c_sim_reg_dma0: 3864e98e3e1Schristos case m32c_sim_reg_dma1: 3874e98e3e1Schristos case m32c_sim_reg_dsa0: 3884e98e3e1Schristos case m32c_sim_reg_dsa1: 3894e98e3e1Schristos case m32c_sim_reg_dra0: 3904e98e3e1Schristos case m32c_sim_reg_dra1: 3914e98e3e1Schristos return 0; 3924e98e3e1Schristos 3934e98e3e1Schristos default: 3944e98e3e1Schristos fprintf (stderr, "m32c minisim: unrecognized register number: %d\n", 3954e98e3e1Schristos regno); 3964e98e3e1Schristos return -1; 3974e98e3e1Schristos } 3984e98e3e1Schristos 3994e98e3e1Schristos put_le (buf, length, val); 4004e98e3e1Schristos } 4014e98e3e1Schristos 4024e98e3e1Schristos return size; 4034e98e3e1Schristos } 4044e98e3e1Schristos 4054e98e3e1Schristos int 4064b169a6bSchristos sim_store_register (SIM_DESC sd, int regno, const void *buf, int length) 4074e98e3e1Schristos { 4084e98e3e1Schristos size_t size; 4094e98e3e1Schristos 4104e98e3e1Schristos check_desc (sd); 4114e98e3e1Schristos 4124e98e3e1Schristos if (!check_regno (regno)) 4134e98e3e1Schristos return -1; 4144e98e3e1Schristos 4154e98e3e1Schristos size = reg_size (regno); 4164e98e3e1Schristos 4174e98e3e1Schristos if (length == size) 4184e98e3e1Schristos { 4194e98e3e1Schristos DI val = get_le (buf, length); 4204e98e3e1Schristos 4214e98e3e1Schristos switch (regno) 4224e98e3e1Schristos { 4234e98e3e1Schristos case m32c_sim_reg_r0_bank0: 4244e98e3e1Schristos regs.r[0].r_r0 = val & 0xffff; 4254e98e3e1Schristos break; 4264e98e3e1Schristos case m32c_sim_reg_r1_bank0: 4274e98e3e1Schristos regs.r[0].r_r1 = val & 0xffff; 4284e98e3e1Schristos break; 4294e98e3e1Schristos case m32c_sim_reg_r2_bank0: 4304e98e3e1Schristos regs.r[0].r_r2 = val & 0xffff; 4314e98e3e1Schristos break; 4324e98e3e1Schristos case m32c_sim_reg_r3_bank0: 4334e98e3e1Schristos regs.r[0].r_r3 = val & 0xffff; 4344e98e3e1Schristos break; 4354e98e3e1Schristos case m32c_sim_reg_a0_bank0: 4364e98e3e1Schristos regs.r[0].r_a0 = val & addr_mask; 4374e98e3e1Schristos break; 4384e98e3e1Schristos case m32c_sim_reg_a1_bank0: 4394e98e3e1Schristos regs.r[0].r_a1 = val & addr_mask; 4404e98e3e1Schristos break; 4414e98e3e1Schristos case m32c_sim_reg_fb_bank0: 4424e98e3e1Schristos regs.r[0].r_fb = val & addr_mask; 4434e98e3e1Schristos break; 4444e98e3e1Schristos case m32c_sim_reg_sb_bank0: 4454e98e3e1Schristos regs.r[0].r_sb = val & addr_mask; 4464e98e3e1Schristos break; 4474e98e3e1Schristos case m32c_sim_reg_r0_bank1: 4484e98e3e1Schristos regs.r[1].r_r0 = val & 0xffff; 4494e98e3e1Schristos break; 4504e98e3e1Schristos case m32c_sim_reg_r1_bank1: 4514e98e3e1Schristos regs.r[1].r_r1 = val & 0xffff; 4524e98e3e1Schristos break; 4534e98e3e1Schristos case m32c_sim_reg_r2_bank1: 4544e98e3e1Schristos regs.r[1].r_r2 = val & 0xffff; 4554e98e3e1Schristos break; 4564e98e3e1Schristos case m32c_sim_reg_r3_bank1: 4574e98e3e1Schristos regs.r[1].r_r3 = val & 0xffff; 4584e98e3e1Schristos break; 4594e98e3e1Schristos case m32c_sim_reg_a0_bank1: 4604e98e3e1Schristos regs.r[1].r_a0 = val & addr_mask; 4614e98e3e1Schristos break; 4624e98e3e1Schristos case m32c_sim_reg_a1_bank1: 4634e98e3e1Schristos regs.r[1].r_a1 = val & addr_mask; 4644e98e3e1Schristos break; 4654e98e3e1Schristos case m32c_sim_reg_fb_bank1: 4664e98e3e1Schristos regs.r[1].r_fb = val & addr_mask; 4674e98e3e1Schristos break; 4684e98e3e1Schristos case m32c_sim_reg_sb_bank1: 4694e98e3e1Schristos regs.r[1].r_sb = val & addr_mask; 4704e98e3e1Schristos break; 4714e98e3e1Schristos 4724e98e3e1Schristos case m32c_sim_reg_usp: 4734e98e3e1Schristos regs.r_usp = val & addr_mask; 4744e98e3e1Schristos break; 4754e98e3e1Schristos case m32c_sim_reg_isp: 4764e98e3e1Schristos regs.r_isp = val & addr_mask; 4774e98e3e1Schristos break; 4784e98e3e1Schristos case m32c_sim_reg_pc: 4794e98e3e1Schristos regs.r_pc = val & membus_mask; 4804e98e3e1Schristos break; 4814e98e3e1Schristos case m32c_sim_reg_intb: 4824e98e3e1Schristos regs.r_intbl = (val & membus_mask) & 0xffff; 4834e98e3e1Schristos regs.r_intbh = (val & membus_mask) >> 16; 4844e98e3e1Schristos break; 4854e98e3e1Schristos case m32c_sim_reg_flg: 4864e98e3e1Schristos regs.r_flags = val & 0xffff; 4874e98e3e1Schristos break; 4884e98e3e1Schristos 4894e98e3e1Schristos /* These registers aren't implemented by the minisim. */ 4904e98e3e1Schristos case m32c_sim_reg_svf: 4914e98e3e1Schristos case m32c_sim_reg_svp: 4924e98e3e1Schristos case m32c_sim_reg_vct: 4934e98e3e1Schristos case m32c_sim_reg_dmd0: 4944e98e3e1Schristos case m32c_sim_reg_dmd1: 4954e98e3e1Schristos case m32c_sim_reg_dct0: 4964e98e3e1Schristos case m32c_sim_reg_dct1: 4974e98e3e1Schristos case m32c_sim_reg_drc0: 4984e98e3e1Schristos case m32c_sim_reg_drc1: 4994e98e3e1Schristos case m32c_sim_reg_dma0: 5004e98e3e1Schristos case m32c_sim_reg_dma1: 5014e98e3e1Schristos case m32c_sim_reg_dsa0: 5024e98e3e1Schristos case m32c_sim_reg_dsa1: 5034e98e3e1Schristos case m32c_sim_reg_dra0: 5044e98e3e1Schristos case m32c_sim_reg_dra1: 5054e98e3e1Schristos return 0; 5064e98e3e1Schristos 5074e98e3e1Schristos default: 5084e98e3e1Schristos fprintf (stderr, "m32c minisim: unrecognized register number: %d\n", 5094e98e3e1Schristos regno); 5104e98e3e1Schristos return 0; 5114e98e3e1Schristos } 5124e98e3e1Schristos } 5134e98e3e1Schristos 5144e98e3e1Schristos return size; 5154e98e3e1Schristos } 5164e98e3e1Schristos 5174e98e3e1Schristos static volatile int stop; 5184e98e3e1Schristos static enum sim_stop reason; 519212397c6Schristos static int siggnal; 5204e98e3e1Schristos 5214e98e3e1Schristos 5224e98e3e1Schristos /* Given a signal number used by the M32C bsp (that is, newlib), 5234e98e3e1Schristos return a target signal number used by GDB. */ 524212397c6Schristos static int 5254e98e3e1Schristos m32c_signal_to_target (int m32c) 5264e98e3e1Schristos { 5274e98e3e1Schristos switch (m32c) 5284e98e3e1Schristos { 5294e98e3e1Schristos case 4: 530a2e2270fSchristos return GDB_SIGNAL_ILL; 5314e98e3e1Schristos 5324e98e3e1Schristos case 5: 533a2e2270fSchristos return GDB_SIGNAL_TRAP; 5344e98e3e1Schristos 5354e98e3e1Schristos case 10: 536a2e2270fSchristos return GDB_SIGNAL_BUS; 5374e98e3e1Schristos 5384e98e3e1Schristos case 11: 539a2e2270fSchristos return GDB_SIGNAL_SEGV; 5404e98e3e1Schristos 5414e98e3e1Schristos case 24: 542a2e2270fSchristos return GDB_SIGNAL_XCPU; 5434e98e3e1Schristos 5444e98e3e1Schristos case 2: 545a2e2270fSchristos return GDB_SIGNAL_INT; 5464e98e3e1Schristos 5474e98e3e1Schristos case 8: 548a2e2270fSchristos return GDB_SIGNAL_FPE; 5494e98e3e1Schristos 5504e98e3e1Schristos case 6: 551a2e2270fSchristos return GDB_SIGNAL_ABRT; 5524e98e3e1Schristos } 5534e98e3e1Schristos 5544e98e3e1Schristos return 0; 5554e98e3e1Schristos } 5564e98e3e1Schristos 5574e98e3e1Schristos 5584e98e3e1Schristos /* Take a step return code RC and set up the variables consulted by 5594e98e3e1Schristos sim_stop_reason appropriately. */ 560212397c6Schristos static void 5614e98e3e1Schristos handle_step (int rc) 5624e98e3e1Schristos { 5634e98e3e1Schristos if (M32C_STEPPED (rc) || M32C_HIT_BREAK (rc)) 5644e98e3e1Schristos { 5654e98e3e1Schristos reason = sim_stopped; 566a2e2270fSchristos siggnal = GDB_SIGNAL_TRAP; 5674e98e3e1Schristos } 5684e98e3e1Schristos else if (M32C_STOPPED (rc)) 5694e98e3e1Schristos { 5704e98e3e1Schristos reason = sim_stopped; 5714e98e3e1Schristos siggnal = m32c_signal_to_target (M32C_STOP_SIG (rc)); 5724e98e3e1Schristos } 5734e98e3e1Schristos else 5744e98e3e1Schristos { 5754e98e3e1Schristos assert (M32C_EXITED (rc)); 5764e98e3e1Schristos reason = sim_exited; 5774e98e3e1Schristos siggnal = M32C_EXIT_STATUS (rc); 5784e98e3e1Schristos } 5794e98e3e1Schristos } 5804e98e3e1Schristos 5814e98e3e1Schristos 5824e98e3e1Schristos void 5834e98e3e1Schristos sim_resume (SIM_DESC sd, int step, int sig_to_deliver) 5844e98e3e1Schristos { 5854e98e3e1Schristos check_desc (sd); 5864e98e3e1Schristos 5874e98e3e1Schristos if (sig_to_deliver != 0) 5884e98e3e1Schristos { 5894e98e3e1Schristos fprintf (stderr, 5904e98e3e1Schristos "Warning: the m32c minisim does not implement " 5914e98e3e1Schristos "signal delivery yet.\n" "Resuming with no signal.\n"); 5924e98e3e1Schristos } 5934e98e3e1Schristos 5944e98e3e1Schristos if (step) 5954e98e3e1Schristos { 5964e98e3e1Schristos handle_step (decode_opcode ()); 5974e98e3e1Schristos #ifdef TIMER_A 5984e98e3e1Schristos update_timer_a (); 5994e98e3e1Schristos #endif 6004e98e3e1Schristos } 6014e98e3e1Schristos else 6024e98e3e1Schristos { 6034e98e3e1Schristos /* We don't clear 'stop' here, because then we would miss 6044e98e3e1Schristos interrupts that arrived on the way here. Instead, we clear 6054e98e3e1Schristos the flag in sim_stop_reason, after GDB has disabled the 6064e98e3e1Schristos interrupt signal handler. */ 6074e98e3e1Schristos for (;;) 6084e98e3e1Schristos { 609212397c6Schristos int rc; 610212397c6Schristos 6114e98e3e1Schristos if (stop) 6124e98e3e1Schristos { 6134e98e3e1Schristos stop = 0; 6144e98e3e1Schristos reason = sim_stopped; 615a2e2270fSchristos siggnal = GDB_SIGNAL_INT; 6164e98e3e1Schristos break; 6174e98e3e1Schristos } 6184e98e3e1Schristos 619212397c6Schristos rc = decode_opcode (); 6204e98e3e1Schristos #ifdef TIMER_A 6214e98e3e1Schristos update_timer_a (); 6224e98e3e1Schristos #endif 6234e98e3e1Schristos 6244e98e3e1Schristos if (!M32C_STEPPED (rc)) 6254e98e3e1Schristos { 6264e98e3e1Schristos handle_step (rc); 6274e98e3e1Schristos break; 6284e98e3e1Schristos } 6294e98e3e1Schristos } 6304e98e3e1Schristos } 6314e98e3e1Schristos m32c_sim_restore_console (); 6324e98e3e1Schristos } 6334e98e3e1Schristos 6344e98e3e1Schristos int 6354e98e3e1Schristos sim_stop (SIM_DESC sd) 6364e98e3e1Schristos { 6374e98e3e1Schristos stop = 1; 6384e98e3e1Schristos 6394e98e3e1Schristos return 1; 6404e98e3e1Schristos } 6414e98e3e1Schristos 6424e98e3e1Schristos void 6434e98e3e1Schristos sim_stop_reason (SIM_DESC sd, enum sim_stop *reason_p, int *sigrc_p) 6444e98e3e1Schristos { 6454e98e3e1Schristos check_desc (sd); 6464e98e3e1Schristos 6474e98e3e1Schristos *reason_p = reason; 6484e98e3e1Schristos *sigrc_p = siggnal; 6494e98e3e1Schristos } 6504e98e3e1Schristos 6514e98e3e1Schristos void 652b23b2582Schristos sim_do_command (SIM_DESC sd, const char *cmd) 6534e98e3e1Schristos { 6544b169a6bSchristos const char *arg; 6554b169a6bSchristos char **argv = buildargv (cmd); 6564e98e3e1Schristos 657b23b2582Schristos check_desc (sd); 6584e98e3e1Schristos 6594b169a6bSchristos cmd = arg = ""; 6604b169a6bSchristos if (argv != NULL) 6614e98e3e1Schristos { 6624b169a6bSchristos if (argv[0] != NULL) 6634b169a6bSchristos cmd = argv[0]; 6644b169a6bSchristos if (argv[1] != NULL) 6654b169a6bSchristos arg = argv[1]; 6664e98e3e1Schristos } 6674e98e3e1Schristos 6684e98e3e1Schristos if (strcmp (cmd, "trace") == 0) 6694e98e3e1Schristos { 6704b169a6bSchristos if (strcmp (arg, "on") == 0) 6714e98e3e1Schristos trace = 1; 6724b169a6bSchristos else if (strcmp (arg, "off") == 0) 6734e98e3e1Schristos trace = 0; 6744e98e3e1Schristos else 6754e98e3e1Schristos printf ("The 'sim trace' command expects 'on' or 'off' " 6764e98e3e1Schristos "as an argument.\n"); 6774e98e3e1Schristos } 6784e98e3e1Schristos else if (strcmp (cmd, "verbose") == 0) 6794e98e3e1Schristos { 6804b169a6bSchristos if (strcmp (arg, "on") == 0) 6814e98e3e1Schristos verbose = 1; 6824b169a6bSchristos else if (strcmp (arg, "off") == 0) 6834e98e3e1Schristos verbose = 0; 6844e98e3e1Schristos else 6854e98e3e1Schristos printf ("The 'sim verbose' command expects 'on' or 'off'" 6864e98e3e1Schristos " as an argument.\n"); 6874e98e3e1Schristos } 6884e98e3e1Schristos else 6894e98e3e1Schristos printf ("The 'sim' command expects either 'trace' or 'verbose'" 6904e98e3e1Schristos " as a subcommand.\n"); 691b23b2582Schristos 6924b169a6bSchristos freeargv (argv); 6934e98e3e1Schristos } 694a2e2270fSchristos 695a2e2270fSchristos char ** 69603467a24Schristos sim_complete_command (SIM_DESC sd, const char *text, const char *word) 697a2e2270fSchristos { 698a2e2270fSchristos return NULL; 699a2e2270fSchristos } 700ba340e45Schristos 7014b169a6bSchristos char * 7024b169a6bSchristos sim_memory_map (SIM_DESC sd) 7034b169a6bSchristos { 7044b169a6bSchristos return NULL; 7054b169a6bSchristos } 7064b169a6bSchristos 707ba340e45Schristos void 708*71f62182Schristos sim_info (SIM_DESC sd, bool verbose) 709ba340e45Schristos { 710ba340e45Schristos printf ("The m32c minisim doesn't collect any statistics.\n"); 711ba340e45Schristos } 712