📄 interp.c
字号:
/* interp.c -- Simulator for Motorola 68HC11/68HC12 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 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 modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public License alongwith this program; if not, write to the Free Software Foundation, Inc.,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#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)#endifstatic void sim_get_info (SIM_DESC sd, char *cmd);char *interrupt_names[] = { "reset", "nmi", "int", NULL};#ifndef INLINE#if defined(__GNUC__) && defined(__OPTIMIZE__)#define INLINE __inline__#else#define INLINE#endif#endifstruct 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 voidfree_state (SIM_DESC sd){ if (STATE_MODULES (sd) != NULL) sim_module_uninstall (sd); sim_state_free (sd);}/* Give some information about the simulator. */static voidsim_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);}voidsim_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 intsim_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 intsim_get_bank_parameters (SIM_DESC sd, bfd* abfd){ sim_cpu *cpu; long symsize; long symbol_count, i; unsigned size; asymbol** asymbols; asymbol** current; cpu = STATE_CPU (sd, 0); symsize = bfd_get_symtab_upper_bound (abfd); if (symsize < 0) { sim_io_eprintf (sd, "Cannot read symbols of program"); return 0; } asymbols = (asymbol **) xmalloc (symsize); symbol_count = bfd_canonicalize_symtab (abfd, asymbols); if (symbol_count < 0) { sim_io_eprintf (sd, "Cannot read symbols of program"); return 0; } size = 0; for (i = 0, current = asymbols; i < symbol_count; i++, current++) { const char* name = bfd_asymbol_name (*current); if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0) { cpu->bank_start = bfd_asymbol_value (*current); } else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0) { size = bfd_asymbol_value (*current); } else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0) { cpu->bank_virtual = bfd_asymbol_value (*current); } } free (asymbols); cpu->bank_end = cpu->bank_start + size; cpu->bank_shift = 0; for (; size > 1; size >>= 1) cpu->bank_shift++; return 0;}static intsim_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_get_section_size (s); if (size > 0) { bfd_vma lma; if (STATE_LOAD_AT_LMA_P (sd)) lma = bfd_section_lma (abfd, s); else lma = bfd_section_vma (abfd, 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, abfd) != 0) sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -