Understand Qemu TCG
- The whole executing process of QEMU
main() //vl.c
main_loop() //vl.c
x86_cpu_realizefn() //例項化虛擬機器CPU裝置模型
qemu_init_vcpu() //KVM沒有enable,並且啟用了TCG的情況下,tcg_enabled()
qemu_tcg_init_vcpu()//啟動VCPU執行緒,執行緒處理函式為qemu_tcg_cpu_thread_fn
qemu_tcg_cpu_thread_fn()
tcg_exec_all()
tcg_cpu_exec()
cpu_exec() //cpu-exee.c
tb = tb_find_fast(); // translate target code to host assemble language and host machine code.
next_tb = cpu_tb_exec()
next_tb = tcg_qemu_tb_exec(tc_ptr); // execute the code contained in translation block.
cpu_exec() 中執行如下:
next_tb = 0; /* force lookup of first TB */
for(;;) {
process interrupt request;
tb_find_fast();
tcg_qemu_tb_exec(tc_ptr);
}
tb_find_fast() {
get translation block from tb cache;
if not found
tb_find_slow();
}
tb_find_slow() {
get translation block from hash table;
if not found
tb_gen_code();//translate it now
}
//generate host code
tb_gen_code() // return a translated block
cpu_gen_code()
gen_intermediate_code(env, tb);
gen_intermediate_code_internal()
pc_ptr = disas_insn(dc, pc_ptr);
gen_code_size = tcg_gen_code(s, gen_code_buf); //generate machine code
tcg_gen_code_common(s, gen_code_buf, -1);
2. How do QEMU execute host instructions containing in translation block ?
2.1 There is a array defined in exec.c:
//uint8_t code_gen_prologue[1024] code_gen_section;(老版本) struct TCGContext { //…… uint8_t *code_ptr; /* Code generation */ uint8_t *code_gen_prologue; }; |
2.2 in function tcg_prologue_init() in tcg.c
/* init global prologue and epilogue */ |
then, {s->code_ptr) points to the address of code_gen_prologue.
2.3 function: tcg_target_qemu_prologue(), call tcg_out_push(), which fills value to *(s->code_ptr).
/* Generate global QEMU prologue and epilogue code */staticvoid tcg_target_qemu_prologue(TCGContext *s){int i, frame_size, push_size, stack_addend;/* TB prologue *//* Save all callee saved registers. */for(i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++){ |
2.4 After getting a translation block by calling tb_find_fast(), call tcg_qemu_tb_exec(tc_ptr), which is a macro defined as following:
# define tcg_qemu_tb_exec(env, tb_ptr) \ |
code_gen_prologue(tb_ptr) is casted to a function with two parameter, in such a way, execute host machine code stored in code_gen_prologue.
3. Distinction between user mode and system mode emulation of QEMU?
QEMU has two operating modes:
- Full system emulation. In this mode, QEMU emulates a full system (for example a PC), including one or several processors and various peripherals. It can be used to launch different Operating Systems without rebooting the PC or to debug system code.
- User mode emulation. In this mode, QEMU can launch processes compiled for one CPU on another CPU. It can be used to launch the Wine Windows API emulator (http://www.winehq.org) or to ease cross-compilation and cross-debugging.
4. One macro glue
#define xglue(x, y) x ## y |
#define SUFFIX _mmx void glue(helper_pcmpistrm, SUFFIX)(Reg *d, Reg *s,uint32_t ctrl) |
First, this function is expanded to :(glue(x, y) -> xglue(x, y))
xglue(helper_pcmpistrm,_mmx)(Reg *d, Reg *s,uint32_t ctrl) |
Second, ( xglue(x, y) -> x ## y )
helper_pcmpistrm_mmx(Reg *d, Reg *s,uint32_t ctrl) |
So,
void glue(helper_pcmpistrm, SUFFIX)(Reg *d, Reg *s,uint32_t ctrl) == helper_pcmpistrm_mmx(Reg *d, Reg *s,uint32_t ctrl) |
5. How do the qemu translate virtual address to physical address when load a instruction ?
phys_pc = get_page_addr_code(env, pc); |
/* NOTE: this function can trigger an exception *//* NOTE2: the returned address is not exactly the physical address: it is the offset relative to phys_ram_base */staticinline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr){int mmu_idx, page_index, pd;void*p; |
5. TCG .vs. Dyngen
6. Helper function
http://www.greensocs.com/Projects/QEMUSystemC/docs/QEMUSystemC/QEMUSystemCDataflow
7. Memory simulation in QEMU
http://www.slideshare.net/zchen/memory-simulation-in-qemu
8. For system simulation.
b = ldub_code(s->pc); |
will call this function(in softmmu_header.h):
glue is a marico, after replacing, it is :
static inline RES_TYPE ld_{USUFFIX}_{MEMSUFFIX}(target_ulong ptr);
staticinline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr){int page_index; |
9. QEMU device model