VirtualBox

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


Ignore:
Timestamp:
May 26, 2015 11:26:35 AM (10 years ago)
Author:
vboxsync
Message:

IOM: Moved some RC code into IOMRC.cpp.

File:
1 edited

Legend:

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

    r45305 r56072  
    4444
    4545/**
     46 * IN <AL|AX|EAX>, <DX|imm16>
     47 *
     48 * @returns Strict VBox status code. Informational status codes other than the one documented
     49 *          here are to be treated as internal failure. Use IOM_SUCCESS() to check for success.
     50 * @retval  VINF_SUCCESS                Success.
     51 * @retval  VINF_EM_FIRST-VINF_EM_LAST  Success with some exceptions (see IOM_SUCCESS()), the
     52 *                                      status code must be passed on to EM.
     53 * @retval  VINF_IOM_R3_IOPORT_READ     Defer the read to ring-3. (R0/GC only)
     54 * @retval  VINF_EM_RAW_GUEST_TRAP      The exception was left pending. (TRPMRaiseXcptErr)
     55 * @retval  VINF_TRPM_XCPT_DISPATCHED   The exception was raised and dispatched for raw-mode execution. (TRPMRaiseXcptErr)
     56 * @retval  VINF_EM_RESCHEDULE_REM      The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr)
     57 *
     58 * @param   pVM         The virtual machine (GC pointer of course).
     59 * @param   pVCpu       Pointer to the virtual CPU structure of the caller.
     60 * @param   pRegFrame   Pointer to CPUMCTXCORE guest registers structure.
     61 * @param   pCpu        Disassembler CPU state.
     62 */
     63static VBOXSTRICTRC iomRCInterpretIN(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
     64{
     65#ifdef IN_RC
     66    STAM_COUNTER_INC(&pVM->iom.s.StatInstIn);
     67#endif
     68
     69    /*
     70     * Get port number from second parameter.
     71     * And get the register size from the first parameter.
     72     */
     73    uint64_t    uPort = 0;
     74    unsigned    cbSize = 0;
     75    bool fRc = iomGetRegImmData(pCpu, &pCpu->Param2, pRegFrame, &uPort, &cbSize);
     76    AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc);
     77
     78    cbSize = DISGetParamSize(pCpu, &pCpu->Param1);
     79    Assert(cbSize > 0);
     80    VBOXSTRICTRC rcStrict = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, uPort, cbSize);
     81    if (rcStrict == VINF_SUCCESS)
     82    {
     83        /*
     84         * Attempt to read the port.
     85         */
     86        uint32_t u32Data = UINT32_C(0xffffffff);
     87        rcStrict = IOMIOPortRead(pVM, pVCpu, uPort, &u32Data, cbSize);
     88        if (IOM_SUCCESS(rcStrict))
     89        {
     90            /*
     91             * Store the result in the AL|AX|EAX register.
     92             */
     93            fRc = iomSaveDataToReg(pCpu, &pCpu->Param1, pRegFrame, u32Data);
     94            AssertMsg(fRc, ("Failed to store register value!\n")); NOREF(fRc);
     95        }
     96        else
     97            AssertMsg(rcStrict == VINF_IOM_R3_IOPORT_READ || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     98    }
     99    else
     100        AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     101
     102    return rcStrict;
     103}
     104
     105
     106/**
     107 * OUT <DX|imm16>, <AL|AX|EAX>
     108 *
     109 * @returns Strict VBox status code. Informational status codes other than the one documented
     110 *          here are to be treated as internal failure. Use IOM_SUCCESS() to check for success.
     111 * @retval  VINF_SUCCESS                Success.
     112 * @retval  VINF_EM_FIRST-VINF_EM_LAST  Success with some exceptions (see IOM_SUCCESS()), the
     113 *                                      status code must be passed on to EM.
     114 * @retval  VINF_IOM_R3_IOPORT_WRITE    Defer the write to ring-3. (R0/GC only)
     115 * @retval  VINF_EM_RAW_GUEST_TRAP      The exception was left pending. (TRPMRaiseXcptErr)
     116 * @retval  VINF_TRPM_XCPT_DISPATCHED   The exception was raised and dispatched for raw-mode execution. (TRPMRaiseXcptErr)
     117 * @retval  VINF_EM_RESCHEDULE_REM      The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr)
     118 *
     119 * @param   pVM         The virtual machine (GC pointer of course).
     120 * @param   pVCpu       Pointer to the virtual CPU structure of the caller.
     121 * @param   pRegFrame   Pointer to CPUMCTXCORE guest registers structure.
     122 * @param   pCpu        Disassembler CPU state.
     123 */
     124static VBOXSTRICTRC iomRCInterpretOUT(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
     125{
     126#ifdef IN_RC
     127    STAM_COUNTER_INC(&pVM->iom.s.StatInstOut);
     128#endif
     129
     130    /*
     131     * Get port number from first parameter.
     132     * And get the register size and value from the second parameter.
     133     */
     134    uint64_t    uPort = 0;
     135    unsigned    cbSize = 0;
     136    bool fRc = iomGetRegImmData(pCpu, &pCpu->Param1, pRegFrame, &uPort, &cbSize);
     137    AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc);
     138
     139    VBOXSTRICTRC rcStrict = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, uPort, cbSize);
     140    if (rcStrict == VINF_SUCCESS)
     141    {
     142        uint64_t u64Data = 0;
     143        fRc = iomGetRegImmData(pCpu, &pCpu->Param2, pRegFrame, &u64Data, &cbSize);
     144        AssertMsg(fRc, ("Failed to get reg value!\n")); NOREF(fRc);
     145
     146        /*
     147         * Attempt to write to the port.
     148         */
     149        rcStrict = IOMIOPortWrite(pVM, pVCpu, uPort, u64Data, cbSize);
     150        AssertMsg(rcStrict == VINF_SUCCESS || rcStrict == VINF_IOM_R3_IOPORT_WRITE || (rcStrict >= VINF_EM_FIRST && rcStrict <= VINF_EM_LAST) || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     151    }
     152    else
     153        AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     154    return rcStrict;
     155}
     156
     157
     158/**
     159 * [REP*] INSB/INSW/INSD
     160 * ES:EDI,DX[,ECX]
     161 *
     162 * @returns Strict VBox status code. Informational status codes other than the one documented
     163 *          here are to be treated as internal failure. Use IOM_SUCCESS() to check for success.
     164 * @retval  VINF_SUCCESS                Success.
     165 * @retval  VINF_EM_FIRST-VINF_EM_LAST  Success with some exceptions (see IOM_SUCCESS()), the
     166 *                                      status code must be passed on to EM.
     167 * @retval  VINF_IOM_R3_IOPORT_READ     Defer the read to ring-3. (R0/GC only)
     168 * @retval  VINF_EM_RAW_EMULATE_INSTR   Defer the read to the REM.
     169 * @retval  VINF_EM_RAW_GUEST_TRAP      The exception was left pending. (TRPMRaiseXcptErr)
     170 * @retval  VINF_TRPM_XCPT_DISPATCHED   The exception was raised and dispatched for raw-mode execution. (TRPMRaiseXcptErr)
     171 * @retval  VINF_EM_RESCHEDULE_REM      The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr)
     172 *
     173 * @param   pVM         The virtual machine.
     174 * @param   pVCpu       Pointer to the virtual CPU structure of the caller.
     175 * @param   pRegFrame   Pointer to CPUMCTXCORE guest registers structure.
     176 * @param   pCpu        Disassembler CPU state.
     177 */
     178static VBOXSTRICTRC iomRCInterpretINS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
     179{
     180    /*
     181     * Get port number directly from the register (no need to bother the
     182     * disassembler). And get the I/O register size from the opcode / prefix.
     183     */
     184    RTIOPORT    Port = pRegFrame->edx & 0xffff;
     185    unsigned    cb;
     186    if (pCpu->pCurInstr->uOpcode == OP_INSB)
     187        cb = 1;
     188    else
     189        cb = (pCpu->uOpMode == DISCPUMODE_16BIT) ? 2 : 4;       /* dword in both 32 & 64 bits mode */
     190
     191    VBOXSTRICTRC rcStrict = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, Port, cb);
     192    if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
     193    {
     194        AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     195        return rcStrict;
     196    }
     197
     198    return IOMInterpretINSEx(pVM, pVCpu, pRegFrame, Port, pCpu->fPrefix, (DISCPUMODE)pCpu->uAddrMode, cb);
     199}
     200
     201
     202/**
     203 * [REP*] OUTSB/OUTSW/OUTSD
     204 * DS:ESI,DX[,ECX]
     205 *
     206 * @returns Strict VBox status code. Informational status codes other than the one documented
     207 *          here are to be treated as internal failure. Use IOM_SUCCESS() to check for success.
     208 * @retval  VINF_SUCCESS                Success.
     209 * @retval  VINF_EM_FIRST-VINF_EM_LAST  Success with some exceptions (see IOM_SUCCESS()), the
     210 *                                      status code must be passed on to EM.
     211 * @retval  VINF_IOM_R3_IOPORT_WRITE    Defer the write to ring-3. (R0/GC only)
     212 * @retval  VINF_EM_RAW_EMULATE_INSTR   Defer the write to the REM.
     213 * @retval  VINF_EM_RAW_GUEST_TRAP      The exception was left pending. (TRPMRaiseXcptErr)
     214 * @retval  VINF_TRPM_XCPT_DISPATCHED   The exception was raised and dispatched for raw-mode execution. (TRPMRaiseXcptErr)
     215 * @retval  VINF_EM_RESCHEDULE_REM      The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr)
     216 *
     217 * @param   pVM         The virtual machine.
     218 * @param   pVCpu       Pointer to the virtual CPU structure of the caller.
     219 * @param   pRegFrame   Pointer to CPUMCTXCORE guest registers structure.
     220 * @param   pCpu        Disassembler CPU state.
     221 */
     222static VBOXSTRICTRC iomRCInterpretOUTS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
     223{
     224    /*
     225     * Get port number from the first parameter.
     226     * And get the I/O register size from the opcode / prefix.
     227     */
     228    uint64_t    Port = 0;
     229    unsigned    cb;
     230    bool fRc = iomGetRegImmData(pCpu, &pCpu->Param1, pRegFrame, &Port, &cb);
     231    AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc);
     232    if (pCpu->pCurInstr->uOpcode == OP_OUTSB)
     233        cb = 1;
     234    else
     235        cb = (pCpu->uOpMode == DISCPUMODE_16BIT) ? 2 : 4;       /* dword in both 32 & 64 bits mode */
     236
     237    VBOXSTRICTRC rcStrict = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, Port, cb);
     238    if (RT_UNLIKELY(rcStrict != VINF_SUCCESS))
     239    {
     240        AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     241        return rcStrict;
     242    }
     243
     244    return IOMInterpretOUTSEx(pVM, pVCpu, pRegFrame, Port, pCpu->fPrefix, (DISCPUMODE)pCpu->uAddrMode, cb);
     245}
     246
     247
     248
     249/**
    46250 * Attempts to service an IN/OUT instruction.
    47251 *
     
    71275    {
    72276        case OP_IN:
    73             return IOMInterpretIN(pVM, pVCpu, pRegFrame, pCpu);
     277            return iomRCInterpretIN(pVM, pVCpu, pRegFrame, pCpu);
    74278
    75279        case OP_OUT:
    76             return IOMInterpretOUT(pVM, pVCpu, pRegFrame, pCpu);
     280            return iomRCInterpretOUT(pVM, pVCpu, pRegFrame, pCpu);
    77281
    78282        case OP_INSB:
    79283        case OP_INSWD:
    80             return IOMInterpretINS(pVM, pVCpu, pRegFrame, pCpu);
     284            return iomRCInterpretINS(pVM, pVCpu, pRegFrame, pCpu);
    81285
    82286        case OP_OUTSB:
    83287        case OP_OUTSWD:
    84             return IOMInterpretOUTS(pVM, pVCpu, pRegFrame, pCpu);
     288            return iomRCInterpretOUTS(pVM, pVCpu, pRegFrame, pCpu);
    85289
    86290        /*
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