Commit ea041c0e3375801694610250a8cc3e1240e2ad87

Authored by bellard
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;
... ...
... ... @@ -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;
... ...