reduced irq latency
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@296 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
c9159e5321
commit
68a7931591
@ -309,6 +309,10 @@ void page_unprotect_range(uint8_t *data, unsigned long data_size);
|
|||||||
void cpu_abort(CPUState *env, const char *fmt, ...);
|
void cpu_abort(CPUState *env, const char *fmt, ...);
|
||||||
extern CPUState *cpu_single_env;
|
extern CPUState *cpu_single_env;
|
||||||
|
|
||||||
|
#define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */
|
||||||
|
#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
|
||||||
|
void cpu_interrupt(CPUX86State *s, int mask);
|
||||||
|
|
||||||
/* gdb stub API */
|
/* gdb stub API */
|
||||||
extern int gdbstub_fd;
|
extern int gdbstub_fd;
|
||||||
CPUState *cpu_gdbstub_get_env(void *opaque);
|
CPUState *cpu_gdbstub_get_env(void *opaque);
|
||||||
|
43
cpu-exec.c
43
cpu-exec.c
@ -71,7 +71,7 @@ int cpu_exec(CPUState *env1)
|
|||||||
#ifdef __sparc__
|
#ifdef __sparc__
|
||||||
int saved_i7, tmp_T0;
|
int saved_i7, tmp_T0;
|
||||||
#endif
|
#endif
|
||||||
int code_gen_size, ret;
|
int code_gen_size, ret, interrupt_request;
|
||||||
void (*gen_func)(void);
|
void (*gen_func)(void);
|
||||||
TranslationBlock *tb, **ptb;
|
TranslationBlock *tb, **ptb;
|
||||||
uint8_t *tc_ptr, *cs_base, *pc;
|
uint8_t *tc_ptr, *cs_base, *pc;
|
||||||
@ -139,7 +139,6 @@ int cpu_exec(CPUState *env1)
|
|||||||
#else
|
#else
|
||||||
#error unsupported target CPU
|
#error unsupported target CPU
|
||||||
#endif
|
#endif
|
||||||
env->interrupt_request = 0;
|
|
||||||
env->exception_index = -1;
|
env->exception_index = -1;
|
||||||
|
|
||||||
/* prepare setjmp context for exception handling */
|
/* prepare setjmp context for exception handling */
|
||||||
@ -176,28 +175,32 @@ int cpu_exec(CPUState *env1)
|
|||||||
}
|
}
|
||||||
env->exception_index = -1;
|
env->exception_index = -1;
|
||||||
}
|
}
|
||||||
#if defined(TARGET_I386)
|
|
||||||
/* if hardware interrupt pending, we execute it */
|
|
||||||
if (env->hard_interrupt_request &&
|
|
||||||
(env->eflags & IF_MASK)) {
|
|
||||||
int intno;
|
|
||||||
intno = cpu_x86_get_pic_interrupt(env);
|
|
||||||
if (loglevel) {
|
|
||||||
fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
|
|
||||||
}
|
|
||||||
do_interrupt(intno, 0, 0, 0);
|
|
||||||
env->hard_interrupt_request = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
T0 = 0; /* force lookup of first TB */
|
T0 = 0; /* force lookup of first TB */
|
||||||
for(;;) {
|
for(;;) {
|
||||||
#ifdef __sparc__
|
#ifdef __sparc__
|
||||||
/* g1 can be modified by some libc? functions */
|
/* g1 can be modified by some libc? functions */
|
||||||
tmp_T0 = T0;
|
tmp_T0 = T0;
|
||||||
#endif
|
#endif
|
||||||
if (env->interrupt_request) {
|
interrupt_request = env->interrupt_request;
|
||||||
env->exception_index = EXCP_INTERRUPT;
|
if (interrupt_request) {
|
||||||
cpu_loop_exit();
|
#if defined(TARGET_I386)
|
||||||
|
/* if hardware interrupt pending, we execute it */
|
||||||
|
if ((interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||||
|
(env->eflags & IF_MASK)) {
|
||||||
|
int intno;
|
||||||
|
intno = cpu_x86_get_pic_interrupt(env);
|
||||||
|
if (loglevel) {
|
||||||
|
fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
|
||||||
|
}
|
||||||
|
do_interrupt(intno, 0, 0, 0);
|
||||||
|
env->interrupt_request &= ~CPU_INTERRUPT_HARD;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (interrupt_request & CPU_INTERRUPT_EXIT) {
|
||||||
|
env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
|
||||||
|
env->exception_index = EXCP_INTERRUPT;
|
||||||
|
cpu_loop_exit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_EXEC
|
#ifdef DEBUG_EXEC
|
||||||
if (loglevel) {
|
if (loglevel) {
|
||||||
@ -212,7 +215,7 @@ int cpu_exec(CPUState *env1)
|
|||||||
env->regs[R_EBP] = EBP;
|
env->regs[R_EBP] = EBP;
|
||||||
env->regs[R_ESP] = ESP;
|
env->regs[R_ESP] = ESP;
|
||||||
env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
|
env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
|
||||||
cpu_x86_dump_state(env, logfile, 0);
|
cpu_x86_dump_state(env, logfile, X86_DUMP_CCOP);
|
||||||
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
|
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
|
||||||
#elif defined(TARGET_ARM)
|
#elif defined(TARGET_ARM)
|
||||||
cpu_arm_dump_state(env, logfile, 0);
|
cpu_arm_dump_state(env, logfile, 0);
|
||||||
@ -454,7 +457,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
|
|||||||
{
|
{
|
||||||
TranslationBlock *tb;
|
TranslationBlock *tb;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (cpu_single_env)
|
if (cpu_single_env)
|
||||||
env = cpu_single_env; /* XXX: find a correct solution for multithread */
|
env = cpu_single_env; /* XXX: find a correct solution for multithread */
|
||||||
#if defined(DEBUG_SIGNAL)
|
#if defined(DEBUG_SIGNAL)
|
||||||
|
@ -254,10 +254,7 @@ typedef struct CPUX86State {
|
|||||||
struct TranslationBlock *current_tb; /* currently executing TB */
|
struct TranslationBlock *current_tb; /* currently executing TB */
|
||||||
uint32_t cr[5]; /* NOTE: cr1 is unused */
|
uint32_t cr[5]; /* NOTE: cr1 is unused */
|
||||||
uint32_t dr[8]; /* debug registers */
|
uint32_t dr[8]; /* debug registers */
|
||||||
int interrupt_request; /* if true, will exit from cpu_exec() ASAP */
|
int interrupt_request;
|
||||||
/* if true, will call cpu_x86_get_pic_interrupt() ASAP to get the
|
|
||||||
request interrupt number */
|
|
||||||
int hard_interrupt_request;
|
|
||||||
int user_mode_only; /* user mode only simulation */
|
int user_mode_only; /* user mode only simulation */
|
||||||
|
|
||||||
/* user data */
|
/* user data */
|
||||||
@ -275,7 +272,6 @@ int cpu_x86_inl(CPUX86State *env, int addr);
|
|||||||
|
|
||||||
CPUX86State *cpu_x86_init(void);
|
CPUX86State *cpu_x86_init(void);
|
||||||
int cpu_x86_exec(CPUX86State *s);
|
int cpu_x86_exec(CPUX86State *s);
|
||||||
void cpu_x86_interrupt(CPUX86State *s);
|
|
||||||
void cpu_x86_close(CPUX86State *s);
|
void cpu_x86_close(CPUX86State *s);
|
||||||
int cpu_x86_get_pic_interrupt(CPUX86State *s);
|
int cpu_x86_get_pic_interrupt(CPUX86State *s);
|
||||||
|
|
||||||
|
7
exec.c
7
exec.c
@ -617,11 +617,12 @@ static void tb_reset_jump_recursive(TranslationBlock *tb)
|
|||||||
tb_reset_jump_recursive2(tb, 1);
|
tb_reset_jump_recursive2(tb, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_interrupt(CPUState *env)
|
/* mask must never be zero */
|
||||||
|
void cpu_interrupt(CPUState *env, int mask)
|
||||||
{
|
{
|
||||||
TranslationBlock *tb;
|
TranslationBlock *tb;
|
||||||
|
|
||||||
env->interrupt_request = 1;
|
env->interrupt_request |= mask;
|
||||||
/* if the cpu is currently executing code, we must unlink it and
|
/* if the cpu is currently executing code, we must unlink it and
|
||||||
all the potentially executing TB */
|
all the potentially executing TB */
|
||||||
tb = env->current_tb;
|
tb = env->current_tb;
|
||||||
|
@ -333,7 +333,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
|
|||||||
host_to_target_siginfo_noswap(&tinfo, info);
|
host_to_target_siginfo_noswap(&tinfo, info);
|
||||||
if (queue_signal(sig, &tinfo) == 1) {
|
if (queue_signal(sig, &tinfo) == 1) {
|
||||||
/* interrupt the virtual CPU as soon as possible */
|
/* interrupt the virtual CPU as soon as possible */
|
||||||
cpu_interrupt(global_env);
|
cpu_interrupt(global_env, CPU_INTERRUPT_EXIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3331,12 +3331,14 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
|||||||
if (!s->vm86) {
|
if (!s->vm86) {
|
||||||
if (s->cpl <= s->iopl) {
|
if (s->cpl <= s->iopl) {
|
||||||
gen_op_sti();
|
gen_op_sti();
|
||||||
|
s->is_jmp = 2; /* give a chance to handle pending irqs */
|
||||||
} else {
|
} else {
|
||||||
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
|
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (s->iopl == 3) {
|
if (s->iopl == 3) {
|
||||||
gen_op_sti();
|
gen_op_sti();
|
||||||
|
s->is_jmp = 2; /* give a chance to handle pending irqs */
|
||||||
} else {
|
} else {
|
||||||
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
|
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user