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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [or1ksim/] [toplevel-support.c] - Blame information for rev 1748

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

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

powered by: WebSVN 2.1.0

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