Commit 1376847f9f003a5a1c7f62a1425352d397348ba7
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,7 +262,42 @@ int cpu_exec(CPUState *env1) | ||
| 262 | tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, | 262 | tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, |
| 263 | flags); | 263 | flags); |
| 264 | if (!tb) { | 264 | if (!tb) { |
| 265 | + TranslationBlock **ptb1; | ||
| 266 | + unsigned int h; | ||
| 267 | + target_ulong phys_pc, phys_page1, phys_page2, virt_page2; | ||
| 268 | + | ||
| 269 | + | ||
| 265 | spin_lock(&tb_lock); | 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 | /* if no translated code available, then translate it now */ | 301 | /* if no translated code available, then translate it now */ |
| 267 | tb = tb_alloc((unsigned long)pc); | 302 | tb = tb_alloc((unsigned long)pc); |
| 268 | if (!tb) { | 303 | if (!tb) { |
| @@ -278,8 +313,18 @@ int cpu_exec(CPUState *env1) | @@ -278,8 +313,18 @@ int cpu_exec(CPUState *env1) | ||
| 278 | tb->tc_ptr = tc_ptr; | 313 | tb->tc_ptr = tc_ptr; |
| 279 | tb->cs_base = (unsigned long)cs_base; | 314 | tb->cs_base = (unsigned long)cs_base; |
| 280 | tb->flags = flags; | 315 | tb->flags = flags; |
| 281 | - tb_invalidated_flag = 0; | ||
| 282 | cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size); | 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 | if (tb_invalidated_flag) { | 328 | if (tb_invalidated_flag) { |
| 284 | /* as some TB could have been invalidated because | 329 | /* as some TB could have been invalidated because |
| 285 | of memory exceptions while generating the code, we | 330 | of memory exceptions while generating the code, we |
| @@ -289,10 +334,10 @@ int cpu_exec(CPUState *env1) | @@ -289,10 +334,10 @@ int cpu_exec(CPUState *env1) | ||
| 289 | ptb = &(*ptb)->hash_next; | 334 | ptb = &(*ptb)->hash_next; |
| 290 | T0 = 0; | 335 | T0 = 0; |
| 291 | } | 336 | } |
| 337 | + /* we add the TB in the virtual pc hash table */ | ||
| 292 | *ptb = tb; | 338 | *ptb = tb; |
| 293 | tb->hash_next = NULL; | 339 | tb->hash_next = NULL; |
| 294 | tb_link(tb); | 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 | spin_unlock(&tb_lock); | 341 | spin_unlock(&tb_lock); |
| 297 | } | 342 | } |
| 298 | #ifdef DEBUG_EXEC | 343 | #ifdef DEBUG_EXEC |