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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [toplevel-support.c] - Blame information for rev 226

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

Line No. Rev Author Line
1 19 jeremybenn
/* toplevel.c -- Top level simulator support source file
2
 
3
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
4
   Copyright (C) 2008 Embecosm Limited
5
 
6
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
7
 
8
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
9
 
10
   This program is free software; you can redistribute it and/or modify it
11
   under the terms of the GNU General Public License as published by the Free
12
   Software Foundation; either version 3 of the License, or (at your option)
13
   any later version.
14
 
15
   This program is distributed in the hope that it will be useful, but WITHOUT
16
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18
   more details.
19
 
20
   You should have received a copy of the GNU General Public License along
21
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
 
23
/* This program is commented throughout in a fashion suitable for processing
24
   with Doxygen. */
25
 
26
 
27
/* Autoconf and/or portability configuration */
28
#include "config.h"
29
 
30
/* System includes */
31
#include <stdlib.h>
32
#include <unistd.h>
33
#include <stdarg.h>
34
#include <stdio.h>
35
#include <errno.h>
36
#include <signal.h>
37
 
38
/* Package includes */
39
#include "toplevel-support.h"
40
#include "sim-config.h"
41
#include "debug-unit.h"
42
#include "sim-cmd.h"
43
#include "sched.h"
44
#include "tick.h"
45
#include "pm.h"
46
#include "pic.h"
47
#include "execute.h"
48
#include "labels.h"
49
#include "stats.h"
50
#include "opcode/or32.h"
51
#include "parse.h"
52
#include "gdbcomm.h"
53
#include "rsp-server.h"
54
#include "vapi.h"
55
#include "abstract.h"
56
#include "mc.h"
57
#include "except.h"
58
 
59
 
60
/*! Struct for list of reset hooks */
61
struct sim_reset_hook
62
{
63
  void *dat;
64
  void (*reset_hook) (void *);
65
  struct sim_reset_hook *next;
66
};
67
 
68
/*! The list of reset hooks. Local to this source file */
69
static struct sim_reset_hook *sim_reset_hooks = NULL;
70
 
71
 
72
/*---------------------------------------------------------------------------*/
73
/*!Signal handler for ctrl-C
74
 
75
   Sets the iprompt flag, so the simulator will stop next time round the
76
   loop. If the iprompt flag is set when we enter here, that means the
77
   simulator has not reacted since the last ctrl-C, so we kill the simulation.
78
 
79
   @param[in] signum  The signal which triggered this handler                */
80
/*---------------------------------------------------------------------------*/
81
void
82
ctrl_c (signum)
83
     int signum;
84
{
85
  /* Incase the user pressed ctrl+c twice without the sim reacting kill it.
86
   * This is incase the sim locks up in a high level routine, without executeing
87
   * any (or) code */
88
  if (runtime.sim.iprompt && !runtime.sim.iprompt_run)
89
    {
90
      sim_done ();
91
      exit (-1);
92
    }
93
 
94
  /* Mark the simulator to stop next time and reinstall the handler */
95
  runtime.sim.iprompt = 1;
96
  signal (SIGINT, ctrl_c);
97
 
98
}       /* ctrl_c() */
99
 
100
 
101
/*---------------------------------------------------------------------------*/
102
/*!Routine poll to see if interaction is needed
103
 
104
   This is most likely to happen due to a ctrl-C. However when the -i flag is
105
   specified, the simulator starts up ready for interaction.
106
 
107
   The main simulator loop will stop for interaction if it hits a breakpoint.
108
 
109
   @param[in] dat  Data passed in by the Or1ksim scheduler. Not needed by this
110
   function.                                                                 */
111
/*---------------------------------------------------------------------------*/
112
void
113
check_int (void *dat)
114
{
115
  if (runtime.sim.iprompt)
116
    {
117
      set_stall_state (0);
118
      handle_sim_command ();
119
    }
120
 
121
  SCHED_ADD (check_int, NULL, CHECK_INT_TIME);
122
 
123
}       /* check_int() */
124
 
125
 
126
/*---------------------------------------------------------------------------*/
127
/*!Register a new reset hook
128
 
129
   The registered functions will be called in turn, whenever the simulation is
130
   reset by calling sim_reset().
131
 
132
   @param[in] reset_hook  The function to be called on reset
133
   @param[in] dat         The data structure to be passed as argument when the
134
                          reset_hook function is called.                     */
135
/*---------------------------------------------------------------------------*/
136
void
137
reg_sim_reset (void (*reset_hook) (void *), void *dat)
138
{
139
  struct sim_reset_hook *new = malloc (sizeof (struct sim_reset_hook));
140
 
141
  if (!new)
142
    {
143
      fprintf (stderr, "reg_sim_reset: Out-of-memory\n");
144
      exit (1);
145
    }
146
 
147
  new->dat = dat;
148
  new->reset_hook = reset_hook;
149
  new->next = sim_reset_hooks;
150
  sim_reset_hooks = new;
151
 
152
}       /* reg_sim_reset() */
153
 
