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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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