分类: LINUX
2010-09-08 15:44:49
Main loop qemu
cpu_exec()
{
for(;;) {
if (setjmp(env->jmp_env) == 0) {
exception handling(2) if requested through the loop break;
for (;;) {
exception handling(1) ARM FIQ case
//PCto find the code corresponding to the converted. Without conversion
tb = tb_find_fast();
//Execute the code converted
next_tb = tcg_qemu_tb_exec(tb->tc_ptr);
}
} else {
Longjmpto the top of the loop through here then
}
}
}
JIT code conversion part is easy to think and understand the instruction cache. If it’s running a cache hit, if you don’t miss cache fill.
main (vl.c)
main_loop (vl.c)
tcg_cpu_exec (vl.c)
qemu_cpu_exec (vl.c)
cpu_exec (cpu_exec.c)
tcg_cpu_exec to simulate a loop in the multi-core. Separate the execution time on each core as TSS. Multithreading is not.
exec.c
tb_find_fast (cpu-exec.c)
tb_find_slow (cpu-exec.c)
not_found:
tb = tb_gen_code( ... ); (exec.c)
Transformed tb (TranslationBlock) looking for a hash table to find first, then find a physical address from the map, if not find, tb_gen_code will be called to convert the code.
tb_gen_code (exec.c) tb_gen_code (exec.c)
cpu_gen_code (translate-all.c) cpu_gen_code (translate-all.c)
gen_intermediate_code (target-arm/translate.c)
tcg_gen_code (tcg / tcg.c)
The intermediate code to generate the target code instruction gen_intermediate_code() is to generate code from intermediate code instruction of the host tcg_gen_code(). This two –step generation has always continue to do.
Intermediate code is always generated in the same fixed array (gen_opc_buf[]), so it will be overwritten the next time. Not saved.
Host instruction codes are stored in code_gen_buffer[]. The default buffer size is 32MB.(Ram_size/4, while ram_size default value is 128MB).
Code_gen_buffer [] can’t detect the overflow issue.
These sizes can be changed by qemu command line options (-M, -tb-size).
Gen_intermediate_code function inside
Target-arm/translate.c
gen_intermediate_code
gen_intermediate_code_internal
disas_asm_insn
disas_thumb_insn
TCG Structure of the intermediate code
l Operation code
uint_16 gen_opc_buf[OPC_BUF_SIZE]; //OPC_BUF_SIZE = 512 uint_16 gen_opc_buf [OPC_BUF_SIZE]; / / OPC_BUF_SIZE = 512
uint_16 *gen_opc_ptr; uint_16 * gen_opc_ptr;
l Operand
TCGARG gen_opparam_buff[OPPARAM_BUF_SIZE]; //OPC_OPPAERAM_BUF_SIZE = 512 * 10 TCGARG gen_opparam_buff [OPPARAM_BUF_SIZE]; / / OPC_OPPAERAM_BUF_SIZE = 512 * 10
TCGARG *gen_opparam_ptr; TCGARG * gen_opparam_ptr;