1 |
227 |
jeremybenn |
/* Main header for the CRIS simulator, based on the m32r header.
|
2 |
|
|
Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
3 |
|
|
Free Software Foundation, Inc.
|
4 |
|
|
Contributed by Axis Communications.
|
5 |
|
|
|
6 |
|
|
This file is part of the GNU simulators.
|
7 |
|
|
|
8 |
|
|
This program is free software; you can redistribute it and/or modify
|
9 |
|
|
it under the terms of the GNU General Public License as published by
|
10 |
|
|
the Free Software Foundation; either version 3 of the License, or
|
11 |
|
|
(at your option) any later version.
|
12 |
|
|
|
13 |
|
|
This program is distributed in the hope that it will be useful,
|
14 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16 |
|
|
GNU General Public License for more details.
|
17 |
|
|
|
18 |
|
|
You should have received a copy of the GNU General Public License
|
19 |
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
20 |
|
|
|
21 |
|
|
/* All FIXME:s present in m32r apply here too; I just refuse to blindly
|
22 |
|
|
carry them over, as I don't know if they're really things that need
|
23 |
|
|
fixing. */
|
24 |
|
|
|
25 |
|
|
#ifndef SIM_MAIN_H
|
26 |
|
|
#define SIM_MAIN_H
|
27 |
|
|
|
28 |
|
|
#define USING_SIM_BASE_H
|
29 |
|
|
|
30 |
|
|
struct _sim_cpu;
|
31 |
|
|
typedef struct _sim_cpu SIM_CPU;
|
32 |
|
|
|
33 |
|
|
#include "symcat.h"
|
34 |
|
|
#include "sim-basics.h"
|
35 |
|
|
#include "cgen-types.h"
|
36 |
|
|
#include "cris-desc.h"
|
37 |
|
|
#include "cris-opc.h"
|
38 |
|
|
#include "arch.h"
|
39 |
|
|
|
40 |
|
|
/* These must be defined before sim-base.h. */
|
41 |
|
|
typedef USI sim_cia;
|
42 |
|
|
|
43 |
|
|
#define CIA_GET(cpu) CPU_PC_GET (cpu)
|
44 |
|
|
#define CIA_SET(cpu,val) CPU_PC_SET ((cpu), (val))
|
45 |
|
|
|
46 |
|
|
#define SIM_ENGINE_HALT_HOOK(sd, cpu, cia) \
|
47 |
|
|
do { \
|
48 |
|
|
if (cpu) /* Null if ctrl-c. */ \
|
49 |
|
|
sim_pc_set ((cpu), (cia)); \
|
50 |
|
|
} while (0)
|
51 |
|
|
#define SIM_ENGINE_RESTART_HOOK(sd, cpu, cia) \
|
52 |
|
|
do { \
|
53 |
|
|
sim_pc_set ((cpu), (cia)); \
|
54 |
|
|
} while (0)
|
55 |
|
|
|
56 |
|
|
#include "sim-base.h"
|
57 |
|
|
#include "cgen-sim.h"
|
58 |
|
|
#include "cris-sim.h"
|
59 |
|
|
|
60 |
|
|
struct cris_sim_mmapped_page {
|
61 |
|
|
USI addr;
|
62 |
|
|
struct cris_sim_mmapped_page *prev;
|
63 |
|
|
};
|
64 |
|
|
|
65 |
|
|
struct cris_thread_info {
|
66 |
|
|
/* Identifier for this thread. */
|
67 |
|
|
unsigned int threadid;
|
68 |
|
|
|
69 |
|
|
/* Identifier for parent thread. */
|
70 |
|
|
unsigned int parent_threadid;
|
71 |
|
|
|
72 |
|
|
/* Signal to send to parent at exit. */
|
73 |
|
|
int exitsig;
|
74 |
|
|
|
75 |
|
|
/* Exit status. */
|
76 |
|
|
int exitval;
|
77 |
|
|
|
78 |
|
|
/* Only as storage to return the "set" value to the "get" method.
|
79 |
|
|
I'm not sure whether this is useful per-thread. */
|
80 |
|
|
USI priority;
|
81 |
|
|
|
82 |
|
|
struct
|
83 |
|
|
{
|
84 |
|
|
USI altstack;
|
85 |
|
|
USI options;
|
86 |
|
|
|
87 |
|
|
char action;
|
88 |
|
|
char pending;
|
89 |
|
|
char blocked;
|
90 |
|
|
char blocked_suspendsave;
|
91 |
|
|
/* The handler stub unblocks the signal, so we don't need a separate
|
92 |
|
|
"temporary save" for that. */
|
93 |
|
|
} sigdata[64];
|
94 |
|
|
|
95 |
|
|
/* Register context, swapped with _sim_cpu.cpu_data. */
|
96 |
|
|
void *cpu_context;
|
97 |
|
|
|
98 |
|
|
/* Similar, temporary copy for the state at a signal call. */
|
99 |
|
|
void *cpu_context_atsignal;
|
100 |
|
|
|
101 |
|
|
/* The number of the reading and writing ends of a pipe if waiting for
|
102 |
|
|
the reader, else 0. */
|
103 |
|
|
int pipe_read_fd;
|
104 |
|
|
int pipe_write_fd;
|
105 |
|
|
|
106 |
|
|
/* System time at last context switch when this thread ran. */
|
107 |
|
|
USI last_execution;
|
108 |
|
|
|
109 |
|
|
/* Nonzero if we just executed a syscall. */
|
110 |
|
|
char at_syscall;
|
111 |
|
|
|
112 |
|
|
/* Nonzero if any of sigaction[0..64].pending is true. */
|
113 |
|
|
char sigpending;
|
114 |
|
|
|
115 |
|
|
/* Nonzero if in (rt_)sigsuspend call. Cleared at every sighandler
|
116 |
|
|
call. */
|
117 |
|
|
char sigsuspended;
|
118 |
|
|
};
|
119 |
|
|
|
120 |
|
|
typedef int (*cris_interrupt_delivery_fn) (SIM_CPU *,
|
121 |
|
|
enum cris_interrupt_type,
|
122 |
|
|
unsigned int);
|
123 |
|
|
|
124 |
|
|
struct _sim_cpu {
|
125 |
|
|
/* sim/common cpu base. */
|
126 |
|
|
sim_cpu_base base;
|
127 |
|
|
|
128 |
|
|
/* Static parts of cgen. */
|
129 |
|
|
CGEN_CPU cgen_cpu;
|
130 |
|
|
|
131 |
|
|
CRIS_MISC_PROFILE cris_misc_profile;
|
132 |
|
|
#define CPU_CRIS_MISC_PROFILE(cpu) (& (cpu)->cris_misc_profile)
|
133 |
|
|
|
134 |
|
|
/* Copy of previous data; only valid when emitting trace-data after
|
135 |
|
|
each insn. */
|
136 |
|
|
CRIS_MISC_PROFILE cris_prev_misc_profile;
|
137 |
|
|
#define CPU_CRIS_PREV_MISC_PROFILE(cpu) (& (cpu)->cris_prev_misc_profile)
|
138 |
|
|
|
139 |
|
|
#if WITH_HW
|
140 |
|
|
cris_interrupt_delivery_fn deliver_interrupt;
|
141 |
|
|
#define CPU_CRIS_DELIVER_INTERRUPT(cpu) (cpu->deliver_interrupt)
|
142 |
|
|
#endif
|
143 |
|
|
|
144 |
|
|
/* Simulator environment data. */
|
145 |
|
|
USI endmem;
|
146 |
|
|
USI endbrk;
|
147 |
|
|
USI stack_low;
|
148 |
|
|
struct cris_sim_mmapped_page *highest_mmapped_page;
|
149 |
|
|
|
150 |
|
|
/* Number of syscalls performed or in progress, counting once extra
|
151 |
|
|
for every time a blocked thread (internally, when threading) polls
|
152 |
|
|
the (pipe) blockage. By default, this is also a time counter: to
|
153 |
|
|
minimize performance noise from minor compiler changes,
|
154 |
|
|
instructions take no time and syscalls always take 1ms. */
|
155 |
|
|
USI syscalls;
|
156 |
|
|
|
157 |
|
|
/* Number of execution contexts minus one. */
|
158 |
|
|
int m1threads;
|
159 |
|
|
|
160 |
|
|
/* Current thread number; index into thread_data when m1threads != 0. */
|
161 |
|
|
int threadno;
|
162 |
|
|
|
163 |
|
|
/* When a new thread is created, it gets a unique number, which we
|
164 |
|
|
count here. */
|
165 |
|
|
int max_threadid;
|
166 |
|
|
|
167 |
|
|
/* Thread-specific info, for simulator thread support, created at
|
168 |
|
|
"clone" call. Vector of [threads+1] when m1threads > 0. */
|
169 |
|
|
struct cris_thread_info *thread_data;
|
170 |
|
|
|
171 |
|
|
/* "If CLONE_SIGHAND is set, the calling process and the child pro-
|
172 |
|
|
cesses share the same table of signal handlers." ... "However, the
|
173 |
|
|
calling process and child processes still have distinct signal
|
174 |
|
|
masks and sets of pending signals." See struct cris_thread_info
|
175 |
|
|
for sigmasks and sigpendings. */
|
176 |
|
|
USI sighandler[64];
|
177 |
|
|
|
178 |
|
|
/* This is a hack to implement just the parts of fcntl F_GETFL that
|
179 |
|
|
are used in open+fdopen calls for the standard scenario: for such
|
180 |
|
|
a call we check that the last syscall was open, we check that the
|
181 |
|
|
passed fd is the same returned then, and so we return the same
|
182 |
|
|
flags passed to open. This way, we avoid complicating the
|
183 |
|
|
generic sim callback machinery by introducing fcntl
|
184 |
|
|
mechanisms. */
|
185 |
|
|
USI last_syscall;
|
186 |
|
|
USI last_open_fd;
|
187 |
|
|
USI last_open_flags;
|
188 |
|
|
|
189 |
|
|
/* Function for initializing CPU thread context, which varies in size
|
190 |
|
|
with each CPU model. They should be in some constant parts or
|
191 |
|
|
initialized in *_init_cpu, but we can't modify that for now. */
|
192 |
|
|
void* (*make_thread_cpu_data) (SIM_CPU *, void *);
|
193 |
|
|
size_t thread_cpu_data_size;
|
194 |
|
|
|
195 |
|
|
/* The register differs, so we dispatch to a CPU-specific function. */
|
196 |
|
|
void (*set_target_thread_data) (SIM_CPU *, USI);
|
197 |
|
|
|
198 |
|
|
/* CPU-model specific parts go here.
|
199 |
|
|
Note that in files that don't need to access these pieces WANT_CPU_FOO
|
200 |
|
|
won't be defined and thus these parts won't appear. This is ok in the
|
201 |
|
|
sense that things work. It is a source of bugs though.
|
202 |
|
|
One has to of course be careful to not take the size of this
|
203 |
|
|
struct and no structure members accessed in non-cpu specific files can
|
204 |
|
|
go after here. */
|
205 |
|
|
#if defined (WANT_CPU_CRISV0F)
|
206 |
|
|
CRISV0F_CPU_DATA cpu_data;
|
207 |
|
|
#elif defined (WANT_CPU_CRISV3F)
|
208 |
|
|
CRISV3F_CPU_DATA cpu_data;
|
209 |
|
|
#elif defined (WANT_CPU_CRISV8F)
|
210 |
|
|
CRISV8F_CPU_DATA cpu_data;
|
211 |
|
|
#elif defined (WANT_CPU_CRISV10F)
|
212 |
|
|
CRISV10F_CPU_DATA cpu_data;
|
213 |
|
|
#elif defined (WANT_CPU_CRISV32F)
|
214 |
|
|
CRISV32F_CPU_DATA cpu_data;
|
215 |
|
|
#else
|
216 |
|
|
/* Let's assume all cpu_data have the same alignment requirements, so
|
217 |
|
|
they all are laid out at the same address. Since we can't get the
|
218 |
|
|
exact definition, we also assume that it has no higher alignment
|
219 |
|
|
requirements than a vector of, say, 16 pointers. (A single member
|
220 |
|
|
is often special-cased, and possibly two as well so we don't want
|
221 |
|
|
that). */
|
222 |
|
|
union { void *dummy[16]; } cpu_data_placeholder;
|
223 |
|
|
#endif
|
224 |
|
|
};
|
225 |
|
|
|
226 |
|
|
/* The sim_state struct. */
|
227 |
|
|
|
228 |
|
|
struct sim_state {
|
229 |
|
|
sim_cpu *cpu;
|
230 |
|
|
#define STATE_CPU(sd, n) (/*&*/ (sd)->cpu)
|
231 |
|
|
|
232 |
|
|
CGEN_STATE cgen_state;
|
233 |
|
|
|
234 |
|
|
sim_state_base base;
|
235 |
|
|
};
|
236 |
|
|
|
237 |
|
|
/* Misc. */
|
238 |
|
|
|
239 |
|
|
/* Catch address exceptions. */
|
240 |
|
|
extern SIM_CORE_SIGNAL_FN cris_core_signal;
|
241 |
|
|
#define SIM_CORE_SIGNAL(SD,CPU,CIA,MAP,NR_BYTES,ADDR,TRANSFER,ERROR) \
|
242 |
|
|
cris_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), \
|
243 |
|
|
(TRANSFER), (ERROR))
|
244 |
|
|
|
245 |
|
|
/* Default memory size. */
|
246 |
|
|
#define CRIS_DEFAULT_MEM_SIZE 0x800000 /* 8M */
|
247 |
|
|
|
248 |
|
|
extern device cris_devices;
|
249 |
|
|
|
250 |
|
|
#endif /* SIM_MAIN_H */
|