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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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