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

Subversion Repositories openrisc

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

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
  printf ("Or1ksim " PACKAGE_VERSION "\n" );
225
  init_labels ();
226
  init_breakpoints ();
227
  initstats ();
228
  build_automata ();
229
 
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
  /* MM170901 always load at address zero */
279
  if (runtime.sim.filename)
280
    {
281
      unsigned long endaddr = loadcode (runtime.sim.filename, 0, 0);
282
 
283
      if (endaddr == -1)
284
        {
285
          fprintf (stderr, "ERROR: sim_init: problem loading code from %s\n",
286
                   runtime.sim.filename);
287
          exit (1);
288
        }
289
    }
290
 
291
  /* Disable GDB debugging, if debug unit is not available.  */
292
  if ((config.debug.gdb_enabled || config.debug.rsp_enabled) &&
293
      !config.debug.enabled)
294
    {
295
      config.debug.gdb_enabled = 0;
296
      config.debug.rsp_enabled = 0;
297
 
298
      if (config.sim.verbose)
299
        {
300
          fprintf (stderr, "WARNING: sim_init: Debug module not enabled, "
301
                   "cannot start remote service to GDB\n");
302
        }
303
    }
304
 
305
  /* Start either RSP or legacy GDB debugging service */
306
  if (config.debug.rsp_enabled)
307
    {
308
      rsp_init ();
309
 
310
      /* RSP always starts stalled as though we have just reset the
311
         processor. */
312
      rsp_exception (EXCEPT_TRAP);
313
      set_stall_state (1);
314
    }
315
  else if (config.debug.gdb_enabled)
316
    {
317
      gdbcomm_init ();
318
    }
319
 
320
  /* Enable dependency stats, if we want to do history analisis */
321
  if (config.sim.history && !config.cpu.dependstats)
322
    {
323
      config.cpu.dependstats = 1;
324
      if (config.sim.verbose)
325
        {
326
          fprintf (stderr, "WARNING: sim_init: dependstats stats must be "
327
                   "enabled to do history analysis\n");
328
        }
329
    }
330
 
331
  /* Debug forces verbose */
332
  if (config.sim.debug && !config.sim.verbose)
333
    {
334
      config.sim.verbose = 1;
335
      fprintf (stderr, "WARNING: sim_init: verbose forced on by debug\n");
336
    }
337
 
338
  /* Start VAPI before device initialization.  */
339
  if (config.vapi.enabled)
340
    {
341
      runtime.vapi.enabled = 1;
342
      vapi_init ();
343
      if (config.sim.verbose)
344
        {
345
          PRINTF ("VAPI started, waiting for clients\n");
346
        }
347
    }
348
 
349
  /* Wait till all test are connected.  */
350
  if (runtime.vapi.enabled)
351
    {
352
      int numu = vapi_num_unconnected (0);
353
      if (numu)
354
        {
355
          PRINTF ("\nWaiting for VAPI tests with ids:\n");
356
          vapi_num_unconnected (1);
357
          PRINTF ("\n");
358
          while ((numu = vapi_num_unconnected (0)))
359
            {
360
              vapi_check ();
361
              PRINTF
362
                ("\rStill waiting for %i VAPI test(s) to connect",
363
                 numu);
364
              usleep (100);
365
            }
366
          PRINTF ("\n");
367
        }
368
      PRINTF ("All devices connected\n");
369
    }
370
}       /* sim_init() */
371
 
372
 
373
/*---------------------------------------------------------------------------*/
374
/*!Clean up
375
 
376
   Close an profile or log files, disconnect VAPI. Call any memory mapped
377
   peripheral close down function. Exit with rc 0.                           */
378
/*---------------------------------------------------------------------------*/
379
void
380
sim_done ()
381
{
382
  if (config.sim.profile)
383
    {
384
      fprintf (runtime.sim.fprof, "-%08llX FFFFFFFF\n", runtime.sim.cycles);
385
      fclose (runtime.sim.fprof);
386
    }
387
 
388
  if (config.sim.mprofile)
389
    {
390
      fclose (runtime.sim.fmprof);
391
    }
392
 
393
  if (config.sim.exe_log)
394
    {
395
      fclose (runtime.sim.fexe_log);
396
    }
397
 
398
  if (runtime.vapi.enabled)
399
    {
400
      vapi_done ();
401
    }
402
 
403
  done_memory_table ();
404
  mc_done ();
405
 
406
  exit (0);
407
 
408
}       /* sim_done() */

powered by: WebSVN 2.1.0

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