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