1 /* interp.c -- Simulator for Motorola 68HC11
2 Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@worldnet.fr)
5 This file is part of GDB, the GNU debugger.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include "sim-assert.h"
24 #include "sim-options.h"
26 #include "hw-device.h"
30 # define MONITOR_BASE (0x0C000)
31 # define MONITOR_SIZE (0x04000)
34 static void sim_get_info (SIM_DESC sd
, char *cmd
);
37 char *interrupt_names
[] = {
45 #if defined(__GNUC__) && defined(__OPTIMIZE__)
46 #define INLINE __inline__
58 struct sim_info_list dev_list
[] = {
60 {"timer", "/m68hc11/m68hc11tim"},
61 {"sio", "/m68hc11/m68hc11sio"},
62 {"spi", "/m68hc11/m68hc11spi"},
63 {"eeprom", "/m68hc11/m68hc11eepr"},
67 /* Give some information about the simulator. */
69 sim_get_info (SIM_DESC sd
, char *cmd
)
73 if (cmd
!= 0 && (cmd
[0] == ' ' || cmd
[0] == '-'))
79 for (i
= 0; dev_list
[i
].name
; i
++)
80 if (strcmp (cmd
, dev_list
[i
].name
) == 0)
83 if (dev_list
[i
].name
== 0)
85 sim_io_eprintf (sd
, "Device '%s' not found.\n", cmd
);
86 sim_io_eprintf (sd
, "Valid devices: cpu timer sio eeprom\n");
89 hw_dev
= sim_hw_parse (sd
, dev_list
[i
].device
);
92 sim_io_eprintf (sd
, "Device '%s' not found\n", dev_list
[i
].device
);
95 hw_ioctl (hw_dev
, 23, 0);
99 cpu
= STATE_CPU (sd
, 0);
101 interrupts_info (sd
, &cpu
->cpu_interrupts
);
106 sim_board_reset (SIM_DESC sd
)
111 cpu
= STATE_CPU (sd
, 0);
112 /* hw_cpu = sim_hw_parse (sd, "/"); */
113 hw_cpu
= sim_hw_parse (sd
, "/m68hc11");
116 sim_io_eprintf (sd
, "m68hc11 cpu not found in device tree.");
121 hw_port_event (hw_cpu
, 3, 0);
126 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
127 struct _bfd
*abfd
, char **argv
)
132 struct hw
*device_tree
;
134 sd
= sim_state_alloc (kind
, callback
);
135 cpu
= STATE_CPU (sd
, 0);
137 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
139 /* for compatibility */
140 current_alignment
= NONSTRICT_ALIGNMENT
;
141 current_target_byte_order
= BIG_ENDIAN
;
143 cpu_initialize (sd
, cpu
);
145 cpu
->cpu_use_elf_start
= 1;
146 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
149 /* getopt will print the error message so we just have to exit if this fails.
150 FIXME: Hmmm... in the case of gdb we need getopt to call
152 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
154 /* Uninstall the modules to avoid memory leaks,
155 file descriptor leaks, etc. */
156 sim_module_uninstall (sd
);
160 device_tree
= sim_hw_parse (sd
, "/");
161 if (hw_tree_find_property (device_tree
, "/m68hc11/reg") == 0)
163 /* Allocate core managed memory */
166 sim_do_commandf (sd
, "memory region 0x%lx@%d,0x%lx",
167 /* MONITOR_BASE, MONITOR_SIZE */
168 0x8000, M6811_RAM_LEVEL
, 0x8000);
169 sim_do_commandf (sd
, "memory region 0x000@%d,0x8000",
171 sim_hw_parse (sd
, "/m68hc11/reg 0x1000 0x03F");
174 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11sio/reg") == 0)
176 sim_hw_parse (sd
, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
177 sim_hw_parse (sd
, "/m68hc11/m68hc11sio/backend stdio");
178 sim_hw_parse (sd
, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11sio");
180 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11tim/reg") == 0)
182 /* M68hc11 Timer configuration. */
183 sim_hw_parse (sd
, "/m68hc11/m68hc11tim/reg 0x1b 0x5");
184 sim_hw_parse (sd
, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11tim");
187 /* Create the SPI device. */
188 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11spi/reg") == 0)
190 sim_hw_parse (sd
, "/m68hc11/m68hc11spi/reg 0x28 0x3");
191 sim_hw_parse (sd
, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
193 if (hw_tree_find_property (device_tree
, "/m68hc11/pram/reg") == 0)
195 /* M68hc11 persistent ram configuration. */
196 sim_hw_parse (sd
, "/m68hc11/nvram/reg 0x0 256");
197 sim_hw_parse (sd
, "/m68hc11/nvram/file m68hc11.ram");
198 sim_hw_parse (sd
, "/m68hc11/nvram/mode save-modified");
199 /*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
201 if (hw_tree_find_property (device_tree
, "/m68hc11/m68hc11eepr/reg") == 0)
203 sim_hw_parse (sd
, "/m68hc11/m68hc11eepr/reg 0xb000 512");
204 /* Connect the CPU reset to all devices. */
205 sim_hw_parse (sd
, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
208 /* Check for/establish the a reference program image. */
209 if (sim_analyze_program (sd
,
210 (STATE_PROG_ARGV (sd
) != NULL
211 ? *STATE_PROG_ARGV (sd
)
212 : NULL
), abfd
) != SIM_RC_OK
)
214 sim_module_uninstall (sd
);
218 /* Establish any remaining configuration options. */
219 if (sim_config (sd
) != SIM_RC_OK
)
221 sim_module_uninstall (sd
);
225 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
227 /* Uninstall the modules to avoid memory leaks,
228 file descriptor leaks, etc. */
229 sim_module_uninstall (sd
);
235 cpu
->cpu_elf_start
= bfd_get_start_address (abfd
);
238 sim_board_reset (sd
);
240 /* Fudge our descriptor. */
246 sim_close (SIM_DESC sd
, int quitting
)
248 /* shut down modules */
249 sim_module_uninstall (sd
);
251 /* Ensure that any resources allocated through the callback
252 mechanism are released: */
253 sim_io_shutdown (sd
);
255 /* FIXME - free SD */
261 sim_set_profile (int n
)
266 sim_set_profile_size (int n
)
270 /* Generic implementation of sim_engine_run that works within the
271 sim_engine setjmp/longjmp framework. */
274 sim_engine_run (SIM_DESC sd
,
275 int next_cpu_nr
, /* ignore */
276 int nr_cpus
, /* ignore */
277 int siggnal
) /* ignore */
281 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
282 cpu
= STATE_CPU (sd
, 0);
285 cpu_single_step (cpu
);
287 /* process any events */
288 if (sim_events_tickn (sd
, cpu
->cpu_current_cycle
))
290 sim_events_process (sd
);
296 sim_trace (SIM_DESC sd
)
298 sim_resume (sd
, 0, 0);
303 sim_info (SIM_DESC sd
, int verbose
)
305 sim_io_eprintf (sd
, "Simulator info:\n");
306 sim_io_eprintf (sd
, " CPU Motorola 68HC11\n");
307 sim_get_info (sd
, 0);
308 sim_module_info (sd
, verbose
|| STATE_VERBOSE_P (sd
));
312 sim_create_inferior (SIM_DESC sd
, struct _bfd
*abfd
,
313 char **argv
, char **env
)
318 cpu
= STATE_CPU (sd
, 0);
322 cpu
->cpu_elf_start
= bfd_get_start_address (abfd
);
325 /* reset all state information */
326 sim_board_reset (sd
);
333 sim_set_callbacks (host_callback
*p
)
335 /* m6811_callback = p; */
340 sim_fetch_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
345 cpu
= STATE_CPU (sd
, 0);
349 val
= cpu_get_a (cpu
);
353 val
= cpu_get_b (cpu
);
357 val
= cpu_get_d (cpu
);
361 val
= cpu_get_x (cpu
);
365 val
= cpu_get_y (cpu
);
369 val
= cpu_get_sp (cpu
);
373 val
= cpu_get_pc (cpu
);
377 val
= cpu_get_ccr (cpu
);
384 memory
[0] = val
>> 8;
385 memory
[1] = val
& 0x0FF;
390 sim_store_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
395 cpu
= STATE_CPU (sd
, 0);
399 val
= (val
<< 8) | *memory
;
404 cpu_set_d (cpu
, val
);
408 cpu_set_a (cpu
, val
);
412 cpu_set_b (cpu
, val
);
416 cpu_set_x (cpu
, val
);
420 cpu_set_y (cpu
, val
);
424 cpu_set_sp (cpu
, val
);
428 cpu_set_pc (cpu
, val
);
432 cpu_set_ccr (cpu
, val
);
449 sim_do_command (SIM_DESC sd
, char *cmd
)
451 char *mm_cmd
= "memory-map";
452 char *int_cmd
= "interrupt";
454 /* Commands available from GDB: */
455 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
457 if (strncmp (cmd
, "info", sizeof ("info") - 1) == 0)
458 sim_get_info (sd
, &cmd
[4]);
459 else if (strncmp (cmd
, "frame", sizeof ("frame") - 1) == 0)
460 cpu_print_frame (sd
, STATE_CPU (sd
, 0));
461 else if (strncmp (cmd
, mm_cmd
, strlen (mm_cmd
) == 0))
463 "`memory-map' command replaced by `sim memory'\n");
464 else if (strncmp (cmd
, int_cmd
, strlen (int_cmd
)) == 0)
465 sim_io_eprintf (sd
, "`interrupt' command replaced by `sim watch'\n");
467 sim_io_eprintf (sd
, "Unknown command `%s'\n", cmd
);