Loading cpu-defs.h +8 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,14 @@ typedef unsigned long ram_addr_t; #define TB_JMP_CACHE_BITS 12 #define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS) /* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for addresses on the same page. The top bits are the same. This allows TLB invalidation to quickly clear a subset of the hash table. */ #define TB_JMP_PAGE_BITS (TB_JMP_CACHE_BITS / 2) #define TB_JMP_PAGE_SIZE (1 << TB_JMP_PAGE_BITS) #define TB_JMP_ADDR_MASK (TB_JMP_PAGE_SIZE - 1) #define TB_JMP_PAGE_MASK (TB_JMP_CACHE_SIZE - TB_JMP_PAGE_SIZE) #define CPU_TLB_BITS 8 #define CPU_TLB_SIZE (1 << CPU_TLB_BITS) Loading exec-all.h +11 −1 Original line number Diff line number Diff line Loading @@ -196,9 +196,19 @@ typedef struct TranslationBlock { struct TranslationBlock *jmp_first; } TranslationBlock; static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc) { target_ulong tmp; tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)); return (tmp >> TB_JMP_PAGE_BITS) & TB_JMP_PAGE_MASK; } static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc) { return (pc ^ (pc >> TB_JMP_CACHE_BITS)) & (TB_JMP_CACHE_SIZE - 1); target_ulong tmp; tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)); return (((tmp >> TB_JMP_PAGE_BITS) & TB_JMP_PAGE_MASK) | (tmp & TB_JMP_ADDR_MASK)); } static inline unsigned int tb_phys_hash_func(unsigned long pc) Loading exec.c +7 −8 Original line number Diff line number Diff line Loading @@ -1288,14 +1288,13 @@ void tlb_flush_page(CPUState *env, target_ulong addr) tlb_flush_entry(&env->tlb_table[0][i], addr); tlb_flush_entry(&env->tlb_table[1][i], addr); for(i = 0; i < TB_JMP_CACHE_SIZE; i++) { tb = env->tb_jmp_cache[i]; if (tb && ((tb->pc & TARGET_PAGE_MASK) == addr || ((tb->pc + tb->size - 1) & TARGET_PAGE_MASK) == addr)) { env->tb_jmp_cache[i] = NULL; } } /* Discard jump cache entries for any tb which might potentially overlap the flushed page. */ i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE); memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb)); i = tb_jmp_cache_hash_page(addr); memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb)); #if !defined(CONFIG_SOFTMMU) if (addr < MMAP_AREA_END) Loading Loading
cpu-defs.h +8 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,14 @@ typedef unsigned long ram_addr_t; #define TB_JMP_CACHE_BITS 12 #define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS) /* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for addresses on the same page. The top bits are the same. This allows TLB invalidation to quickly clear a subset of the hash table. */ #define TB_JMP_PAGE_BITS (TB_JMP_CACHE_BITS / 2) #define TB_JMP_PAGE_SIZE (1 << TB_JMP_PAGE_BITS) #define TB_JMP_ADDR_MASK (TB_JMP_PAGE_SIZE - 1) #define TB_JMP_PAGE_MASK (TB_JMP_CACHE_SIZE - TB_JMP_PAGE_SIZE) #define CPU_TLB_BITS 8 #define CPU_TLB_SIZE (1 << CPU_TLB_BITS) Loading
exec-all.h +11 −1 Original line number Diff line number Diff line Loading @@ -196,9 +196,19 @@ typedef struct TranslationBlock { struct TranslationBlock *jmp_first; } TranslationBlock; static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc) { target_ulong tmp; tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)); return (tmp >> TB_JMP_PAGE_BITS) & TB_JMP_PAGE_MASK; } static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc) { return (pc ^ (pc >> TB_JMP_CACHE_BITS)) & (TB_JMP_CACHE_SIZE - 1); target_ulong tmp; tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)); return (((tmp >> TB_JMP_PAGE_BITS) & TB_JMP_PAGE_MASK) | (tmp & TB_JMP_ADDR_MASK)); } static inline unsigned int tb_phys_hash_func(unsigned long pc) Loading
exec.c +7 −8 Original line number Diff line number Diff line Loading @@ -1288,14 +1288,13 @@ void tlb_flush_page(CPUState *env, target_ulong addr) tlb_flush_entry(&env->tlb_table[0][i], addr); tlb_flush_entry(&env->tlb_table[1][i], addr); for(i = 0; i < TB_JMP_CACHE_SIZE; i++) { tb = env->tb_jmp_cache[i]; if (tb && ((tb->pc & TARGET_PAGE_MASK) == addr || ((tb->pc + tb->size - 1) & TARGET_PAGE_MASK) == addr)) { env->tb_jmp_cache[i] = NULL; } } /* Discard jump cache entries for any tb which might potentially overlap the flushed page. */ i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE); memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb)); i = tb_jmp_cache_hash_page(addr); memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb)); #if !defined(CONFIG_SOFTMMU) if (addr < MMAP_AREA_END) Loading