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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [sparclet-rom.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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