2008-02-11 Maxim Grigoriev <maxim2405@gmail.com>
authorMaxim Grigoriev <maxim2405@gmail.com>
Mon, 11 Feb 2008 22:00:31 +0000 (22:00 +0000)
committerMaxim Grigoriev <maxim2405@gmail.com>
Mon, 11 Feb 2008 22:00:31 +0000 (22:00 +0000)
* gdbserver/Makefile.in (SFILES): Add linux-xtensa-low.c.
(clean): Add reg-xtensa.c.
(linux-xtensa-low.o, reg-xtensa.o, reg-xtensa.c): New dependencies.
* gdbserver/configure.srv (xtensa*-*-linux*) New target.
* gdbserver/linux-xtensa-low.c: New.
* gdbserver/xtensa-xtregs.c: New.

gdb/gdbserver/ChangeLog
gdb/gdbserver/Makefile.in
gdb/gdbserver/configure.srv
gdb/gdbserver/linux-xtensa-low.c [new file with mode: 0644]
gdb/gdbserver/xtensa-xtregs.c [new file with mode: 0644]

index 07f0a447c569c09a54ecf026f07b900ef3f0b096..05869664379ca79fa5607703076dabc684afb7e1 100644 (file)
@@ -1,3 +1,12 @@
+2008-02-11  Maxim Grigoriev  <maxim2405@gmail.com>
+
+       * gdbserver/Makefile.in (SFILES): Add linux-xtensa-low.c.
+       (clean): Add reg-xtensa.c.
+       (linux-xtensa-low.o, reg-xtensa.o, reg-xtensa.c): New dependencies.
+       * gdbserver/configure.srv (xtensa*-*-linux*) New target.
+       * gdbserver/linux-xtensa-low.c: New.
+       * gdbserver/xtensa-xtregs.c: New.
+
 2008-02-01  Pedro Alves  <pedro_alves@portugalmail.pt>
 
        * hostio.c: Don't include errno.h.
index d643bdf379cede39c7f33ce464b38b0104b2bb66..2c7cb75920a9351350283676e7d405f52127897a 100644 (file)
@@ -129,6 +129,7 @@ SFILES=     $(srcdir)/gdbreplay.c $(srcdir)/inferiors.c \
        $(srcdir)/linux-ppc-low.c $(srcdir)/linux-ppc64-low.c \
        $(srcdir)/linux-s390-low.c \
        $(srcdir)/linux-sh-low.c $(srcdir)/linux-x86-64-low.c \
+       $(srcdir)/linux-xtensa-low.c \
        $(srcdir)/win32-arm-low.c $(srcdir)/win32-i386-low.c \
        $(srcdir)/win32-low.c $(srcdir)/wincecompat.c \
        $(srcdir)/hostio.c $(srcdir)/hostio-errno.c
@@ -218,7 +219,7 @@ clean:
        rm -f gdbserver$(EXEEXT) gdbreplay$(EXEEXT) core make.log
        rm -f reg-arm.c reg-i386.c reg-ia64.c reg-m32r.c reg-m68k.c
        rm -f reg-ppc.c reg-sh.c reg-spu.c reg-x86-64.c reg-i386-linux.c
-       rm -f reg-cris.c reg-crisv32.c reg-x86-64-linux.c
+       rm -f reg-cris.c reg-crisv32.c reg-x86-64-linux.c reg-xtensa.c
        rm -f arm-with-iwmmxt.c mips-linux.c mips64-linux.c
        rm -f powerpc-32.c powerpc-64.c powerpc-e500.c
        rm -f xml-builtin.c stamp-xml target.xml
@@ -316,6 +317,7 @@ linux-s390-low.o: linux-s390-low.c $(linux_low_h) $(server_h)
 linux-sh-low.o: linux-sh-low.c $(linux_low_h) $(server_h)
 linux-x86-64-low.o: linux-x86-64-low.c $(linux_low_h) $(server_h) \
        $(gdb_proc_service_h)
+linux-xtensa-low.o: linux-xtensa-low.c xtensa-xtregs.c $(linux_low_h) $(server_h)
 
 win32_low_h = $(srcdir)/win32-low.h
 
