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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [sparclet-rom.c] - Blame information for rev 1767

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

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

powered by: WebSVN 2.1.0

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