Changeset 2228 in vbox for trunk/src/VBox/VMM/VMMAll/IOMAll.cpp
- Timestamp:
- Apr 19, 2007 1:52:53 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IOMAll.cpp
r2226 r2228 37 37 #include <iprt/assert.h> 38 38 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 by169 * 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_STATISTICS218 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 #else235 NOREF(pVM); NOREF(cb);236 #endif237 }238 39 239 40 /** … … 1293 1094 return VINF_SUCCESS; 1294 1095 } 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_GC1308 STAM_COUNTER_INC(&pVM->iom.s.StatGCInstIn);1309 #endif1310 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_GC1355 STAM_COUNTER_INC(&pVM->iom.s.StatGCInstOut);1356 #endif1357 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.