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