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 | 251 | int error_code; |
252 | 252 | int exception_is_int; |
253 | 253 | int exception_next_eip; |
254 | - | |
254 | + struct TranslationBlock *current_tb; /* currently executing TB */ | |
255 | 255 | uint32_t cr[5]; /* NOTE: cr1 is unused */ |
256 | 256 | uint32_t dr[8]; /* debug registers */ |
257 | 257 | int interrupt_request; /* if true, will exit from cpu_exec() ASAP */ |
... | ... | @@ -259,7 +259,7 @@ typedef struct CPUX86State { |
259 | 259 | request interrupt number */ |
260 | 260 | int hard_interrupt_request; |
261 | 261 | int user_mode_only; /* user mode only simulation */ |
262 | - | |
262 | + | |
263 | 263 | /* user data */ |
264 | 264 | void *opaque; |
265 | 265 | } CPUX86State; |
... | ... | @@ -295,7 +295,6 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, |
295 | 295 | |
296 | 296 | /* MMU defines */ |
297 | 297 | void cpu_x86_init_mmu(CPUX86State *env); |
298 | -extern CPUX86State *global_env; | |
299 | 298 | extern int phys_ram_size; |
300 | 299 | extern int phys_ram_fd; |
301 | 300 | extern uint8_t *phys_ram_base; | ... | ... |
exec.c
... | ... | @@ -26,7 +26,13 @@ |
26 | 26 | #include <inttypes.h> |
27 | 27 | #include <sys/mman.h> |
28 | 28 | |
29 | +#include "config.h" | |
30 | +#ifdef TARGET_I386 | |
29 | 31 | #include "cpu-i386.h" |
32 | +#endif | |
33 | +#ifdef TARGET_ARM | |
34 | +#include "cpu-arm.h" | |
35 | +#endif | |
30 | 36 | #include "exec.h" |
31 | 37 | |
32 | 38 | //#define DEBUG_TB_INVALIDATE |
... | ... | @@ -564,6 +570,67 @@ TranslationBlock *tb_find_pc(unsigned long tc_ptr) |
564 | 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 | 634 | void cpu_abort(CPUState *env, const char *fmt, ...) |
568 | 635 | { |
569 | 636 | va_list ap; | ... | ... |