VirtualBox

Changeset 20343 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Jun 5, 2009 3:41:18 PM (16 years ago)
Author:
vboxsync
Message:

TPR emulation updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp

    r20330 r20343  
    17051705            &&  pVM->hwaccm.s.fHasIoApic
    17061706            &&  !(errCode & X86_TRAP_PF_P)  /* not present */
     1707            &&  CPUMGetGuestCPL(pVCpu, CPUMCTX2CORE(pCtx)) == 0
    17071708            &&  !CPUMIsGuestInLongModeEx(pCtx))
    17081709        {
     
    23342335}
    23352336
     2337/**
     2338 * Emulate simple mov tpr instruction
     2339 *
     2340 * @returns VBox status code.
     2341 * @param   pVCpu       The VM CPU to operate on.
     2342 * @param   pDisState   Disassembly state
     2343 * @param   pCtx        CPU context
     2344 * @param   cbOp        Opcode size
     2345 */
     2346static int svmR0EmulateTprMov(PVMCPU pVCpu, DISCPUSTATE *pDisState, PCPUMCTX pCtx, unsigned cbOp)
     2347{
     2348    int rc;
     2349
     2350    if (pDisState->param1.flags == USE_DISPLACEMENT32)
     2351    {
     2352        /* write */
     2353        uint8_t u8Tpr;
     2354
     2355        /* Fetch the new TPR value */
     2356        if (pDisState->param2.flags == USE_REG_GEN32)
     2357        {
     2358            uint32_t val;
     2359
     2360            rc = DISFetchReg32(CPUMCTX2CORE(pCtx), pDisState->param2.base.reg_gen, &val);
     2361            AssertRC(rc);
     2362            u8Tpr = val >> 4;
     2363        }
     2364        else
     2365        if (pDisState->param2.flags == USE_IMMEDIATE32)
     2366        {
     2367            u8Tpr = (uint8_t)pDisState->param2.parval >> 4;
     2368        }
     2369        else
     2370            return VERR_EM_INTERPRETER;
     2371
     2372        rc = PDMApicSetTPR(pVCpu, u8Tpr);
     2373        AssertRC(rc);
     2374
     2375        pCtx->rip += cbOp;
     2376        return VINF_SUCCESS;
     2377    }
     2378    else
     2379    if (pDisState->param2.flags == USE_DISPLACEMENT32)
     2380    {
     2381        /* read */
     2382        bool    fPending;
     2383        uint8_t u8Tpr;
     2384
     2385        /* TPR caching in CR8 */
     2386        rc = PDMApicGetTPR(pVCpu, &u8Tpr, &fPending);
     2387        AssertRC(rc);
     2388
     2389        rc = DISWriteReg32(CPUMCTX2CORE(pCtx), pDisState->param1.base.reg_gen, u8Tpr << 4);
     2390        AssertRC(rc);
     2391
     2392        pCtx->rip += cbOp;
     2393        return VINF_SUCCESS;
     2394    }
     2395    return VERR_EM_INTERPRETER;
     2396}
    23362397
    23372398/**
     
    23552416        &&  Cpu.pCurInstr->opcode == OP_MOV)
    23562417    {
     2418        rc = svmR0EmulateTprMov(pVCpu, &Cpu, pCtx, cbOp);
     2419        if (rc != VINF_SUCCESS)
     2420            return rc;
     2421
    23572422        uint8_t szInstr[15];
    23582423        if (    cbOp == 10
     
    23692434             *
    23702435             */
    2371             RTGCPTR     oldEip = pCtx->eip;
    23722436            uint32_t    u32tpr = (uint32_t)Cpu.param2.parval;
    23732437
     
    23772441             * it does, then we can safely use it ourselves.
    23782442             */
    2379             pCtx->eip += cbOp;
    23802443            rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), &Cpu, &cbOp);
    2381             pCtx->eip = oldEip;
    23822444            if (    rc == VINF_SUCCESS
    23832445                &&  Cpu.pCurInstr->opcode == OP_MOV
     
    24102472                &&  cbOp == 6)
    24112473            {
    2412                 RTGCPTR  oldEip   = pCtx->eip;
    24132474                RTGCPTR  GCPtrTpr = (uint32_t)Cpu.param1.disp32;
    24142475                uint32_t uMmioReg = Cpu.param2.base.reg_gen;
     
    24192480                 *   mov ecx, dword [fffe0080]        (5 bytes)
    24202481                 */
    2421                 pCtx->eip += cbOp;
    24222482                rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), &Cpu, &cbOp);
    2423                 pCtx->eip = oldEip;
    24242483                if (    rc == VINF_SUCCESS
    24252484                    &&  Cpu.pCurInstr->opcode == OP_MOV
     
    24532512                    AssertRC(rc);
    24542513
    2455                     Log(("Acceptable write candidate!\n"));
     2514                    Log(("Acceptable read/write candidate!\n"));
    24562515                    return VINF_SUCCESS;
    24572516                }
     
    24612520                &&  cbOp == 5)
    24622521            {
    2463                 RTGCPTR  oldEip = pCtx->eip;
    24642522                uint32_t uMmioReg = Cpu.param1.base.reg_gen;
    24652523
     
    24692527                 *   shr eax, 4
    24702528                 */
    2471                 pCtx->eip += cbOp;
    24722529                rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), &Cpu, &cbOp);
    2473                 pCtx->eip = oldEip;
    24742530                if (    rc == VINF_SUCCESS
    24752531                    &&  Cpu.pCurInstr->opcode == OP_SHR
     
    24952551            }
    24962552        }
     2553        /* Emulated successfully, so continue. */
     2554        return VINF_SUCCESS;
    24972555    }
    24982556    return VERR_ACCESS_DENIED;
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