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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [sim/] [ppc/] [sim_calls.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*  This file is part of the program psim.
2
 
3
    Copyright (C) 1994-1996,1998, Andrew Cagney <cagney@highland.com.au>
4
 
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation; either version 2 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License
16
    along with this program; if not, write to the Free Software
17
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 
19
    */
20
 
21
 
22
#include <signal.h> /* FIXME - should be machine dependant version */
23
#include <stdarg.h>
24
#include <ctype.h>
25
 
26
#include "psim.h"
27
#include "options.h"
28
 
29
#undef printf_filtered /* blow away the mapping */
30
 
31
#ifdef HAVE_STDLIB_H
32
#include <stdlib.h>
33
#endif
34
 
35
#ifdef HAVE_STRING_H
36
#include <string.h>
37
#else
38
#ifdef HAVE_STRINGS_H
39
#include <strings.h>
40
#endif
41
#endif
42
 
43
#include "defs.h"
44
#include "bfd.h"
45
#include "callback.h"
46
#include "remote-sim.h"
47
 
48
/* Define the rate at which the simulator should poll the host
49
   for a quit. */
50
#ifndef POLL_QUIT_INTERVAL
51
#define POLL_QUIT_INTERVAL 0x20
52
#endif
53
 
54
static int poll_quit_count = POLL_QUIT_INTERVAL;
55
 
56
/* Structures used by the simulator, for gdb just have static structures */
57
 
58
static psim *simulator;
59
static device *root_device;
60
static host_callback *callbacks;
61
 
62
/* We use GDB's gdbarch_register_name function to map GDB register
63
   numbers onto names, which we can then look up in the register
64
   table.  Since the `set architecture' command can select a new
65
   processor variant at run-time, the meanings of the register numbers
66
   can change, so we need to make sure the sim uses the same
67
   name/number mapping that GDB uses.
68
 
69
   (We don't use the REGISTER_NAME macro, which is a wrapper for
70
   gdbarch_register_name.  We #include GDB's "defs.h", which tries to
71
   #include GDB's "config.h", but gets ours instead, and REGISTER_NAME
72
   ends up not getting defined.  Simpler to just use
73
   gdbarch_register_name directly.)
74
 
75
   We used to just use the REGISTER_NAMES macro from GDB's
76
   target-dependent header files, which expanded into an initializer
77
   for an array of strings.  That was kind of nice, because it meant
78
   that libsim.a had only a compile-time dependency on GDB; using
79
   gdbarch_register_name directly means that there are now link-time
80
   and run-time dependencies too.
81
 
82
   Perhaps the host_callback structure could provide a function for
83
   retrieving register names; that would be cleaner.  */
84
 
85
SIM_DESC
86
sim_open (SIM_OPEN_KIND kind,
87
          host_callback *callback,
88
          struct _bfd *abfd,
89
          char **argv)
90
{
91
  callbacks = callback;
92
 
93
  /* Note: The simulation is not created by sim_open() because
94
     complete information is not yet available */
95
  /* trace the call */
96
  TRACE(trace_gdb, ("sim_open called\n"));
97
 
98
  if (root_device != NULL)
99
    sim_io_printf_filtered("Warning - re-open of simulator leaks memory\n");
100
  root_device = psim_tree();
101
  simulator = NULL;
102
 
103
  psim_options(root_device, argv + 1);
104
 
105
  if (ppc_trace[trace_opts])
106
    print_options ();
107
 
108
  /* fudge our descriptor for now */
109
  return (SIM_DESC) 1;
110
}
111
 
112
 
113
void
114
sim_close (SIM_DESC sd, int quitting)
115
{
116
  TRACE(trace_gdb, ("sim_close(quitting=%d) called\n", quitting));
117
  if (ppc_trace[trace_print_info] && simulator != NULL)
118
    psim_print_info (simulator, ppc_trace[trace_print_info]);
119
}
120
 
121
 
122
SIM_RC
123
sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
124
{
125
  TRACE(trace_gdb, ("sim_load(prog=%s, from_tty=%d) called\n",
126
                    prog, from_tty));
127
  ASSERT(prog != NULL);
128
 
129
  /* create the simulator */
130
  TRACE(trace_gdb, ("sim_load() - first time, create the simulator\n"));
131
  simulator = psim_create(prog, root_device);
132
 
133
  /* bring in all the data section */
134
  psim_init(simulator);
135
 
136
  /* get the start address */
137
  if (abfd == NULL)
138
    {
139
      abfd = bfd_openr (prog, 0);
140
      if (abfd == NULL)
141
        error ("psim: can't open \"%s\": %s\n",
142
               prog, bfd_errmsg (bfd_get_error ()));
143
      if (!bfd_check_format (abfd, bfd_object))
144
        {
145
          const char *errmsg = bfd_errmsg (bfd_get_error ());
146
          bfd_close (abfd);
147
          error ("psim: \"%s\" is not an object file: %s\n",
148
                 prog, errmsg);
149
        }
150
      bfd_close (abfd);
151
    }
152
 
153
  return SIM_RC_OK;
154
}
155
 
156
 
157
int
158
sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)
159
{
160
  int result = psim_read_memory(simulator, MAX_NR_PROCESSORS,
161
                                buf, mem, length);
162
  TRACE(trace_gdb, ("sim_read(mem=0x%lx, buf=0x%lx, length=%d) = %d\n",
163
                    (long)mem, (long)buf, length, result));
164
  return result;
165
}
166
 
