mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-15 04:31:49 +08:00
fd3619828e
This large patch removes the unnecessary bfd parameter from various bfd section macros and functions. The bfd is hardly ever used and if needed for the bfd_set_section_* or bfd_rename_section functions can be found via section->owner except for the com, und, abs, and ind std_section special sections. Those sections shouldn't be modified anyway. The patch also removes various bfd_get_section_<field> macros, replacing their use with bfd_section_<field>, and adds bfd_set_section_lma. I've also fixed a minor bug in gas where compressed section renaming was done directly rather than calling bfd_rename_section. This would have broken bfd_get_section_by_name and similar functions, but that hardly mattered at such a late stage in gas processing. bfd/ * bfd-in.h (bfd_get_section_name, bfd_get_section_vma), (bfd_get_section_lma, bfd_get_section_alignment), (bfd_get_section_size, bfd_get_section_flags), (bfd_get_section_userdata): Delete. (bfd_section_name, bfd_section_size, bfd_section_vma), (bfd_section_lma, bfd_section_alignment): Lose bfd parameter. (bfd_section_flags, bfd_section_userdata): New. (bfd_is_com_section): Rename parameter. * section.c (bfd_set_section_userdata, bfd_set_section_vma), (bfd_set_section_alignment, bfd_set_section_flags, bfd_rename_section), (bfd_set_section_size): Delete bfd parameter, rename section parameter. (bfd_set_section_lma): New. * bfd-in2.h: Regenerate. * mach-o.c (bfd_mach_o_init_section_from_mach_o): Delete bfd param, update callers. * aoutx.h, * bfd.c, * coff-alpha.c, * coff-arm.c, * coff-mips.c, * coff64-rs6000.c, * coffcode.h, * coffgen.c, * cofflink.c, * compress.c, * ecoff.c, * elf-eh-frame.c, * elf-hppa.h, * elf-ifunc.c, * elf-m10200.c, * elf-m10300.c, * elf-properties.c, * elf-s390-common.c, * elf-vxworks.c, * elf.c, * elf32-arc.c, * elf32-arm.c, * elf32-avr.c, * elf32-bfin.c, * elf32-cr16.c, * elf32-cr16c.c, * elf32-cris.c, * elf32-crx.c, * elf32-csky.c, * elf32-d10v.c, * elf32-epiphany.c, * elf32-fr30.c, * elf32-frv.c, * elf32-ft32.c, * elf32-h8300.c, * elf32-hppa.c, * elf32-i386.c, * elf32-ip2k.c, * elf32-iq2000.c, * elf32-lm32.c, * elf32-m32c.c, * elf32-m32r.c, * elf32-m68hc1x.c, * elf32-m68k.c, * elf32-mcore.c, * elf32-mep.c, * elf32-metag.c, * elf32-microblaze.c, * elf32-moxie.c, * elf32-msp430.c, * elf32-mt.c, * elf32-nds32.c, * elf32-nios2.c, * elf32-or1k.c, * elf32-ppc.c, * elf32-pru.c, * elf32-rl78.c, * elf32-rx.c, * elf32-s390.c, * elf32-score.c, * elf32-score7.c, * elf32-sh.c, * elf32-spu.c, * elf32-tic6x.c, * elf32-tilepro.c, * elf32-v850.c, * elf32-vax.c, * elf32-visium.c, * elf32-xstormy16.c, * elf32-xtensa.c, * elf64-alpha.c, * elf64-bpf.c, * elf64-hppa.c, * elf64-ia64-vms.c, * elf64-mmix.c, * elf64-ppc.c, * elf64-s390.c, * elf64-sparc.c, * elf64-x86-64.c, * elflink.c, * elfnn-aarch64.c, * elfnn-ia64.c, * elfnn-riscv.c, * elfxx-aarch64.c, * elfxx-mips.c, * elfxx-sparc.c, * elfxx-tilegx.c, * elfxx-x86.c, * i386msdos.c, * linker.c, * mach-o.c, * mmo.c, * opncls.c, * pdp11.c, * pei-x86_64.c, * peicode.h, * reloc.c, * section.c, * syms.c, * vms-alpha.c, * xcofflink.c: Update throughout for bfd section macro and function changes. binutils/ * addr2line.c, * bucomm.c, * coffgrok.c, * dlltool.c, * nm.c, * objcopy.c, * objdump.c, * od-elf32_avr.c, * od-macho.c, * od-xcoff.c, * prdbg.c, * rdcoff.c, * rddbg.c, * rescoff.c, * resres.c, * size.c, * srconv.c, * strings.c, * windmc.c: Update throughout for bfd section macro and function changes. gas/ * as.c, * as.h, * dw2gencfi.c, * dwarf2dbg.c, * ecoff.c, * read.c, * stabs.c, * subsegs.c, * subsegs.h, * write.c, * config/obj-coff-seh.c, * config/obj-coff.c, * config/obj-ecoff.c, * config/obj-elf.c, * config/obj-macho.c, * config/obj-som.c, * config/tc-aarch64.c, * config/tc-alpha.c, * config/tc-arc.c, * config/tc-arm.c, * config/tc-avr.c, * config/tc-bfin.c, * config/tc-bpf.c, * config/tc-d10v.c, * config/tc-d30v.c, * config/tc-epiphany.c, * config/tc-fr30.c, * config/tc-frv.c, * config/tc-h8300.c, * config/tc-hppa.c, * config/tc-i386.c, * config/tc-ia64.c, * config/tc-ip2k.c, * config/tc-iq2000.c, * config/tc-lm32.c, * config/tc-m32c.c, * config/tc-m32r.c, * config/tc-m68hc11.c, * config/tc-mep.c, * config/tc-microblaze.c, * config/tc-mips.c, * config/tc-mmix.c, * config/tc-mn10200.c, * config/tc-mn10300.c, * config/tc-msp430.c, * config/tc-mt.c, * config/tc-nds32.c, * config/tc-or1k.c, * config/tc-ppc.c, * config/tc-pru.c, * config/tc-rl78.c, * config/tc-rx.c, * config/tc-s12z.c, * config/tc-s390.c, * config/tc-score.c, * config/tc-score7.c, * config/tc-sh.c, * config/tc-sparc.c, * config/tc-spu.c, * config/tc-tic4x.c, * config/tc-tic54x.c, * config/tc-tic6x.c, * config/tc-tilegx.c, * config/tc-tilepro.c, * config/tc-v850.c, * config/tc-visium.c, * config/tc-wasm32.c, * config/tc-xc16x.c, * config/tc-xgate.c, * config/tc-xstormy16.c, * config/tc-xtensa.c, * config/tc-z8k.c: Update throughout for bfd section macro and function changes. * write.c (compress_debug): Use bfd_rename_section. gdb/ * aarch64-linux-tdep.c, * arm-tdep.c, * auto-load.c, * coff-pe-read.c, * coffread.c, * corelow.c, * dbxread.c, * dicos-tdep.c, * dwarf2-frame.c, * dwarf2read.c, * elfread.c, * exec.c, * fbsd-tdep.c, * gcore.c, * gdb_bfd.c, * gdb_bfd.h, * hppa-tdep.c, * i386-cygwin-tdep.c, * i386-fbsd-tdep.c, * i386-linux-tdep.c, * jit.c, * linux-tdep.c, * machoread.c, * maint.c, * mdebugread.c, * minidebug.c, * mips-linux-tdep.c, * mips-sde-tdep.c, * mips-tdep.c, * mipsread.c, * nto-tdep.c, * objfiles.c, * objfiles.h, * osabi.c, * ppc-linux-tdep.c, * ppc64-tdep.c, * record-btrace.c, * record-full.c, * remote.c, * rs6000-aix-tdep.c, * rs6000-tdep.c, * s390-linux-tdep.c, * s390-tdep.c, * solib-aix.c, * solib-dsbt.c, * solib-frv.c, * solib-spu.c, * solib-svr4.c, * solib-target.c, * spu-linux-nat.c, * spu-tdep.c, * symfile-mem.c, * symfile.c, * symmisc.c, * symtab.c, * target.c, * windows-nat.c, * xcoffread.c, * cli/cli-dump.c, * compile/compile-object-load.c, * mi/mi-interp.c: Update throughout for bfd section macro and function changes. * gcore (gcore_create_callback): Use bfd_set_section_lma. * spu-tdep.c (spu_overlay_new_objfile): Likewise. gprof/ * corefile.c, * symtab.c: Update throughout for bfd section macro and function changes. ld/ * ldcref.c, * ldctor.c, * ldelf.c, * ldlang.c, * pe-dll.c, * emultempl/aarch64elf.em, * emultempl/aix.em, * emultempl/armcoff.em, * emultempl/armelf.em, * emultempl/cr16elf.em, * emultempl/cskyelf.em, * emultempl/m68hc1xelf.em, * emultempl/m68kelf.em, * emultempl/mipself.em, * emultempl/mmix-elfnmmo.em, * emultempl/mmo.em, * emultempl/msp430.em, * emultempl/nios2elf.em, * emultempl/pe.em, * emultempl/pep.em, * emultempl/ppc64elf.em, * emultempl/xtensaelf.em: Update throughout for bfd section macro and function changes. libctf/ * ctf-open-bfd.c: Update throughout for bfd section macro changes. opcodes/ * arc-ext.c: Update throughout for bfd section macro changes. sim/ * common/sim-load.c, * common/sim-utils.c, * cris/sim-if.c, * erc32/func.c, * lm32/sim-if.c, * m32c/load.c, * m32c/trace.c, * m68hc11/interp.c, * ppc/hw_htab.c, * ppc/hw_init.c, * rl78/load.c, * rl78/trace.c, * rx/gdb-if.c, * rx/load.c, * rx/trace.c: Update throughout for bfd section macro changes.
647 lines
16 KiB
C
647 lines
16 KiB
C
/* interp.c -- Simulator for Motorola 68HC11/68HC12
|
|
Copyright (C) 1999-2019 Free Software Foundation, Inc.
|
|
Written by Stephane Carrez (stcarrez@nerim.fr)
|
|
|
|
This file is part of GDB, the GNU debugger.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
#include "sim-main.h"
|
|
#include "sim-assert.h"
|
|
#include "sim-hw.h"
|
|
#include "sim-options.h"
|
|
#include "hw-tree.h"
|
|
#include "hw-device.h"
|
|
#include "hw-ports.h"
|
|
#include "elf32-m68hc1x.h"
|
|
|
|
#ifndef MONITOR_BASE
|
|
# define MONITOR_BASE (0x0C000)
|
|
# define MONITOR_SIZE (0x04000)
|
|
#endif
|
|
|
|
static void sim_get_info (SIM_DESC sd, char *cmd);
|
|
|
|
struct sim_info_list
|
|
{
|
|
const char *name;
|
|
const char *device;
|
|
};
|
|
|
|
struct sim_info_list dev_list_68hc11[] = {
|
|
{"cpu", "/m68hc11"},
|
|
{"timer", "/m68hc11/m68hc11tim"},
|
|
{"sio", "/m68hc11/m68hc11sio"},
|
|
{"spi", "/m68hc11/m68hc11spi"},
|
|
{"eeprom", "/m68hc11/m68hc11eepr"},
|
|
{0, 0}
|
|
};
|
|
|
|
struct sim_info_list dev_list_68hc12[] = {
|
|
{"cpu", "/m68hc12"},
|
|
{"timer", "/m68hc12/m68hc12tim"},
|
|
{"sio", "/m68hc12/m68hc12sio"},
|
|
{"spi", "/m68hc12/m68hc12spi"},
|
|
{"eeprom", "/m68hc12/m68hc12eepr"},
|
|
{0, 0}
|
|
};
|
|
|
|
/* Cover function of sim_state_free to free the cpu buffers as well. */
|
|
|
|
static void
|
|
free_state (SIM_DESC sd)
|
|
{
|
|
if (STATE_MODULES (sd) != NULL)
|
|
sim_module_uninstall (sd);
|
|
|
|
sim_state_free (sd);
|
|
}
|
|
|
|
/* Give some information about the simulator. */
|
|
static void
|
|
sim_get_info (SIM_DESC sd, char *cmd)
|
|
{
|
|
sim_cpu *cpu;
|
|
|
|
cpu = STATE_CPU (sd, 0);
|
|
if (cmd != 0 && (cmd[0] == ' ' || cmd[0] == '-'))
|
|
{
|
|
int i;
|
|
struct hw *hw_dev;
|
|
struct sim_info_list *dev_list;
|
|
const struct bfd_arch_info *arch;
|
|
|
|
arch = STATE_ARCHITECTURE (sd);
|
|
cmd++;
|
|
|
|
if (arch->arch == bfd_arch_m68hc11)
|
|
dev_list = dev_list_68hc11;
|
|
else
|
|
dev_list = dev_list_68hc12;
|
|
|
|
for (i = 0; dev_list[i].name; i++)
|
|
if (strcmp (cmd, dev_list[i].name) == 0)
|
|
break;
|
|
|
|
if (dev_list[i].name == 0)
|
|
{
|
|
sim_io_eprintf (sd, "Device '%s' not found.\n", cmd);
|
|
sim_io_eprintf (sd, "Valid devices: cpu timer sio eeprom\n");
|
|
return;
|
|
}
|
|
hw_dev = sim_hw_parse (sd, dev_list[i].device);
|
|
if (hw_dev == 0)
|
|
{
|
|
sim_io_eprintf (sd, "Device '%s' not found\n", dev_list[i].device);
|
|
return;
|
|
}
|
|
hw_ioctl (hw_dev, 23, 0);
|
|
return;
|
|
}
|
|
|
|
cpu_info (sd, cpu);
|
|
interrupts_info (sd, &cpu->cpu_interrupts);
|
|
}
|
|
|
|
|
|
void
|
|
sim_board_reset (SIM_DESC sd)
|
|
{
|
|
struct hw *hw_cpu;
|
|
sim_cpu *cpu;
|
|
const struct bfd_arch_info *arch;
|
|
const char *cpu_type;
|
|
|
|
cpu = STATE_CPU (sd, 0);
|
|
arch = STATE_ARCHITECTURE (sd);
|
|
|
|
/* hw_cpu = sim_hw_parse (sd, "/"); */
|
|
if (arch->arch == bfd_arch_m68hc11)
|
|
{
|
|
cpu->cpu_type = CPU_M6811;
|
|
cpu_type = "/m68hc11";
|
|
}
|
|
else
|
|
{
|
|
cpu->cpu_type = CPU_M6812;
|
|
cpu_type = "/m68hc12";
|
|
}
|
|
|
|
hw_cpu = sim_hw_parse (sd, cpu_type);
|
|
if (hw_cpu == 0)
|
|
{
|
|
sim_io_eprintf (sd, "%s cpu not found in device tree.", cpu_type);
|
|
return;
|
|
}
|
|
|
|
cpu_reset (cpu);
|
|
hw_port_event (hw_cpu, 3, 0);
|
|
cpu_restart (cpu);
|
|
}
|
|
|
|
static int
|
|
sim_hw_configure (SIM_DESC sd)
|
|
{
|
|
const struct bfd_arch_info *arch;
|
|
struct hw *device_tree;
|
|
sim_cpu *cpu;
|
|
|
|
arch = STATE_ARCHITECTURE (sd);
|
|
if (arch == 0)
|
|
return 0;
|
|
|
|
cpu = STATE_CPU (sd, 0);
|
|
cpu->cpu_configured_arch = arch;
|
|
device_tree = sim_hw_parse (sd, "/");
|
|
if (arch->arch == bfd_arch_m68hc11)
|
|
{
|
|
cpu->cpu_interpretor = cpu_interp_m6811;
|
|
if (hw_tree_find_property (device_tree, "/m68hc11/reg") == 0)
|
|
{
|
|
/* Allocate core managed memory */
|
|
|
|
/* the monitor */
|
|
sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
|
|
/* MONITOR_BASE, MONITOR_SIZE */
|
|
0x8000, M6811_RAM_LEVEL, 0x8000);
|
|
sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
|
|
M6811_RAM_LEVEL);
|
|
sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
|
|
if (cpu->bank_start < cpu->bank_end)
|
|
{
|
|
sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
|
|
cpu->bank_virtual, M6811_RAM_LEVEL);
|
|
sim_hw_parse (sd, "/m68hc11/use_bank 1");
|
|
}
|
|
}
|
|
if (cpu->cpu_start_mode)
|
|
{
|
|
sim_hw_parse (sd, "/m68hc11/mode %s", cpu->cpu_start_mode);
|
|
}
|
|
if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
|
|
{
|
|
sim_hw_parse (sd, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
|
|
sim_hw_parse (sd, "/m68hc11/m68hc11sio/backend stdio");
|
|
sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11sio");
|
|
}
|
|
if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11tim/reg") == 0)
|
|
{
|
|
/* M68hc11 Timer configuration. */
|
|
sim_hw_parse (sd, "/m68hc11/m68hc11tim/reg 0x1b 0x5");
|
|
sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11tim");
|
|
sim_hw_parse (sd, "/m68hc11 > capture capture /m68hc11/m68hc11tim");
|
|
}
|
|
|
|
/* Create the SPI device. */
|
|
if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11spi/reg") == 0)
|
|
{
|
|
sim_hw_parse (sd, "/m68hc11/m68hc11spi/reg 0x28 0x3");
|
|
sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
|
|
}
|
|
if (hw_tree_find_property (device_tree, "/m68hc11/nvram/reg") == 0)
|
|
{
|
|
/* M68hc11 persistent ram configuration. */
|
|
sim_hw_parse (sd, "/m68hc11/nvram/reg 0x0 256");
|
|
sim_hw_parse (sd, "/m68hc11/nvram/file m68hc11.ram");
|
|
sim_hw_parse (sd, "/m68hc11/nvram/mode save-modified");
|
|
/*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
|
|
}
|
|
if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11eepr/reg") == 0)
|
|
{
|
|
sim_hw_parse (sd, "/m68hc11/m68hc11eepr/reg 0xb000 512");
|
|
sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
|
|
}
|
|
sim_hw_parse (sd, "/m68hc11 > port-a cpu-write-port /m68hc11");
|
|
sim_hw_parse (sd, "/m68hc11 > port-b cpu-write-port /m68hc11");
|
|
sim_hw_parse (sd, "/m68hc11 > port-c cpu-write-port /m68hc11");
|
|
sim_hw_parse (sd, "/m68hc11 > port-d cpu-write-port /m68hc11");
|
|
cpu->hw_cpu = sim_hw_parse (sd, "/m68hc11");
|
|
}
|
|
else
|
|
{
|
|
cpu->cpu_interpretor = cpu_interp_m6812;
|
|
if (hw_tree_find_property (device_tree, "/m68hc12/reg") == 0)
|
|
{
|
|
/* Allocate core external memory. */
|
|
sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
|
|
0x8000, M6811_RAM_LEVEL, 0x8000);
|
|
sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
|
|
M6811_RAM_LEVEL);
|
|
if (cpu->bank_start < cpu->bank_end)
|
|
{
|
|
sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
|
|
cpu->bank_virtual, M6811_RAM_LEVEL);
|
|
sim_hw_parse (sd, "/m68hc12/use_bank 1");
|
|
}
|
|
sim_hw_parse (sd, "/m68hc12/reg 0x0 0x3FF");
|
|
}
|
|
|
|
if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@1/reg"))
|
|
{
|
|
sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/reg 0xC0 0x8");
|
|
sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/backend stdio");
|
|
sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12sio@1");
|
|
}
|
|
if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12tim/reg") == 0)
|
|
{
|
|
/* M68hc11 Timer configuration. */
|
|
sim_hw_parse (sd, "/m68hc12/m68hc12tim/reg 0x1b 0x5");
|
|
sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12tim");
|
|
sim_hw_parse (sd, "/m68hc12 > capture capture /m68hc12/m68hc12tim");
|
|
}
|
|
|
|
/* Create the SPI device. */
|
|
if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12spi/reg") == 0)
|
|
{
|
|
sim_hw_parse (sd, "/m68hc12/m68hc12spi/reg 0x28 0x3");
|
|
sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
|
|
}
|
|
if (hw_tree_find_property (device_tree, "/m68hc12/nvram/reg") == 0)
|
|
{
|
|
/* M68hc11 persistent ram configuration. */
|
|
sim_hw_parse (sd, "/m68hc12/nvram/reg 0x2000 8192");
|
|
sim_hw_parse (sd, "/m68hc12/nvram/file m68hc12.ram");
|
|
sim_hw_parse (sd, "/m68hc12/nvram/mode save-modified");
|
|
}
|
|
if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12eepr/reg") == 0)
|
|
{
|
|
sim_hw_parse (sd, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
|
|
sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
|
|
}
|
|
|
|
sim_hw_parse (sd, "/m68hc12 > port-a cpu-write-port /m68hc12");
|
|
sim_hw_parse (sd, "/m68hc12 > port-b cpu-write-port /m68hc12");
|
|
sim_hw_parse (sd, "/m68hc12 > port-c cpu-write-port /m68hc12");
|
|
sim_hw_parse (sd, "/m68hc12 > port-d cpu-write-port /m68hc12");
|
|
cpu->hw_cpu = sim_hw_parse (sd, "/m68hc12");
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/* Get the memory bank parameters by looking at the global symbols
|
|
defined by the linker. */
|
|
static int
|
|
sim_get_bank_parameters (SIM_DESC sd)
|
|
{
|
|
sim_cpu *cpu;
|
|
unsigned size;
|
|
bfd_vma addr;
|
|
|
|
cpu = STATE_CPU (sd, 0);
|
|
|
|
addr = trace_sym_value (sd, BFD_M68HC11_BANK_START_NAME);
|
|
if (addr != -1)
|
|
cpu->bank_start = addr;
|
|
|
|
size = trace_sym_value (sd, BFD_M68HC11_BANK_SIZE_NAME);
|
|
if (size == -1)
|
|
size = 0;
|
|
|
|
addr = trace_sym_value (sd, BFD_M68HC11_BANK_VIRTUAL_NAME);
|
|
if (addr != -1)
|
|
cpu->bank_virtual = addr;
|
|
|
|
cpu->bank_end = cpu->bank_start + size;
|
|
cpu->bank_shift = 0;
|
|
for (; size > 1; size >>= 1)
|
|
cpu->bank_shift++;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
|
|
{
|
|
sim_cpu *cpu;
|
|
int elf_flags = 0;
|
|
|
|
cpu = STATE_CPU (sd, 0);
|
|
|
|
if (abfd != NULL)
|
|
{
|
|
asection *s;
|
|
|
|
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
|
|
elf_flags = elf_elfheader (abfd)->e_flags;
|
|
|
|
cpu->cpu_elf_start = bfd_get_start_address (abfd);
|
|
/* See if any section sets the reset address */
|
|
cpu->cpu_use_elf_start = 1;
|
|
for (s = abfd->sections; s && cpu->cpu_use_elf_start; s = s->next)
|
|
{
|
|
if (s->flags & SEC_LOAD)
|
|
{
|
|
bfd_size_type size;
|
|
|
|
size = bfd_section_size (s);
|
|
if (size > 0)
|
|
{
|
|
bfd_vma lma;
|
|
|
|
if (STATE_LOAD_AT_LMA_P (sd))
|
|
lma = bfd_section_lma (s);
|
|
else
|
|
lma = bfd_section_vma (s);
|
|
|
|
if (lma <= 0xFFFE && lma+size >= 0x10000)
|
|
cpu->cpu_use_elf_start = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (elf_flags & E_M68HC12_BANKS)
|
|
{
|
|
if (sim_get_bank_parameters (sd) != 0)
|
|
sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
|
|
}
|
|
}
|
|
|
|
if (!sim_hw_configure (sd))
|
|
return SIM_RC_FAIL;
|
|
|
|
/* reset all state information */
|
|
sim_board_reset (sd);
|
|
|
|
return SIM_RC_OK;
|
|
}
|
|
|
|
static sim_cia
|
|
m68hc11_pc_get (sim_cpu *cpu)
|
|
{
|
|
return cpu_get_pc (cpu);
|
|
}
|
|
|
|
static void
|
|
m68hc11_pc_set (sim_cpu *cpu, sim_cia pc)
|
|
{
|
|
cpu_set_pc (cpu, pc);
|
|
}
|
|
|
|
static int m68hc11_reg_fetch (SIM_CPU *, int, unsigned char *, int);
|
|
static int m68hc11_reg_store (SIM_CPU *, int, unsigned char *, int);
|
|
|
|
SIM_DESC
|
|
sim_open (SIM_OPEN_KIND kind, host_callback *callback,
|
|
bfd *abfd, char * const *argv)
|
|
{
|
|
int i;
|
|
SIM_DESC sd;
|
|
sim_cpu *cpu;
|
|
|
|
sd = sim_state_alloc (kind, callback);
|
|
|
|
SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
|
|
|
|
/* The cpu data is kept in a separately allocated chunk of memory. */
|
|
if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
|
|
{
|
|
free_state (sd);
|
|
return 0;
|
|
}
|
|
|
|
cpu = STATE_CPU (sd, 0);
|
|
|
|
cpu_initialize (sd, cpu);
|
|
|
|
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
|
|
{
|
|
free_state (sd);
|
|
return 0;
|
|
}
|
|
|
|
/* The parser will print an error message for us, so we silently return. */
|
|
if (sim_parse_args (sd, argv) != SIM_RC_OK)
|
|
{
|
|
/* Uninstall the modules to avoid memory leaks,
|
|
file descriptor leaks, etc. */
|
|
free_state (sd);
|
|
return 0;
|
|
}
|
|
|
|
/* Check for/establish the a reference program image. */
|
|
if (sim_analyze_program (sd,
|
|
(STATE_PROG_ARGV (sd) != NULL
|
|
? *STATE_PROG_ARGV (sd)
|
|
: NULL), abfd) != SIM_RC_OK)
|
|
{
|
|
free_state (sd);
|
|
return 0;
|
|
}
|
|
|
|
/* Establish any remaining configuration options. */
|
|
if (sim_config (sd) != SIM_RC_OK)
|
|
{
|
|
free_state (sd);
|
|
return 0;
|
|
}
|
|
|
|
if (sim_post_argv_init (sd) != SIM_RC_OK)
|
|
{
|
|
/* Uninstall the modules to avoid memory leaks,
|
|
file descriptor leaks, etc. */
|
|
free_state (sd);
|
|
return 0;
|
|
}
|
|
if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK)
|
|
{
|
|
free_state (sd);
|
|
return 0;
|
|
}
|
|
|
|
/* CPU specific initialization. */
|
|
for (i = 0; i < MAX_NR_PROCESSORS; ++i)
|
|
{
|
|
SIM_CPU *cpu = STATE_CPU (sd, i);
|
|
|
|
CPU_REG_FETCH (cpu) = m68hc11_reg_fetch;
|
|
CPU_REG_STORE (cpu) = m68hc11_reg_store;
|
|
CPU_PC_FETCH (cpu) = m68hc11_pc_get;
|
|
CPU_PC_STORE (cpu) = m68hc11_pc_set;
|
|
}
|
|
|
|
return sd;
|
|
}
|
|
|
|
/* Generic implementation of sim_engine_run that works within the
|
|
sim_engine setjmp/longjmp framework. */
|
|
|
|
void
|
|
sim_engine_run (SIM_DESC sd,
|
|
int next_cpu_nr, /* ignore */
|
|
int nr_cpus, /* ignore */
|
|
int siggnal) /* ignore */
|
|
{
|
|
sim_cpu *cpu;
|
|
|
|
SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
|
|
cpu = STATE_CPU (sd, 0);
|
|
while (1)
|
|
{
|
|
cpu_single_step (cpu);
|
|
|
|
/* process any events */
|
|
if (sim_events_tickn (sd, cpu->cpu_current_cycle))
|
|
{
|
|
sim_events_process (sd);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
sim_info (SIM_DESC sd, int verbose)
|
|
{
|
|
const char *cpu_type;
|
|
const struct bfd_arch_info *arch;
|
|
|
|
/* Nothing to do if there is no verbose flag set. */
|
|
if (verbose == 0 && STATE_VERBOSE_P (sd) == 0)
|
|
return;
|
|
|
|
arch = STATE_ARCHITECTURE (sd);
|
|
if (arch->arch == bfd_arch_m68hc11)
|
|
cpu_type = "68HC11";
|
|
else
|
|
cpu_type = "68HC12";
|
|
|
|
sim_io_eprintf (sd, "Simulator info:\n");
|
|
sim_io_eprintf (sd, " CPU Motorola %s\n", cpu_type);
|
|
sim_get_info (sd, 0);
|
|
sim_module_info (sd, verbose || STATE_VERBOSE_P (sd));
|
|
}
|
|
|
|
SIM_RC
|
|
sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
|
|
char * const *argv, char * const *env)
|
|
{
|
|
return sim_prepare_for_program (sd, abfd);
|
|
}
|
|
|
|
static int
|
|
m68hc11_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
|
|
{
|
|
uint16 val;
|
|
int size = 2;
|
|
|
|
switch (rn)
|
|
{
|
|
case A_REGNUM:
|
|
val = cpu_get_a (cpu);
|
|
size = 1;
|
|
break;
|
|
|
|
case B_REGNUM:
|
|
val = cpu_get_b (cpu);
|
|
size = 1;
|
|
break;
|
|
|
|
case D_REGNUM:
|
|
val = cpu_get_d (cpu);
|
|
break;
|
|
|
|
case X_REGNUM:
|
|
val = cpu_get_x (cpu);
|
|
break;
|
|
|
|
case Y_REGNUM:
|
|
val = cpu_get_y (cpu);
|
|
break;
|
|
|
|
case SP_REGNUM:
|
|
val = cpu_get_sp (cpu);
|
|
break;
|
|
|
|
case PC_REGNUM:
|
|
val = cpu_get_pc (cpu);
|
|
break;
|
|
|
|
case PSW_REGNUM:
|
|
val = cpu_get_ccr (cpu);
|
|
size = 1;
|
|
break;
|
|
|
|
case PAGE_REGNUM:
|
|
val = cpu_get_page (cpu);
|
|
size = 1;
|
|
break;
|
|
|
|
default:
|
|
val = 0;
|
|
break;
|
|
}
|
|
if (size == 1)
|
|
{
|
|
memory[0] = val;
|
|
}
|
|
else
|
|
{
|
|
memory[0] = val >> 8;
|
|
memory[1] = val & 0x0FF;
|
|
}
|
|
return size;
|
|
}
|
|
|
|
static int
|
|
m68hc11_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
|
|
{
|
|
uint16 val;
|
|
|
|
val = *memory++;
|
|
if (length == 2)
|
|
val = (val << 8) | *memory;
|
|
|
|
switch (rn)
|
|
{
|
|
case D_REGNUM:
|
|
cpu_set_d (cpu, val);
|
|
break;
|
|
|
|
case A_REGNUM:
|
|
cpu_set_a (cpu, val);
|
|
return 1;
|
|
|
|
case B_REGNUM:
|
|
cpu_set_b (cpu, val);
|
|
return 1;
|
|
|
|
case X_REGNUM:
|
|
cpu_set_x (cpu, val);
|
|
break;
|
|
|
|
case Y_REGNUM:
|
|
cpu_set_y (cpu, val);
|
|
break;
|
|
|
|
case SP_REGNUM:
|
|
cpu_set_sp (cpu, val);
|
|
break;
|
|
|
|
case PC_REGNUM:
|
|
cpu_set_pc (cpu, val);
|
|
break;
|
|
|
|
case PSW_REGNUM:
|
|
cpu_set_ccr (cpu, val);
|
|
return 1;
|
|
|
|
case PAGE_REGNUM:
|
|
cpu_set_page (cpu, val);
|
|
return 1;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 2;
|
|
}
|