]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/m68hc11/interp.c
* dv-m68hc11sio.c (m68hc11sio_tx_poll): Always check for
[thirdparty/binutils-gdb.git] / sim / m68hc11 / interp.c
CommitLineData
e0709f50
AC
1/* interp.c -- Simulator for Motorola 68HC11
2 Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@worldnet.fr)
4
5This file is part of GDB, the GNU debugger.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License along
18with this program; if not, write to the Free Software Foundation, Inc.,
1959 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#include "sim-main.h"
22#include "sim-assert.h"
23#include "sim-hw.h"
24#include "sim-options.h"
25#include "hw-tree.h"
26#include "hw-device.h"
27#include "hw-ports.h"
28
29#ifndef MONITOR_BASE
30# define MONITOR_BASE (0x0C000)
31# define MONITOR_SIZE (0x04000)
32#endif
33
34static void sim_get_info (SIM_DESC sd, char *cmd);
35
36
37char *interrupt_names[] = {
38 "reset",
39 "nmi",
40 "int",
41 NULL
42};
43
44#ifndef INLINE
45#if defined(__GNUC__) && defined(__OPTIMIZE__)
46#define INLINE __inline__
47#else
48#define INLINE
49#endif
50#endif
51
52struct sim_info_list
53{
54 const char *name;
55 const char *device;
56};
57
58struct sim_info_list dev_list[] = {
59 {"cpu", "/m68hc11"},
60 {"timer", "/m68hc11/m68hc11tim"},
61 {"sio", "/m68hc11/m68hc11sio"},
62 {"spi", "/m68hc11/m68hc11spi"},
63 {"eeprom", "/m68hc11/m68hc11eepr"},
64 {0, 0}
65};
66
67/* Give some information about the simulator. */
68static void
69sim_get_info (SIM_DESC sd, char *cmd)
70{
71 sim_cpu *cpu;
72
73 if (cmd != 0 && (cmd[0] == ' ' || cmd[0] == '-'))
74 {
75 int i;
76 struct hw *hw_dev;
77 cmd++;
78
79 for (i = 0; dev_list[i].name; i++)
80 if (strcmp (cmd, dev_list[i].name) == 0)
81 break;
82
83 if (dev_list[i].name == 0)
84 {
85 sim_io_eprintf (sd, "Device '%s' not found.\n", cmd);
86 sim_io_eprintf (sd, "Valid devices: cpu timer sio eeprom\n");
87 return;
88 }
89 hw_dev = sim_hw_parse (sd, dev_list[i].device);
90 if (hw_dev == 0)
91 {
92 sim_io_eprintf (sd, "Device '%s' not found\n", dev_list[i].device);
93 return;
94 }
95 hw_ioctl (hw_dev, 23, 0);
96 return;
97 }
98
99 cpu = STATE_CPU (sd, 0);
100 cpu_info (sd, cpu);
101 interrupts_info (sd, &cpu->cpu_interrupts);
102}
103
104
105void
106sim_board_reset (SIM_DESC sd)
107{
108 struct hw *hw_cpu;
109 sim_cpu *cpu;
110
111 cpu = STATE_CPU (sd, 0);
112 /* hw_cpu = sim_hw_parse (sd, "/"); */
113 hw_cpu = sim_hw_parse (sd, "/m68hc11");
114 if (hw_cpu == 0)
115 {
116 sim_io_eprintf (sd, "m68hc11 cpu not found in device tree.");
117 return;
118 }
119
120 cpu_reset (cpu);
121 hw_port_event (hw_cpu, 3, 0);
122 cpu_restart (cpu);
123}
124
125SIM_DESC
126sim_open (SIM_OPEN_KIND kind, host_callback *callback,
127 struct _bfd *abfd, char **argv)
128{
129 char **p;
130 SIM_DESC sd;
131 sim_cpu *cpu;
132 struct hw *device_tree;
133
134 sd = sim_state_alloc (kind, callback);
135 cpu = STATE_CPU (sd, 0);
136
137 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
138
139 /* for compatibility */
140 current_alignment = NONSTRICT_ALIGNMENT;
141 current_target_byte_order = BIG_ENDIAN;
142
143 cpu_initialize (sd, cpu);
144
145 cpu->cpu_use_elf_start = 1;
146 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
147 return 0;
148
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
151 print_filtered. */
152 if (sim_parse_args (sd, argv) != SIM_RC_OK)
153 {
154 /* Uninstall the modules to avoid memory leaks,
155 file descriptor leaks, etc. */
156 sim_module_uninstall (sd);
157 return 0;
158 }
159
160 device_tree = sim_hw_parse (sd, "/");
161 if (hw_tree_find_property (device_tree, "/m68hc11/reg") == 0)
162 {
163 /* Allocate core managed memory */
164
165 /* the monitor */
63348d04 166 sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
e0709f50 167 /* MONITOR_BASE, MONITOR_SIZE */
63348d04
SC
168 0x8000, M6811_RAM_LEVEL, 0x8000);
169 sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
170 M6811_RAM_LEVEL);
e0709f50
AC
171 sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
172 }
173
174 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
175 {
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");
179 }
180 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11tim/reg") == 0)
181 {
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");
185 }
186
187 /* Create the SPI device. */
188 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11spi/reg") == 0)
189 {
190 sim_hw_parse (sd, "/m68hc11/m68hc11spi/reg 0x28 0x3");
191 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
192 }
193 if (hw_tree_find_property (device_tree, "/m68hc11/pram/reg") == 0)
194 {
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");
e0709f50
AC
199 /*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
200 }
201 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11eepr/reg") == 0)
202 {
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");
206 }
207
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)
213 {
214 sim_module_uninstall (sd);
215 return 0;
216 }
217
218 /* Establish any remaining configuration options. */
219 if (sim_config (sd) != SIM_RC_OK)
220 {
221 sim_module_uninstall (sd);
222 return 0;
223 }
224
225 if (sim_post_argv_init (sd) != SIM_RC_OK)
226 {
227 /* Uninstall the modules to avoid memory leaks,
228 file descriptor leaks, etc. */
229 sim_module_uninstall (sd);
230 return 0;
231 }
232
233 if (abfd != NULL)
234 {
235 cpu->cpu_elf_start = bfd_get_start_address (abfd);
236 }
237
238 sim_board_reset (sd);
239
240 /* Fudge our descriptor. */
241 return sd;
242}
243
244
245void
246sim_close (SIM_DESC sd, int quitting)
247{
248 /* shut down modules */
249 sim_module_uninstall (sd);
250
251 /* Ensure that any resources allocated through the callback
252 mechanism are released: */
253 sim_io_shutdown (sd);
254
255 /* FIXME - free SD */
256
257 return;
258}
259
260void
261sim_set_profile (int n)
262{
263}
264
265void
266sim_set_profile_size (int n)
267{
268}
269
270/* Generic implementation of sim_engine_run that works within the
271 sim_engine setjmp/longjmp framework. */
272
273void
274sim_engine_run (SIM_DESC sd,
275 int next_cpu_nr, /* ignore */
276 int nr_cpus, /* ignore */
277 int siggnal) /* ignore */
278{
279 sim_cpu *cpu;
280
281 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
282 cpu = STATE_CPU (sd, 0);
283 while (1)
284 {
285 cpu_single_step (cpu);
286
287 /* process any events */
288 if (sim_events_tickn (sd, cpu->cpu_current_cycle))
289 {
290 sim_events_process (sd);
291 }
292 }
293}
294
295int
296sim_trace (SIM_DESC sd)
297{
298 sim_resume (sd, 0, 0);
299 return 1;
300}
301
302void
303sim_info (SIM_DESC sd, int verbose)
304{
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));
309}
310
311SIM_RC
312sim_create_inferior (SIM_DESC sd, struct _bfd *abfd,
313 char **argv, char **env)
314{
315 sim_cpu *cpu;
316 int i;
317
318 cpu = STATE_CPU (sd, 0);
319
320 if (abfd != NULL)
321 {
322 cpu->cpu_elf_start = bfd_get_start_address (abfd);
323 }
324
325 /* reset all state information */
326 sim_board_reset (sd);
327
e0709f50
AC
328 return SIM_RC_OK;
329}
330
331
332void
333sim_set_callbacks (host_callback *p)
334{
335 /* m6811_callback = p; */
336}
337
338
339int
340sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
341{
342 sim_cpu *cpu;
343 uint16 val;
344
345 cpu = STATE_CPU (sd, 0);
346 switch (rn)
347 {
348 case A_REGNUM:
349 val = cpu_get_a (cpu);
350 break;
351
352 case B_REGNUM:
353 val = cpu_get_b (cpu);
354 break;
355
356 case D_REGNUM:
357 val = cpu_get_d (cpu);
358 break;
359
360 case X_REGNUM:
361 val = cpu_get_x (cpu);
362 break;
363
364 case Y_REGNUM:
365 val = cpu_get_y (cpu);
366 break;
367
368 case SP_REGNUM:
369 val = cpu_get_sp (cpu);
370 break;
371
372 case PC_REGNUM:
373 val = cpu_get_pc (cpu);
374 break;
375
376 case PSW_REGNUM:
377 val = cpu_get_ccr (cpu);
378 break;
379
e0709f50 380 default:
9830501b 381 val = 0;
e0709f50
AC
382 break;
383 }
384 memory[0] = val >> 8;
385 memory[1] = val & 0x0FF;
386 return 2;
387}
388
389int
390sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
391{
392 uint16 val;
393 sim_cpu *cpu;
394
395 cpu = STATE_CPU (sd, 0);
396
397 val = *memory++;
398 if (length == 2)
399 val = (val << 8) | *memory;
400
401 switch (rn)
402 {
403 case D_REGNUM:
404 cpu_set_d (cpu, val);
405 break;
406
407 case A_REGNUM:
408 cpu_set_a (cpu, val);
409 break;
410
411 case B_REGNUM:
412 cpu_set_b (cpu, val);
413 break;
414
415 case X_REGNUM:
416 cpu_set_x (cpu, val);
417 break;
418
419 case Y_REGNUM:
420 cpu_set_y (cpu, val);
421 break;
422
423 case SP_REGNUM:
424 cpu_set_sp (cpu, val);
425 break;
426
427 case PC_REGNUM:
428 cpu_set_pc (cpu, val);
429 break;
430
431 case PSW_REGNUM:
432 cpu_set_ccr (cpu, val);
433 break;
434
e0709f50 435 default:
e0709f50
AC
436 break;
437 }
438
439 return 2;
440}
441
442void
443sim_size (int s)
444{
445 ;
446}
447
448void
449sim_do_command (SIM_DESC sd, char *cmd)
450{
451 char *mm_cmd = "memory-map";
452 char *int_cmd = "interrupt";
453
454 /* Commands available from GDB: */
455 if (sim_args_command (sd, cmd) != SIM_RC_OK)
456 {
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))
462 sim_io_eprintf (sd,
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");
466 else
467 sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
468 }
469}