00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _EXEC_ALL_H_
00022 #define _EXEC_ALL_H_
00023
00024 #include "qemu-common.h"
00025
00026
00027 #define DEBUG_DISAS
00028
00029
00030 #define DISAS_NEXT 0
00031 #define DISAS_JUMP 1
00032 #define DISAS_UPDATE 2
00033 #define DISAS_TB_JUMP 3
00034
00035 typedef struct TranslationBlock TranslationBlock;
00036
00037
00038 #define MAX_OP_PER_INSTR 64
00039
00040 #define MAX_OPC_PARAM 10
00041 #define OPC_BUF_SIZE 512
00042 #define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
00043
00044
00045
00046
00047
00048 #define TCG_MAX_OP_SIZE 128
00049
00050 #define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * MAX_OPC_PARAM)
00051
00052 extern target_ulong gen_opc_pc[OPC_BUF_SIZE];
00053 extern target_ulong gen_opc_npc[OPC_BUF_SIZE];
00054 extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
00055 extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
00056 extern uint16_t gen_opc_icount[OPC_BUF_SIZE];
00057 extern target_ulong gen_opc_jump_pc[2];
00058 extern uint32_t gen_opc_hflags[OPC_BUF_SIZE];
00059
00060 #include "qemu-log.h"
00061
00062 void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
00063 void gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
00064 void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
00065 unsigned long searched_pc, int pc_pos, void *puc);
00066
00067 unsigned long code_gen_max_block_size(void);
00068 void cpu_gen_init(void);
00069 int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
00070 int *gen_code_size_ptr);
00071 int cpu_restore_state(struct TranslationBlock *tb,
00072 CPUState *env, unsigned long searched_pc,
00073 void *puc);
00074 int cpu_restore_state_copy(struct TranslationBlock *tb,
00075 CPUState *env, unsigned long searched_pc,
00076 void *puc);
00077 void cpu_resume_from_signal(CPUState *env1, void *puc);
00078 void cpu_io_recompile(CPUState *env, void *retaddr);
00079 TranslationBlock *tb_gen_code(CPUState *env,
00080 target_ulong pc, target_ulong cs_base, int flags,
00081 int cflags);
00082 void cpu_exec_init(CPUState *env);
00083 void QEMU_NORETURN cpu_loop_exit(void);
00084 int page_unprotect(target_ulong address, unsigned long pc, void *puc);
00085 void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end,
00086 int is_cpu_write_access);
00087 void tb_invalidate_page_range(target_ulong start, target_ulong end);
00088 void tlb_flush_page(CPUState *env, target_ulong addr);
00089 void tlb_flush(CPUState *env, int flush_global);
00090 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
00091 target_phys_addr_t paddr, int prot,
00092 int mmu_idx, int is_softmmu);
00093 static inline int tlb_set_page(CPUState *env1, target_ulong vaddr,
00094 target_phys_addr_t paddr, int prot,
00095 int mmu_idx, int is_softmmu)
00096 {
00097 if (prot & PAGE_READ)
00098 prot |= PAGE_EXEC;
00099 return tlb_set_page_exec(env1, vaddr, paddr, prot, mmu_idx, is_softmmu);
00100 }
00101
00102 #define CODE_GEN_ALIGN 16
00103
00104 #define CODE_GEN_PHYS_HASH_BITS 15
00105 #define CODE_GEN_PHYS_HASH_SIZE (1 << CODE_GEN_PHYS_HASH_BITS)
00106
00107 #define MIN_CODE_GEN_BUFFER_SIZE (1024 * 1024)
00108
00109
00110
00111
00112 #if defined(CONFIG_SOFTMMU)
00113 #define CODE_GEN_AVG_BLOCK_SIZE 128
00114 #else
00115 #define CODE_GEN_AVG_BLOCK_SIZE 64
00116 #endif
00117
00118 #if defined(_ARCH_PPC) || defined(__x86_64__) || defined(__arm__)
00119 #define USE_DIRECT_JUMP
00120 #endif
00121 #if defined(__i386__) && !defined(_WIN32)
00122 #define USE_DIRECT_JUMP
00123 #endif
00124
00125 struct TranslationBlock {
00126 target_ulong pc;
00127 target_ulong cs_base;
00128 uint64_t flags;
00129 uint16_t size;
00130
00131 uint16_t cflags;
00132 #define CF_COUNT_MASK 0x7fff
00133 #define CF_LAST_IO 0x8000
00134
00135 uint8_t *tc_ptr;
00136
00137 struct TranslationBlock *phys_hash_next;
00138
00139
00140 struct TranslationBlock *page_next[2];
00141 target_ulong page_addr[2];
00142
00143
00144
00145 uint16_t tb_next_offset[2];
00146 #ifdef USE_DIRECT_JUMP
00147 uint16_t tb_jmp_offset[4];
00148 #else
00149 unsigned long tb_next[2];
00150 #endif
00151
00152
00153
00154
00155 struct TranslationBlock *jmp_next[2];
00156 struct TranslationBlock *jmp_first;
00157 uint32_t icount;
00158 };
00159
00160 static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
00161 {
00162 target_ulong tmp;
00163 tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
00164 return (tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK;
00165 }
00166
00167 static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc)
00168 {
00169 target_ulong tmp;
00170 tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
00171 return (((tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK)
00172 | (tmp & TB_JMP_ADDR_MASK));
00173 }
00174
00175 static inline unsigned int tb_phys_hash_func(unsigned long pc)
00176 {
00177 return pc & (CODE_GEN_PHYS_HASH_SIZE - 1);
00178 }
00179
00180 TranslationBlock *tb_alloc(target_ulong pc);
00181 void tb_free(TranslationBlock *tb);
00182 void tb_flush(CPUState *env);
00183 void tb_link_phys(TranslationBlock *tb,
00184 target_ulong phys_pc, target_ulong phys_page2);
00185 void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr);
00186
00187 extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
00188 extern uint8_t *code_gen_ptr;
00189 extern int code_gen_max_blocks;
00190
00191 #if defined(USE_DIRECT_JUMP)
00192
00193 #if defined(_ARCH_PPC)
00194 extern void ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr);
00195 #define tb_set_jmp_target1 ppc_tb_set_jmp_target
00196 #elif defined(__i386__) || defined(__x86_64__)
00197 static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
00198 {
00199
00200 *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
00201
00202 }
00203 #elif defined(__arm__)
00204 static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
00205 {
00206 #if QEMU_GNUC_PREREQ(4, 1)
00207 void __clear_cache(char *beg, char *end);
00208 #else
00209 register unsigned long _beg __asm ("a1");
00210 register unsigned long _end __asm ("a2");
00211 register unsigned long _flg __asm ("a3");
00212 #endif
00213
00214
00215 *(uint32_t *)jmp_addr |= ((addr - (jmp_addr + 8)) >> 2) & 0xffffff;
00216
00217 #if QEMU_GNUC_PREREQ(4, 1)
00218 __clear_cache((char *) jmp_addr, (char *) jmp_addr + 4);
00219 #else
00220
00221 _beg = jmp_addr;
00222 _end = jmp_addr + 4;
00223 _flg = 0;
00224 __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
00225 #endif
00226 }
00227 #endif
00228
00229 static inline void tb_set_jmp_target(TranslationBlock *tb,
00230 int n, unsigned long addr)
00231 {
00232 unsigned long offset;
00233
00234 offset = tb->tb_jmp_offset[n];
00235 tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
00236 offset = tb->tb_jmp_offset[n + 2];
00237 if (offset != 0xffff)
00238 tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
00239 }
00240
00241 #else
00242
00243
00244 static inline void tb_set_jmp_target(TranslationBlock *tb,
00245 int n, unsigned long addr)
00246 {
00247 tb->tb_next[n] = addr;
00248 }
00249
00250 #endif
00251
00252 static inline void tb_add_jump(TranslationBlock *tb, int n,
00253 TranslationBlock *tb_next)
00254 {
00255
00256 if (!tb->jmp_next[n]) {
00257
00258 tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr);
00259
00260
00261 tb->jmp_next[n] = tb_next->jmp_first;
00262 tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n));
00263 }
00264 }
00265
00266 TranslationBlock *tb_find_pc(unsigned long pc_ptr);
00267
00268 extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
00269 extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
00270 extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
00271
00272 #include "qemu-lock.h"
00273
00274 extern spinlock_t tb_lock;
00275
00276 extern int tb_invalidated_flag;
00277
00278 #if !defined(CONFIG_USER_ONLY)
00279
00280 void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
00281 void *retaddr);
00282
00283 #include "softmmu_defs.h"
00284
00285 #define ACCESS_TYPE (NB_MMU_MODES + 1)
00286 #define MEMSUFFIX _code
00287 #define env cpu_single_env
00288
00289 #define DATA_SIZE 1
00290 #include "softmmu_header.h"
00291
00292 #define DATA_SIZE 2
00293 #include "softmmu_header.h"
00294
00295 #define DATA_SIZE 4
00296 #include "softmmu_header.h"
00297
00298 #define DATA_SIZE 8
00299 #include "softmmu_header.h"
00300
00301 #undef ACCESS_TYPE
00302 #undef MEMSUFFIX
00303 #undef env
00304
00305 #endif
00306
00307 #if defined(CONFIG_USER_ONLY)
00308 static inline target_ulong get_phys_addr_code(CPUState *env1, target_ulong addr)
00309 {
00310 return addr;
00311 }
00312 #else
00313
00314
00315
00316 static inline target_ulong get_phys_addr_code(CPUState *env1, target_ulong addr)
00317 {
00318 int mmu_idx, page_index, pd;
00319
00320 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
00321 mmu_idx = cpu_mmu_index(env1);
00322 if (unlikely(env1->tlb_table[mmu_idx][page_index].addr_code !=
00323 (addr & TARGET_PAGE_MASK))) {
00324 ldub_code(addr);
00325 }
00326 pd = env1->tlb_table[mmu_idx][page_index].addr_code & ~TARGET_PAGE_MASK;
00327 if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
00328 #if defined(TARGET_SPARC) || defined(TARGET_MIPS)
00329 do_unassigned_access(addr, 0, 1, 0, 4);
00330 #else
00331 cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
00332 #endif
00333 }
00334 return addr + env1->tlb_table[mmu_idx][page_index].addend - (unsigned long)phys_ram_base;
00335 }
00336
00337
00338
00339 static inline int can_do_io(CPUState *env)
00340 {
00341 if (!use_icount)
00342 return 1;
00343
00344
00345 if (!env->current_tb)
00346 return 1;
00347
00348 return env->can_do_io != 0;
00349 }
00350 #endif
00351
00352 #ifdef USE_KQEMU
00353 #define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
00354
00355 #define MSR_QPI_COMMBASE 0xfabe0010
00356
00357 int kqemu_init(CPUState *env);
00358 int kqemu_cpu_exec(CPUState *env);
00359 void kqemu_flush_page(CPUState *env, target_ulong addr);
00360 void kqemu_flush(CPUState *env, int global);
00361 void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr);
00362 void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr);
00363 void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size,
00364 ram_addr_t phys_offset);
00365 void kqemu_cpu_interrupt(CPUState *env);
00366 void kqemu_record_dump(void);
00367
00368 extern uint32_t kqemu_comm_base;
00369
00370 static inline int kqemu_is_ok(CPUState *env)
00371 {
00372 return(env->kqemu_enabled &&
00373 (env->cr[0] & CR0_PE_MASK) &&
00374 !(env->hflags & HF_INHIBIT_IRQ_MASK) &&
00375 (env->eflags & IF_MASK) &&
00376 !(env->eflags & VM_MASK) &&
00377 (env->kqemu_enabled == 2 ||
00378 ((env->hflags & HF_CPL_MASK) == 3 &&
00379 (env->eflags & IOPL_MASK) != IOPL_MASK)));
00380 }
00381
00382 #endif
00383
00384 typedef void (CPUDebugExcpHandler)(CPUState *env);
00385
00386 CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);
00387 #endif