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
);
328 /* Get information about the number of pseudo registers. */
329 for (i
= FIRST_SOFT_REGNUM
; i
<= ZD32_REGNUM
; i
++)
334 cpu
->cpu_page0_reg
[i
- FIRST_SOFT_REGNUM
] = 0;
338 cpu
->cpu_page0_reg
[i
- FIRST_SOFT_REGNUM
] = 2;
341 cpu
->cpu_page0_reg
[i
- FIRST_SOFT_REGNUM
] = 4;
344 cpu
->cpu_page0_reg
[i
- FIRST_SOFT_REGNUM
] = 6;
347 cpu
->cpu_page0_reg
[i
- FIRST_SOFT_REGNUM
]
348 = ((i
- FIRST_SOFT_REGNUM
) * 2) - 2;
352 cpu
->cpu_nb_pseudo_regs
= 8;
359 sim_set_callbacks (host_callback
*p
)
361 /* m6811_callback = p; */
366 sim_fetch_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
371 cpu
= STATE_CPU (sd
, 0);
375 val
= cpu_get_a (cpu
);
379 val
= cpu_get_b (cpu
);
383 val
= cpu_get_d (cpu
);
387 val
= cpu_get_x (cpu
);
391 val
= cpu_get_y (cpu
);
395 val
= cpu_get_sp (cpu
);
399 val
= cpu_get_pc (cpu
);
403 val
= cpu_get_ccr (cpu
);
407 /* Read a pseudo register. Pseudo registers are located at
408 beginning of page 0. Each of them is 2 bytes. */
410 if (rn
< FIRST_SOFT_REGNUM
|| rn
>= ZD32_REGNUM
)
418 addr
= cpu
->cpu_page0_reg
[rn
- FIRST_SOFT_REGNUM
];
419 val
= memory_read16 (cpu
, addr
);
423 memory
[0] = val
>> 8;
424 memory
[1] = val
& 0x0FF;
429 sim_store_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
434 cpu
= STATE_CPU (sd
, 0);
438 val
= (val
<< 8) | *memory
;
443 cpu_set_d (cpu
, val
);
447 cpu_set_a (cpu
, val
);
451 cpu_set_b (cpu
, val
);
455 cpu_set_x (cpu
, val
);
459 cpu_set_y (cpu
, val
);
463 cpu_set_sp (cpu
, val
);
467 cpu_set_pc (cpu
, val
);
471 cpu_set_ccr (cpu
, val
);
474 /* Write a pseudo register. Pseudo registers are located at
475 beginning of page 0. Each of them is 2 bytes. */
477 if (rn
>= FIRST_SOFT_REGNUM
&& rn
<= ZD32_REGNUM
)
481 addr
= cpu
->cpu_page0_reg
[rn
- FIRST_SOFT_REGNUM
];
482 memory_write16 (cpu
, addr
, val
);
497 sim_do_command (SIM_DESC sd
, char *cmd
)
499 char *mm_cmd
= "memory-map";
500 char *int_cmd
= "interrupt";
502 /* Commands available from GDB: */
503 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
505 if (strncmp (cmd
, "info", sizeof ("info") - 1) == 0)
506 sim_get_info (sd
, &cmd
[4]);
507 else if (strncmp (cmd
, "frame", sizeof ("frame") - 1) == 0)
508 cpu_print_frame (sd
, STATE_CPU (sd
, 0));
509 else if (strncmp (cmd
, mm_cmd
, strlen (mm_cmd
) == 0))
511 "`memory-map' command replaced by `sim memory'\n");
512 else if (strncmp (cmd
, int_cmd
, strlen (int_cmd
)) == 0)
513 sim_io_eprintf (sd
, "`interrupt' command replaced by `sim watch'\n");
515 sim_io_eprintf (sd
, "Unknown command `%s'\n", cmd
);