Commit ea041c0e3375801694610250a8cc3e1240e2ad87
1 parent
83479e77
more precise cpu_interrupt()
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@276 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
69 additions
and
3 deletions
cpu-i386.h
| @@ -251,7 +251,7 @@ typedef struct CPUX86State { | @@ -251,7 +251,7 @@ typedef struct CPUX86State { | ||
| 251 | int error_code; | 251 | int error_code; |
| 252 | int exception_is_int; | 252 | int exception_is_int; |
| 253 | int exception_next_eip; | 253 | int exception_next_eip; |
| 254 | - | 254 | + struct TranslationBlock *current_tb; /* currently executing TB */ |
| 255 | uint32_t cr[5]; /* NOTE: cr1 is unused */ | 255 | uint32_t cr[5]; /* NOTE: cr1 is unused */ |
| 256 | uint32_t dr[8]; /* debug registers */ | 256 | uint32_t dr[8]; /* debug registers */ |
| 257 | int interrupt_request; /* if true, will exit from cpu_exec() ASAP */ | 257 | int interrupt_request; /* if true, will exit from cpu_exec() ASAP */ |
| @@ -259,7 +259,7 @@ typedef struct CPUX86State { | @@ -259,7 +259,7 @@ typedef struct CPUX86State { | ||
| 259 | request interrupt number */ | 259 | request interrupt number */ |
| 260 | int hard_interrupt_request; | 260 | int hard_interrupt_request; |
| 261 | int user_mode_only; /* user mode only simulation */ | 261 | int user_mode_only; /* user mode only simulation */ |
| 262 | - | 262 | + |
| 263 | /* user data */ | 263 | /* user data */ |
| 264 | void *opaque; | 264 | void *opaque; |
| 265 | } CPUX86State; | 265 | } CPUX86State; |
| @@ -295,7 +295,6 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, | @@ -295,7 +295,6 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, | ||
| 295 | 295 | ||
| 296 | /* MMU defines */ | 296 | /* MMU defines */ |
| 297 | void cpu_x86_init_mmu(CPUX86State *env); | 297 | void cpu_x86_init_mmu(CPUX86State *env); |
| 298 | -extern CPUX86State *global_env; | ||
| 299 | extern int phys_ram_size; | 298 | extern int phys_ram_size; |
| 300 | extern int phys_ram_fd; | 299 | extern int phys_ram_fd; |
| 301 | extern uint8_t *phys_ram_base; | 300 | extern uint8_t *phys_ram_base; |
exec.c
| @@ -26,7 +26,13 @@ | @@ -26,7 +26,13 @@ | ||
| 26 | #include <inttypes.h> | 26 | #include <inttypes.h> |
| 27 | #include <sys/mman.h> | 27 | #include <sys/mman.h> |
| 28 | 28 | ||
| 29 | +#include "config.h" | ||
| 30 | +#ifdef TARGET_I386 | ||
| 29 | #include "cpu-i386.h" | 31 | #include "cpu-i386.h" |
| 32 | +#endif | ||
| 33 | +#ifdef TARGET_ARM | ||
| 34 | +#include "cpu-arm.h" | ||
| 35 | +#endif | ||
| 30 | #include "exec.h" | 36 | #include "exec.h" |
| 31 | 37 | ||
| 32 | //#define DEBUG_TB_INVALIDATE | 38 | //#define DEBUG_TB_INVALIDATE |
| @@ -564,6 +570,67 @@ TranslationBlock *tb_find_pc(unsigned long tc_ptr) | @@ -564,6 +570,67 @@ TranslationBlock *tb_find_pc(unsigned long tc_ptr) | ||
| 564 | return &tbs[m_max]; | 570 | return &tbs[m_max]; |
| 565 | } | 571 | } |
| 566 | 572 | ||
| 573 | +static void tb_reset_jump_recursive(TranslationBlock *tb); | ||
| 574 | + | ||
| 575 | +static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n) | ||
| 576 | +{ | ||
| 577 | + TranslationBlock *tb1, *tb_next, **ptb; | ||
| 578 | + unsigned int n1; | ||
| 579 | + | ||
| 580 | + tb1 = tb->jmp_next[n]; | ||
| 581 | + if (tb1 != NULL) { | ||
| 582 | + /* find head of list */ | ||
| 583 | + for(;;) { | ||
| 584 | + n1 = (long)tb1 & 3; | ||
| 585 | + tb1 = (TranslationBlock *)((long)tb1 & ~3); | ||
| 586 | + if (n1 == 2) | ||
| 587 | + break; | ||
| 588 | + tb1 = tb1->jmp_next[n1]; | ||
| 589 | + } | ||
| 590 | + /* we are now sure now that tb jumps to tb1 */ | ||
| 591 | + tb_next = tb1; | ||
| 592 | + | ||
| 593 | + /* remove tb from the jmp_first list */ | ||
| 594 | + ptb = &tb_next->jmp_first; | ||
| 595 | + for(;;) { | ||
| 596 | + tb1 = *ptb; | ||
| 597 | + n1 = (long)tb1 & 3; | ||
| 598 | + tb1 = (TranslationBlock *)((long)tb1 & ~3); | ||
| 599 | + if (n1 == n && tb1 == tb) | ||
| 600 | + break; | ||
| 601 | + ptb = &tb1->jmp_next[n1]; | ||
| 602 | + } | ||
| 603 | + *ptb = tb->jmp_next[n]; | ||
| 604 | + tb->jmp_next[n] = NULL; | ||
| 605 | + | ||
| 606 | + /* suppress the jump to next tb in generated code */ | ||
| 607 | + tb_reset_jump(tb, n); | ||
| 608 | + | ||
| 609 | + /* suppress jumps in the tb on which we could have jump */ | ||
| 610 | + tb_reset_jump_recursive(tb_next); | ||
| 611 | + } | ||
| 612 | +} | ||
| 613 | + | ||
| 614 | +static void tb_reset_jump_recursive(TranslationBlock *tb) | ||
| 615 | +{ | ||
| 616 | + tb_reset_jump_recursive2(tb, 0); | ||
| 617 | + tb_reset_jump_recursive2(tb, 1); | ||
| 618 | +} | ||
| 619 | + | ||
| 620 | +void cpu_interrupt(CPUState *env) | ||
| 621 | +{ | ||
| 622 | + TranslationBlock *tb; | ||
| 623 | + | ||
| 624 | + env->interrupt_request = 1; | ||
| 625 | + /* if the cpu is currently executing code, we must unlink it and | ||
| 626 | + all the potentially executing TB */ | ||
| 627 | + tb = env->current_tb; | ||
| 628 | + if (tb) { | ||
| 629 | + tb_reset_jump_recursive(tb); | ||
| 630 | + } | ||
| 631 | +} | ||
| 632 | + | ||
| 633 | + | ||
| 567 | void cpu_abort(CPUState *env, const char *fmt, ...) | 634 | void cpu_abort(CPUState *env, const char *fmt, ...) |
| 568 | { | 635 | { |
| 569 | va_list ap; | 636 | va_list ap; |