167
 
168
int
169
sim_write (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)
170
{
171
  int result = psim_write_memory(simulator, MAX_NR_PROCESSORS,
172
                                 buf, mem, length,
173
                                 1/*violate_ro*/);
174
  TRACE(trace_gdb, ("sim_write(mem=0x%lx, buf=0x%lx, length=%d) = %d\n",
175
                    (long)mem, (long)buf, length, result));
176
  return result;
177
}
178
 
179
 
180
int
181
sim_fetch_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
182
{
183
  char *regname;
184
 
185
  if (simulator == NULL) {
186
    return 0;
187
  }
188
 
189
  /* GDB will sometimes ask for the contents of a register named "";
190
     we ignore such requests, and leave garbage in *BUF.  In GDB
191
     terms, the empty string means "the register with this number is
192
     not present in the currently selected architecture variant."
193
     That's following the kludge we're using for the MIPS processors.
194
     But there are loops that just walk through the entire list of
195
     names and try to get everything.  */
196
  regname = gdbarch_register_name (current_gdbarch, regno);
197
  if (! regname || regname[0] == '\0')
198
    return -1;
199
 
200
  TRACE(trace_gdb, ("sim_fetch_register(regno=%d(%s), buf=0x%lx)\n",
201
                    regno, regname, (long)buf));
202
  psim_read_register(simulator, MAX_NR_PROCESSORS,
203
                     buf, regname, raw_transfer);
204
  return -1;
205
}
206
 
207
 
208
int
209
sim_store_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
210
{
211
  char *regname;
212
 
213
  if (simulator == NULL)
214
    return 0;
215
 
216
  /* See comments in sim_fetch_register, above.  */
217
  regname = gdbarch_register_name (current_gdbarch, regno);
218
  if (! regname || regname[0] == '\0')
219
    return -1;
220
 
221
  TRACE(trace_gdb, ("sim_store_register(regno=%d(%s), buf=0x%lx)\n",
222
                    regno, regname, (long)buf));
223
  psim_write_register(simulator, MAX_NR_PROCESSORS,
224
                      buf, regname, raw_transfer);
225
  return -1;
226
}
227
 
228
 
229
void
230
sim_info (SIM_DESC sd, int verbose)
231
{
232
  TRACE(trace_gdb, ("sim_info(verbose=%d) called\n", verbose));
233
  psim_print_info (simulator, verbose);
234
}
235
 
236
 
237
SIM_RC
238
sim_create_inferior (SIM_DESC sd,
239
                     struct _bfd *abfd,
240
                     char **argv,
241
                     char **envp)
242
{
243
  unsigned_word entry_point;
244
  TRACE(trace_gdb, ("sim_create_inferior(start_address=0x%x, ...)\n",
245
                    entry_point));
246
 
247
  if (simulator == NULL)
248
    error ("No program loaded");
249
 
250
  if (abfd != NULL)
251
    entry_point = bfd_get_start_address (abfd);
252
  else
253
    entry_point = 0xfff00000; /* ??? */
254
 
255
  psim_init(simulator);
256
  psim_stack(simulator, argv, envp);
257
 
258
  psim_write_register(simulator, -1 /* all start at same PC */,
259
                      &entry_point, "pc", cooked_transfer);
260
  return SIM_RC_OK;
261
}
262
 
263
 
264
void
265
sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
266
{
267
  psim_status status = psim_get_status(simulator);
268
 
269
  switch (status.reason) {
270
  case was_continuing:
271
    *reason = sim_stopped;
272
    if (status.signal == 0)
273
      *sigrc = SIGTRAP;
274
    else
275
      *sigrc = status.signal;
276
    break;
277
  case was_trap:
278
    *reason = sim_stopped;
279
    *sigrc = SIGTRAP;
280
    break;
281
  case was_exited:
282
    *reason = sim_exited;
283
    *sigrc = status.signal;
284
    break;
285
  case was_signalled:
286
    *reason = sim_signalled;
287
    *sigrc = status.signal;
288
    break;
289
  }
290
 
291
  TRACE(trace_gdb, ("sim_stop_reason(reason=0x%lx(%ld), sigrc=0x%lx(%ld))\n",
292
                    (long)reason, (long)*reason, (long)sigrc, (long)*sigrc));
293
}
294
 
