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]: Support memory banks debug with 68HC12


Hi!

This patch allows debugging 68HC12 code in its 16K memory bank window.
It creates a virtual PC (pseudo reg) which represents code in the banked memory.
It is computed using the real PC and the page number.  The banked memory is a
flat address space starting at hypothetical address 0x1000000.  It is accessed
using the 8-bit page register and the 14 lower bits of the PC.

I've committed this patch on mainline.  (but only tested with simple program).

	Stephane

2002-08-13  Stephane Carrez  <stcarrez@nerim.fr>

	* m68hc11-tdep.c (M68HC12_NUM_PSEUDO_REGS): New define.
	(M68HC12_HARD_PC_REGNUM): Define specific PC for 68HC12 (pseudo reg).
	(m68hc11_pseudo_register_read): Compute the 68HC12 PC using the
	real PC and the page number (if it's within the memory bank window).
	(m68hc11_pseudo_register_write): Likewise when saving.
	(m68hc11_register_name): Name the virtual pc 'pc' and the real one ppc.
	(m68hc11_register_virtual_type): Return uint32 for virtual pc.
	(m68hc11_register_raw_size): And use 32-bit for it.
	(m68hc11_gdbarch_init): Use 32-bit address for 68HC12 if the
	16K memory bank is used by the prog; also use the virtual pc.

Index: m68hc11-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m68hc11-tdep.c,v
retrieving revision 1.27
diff -u -p -r1.27 m68hc11-tdep.c
--- m68hc11-tdep.c	13 Aug 2002 16:40:46 -0000	1.27
+++ m68hc11-tdep.c	13 Aug 2002 17:13:33 -0000
@@ -128,6 +128,10 @@ enum insn_return_kind {
 
 #define M68HC11_REG_SIZE    (2)
 
+#define M68HC12_NUM_REGS        (9)
+#define M68HC12_NUM_PSEUDO_REGS ((M68HC11_MAX_SOFT_REGS+5)+1-1)
+#define M68HC12_HARD_PC_REGNUM  (SOFT_D32_REGNUM+1)
+
 struct insn_sequence;
 struct gdbarch_tdep
   {
@@ -280,6 +284,24 @@ m68hc11_pseudo_register_read (struct gdb
 			      struct regcache *regcache,
 			      int regno, void *buf)
 {
+  /* The PC is a pseudo reg only for 68HC12 with the memory bank
+     addressing mode.  */
+  if (regno == M68HC12_HARD_PC_REGNUM)
+    {
+      const int regsize = TYPE_LENGTH (builtin_type_uint32);
+      CORE_ADDR pc = read_register (HARD_PC_REGNUM);
+      int page = read_register (HARD_PAGE_REGNUM);
+
+      if (pc >= 0x8000 && pc < 0xc000)
+        {
+          pc -= 0x8000;
+          pc += (page << 14);
+          pc += 0x1000000;
+        }
+      store_unsigned_integer (buf, regsize, pc);
+      return;
+    }
+
   m68hc11_initialize_register_info ();
   
   /* Fetch a soft register: translate into a memory read.  */
@@ -300,6 +322,28 @@ m68hc11_pseudo_register_write (struct gd
 			       struct regcache *regcache,
 			       int regno, const void *buf)
 {
+  /* The PC is a pseudo reg only for 68HC12 with the memory bank
+     addressing mode.  */
+  if (regno == M68HC12_HARD_PC_REGNUM)
+    {
+      const int regsize = TYPE_LENGTH (builtin_type_uint32);
+      char *tmp = alloca (regsize);
+      CORE_ADDR pc;
+
+      memcpy (tmp, buf, regsize);
+      pc = extract_unsigned_integer (tmp, regsize);
+      if (pc >= 0x1000000)
+        {
+          pc -= 0x1000000;
+          write_register (HARD_PAGE_REGNUM, (pc >> 14) & 0x0ff);
+          pc &= 0x03fff;
+          write_register (HARD_PC_REGNUM, pc + 0x8000);
+        }
+      else
+        write_register (HARD_PC_REGNUM, pc);
+      return;
+    }
+  
   m68hc11_initialize_register_info ();
 
   /* Store a soft register: translate into a memory write.  */
@@ -315,6 +359,11 @@ m68hc11_pseudo_register_write (struct gd
 static const char *
 m68hc11_register_name (int reg_nr)
 {
+  if (reg_nr == M68HC12_HARD_PC_REGNUM && USE_PAGE_REGISTER)
+    return "pc";
+  if (reg_nr == HARD_PC_REGNUM && USE_PAGE_REGISTER)
+    return "ppc";
+  
   if (reg_nr < 0)
     return NULL;
   if (reg_nr >= M68HC11_ALL_REGS)
@@ -1011,6 +1060,9 @@ m68hc11_register_virtual_type (int reg_n
     case HARD_CCR_REGNUM:
       return builtin_type_uint8;
 
+    case M68HC12_HARD_PC_REGNUM:
+      return builtin_type_uint32;
+
     default:
       return builtin_type_uint16;
     }
@@ -1144,6 +1196,9 @@ m68hc11_register_raw_size (int reg_nr)
     case HARD_CCR_REGNUM:
       return 1;
 
+    case M68HC12_HARD_PC_REGNUM:
+      return 4;
+
     default:
       return M68HC11_REG_SIZE;
     }
@@ -1214,12 +1269,25 @@ m68hc11_gdbarch_init (struct gdbarch_inf
       tdep->stack_correction = 1;
       tdep->use_page_register = 0;
       tdep->prologue = m6811_prologue;
+      set_gdbarch_addr_bit (gdbarch, 16);
+      set_gdbarch_num_pseudo_regs (gdbarch, M68HC11_NUM_PSEUDO_REGS);
+      set_gdbarch_pc_regnum (gdbarch, HARD_PC_REGNUM);
+      set_gdbarch_num_regs (gdbarch, M68HC11_NUM_REGS);
       break;
 
     case bfd_arch_m68hc12:
       tdep->stack_correction = 0;
       tdep->use_page_register = elf_flags & E_M68HC12_BANKS;
       tdep->prologue = m6812_prologue;
+      set_gdbarch_addr_bit (gdbarch, elf_flags & E_M68HC12_BANKS ? 32 : 16);
+      set_gdbarch_num_pseudo_regs (gdbarch,
+                                   elf_flags & E_M68HC12_BANKS
+                                   ? M68HC12_NUM_PSEUDO_REGS
+                                   : M68HC11_NUM_PSEUDO_REGS);
+      set_gdbarch_pc_regnum (gdbarch, elf_flags & E_M68HC12_BANKS
+                             ? M68HC12_HARD_PC_REGNUM : HARD_PC_REGNUM);
+      set_gdbarch_num_regs (gdbarch, elf_flags & E_M68HC12_BANKS
+                            ? M68HC12_NUM_REGS : M68HC11_NUM_REGS);
       break;
 
     default:
@@ -1255,11 +1323,8 @@ m68hc11_gdbarch_init (struct gdbarch_inf
   set_gdbarch_read_sp (gdbarch, generic_target_read_sp);
   set_gdbarch_write_sp (gdbarch, generic_target_write_sp);
 
-  set_gdbarch_num_regs (gdbarch, M68HC11_NUM_REGS);
-  set_gdbarch_num_pseudo_regs (gdbarch, M68HC11_NUM_PSEUDO_REGS);
   set_gdbarch_sp_regnum (gdbarch, HARD_SP_REGNUM);
   set_gdbarch_fp_regnum (gdbarch, SOFT_FP_REGNUM);
-  set_gdbarch_pc_regnum (gdbarch, HARD_PC_REGNUM);
   set_gdbarch_register_name (gdbarch, m68hc11_register_name);
   set_gdbarch_register_size (gdbarch, 2);
   set_gdbarch_register_bytes (gdbarch, M68HC11_ALL_REGS * 2);

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