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 1751

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

powered by: WebSVN 2.1.0

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