OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [gdbserver/] [linux-sparc-low.c] - Blame information for rev 861

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Low level interface to ptrace, for the remote server for GDB.
2
   Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3
   2006, 2007, 2008, 2009, 2010 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 3 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, see <http://www.gnu.org/licenses/>.  */
19
 
20
#include "server.h"
21
#include "linux-low.h"
22
 
23
#include <sys/ptrace.h>
24
 
25
#include "gdb_proc_service.h"
26
 
27
/* The stack pointer is offset from the stack frame by a BIAS of 2047
28
   (0x7ff) for 64-bit code.  BIAS is likely to be defined on SPARC
29
   hosts, so undefine it first.  */
30
#undef BIAS
31
#define BIAS 2047
32
 
33
#ifdef HAVE_SYS_REG_H
34
#include <sys/reg.h>
35
#endif
36
 
37
#define INSN_SIZE 4
38
 
39
#define SPARC_R_REGS_NUM 32
40
#define SPARC_F_REGS_NUM 48
41
#define SPARC_CONTROL_REGS_NUM 6
42
 
43
#define sparc_num_regs (SPARC_R_REGS_NUM + SPARC_F_REGS_NUM + SPARC_CONTROL_REGS_NUM)
44
 
45
/* Each offset is multiplied by 8, because of the register size.
46
   These offsets apply to the buffer sent/filled by ptrace.
47
   Additionally, the array elements order corresponds to the .dat file, and the
48
   gdb's registers enumeration order.  */
49
 
50
static int sparc_regmap[] = {
51
  /* These offsets correspond to GET/SETREGSET.  */
52
        -1,  0*8,  1*8,  2*8,  3*8,  4*8,  5*8,  6*8,       /* g0 .. g7 */
53
        7*8,  8*8,  9*8, 10*8, 11*8, 12*8, 13*8, 14*8,     /* o0 .. o5, sp, o7 */
54
        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,      /* l0 .. l7 */
55
        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,      /* i0 .. i5, fp, i7 */
56
 
57
  /* Floating point registers offsets correspond to GET/SETFPREGSET.  */
58
    0*4,  1*4,  2*4,  3*4,  4*4,  5*4,  6*4,  7*4,          /*  f0 ..  f7 */
59
    8*4,  9*4, 10*4, 11*4, 12*4, 13*4, 14*4, 15*4,         /*  f8 .. f15 */
60
   16*4, 17*4, 18*4, 19*4, 20*4, 21*4, 22*4, 23*4,         /* f16 .. f23 */
61
   24*4, 25*4, 26*4, 27*4, 28*4, 29*4, 30*4, 31*4,         /* f24 .. f31 */
62
 
63
  /* F32 offset starts next to f31: 31*4+4 = 16 * 8.  */
64
   16*8, 17*8, 18*8, 19*8, 20*8, 21*8, 22*8, 23*8,         /* f32 .. f46 */
65
   24*8, 25*8, 26*8, 27*8, 28*8, 29*8, 30*8, 31*8,         /* f48 .. f62 */
66
 
67
   17 *8, /*    pc */
68
   18 *8, /*   npc */
69
   16 *8, /* state */
70
  /* FSR offset also corresponds to GET/SETFPREGSET, ans is placed next to f62.  */
71
   32 *8, /*   fsr */
72
      -1, /*  fprs */
73
  /* Y register is 32-bits length, but gdb takes care of that.  */
74
   19 *8, /*     y */
75
 
76
};
77
 
78
 
79
struct regs_range_t
80
{
81
  int regno_start;
82
  int regno_end;
83
};
84
 
85
static const struct regs_range_t gregs_ranges[] = {
86
 {  0, 31 }, /*   g0 .. i7  */
87
 { 80, 82 }, /*   pc .. state */
88
 { 84, 85 }  /* fprs .. y */
89
};
90
 
91
#define N_GREGS_RANGES (sizeof (gregs_ranges) / sizeof (struct regs_range_t))
92
 
93
static const struct regs_range_t fpregs_ranges[] = {
94
 { 32, 79 }, /* f0 .. f62  */
95
 { 83, 83 }  /* fsr */
96
};
97
 
98
#define N_FPREGS_RANGES (sizeof (fpregs_ranges) / sizeof (struct regs_range_t))
99
 
100
/* Defined in auto-generated file reg-sparc64.c.  */
101
void init_registers_sparc64 (void);
102
 
103
static int
104
sparc_cannot_store_register (int regno)
105
{
106
  return (regno >= sparc_num_regs || sparc_regmap[regno] == -1);
107
}
108
 
109
static int
110
sparc_cannot_fetch_register (int regno)
111
{
112
  return (regno >= sparc_num_regs || sparc_regmap[regno] == -1);
113
}
114
 
115
static void
116
sparc_fill_gregset_to_stack (struct regcache *regcache, const void *buf)
117
{
118
  int i;
119
  CORE_ADDR addr = 0;
120
  unsigned char tmp_reg_buf[8];
121
  const int l0_regno = find_regno("l0");
122
  const int i7_regno = l0_regno + 15;
123
 
124
  /* These registers have to be stored in the stack.  */
125
  memcpy(&addr, ((char *) buf) + sparc_regmap[find_regno("sp")], sizeof(addr));
126
 
127
  addr += BIAS;
128
 
129
  for (i = l0_regno; i <= i7_regno; i++)
130
    {
131
      collect_register (regcache, i, tmp_reg_buf);
132
      (*the_target->write_memory) (addr, tmp_reg_buf, sizeof(tmp_reg_buf));
133
      addr += sizeof(tmp_reg_buf);
134
    }
135
}
136
 
