2005-05-23 Orjan Friberg <orjanf@axis.com>
[external/binutils.git] / gdb / gdbserver / linux-cris-low.c
1 /* GNU/Linux/CRIS specific low level interface, for the remote server for GDB.
2    Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3    Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 #include "server.h"
23 #include "linux-low.h"
24 #include <sys/ptrace.h>
25
26 /* CRISv10 */
27 #define cris_num_regs 32
28
29 /* Locations need to match <include/asm/arch/ptrace.h>.  */
30 static int cris_regmap[] = {
31   15*4, 14*4, 13*4, 12*4,
32   11*4, 10*4, 9*4, 8*4,
33   7*4, 6*4, 5*4, 4*4,
34   3*4, 2*4, 23*4, 19*4,
35
36   -1, -1, -1, -1,
37   -1, 17*4, -1, 16*4,
38   -1, -1, -1, 18*4,
39   -1, 17*4, -1, -1
40   
41 };
42
43 static int
44 cris_cannot_store_register (int regno)
45 {
46   if (cris_regmap[regno] == -1)
47     return 1;
48   
49   return (regno >= cris_num_regs);
50 }
51
52 static int
53 cris_cannot_fetch_register (int regno)
54 {
55   if (cris_regmap[regno] == -1)
56     return 1;
57
58   return (regno >= cris_num_regs);
59 }
60
61 extern int debug_threads;
62
63 static CORE_ADDR
64 cris_get_pc (void)
65 {
66   unsigned long pc;
67   collect_register_by_name ("pc", &pc);
68   if (debug_threads)
69     fprintf (stderr, "stop pc is %08lx\n", pc);
70   return pc;
71 }
72
73 static void
74 cris_set_pc (CORE_ADDR pc)
75 {
76   unsigned long newpc = pc;
77   supply_register_by_name ("pc", &newpc);
78 }
79
80 static const unsigned short cris_breakpoint = 0xe938;
81 #define cris_breakpoint_len 2
82
83 static int
84 cris_breakpoint_at (CORE_ADDR where)
85 {
86   unsigned short insn;
87
88   (*the_target->read_memory) (where, (char *) &insn, cris_breakpoint_len);
89   if (insn == cris_breakpoint)
90     return 1;
91
92   /* If necessary, recognize more trap instructions here.  GDB only uses the
93      one.  */
94   return 0;
95 }
96
97 /* We only place breakpoints in empty marker functions, and thread locking
98    is outside of the function.  So rather than importing software single-step,
99    we can just run until exit.  */
100 static CORE_ADDR
101 cris_reinsert_addr (void)
102 {
103   unsigned long pc;
104   collect_register_by_name ("srp", &pc);
105   return pc;
106 }
107
108 struct linux_target_ops the_low_target = {
109   cris_num_regs,
110   cris_regmap,
111   cris_cannot_fetch_register,
112   cris_cannot_store_register,
113   cris_get_pc,
114   cris_set_pc,
115   (const char *) &cris_breakpoint,
116   cris_breakpoint_len,
117   cris_reinsert_addr,
118   0,
119   cris_breakpoint_at,
120   0,
121   0,
122   0,
123   0,
124 };