sim: unify sim-cpu usage
[deliverable/binutils-gdb.git] / sim / m68hc11 / interp.c
CommitLineData
5abb9efa 1/* interp.c -- Simulator for Motorola 68HC11/68HC12
32d0add0 2 Copyright (C) 1999-2015 Free Software Foundation, Inc.
63f36def 3 Written by Stephane Carrez (stcarrez@nerim.fr)
e0709f50
AC
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
4744ac1b
JB
9the Free Software Foundation; either version 3 of the License, or
10(at your option) any later version.
e0709f50
AC
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
4744ac1b
JB
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>. */
e0709f50
AC
19
20#include "sim-main.h"
21#include "sim-assert.h"
22#include "sim-hw.h"
23#include "sim-options.h"
24#include "hw-tree.h"
25#include "hw-device.h"
26#include "hw-ports.h"
77342e5e 27#include "elf32-m68hc1x.h"
e0709f50
AC
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
81e09ed8 58struct sim_info_list dev_list_68hc11[] = {
e0709f50
AC
59 {"cpu", "/m68hc11"},
60 {"timer", "/m68hc11/m68hc11tim"},
61 {"sio", "/m68hc11/m68hc11sio"},
62 {"spi", "/m68hc11/m68hc11spi"},
63 {"eeprom", "/m68hc11/m68hc11eepr"},
64 {0, 0}
65};
66
81e09ed8
SC
67struct sim_info_list dev_list_68hc12[] = {
68 {"cpu", "/m68hc12"},
69 {"timer", "/m68hc12/m68hc12tim"},
70 {"sio", "/m68hc12/m68hc12sio"},
71 {"spi", "/m68hc12/m68hc12spi"},
72 {"eeprom", "/m68hc12/m68hc12eepr"},
73 {0, 0}
74};
75
76/* Cover function of sim_state_free to free the cpu buffers as well. */
77
78static void
79free_state (SIM_DESC sd)
80{
81 if (STATE_MODULES (sd) != NULL)
82 sim_module_uninstall (sd);
83
84 sim_state_free (sd);
85}
86
e0709f50
AC
87/* Give some information about the simulator. */
88static void
89sim_get_info (SIM_DESC sd, char *cmd)
90{
91 sim_cpu *cpu;
92
81e09ed8 93 cpu = STATE_CPU (sd, 0);
e0709f50
AC
94 if (cmd != 0 && (cmd[0] == ' ' || cmd[0] == '-'))
95 {
96 int i;
97 struct hw *hw_dev;
81e09ed8
SC
98 struct sim_info_list *dev_list;
99 const struct bfd_arch_info *arch;
100
101 arch = STATE_ARCHITECTURE (sd);
e0709f50
AC
102 cmd++;
103
81e09ed8
SC
104 if (arch->arch == bfd_arch_m68hc11)
105 dev_list = dev_list_68hc11;
106 else
107 dev_list = dev_list_68hc12;
108
e0709f50
AC
109 for (i = 0; dev_list[i].name; i++)
110 if (strcmp (cmd, dev_list[i].name) == 0)
111 break;
112
113 if (dev_list[i].name == 0)
114 {
115 sim_io_eprintf (sd, "Device '%s' not found.\n", cmd);
116 sim_io_eprintf (sd, "Valid devices: cpu timer sio eeprom\n");
117 return;
118 }
119 hw_dev = sim_hw_parse (sd, dev_list[i].device);
120 if (hw_dev == 0)
121 {
122 sim_io_eprintf (sd, "Device '%s' not found\n", dev_list[i].device);
123 return;
124 }
125 hw_ioctl (hw_dev, 23, 0);
126 return;
127 }
128
e0709f50
AC
129 cpu_info (sd, cpu);
130 interrupts_info (sd, &cpu->cpu_interrupts);
131}
132
133
134void
135sim_board_reset (SIM_DESC sd)
136{
137 struct hw *hw_cpu;
138 sim_cpu *cpu;
81e09ed8
SC
139 const struct bfd_arch_info *arch;
140 const char *cpu_type;
e0709f50
AC
141
142 cpu = STATE_CPU (sd, 0);
81e09ed8
SC
143 arch = STATE_ARCHITECTURE (sd);
144
e0709f50 145 /* hw_cpu = sim_hw_parse (sd, "/"); */
81e09ed8
SC
146 if (arch->arch == bfd_arch_m68hc11)
147 {
148 cpu->cpu_type = CPU_M6811;
149 cpu_type = "/m68hc11";
150 }
151 else
152 {
153 cpu->cpu_type = CPU_M6812;
154 cpu_type = "/m68hc12";
155 }
156
157 hw_cpu = sim_hw_parse (sd, cpu_type);
e0709f50
AC
158 if (hw_cpu == 0)
159 {
81e09ed8 160 sim_io_eprintf (sd, "%s cpu not found in device tree.", cpu_type);
e0709f50
AC
161 return;
162 }
163
164 cpu_reset (cpu);
165 hw_port_event (hw_cpu, 3, 0);
166 cpu_restart (cpu);
167}
168
39762100 169static int
81e09ed8
SC
170sim_hw_configure (SIM_DESC sd)
171{
172 const struct bfd_arch_info *arch;
173 struct hw *device_tree;
81e09ed8
SC
174 sim_cpu *cpu;
175
176 arch = STATE_ARCHITECTURE (sd);
177 if (arch == 0)
178 return 0;
179
180 cpu = STATE_CPU (sd, 0);
181 cpu->cpu_configured_arch = arch;
182 device_tree = sim_hw_parse (sd, "/");
183 if (arch->arch == bfd_arch_m68hc11)
184 {
185 cpu->cpu_interpretor = cpu_interp_m6811;
186 if (hw_tree_find_property (device_tree, "/m68hc11/reg") == 0)
187 {
188 /* Allocate core managed memory */
189
190 /* the monitor */
191 sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
192 /* MONITOR_BASE, MONITOR_SIZE */
193 0x8000, M6811_RAM_LEVEL, 0x8000);
194 sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
195 M6811_RAM_LEVEL);
196 sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
77342e5e
SC
197 if (cpu->bank_start < cpu->bank_end)
198 {
199 sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
200 cpu->bank_virtual, M6811_RAM_LEVEL);
201 sim_hw_parse (sd, "/m68hc11/use_bank 1");
202 }
81e09ed8 203 }
77342e5e
SC
204 if (cpu->cpu_start_mode)
205 {
206 sim_hw_parse (sd, "/m68hc11/mode %s", cpu->cpu_start_mode);
207 }
81e09ed8
SC
208 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
209 {
210 sim_hw_parse (sd, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
211 sim_hw_parse (sd, "/m68hc11/m68hc11sio/backend stdio");
212 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11sio");
213 }
214 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11tim/reg") == 0)
215 {
216 /* M68hc11 Timer configuration. */
217 sim_hw_parse (sd, "/m68hc11/m68hc11tim/reg 0x1b 0x5");
218 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11tim");
827ec39a 219 sim_hw_parse (sd, "/m68hc11 > capture capture /m68hc11/m68hc11tim");
81e09ed8
SC
220 }
221
222 /* Create the SPI device. */
223 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11spi/reg") == 0)
224 {
225 sim_hw_parse (sd, "/m68hc11/m68hc11spi/reg 0x28 0x3");
226 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
227 }
228 if (hw_tree_find_property (device_tree, "/m68hc11/nvram/reg") == 0)
229 {
230 /* M68hc11 persistent ram configuration. */
231 sim_hw_parse (sd, "/m68hc11/nvram/reg 0x0 256");
232 sim_hw_parse (sd, "/m68hc11/nvram/file m68hc11.ram");
233 sim_hw_parse (sd, "/m68hc11/nvram/mode save-modified");
234 /*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
235 }
236 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11eepr/reg") == 0)
237 {
238 sim_hw_parse (sd, "/m68hc11/m68hc11eepr/reg 0xb000 512");
239 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
240 }
dcceded2
SC
241 sim_hw_parse (sd, "/m68hc11 > port-a cpu-write-port /m68hc11");
242 sim_hw_parse (sd, "/m68hc11 > port-b cpu-write-port /m68hc11");
243 sim_hw_parse (sd, "/m68hc11 > port-c cpu-write-port /m68hc11");
244 sim_hw_parse (sd, "/m68hc11 > port-d cpu-write-port /m68hc11");
827ec39a 245 cpu->hw_cpu = sim_hw_parse (sd, "/m68hc11");
81e09ed8
SC
246 }
247 else
248 {
249 cpu->cpu_interpretor = cpu_interp_m6812;
250 if (hw_tree_find_property (device_tree, "/m68hc12/reg") == 0)
251 {
252 /* Allocate core external memory. */
253 sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
77342e5e 254 0x8000, M6811_RAM_LEVEL, 0x8000);
81e09ed8
SC
255 sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
256 M6811_RAM_LEVEL);
77342e5e
SC
257 if (cpu->bank_start < cpu->bank_end)
258 {
259 sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
260 cpu->bank_virtual, M6811_RAM_LEVEL);
261 sim_hw_parse (sd, "/m68hc12/use_bank 1");
262 }
81e09ed8
SC
263 sim_hw_parse (sd, "/m68hc12/reg 0x0 0x3FF");
264 }
265
266 if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@1/reg"))
267 {
268 sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/reg 0xC0 0x8");
269 sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/backend stdio");
270 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12sio@1");
271 }
81e09ed8
SC
272 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12tim/reg") == 0)
273 {
274 /* M68hc11 Timer configuration. */
275 sim_hw_parse (sd, "/m68hc12/m68hc12tim/reg 0x1b 0x5");
276 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12tim");
dcceded2 277 sim_hw_parse (sd, "/m68hc12 > capture capture /m68hc12/m68hc12tim");
81e09ed8
SC
278 }
279
280 /* Create the SPI device. */
281 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12spi/reg") == 0)
282 {
283 sim_hw_parse (sd, "/m68hc12/m68hc12spi/reg 0x28 0x3");
284 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
285 }
286 if (hw_tree_find_property (device_tree, "/m68hc12/nvram/reg") == 0)
287 {
288 /* M68hc11 persistent ram configuration. */
289 sim_hw_parse (sd, "/m68hc12/nvram/reg 0x2000 8192");
290 sim_hw_parse (sd, "/m68hc12/nvram/file m68hc12.ram");
291 sim_hw_parse (sd, "/m68hc12/nvram/mode save-modified");
292 }
293 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12eepr/reg") == 0)
294 {
295 sim_hw_parse (sd, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
296 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
297 }
827ec39a 298
dcceded2
SC
299 sim_hw_parse (sd, "/m68hc12 > port-a cpu-write-port /m68hc12");
300 sim_hw_parse (sd, "/m68hc12 > port-b cpu-write-port /m68hc12");
301 sim_hw_parse (sd, "/m68hc12 > port-c cpu-write-port /m68hc12");
302 sim_hw_parse (sd, "/m68hc12 > port-d cpu-write-port /m68hc12");
827ec39a 303 cpu->hw_cpu = sim_hw_parse (sd, "/m68hc12");
81e09ed8 304 }
39762100 305 return 1;
81e09ed8
SC
306}
307
77342e5e
SC
308/* Get the memory bank parameters by looking at the global symbols
309 defined by the linker. */
81e09ed8 310static int
77342e5e 311sim_get_bank_parameters (SIM_DESC sd, bfd* abfd)
81e09ed8
SC
312{
313 sim_cpu *cpu;
77342e5e
SC
314 long symsize;
315 long symbol_count, i;
316 unsigned size;
317 asymbol** asymbols;
318 asymbol** current;
81e09ed8
SC
319
320 cpu = STATE_CPU (sd, 0);
321
77342e5e
SC
322 symsize = bfd_get_symtab_upper_bound (abfd);
323 if (symsize < 0)
324 {
325 sim_io_eprintf (sd, "Cannot read symbols of program");
326 return 0;
327 }
328 asymbols = (asymbol **) xmalloc (symsize);
329 symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
330 if (symbol_count < 0)
331 {
332 sim_io_eprintf (sd, "Cannot read symbols of program");
333 return 0;
334 }
335
336 size = 0;
337 for (i = 0, current = asymbols; i < symbol_count; i++, current++)
338 {
339 const char* name = bfd_asymbol_name (*current);
340
341 if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0)
342 {
343 cpu->bank_start = bfd_asymbol_value (*current);
344 }
345 else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0)
346 {
347 size = bfd_asymbol_value (*current);
348 }
349 else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0)
350 {
351 cpu->bank_virtual = bfd_asymbol_value (*current);
352 }
353 }
354 free (asymbols);
355
356 cpu->bank_end = cpu->bank_start + size;
357 cpu->bank_shift = 0;
358 for (; size > 1; size >>= 1)
359 cpu->bank_shift++;
360
361 return 0;
362}
363
364static int
365sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
366{
367 sim_cpu *cpu;
368 int elf_flags = 0;
369
370 cpu = STATE_CPU (sd, 0);
39762100 371
81e09ed8
SC
372 if (abfd != NULL)
373 {
31c7c532 374 asection *s;
77342e5e
SC
375
376 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
377 elf_flags = elf_elfheader (abfd)->e_flags;
378
81e09ed8 379 cpu->cpu_elf_start = bfd_get_start_address (abfd);
31c7c532
SC
380 /* See if any section sets the reset address */
381 cpu->cpu_use_elf_start = 1;
382 for (s = abfd->sections; s && cpu->cpu_use_elf_start; s = s->next)
383 {
384 if (s->flags & SEC_LOAD)
385 {
386 bfd_size_type size;
387
84b11e2e 388 size = bfd_get_section_size (s);
31c7c532
SC
389 if (size > 0)
390 {
391 bfd_vma lma;
392
393 if (STATE_LOAD_AT_LMA_P (sd))
394 lma = bfd_section_lma (abfd, s);
395 else
396 lma = bfd_section_vma (abfd, s);
397
398 if (lma <= 0xFFFE && lma+size >= 0x10000)
399 cpu->cpu_use_elf_start = 0;
400 }
401 }
402 }
77342e5e
SC
403
404 if (elf_flags & E_M68HC12_BANKS)
405 {
406 if (sim_get_bank_parameters (sd, abfd) != 0)
407 sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
408 }
81e09ed8
SC
409 }
410
77342e5e
SC
411 if (!sim_hw_configure (sd))
412 return SIM_RC_FAIL;
413
81e09ed8
SC
414 /* reset all state information */
415 sim_board_reset (sd);
416
417 return SIM_RC_OK;
418}
419
bea3f671
MF
420static sim_cia
421m68hc11_pc_get (sim_cpu *cpu)
422{
423 return cpu_get_pc (cpu);
424}
425
426static void
427m68hc11_pc_set (sim_cpu *cpu, sim_cia pc)
428{
429 cpu_set_pc (cpu, pc);
430}
431
e0709f50
AC
432SIM_DESC
433sim_open (SIM_OPEN_KIND kind, host_callback *callback,
77342e5e 434 bfd *abfd, char **argv)
e0709f50 435{
bea3f671 436 int i;
e0709f50
AC
437 SIM_DESC sd;
438 sim_cpu *cpu;
e0709f50
AC
439
440 sd = sim_state_alloc (kind, callback);
e0709f50
AC
441
442 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
443
bea3f671
MF
444 /* The cpu data is kept in a separately allocated chunk of memory. */
445 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
446 {
447 free_state (sd);
448 return 0;
449 }
450
451 cpu = STATE_CPU (sd, 0);
452
e0709f50
AC
453 /* for compatibility */
454 current_alignment = NONSTRICT_ALIGNMENT;
455 current_target_byte_order = BIG_ENDIAN;
456
457 cpu_initialize (sd, cpu);
458
e0709f50 459 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
81e09ed8
SC
460 {
461 free_state (sd);
462 return 0;
463 }
e0709f50
AC
464
465 /* getopt will print the error message so we just have to exit if this fails.
466 FIXME: Hmmm... in the case of gdb we need getopt to call
467 print_filtered. */
468 if (sim_parse_args (sd, argv) != SIM_RC_OK)
469 {
470 /* Uninstall the modules to avoid memory leaks,
471 file descriptor leaks, etc. */
81e09ed8 472 free_state (sd);
e0709f50
AC
473 return 0;
474 }
475
e0709f50
AC
476 /* Check for/establish the a reference program image. */
477 if (sim_analyze_program (sd,
478 (STATE_PROG_ARGV (sd) != NULL
479 ? *STATE_PROG_ARGV (sd)
480 : NULL), abfd) != SIM_RC_OK)
481 {
81e09ed8 482 free_state (sd);
e0709f50
AC
483 return 0;
484 }
485
486 /* Establish any remaining configuration options. */
487 if (sim_config (sd) != SIM_RC_OK)
488 {
81e09ed8 489 free_state (sd);
e0709f50
AC
490 return 0;
491 }
492
493 if (sim_post_argv_init (sd) != SIM_RC_OK)
494 {
495 /* Uninstall the modules to avoid memory leaks,
496 file descriptor leaks, etc. */
81e09ed8 497 free_state (sd);
e0709f50
AC
498 return 0;
499 }
77342e5e
SC
500 if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK)
501 {
502 free_state (sd);
503 return 0;
504 }
e0709f50 505
bea3f671
MF
506 /* CPU specific initialization. */
507 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
508 {
509 SIM_CPU *cpu = STATE_CPU (sd, i);
510
511 CPU_PC_FETCH (cpu) = m68hc11_pc_get;
512 CPU_PC_STORE (cpu) = m68hc11_pc_set;
513 }
514
e0709f50
AC
515 return sd;
516}
517
518
519void
520sim_close (SIM_DESC sd, int quitting)
521{
522 /* shut down modules */
523 sim_module_uninstall (sd);
524
525 /* Ensure that any resources allocated through the callback
526 mechanism are released: */
527 sim_io_shutdown (sd);
528
529 /* FIXME - free SD */
81e09ed8 530 sim_state_free (sd);
e0709f50
AC
531 return;
532}
533
e0709f50
AC
534/* Generic implementation of sim_engine_run that works within the
535 sim_engine setjmp/longjmp framework. */
536
537void
538sim_engine_run (SIM_DESC sd,
539 int next_cpu_nr, /* ignore */
540 int nr_cpus, /* ignore */
541 int siggnal) /* ignore */
542{
543 sim_cpu *cpu;
544
545 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
546 cpu = STATE_CPU (sd, 0);
547 while (1)
548 {
549 cpu_single_step (cpu);
550
551 /* process any events */
552 if (sim_events_tickn (sd, cpu->cpu_current_cycle))
553 {
554 sim_events_process (sd);
555 }
556 }
557}
558
e0709f50
AC
559void
560sim_info (SIM_DESC sd, int verbose)
561{
81e09ed8
SC
562 const char *cpu_type;
563 const struct bfd_arch_info *arch;
564
00d0c012
SC
565 /* Nothing to do if there is no verbose flag set. */
566 if (verbose == 0 && STATE_VERBOSE_P (sd) == 0)
567 return;
568
81e09ed8
SC
569 arch = STATE_ARCHITECTURE (sd);
570 if (arch->arch == bfd_arch_m68hc11)
571 cpu_type = "68HC11";
572 else
573 cpu_type = "68HC12";
574
e0709f50 575 sim_io_eprintf (sd, "Simulator info:\n");
81e09ed8 576 sim_io_eprintf (sd, " CPU Motorola %s\n", cpu_type);
e0709f50
AC
577 sim_get_info (sd, 0);
578 sim_module_info (sd, verbose || STATE_VERBOSE_P (sd));
579}
580
581SIM_RC
6b4a8935 582sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
e0709f50
AC
583 char **argv, char **env)
584{
81e09ed8 585 return sim_prepare_for_program (sd, abfd);
e0709f50
AC
586}
587
e0709f50
AC
588int
589sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
590{
591 sim_cpu *cpu;
592 uint16 val;
63f36def 593 int size = 2;
e0709f50
AC
594
595 cpu = STATE_CPU (sd, 0);
596 switch (rn)
597 {
598 case A_REGNUM:
599 val = cpu_get_a (cpu);
63f36def 600 size = 1;
e0709f50
AC
601 break;
602
603 case B_REGNUM:
604 val = cpu_get_b (cpu);
63f36def 605 size = 1;
e0709f50
AC
606 break;
607
608 case D_REGNUM:
609 val = cpu_get_d (cpu);
610 break;
611
612 case X_REGNUM:
613 val = cpu_get_x (cpu);
614 break;
615
616 case Y_REGNUM:
617 val = cpu_get_y (cpu);
618 break;
619
620 case SP_REGNUM:
621 val = cpu_get_sp (cpu);
622 break;
623
624 case PC_REGNUM:
625 val = cpu_get_pc (cpu);
626 break;
627
628 case PSW_REGNUM:
629 val = cpu_get_ccr (cpu);
63f36def
SC
630 size = 1;
631 break;
632
633 case PAGE_REGNUM:
634 val = cpu_get_page (cpu);
635 size = 1;
e0709f50
AC
636 break;
637
e0709f50 638 default:
9830501b 639 val = 0;
e0709f50
AC
640 break;
641 }
00416c6e
SC
642 if (size == 1)
643 {
644 memory[0] = val;
645 }
646 else
647 {
648 memory[0] = val >> 8;
649 memory[1] = val & 0x0FF;
650 }
63f36def 651 return size;
e0709f50
AC
652}
653
654int
655sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
656{
657 uint16 val;
658 sim_cpu *cpu;
659
660 cpu = STATE_CPU (sd, 0);
661
662 val = *memory++;
663 if (length == 2)
664 val = (val << 8) | *memory;
665
666 switch (rn)
667 {
668 case D_REGNUM:
669 cpu_set_d (cpu, val);
670 break;
671
672 case A_REGNUM:
673 cpu_set_a (cpu, val);
63f36def 674 return 1;
e0709f50
AC
675
676 case B_REGNUM:
677 cpu_set_b (cpu, val);
63f36def 678 return 1;
e0709f50
AC
679
680 case X_REGNUM:
681 cpu_set_x (cpu, val);
682 break;
683
684 case Y_REGNUM:
685 cpu_set_y (cpu, val);
686 break;
687
688 case SP_REGNUM:
689 cpu_set_sp (cpu, val);
690 break;
691
692 case PC_REGNUM:
693 cpu_set_pc (cpu, val);
694 break;
695
696 case PSW_REGNUM:
697 cpu_set_ccr (cpu, val);
63f36def
SC
698 return 1;
699
700 case PAGE_REGNUM:
701 cpu_set_page (cpu, val);
702 return 1;
e0709f50 703
e0709f50 704 default:
e0709f50
AC
705 break;
706 }
707
708 return 2;
709}
710
00d0c012
SC
711/* Halt the simulator after just one instruction */
712
713static void
714has_stepped (SIM_DESC sd,
715 void *data)
716{
717 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
718 sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
719}
720
721
722/* Generic resume - assumes the existance of sim_engine_run */
723
724void
725sim_resume (SIM_DESC sd,
726 int step,
727 int siggnal)
728{
729 sim_engine *engine = STATE_ENGINE (sd);
730 jmp_buf buf;
731 int jmpval;
732
733 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
734
735 /* we only want to be single stepping the simulator once */
736 if (engine->stepper != NULL)
737 {
738 sim_events_deschedule (sd, engine->stepper);
739 engine->stepper = NULL;
740 }
741 sim_module_resume (sd);
742
743 /* run/resume the simulator */
744 engine->jmpbuf = &buf;
745 jmpval = setjmp (buf);
746 if (jmpval == sim_engine_start_jmpval
747 || jmpval == sim_engine_restart_jmpval)
748 {
749 int last_cpu_nr = sim_engine_last_cpu_nr (sd);
750 int next_cpu_nr = sim_engine_next_cpu_nr (sd);
751 int nr_cpus = sim_engine_nr_cpus (sd);
752
753 sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
754 if (next_cpu_nr >= nr_cpus)
755 next_cpu_nr = 0;
756
757 /* Only deliver the siggnal ]sic] the first time through - don't
758 re-deliver any siggnal during a restart. */
759 if (jmpval == sim_engine_restart_jmpval)
760 siggnal = 0;
761
762 /* Install the stepping event after having processed some
763 pending events. This is necessary for HC11/HC12 simulator
764 because the tick counter is incremented by the number of cycles
765 the instruction took. Some pending ticks to process can still
766 be recorded internally by the simulator and sim_events_preprocess
767 will handle them. If the stepping event is inserted before,
768 these pending ticks will raise the event and the simulator will
769 stop without having executed any instruction. */
770 if (step)
771 engine->stepper = sim_events_schedule (sd, 0, has_stepped, sd);
772
773#ifdef SIM_CPU_EXCEPTION_RESUME
774 {
775 sim_cpu* cpu = STATE_CPU (sd, next_cpu_nr);
776 SIM_CPU_EXCEPTION_RESUME(sd, cpu, siggnal);
777 }
778#endif
779
780 sim_engine_run (sd, next_cpu_nr, nr_cpus, siggnal);
781 }
782 engine->jmpbuf = NULL;
783
784 sim_module_suspend (sd);
785}
This page took 0.670015 seconds and 4 git commands to generate.