1/* GNU/Linux/ARM specific low level interface, for the remote server for GDB.
2   Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004
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
25#ifdef HAVE_SYS_REG_H
26#include <sys/reg.h>
27#endif
28
29#define arm_num_regs 26
30
31static int arm_regmap[] = {
32  0, 4, 8, 12, 16, 20, 24, 28,
33  32, 36, 40, 44, 48, 52, 56, 60,
34  -1, -1, -1, -1, -1, -1, -1, -1, -1,
35  64
36};
37
38static int
39arm_cannot_store_register (int regno)
40{
41  return (regno >= arm_num_regs);
42}
43
44static int
45arm_cannot_fetch_register (int regno)
46{
47  return (regno >= arm_num_regs);
48}
49
50extern int debug_threads;
51
52static CORE_ADDR
53arm_get_pc ()
54{
55  unsigned long pc;
56  collect_register_by_name ("pc", &pc);
57  if (debug_threads)
58    fprintf (stderr, "stop pc is %08lx\n", pc);
59  return pc;
60}
61
62static void
63arm_set_pc (CORE_ADDR pc)
64{
65  unsigned long newpc = pc;
66  supply_register_by_name ("pc", &newpc);
67}
68
69/* Correct in either endianness.  We do not support Thumb yet.  */
70static const unsigned long arm_breakpoint = 0xef9f0001;
71#define arm_breakpoint_len 4
72
73static int
74arm_breakpoint_at (CORE_ADDR where)
75{
76  unsigned long insn;
77
78  (*the_target->read_memory) (where, (char *) &insn, 4);
79  if (insn == arm_breakpoint)
80    return 1;
81
82  /* If necessary, recognize more trap instructions here.  GDB only uses the
83     one.  */
84  return 0;
85}
86
87/* We only place breakpoints in empty marker functions, and thread locking
88   is outside of the function.  So rather than importing software single-step,
89   we can just run until exit.  */
90static CORE_ADDR
91arm_reinsert_addr ()
92{
93  unsigned long pc;
94  collect_register_by_name ("lr", &pc);
95  return pc;
96}
97
98struct linux_target_ops the_low_target = {
99  arm_num_regs,
100  arm_regmap,
101  arm_cannot_fetch_register,
102  arm_cannot_store_register,
103  arm_get_pc,
104  arm_set_pc,
105  (const char *) &arm_breakpoint,
106  arm_breakpoint_len,
107  arm_reinsert_addr,
108  0,
109  arm_breakpoint_at,
110};
111