VirtualBox

Changeset 1588 in vbox for trunk/src


Ignore:
Timestamp:
Mar 20, 2007 11:10:58 PM (18 years ago)
Author:
vboxsync
Message:

Merged in http://linserv/vbox/changeset?old_path=trunk%2Fsrc%2Frecompiler&old=18834&new_path=trunk%2Fsrc%2Frecompiler&new=19696

Location:
trunk/src/recompiler/new
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/recompiler/new/VBoxRecompiler.c

    r1200 r1588  
    171171    remR3HandlerWriteU32
    172172};
    173 
    174 
    175 #if 0 /* exec.c:99 */
    176 /*
    177  * Instance stuff.
    178  */
    179 /** Pointer to the cpu state. */
    180 CPUState       *cpu_single_env;
    181 #endif
    182173
    183174
     
    12101201        if (!(env->eflags & IF_MASK))
    12111202        {
    1212 #ifdef VBOX_RAW_V86
    1213             if(!(fFlags & VM_MASK))
    1214                 return false;
    1215 #else
    12161203            STAM_COUNTER_INC(&gStatRefuseIF0);
    12171204            Log2(("raw mode refused: IF (RawR3)\n"));
    12181205            return false;
    1219 #endif
    12201206        }
    12211207
     
    20282014        Log2(("REMR3State: trap=%02x errcd=%VGv cr2=%VGv nexteip=%VGv%s\n", pVM->rem.s.Env.exception_index, pVM->rem.s.Env.error_code,
    20292015              pVM->rem.s.Env.cr[2], pVM->rem.s.Env.exception_next_eip, pVM->rem.s.Env.exception_is_int ? " software" : ""));
    2030 //if (pVM->rem.s.Env.eip == 0x40005a2f)
    2031 //    pVM->rem.s.Env.state |= CPU_EMULATE_SINGLE_STEP | CPU_RAW_MODE_DISABLED | CPU_RAWR0_MODE_DISABLED;
    20322016    }
    20332017
     
    27652749        &&  off < PGM_DYNAMIC_CHUNK_SIZE)
    27662750    {
    2767         Log(("remR3HCVirt2GCPhys %x -> %x\n", addr, pVM->rem.s.paHCVirtToGCPhys[idx].GCPhys1 + off));
     2751        Log2(("remR3HCVirt2GCPhys %x -> %x\n", addr, pVM->rem.s.paHCVirtToGCPhys[idx].GCPhys1 + off));
    27682752        return pVM->rem.s.paHCVirtToGCPhys[idx].GCPhys1 + off;
    27692753    }
     
    27732757        &&  off < PGM_DYNAMIC_CHUNK_SIZE)
    27742758    {
    2775         Log(("remR3HCVirt2GCPhys %x -> %x\n", addr, pVM->rem.s.paHCVirtToGCPhys[idx].GCPhys2 + off));
     2759        Log2(("remR3HCVirt2GCPhys %x -> %x\n", addr, pVM->rem.s.paHCVirtToGCPhys[idx].GCPhys2 + off));
    27762760        return pVM->rem.s.paHCVirtToGCPhys[idx].GCPhys2 + off;
    27772761    }
     
    27832767        if (off < pVM->rem.s.aPhysReg[i].cb)
    27842768        {
    2785             Log(("remR3HCVirt2GCPhys %x -> %x\n", addr, pVM->rem.s.aPhysReg[i].GCPhys + off));
     2769            Log2(("remR3HCVirt2GCPhys %x -> %x\n", addr, pVM->rem.s.aPhysReg[i].GCPhys + off));
    27862770            return pVM->rem.s.aPhysReg[i].GCPhys + off;
    27872771        }
  • trunk/src/recompiler/new/cpu-exec.c

    r644 r1588  
    498498                        if(env->eflags & VM_MASK)
    499499                        {
    500                             Log(("EMV86: %08X IF=%d TF=%d CPL=%d CR0=%08X\n", env->eip, (env->eflags & IF_MASK) ? 1 : 0, (env->eflags & TF_MASK) ? 1 : 0, (env->hflags >> HF_CPL_SHIFT) & 3, env->cr[0]));
     500                            Log(("EMV86: %04X:%04X IF=%d TF=%d CPL=%d CR0=%08X\n", env->segs[R_CS].selector, env->eip, (env->eflags & IF_MASK) ? 1 : 0, (env->eflags & TF_MASK) ? 1 : 0, (env->hflags >> HF_CPL_SHIFT) & 3, env->cr[0]));
    501501                        }
    502502                        else
  • trunk/src/recompiler/new/target-i386/exec.h

    r644 r1588  
    182182void OPPROTO op_movl_eflags_T0(void);
    183183void OPPROTO op_movl_T0_eflags(void);
     184#ifdef VBOX
     185void OPPROTO op_movl_T0_eflags_vme(void);
     186void OPPROTO op_movw_eflags_T0_vme(void);
     187void OPPROTO op_cli_vme(void);
     188void OPPROTO op_sti_vme(void);
     189#endif
    184190void helper_divl_EAX_T0(void);
    185191void helper_idivl_EAX_T0(void);
  • trunk/src/recompiler/new/target-i386/helper.c

    r1094 r1588  
    816816    env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
    817817}
     818
     819#ifdef VBOX
     820
     821/* check if VME interrupt redirection is enabled in TSS */
     822static inline bool is_vme_irq_redirected(int intno)
     823{
     824    int io_offset, intredir_offset;
     825    unsigned char val, mask;
     826   
     827    /* TSS must be a valid 32 bit one */
     828    if (!(env->tr.flags & DESC_P_MASK) ||
     829        ((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 ||
     830        env->tr.limit < 103)
     831        goto fail;
     832    io_offset = lduw_kernel(env->tr.base + 0x66);
     833    /* the virtual interrupt redirection bitmap is located below the io bitmap */
     834    intredir_offset = io_offset - 0x20;
     835   
     836    intredir_offset += (intno >> 3);
     837    if ((intredir_offset) > env->tr.limit)
     838        goto fail;
     839
     840    val = ldub_kernel(env->tr.base + intredir_offset);
     841    mask = 1 << (unsigned char)(intno & 7);
     842
     843    /* bit set means no redirection. */
     844    if ((val & mask) != 0) {
     845        return false;
     846    }
     847    return true;
     848
     849fail:
     850    raise_exception_err(EXCP0D_GPF, 0);
     851    return true;
     852}
     853
     854/* V86 mode software interrupt with CR4.VME=1 */
     855static void do_soft_interrupt_vme(int intno, int error_code, unsigned int next_eip)
     856{
     857    target_ulong ptr, ssp;
     858    int selector;
     859    uint32_t offset, esp;
     860    uint32_t old_cs, old_eflags;
     861    uint32_t iopl;
     862
     863    iopl = ((env->eflags >> IOPL_SHIFT) & 3);
     864
     865    if (!is_vme_irq_redirected(intno))
     866    {
     867        if (iopl == 3)
     868            /* normal protected mode handler call */
     869            return do_interrupt_protected(intno, 1, error_code, next_eip, 0);
     870        else
     871            raise_exception_err(EXCP0D_GPF, 0);
     872    }
     873
     874    /* virtual mode idt is at linear address 0 */
     875    ptr = 0 + intno * 4;
     876    offset = lduw_kernel(ptr);
     877    selector = lduw_kernel(ptr + 2);
     878    esp = ESP;
     879    ssp = env->segs[R_SS].base;
     880    old_cs = env->segs[R_CS].selector;
     881
     882    old_eflags = compute_eflags();
     883    if (iopl < 3)
     884    {
     885        /* copy VIF into IF and set IOPL to 3 */
     886        if (env->eflags & VIF_MASK)
     887            old_eflags |= IF_MASK;
     888        else
     889            old_eflags &= ~IF_MASK;
     890
     891        old_eflags |= (3 << IOPL_SHIFT);
     892    }
     893
     894    /* XXX: use SS segment size ? */
     895    PUSHW(ssp, esp, 0xffff, old_eflags);
     896    PUSHW(ssp, esp, 0xffff, old_cs);
     897    PUSHW(ssp, esp, 0xffff, next_eip);
     898   
     899    /* update processor state */
     900    ESP = (ESP & ~0xffff) | (esp & 0xffff);
     901    env->eip = offset;
     902    env->segs[R_CS].selector = selector;
     903    env->segs[R_CS].base = (selector << 4);
     904    env->eflags &= ~(TF_MASK | RF_MASK);
     905
     906    if (iopl < 3)
     907        env->eflags &= ~IF_MASK;
     908    else
     909        env->eflags &= ~VIF_MASK;
     910}
     911#endif /* VBOX */
    818912
    819913#ifdef TARGET_X86_64
     
    12451339#endif
    12461340        {
    1247             do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw);
     1341#ifdef VBOX
     1342            /* int xx *, v86 code and VME enabled? */
     1343            if (    (env->eflags & VM_MASK)
     1344                &&  (env->cr[4] & CR4_VME_MASK)
     1345                &&  is_int
     1346                &&  !is_hw
     1347                &&  env->eip + 1 != next_eip /* single byte int 3 goes straight to the protected mode handler */
     1348               )
     1349                do_soft_interrupt_vme(intno, error_code, next_eip);
     1350            else
     1351#endif /* VBOX */
     1352                do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw);
    12481353        }
    12491354    } else {
     
    23562461    target_ulong ssp;
    23572462    int eflags_mask;
    2358 
    23592463#ifdef VBOX
     2464    bool fVME = false;
     2465
    23602466    remR3TrapClear(env->pVM);
    2361 #endif
     2467#endif /* VBOX */
    23622468
    23632469    sp_mask = 0xffff; /* XXXX: use SS segment size ? */
     
    23762482        POPW(ssp, sp, sp_mask, new_eflags);
    23772483    }
     2484#ifdef VBOX
     2485    if (    (env->eflags & VM_MASK)
     2486        &&  ((env->eflags >> IOPL_SHIFT) & 3) != 3
     2487        &&  (env->cr[4] & CR4_VME_MASK)) /* implied or else we would fault earlier */
     2488    {
     2489        fVME = true;
     2490        /* if virtual interrupt pending and (virtual) interrupts will be enabled -> #GP */
     2491        /* if TF will be set -> #GP */
     2492        if (    ((new_eflags & IF_MASK) && (env->eflags & VIP_MASK))
     2493            ||  (new_eflags & TF_MASK))
     2494            raise_exception(EXCP0D_GPF);
     2495    }
     2496#endif /* VBOX */
     2497
    23782498    ESP = (ESP & ~sp_mask) | (sp & sp_mask);
    23792499    load_seg_vm(R_CS, new_cs);
    23802500    env->eip = new_eip;
     2501#ifdef VBOX
     2502    if (fVME)
     2503        eflags_mask = TF_MASK | AC_MASK | ID_MASK | RF_MASK | NT_MASK;
     2504    else
     2505#endif
    23812506    if (env->eflags & VM_MASK)
    23822507        eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | RF_MASK | NT_MASK;
     
    23862511        eflags_mask &= 0xffff;
    23872512    load_eflags(new_eflags, eflags_mask);
     2513
     2514#ifdef VBOX
     2515    if (fVME)
     2516    {
     2517        if (new_eflags & IF_MASK)
     2518            env->eflags |= VIF_MASK;
     2519        else
     2520            env->eflags &= ~VIF_MASK;
     2521    }
     2522#endif /* VBOX */
    23882523}
    23892524
     
    26212756        eflags_mask = TF_MASK | AC_MASK | ID_MASK | RF_MASK | NT_MASK;
    26222757        if (cpl == 0)
     2758#ifdef VBOX
     2759            eflags_mask |= IOPL_MASK | VIF_MASK | VIP_MASK;
     2760#else
    26232761            eflags_mask |= IOPL_MASK;
     2762#endif
    26242763        iopl = (env->eflags >> IOPL_SHIFT) & 3;
    26252764        if (cpl <= iopl)
  • trunk/src/recompiler/new/target-i386/op.c

    r644 r1588  
    492492    uint32_t idx = (PARAM1 - offsetof(CPUX86State,segs[0].base)) / sizeof(SegmentCache);
    493493
    494     if (env->segs[idx].newselector && !(env->eflags & VM_MASK))
     494    if (env->segs[idx].newselector && !(env->eflags & VM_MASK)) {
    495495        sync_seg(env, idx, env->segs[idx].newselector);
     496    }
     497    /* Loading a null selector into a segment register is valid, but using it is most definitely not! */
     498    if (    (env->cr[0] & (CR0_PE_MASK|CR0_PG_MASK)) == (CR0_PE_MASK|CR0_PG_MASK)
     499        &&  !(env->eflags & VM_MASK)
     500        &&  env->segs[idx].selector == 0) {
     501        raise_exception(EXCP0D_GPF);
     502    }
    496503    A0 = (uint32_t)env->segs[idx].base;
     504    FORCE_RET();
    497505#else  /* !VBOX */
    498506    A0 = (uint32_t)*(target_ulong *)((char *)env + PARAM1);
     
    505513    uint32_t idx = (PARAM1 - offsetof(CPUX86State,segs[0].base)) / sizeof(SegmentCache);
    506514
    507     if (env->segs[idx].newselector && !(env->eflags & VM_MASK))
     515    if (env->segs[idx].newselector && !(env->eflags & VM_MASK)) {
    508516        sync_seg(env, idx, env->segs[idx].newselector);
     517    }
     518    /* Loading a null selector into a segment register is valid, but using it is most definitely not! */
     519    if (    (env->cr[0] & (CR0_PE_MASK|CR0_PG_MASK)) == (CR0_PE_MASK|CR0_PG_MASK)
     520        &&  !(env->eflags & VM_MASK)
     521        &&  env->segs[idx].selector == 0) {
     522        raise_exception(EXCP0D_GPF);
     523    }
    509524    A0 = (uint32_t)(A0 + env->segs[idx].base);
     525    FORCE_RET();
    510526#else  /* !VBOX */
    511527    A0 = (uint32_t)(A0 + *(target_ulong *)((char *)env + PARAM1));
     
    718734}
    719735
     736#ifndef VBOX
    720737#if 0
    721738/* vm86plus instructions */
     
    735752}
    736753#endif
     754
     755#else /* VBOX */
     756void OPPROTO op_cli_vme(void)
     757{
     758    env->eflags &= ~VIF_MASK;
     759}
     760
     761void OPPROTO op_sti_vme(void)
     762{
     763    /* First check, then change eflags according to the AMD manual */
     764    if (env->eflags & VIP_MASK) {
     765        raise_exception(EXCP0D_GPF);
     766    }
     767    env->eflags |= VIF_MASK;
     768    FORCE_RET();
     769}
     770#endif /* VBOX */
    737771
    738772void OPPROTO op_boundw(void)
     
    14651499
    14661500/* XXX: clear VIF/VIP in all ops ? */
     1501#ifdef VBOX
     1502/* XXX: AMD docs say they remain unchanged. */
     1503#endif
    14671504
    14681505void OPPROTO op_movl_eflags_T0(void)
     
    14961533}
    14971534
     1535#ifndef VBOX
    14981536#if 0
    14991537/* vm86plus version */
     
    15371575#endif
    15381576
     1577#else /* VBOX */
     1578/* IOPL != 3, CR4.VME=1 */
     1579void OPPROTO op_movw_eflags_T0_vme(void)
     1580{
     1581    unsigned int new_eflags = T0;
     1582
     1583    /* if virtual interrupt pending and (virtual) interrupts will be enabled -> #GP */
     1584    /* if TF will be set -> #GP */
     1585    if (    ((new_eflags & IF_MASK) && (env->eflags & VIP_MASK))
     1586        ||  (new_eflags & TF_MASK)) {
     1587        raise_exception(EXCP0D_GPF);
     1588    } else {
     1589        load_eflags(new_eflags, (TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff);
     1590
     1591        if (new_eflags & IF_MASK) {
     1592            env->eflags |= VIF_MASK;
     1593        } else {
     1594            env->eflags &= ~VIF_MASK;
     1595        }
     1596    }
     1597
     1598    FORCE_RET();
     1599}
     1600#endif /* VBOX */
     1601
    15391602/* XXX: compute only O flag */
    15401603void OPPROTO op_movb_eflags_T0(void)
     
    15551618
    15561619/* vm86plus version */
    1557 #if 0
    1558 void OPPROTO op_movl_T0_eflags_vm(void)
     1620#ifdef VBOX /* #if 0 */
     1621void OPPROTO op_movl_T0_eflags_vme(void)
    15591622{
    15601623    int eflags;
     
    15661629    T0 = eflags;
    15671630}
    1568 #endif
     1631#endif /* VBOX / 0 */
    15691632
    15701633void OPPROTO op_cld(void)
  • trunk/src/recompiler/new/target-i386/translate.c

    r644 r1588  
    121121    int f_st;   /* currently unused */
    122122    int vm86;   /* vm86 mode */
     123#ifdef VBOX
     124    int vme;    /* CR4.VME */
     125#endif
    123126    int cpl;
    124127    int iopl;
     
    832835    gen_op_check_external_event();
    833836}
     837
     838static inline void gen_update_eip(target_ulong pc)
     839{
     840#ifdef TARGET_X86_64
     841    if (pc == (uint32_t)pc) {
     842        gen_op_movl_eip_im(pc);
     843    } else if (pc == (int32_t)pc) {
     844        gen_op_movq_eip_im(pc);
     845    } else {
     846        gen_op_movq_eip_im64(pc >> 32, pc);
     847    }
     848#else
     849    gen_op_movl_eip_im(pc);
     850#endif
     851}
     852
    834853#endif /* VBOX */
    835854
     
    32153234#endif
    32163235    s->rip_offset = 0; /* for relative ip address */
     3236
     3237#ifdef VBOX
     3238    /* Always update EIP. Otherwise one must be very careful with generated code that can raise exceptions. */
     3239    gen_update_eip(pc_start - s->cs_base);
     3240#endif
     3241
    32173242 next_byte:
    32183243    b = ldub_code(s->pc);
     
    50605085            s->cc_op = CC_OP_EFLAGS;
    50615086        } else if (s->vm86) {
     5087#ifdef VBOX
     5088            if (s->iopl != 3 && (!s->vme || s->dflag)) {
     5089#else
    50625090            if (s->iopl != 3) {
     5091#endif
    50635092                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
    50645093            } else {
     
    51765205        /* flags */
    51775206    case 0x9c: /* pushf */
     5207#ifdef VBOX
     5208        if (s->vm86 && s->iopl != 3 && (!s->vme || s->dflag)) {
     5209#else
    51785210        if (s->vm86 && s->iopl != 3) {
     5211#endif
    51795212            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
    51805213        } else {
    51815214            if (s->cc_op != CC_OP_DYNAMIC)
    51825215                gen_op_set_cc_op(s->cc_op);
    5183             gen_op_movl_T0_eflags();
     5216#ifdef VBOX
     5217            if (s->vm86 && s->vme && s->iopl != 3)
     5218                gen_op_movl_T0_eflags_vme();
     5219            else
     5220#endif
     5221                gen_op_movl_T0_eflags();
    51845222            gen_push_T0(s);
    51855223        }
    51865224        break;
    51875225    case 0x9d: /* popf */
     5226#ifdef VBOX
     5227        if (s->vm86 && s->iopl != 3 && (!s->vme || s->dflag)) {
     5228#else
    51885229        if (s->vm86 && s->iopl != 3) {
     5230#endif
    51895231            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
    51905232        } else {
     
    52075249                        gen_op_movl_eflags_T0();
    52085250                    } else {
    5209                         gen_op_movw_eflags_T0();
     5251#ifdef VBOX
     5252                        if (s->vm86 && s->vme)
     5253                            gen_op_movw_eflags_T0_vme();
     5254                        else
     5255#endif
     5256                            gen_op_movw_eflags_T0();
    52105257                    }
    52115258                }
     
    54085455        break;
    54095456    case 0xcc: /* int3 */
    5410         gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
     5457#ifdef VBOX
     5458        if (s->vm86 && s->iopl != 3 && !s->vme) {
     5459            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
     5460        } else
     5461#endif
     5462            gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
    54115463        break;
    54125464    case 0xcd: /* int N */
    54135465        val = ldub_code(s->pc++);
     5466#ifdef VBOX
     5467        if (s->vm86 && s->iopl != 3 && !s->vme) {
     5468#else
    54145469        if (s->vm86 && s->iopl != 3) {
     5470#endif
    54155471            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
    54165472        } else {
     
    54455501            if (s->iopl == 3) {
    54465502                gen_op_cli();
     5503#ifdef VBOX
     5504            } else if (s->iopl != 3 && s->vme) {
     5505                gen_op_cli_vme();
     5506#endif
    54475507            } else {
    54485508                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
     
    54695529            if (s->iopl == 3) {
    54705530                goto gen_sti;
     5531#ifdef VBOX
     5532            } else if (s->iopl != 3 && s->vme) {
     5533                gen_op_sti_vme();
     5534                /* give a chance to handle pending irqs */
     5535                gen_jmp_im(s->pc - s->cs_base);
     5536                gen_eob(s);
     5537#endif
    54715538            } else {
    54725539                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
     
    65256592    dc->f_st = 0;
    65266593    dc->vm86 = (flags >> VM_SHIFT) & 1;
     6594#ifdef VBOX
     6595    dc->vme = !!(env->cr[4] & CR4_VME_MASK);
     6596#endif
    65276597    dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
    65286598    dc->iopl = (flags >> IOPL_SHIFT) & 3;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette