master
h 319 lines 12 KB
Raw
1 /*
2 * TCG CPU-specific operations
3 *
4 * Copyright 2021 SUSE LLC
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
7 * See the COPYING file in the top-level directory.
8 */
9
10 #ifndef TCG_CPU_OPS_H
11 #define TCG_CPU_OPS_H
12
13 #ifndef CONFIG_TCG
14 #error Can only include this header with TCG
15 #endif
16
17 #include "exec/breakpoint.h"
18 #include "exec/hwaddr.h"
19 #include "exec/memattrs.h"
20 #include "exec/memop.h"
21 #include "exec/mmu-access-type.h"
22 #include "exec/vaddr.h"
23 #include "accel/tcg/tb-cpu-state.h"
24 #include "tcg/tcg-mo.h"
25
26 struct TCGCPUOps {
27 /**
28 * mttcg_supported: multi-threaded TCG is supported
29 *
30 * Target (TCG frontend) supports:
31 * - atomic instructions
32 * - memory ordering primitives (barriers)
33 */
34 bool mttcg_supported;
35
36 /**
37 * @precise_smc: Stores which modify code within the current TB force
38 * the TB to exit; the next executed instruction will see
39 * the result of the store.
40 */
41 bool precise_smc;
42
43 /**
44 * @guest_default_memory_order: default barrier that is required
45 * for the guest memory ordering.
46 */
47 TCGBar guest_default_memory_order;
48
49 /**
50 * @initialize: Initialize TCG state
51 *
52 * Called when the first CPU is realized.
53 */
54 void (*initialize)(void);
55 /**
56 * @translate_code: Translate guest instructions to TCGOps
57 * @cpu: cpu context
58 * @tb: translation block
59 * @max_insns: max number of instructions to translate
60 * @pc: guest virtual program counter address
61 * @host_pc: host physical program counter address
62 *
63 * This function must be provided by the target, which should create
64 * the target-specific DisasContext, and then invoke translator_loop.
65 */
66 void (*translate_code)(CPUState *cpu, TranslationBlock *tb,
67 int *max_insns, vaddr pc, void *host_pc);
68 /**
69 * @get_tb_cpu_state: Extract CPU state for a TCG #TranslationBlock
70 *
71 * Fill in all data required to select or compile a TranslationBlock.
72 */
73 TCGTBCPUState (*get_tb_cpu_state)(CPUState *cs);
74 /**
75 * @synchronize_from_tb: Synchronize state from a TCG #TranslationBlock
76 *
77 * This is called when we abandon execution of a TB before starting it,
78 * and must set all parts of the CPU state which the previous TB in the
79 * chain may not have updated.
80 * By default, when this is NULL, a call is made to @set_pc(tb->pc).
81 *
82 * If more state needs to be restored, the target must implement a
83 * function to restore all the state, and register it here.
84 */
85 void (*synchronize_from_tb)(CPUState *cpu, const TranslationBlock *tb);
86 /**
87 * @restore_state_to_opc: Synchronize state from INDEX_op_start_insn
88 *
89 * This is called when we unwind state in the middle of a TB,
90 * usually before raising an exception. Set all part of the CPU
91 * state which are tracked insn-by-insn in the target-specific
92 * arguments to start_insn, passed as @data.
93 */
94 void (*restore_state_to_opc)(CPUState *cpu, const TranslationBlock *tb,
95 const uint64_t *data);
96
97 /** @cpu_exec_enter: Callback for cpu_exec preparation */
98 void (*cpu_exec_enter)(CPUState *cpu);
99 /** @cpu_exec_exit: Callback for cpu_exec cleanup */
100 void (*cpu_exec_exit)(CPUState *cpu);
101 /** @debug_excp_handler: Callback for handling debug exceptions */
102 void (*debug_excp_handler)(CPUState *cpu);
103
104 /** @mmu_index: Callback for choosing softmmu mmu index */
105 int (*mmu_index)(CPUState *cpu, bool ifetch);
106
107 #ifdef CONFIG_USER_ONLY
108 /**
109 * @fake_user_interrupt: Callback for 'fake exception' handling.
110 *
111 * Simulate 'fake exception' which will be handled outside the
112 * cpu execution loop (hack for x86 user mode).
113 */
114 void (*fake_user_interrupt)(CPUState *cpu);
115
116 /**
117 * record_sigsegv:
118 * @cpu: cpu context
119 * @addr: faulting guest address
120 * @access_type: access was read/write/execute
121 * @maperr: true for invalid page, false for permission fault
122 * @ra: host pc for unwinding
123 *
124 * We are about to raise SIGSEGV with si_code set for @maperr,
125 * and si_addr set for @addr. Record anything further needed
126 * for the signal ucontext_t.
127 *
128 * If the emulated kernel does not provide anything to the signal
129 * handler with anything besides the user context registers, and
130 * the siginfo_t, then this hook need do nothing and may be omitted.
131 * Otherwise, record the data and return; the caller will raise
132 * the signal, unwind the cpu state, and return to the main loop.
133 *
134 * If it is simpler to re-use the sysemu tlb_fill code, @ra is provided
135 * so that a "normal" cpu exception can be raised. In this case,
136 * the signal must be raised by the architecture cpu_loop.
137 */
138 void (*record_sigsegv)(CPUState *cpu, vaddr addr,
139 MMUAccessType access_type,
140 bool maperr, uintptr_t ra);
141 /**
142 * record_sigbus:
143 * @cpu: cpu context
144 * @addr: misaligned guest address
145 * @access_type: access was read/write/execute
146 * @ra: host pc for unwinding
147 *
148 * We are about to raise SIGBUS with si_code BUS_ADRALN,
149 * and si_addr set for @addr. Record anything further needed
150 * for the signal ucontext_t.
151 *
152 * If the emulated kernel does not provide the signal handler with
153 * anything besides the user context registers, and the siginfo_t,
154 * then this hook need do nothing and may be omitted.
155 * Otherwise, record the data and return; the caller will raise
156 * the signal, unwind the cpu state, and return to the main loop.
157 *
158 * If it is simpler to re-use the sysemu do_unaligned_access code,
159 * @ra is provided so that a "normal" cpu exception can be raised.
160 * In this case, the signal must be raised by the architecture cpu_loop.
161 */
162 void (*record_sigbus)(CPUState *cpu, vaddr addr,
163 MMUAccessType access_type, uintptr_t ra);
164
165 /**
166 * untagged_addr: Remove an ignored tag from an address
167 * @cpu: cpu context
168 * @addr: tagged guest address
169 */
170 vaddr (*untagged_addr)(CPUState *cs, vaddr addr);
171 #else
172 /** @do_interrupt: Callback for interrupt handling. */
173 void (*do_interrupt)(CPUState *cpu);
174 /** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */
175 bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
176 /** @cpu_exec_reset: Callback for reset in cpu_exec. */
177 void (*cpu_exec_reset)(CPUState *cpu);
178 /**
179 * @cpu_exec_halt: Callback for handling halt in cpu_exec.
180 *
181 * The target CPU should do any special processing here that it needs
182 * to do when the CPU is in the halted state.
183 *
184 * Return true to indicate that the CPU should now leave halt, false
185 * if it should remain in the halted state. (This should generally
186 * be the same value that cpu_has_work() would return.)
187 *
188 * This method must be provided. If the target does not need to
189 * do anything special for halt, the same function used for its
190 * SysemuCPUOps::has_work method can be used here, as they have the
191 * same function signature.
192 */
193 bool (*cpu_exec_halt)(CPUState *cpu);
194 /**
195 * @tlb_fill_align: Handle a softmmu tlb miss
196 * @cpu: cpu context
197 * @out: output page properties
198 * @addr: virtual address
199 * @access_type: read, write or execute
200 * @mmu_idx: mmu context
201 * @memop: memory operation for the access
202 * @size: memory access size, or 0 for whole page
203 * @probe: test only, no fault
204 * @ra: host return address for exception unwind
205 *
206 * If the access is valid, fill in @out and return true.
207 * Otherwise if probe is true, return false.
208 * Otherwise raise an exception and do not return.
209 *
210 * The alignment check for the access is deferred to this hook,
211 * so that the target can determine the priority of any alignment
212 * fault with respect to other potential faults from paging.
213 * Zero may be passed for @memop to skip any alignment check
214 * for non-memory-access operations such as probing.
215 */
216 bool (*tlb_fill_align)(CPUState *cpu, CPUTLBEntryFull *out, vaddr addr,
217 MMUAccessType access_type, int mmu_idx,
218 MemOp memop, int size, bool probe, uintptr_t ra);
219 /**
220 * @tlb_fill: Handle a softmmu tlb miss
221 *
222 * If the access is valid, call tlb_set_page and return true;
223 * if the access is invalid and probe is true, return false;
224 * otherwise raise an exception and do not return.
225 */
226 bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
227 MMUAccessType access_type, int mmu_idx,
228 bool probe, uintptr_t retaddr);
229 /**
230 * @pointer_wrap:
231 *
232 * We have incremented @base to @result, resulting in a page change.
233 * For the current cpu state, adjust @result for possible overflow.
234 */
235 vaddr (*pointer_wrap)(CPUState *cpu, int mmu_idx, vaddr result, vaddr base);
236 /**
237 * @do_transaction_failed: Callback for handling failed memory transactions
238 * (ie bus faults or external aborts; not MMU faults)
239 */
240 void (*do_transaction_failed)(CPUState *cpu, hwaddr physaddr, vaddr addr,
241 unsigned size, MMUAccessType access_type,
242 int mmu_idx, MemTxAttrs attrs,
243 MemTxResult response, uintptr_t retaddr);
244 /**
245 * @do_unaligned_access: Callback for unaligned access handling
246 * The callback must exit via raising an exception.
247 */
248 G_NORETURN void (*do_unaligned_access)(CPUState *cpu, vaddr addr,
249 MMUAccessType access_type,
250 int mmu_idx, uintptr_t retaddr);
251
252 /**
253 * @adjust_watchpoint_address: hack for cpu_check_watchpoint (used by ARM)
254 */
255 vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr, int len);
256
257 /**
258 * @debug_check_watchpoint: return true if the architectural
259 * watchpoint whose address has matched should really fire.
260 */
261 bool (*debug_check_watchpoint)(CPUState *cpu, CPUWatchpoint *wp);
262
263 /**
264 * @debug_check_breakpoint: return true if the architectural
265 * breakpoint whose PC has matched should really fire.
266 */
267 bool (*debug_check_breakpoint)(CPUState *cpu);
268
269 /**
270 * @io_recompile_replay_branch: Callback for cpu_io_recompile.
271 *
272 * The cpu has been stopped, and cpu_restore_state_from_tb has been
273 * called. If the faulting instruction is in a delay slot, and the
274 * target architecture requires re-execution of the branch, then
275 * adjust the cpu state as required and return true.
276 */
277 bool (*io_recompile_replay_branch)(CPUState *cpu,
278 const TranslationBlock *tb);
279 /**
280 * @need_replay_interrupt: Return %true if @interrupt_request
281 * needs to be recorded for replay purposes.
282 */
283 bool (*need_replay_interrupt)(int interrupt_request);
284 #endif /* !CONFIG_USER_ONLY */
285 };
286
287 /**
288 * cpu_check_watchpoint:
289 * @cpu: cpu context
290 * @addr: guest virtual address
291 * @len: access length
292 * @attrs: memory access attributes
293 * @flags: watchpoint access type
294 * @ra: unwind return address
295 *
296 * Check for a watchpoint hit in [addr, addr+len) of the type
297 * specified by @flags. Exit via exception with a hit.
298 */
299 void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
300 MemTxAttrs attrs, int flags, uintptr_t ra);
301
302 /**
303 * cpu_watchpoint_address_matches:
304 * @cpu: cpu context
305 * @addr: guest virtual address
306 * @len: access length
307 *
308 * Return the watchpoint flags that apply to [addr, addr+len).
309 * If no watchpoint is registered for the range, the result is 0.
310 */
311 int cpu_watchpoint_address_matches(CPUState *cpu, vaddr addr, vaddr len);
312
313 /*
314 * Common pointer_wrap implementations.
315 */
316 vaddr cpu_pointer_wrap_notreached(CPUState *, int, vaddr, vaddr);
317 vaddr cpu_pointer_wrap_uint32(CPUState *, int, vaddr, vaddr);
318
319 #endif /* TCG_CPU_OPS_H */