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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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