@@ -392,5 +394,7 @@ reg-x86-64.c : $(srcdir)/../regformats/reg-x86-64.dat $(regdat_sh)
 reg-x86-64-linux.o : reg-x86-64-linux.c $(regdef_h)
 reg-x86-64-linux.c : $(srcdir)/../regformats/reg-x86-64-linux.dat $(regdat_sh)
        $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-x86-64-linux.dat reg-x86-64-linux.c
-
+reg-xtensa.o : reg-xtensa.c $(regdef_h)
+reg-xtensa.c : $(srcdir)/../regformats/reg-xtensa.dat $(regdat_sh)
+       $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-xtensa.dat reg-xtensa.c
 # This is the end of "Makefile.in".
index b57c8a50ce15187b766235672299012563303c04..4f1c22b3aa4a9b4be5a828c51d1cdd72e497b40b 100644 (file)
@@ -170,6 +170,10 @@ case "${target}" in
                        srv_linux_usrregs=yes
                        srv_linux_thread_db=yes
                        ;;
+  xtensa*-*-linux*)    srv_regobj=reg-xtensa.o
+                       srv_tgtobj="linux-low.o linux-xtensa-low.o"
+                       srv_linux_regsets=yes
+                       ;;
   *)                   echo "Error: target not supported by gdbserver."
                        exit 1
                        ;;
