VirtualBox

Changeset 42670 in vbox for trunk


Ignore:
Timestamp:
Aug 7, 2012 11:43:32 PM (12 years ago)
Author:
vboxsync
Message:

Fixed fnstcw. Implemented fnsave and frstor.

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r42662 r42670  
    50965096     * Check the input and figure out which mapping entry to use.
    50975097     */
    5098     Assert(cbMem <= 32 || cbMem == 512);
     5098    Assert(cbMem <= 32 || cbMem == 512 || cbMem == 108 || cbMem == 94);
    50995099    Assert(~(fAccess & ~(IEM_ACCESS_TYPE_MASK | IEM_ACCESS_WHAT_MASK)));
    51005100
     
    73967396#if 0 /* NT4SP1 - fnstsw + 2 (AMD). */
    73977397            || (pOrgCtx->cs.Sel == 8 && pOrgCtx->rip == 0x801c6b88+2)
     7398#endif
     7399#if 0 /* NT4SP1 - iret to v8086 -- too generic a place? (N/A with GAs installed) */
     7400            || (pOrgCtx->cs.Sel == 8 && pOrgCtx->rip == 0x8013bd5d)
     7401
     7402#endif
     7403#if 1 /* NT4SP1 - iret to v8086 (executing edlin) */
     7404            || (pOrgCtx->cs.Sel == 8 && pOrgCtx->rip == 0x8013b609)
     7405
     7406#endif
     7407#if 0 /* NT4SP1 - frstor [ecx] */
     7408            || (pOrgCtx->cs.Sel == 8 && pOrgCtx->rip == 0x8013d11f)
    73987409#endif
    73997410           )
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r42666 r42670  
    40654065        pCtx->fpu.FPUDP = 0;
    40664066        pCtx->fpu.DS    = 0; //??
     4067        pCtx->fpu.Rsrvd2= 0;
    40674068        pCtx->fpu.FPUIP = 0;
    40684069        pCtx->fpu.CS    = 0; //??
     4070        pCtx->fpu.Rsrvd1= 0;
    40694071        pCtx->fpu.FOP   = 0;
    40704072    }
     
    43734375            pCtx->fpu.FOP   = uPtr.pu16[4] & UINT16_C(0x07ff);
    43744376            pCtx->fpu.CS    = 0;
     4377            pCtx->fpu.Rsrvd1= 0;
    43754378            pCtx->fpu.DS    = 0;
     4379            pCtx->fpu.Rsrvd2= 0;
    43764380        }
    43774381        else
     
    43794383            pCtx->fpu.FPUIP = uPtr.pu16[3];
    43804384            pCtx->fpu.CS    = uPtr.pu16[4];
     4385            pCtx->fpu.Rsrvd1= 0;
    43814386            pCtx->fpu.FPUDP = uPtr.pu16[5];
    43824387            pCtx->fpu.DS    = uPtr.pu16[6];
     4388            pCtx->fpu.Rsrvd2= 0;
    43834389            /** @todo Testcase: Is FOP cleared when doing 16-bit protected mode fldenv? */
    43844390        }
     
    43954401            pCtx->fpu.FPUDP = uPtr.pu16[5*2] | ((uPtr.pu32[6] & UINT32_C(0x0ffff000)) << 4);
    43964402            pCtx->fpu.CS    = 0;
     4403            pCtx->fpu.Rsrvd1= 0;
    43974404            pCtx->fpu.DS    = 0;
     4405            pCtx->fpu.Rsrvd2= 0;
    43984406        }
    43994407        else
     
    44014409            pCtx->fpu.FPUIP = uPtr.pu32[3];
    44024410            pCtx->fpu.CS    = uPtr.pu16[4*2];
     4411            pCtx->fpu.Rsrvd1= 0;
    44034412            pCtx->fpu.FOP   = uPtr.pu16[4*2+1];
    44044413            pCtx->fpu.FPUDP = uPtr.pu32[5];
    44054414            pCtx->fpu.DS    = uPtr.pu16[6*2];
     4415            pCtx->fpu.Rsrvd2= 0;
    44064416        }
    44074417    }
     
    44454455
    44464456/**
     4457 * Implements 'FNSAVE'.
     4458 *
     4459 * @param   GCPtrEffDst     The address of the image.
     4460 * @param   enmEffOpSize    The operand size.
     4461 */
     4462IEM_CIMPL_DEF_3(iemCImpl_fnsave, IEMMODE, enmEffOpSize, uint8_t, iEffSeg, RTGCPTR, GCPtrEffDst)
     4463{
     4464    PCPUMCTX     pCtx = pIemCpu->CTX_SUFF(pCtx);
     4465    RTPTRUNION   uPtr;
     4466    VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu, &uPtr.pv, enmEffOpSize == IEMMODE_16BIT ? 94 : 108,
     4467                                      iEffSeg, GCPtrEffDst, IEM_ACCESS_DATA_W | IEM_ACCESS_PARTIAL_WRITE);
     4468    if (rcStrict != VINF_SUCCESS)
     4469        return rcStrict;
     4470
     4471    iemCImplCommonFpuStoreEnv(pIemCpu, enmEffOpSize, uPtr, pCtx);
     4472    PRTFLOAT80U paRegs = (PRTFLOAT80U)(uPtr.pu8 + (enmEffOpSize == IEMMODE_16BIT ? 14 : 28));
     4473    for (uint32_t i = 0; i < RT_ELEMENTS(pCtx->fpu.aRegs); i++)
     4474    {
     4475        paRegs[i].au32[0] = pCtx->fpu.aRegs[i].au32[0];
     4476        paRegs[i].au32[1] = pCtx->fpu.aRegs[i].au32[1];
     4477        paRegs[i].au16[4] = pCtx->fpu.aRegs[i].au16[4];
     4478    }
     4479
     4480    rcStrict = iemMemCommitAndUnmap(pIemCpu, uPtr.pv, IEM_ACCESS_DATA_W | IEM_ACCESS_PARTIAL_WRITE);
     4481    if (rcStrict != VINF_SUCCESS)
     4482        return rcStrict;
     4483
     4484    /*
     4485     * Re-initialize the FPU.
     4486     */
     4487    pCtx->fpu.FCW   = 0x37f;
     4488    pCtx->fpu.FSW   = 0;
     4489    pCtx->fpu.FTW   = 0xffff;       /* 11 - empty */
     4490    pCtx->fpu.FPUDP = 0;
     4491    pCtx->fpu.DS    = 0;
     4492    pCtx->fpu.Rsrvd2= 0;
     4493    pCtx->fpu.FPUIP = 0;
     4494    pCtx->fpu.CS    = 0;
     4495    pCtx->fpu.Rsrvd1= 0;
     4496    pCtx->fpu.FOP   = 0;
     4497
     4498
     4499    /* Note: C0, C1, C2 and C3 are documented as undefined, we leave them untouched! */
     4500    iemRegAddToRip(pIemCpu, cbInstr);
     4501    return VINF_SUCCESS;
     4502}
     4503
     4504
     4505
     4506/**
    44474507 * Implements 'FLDENV'.
    44484508 *
     
    44614521
    44624522    iemCImplCommonFpuRestoreEnv(pIemCpu, enmEffOpSize, uPtr, pCtx);
     4523
     4524    rcStrict = iemMemCommitAndUnmap(pIemCpu, (void *)uPtr.pv, IEM_ACCESS_DATA_R);
     4525    if (rcStrict != VINF_SUCCESS)
     4526        return rcStrict;
     4527
     4528    iemRegAddToRip(pIemCpu, cbInstr);
     4529    return VINF_SUCCESS;
     4530}
     4531
     4532
     4533/**
     4534 * Implements 'FRSTOR'.
     4535 *
     4536 * @param   GCPtrEffSrc     The address of the image.
     4537 * @param   enmEffOpSize    The operand size.
     4538 */
     4539IEM_CIMPL_DEF_3(iemCImpl_frstor, IEMMODE, enmEffOpSize, uint8_t, iEffSeg, RTGCPTR, GCPtrEffSrc)
     4540{
     4541    PCPUMCTX     pCtx = pIemCpu->CTX_SUFF(pCtx);
     4542    RTCPTRUNION  uPtr;
     4543    VBOXSTRICTRC rcStrict = iemMemMap(pIemCpu, (void **)&uPtr.pv, enmEffOpSize == IEMMODE_16BIT ? 94 : 108,
     4544                                      iEffSeg, GCPtrEffSrc, IEM_ACCESS_DATA_R);
     4545    if (rcStrict != VINF_SUCCESS)
     4546        return rcStrict;
     4547
     4548    iemCImplCommonFpuRestoreEnv(pIemCpu, enmEffOpSize, uPtr, pCtx);
     4549    PCRTFLOAT80U paRegs = (PCRTFLOAT80U)(uPtr.pu8 + (enmEffOpSize == IEMMODE_16BIT ? 14 : 28));
     4550    for (uint32_t i = 0; i < RT_ELEMENTS(pCtx->fpu.aRegs); i++)
     4551    {
     4552        pCtx->fpu.aRegs[i].au32[0] = paRegs[i].au32[0];
     4553        pCtx->fpu.aRegs[i].au32[1] = paRegs[i].au32[1];
     4554        pCtx->fpu.aRegs[i].au32[2] = paRegs[i].au16[4];
     4555        pCtx->fpu.aRegs[i].au32[3] = 0;
     4556    }
    44634557
    44644558    rcStrict = iemMemCommitAndUnmap(pIemCpu, (void *)uPtr.pv, IEM_ACCESS_DATA_R);
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r42660 r42670  
    1172311723FNIEMOP_DEF_1(iemOp_fnstenv, uint8_t, bRm)
    1172411724{
    11725     IEMOP_MNEMONIC("fstenv m14/28byte");
     11725    IEMOP_MNEMONIC("fstenv m14/m28byte");
    1172611726    IEM_MC_BEGIN(3, 0);
    1172711727    IEM_MC_ARG_CONST(IEMMODE,           enmEffOpSize, /*=*/ pIemCpu->enmEffOpSize,  0);
     
    1174711747    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    1174811748    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
    11749     IEM_MC_FETCH_FSW(u16Fcw);
     11749    IEM_MC_FETCH_FCW(u16Fcw);
    1175011750    IEM_MC_STORE_MEM_U16(pIemCpu->iEffSeg, GCPtrEffDst, u16Fcw);
    1175111751    IEM_MC_ADVANCE_RIP(); /* C0-C3 are documented as undefined, we leave them unmodified. */
     
    1354513545
    1354613546/** Opcode 0xdd !11/0. */
    13547 FNIEMOP_STUB_1(iemOp_frstor,      uint8_t, bRm);
     13547FNIEMOP_DEF_1(iemOp_frstor,      uint8_t, bRm)
     13548{
     13549    IEMOP_MNEMONIC("fxrstor m94/108byte");
     13550    IEM_MC_BEGIN(3, 0);
     13551    IEM_MC_ARG_CONST(IEMMODE,           enmEffOpSize, /*=*/ pIemCpu->enmEffOpSize,  0);
     13552    IEM_MC_ARG_CONST(uint8_t,           iEffSeg,      /*=*/ pIemCpu->iEffSeg,       1);
     13553    IEM_MC_ARG(RTGCPTR,                 GCPtrEffSrc,                                2);
     13554    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm);
     13555    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     13556    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     13557    IEM_MC_CALL_CIMPL_3(iemCImpl_frstor, enmEffOpSize, iEffSeg, GCPtrEffSrc);
     13558    IEM_MC_END();
     13559    return VINF_SUCCESS;
     13560}
     13561
    1354813562
    1354913563/** Opcode 0xdd !11/0. */
    13550 FNIEMOP_STUB_1(iemOp_fnsave,      uint8_t, bRm);
    13551 
     13564FNIEMOP_DEF_1(iemOp_fnsave,      uint8_t, bRm)
     13565{
     13566    IEMOP_MNEMONIC("fnsave m94/108byte");
     13567    IEM_MC_BEGIN(3, 0);
     13568    IEM_MC_ARG_CONST(IEMMODE,           enmEffOpSize, /*=*/ pIemCpu->enmEffOpSize,  0);
     13569    IEM_MC_ARG_CONST(uint8_t,           iEffSeg,      /*=*/ pIemCpu->iEffSeg,       1);
     13570    IEM_MC_ARG(RTGCPTR,                 GCPtrEffDst,                                2);
     13571    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm);
     13572    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     13573    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     13574    IEM_MC_CALL_CIMPL_3(iemCImpl_fnsave, enmEffOpSize, iEffSeg, GCPtrEffDst);
     13575    IEM_MC_END();
     13576    return VINF_SUCCESS;
     13577
     13578}
    1355213579
    1355313580/** Opcode 0xdd !11/0. */
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r42621 r42670  
    365365#define IEM_MC_FETCH_EFLAGS_U8(a_EFlags)                do { (a_EFlags) = 0; CHK_TYPE(uint8_t,  a_EFlags); } while (0)
    366366#define IEM_MC_FETCH_FSW(a_u16Fsw)                      do { (a_u16Fsw) = 0; CHK_TYPE(uint16_t, a_u16Fsw); } while (0)
     367#define IEM_MC_FETCH_FCW(a_u16Fcw)                      do { (a_u16Fcw) = 0; CHK_TYPE(uint16_t, a_u16Fcw); } while (0)
    367368#define IEM_MC_STORE_GREG_U8(a_iGReg, a_u8Value)        do { CHK_TYPE(uint8_t, a_u8Value); } while (0)
    368369#define IEM_MC_STORE_GREG_U16(a_iGReg, a_u16Value)      do { CHK_TYPE(uint16_t, a_u16Value); } while (0)
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