1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
/* Generic simulator halt/resume.
Copyright (C) 1997-2021 Free Software Foundation, Inc.
Contributed by Cygnus Support.
This file is part of GDB, the GNU debugger.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef SIM_ENGINE_H
#define SIM_ENGINE_H
typedef struct _sim_engine sim_engine;
struct _sim_engine
{
void *jmpbuf;
sim_cpu *last_cpu;
sim_cpu *next_cpu;
int nr_cpus;
enum sim_stop reason;
sim_event *stepper;
int sigrc;
};
/* jmpval: 0 (initial use) start simulator
1 halt simulator
2 restart simulator
This is required by the ISO C standard (the only time 0 is returned
is at the initial call to setjmp). */
enum {
sim_engine_start_jmpval,
sim_engine_halt_jmpval,
sim_engine_restart_jmpval,
};
/* Get/set the run state of CPU to REASON/SIGRC.
REASON/SIGRC are the values returned by sim_stop_reason. */
void sim_engine_get_run_state (SIM_DESC sd, enum sim_stop *reason, int *sigrc);
void sim_engine_set_run_state (SIM_DESC sd, enum sim_stop reason, int sigrc);
/* Halt the simulator *now* */
extern void sim_engine_halt
(SIM_DESC sd,
sim_cpu *last_cpu, /* NULL -> in event-mgr */
sim_cpu *next_cpu, /* NULL -> succ (last_cpu) or event-mgr */
sim_cia cia,
enum sim_stop reason,
int sigrc) ATTRIBUTE_NORETURN;
/* Halt hook - allow target specific operation when halting a
simulator */
#if !defined (SIM_ENGINE_HALT_HOOK)
#define SIM_ENGINE_HALT_HOOK(SD, LAST_CPU, CIA) \
if ((LAST_CPU) != NULL) CPU_PC_SET (LAST_CPU, CIA)
#endif
/* NB: If a port uses the SIM_CPU_EXCEPTION_* hooks, the default
SIM_ENGINE_HALT_HOOK and SIM_ENGINE_RESUME_HOOK must not be used.
They conflict in that the PC set by the HALT_HOOK may overwrite the
proper one, as intended to be saved by the EXCEPTION_TRIGGER
hook. */
/* restart the simulator *now* */
extern void sim_engine_restart
(SIM_DESC sd,
sim_cpu *last_cpu, /* NULL -> in event-mgr */
sim_cpu *next_cpu, /* NULL -> succ (last_cpu) or event-mgr */
sim_cia cia);
/* Restart hook - allow target specific operation when restarting a
simulator */
#if !defined (SIM_ENGINE_RESTART_HOOK)
#define SIM_ENGINE_RESTART_HOOK(SD, LAST_CPU, CIA) SIM_ENGINE_HALT_HOOK(SD, LAST_CPU, CIA)
#endif
/* Abort the simulator *now*.
This function is NULL safe. It can be called when either of SD or
CIA are NULL.
This function is setjmp/longjmp safe. It can be called when of
the sim_engine setjmp/longjmp buffer has not been established.
Simulators that are using components such as sim-core but are not
yet using this sim-engine module should link in file sim-abort.o
which implements a non setjmp/longjmp version of
sim_engine_abort. */
extern void sim_engine_abort
(SIM_DESC sd,
sim_cpu *cpu,
sim_cia cia,
const char *fmt,
...) ATTRIBUTE_PRINTF (4, 5) ATTRIBUTE_NORETURN;
extern void sim_engine_vabort
(SIM_DESC sd,
sim_cpu *cpu,
sim_cia cia,
const char *fmt,
va_list ap) ATTRIBUTE_PRINTF (4, 0) ATTRIBUTE_NORETURN;
/* No abort hook - when possible this function exits using the
engine_halt function (and SIM_ENGINE_HALT_HOOK). */
/* Called by the generic sim_resume to run the simulation within the
above safty net.
An example implementation of sim_engine_run can be found in the
file sim-run.c */
extern void sim_engine_run
(SIM_DESC sd,
int next_cpu_nr,
int nr_cpus,
int siggnal); /* most simulators ignore siggnal */
/* Determine the state of next/last cpu when the simulator was last
halted - a value >= MAX_NR_PROCESSORS indicates that the
event-queue was next/last. */
extern int sim_engine_next_cpu_nr (SIM_DESC sd);
extern int sim_engine_last_cpu_nr (SIM_DESC sd);
extern int sim_engine_nr_cpus (SIM_DESC sd);
#endif
|