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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [sparclet-rom.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 1181 sfurman
/* Remote target glue for the SPARC Sparclet ROM monitor.
2
 
3
   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free
4
   Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 2 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 59 Temple Place - Suite 330,
21
   Boston, MA 02111-1307, USA.  */
22
 
23
 
24
#include "defs.h"
25
#include "gdbcore.h"
26
#include "target.h"
27
#include "monitor.h"
28
#include "serial.h"
29
#include "srec.h"
30
#include "symtab.h"
31
#include "symfile.h"            /* for generic_load */
32
#include "regcache.h"
33
#include <time.h>
34
 
35
extern void report_transfer_performance (unsigned long, time_t, time_t);
36
 
37
static struct target_ops sparclet_ops;
38
 
39
static void sparclet_open (char *args, int from_tty);
40
 
41
/* This array of registers need to match the indexes used by GDB.
42
   This exists because the various ROM monitors use different strings
43
   than does GDB, and don't necessarily support all the registers
44
   either. So, typing "info reg sp" becomes a "r30".  */
45
 
46
/*PSR 0x00000080  impl ver icc AW LE EE EC EF PIL S PS ET CWP  WIM
47
   0x0  0x0 0x0  0  0  0  0  0 0x0 1  0  0 0x00 0x2
48
   0000010
49
   INS        LOCALS       OUTS      GLOBALS
50
 
51
   1  0x00000000  0x00000000  0x00000000  0x00000000
52
   2  0x00000000  0x00000000  0x00000000  0x00000000
53
   3  0x00000000  0x00000000  0x00000000  0x00000000
54
   4  0x00000000  0x00000000  0x00000000  0x00000000
55
   5  0x00000000  0x00001000  0x00000000  0x00000000
56
   6  0x00000000  0x00000000  0x123f0000  0x00000000
57
   7  0x00000000  0x00000000  0x00000000  0x00000000
58
   pc:  0x12010000 0x00000000    unimp
59
   npc: 0x12010004 0x00001000    unimp     0x1000
60
   tbr: 0x00000000
61
   y:   0x00000000
62
 */
63
/* these correspond to the offsets from tm-* files from config directories */
64
 
65
/* is wim part of psr?? */
66
/* monitor wants lower case */
67
static char *sparclet_regnames[] = {
68
  "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
69
  "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
70
  "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
71
  "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
72
 
73
  "", "", "", "", "", "", "", "", /* no FPU regs */
74
  "", "", "", "", "", "", "", "",
75
  "", "", "", "", "", "", "", "",
76
  "", "", "", "", "", "", "", "",
77
                                  /* no CPSR, FPSR */
78
  "y", "psr", "wim", "tbr", "pc", "npc", "", "",
79
 
80
  "ccsr", "ccpr", "cccrcr", "ccor", "ccobr", "ccibr", "ccir", "",
81
 
82
  /*       ASR15                 ASR19 (don't display them) */
83
  "asr1",  "", "asr17", "asr18", "", "asr20", "asr21", "asr22",
84
/*
85
  "awr0",  "awr1",  "awr2",  "awr3",  "awr4",  "awr5",  "awr6",  "awr7",
86
  "awr8",  "awr9",  "awr10", "awr11", "awr12", "awr13", "awr14", "awr15",
87
  "awr16", "awr17", "awr18", "awr19", "awr20", "awr21", "awr22", "awr23",
88
  "awr24", "awr25", "awr26", "awr27", "awr28", "awr29", "awr30", "awr31",
89
  "apsr",
90
 */
91
};
92
 
93
 
94
 
95
/* Function: sparclet_supply_register
96
   Just returns with no action.
97
   This function is required, because parse_register_dump (monitor.c)
98
   expects to be able to call it.  If we don't supply something, it will
99
   call a null pointer and core-dump.  Since this function does not
100
   actually do anything, GDB will request the registers individually.  */
101
 
102
static void
103
sparclet_supply_register (char *regname, int regnamelen, char *val, int vallen)
104
{
105
  return;
106
}
107
 
108
static void
109
sparclet_load (struct serial *desc, char *file, int hashmark)
110
{
111
  bfd *abfd;
112
  asection *s;
113
  int i;
114
  CORE_ADDR load_offset;
115
  time_t start_time, end_time;
116
  unsigned long data_count = 0;
117
 
118
  /* enable user to specify address for downloading as 2nd arg to load */
119
 
120
  i = sscanf (file, "%*s 0x%lx", &load_offset);
121
  if (i >= 1)
122
    {
123
      char *p;
124
 
125
      for (p = file; *p != '\000' && !isspace (*p); p++);
126
 
127
      *p = '\000';
128
    }
129
  else
130
    load_offset = 0;
131
 
132
  abfd = bfd_openr (file, 0);
133
  if (!abfd)
134
    {
135
      printf_filtered ("Unable to open file %s\n", file);
136
      return;
137
    }
138
 
139
  if (bfd_check_format (abfd, bfd_object) == 0)
140
    {
141
      printf_filtered ("File is not an object file\n");
142
      return;
143
    }
144
 
145
  start_time = time (NULL);
146
 
147
  for (s = abfd->sections; s; s = s->next)
148
    if (s->flags & SEC_LOAD)
149
      {
150
        bfd_size_type section_size;
151
        bfd_vma vma;
152
 
153
        vma = bfd_get_section_vma (abfd, s) + load_offset;
154
        section_size = bfd_section_size (abfd, s);
155
 
156
        data_count += section_size;
157
 
158
        printf_filtered ("%s\t: 0x%4x .. 0x%4x  ",
159
                         bfd_get_section_name (abfd, s), vma,
160
                         vma + section_size);
161
        gdb_flush (gdb_stdout);
162
 
163
        monitor_printf ("load c r %x %x\r", vma, section_size);
164
 
165
        monitor_expect ("load: loading ", NULL, 0);
166
        monitor_expect ("\r", NULL, 0);
167
 
168
        for (i = 0; i < section_size; i += 2048)
169
          {
170
            int numbytes;
171
            char buf[2048];
172
 
173
            numbytes = min (sizeof buf, section_size - i);
174
 
175
            bfd_get_section_contents (abfd, s, buf, i, numbytes);
176
 
177
            serial_write (desc, buf, numbytes);
178
 
179
            if (hashmark)
180
              {
181
                putchar_unfiltered ('#');
182
                gdb_flush (gdb_stdout);
183
              }
184
          }                     /* Per-packet (or S-record) loop */
185
 
186
        monitor_expect_prompt (NULL, 0);
187
 
188
        putchar_unfiltered ('\n');
189
      }                         /* Loadable sections */
190
 
191
  monitor_printf ("reg pc %x\r", bfd_get_start_address (abfd));
192
  monitor_expect_prompt (NULL, 0);
193
  monitor_printf ("reg npc %x\r", bfd_get_start_address (abfd) + 4);
194
  monitor_expect_prompt (NULL, 0);
195
 
196
  monitor_printf ("run\r");
197
 
198
  end_time = time (NULL);
199
 
200
  if (hashmark)
201
    putchar_unfiltered ('\n');
202
 
203
  report_transfer_performance (data_count, start_time, end_time);
204
 
205
  pop_target ();
206
  push_remote_target (monitor_get_dev_name (), 1);
207
 
208
  throw_exception (RETURN_QUIT);
209
}
210
 
211
/* Define the monitor command strings. Since these are passed directly
212
   through to a printf style function, we may include formatting
213
   strings. We also need a CR or LF on the end.  */
214
 
215
/* need to pause the monitor for timing reasons, so slow it down */
216
 
217
static char *sparclet_inits[] =
218
{"\n\r\r\n", NULL};
219
 
220
static struct monitor_ops sparclet_cmds;
221
 
222
static void
223
init_sparclet_cmds (void)
224
{
225
  sparclet_cmds.flags = MO_CLR_BREAK_USES_ADDR |
226
    MO_HEX_PREFIX |
227
    MO_NO_ECHO_ON_OPEN |
228
    MO_NO_ECHO_ON_SETMEM |
229
    MO_RUN_FIRST_TIME |
230
    MO_GETMEM_READ_SINGLE;      /* flags */
231
  sparclet_cmds.init = sparclet_inits;  /* Init strings */
232
  sparclet_cmds.cont = "cont\r";        /* continue command */
233
  sparclet_cmds.step = "step\r";        /* single step */
234
  sparclet_cmds.stop = "\r";    /* break interrupts the program */
235
  sparclet_cmds.set_break = "+bp %x\r";         /* set a breakpoint */
236
  sparclet_cmds.clr_break = "-bp %x\r";         /* can't use "br" because only 2 hw bps are supported */
237
  sparclet_cmds.clr_all_break = "-bp %x\r";     /* clear a breakpoint */
238
  "-bp\r";                      /* clear all breakpoints */
239
  sparclet_cmds.fill = "fill %x -n %x -v %x -b\r";      /* fill (start length val) */
240
  /* can't use "fi" because it takes words, not bytes */
241
  /* ex [addr] [-n count] [-b|-s|-l]          default: ex cur -n 1 -b */
242
  sparclet_cmds.setmem.cmdb = "ex %x -b\r%x\rq\r";      /* setmem.cmdb (addr, value) */
243
  sparclet_cmds.setmem.cmdw = "ex %x -s\r%x\rq\r";      /* setmem.cmdw (addr, value) */
244
  sparclet_cmds.setmem.cmdl = "ex %x -l\r%x\rq\r";      /* setmem.cmdl (addr, value) */
245
  sparclet_cmds.setmem.cmdll = NULL;    /* setmem.cmdll (addr, value) */
246
  sparclet_cmds.setmem.resp_delim = NULL;       /*": " *//* setmem.resp_delim */
247
  sparclet_cmds.setmem.term = NULL;     /*"? " *//* setmem.term */
248
  sparclet_cmds.setmem.term_cmd = NULL;         /*"q\r" *//* setmem.term_cmd */
249
  /* since the parsing of multiple bytes is difficult due to
250
     interspersed addresses, we'll only read 1 value at a time,
251
     even tho these can handle a count */
252
  /* we can use -n to set count to read, but may have to parse? */
253
  sparclet_cmds.getmem.cmdb = "ex %x -n 1 -b\r";        /* getmem.cmdb (addr, #bytes) */
254
  sparclet_cmds.getmem.cmdw = "ex %x -n 1 -s\r";        /* getmem.cmdw (addr, #swords) */
255
  sparclet_cmds.getmem.cmdl = "ex %x -n 1 -l\r";        /* getmem.cmdl (addr, #words) */
256
  sparclet_cmds.getmem.cmdll = NULL;    /* getmem.cmdll (addr, #dwords) */
257
  sparclet_cmds.getmem.resp_delim = ": ";       /* getmem.resp_delim */
258
  sparclet_cmds.getmem.term = NULL;     /* getmem.term */
259
  sparclet_cmds.getmem.term_cmd = NULL;         /* getmem.term_cmd */
260
  sparclet_cmds.setreg.cmd = "reg %s 0x%x\r";   /* setreg.cmd (name, value) */
261
  sparclet_cmds.setreg.resp_delim = NULL;       /* setreg.resp_delim */
262
  sparclet_cmds.setreg.term = NULL;     /* setreg.term */
263
  sparclet_cmds.setreg.term_cmd = NULL;         /* setreg.term_cmd */
264
  sparclet_cmds.getreg.cmd = "reg %s\r";        /* getreg.cmd (name) */
265
  sparclet_cmds.getreg.resp_delim = " ";        /* getreg.resp_delim */
266
  sparclet_cmds.getreg.term = NULL;     /* getreg.term */
267
  sparclet_cmds.getreg.term_cmd = NULL;         /* getreg.term_cmd */
268
  sparclet_cmds.dump_registers = "reg\r";       /* dump_registers */
269
  sparclet_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)";     /* register_pattern */
270
  sparclet_cmds.supply_register = sparclet_supply_register;     /* supply_register */
271
  sparclet_cmds.load_routine = sparclet_load;   /* load_routine */
272
  sparclet_cmds.load = NULL;    /* download command (srecs on console) */
273
  sparclet_cmds.loadresp = NULL;        /* load response */
274
  sparclet_cmds.prompt = "monitor>";    /* monitor command prompt */
275
  /* yikes!  gdb core dumps without this delimitor!! */
276
  sparclet_cmds.line_term = "\r";       /* end-of-command delimitor */
277
  sparclet_cmds.cmd_end = NULL; /* optional command terminator */
278
  sparclet_cmds.target = &sparclet_ops;         /* target operations */
279
  sparclet_cmds.stopbits = SERIAL_1_STOPBITS;   /* number of stop bits */
280
  sparclet_cmds.regnames = sparclet_regnames;   /* registers names */
281
  sparclet_cmds.magic = MONITOR_OPS_MAGIC;      /* magic */
282
};
283
 
