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