diff options
Diffstat (limited to 'sim')
-rw-r--r-- | sim/m68hc11/ChangeLog | 18 | ||||
-rw-r--r-- | sim/m68hc11/dv-m68hc11.c | 14 | ||||
-rw-r--r-- | sim/m68hc11/interp.c | 108 | ||||
-rw-r--r-- | sim/m68hc11/m68hc11_sim.c | 3 | ||||
-rw-r--r-- | sim/m68hc11/sim-main.h | 19 |
5 files changed, 137 insertions, 25 deletions
diff --git a/sim/m68hc11/ChangeLog b/sim/m68hc11/ChangeLog index 086f508..5cd46d0 100644 --- a/sim/m68hc11/ChangeLog +++ b/sim/m68hc11/ChangeLog @@ -1,3 +1,21 @@ +2003-08-08 Stephane Carrez <stcarrez@nerim.fr> + + * sim-main.h (phys_to_virt): Use memory bank parameters to translate + the physical address in virtual address. + (struct _sim_cpu): Add memory bank members. + * m68hc11_sim.c (cpu_initialize): Clear memory bank parameters. + * interp.c (sim_hw_configure): Create memory bank according to memory + bank parameters. + (sim_get_bank_parameters): New function to obtain memory bank config + from the symbol table. + (sim_prepare_for_program): Call it to obtain the memory bank parameters. + (sim_open): Call sim_prepare_for_program. + * dv-m68hc11.c (m68hc11cpu_io_write_buffer): Use memory bank parameters + to check if address is within bank window. + (m68hc11cpu_io_read_buffer): Likewise. + (attach_m68hc11_regs): Map the memory bank according to memory bank + parameters. + 2003-08-08 Stephane Carrez <stcarrez@nerim.fr>, * sim-main.h (PAGE_REGNUM, Z_REGNUM): Use same numbering as gdb. diff --git a/sim/m68hc11/dv-m68hc11.c b/sim/m68hc11/dv-m68hc11.c index 669a045..cad100a 100644 --- a/sim/m68hc11/dv-m68hc11.c +++ b/sim/m68hc11/dv-m68hc11.c @@ -1,5 +1,5 @@ /* dv-m68hc11.c -- CPU 68HC11&68HC12 as a device. - Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Written by Stephane Carrez (stcarrez@nerim.fr) (From a driver model Contributed by Cygnus Solutions.) @@ -324,8 +324,8 @@ attach_m68hc11_regs (struct hw *me, if (hw_find_property (me, "use_bank") != NULL) hw_attach_address (hw_parent (me), 0, exec_map, - 0x08000, - 0x04000, + cpu->bank_start, + cpu->bank_end - cpu->bank_start, me); cpu_mode = "expanded"; @@ -843,7 +843,7 @@ m68hc11cpu_io_read_buffer (struct hw *me, sd = hw_system (me); cpu = STATE_CPU (sd, 0); - if (base >= 0x8000 && base < 0xc000) + if (base >= cpu->bank_start && base < cpu->bank_end) { address_word virt_addr = phys_to_virt (cpu, base); if (virt_addr != base) @@ -864,7 +864,7 @@ m68hc11cpu_io_read_buffer (struct hw *me, break; memcpy (dest, &cpu->ios[base], 1); - dest++; + dest = (char*) dest + 1; base++; byte++; nr_bytes--; @@ -1091,7 +1091,7 @@ m68hc11cpu_io_write_buffer (struct hw *me, sd = hw_system (me); cpu = STATE_CPU (sd, 0); - if (base >= 0x8000 && base < 0xc000) + if (base >= cpu->bank_start && base < cpu->bank_end) { address_word virt_addr = phys_to_virt (cpu, base); if (virt_addr != base) @@ -1113,7 +1113,7 @@ m68hc11cpu_io_write_buffer (struct hw *me, val = *((uint8*) source); m68hc11cpu_io_write (me, cpu, base, val); - source++; + source = (char*) source + 1; base++; byte++; nr_bytes--; diff --git a/sim/m68hc11/interp.c b/sim/m68hc11/interp.c index 3da382d..b80bc94 100644 --- a/sim/m68hc11/interp.c +++ b/sim/m68hc11/interp.c @@ -1,5 +1,5 @@ /* interp.c -- Simulator for Motorola 68HC11/68HC12 - Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Written by Stephane Carrez (stcarrez@nerim.fr) This file is part of GDB, the GNU debugger. @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "hw-tree.h" #include "hw-device.h" #include "hw-ports.h" +#include "elf32-m68hc1x.h" #ifndef MONITOR_BASE # define MONITOR_BASE (0x0C000) @@ -194,8 +195,17 @@ sim_hw_configure (SIM_DESC sd) 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"); @@ -242,14 +252,16 @@ sim_hw_configure (SIM_DESC sd) { /* Allocate core external memory. */ sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx", - 0xC000, M6811_RAM_LEVEL, 0x4000); + 0x8000, M6811_RAM_LEVEL, 0x8000); sim_do_commandf (sd, "memory region 0x000@%d,0x8000", M6811_RAM_LEVEL); - sim_do_commandf (sd, "memory region 0x01000000@%d,0x100000", - 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"); - sim_hw_parse (sd, "/m68hc12/use_bank 1"); } if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@1/reg")) @@ -294,19 +306,77 @@ sim_hw_configure (SIM_DESC sd) return 1; } +/* Get the memory bank parameters by looking at the global symbols + defined by the linker. */ static int -sim_prepare_for_program (SIM_DESC sd, struct bfd* abfd) +sim_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); - if (!sim_hw_configure (sd)) - return SIM_RC_FAIL; + 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 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; @@ -331,8 +401,17 @@ sim_prepare_for_program (SIM_DESC sd, struct bfd* abfd) } } } + + 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"); + } } + if (!sim_hw_configure (sd)) + return SIM_RC_FAIL; + /* reset all state information */ sim_board_reset (sd); @@ -341,7 +420,7 @@ sim_prepare_for_program (SIM_DESC sd, struct bfd* abfd) SIM_DESC sim_open (SIM_OPEN_KIND kind, host_callback *callback, - struct bfd *abfd, char **argv) + bfd *abfd, char **argv) { SIM_DESC sd; sim_cpu *cpu; @@ -398,8 +477,11 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback, free_state (sd); return 0; } - - sim_hw_configure (sd); + if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK) + { + free_state (sd); + return 0; + } /* Fudge our descriptor. */ return sd; diff --git a/sim/m68hc11/m68hc11_sim.c b/sim/m68hc11/m68hc11_sim.c index 3e34598..1daa39c 100644 --- a/sim/m68hc11/m68hc11_sim.c +++ b/sim/m68hc11/m68hc11_sim.c @@ -464,6 +464,9 @@ cpu_initialize (SIM_DESC sd, sim_cpu *cpu) cpu->cpu_use_elf_start = 0; cpu->cpu_elf_start = 0; cpu->cpu_use_local_config = 0; + cpu->bank_start = 0; + cpu->bank_end = 0; + cpu->bank_shift = 0; cpu->cpu_config = M6811_NOSEC | M6811_NOCOP | M6811_ROMON | M6811_EEON; interrupts_initialize (sd, cpu); diff --git a/sim/m68hc11/sim-main.h b/sim/m68hc11/sim-main.h index eac6b0e..054933b 100644 --- a/sim/m68hc11/sim-main.h +++ b/sim/m68hc11/sim-main.h @@ -210,6 +210,14 @@ struct _sim_cpu { uint8 ios[MAX_PORTS]; + /* Memory bank parameters which describe how the memory bank window + is mapped in memory and how to convert it in virtual address. */ + uint16 bank_start; + uint16 bank_end; + address_word bank_virtual; + unsigned bank_shift; + + struct hw *hw_cpu; /* ... base type ... */ @@ -237,7 +245,7 @@ struct _sim_cpu { #define cpu_get_sp(PROC) ((PROC)->cpu_regs.sp) #define cpu_get_a(PROC) ((PROC->cpu_regs.d >> 8) & 0x0FF) #define cpu_get_b(PROC) ((PROC->cpu_regs.d) & 0x0FF) -#define cpu_get_page(PROC) (PROC->cpu_regs.page) +#define cpu_get_page(PROC) ((PROC)->cpu_regs.page) /* 68HC12 specific and Motorola internal registers. */ #define cpu_get_tmp3(PROC) (0) @@ -246,7 +254,7 @@ struct _sim_cpu { #define cpu_set_d(PROC,VAL) (((PROC)->cpu_regs.d) = (VAL)) #define cpu_set_x(PROC,VAL) (((PROC)->cpu_regs.ix) = (VAL)) #define cpu_set_y(PROC,VAL) (((PROC)->cpu_regs.iy) = (VAL)) -#define cpu_set_page(PROC,VAL) ((PROC->cpu_regs.page) = (VAL)) +#define cpu_set_page(PROC,VAL) (((PROC)->cpu_regs.page) = (VAL)) /* 68HC12 specific and Motorola internal registers. */ #define cpu_set_tmp3(PROC,VAL) (0) @@ -297,9 +305,10 @@ extern void cpu_memory_exception (struct _sim_cpu *proc, inline address_word phys_to_virt (sim_cpu *cpu, address_word addr) { - if (addr >= 0x8000 && addr < 0xc000) - return ((address_word) (addr) - 0x8000) - + (((address_word) cpu->cpu_regs.page) << 14) + 0x01000000; + if (addr >= cpu->bank_start && addr < cpu->bank_end) + return ((address_word) (addr - cpu->bank_start) + + (((address_word) cpu->cpu_regs.page) << cpu->bank_shift) + + cpu->bank_virtual); else return (address_word) (addr); } |