284
static void
285
sparclet_open (char *args, int from_tty)
286
{
287
  monitor_open (args, &sparclet_cmds, from_tty);
288
}
289
 
290
void
291
_initialize_sparclet (void)
292
{
293
  int i;
294
  init_sparclet_cmds ();
295
 
296
  for (i = 0; i < NUM_REGS; i++)
297
    if (sparclet_regnames[i][0] == 'c' ||
298
        sparclet_regnames[i][0] == 'a')
299
      sparclet_regnames[i] = 0;  /* mon can't report c* or a* regs */
300
 
301
  sparclet_regnames[0] = 0;       /* mon won't report %G0 */
302
 
303
  init_monitor_ops (&sparclet_ops);
304
  sparclet_ops.to_shortname = "sparclet";       /* for the target command */
305
  sparclet_ops.to_longname = "SPARC Sparclet monitor";
306
  /* use SW breaks; target only supports 2 HW breakpoints */
307
  sparclet_ops.to_insert_breakpoint = memory_insert_breakpoint;
308
  sparclet_ops.to_remove_breakpoint = memory_remove_breakpoint;
309
 
310
  sparclet_ops.to_doc =
311
    "Use a board running the Sparclet debug monitor.\n\
312
Specify the serial device it is connected to (e.g. /dev/ttya).";
313
 
314
  sparclet_ops.to_open = sparclet_open;
315
  add_target (&sparclet_ops);
316
}

powered by: WebSVN 2.1.0

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