154
 
155
/*---------------------------------------------------------------------------*/
156
/*!Reset the simulator
157
 
158
   The scheduler is reset, then all reset functions on the reset hook list
159
   (i.e. peripherals) are reset. Then standard core functions (which do not
160
   use reset hooks) are reset: tick timer, power management, programmable
161
   interrupt controller and debug unit.
162
 
163
   The scheduler queue is reinitialized with an immediate check for ctrl-C on
164
   its queue.
165
 
166
   Finally the count of simulated cycles is set to zero. and the CPU itself is
167
   reset.                                                                    */
168
/*---------------------------------------------------------------------------*/
169
void
170
sim_reset ()
171
{
172
  struct sim_reset_hook *cur_reset = sim_reset_hooks;
173
 
174
  /* We absolutely MUST reset the scheduler first */
175
  sched_reset ();
176
 
177
  while (cur_reset)
178
    {
179
      cur_reset->reset_hook (cur_reset->dat);
180
      cur_reset = cur_reset->next;
181
    }
182
 
183
  tick_reset ();
184
  pm_reset ();
185
  pic_reset ();
186
  du_reset ();
187
 
188
  /* Make sure that runtime.sim.iprompt is the first thing to get checked */
189
  SCHED_ADD (check_int, NULL, 1);
190
 
191
  /* FIXME: Lame-ass way to get runtime.sim.mem_cycles not going into overly
192
   * negative numbers.  This happens because parse.c uses setsim_mem32 to load
193
   * the program but set_mem32 calls dc_simulate_write, which inturn calls
194
   * setsim_mem32.  This mess of memory statistics needs to be sorted out for
195
   * good one day */
196
  runtime.sim.mem_cycles = 0;
197
  cpu_reset ();
198
 
199
}       /* sim_reset() */
200
 
201
 
202
/*---------------------------------------------------------------------------*/
203
/*!Initalize the simulator
204
 
205
  Reset internal data: symbol table (aka labels), breakpoints and
206
  stats. Rebuild the FSA's used for disassembly.
207
 
208
  Initialize the dynamic execution system if required.
209
 
210
  Initialize the scheduler.
211
 
212
  Open the various logs and statistics files requested by the configuration
213
  and/or command arguments.
214
 
215
  Initialize GDB and VAPI connections.
216
 
217
  Reset the simulator.
218
 
219
  Wait for VAPI to connect if configured.                                    */
