enum vmmerr cpu_emul_realmode_int (u8 num) { u16 seg, off; ulong rflags, rip; u16 cs; ulong idtr_base, idtr_limit; struct cpu_stack st; /* FIXME: IDTR LIMIT CHECK */ /* FIXME: stack limit check */ current->vmctl.read_idtr (&idtr_base, &idtr_limit); RIE (read_linearaddr_w (idtr_base + ((u32)num << 2) + 0, &off)); RIE (read_linearaddr_w (idtr_base + ((u32)num << 2) + 2, &seg)); current->vmctl.read_flags (&rflags); current->vmctl.read_sreg_sel (SREG_CS, &cs); current->vmctl.read_ip (&rip); RIE (cpu_stack_get (&st)); RIE (cpu_stack_push (&st, &rflags, OPTYPE_16BIT)); RIE (cpu_stack_push (&st, &cs, OPTYPE_16BIT)); RIE (cpu_stack_push (&st, &rip, OPTYPE_16BIT)); current->vmctl.write_realmode_seg (SREG_CS, seg); current->vmctl.write_ip (off); rflags &= ~(RFLAGS_TF_BIT | RFLAGS_AC_BIT); current->vmctl.write_flags (rflags); RIE (cpu_stack_set (&st)); cpu_emul_cli (); return VMMERR_SUCCESS; }
enum vmmerr cpu_emul_realmode_int (u8 num) { u16 seg, off; ulong rflags, rip; u16 cs; ulong idtr_base, idtr_limit; struct cpu_stack st; /* FIXME: IDTR LIMIT CHECK */ /* FIXME: stack limit check */ current->vmctl.read_idtr (&idtr_base, &idtr_limit); RIE (read_linearaddr_w (idtr_base + ((u32)num << 2) + 0, &off)); RIE (read_linearaddr_w (idtr_base + ((u32)num << 2) + 2, &seg)); current->vmctl.read_flags (&rflags); current->vmctl.read_sreg_sel (SREG_CS, &cs); current->vmctl.read_ip (&rip); #ifdef DISABLE_TCG_BIOS if (num == 0x1A) { ulong rax; current->vmctl.read_general_reg (GENERAL_REG_RAX, &rax); rax &= 0xFFFF; if (rax == 0xBB00) { /* TCG_StatusCheck function */ current->vmctl.write_flags (rflags | RFLAGS_CF_BIT); return VMMERR_SUCCESS; } } #endif /* DISABLE_TCG_BIOS */ RIE (cpu_stack_get (&st)); RIE (cpu_stack_push (&st, &rflags, OPTYPE_16BIT)); RIE (cpu_stack_push (&st, &cs, OPTYPE_16BIT)); RIE (cpu_stack_push (&st, &rip, OPTYPE_16BIT)); current->vmctl.write_realmode_seg (SREG_CS, seg); current->vmctl.write_ip (off); rflags &= ~(RFLAGS_TF_BIT | RFLAGS_AC_BIT); current->vmctl.write_flags (rflags); RIE (cpu_stack_set (&st)); cpu_emul_cli (); return VMMERR_SUCCESS; }