Commit 1376847f9f003a5a1c7f62a1425352d397348ba7

Authored by bellard
1 parent 17348a7f

support for new TLB handling


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@513 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 47 additions and 2 deletions
cpu-exec.c
... ... @@ -262,7 +262,42 @@ int cpu_exec(CPUState *env1)
262 262 tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base,
263 263 flags);
264 264 if (!tb) {
  265 + TranslationBlock **ptb1;
  266 + unsigned int h;
  267 + target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
  268 +
  269 +
265 270 spin_lock(&tb_lock);
  271 +
  272 + tb_invalidated_flag = 0;
  273 +
  274 + /* find translated block using physical mappings */
  275 + phys_pc = get_phys_addr_code(env, (unsigned long)pc);
  276 + phys_page1 = phys_pc & TARGET_PAGE_MASK;
  277 + phys_page2 = -1;
  278 + h = tb_phys_hash_func(phys_pc);
  279 + ptb1 = &tb_phys_hash[h];
  280 + for(;;) {
  281 + tb = *ptb1;
  282 + if (!tb)
  283 + goto not_found;
  284 + if (tb->pc == (unsigned long)pc &&
  285 + tb->page_addr[0] == phys_page1 &&
  286 + tb->cs_base == (unsigned long)cs_base &&
  287 + tb->flags == flags) {
  288 + /* check next page if needed */
  289 + virt_page2 = ((unsigned long)pc + tb->size - 1) & TARGET_PAGE_MASK;
  290 + if (((unsigned long)pc & TARGET_PAGE_MASK) != virt_page2) {
  291 + phys_page2 = get_phys_addr_code(env, virt_page2);
  292 + if (tb->page_addr[1] == phys_page2)
  293 + goto found;
  294 + } else {
  295 + goto found;
  296 + }
  297 + }
  298 + ptb1 = &tb->phys_hash_next;
  299 + }
  300 + not_found:
266 301 /* if no translated code available, then translate it now */
267 302 tb = tb_alloc((unsigned long)pc);
268 303 if (!tb) {
... ... @@ -278,8 +313,18 @@ int cpu_exec(CPUState *env1)
278 313 tb->tc_ptr = tc_ptr;
279 314 tb->cs_base = (unsigned long)cs_base;
280 315 tb->flags = flags;
281   - tb_invalidated_flag = 0;
282 316 cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
  317 + code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
  318 +
  319 + /* check next page if needed */
  320 + virt_page2 = ((unsigned long)pc + tb->size - 1) & TARGET_PAGE_MASK;
  321 + phys_page2 = -1;
  322 + if (((unsigned long)pc & TARGET_PAGE_MASK) != virt_page2) {
  323 + phys_page2 = get_phys_addr_code(env, virt_page2);
  324 + }
  325 + tb_link_phys(tb, phys_pc, phys_page2);
  326 +
  327 + found:
283 328 if (tb_invalidated_flag) {
284 329 /* as some TB could have been invalidated because
285 330 of memory exceptions while generating the code, we
... ... @@ -289,10 +334,10 @@ int cpu_exec(CPUState *env1)
289 334 ptb = &(*ptb)->hash_next;
290 335 T0 = 0;
291 336 }
  337 + /* we add the TB in the virtual pc hash table */
292 338 *ptb = tb;
293 339 tb->hash_next = NULL;
294 340 tb_link(tb);
295   - code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
296 341 spin_unlock(&tb_lock);
297 342 }
298 343 #ifdef DEBUG_EXEC
... ...