220
/*---------------------------------------------------------------------------*/
221
void
222
sim_init ()
223
{
224 220 jeremybenn
  PRINTFQ ("Or1ksim " PACKAGE_VERSION "\n" );
225 19 jeremybenn
  init_labels ();
226
  init_breakpoints ();
227
  initstats ();
228 220 jeremybenn
  build_automata (config.sim.quiet);
229 19 jeremybenn
 
230
#if DYNAMIC_EXECUTION
231
  /* Note: This must be called before the scheduler is used */
232
  init_dyn_recomp ();
233
#endif
234
 
235
  sched_init ();
236
 
237
  sim_reset ();                 /* Must do this first - torches memory! */
238
 
239
  if (config.sim.profile)
240
    {
241
      runtime.sim.fprof = fopen (config.sim.prof_fn, "wt+");
242
      if (!runtime.sim.fprof)
243
        {
244
          fprintf (stderr, "ERROR: sim_init: cannot open profile file %s: ",
245
                   config.sim.prof_fn);
246
          perror (NULL);
247
          exit (1);
248
        }
249
      else
250
        fprintf (runtime.sim.fprof,
251
                 "+00000000 FFFFFFFF FFFFFFFF [outside_functions]\n");
252
    }
253
 
254
  if (config.sim.mprofile)
255
    {
256
      runtime.sim.fmprof = fopen (config.sim.mprof_fn, "wb+");
257
      if (!runtime.sim.fmprof)
258
        {
259
          fprintf (stderr, "ERROR: sim_init: cannot open memory profile "
260
                   "file %s: ", config.sim.mprof_fn);
261
          perror (NULL);
262
          exit (1);
263
        }
264
    }
265
 
266
  if (config.sim.exe_log)
267
    {
268
      runtime.sim.fexe_log = fopen (config.sim.exe_log_fn, "wt+");
269
      if (!runtime.sim.fexe_log)
270
        {
271
          fprintf (stderr, "sim_init: cannot open execution log file %s: ",
272
                   config.sim.exe_log_fn);
273
          perror (NULL);
274
          exit (1);
275
        }
276
    }
277
 
278 202 julius
  if (config.sim.exe_bin_insn_log)
279
    {
280
      runtime.sim.fexe_bin_insn_log = fopen (config.sim.exe_bin_insn_log_fn, "wb+");
281
      if (!runtime.sim.fexe_bin_insn_log)
282
        {
283
          fprintf (stderr, "sim_init: cannot open binary instruction execution log file %s: ",
284
                   config.sim.exe_bin_insn_log_fn);
285
          perror (NULL);
286
          exit (1);
287
        }
288
    }
289
 
290 19 jeremybenn
  /* MM170901 always load at address zero */
291
  if (runtime.sim.filename)
292
    {
293
      unsigned long endaddr = loadcode (runtime.sim.filename, 0, 0);
294
 
295
      if (endaddr == -1)
296
        {
297
          fprintf (stderr, "ERROR: sim_init: problem loading code from %s\n",
298
                   runtime.sim.filename);
299
          exit (1);
300
        }
301
    }
302
 
303
  /* Disable GDB debugging, if debug unit is not available.  */
304
  if ((config.debug.gdb_enabled || config.debug.rsp_enabled) &&
305
      !config.debug.enabled)
306
    {
307
      config.debug.gdb_enabled = 0;
308
      config.debug.rsp_enabled = 0;
309
 
310
      if (config.sim.verbose)
311
        {
312
          fprintf (stderr, "WARNING: sim_init: Debug module not enabled, "
313
                   "cannot start remote service to GDB\n");
314
        }
315
    }
316
 
317
  /* Start either RSP or legacy GDB debugging service */
318
  if (config.debug.rsp_enabled)
319
    {
320
      rsp_init ();
321
 
322
      /* RSP always starts stalled as though we have just reset the
323
         processor. */
324
      rsp_exception (EXCEPT_TRAP);
325
      set_stall_state (1);
326
    }
327
  else if (config.debug.gdb_enabled)
328
    {
329
      gdbcomm_init ();
330
    }
331
 
332
  /* Enable dependency stats, if we want to do history analisis */
333
  if (config.sim.history && !config.cpu.dependstats)
334
    {
335
      config.cpu.dependstats = 1;
336
      if (config.sim.verbose)
337
        {
338
          fprintf (stderr, "WARNING: sim_init: dependstats stats must be "
339
                   "enabled to do history analysis\n");
340
        }
341
    }
342
 
343
  /* Debug forces verbose */
344
  if (config.sim.debug && !config.sim.verbose)
345
    {
346
      config.sim.verbose = 1;
347
      fprintf (stderr, "WARNING: sim_init: verbose forced on by debug\n");
348
    }
349
 
350
  /* Start VAPI before device initialization.  */
351
  if (config.vapi.enabled)
352
    {
353
      runtime.vapi.enabled = 1;
354
      vapi_init ();
355
      if (config.sim.verbose)
356
        {
357
          PRINTF ("VAPI started, waiting for clients\n");
358
        }
359
    }
360
 
361
  /* Wait till all test are connected.  */
362
  if (runtime.vapi.enabled)
363
    {
364
      int numu = vapi_num_unconnected (0);
365
      if (numu)
366
        {
367
          PRINTF ("\nWaiting for VAPI tests with ids:\n");
368
          vapi_num_unconnected (1);
369
          PRINTF ("\n");
370
          while ((numu = vapi_num_unconnected (0)))
371
            {
372
              vapi_check ();
373
              PRINTF
374
                ("\rStill waiting for %i VAPI test(s) to connect",
375
                 numu);
376
              usleep (100);
377
            }
378
          PRINTF ("\n");
379
        }
380
      PRINTF ("All devices connected\n");
381
    }
382
}       /* sim_init() */
383
 
384
 
385
/*---------------------------------------------------------------------------*/
386
/*!Clean up
387
 
388
   Close an profile or log files, disconnect VAPI. Call any memory mapped
389
   peripheral close down function. Exit with rc 0.                           */
390
/*---------------------------------------------------------------------------*/
391
void
392
sim_done ()
393
{
394
  if (config.sim.profile)
395
    {
396
      fprintf (runtime.sim.fprof, "-%08llX FFFFFFFF\n", runtime.sim.cycles);
397
      fclose (runtime.sim.fprof);
398
    }
399
 
400
  if (config.sim.mprofile)
401
    {
402
      fclose (runtime.sim.fmprof);
403
    }
404
 
405
  if (config.sim.exe_log)
406
    {
407
      fclose (runtime.sim.fexe_log);
408
    }
409
 
410 202 julius
  if (config.sim.exe_bin_insn_log)
411
    {
412
      fclose (runtime.sim.fexe_bin_insn_log);
413
    }
414
 
415 19 jeremybenn
  if (runtime.vapi.enabled)
416
    {
417
      vapi_done ();
418
    }
419
 
420
  done_memory_table ();
421
  mc_done ();
422
 
423
  exit (0);
424
 
425
}       /* sim_done() */

powered by: WebSVN 2.1.0

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