X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=exec-all.h;h=ff3b24015ff59bf12909f463123e53f2601e51e6;hb=db667a1205587d7b5123330f1f0dc506a9b06459;hp=93e0b5ddfb47a8f355b547a1882ebbd2bb15f648;hpb=6db73509bce1a241040039dd5466977a7356a913;p=mirror_qemu.git diff --git a/exec-all.h b/exec-all.h index 93e0b5ddfb..ff3b24015f 100644 --- a/exec-all.h +++ b/exec-all.h @@ -25,6 +25,15 @@ /* allow to see translation results - the slowdown should be negligible, so we leave it */ #define DEBUG_DISAS +/* Page tracking code uses ram addresses in system mode, and virtual + addresses in userspace mode. Define tb_page_addr_t to be an appropriate + type. */ +#if defined(CONFIG_USER_ONLY) +typedef abi_ulong tb_page_addr_t; +#else +typedef ram_addr_t tb_page_addr_t; +#endif + /* is_jmp field values */ #define DISAS_NEXT 0 /* next instruction can be analyzed */ #define DISAS_JUMP 1 /* only pc was modified dynamically */ @@ -41,10 +50,10 @@ typedef struct TranslationBlock TranslationBlock; #define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR) /* Maximum size a TCG op can expand to. This is complicated because a - single op may require several host instructions and regirster reloads. - For now take a wild guess at 128 bytes, which should allow at least + single op may require several host instructions and register reloads. + For now take a wild guess at 192 bytes, which should allow at least a couple of fixup instructions per argument. */ -#define TCG_MAX_OP_SIZE 128 +#define TCG_MAX_OP_SIZE 192 #define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * MAX_OPC_PARAM) @@ -81,22 +90,16 @@ TranslationBlock *tb_gen_code(CPUState *env, void cpu_exec_init(CPUState *env); void QEMU_NORETURN cpu_loop_exit(void); int page_unprotect(target_ulong address, unsigned long pc, void *puc); -void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end, +void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, int is_cpu_write_access); void tb_invalidate_page_range(target_ulong start, target_ulong end); void tlb_flush_page(CPUState *env, target_ulong addr); void tlb_flush(CPUState *env, int flush_global); -int tlb_set_page_exec(CPUState *env, target_ulong vaddr, - target_phys_addr_t paddr, int prot, - int mmu_idx, int is_softmmu); -static inline int tlb_set_page(CPUState *env1, target_ulong vaddr, - target_phys_addr_t paddr, int prot, - int mmu_idx, int is_softmmu) -{ - if (prot & PAGE_READ) - prot |= PAGE_EXEC; - return tlb_set_page_exec(env1, vaddr, paddr, prot, mmu_idx, is_softmmu); -} +#if !defined(CONFIG_USER_ONLY) +void tlb_set_page(CPUState *env, target_ulong vaddr, + target_phys_addr_t paddr, int prot, + int mmu_idx, target_ulong size); +#endif #define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */ @@ -134,7 +137,7 @@ struct TranslationBlock { /* first and second physical page containing code. The lower bit of the pointer tells the index in page_next[] */ struct TranslationBlock *page_next[2]; - target_ulong page_addr[2]; + tb_page_addr_t page_addr[2]; /* the following data are used to directly call another TB from the code of this one. */ @@ -168,7 +171,7 @@ static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc) | (tmp & TB_JMP_ADDR_MASK)); } -static inline unsigned int tb_phys_hash_func(unsigned long pc) +static inline unsigned int tb_phys_hash_func(tb_page_addr_t pc) { return pc & (CODE_GEN_PHYS_HASH_SIZE - 1); } @@ -176,9 +179,9 @@ static inline unsigned int tb_phys_hash_func(unsigned long pc) TranslationBlock *tb_alloc(target_ulong pc); void tb_free(TranslationBlock *tb); void tb_flush(CPUState *env); -void tb_link_phys(TranslationBlock *tb, - target_ulong phys_pc, target_ulong phys_page2); -void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr); +void tb_link_page(TranslationBlock *tb, + tb_page_addr_t phys_pc, tb_page_addr_t phys_page2); +void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr); extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; extern uint8_t *code_gen_ptr; @@ -208,7 +211,9 @@ static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr #endif /* we could use a ldr pc, [pc, #-4] kind of branch and avoid the flush */ - *(uint32_t *)jmp_addr |= ((addr - (jmp_addr + 8)) >> 2) & 0xffffff; + *(uint32_t *)jmp_addr = + (*(uint32_t *)jmp_addr & ~0xffffff) + | (((addr - (jmp_addr + 8)) >> 2) & 0xffffff); #if QEMU_GNUC_PREREQ(4, 1) __clear_cache((char *) jmp_addr, (char *) jmp_addr + 4); @@ -261,10 +266,6 @@ static inline void tb_add_jump(TranslationBlock *tb, int n, TranslationBlock *tb_find_pc(unsigned long pc_ptr); -extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; -extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; -extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; - #include "qemu-lock.h" extern spinlock_t tb_lock; @@ -273,6 +274,10 @@ extern int tb_invalidated_flag; #if !defined(CONFIG_USER_ONLY) +extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; +extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; +extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; + void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr); @@ -301,7 +306,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, #endif #if defined(CONFIG_USER_ONLY) -static inline target_ulong get_phys_addr_code(CPUState *env1, target_ulong addr) +static inline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr) { return addr; } @@ -309,7 +314,7 @@ static inline target_ulong get_phys_addr_code(CPUState *env1, target_ulong addr) /* 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 */ -static inline target_ulong get_phys_addr_code(CPUState *env1, target_ulong addr) +static inline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr) { int mmu_idx, page_index, pd; void *p; @@ -332,20 +337,6 @@ static inline target_ulong get_phys_addr_code(CPUState *env1, target_ulong addr) + env1->tlb_table[mmu_idx][page_index].addend; return qemu_ram_addr_from_host(p); } - -/* Deterministic execution requires that IO only be performed on the last - instruction of a TB so that interrupts take effect immediately. */ -static inline int can_do_io(CPUState *env) -{ - if (!use_icount) - return 1; - - /* If not executing code then assume we are ok. */ - if (!env->current_tb) - return 1; - - return env->can_do_io != 0; -} #endif typedef void (CPUDebugExcpHandler)(CPUState *env);