1/* GNU/Linux/SH specific low level interface, for the remote server for GDB.
2   Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003
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#include <asm/ptrace.h>
30
31#define sh_num_regs 41
32
33/* Currently, don't check/send MQ.  */
34static int sh_regmap[] = {
35 0,	4,	8,	12,	16,	20,	24,	28,
36 32,	36,	40,	44,	48,	52,	56,	60,
37
38 REG_PC*4,   REG_PR*4,   REG_GBR*4,  -1,
39 REG_MACH*4, REG_MACL*4, REG_SR*4,
40 REG_FPUL*4, REG_FPSCR*4,
41
42 REG_FPREG0*4+0,   REG_FPREG0*4+4,   REG_FPREG0*4+8,   REG_FPREG0*4+12,
43 REG_FPREG0*4+16,  REG_FPREG0*4+20,  REG_FPREG0*4+24,  REG_FPREG0*4+28,
44 REG_FPREG0*4+32,  REG_FPREG0*4+36,  REG_FPREG0*4+40,  REG_FPREG0*4+44,
45 REG_FPREG0*4+48,  REG_FPREG0*4+52,  REG_FPREG0*4+56,  REG_FPREG0*4+60,
46};
47
48static int
49sh_cannot_store_register (int regno)
50{
51  return 0;
52}
53
54static int
55sh_cannot_fetch_register (int regno)
56{
57  return 0;
58}
59
60static CORE_ADDR
61sh_get_pc ()
62{
63  unsigned long pc;
64  collect_register_by_name ("pc", &pc);
65  return pc;
66}
67
68static void
69sh_set_pc (CORE_ADDR pc)
70{
71  unsigned long newpc = pc;
72  supply_register_by_name ("pc", &newpc);
73}
74
75/* Correct in either endianness, obviously.  */
76static const unsigned short sh_breakpoint = 0xc3c3;
77#define sh_breakpoint_len 2
78
79static int
80sh_breakpoint_at (CORE_ADDR where)
81{
82  unsigned short insn;
83
84  (*the_target->read_memory) (where, (char *) &insn, 2);
85  if (insn == sh_breakpoint)
86    return 1;
87
88  /* If necessary, recognize more trap instructions here.  GDB only uses the
89     one.  */
90  return 0;
91}
92
93struct linux_target_ops the_low_target = {
94  sh_num_regs,
95  sh_regmap,
96  sh_cannot_fetch_register,
97  sh_cannot_store_register,
98  sh_get_pc,
99  sh_set_pc,
100  (const char *) &sh_breakpoint,
101  sh_breakpoint_len,
102  NULL,
103  0,
104  sh_breakpoint_at,
105};
106