| 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 */ |