VirtualBox

Changeset 60874 in vbox for trunk/src/VBox/VMM/VMMRC


Ignore:
Timestamp:
May 7, 2016 5:55:21 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
107086
Message:

IOMRC.cpp,++: Use IEM for IN and OUT too, cleaning out unnecessary code.

Location:
trunk/src/VBox/VMM/VMMRC
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMRC/IOMRC.cpp

    r60847 r60874  
    4343
    4444
    45 #ifdef VBOX_WITH_3RD_IEM_STEP
    4645/**
    4746 * Converts disassembler mode to IEM mode.
     
    6160    }
    6261}
    63 #endif
    64 
    6562
    6663
     
    8582static VBOXSTRICTRC iomRCInterpretIN(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
    8683{
    87 #ifdef IN_RC
    8884    STAM_COUNTER_INC(&pVM->iom.s.StatInstIn);
    89 #endif
    90 
    91     /*
    92      * Get port number from second parameter.
    93      * And get the register size from the first parameter.
    94      */
    95     uint64_t    uPort = 0;
    96     unsigned    cbSize = 0;
    97     bool fRc = iomGetRegImmData(pCpu, &pCpu->Param2, pRegFrame, &uPort, &cbSize);
    98     AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc);
    99 
    100     cbSize = DISGetParamSize(pCpu, &pCpu->Param1);
    101     Assert(cbSize > 0);
    102     VBOXSTRICTRC rcStrict = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, uPort, cbSize);
    103     if (rcStrict == VINF_SUCCESS)
    104     {
    105         /*
    106          * Attempt to read the port.
    107          */
    108         uint32_t u32Data = UINT32_C(0xffffffff);
    109         rcStrict = IOMIOPortRead(pVM, pVCpu, uPort, &u32Data, cbSize);
    110         if (IOM_SUCCESS(rcStrict))
    111         {
    112             /*
    113              * Store the result in the AL|AX|EAX register.
    114              */
    115             fRc = iomSaveDataToReg(pCpu, &pCpu->Param1, pRegFrame, u32Data);
    116             AssertMsg(fRc, ("Failed to store register value!\n")); NOREF(fRc);
    117         }
    118         else
    119             AssertMsg(rcStrict == VINF_IOM_R3_IOPORT_READ || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    120     }
    121     else
    122         AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    123 
    124     return rcStrict;
     85    Assert(pCpu->Param2.fUse & (DISUSE_IMMEDIATE8 | DISUSE_REG_GEN16));
     86    uint16_t u16Port = pCpu->Param2.fUse & DISUSE_REG_GEN16 ? pRegFrame->dx : (uint16_t)pCpu->Param2.uValue;
     87
     88    Assert(pCpu->Param1.fUse & (DISUSE_REG_GEN32 | DISUSE_REG_GEN16 | DISUSE_REG_GEN8));
     89    uint8_t cbValue = pCpu->Param1.fUse & DISUSE_REG_GEN32 ? 4 : pCpu->Param1.fUse & DISUSE_REG_GEN16 ? 2 : 1;
     90
     91    return IEMExecDecodedIn(pVCpu, pCpu->cbInstr, u16Port, cbValue);
    12592}
    12693
     
    147114static VBOXSTRICTRC iomRCInterpretOUT(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
    148115{
    149 #ifdef IN_RC
    150116    STAM_COUNTER_INC(&pVM->iom.s.StatInstOut);
    151 #endif
    152 
    153     /*
    154      * Get port number from first parameter.
    155      * And get the register size and value from the second parameter.
    156      */
    157     uint64_t    uPort = 0;
    158     unsigned    cbSize = 0;
    159     bool fRc = iomGetRegImmData(pCpu, &pCpu->Param1, pRegFrame, &uPort, &cbSize);
    160     AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc);
    161 
    162     VBOXSTRICTRC rcStrict = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, uPort, cbSize);
    163     if (rcStrict == VINF_SUCCESS)
    164     {
    165         uint64_t u64Data = 0;
    166         fRc = iomGetRegImmData(pCpu, &pCpu->Param2, pRegFrame, &u64Data, &cbSize);
    167         AssertMsg(fRc, ("Failed to get reg value!\n")); NOREF(fRc);
    168 
    169         /*
    170          * Attempt to write to the port.
    171          */
    172         rcStrict = IOMIOPortWrite(pVM, pVCpu, uPort, u64Data, cbSize);
    173         AssertMsg(rcStrict == VINF_SUCCESS || rcStrict == VINF_IOM_R3_IOPORT_WRITE || rcStrict == VINF_IOM_R3_IOPORT_COMMIT_WRITE
    174                   || (rcStrict >= VINF_EM_FIRST && rcStrict <= VINF_EM_LAST) || RT_FAILURE(rcStrict),
    175                   ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    176     }
    177     else
    178         AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    179     return rcStrict;
     117    Assert(pCpu->Param1.fUse & (DISUSE_IMMEDIATE8 | DISUSE_REG_GEN16));
     118    uint16_t const u16Port = pCpu->Param1.fUse & DISUSE_REG_GEN16 ? pRegFrame->dx : (uint16_t)pCpu->Param1.uValue;
     119
     120    Assert(pCpu->Param2.fUse & (DISUSE_REG_GEN32 | DISUSE_REG_GEN16 | DISUSE_REG_GEN8));
     121    uint8_t const cbValue = pCpu->Param2.fUse & DISUSE_REG_GEN32 ? 4 : pCpu->Param2.fUse & DISUSE_REG_GEN16 ? 2 : 1;
     122
     123    return IEMExecDecodedOut(pVCpu, pCpu->cbInstr, u16Port, cbValue);
    180124}
    181125
     
    203147static VBOXSTRICTRC iomRCInterpretINS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
    204148{
    205 #ifdef VBOX_WITH_3RD_IEM_STEP
    206149    uint8_t cbValue = pCpu->pCurInstr->uOpcode == OP_INSB ? 1
    207150                    : pCpu->uOpMode == DISCPUMODE_16BIT ? 2 : 4;       /* dword in both 32 & 64 bits mode */
     
    210153                               iomDisModeToIemMode((DISCPUMODE)pCpu->uCpuMode),
    211154                               RT_BOOL(pCpu->fPrefix & (DISPREFIX_REPNE | DISPREFIX_REP)),
    212                                pCpu->cbInstr);
    213 #else
    214     /*
    215      * Get port number directly from the register (no need to bother the
    216      * disassembler). And get the I/O register size from the opcode / prefix.
    217      */
    218     RTIOPORT    Port = pRegFrame->edx & 0xffff;
    219     unsigned    cb;
    220     if (pCpu->pCurInstr->uOpcode == OP_INSB)
    221         cb = 1;
    222     else
    223         cb = (pCpu->uOpMode == DISCPUMODE_16BIT) ? 2 : 4;       /* dword in both 32 & 64 bits mode */
    224 
    225     VBOXSTRICTRC rcStrict = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, Port, cb);
    226     if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
    227     {
    228         AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    229         return rcStrict;
    230     }
    231 
    232     return IOMInterpretINSEx(pVM, pVCpu, pRegFrame, Port, pCpu->fPrefix, (DISCPUMODE)pCpu->uAddrMode, cb);
    233 #endif
     155                               pCpu->cbInstr,
     156                               false /*fIoChecked*/);
    234157}
    235158
     
    258181static VBOXSTRICTRC iomRCInterpretOUTS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
    259182{
    260 #ifdef VBOX_WITH_3RD_IEM_STEP
    261183    uint8_t cbValue = pCpu->pCurInstr->uOpcode == OP_OUTSB ? 1
    262184                    : pCpu->uOpMode == DISCPUMODE_16BIT ? 2 : 4;       /* dword in both 32 & 64 bits mode */
     
    266188                                RT_BOOL(pCpu->fPrefix & (DISPREFIX_REPNE | DISPREFIX_REP)),
    267189                                pCpu->cbInstr,
    268                                 pCpu->fPrefix & DISPREFIX_SEG ? pCpu->idxSegPrefix : X86_SREG_DS);
    269 #else
    270     /*
    271      * Get port number from the first parameter.
    272      * And get the I/O register size from the opcode / prefix.
    273      */
    274     uint64_t    Port = 0;
    275     unsigned    cb;
    276     bool fRc = iomGetRegImmData(pCpu, &pCpu->Param1, pRegFrame, &Port, &cb);
    277     AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc);
    278     if (pCpu->pCurInstr->uOpcode == OP_OUTSB)
    279         cb = 1;
    280     else
    281         cb = (pCpu->uOpMode == DISCPUMODE_16BIT) ? 2 : 4;       /* dword in both 32 & 64 bits mode */
    282 
    283     VBOXSTRICTRC rcStrict = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, Port, cb);
    284     if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
    285     {
    286         AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    287         return rcStrict;
    288     }
    289 
    290     return IOMInterpretOUTSEx(pVM, pVCpu, pRegFrame, Port, pCpu->fPrefix, (DISCPUMODE)pCpu->uAddrMode, cb);
    291 #endif
     190                                pCpu->fPrefix & DISPREFIX_SEG ? pCpu->idxSegPrefix : X86_SREG_DS,
     191                                false /*fIoChecked*/);
    292192}
    293193
  • trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp

    r60847 r60874  
    11141114    {
    11151115        VBOXSTRICTRC rcStrict = IOMRCIOPortHandler(pVM, pVCpu, pRegFrame, &Cpu);
    1116         if (IOM_SUCCESS(rcStrict))
    1117         {
    1118             pRegFrame->rip += cbOp;
    1119 
    1120             /*
    1121              * Check for I/O breakpoints.  A bit clumsy, but should be short lived (moved to IEM).
    1122              */
    1123             uint32_t const uDr7 = CPUMGetGuestDR7(pVCpu);
    1124             if (RT_UNLIKELY(   (   (uDr7 & X86_DR7_ENABLED_MASK)
    1125                                 && X86_DR7_ANY_RW_IO(uDr7)
    1126                                 && (CPUMGetGuestCR4(pVCpu) & X86_CR4_DE))
    1127                             || DBGFBpIsHwIoArmed(pVM)))
    1128             {
    1129                 uint64_t    uPort = pRegFrame->dx;
    1130                 unsigned    cbValue;
    1131                 if (   Cpu.pCurInstr->uOpcode == OP_IN
    1132                     || Cpu.pCurInstr->uOpcode == OP_INSB
    1133                     || Cpu.pCurInstr->uOpcode == OP_INSWD)
    1134                 {
    1135                     cbValue = DISGetParamSize(&Cpu, &Cpu.Param1);
    1136                     if (Cpu.Param2.fUse & DISUSE_IMMEDIATE)
    1137                         uPort = Cpu.Param2.uValue;
    1138                 }
    1139                 else
    1140                 {
    1141                     cbValue = DISGetParamSize(&Cpu, &Cpu.Param2);
    1142                     if (Cpu.Param1.fUse & DISUSE_IMMEDIATE)
    1143                         uPort = Cpu.Param1.uValue;
    1144                 }
    1145 
    1146                 VBOXSTRICTRC rcStrict2 = DBGFBpCheckIo(pVM, pVCpu, CPUMCTX_FROM_CORE(pRegFrame), uPort, cbValue);
    1147                 if (rcStrict2 == VINF_EM_RAW_GUEST_TRAP)
    1148                 {
    1149                     /* Raise #DB. */
    1150                     TRPMResetTrap(pVCpu);
    1151                     TRPMAssertTrap(pVCpu, X86_XCPT_DE, TRPM_TRAP);
    1152                     if (rcStrict != VINF_SUCCESS)
    1153                         LogRel(("trpmGCTrap0dHandler: Overriding %Rrc with #DB on I/O port access.\n", VBOXSTRICTRC_VAL(rcStrict)));
    1154                     rcStrict = VINF_EM_RAW_GUEST_TRAP;
    1155                 }
    1156                 /* rcStrict is VINF_SUCCESS or in [VINF_EM_FIRST..VINF_EM_LAST]. */
    1157                 else if (   rcStrict2 != VINF_SUCCESS
    1158                          && (rcStrict == VINF_SUCCESS || rcStrict2 < rcStrict))
    1159                     rcStrict = rcStrict2;
    1160             }
    1161         }
    1162         rc = VBOXSTRICTRC_TODO(rcStrict);
    11631116        TRPM_EXIT_DBG_HOOK(0xd);
    1164         return trpmGCExitTrap(pVM, pVCpu, rc, pRegFrame);
     1117        return trpmGCExitTrap(pVM, pVCpu, VBOXSTRICTRC_TODO(rcStrict), pRegFrame);
    11651118    }
    11661119
Note: See TracChangeset for help on using the changeset viewer.

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