* sim-main.h (phys_to_virt): Use memory bank parameters to translate
authorStephane Carrez <stcarrez@nerim.fr>
Fri, 8 Aug 2003 20:42:21 +0000 (20:42 +0000)
committerStephane Carrez <stcarrez@nerim.fr>
Fri, 8 Aug 2003 20:42:21 +0000 (20:42 +0000)
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.

sim/m68hc11/ChangeLog
sim/m68hc11/dv-m68hc11.c
sim/m68hc11/interp.c
sim/m68hc11/m68hc11_sim.c
sim/m68hc11/sim-main.h

index 086f508..5cd46d0 100644 (file)
@@ -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.
index 669a045..cad100a 100644 (file)
@@ -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--;
index 3da382d..b80bc94 100644 (file)
@@ -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;
index 3e34598..1daa39c 100644 (file)
@@ -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);
index eac6b0e..054933b 100644 (file)
@@ -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);
 }