VirtualBox

Ignore:
Timestamp:
Apr 19, 2007 1:52:53 PM (18 years ago)
Author:
vboxsync
Message:

backed out 20576 due to regressions

File:
1 edited

Legend:

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

    r2226 r2228  
    3737#include <iprt/assert.h>
    3838
    39 
    40 /*******************************************************************************
    41 *   Global Variables                                                           *
    42 *******************************************************************************/
    43 
    44 /**
    45  * Array for fast recode of the operand size (1/2/4/8 bytes) to bit shift value.
    46  */
    47 static const unsigned g_aSize2Shift[] =
    48 {
    49     ~0,    /* 0 - invalid */
    50     0,     /* *1 == 2^0 */
    51     1,     /* *2 == 2^1 */
    52     ~0,    /* 3 - invalid */
    53     2,     /* *4 == 2^2 */
    54     ~0,    /* 5 - invalid */
    55     ~0,    /* 6 - invalid */
    56     ~0,    /* 7 - invalid */
    57     3      /* *8 == 2^3 */
    58 };
    59 
    60 /**
    61  * Macro for fast recode of the operand size (1/2/4/8 bytes) to bit shift value.
    62  */
    63 #define SIZE2SHIFT(cb) (g_aSize2Shift[cb])
    64 
    65 /**
    66  * Calculates the size of register parameter.
    67  *
    68  * @returns 1, 2, 4 on success.
    69  * @returns 0 if non-register parameter.
    70  * @param   pCpu                Pointer to current disassembler context.
    71  * @param   pParam              Pointer to parameter of instruction to proccess.
    72  */
    73 static unsigned iomGCGetRegSize(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam)
    74 {
    75     if (pParam->flags & (USE_BASE | USE_INDEX | USE_SCALE | USE_DISPLACEMENT8 | USE_DISPLACEMENT16 | USE_DISPLACEMENT32 | USE_IMMEDIATE8 | USE_IMMEDIATE16 | USE_IMMEDIATE32 | USE_IMMEDIATE16_SX8 | USE_IMMEDIATE32_SX8))
    76         return 0;
    77 
    78     if (pParam->flags & USE_REG_GEN32)
    79         return 4;
    80 
    81     if (pParam->flags & USE_REG_GEN16)
    82         return 2;
    83 
    84     if (pParam->flags & USE_REG_GEN8)
    85         return 1;
    86 
    87     if (pParam->flags & USE_REG_SEG)
    88         return 2;
    89     return 0;
    90 }
    91 
    92 /**
    93  * Returns the contents of register or immediate data of instruction's parameter.
    94  *
    95  * @returns true on success.
    96  *
    97  * @param   pCpu                Pointer to current disassembler context.
    98  * @param   pParam              Pointer to parameter of instruction to proccess.
    99  * @param   pRegFrame           Pointer to CPUMCTXCORE guest structure.
    100  * @param   pu32Data            Where to store retrieved data.
    101  * @param   pcbSize             Where to store the size of data (1, 2, 4).
    102  */
    103 static bool iomGCGetRegImmData(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint32_t *pu32Data, unsigned *pcbSize)
    104 {
    105     if (pParam->flags & (USE_BASE | USE_INDEX | USE_SCALE | USE_DISPLACEMENT8 | USE_DISPLACEMENT16 | USE_DISPLACEMENT32))
    106     {
    107         *pcbSize  = 0;
    108         *pu32Data = 0;
    109         return false;
    110     }
    111 
    112     if (pParam->flags & USE_REG_GEN32)
    113     {
    114         *pcbSize  = 4;
    115         DISFetchReg32(pRegFrame, pParam->base.reg_gen32, pu32Data);
    116         return true;
    117     }
    118 
    119     if (pParam->flags & USE_REG_GEN16)
    120     {
    121         *pcbSize  = 2;
    122         DISFetchReg16(pRegFrame, pParam->base.reg_gen16, (uint16_t *)pu32Data);
    123         return true;
    124     }
    125 
    126     if (pParam->flags & USE_REG_GEN8)
    127     {
    128         *pcbSize  = 1;
    129         DISFetchReg8(pRegFrame, pParam->base.reg_gen8, (uint8_t *)pu32Data);
    130         return true;
    131     }
    132 
    133     if (pParam->flags & (USE_IMMEDIATE32|USE_IMMEDIATE32_SX8))
    134     {
    135         *pcbSize  = 4;
    136         *pu32Data = (uint32_t)pParam->parval;
    137         return true;
    138     }
    139 
    140     if (pParam->flags & (USE_IMMEDIATE16|USE_IMMEDIATE16_SX8))
    141     {
    142         *pcbSize  = 2;
    143         *pu32Data = (uint16_t)pParam->parval;
    144         return true;
    145     }
    146 
    147     if (pParam->flags & USE_IMMEDIATE8)
    148     {
    149         *pcbSize  = 1;
    150         *pu32Data = (uint8_t)pParam->parval;
    151         return true;
    152     }
    153 
    154     if (pParam->flags & USE_REG_SEG)
    155     {
    156         *pcbSize  = 2;
    157         DISFetchRegSeg(pRegFrame, pParam->base.reg_seg, (RTSEL *)pu32Data);
    158         return true;
    159     } /* Else - error. */
    160 
    161     *pcbSize  = 0;
    162     *pu32Data = 0;
    163     return false;
    164 }
    165 
    166 
    167 /**
    168  * Saves data to 8/16/32 general purpose or segment register defined by
    169  * instruction's parameter.
    170  *
    171  * @returns true on success.
    172  * @param   pCpu                Pointer to current disassembler context.
    173  * @param   pParam              Pointer to parameter of instruction to proccess.
    174  * @param   pRegFrame           Pointer to CPUMCTXCORE guest structure.
    175  * @param   u32Data             8/16/32 bit data to store.
    176  */
    177 static bool iomGCSaveDataToReg(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, unsigned u32Data)
    178 {
    179     if (pParam->flags & (USE_BASE | USE_INDEX | USE_SCALE | USE_DISPLACEMENT8 | USE_DISPLACEMENT16 | USE_DISPLACEMENT32 | USE_IMMEDIATE8 | USE_IMMEDIATE16 | USE_IMMEDIATE32 | USE_IMMEDIATE32_SX8 | USE_IMMEDIATE16_SX8))
    180     {
    181         return false;
    182     }
    183 
    184     if (pParam->flags & USE_REG_GEN32)
    185     {
    186         DISWriteReg32(pRegFrame, pParam->base.reg_gen32, u32Data);
    187         return true;
    188     }
    189 
    190     if (pParam->flags & USE_REG_GEN16)
    191     {
    192         DISWriteReg16(pRegFrame, pParam->base.reg_gen16, (uint16_t)u32Data);
    193         return true;
    194     }
    195 
    196     if (pParam->flags & USE_REG_GEN8)
    197     {
    198         DISWriteReg8(pRegFrame, pParam->base.reg_gen8, (uint8_t)u32Data);
    199         return true;
    200     }
    201 
    202     if (pParam->flags & USE_REG_SEG)
    203     {
    204         DISWriteRegSeg(pRegFrame, pParam->base.reg_seg, (RTSEL)u32Data);
    205         return true;
    206     }
    207 
    208     /* Else - error. */
    209     return false;
    210 }
    211 
    212 /*
    213  * Internal - statistics only.
    214  */
    215 inline void iomGCMMIOStatLength(PVM pVM, unsigned cb)
    216 {
    217 #ifdef VBOX_WITH_STATISTICS
    218     switch (cb)
    219     {
    220         case 1:
    221             STAM_COUNTER_INC(&pVM->iom.s.StatGCMMIO1Byte);
    222             break;
    223         case 2:
    224             STAM_COUNTER_INC(&pVM->iom.s.StatGCMMIO2Bytes);
    225             break;
    226         case 4:
    227             STAM_COUNTER_INC(&pVM->iom.s.StatGCMMIO4Bytes);
    228             break;
    229         default:
    230             /* No way. */
    231             AssertMsgFailed(("Invalid data length %d\n", cb));
    232             break;
    233     }
    234 #else
    235     NOREF(pVM); NOREF(cb);
    236 #endif
    237 }
    23839
    23940/**
     
    12931094    return VINF_SUCCESS;
    12941095}
    1295 
    1296 /**
    1297  * IN <AL|AX|EAX>, <DX|imm16>
    1298  *
    1299  * @returns VBox status code.
    1300  *
    1301  * @param   pVM         The virtual machine (GC pointer ofcourse).
    1302  * @param   pRegFrame   Pointer to CPUMCTXCORE guest registers structure.
    1303  * @param   pCpu        Disassembler CPU state.
    1304  */
    1305 IOMDECL(int) IOMInterpretIN(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
    1306 {
    1307 #ifdef IN_GC
    1308     STAM_COUNTER_INC(&pVM->iom.s.StatGCInstIn);
    1309 #endif
    1310 
    1311     /*
    1312      * Get port number from second parameter.
    1313      * And get the register size from the first parameter.
    1314      */
    1315     uint32_t    uPort = 0;
    1316     unsigned    cbSize = 0;
    1317     bool fRc = iomGCGetRegImmData(pCpu, &pCpu->param2, pRegFrame, &uPort, &cbSize);
    1318     AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc);
    1319 
    1320     cbSize = iomGCGetRegSize(pCpu, &pCpu->param1);
    1321     Assert(cbSize > 0);
    1322     int rc = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, uPort, cbSize);
    1323     if (rc == VINF_SUCCESS)
    1324     {
    1325         /*
    1326          * Attemp to read the port.
    1327          */
    1328         uint32_t    u32Data = ~0U;
    1329         rc = IOMIOPortRead(pVM, uPort, &u32Data, cbSize);
    1330         if (rc == VINF_SUCCESS)
    1331         {
    1332             /*
    1333              * Store the result in the AL|AX|EAX register.
    1334              */
    1335             fRc = iomGCSaveDataToReg(pCpu, &pCpu->param1, pRegFrame, u32Data);
    1336             AssertMsg(fRc, ("Failed to store register value!\n")); NOREF(fRc);
    1337         }
    1338     }
    1339     return rc;
    1340 }
    1341 
    1342 
    1343 /**
    1344  * OUT <DX|imm16>, <AL|AX|EAX>
    1345  *
    1346  * @returns VBox status code.
    1347  *
    1348  * @param   pVM         The virtual machine (GC pointer ofcourse).
    1349  * @param   pRegFrame   Pointer to CPUMCTXCORE guest registers structure.
    1350  * @param   pCpu        Disassembler CPU state.
    1351  */
    1352 IOMDECL(int) IOMInterpretOUT(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
    1353 {
    1354 #ifdef IN_GC
    1355     STAM_COUNTER_INC(&pVM->iom.s.StatGCInstOut);
    1356 #endif
    1357 
    1358     /*
    1359      * Get port number from first parameter.
    1360      * And get the register size and value from the second parameter.
    1361      */
    1362     uint32_t    uPort = 0;
    1363     unsigned    cbSize = 0;
    1364     bool fRc = iomGCGetRegImmData(pCpu, &pCpu->param1, pRegFrame, &uPort, &cbSize);
    1365     AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc);
    1366 
    1367     int rc = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, uPort, cbSize);
    1368     if (rc == VINF_SUCCESS)
    1369     {
    1370         uint32_t    u32Data = 0;
    1371         fRc = iomGCGetRegImmData(pCpu, &pCpu->param2, pRegFrame, &u32Data, &cbSize);
    1372         AssertMsg(fRc, ("Failed to get reg value!\n")); NOREF(fRc);
    1373 
    1374         /*
    1375          * Attemp to write to the port.
    1376          */
    1377         rc = IOMIOPortWrite(pVM, uPort, u32Data, cbSize);
    1378     }
    1379     return rc;
    1380 }
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