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