This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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);
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]