This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[PATCH]: Improve 68hc11 simulator memory bank support
- From: Stephane Carrez <stcarrez at nerim dot fr>
- To: gdb-patches at sources dot redhat dot com
- Date: Fri, 08 Aug 2003 22:47:14 +0200
- Subject: [PATCH]: Improve 68hc11 simulator memory bank support
Hi!
This patch improves the memory bank support in the 68hc11 simulator to map the
memory window according to the program being simulated. The information is
obtained by looking at the ELF header (to know that there is banked memory)
and then at the symtab to obtain the window address and virtual address (so that
it later matches the gdb memory queries). I have this in my queue since march...
Committed on 6_0 and mainline.
Stephane
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.
Index: dv-m68hc11.c
===================================================================
RCS file: /cvs/src/src/sim/m68hc11/dv-m68hc11.c,v
retrieving revision 1.9
diff -u -p -r1.9 dv-m68hc11.c
--- dv-m68hc11.c 13 Aug 2002 08:38:09 -0000 1.9
+++ dv-m68hc11.c 8 Aug 2003 20:41:47 -0000
@@ -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 *m
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 *m
val = *((uint8*) source);
m68hc11cpu_io_write (me, cpu, base, val);
- source++;
+ source = (char*) source + 1;
base++;
byte++;
nr_bytes--;
Index: interp.c
===================================================================
RCS file: /cvs/src/src/sim/m68hc11/interp.c,v
retrieving revision 1.15
diff -u -p -r1.15 interp.c
--- interp.c 1 Mar 2003 16:00:09 -0000 1.15
+++ interp.c 8 Aug 2003 20:41:48 -0000
@@ -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
#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, st
}
}
}
+
+ 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, st
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_callb
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;
Index: m68hc11_sim.c
===================================================================
RCS file: /cvs/src/src/sim/m68hc11/m68hc11_sim.c,v
retrieving revision 1.7.44.1
diff -u -p -r1.7.44.1 m68hc11_sim.c
--- m68hc11_sim.c 8 Aug 2003 20:26:28 -0000 1.7.44.1
+++ m68hc11_sim.c 8 Aug 2003 20:41:48 -0000
@@ -464,6 +464,9 @@ cpu_initialize (SIM_DESC sd, sim_cpu *cp
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);
Index: sim-main.h
===================================================================
RCS file: /cvs/src/src/sim/m68hc11/sim-main.h,v
retrieving revision 1.9.44.2
diff -u -p -r1.9.44.2 sim-main.h
--- sim-main.h 8 Aug 2003 20:34:15 -0000 1.9.44.2
+++ sim-main.h 8 Aug 2003 20:41:48 -0000
@@ -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
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);
}