aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpu-i386.h5
-rw-r--r--exec.c67
2 files changed, 69 insertions, 3 deletions
diff --git a/cpu-i386.h b/cpu-i386.h
index abbb037235..6c7afbf6e2 100644
--- a/cpu-i386.h
+++ b/cpu-i386.h
@@ -251,7 +251,7 @@ typedef struct CPUX86State {
int error_code;
int exception_is_int;
int exception_next_eip;
-
+ struct TranslationBlock *current_tb; /* currently executing TB */
uint32_t cr[5]; /* NOTE: cr1 is unused */
uint32_t dr[8]; /* debug registers */
int interrupt_request; /* if true, will exit from cpu_exec() ASAP */
@@ -259,7 +259,7 @@ typedef struct CPUX86State {
request interrupt number */
int hard_interrupt_request;
int user_mode_only; /* user mode only simulation */
-
+
/* user data */
void *opaque;
} CPUX86State;
@@ -295,7 +295,6 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info,
/* MMU defines */
void cpu_x86_init_mmu(CPUX86State *env);
-extern CPUX86State *global_env;
extern int phys_ram_size;
extern int phys_ram_fd;
extern uint8_t *phys_ram_base;
diff --git a/exec.c b/exec.c
index 636fe25b80..4de0c60f1a 100644
--- a/exec.c
+++ b/exec.c
@@ -26,7 +26,13 @@
#include <inttypes.h>
#include <sys/mman.h>
+#include "config.h"
+#ifdef TARGET_I386
#include "cpu-i386.h"
+#endif
+#ifdef TARGET_ARM
+#include "cpu-arm.h"
+#endif
#include "exec.h"
//#define DEBUG_TB_INVALIDATE
@@ -564,6 +570,67 @@ TranslationBlock *tb_find_pc(unsigned long tc_ptr)
return &tbs[m_max];
}
+static void tb_reset_jump_recursive(TranslationBlock *tb);
+
+static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n)
+{
+ TranslationBlock *tb1, *tb_next, **ptb;
+ unsigned int n1;
+
+ tb1 = tb->jmp_next[n];
+ if (tb1 != NULL) {
+ /* find head of list */
+ for(;;) {
+ n1 = (long)tb1 & 3;
+ tb1 = (TranslationBlock *)((long)tb1 & ~3);
+ if (n1 == 2)
+ break;
+ tb1 = tb1->jmp_next[n1];
+ }
+ /* we are now sure now that tb jumps to tb1 */
+ tb_next = tb1;
+
+ /* remove tb from the jmp_first list */
+ ptb = &tb_next->jmp_first;
+ for(;;) {
+ tb1 = *ptb;
+ n1 = (long)tb1 & 3;
+ tb1 = (TranslationBlock *)((long)tb1 & ~3);
+ if (n1 == n && tb1 == tb)
+ break;
+ ptb = &tb1->jmp_next[n1];
+ }
+ *ptb = tb->jmp_next[n];
+ tb->jmp_next[n] = NULL;
+
+ /* suppress the jump to next tb in generated code */
+ tb_reset_jump(tb, n);
+
+ /* suppress jumps in the tb on which we could have jump */
+ tb_reset_jump_recursive(tb_next);
+ }
+}
+
+static void tb_reset_jump_recursive(TranslationBlock *tb)
+{
+ tb_reset_jump_recursive2(tb, 0);
+ tb_reset_jump_recursive2(tb, 1);
+}
+
+void cpu_interrupt(CPUState *env)
+{
+ TranslationBlock *tb;
+
+ env->interrupt_request = 1;
+ /* if the cpu is currently executing code, we must unlink it and
+ all the potentially executing TB */
+ tb = env->current_tb;
+ if (tb) {
+ tb_reset_jump_recursive(tb);
+ }
+}
+
+
void cpu_abort(CPUState *env, const char *fmt, ...)
{
va_list ap;