295
 
296
 
297
/* Run (or resume) the program.  */
298
 
299
int
300
sim_stop (SIM_DESC sd)
301
{
302
  psim_stop (simulator);
303
  return 1;
304
}
305
 
306
void
307
sim_resume (SIM_DESC sd, int step, int siggnal)
308
{
309
  TRACE(trace_gdb, ("sim_resume(step=%d, siggnal=%d)\n",
310
                    step, siggnal));
311
 
312
  if (step)
313
    {
314
      psim_step (simulator);
315
    }
316
  else
317
    {
318
      psim_run (simulator);
319
    }
320
}
321
 
322
void
323
sim_do_command (SIM_DESC sd, char *cmd)
324
{
325
  TRACE(trace_gdb, ("sim_do_commands(cmd=%s) called\n",
326
                    cmd ? cmd : "(null)"));
327
  if (cmd != NULL) {
328
    char **argv = buildargv(cmd);
329
    psim_command(root_device, argv);
330
    freeargv(argv);
331
  }
332
}
333
 
334
 
335
/* Polling, if required */
336
 
337
void
338
sim_io_poll_quit (void)
339
{
340
  if (callbacks->poll_quit != NULL && poll_quit_count-- < 0)
341
    {
342
      poll_quit_count = POLL_QUIT_INTERVAL;
343
      if (callbacks->poll_quit (callbacks))
344
        psim_stop (simulator);
345
    }
346
}
347
 
348
 
349
 
350
/* Map simulator IO operations onto the corresponding GDB I/O
351
   functions.
352
 
353
   NB: Only a limited subset of operations are mapped across.  More
354
   advanced operations (such as dup or write) must either be mapped to
355
   one of the below calls or handled internally */
356
 
357
int
358
sim_io_read_stdin(char *buf,
359
                  int sizeof_buf)
360
{
361
  switch (CURRENT_STDIO) {
362
  case DO_USE_STDIO:
363
    return callbacks->read_stdin(callbacks, buf, sizeof_buf);
364
    break;
365
  case DONT_USE_STDIO:
366
    return callbacks->read(callbacks, 0, buf, sizeof_buf);
367
    break;
368
  default:
369
    error("sim_io_read_stdin: unaccounted switch\n");
370
    break;
371
  }
372
  return 0;
373
}
374
 
375
int
376
sim_io_write_stdout(const char *buf,
377
                    int sizeof_buf)
378
{
379
  switch (CURRENT_STDIO) {
380
  case DO_USE_STDIO:
381
    return callbacks->write_stdout(callbacks, buf, sizeof_buf);
382
    break;
383
  case DONT_USE_STDIO:
384
    return callbacks->write(callbacks, 1, buf, sizeof_buf);
385
    break;
386
  default:
387
    error("sim_io_write_stdout: unaccounted switch\n");
388
    break;
389
  }
390
  return 0;
391
}
392
 
393
int
394
sim_io_write_stderr(const char *buf,
395
                    int sizeof_buf)
396
{
397
  switch (CURRENT_STDIO) {
398
  case DO_USE_STDIO:
399
    /* NB: I think there should be an explicit write_stderr callback */
400
    return callbacks->write(callbacks, 3, buf, sizeof_buf);
401
    break;
402
  case DONT_USE_STDIO:
403
    return callbacks->write(callbacks, 3, buf, sizeof_buf);
404
    break;
405
  default:
406
    error("sim_io_write_stderr: unaccounted switch\n");
407
    break;
408
  }
409
  return 0;
410
}
411
 
412
 
413
void
414
sim_io_printf_filtered(const char *fmt,
415
                       ...)
416
{
417
  char message[1024];
418
  va_list ap;
419
  /* format the message */
420
  va_start(ap, fmt);
421
  vsprintf(message, fmt, ap);
422
  va_end(ap);
423
  /* sanity check */
424
  if (strlen(message) >= sizeof(message))
425
    error("sim_io_printf_filtered: buffer overflow\n");
426
  callbacks->printf_filtered(callbacks, "%s", message);
427
}
428
 
429
void
430
sim_io_flush_stdoutput(void)
431
{
432
  switch (CURRENT_STDIO) {
433
  case DO_USE_STDIO:
434
    callbacks->flush_stdout (callbacks);
435
    break;
436
  case DONT_USE_STDIO:
437
    break;
438
  default:
439
    error("sim_io_read_stdin: unaccounted switch\n");
440
    break;
441
  }
442
}
443
 
444
/****/
445
 
446
void *
447
zalloc(long size)
448
{
449
  void *memory = (void*)xmalloc(size);
450
  if (memory == NULL)
451
    error("xmalloc failed\n");
452
  memset(memory, 0, size);
453
  return memory;
454
}
455
 
456
void zfree(void *data)
457
{
458
  free(data);
459
}

powered by: WebSVN 2.1.0

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