【QEMU源码】TCG结构体
TCGCPUOps
static const struct TCGCPUOps riscv_tcg_ops = {
.initialize = riscv_translate_init,
.synchronize_from_tb = riscv_cpu_synchronize_from_tb,
.restore_state_to_opc = riscv_restore_state_to_opc,
#ifndef CONFIG_USER_ONLY
.tlb_fill = riscv_cpu_tlb_fill,
.cpu_exec_interrupt = riscv_cpu_exec_interrupt,
.do_interrupt = riscv_cpu_do_interrupt,
.do_transaction_failed = riscv_cpu_do_transaction_failed,
.do_unaligned_access = riscv_cpu_do_unaligned_access,
.debug_excp_handler = riscv_cpu_debug_excp_handler,
.debug_check_breakpoint = riscv_cpu_debug_check_breakpoint,
.debug_check_watchpoint = riscv_cpu_debug_check_watchpoint,
#endif /* !CONFIG_USER_ONLY */
};
struct TCGCPUOps {
void (*initialize)(void);
void (*synchronize_from_tb)(CPUState *cpu, const TranslationBlock *tb);
void (*restore_state_to_opc)(CPUState *cpu, const TranslationBlock *tb,
const uint64_t *data);
void (*cpu_exec_enter)(CPUState *cpu);
void (*cpu_exec_exit)(CPUState *cpu);
void (*debug_excp_handler)(CPUState *cpu);
#ifdef NEED_CPU_H
#if defined(CONFIG_USER_ONLY) && defined(TARGET_I386)
void (*fake_user_interrupt)(CPUState *cpu);
#else
void (*do_interrupt)(CPUState *cpu);
#endif /* !CONFIG_USER_ONLY || !TARGET_I386 */
#ifdef CONFIG_USER_ONLY
void (*record_sigsegv)(CPUState *cpu, vaddr addr,
MMUAccessType access_type,
bool maperr, uintptr_t ra);
void (*record_sigbus)(CPUState *cpu, vaddr addr,
MMUAccessType access_type, uintptr_t ra);
#else
bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
void (*do_transaction_failed)(CPUState *cpu, hwaddr physaddr, vaddr addr,
unsigned size, MMUAccessType access_type,
int mmu_idx, MemTxAttrs attrs,
MemTxResult response, uintptr_t retaddr);
G_NORETURN void (*do_unaligned_access)(CPUState *cpu, vaddr addr,
MMUAccessType access_type,
int mmu_idx, uintptr_t retaddr);
vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr, int len);
bool (*debug_check_watchpoint)(CPUState *cpu, CPUWatchpoint *wp);
bool (*debug_check_breakpoint)(CPUState *cpu);
bool (*io_recompile_replay_branch)(CPUState *cpu,
const TranslationBlock *tb);
#endif /* !CONFIG_USER_ONLY */
#endif /* NEED_CPU_H */
};
层次关系和调用流程
1. TCGCPUOps 调用 TranslatorOps
在架构实现中,TCGCPUOps 的 translate_code 函数会调用 translator_loop,并传入架构特定的 TranslatorOps
2. translator_loop 使用 TranslatorOps
通用的翻译循环 translator.c:122-176 会依次调用 TranslatorOps 中的回调函数来完成指令翻译。
3. cpu 执行中的 TCGCPUOps 使用
在 CPU 执行过程中,TCGCPUOps 的其他函数被广泛使用: cpu-exec.c:493-509