IOMAll.cpp revision 6ca4e5aa3635ceff1141c84761528848805e1037
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync * IOM - Input / Output Monitor - Any Context.
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync * Copyright (C) 2006-2012 Oracle Corporation
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync * available from http://www.virtualbox.org. This file is free software;
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync * General Public License (GPL) as published by the Free Software
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync/*******************************************************************************
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync* Header Files *
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync*******************************************************************************/
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
#include "IOMInline.h"
#ifdef IOM_WITH_CRIT_SECT_RW
bool iomGetRegImmData(PDISCPUSTATE pCpu, PCDISOPPARAM pParam, PCPUMCTXCORE pRegFrame, uint64_t *pu64Data, unsigned *pcbSize)
if (pParam->fUse & (DISUSE_BASE | DISUSE_INDEX | DISUSE_SCALE | DISUSE_DISPLACEMENT8 | DISUSE_DISPLACEMENT16 | DISUSE_DISPLACEMENT32))
*pcbSize = 0;
*pu64Data = 0;
AssertFailed();
*pcbSize = 0;
*pu64Data = 0;
bool iomSaveDataToReg(PDISCPUSTATE pCpu, PCDISOPPARAM pParam, PCPUMCTXCORE pRegFrame, uint64_t u64Data)
if (pParam->fUse & (DISUSE_BASE | DISUSE_INDEX | DISUSE_SCALE | DISUSE_DISPLACEMENT8 | DISUSE_DISPLACEMENT16 | DISUSE_DISPLACEMENT32 | DISUSE_DISPLACEMENT64 | DISUSE_IMMEDIATE8 | DISUSE_IMMEDIATE16 | DISUSE_IMMEDIATE32 | DISUSE_IMMEDIATE32_SX8 | DISUSE_IMMEDIATE16_SX8))
VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue)
#ifndef IN_RING3
return VINF_IOM_R3_IOPORT_READ;
#ifdef VBOX_WITH_STATISTICS
if (pStats)
if ( !pRange
if (pRange)
if (pRange)
#ifndef IN_RING3
if (!pfnInCallback)
return VINF_IOM_R3_IOPORT_READ;
return rcStrict;
#ifdef VBOX_WITH_STATISTICS
if (pStats)
#ifdef VBOX_WITH_STATISTICS
# ifndef IN_RING3
switch (cbValue)
return VERR_IOM_INVALID_IOPORT_SIZE;
Log3(("IOMIOPortRead: Port=%RTiop *pu32=%08RX32 cb=%d rc=%Rrc\n", Port, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rcStrict)));
return rcStrict;
#ifndef IN_RING3
if (pRangeR3)
# ifdef VBOX_WITH_STATISTICS
if (pStats)
return VINF_IOM_R3_IOPORT_READ;
#ifdef VBOX_WITH_STATISTICS
if (pStats)
# ifndef IN_RING3
return VINF_IOM_R3_IOPORT_READ;
if (pStats)
switch (cbValue)
return VERR_IOM_INVALID_IOPORT_SIZE;
Log3(("IOMIOPortRead: Port=%RTiop *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", Port, *pu32Value, cbValue));
return VINF_SUCCESS;
* @param pcTransfers Pointer to the number of transfer units to read, on return remaining transfer units.
#ifndef IN_RING3
return VINF_IOM_R3_IOPORT_READ;
#ifdef LOG_ENABLED
#ifdef VBOX_WITH_STATISTICS
if (pStats)
if ( !pRange
if (pRange)
if (pRange)
#ifndef IN_RING3
if (!pfnInStrCallback)
return VINF_IOM_R3_IOPORT_READ;
return rcStrict;
#ifdef VBOX_WITH_STATISTICS
if (pStats)
#ifdef VBOX_WITH_STATISTICS
# ifndef IN_RING3
return rcStrict;
#ifndef IN_RING3
if (pRangeR3)
# ifdef VBOX_WITH_STATISTICS
if (pStats)
return VINF_IOM_R3_IOPORT_READ;
#ifdef VBOX_WITH_STATISTICS
if (pStats)
# ifndef IN_RING3
return VINF_IOM_R3_IOPORT_READ;
if (pStats)
Log3(("IOMIOPortReadStr: Port=%RTiop pGCPtrDst=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=VINF_SUCCESS\n",
return VINF_SUCCESS;
VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue)
#ifndef IN_RING3
return VINF_IOM_R3_IOPORT_WRITE;
#ifdef VBOX_WITH_STATISTICS
if (pStats)
if ( !pRange
if (pRange)
if (pRange)
#ifndef IN_RING3
if (!pfnOutCallback)
return VINF_IOM_R3_IOPORT_WRITE;
return rcStrict;
#ifdef VBOX_WITH_STATISTICS
if (pStats)
#ifdef VBOX_WITH_STATISTICS
# ifndef IN_RING3
Log3(("IOMIOPortWrite: Port=%RTiop u32=%08RX32 cb=%d rc=%Rrc\n", Port, u32Value, cbValue, VBOXSTRICTRC_VAL(rcStrict)));
return rcStrict;
#ifndef IN_RING3
if (pRangeR3)
# ifdef VBOX_WITH_STATISTICS
if (pStats)
return VINF_IOM_R3_IOPORT_WRITE;
#ifdef VBOX_WITH_STATISTICS
if (pStats)
# ifndef IN_RING3
return VINF_IOM_R3_IOPORT_WRITE;
if (pStats)
return VINF_SUCCESS;
* @param pcTransfers Pointer to the number of transfer units to write, on return remaining transfer units.
#ifndef IN_RING3
return VINF_IOM_R3_IOPORT_WRITE;
#ifdef LOG_ENABLED
#ifdef VBOX_WITH_STATISTICS
if (pStats)
if ( !pRange
if (pRange)
if (pRange)
#ifndef IN_RING3
if (!pfnOutStrCallback)
return VINF_IOM_R3_IOPORT_WRITE;
return rcStrict;
#ifdef VBOX_WITH_STATISTICS
if (pStats)
#ifdef VBOX_WITH_STATISTICS
# ifndef IN_RING3
return rcStrict;
#ifndef IN_RING3
if (pRangeR3)
# ifdef VBOX_WITH_STATISTICS
if (pStats)
return VINF_IOM_R3_IOPORT_WRITE;
#ifdef VBOX_WITH_STATISTICS
if (pStats)
# ifndef IN_RING3
return VINF_IOM_R3_IOPORT_WRITE;
if (pStats)
Log3(("IOMIOPortWriteStr: Port=%RTiop pGCPtrSrc=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=VINF_SUCCESS\n",
return VINF_SUCCESS;
* @retval VINF_TRPM_XCPT_DISPATCHED The exception was raised and dispatched for raw-mode execution. (TRPMRaiseXcptErr)
* @retval VINF_EM_RESCHEDULE_REM The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr)
VMMDECL(VBOXSTRICTRC) IOMInterpretCheckPortIOAccess(PVM pVM, PCPUMCTXCORE pCtxCore, RTIOPORT Port, unsigned cb)
if ( ( cpl > 0
bool fCanHaveIOBitmap;
if ( !fCanHaveIOBitmap
|| cbTss <= sizeof(VBOXTSS)) /** @todo r=bird: Should this really include the interrupt redirection bitmap? */
Log(("iomInterpretCheckPortIOAccess: Port=%RTiop cb=%d cbTss=%#x fCanHaveIOBitmap=%RTbool -> #GP(0)\n",
VBOXSTRICTRC rcStrict = PGMPhysInterpretedRead(pVCpu, pCtxCore, &offIOPB, GCPtrTss + RT_OFFSETOF(VBOXTSS, offIoBitmap), sizeof(offIOPB));
return rcStrict;
return rcStrict;
return VINF_SUCCESS;
* @retval VINF_TRPM_XCPT_DISPATCHED The exception was raised and dispatched for raw-mode execution. (TRPMRaiseXcptErr)
* @retval VINF_EM_RESCHEDULE_REM The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr)
VMMDECL(VBOXSTRICTRC) IOMInterpretIN(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
#ifdef IN_RC
unsigned cbSize = 0;
AssertMsg(rcStrict == VINF_IOM_R3_IOPORT_READ || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
return rcStrict;
* @retval VINF_TRPM_XCPT_DISPATCHED The exception was raised and dispatched for raw-mode execution. (TRPMRaiseXcptErr)
* @retval VINF_EM_RESCHEDULE_REM The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr)
VMMDECL(VBOXSTRICTRC) IOMInterpretOUT(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
#ifdef IN_RC
unsigned cbSize = 0;
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)));
AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
return rcStrict;