137
static void
138
sparc_fill_gregset (struct regcache *regcache, void *buf)
139
{
140
  int i;
141
  int range;
142
 
143
  for (range = 0; range < N_GREGS_RANGES; range++)
144
    for (i = gregs_ranges[range].regno_start; i <= gregs_ranges[range].regno_end; i++)
145
      if (sparc_regmap[i] != -1)
146
        collect_register (regcache, i, ((char *) buf) + sparc_regmap[i]);
147
 
148
  sparc_fill_gregset_to_stack (regcache, buf);
149
}
150
 
151
static void
152
sparc_fill_fpregset (struct regcache *regcache, void *buf)
153
{
154
  int i;
155
  int range;
156
 
157
  for (range = 0; range < N_FPREGS_RANGES; range++)
158
    for (i = fpregs_ranges[range].regno_start; i <= fpregs_ranges[range].regno_end; i++)
159
      collect_register (regcache, i, ((char *) buf) + sparc_regmap[i]);
160
 
161
}
162
 
163
static void
164
sparc_store_gregset_from_stack (struct regcache *regcache, const void *buf)
165
{
166
  int i;
167
  CORE_ADDR addr = 0;
168
  unsigned char tmp_reg_buf[8];
169
  const int l0_regno = find_regno("l0");
170
  const int i7_regno = l0_regno + 15;
171
 
172
  /* These registers have to be obtained from the stack.  */
173
  memcpy(&addr, ((char *) buf) + sparc_regmap[find_regno("sp")], sizeof(addr));
174
 
175
  addr += BIAS;
176
 
177
  for (i = l0_regno; i <= i7_regno; i++)
178
    {
179
      (*the_target->read_memory) (addr, tmp_reg_buf, sizeof(tmp_reg_buf));
180
      supply_register (regcache, i, tmp_reg_buf);
181
      addr += sizeof(tmp_reg_buf);
182
    }
183
}
184
 
185
static void
186
sparc_store_gregset (struct regcache *regcache, const void *buf)
187
{
188
  int i;
189
  char zerobuf[8];
190
  int range;
191
 
192
  memset (zerobuf, 0, sizeof(zerobuf));
193
 
194
  for (range = 0; range < N_GREGS_RANGES; range++)
195
    for (i = gregs_ranges[range].regno_start; i <= gregs_ranges[range].regno_end; i++)
196
      if (sparc_regmap[i] != -1)
197
        supply_register (regcache, i, ((char *) buf) + sparc_regmap[i]);
198
      else
199
        supply_register (regcache, i, zerobuf);
200
 
201
  sparc_store_gregset_from_stack (regcache, buf);
202
}
203
 
204
static void
205
sparc_store_fpregset (struct regcache *regcache, const void *buf)
206
{
207
  int i;
208
  int range;
209
 
210
  for (range = 0; range < N_FPREGS_RANGES; range++)
211
    for (i = fpregs_ranges[range].regno_start;
212
         i <= fpregs_ranges[range].regno_end;
213
         i++)
214
      supply_register (regcache, i, ((char *) buf) + sparc_regmap[i]);
215
}
216
 
217
extern int debug_threads;
218
 
219
static CORE_ADDR
220
sparc_get_pc (struct regcache *regcache)
221
{
222
  unsigned long pc;
223
  collect_register_by_name (regcache, "pc", &pc);
224
  if (debug_threads)
225
    fprintf (stderr, "stop pc is %08lx\n", pc);
226
  return pc;
227
}
228
 
229
static const unsigned char sparc_breakpoint[INSN_SIZE] = { 0x91, 0xd0, 0x20, 0x01 };
230
#define sparc_breakpoint_len INSN_SIZE
231
 
232
 
233
static int
234
sparc_breakpoint_at (CORE_ADDR where)
235
{
236
  unsigned char insn[INSN_SIZE];
237
 
238
  (*the_target->read_memory) (where, (unsigned char *) insn, sizeof(insn));
239
 
240
  if (memcmp(sparc_breakpoint, insn, sizeof(insn)) == 0)
241
    return 1;
242
 
243
  /* If necessary, recognize more trap instructions here.  GDB only uses TRAP Always.  */
244
 
245
  return 0;
246
}
247
 
248
/* We only place breakpoints in empty marker functions, and thread locking
249
   is outside of the function.  So rather than importing software single-step,
250
   we can just run until exit.  */
251
static CORE_ADDR
252
sparc_reinsert_addr (void)
253
{
254
  struct regcache *regcache = get_thread_regcache (current_inferior, 1);
255
  CORE_ADDR lr;
256
  /* O7 is the equivalent to the 'lr' of other archs.  */
257
  collect_register_by_name (regcache, "o7", &lr);
258
  return lr;
259
}
260
 
261
 
262
struct regset_info target_regsets[] = {
263
  { PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t),
264
    GENERAL_REGS,
265
    sparc_fill_gregset, sparc_store_gregset },
266
  { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, sizeof (fpregset_t),
267
    FP_REGS,
268
    sparc_fill_fpregset, sparc_store_fpregset },
269
  { 0, 0, 0, -1, -1, NULL, NULL }
270
};
271
 
272
struct linux_target_ops the_low_target = {
273
  init_registers_sparc64,
274
  sparc_num_regs,
275
  /* No regmap needs to be provided since this impl. doesn't use USRREGS.  */
276
  NULL,
277
  sparc_cannot_fetch_register,
278
  sparc_cannot_store_register,
279
  sparc_get_pc,
280
  /* No sparc_set_pc is needed.  */
281
  NULL,
282
  (const unsigned char *) sparc_breakpoint,
283
  sparc_breakpoint_len,
284
  sparc_reinsert_addr,
285
  0,
286
  sparc_breakpoint_at,
287
  NULL, NULL, NULL, NULL,
288
  NULL, NULL
289
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.