diff --git a/gdb/gdbserver/linux-xtensa-low.c b/gdb/gdbserver/linux-xtensa-low.c
new file mode 100644 (file)
index 0000000..cbf5a51
--- /dev/null
@@ -0,0 +1,187 @@
+/* GNU/Linux/Xtensa specific low level interface, for the remote server for GDB.
+   Copyright 2007, 2008 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+#include "server.h"
+#include "linux-low.h"
+
+#include <sys/ptrace.h>
+#include <xtensa-config.h>
+
+#include "xtensa-xtregs.c"
+
+enum regnum {
+       R_PC=0, R_PS,
+       R_LBEG, R_LEND, R_LCOUNT,
+       R_SAR,
+       R_WS, R_WB,
+       R_A0 = 64 
+};
+
+static void
+xtensa_fill_gregset (void *buf)
+{
+  elf_greg_t* rset = (elf_greg_t*)buf;
+  int ar0_regnum;
+  char *ptr;
+  int i;
+
+  /* Take care of AR registers.  */
+
+  ar0_regnum = find_regno ("ar0");
+  ptr = (char*)&rset[R_A0];
+
+  for (i = ar0_regnum; i < ar0_regnum + XCHAL_NUM_AREGS; i++)
+    {
+      collect_register (i, ptr);
+      ptr += register_size(i);
+    }
+
+  /* Loop registers, if hardware has it.  */
+
+#if XCHAL_HAVE_LOOP
+  collect_register_by_name ("lbeg", (char*)&rset[R_LBEG]);
+  collect_register_by_name ("lend", (char*)&rset[R_LEND]);
+  collect_register_by_name ("lcount", (char*)&rset[R_LCOUNT]);
+#endif
+
+  collect_register_by_name ("sar", (char*)&rset[R_SAR]);
+  collect_register_by_name ("pc", (char*)&rset[R_PC]);
+  collect_register_by_name ("ps", (char*)&rset[R_PS]);
+  collect_register_by_name ("windowbase", (char*)&rset[R_WB]);
+  collect_register_by_name ("windowstart", (char*)&rset[R_WS]);
+}
+
+static void
+xtensa_store_gregset (const void *buf)
+{
+  const elf_greg_t* rset = (const elf_greg_t*)buf;
+  int ar0_regnum;
+  char *ptr;
+  int i;
+
+  /* Take care of AR registers.  */
+
+  ar0_regnum = find_regno ("ar0");
+  ptr = (char *)&rset[R_A0];
+
+  for (i = ar0_regnum; i < ar0_regnum + XCHAL_NUM_AREGS; i++)
+    {
+      supply_register (i, ptr);
+      ptr += register_size(i);
+    }
+
+  /* Loop registers, if hardware has it.  */
+
+#if XCHAL_HAVE_LOOP
+  supply_register_by_name ("lbeg", (char*)&rset[R_LBEG]);
+  supply_register_by_name ("lend", (char*)&rset[R_LEND]);
+  supply_register_by_name ("lcount", (char*)&rset[R_LCOUNT]);
+#endif
+
+  supply_register_by_name ("sar", (char*)&rset[R_SAR]);
+  supply_register_by_name ("pc", (char*)&rset[R_PC]);
+  supply_register_by_name ("ps", (char*)&rset[R_PS]);
+  supply_register_by_name ("windowbase", (char*)&rset[R_WB]);
+  supply_register_by_name ("windowstart", (char*)&rset[R_WS]);
+}
+
+/* Xtensa GNU/Linux PTRACE interface includes extended register set.  */
+
+static void
+xtensa_fill_xtregset (void *buf)
+{
+  const xtensa_regtable_t *ptr;
+
+  for (ptr = xtensa_regmap_table; ptr->name; ptr++)
+    {
+      collect_register_by_name (ptr->name,
+                               (char*)buf + ptr->ptrace_offset);
+    }
+}
+
+static void
+xtensa_store_xtregset (const void *buf)
+{
+  const xtensa_regtable_t *ptr;
+
+  for (ptr = xtensa_regmap_table; ptr->name; ptr++)
+    {
+      supply_register_by_name (ptr->name,
+                               (char*)buf + ptr->ptrace_offset);
+    }
+}
+
+struct regset_info target_regsets[] = {
+  { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
+    GENERAL_REGS,
+    xtensa_fill_gregset, xtensa_store_gregset },
+  { PTRACE_GETXTREGS, PTRACE_SETXTREGS, XTENSA_ELF_XTREG_SIZE,
+    EXTENDED_REGS,
+    xtensa_fill_xtregset, xtensa_store_xtregset },
+  { 0, 0, -1, -1, NULL, NULL }
+};
+
+#if XCHAL_HAVE_BE
+#define XTENSA_BREAKPOINT {0xd2,0x0f}
+#else
+#define XTENSA_BREAKPOINT {0x2d,0xf0}
+#endif
+
+static const unsigned char xtensa_breakpoint[] = XTENSA_BREAKPOINT;
+#define xtensa_breakpoint_len 2
+
+static CORE_ADDR
+xtensa_get_pc (void)
+{
+  unsigned long pc;
+
+  collect_register_by_name ("pc", &pc);
+  return pc;
+}
+
+static void
+xtensa_set_pc (CORE_ADDR pc)
+{
+  unsigned long newpc = pc;
+  supply_register_by_name ("pc", &newpc);
+}
+
+static int
+xtensa_breakpoint_at (CORE_ADDR where)
+{
+    unsigned long insn;
+
+    (*the_target->read_memory) (where, (unsigned char *) &insn,
+                               xtensa_breakpoint_len);
+    return memcmp((char *)&insn, xtensa_breakpoint, xtensa_breakpoint_len) == 0;
+}
+
+struct linux_target_ops the_low_target = {
+  0,
+  0,
+  0,
+  0,
+  xtensa_get_pc,
+  xtensa_set_pc,
+  xtensa_breakpoint,
+  xtensa_breakpoint_len,
+  NULL,
+  0,
+  xtensa_breakpoint_at,
+};
diff --git a/gdb/gdbserver/xtensa-xtregs.c b/gdb/gdbserver/xtensa-xtregs.c
new file mode 100644 (file)
index 0000000..9faa50d
--- /dev/null
@@ -0,0 +1,37 @@
+/* Table mapping between kernel xtregset and GDB register cache.
+   Copyright 2007, 2008 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+typedef struct {
+  int   gdb_regnum;
+  int   gdb_offset;
+  int   ptrace_cp_offset;
+  int   ptrace_offset;
+  int   size;
+  int   coproc;
+  int   dbnum;
+  char* name
+;} xtensa_regtable_t;
+
+#define XTENSA_ELF_XTREG_SIZE  0
+
+const xtensa_regtable_t  xtensa_regmap_table[] = {
+  /* gnum,gofs,cpofs,ofs,siz,cp, dbnum,  name */
+  { 0 }
+};
+