IOMAllMMIO.cpp revision a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fc
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * IOM - Input / Output Monitor - Guest Context.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Copyright (C) 2006-2007 innotek GmbH
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * This file is part of VirtualBox Open Source Edition (OSE), as
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * available from http://www.virtualbox.org. This file is free software;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * you can redistribute it and/or modify it under the terms of the GNU
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * General Public License (GPL) as published by the Free Software
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Foundation, in version 2 as it comes in the "COPYING" file of the
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/*******************************************************************************
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi* Header Files *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi*******************************************************************************/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/*******************************************************************************
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi* Internal Functions *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi*******************************************************************************/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchistatic bool iomGCGetRegImmData(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint32_t *pu32Data, unsigned *pcbSize);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchistatic bool iomGCSaveDataToReg(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint32_t u32Data);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi/*******************************************************************************
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi* Global Variables *
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi*******************************************************************************/
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Array for accessing 32-bit general registers in VMMREGFRAME structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * by register's index from disasm.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchistatic unsigned g_aReg32Index[] =
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, eax), /* USE_REG_EAX */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, ecx), /* USE_REG_ECX */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, edx), /* USE_REG_EDX */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, ebx), /* USE_REG_EBX */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, esp), /* USE_REG_ESP */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, ebp), /* USE_REG_EBP */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, esi), /* USE_REG_ESI */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, edi) /* USE_REG_EDI */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Macro for accessing 32-bit general purpose registers in CPUMCTXCORE structure.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi#define ACCESS_REG32(p, idx) (*((uint32_t *)((char *)(p) + g_aReg32Index[idx])))
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Array for accessing 16-bit general registers in CPUMCTXCORE structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * by register's index from disasm.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchistatic unsigned g_aReg16Index[] =
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, eax), /* USE_REG_AX */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, ecx), /* USE_REG_CX */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, edx), /* USE_REG_DX */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, ebx), /* USE_REG_BX */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, esp), /* USE_REG_SP */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, ebp), /* USE_REG_BP */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, esi), /* USE_REG_SI */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, edi) /* USE_REG_DI */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Macro for accessing 16-bit general purpose registers in CPUMCTXCORE structure.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi#define ACCESS_REG16(p, idx) (*((uint16_t *)((char *)(p) + g_aReg16Index[idx])))
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Array for accessing 8-bit general registers in CPUMCTXCORE structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * by register's index from disasm.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchistatic unsigned g_aReg8Index[] =
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, eax), /* USE_REG_AL */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, ecx), /* USE_REG_CL */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, edx), /* USE_REG_DL */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, ebx), /* USE_REG_BL */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, eax) + 1, /* USE_REG_AH */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, ecx) + 1, /* USE_REG_CH */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, edx) + 1, /* USE_REG_DH */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, ebx) + 1 /* USE_REG_BH */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Macro for accessing 8-bit general purpose registers in CPUMCTXCORE structure.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi#define ACCESS_REG8(p, idx) (*((uint8_t *)((char *)(p) + g_aReg8Index[idx])))
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Array for accessing segment registers in CPUMCTXCORE structure
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * by register's index from disasm.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchistatic unsigned g_aRegSegIndex[] =
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, es), /* USE_REG_ES */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, cs), /* USE_REG_CS */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, ss), /* USE_REG_SS */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, ds), /* USE_REG_DS */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, fs), /* USE_REG_FS */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi RT_OFFSETOF(CPUMCTXCORE, gs) /* USE_REG_GS */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Macro for accessing segment registers in CPUMCTXCORE structure.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi#define ACCESS_REGSEG(p, idx) (*((uint16_t *)((char *)(p) + g_aRegSegIndex[idx])))
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Array for fast recode of the operand size (1/2/4/8 bytes) to bit shift value.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchistatic const unsigned g_aSize2Shift[] =
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ~0, /* 0 - invalid */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi 0, /* *1 == 2^0 */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ~0, /* 3 - invalid */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ~0, /* 5 - invalid */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ~0, /* 6 - invalid */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi ~0, /* 7 - invalid */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Macro for fast recode of the operand size (1/2/4/8 bytes) to bit shift value.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Wrapper which does the write and updates range statistics when such are enabled.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @warning VBOX_SUCCESS(rc=VINF_IOM_HC_MMIO_WRITE) is TRUE!
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchiinline int iomGCMMIODoWrite(PVM pVM, CTXALLSUFF(PIOMMMIORANGE) pRange, RTGCPHYS GCPhysFault, const void *pvData, unsigned cbSize)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi PIOMMMIOSTATS pStats = iomMMIOGetStats(&pVM->iom.s, GCPhysFault);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi int rc = pRange->pfnWriteCallback(pRange->pDevIns, pRange->pvUser, GCPhysFault, (void *)pvData, cbSize); /* @todo fix const!! */
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return pRange->pfnWriteCallback(pRange->pDevIns, pRange->pvUser, GCPhysFault, (void *)pvData, cbSize);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Wrapper which does the read and updates range statistics when such are enabled.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchiinline int iomGCMMIODoRead(PVM pVM, CTXALLSUFF(PIOMMMIORANGE) pRange, RTGCPHYS GCPhysFault, void *pvData, unsigned cbSize)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi PIOMMMIOSTATS pStats = iomMMIOGetStats(&pVM->iom.s, GCPhysFault);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi int rc = pRange->pfnReadCallback(pRange->pDevIns, pRange->pvUser, GCPhysFault, pvData, cbSize);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return pRange->pfnReadCallback(pRange->pDevIns, pRange->pvUser, GCPhysFault, pvData, cbSize);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * Returns the contents of register or immediate data of instruction's parameter.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @returns true on success.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @param pCpu Pointer to current disassembler context.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @param pParam Pointer to parameter of instruction to proccess.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @param pRegFrame Pointer to CPUMCTXCORE guest structure.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @param pu32Data Where to store retrieved data.
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi * @param pcbSize Where to store the size of data (1, 2, 4).
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchistatic bool iomGCGetRegImmData(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint32_t *pu32Data, unsigned *pcbSize)
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (pParam->flags & (USE_BASE | USE_INDEX | USE_SCALE | USE_DISPLACEMENT8 | USE_DISPLACEMENT16 | USE_DISPLACEMENT32))
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi return false;
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *pu32Data = ACCESS_REG32(pRegFrame, pParam->base.reg_gen32);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *pu32Data = ACCESS_REG16(pRegFrame, pParam->base.reg_gen16);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi *pu32Data = ACCESS_REG8(pRegFrame, pParam->base.reg_gen8);
9d26e4fc021e249c93c2861629cc665e4f5bd4d6Robert Mustacchi if (pParam->flags & (USE_IMMEDIATE32|USE_IMMEDIATE32_SX8))
*pcbSize = 0;
*pu32Data = 0;
static bool iomGCSaveDataToReg(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, unsigned u32Data)
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))
#ifdef VBOX_WITH_STATISTICS
switch (cb)
static int iomGCInterpretMOVxXRead(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu, CTXALLSUFF(PIOMMMIORANGE) pRange, RTGCPHYS GCPhysFault)
return VINF_IOM_HC_MMIO_READ;
return rc;
static int iomGCInterpretMOVxXWrite(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu, CTXALLSUFF(PIOMMMIORANGE) pRange, RTGCPHYS GCPhysFault)
return VINF_IOM_HC_MMIO_WRITE;
unsigned cbSize = 0;
return rc;
* -> I don't see the problem here. MMIO ranges are by definition linear ranges. The virtual source or destination is read/written properly.
#ifdef IN_GC
#ifdef IN_GC
#ifdef IOMGC_MOVS_SUPPORT
static int iomGCInterpretMOVS(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, CTXALLSUFF(PIOMMMIORANGE) pRange)
return VINF_IOM_HC_MMIO_READ_WRITE;
if (!cTransfers)
return VINF_SUCCESS;
#ifdef VBOX_WITH_STATISTICS
int rc;
return VINF_IOM_HC_MMIO_WRITE;
rc = SELMToFlatEx(pVM, pRegFrame->eflags, pRegFrame->ds, (RTGCPTR)pRegFrame->esi, &pRegFrame->dsHid,
/* Access verification first; we currently can't recover properly from traps inside this instruction */
return VINF_EM_RAW_EMULATE_INSTR;
#ifdef IN_GC
while (cTransfers)
cTransfers--;
#ifdef IN_GC
return VINF_IOM_HC_MMIO_READ;
rc = SELMToFlatEx(pVM, pRegFrame->eflags, pRegFrame->es, (RTGCPTR)pRegFrame->edi, &pRegFrame->esHid,
return VINF_EM_RAW_GUEST_TRAP;
if ( !pMMIODst
return VINF_IOM_HC_MMIO_READ_WRITE;
while (cTransfers)
cTransfers--;
/* Access verification first; we currently can't recover properly from traps inside this instruction */
rc = PGMVerifyAccess(pVM, pu8Virt, cTransfers * cbSize, X86_PTE_RW | ((cpl == 3) ? X86_PTE_US : 0));
return VINF_EM_RAW_EMULATE_INSTR;
#ifdef IN_GC
while (cTransfers)
cTransfers--;
#ifdef IN_GC
return rc;
static int iomGCInterpretSTOS(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, CTXALLSUFF(PIOMMMIORANGE) pRange)
return VINF_IOM_HC_MMIO_READ_WRITE;
if (!cTransfers)
return VINF_SUCCESS;
#ifdef VBOX_WITH_STATISTICS
int rc;
if (offIncrement > 0)
rc = pRange->pfnFillCallback(pRange->pDevIns, pRange->pvUser, (Phys - (cTransfers - 1)) << SIZE2SHIFT(cbSize), u32Data, cbSize, cTransfers);
return VINF_IOM_HC_MMIO_WRITE;
cTransfers--;
} while (cTransfers);
return rc;
static int iomGCInterpretLODS(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, CTXALLSUFF(PIOMMMIORANGE) pRange)
return VINF_IOM_HC_MMIO_READ_WRITE;
return VINF_IOM_HC_MMIO_READ;
return rc;
static int iomGCInterpretCMP(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, CTXALLSUFF(PIOMMMIORANGE) pRange)
return VINF_EM_RAW_GUEST_TRAP;
unsigned cbSize = 0;
int rc;
pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF))
return rc;
static int iomGCInterpretAND(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, CTXALLSUFF(PIOMMMIORANGE) pRange)
unsigned cbSize = 0;
bool fAndWrite;
int rc;
fAndWrite = false;
fAndWrite = true;
if (fAndWrite)
pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF))
return rc;
static int iomGCInterpretTEST(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, CTXALLSUFF(PIOMMMIORANGE) pRange)
unsigned cbSize = 0;
int rc;
pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF))
return rc;
static int iomGCInterpretXCHG(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, PDISCPUSTATE pCpu, CTXALLSUFF(PIOMMMIORANGE) pRange)
unsigned cbSize = 0;
int rc;
goto end;
goto end;
end:
return rc;
#ifdef IN_RING0
return rc;
IOMDECL(int) IOMMMIOHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, void *pvFault, RTGCPHYS GCPhysFault, void *pvUser)
if (!pRange)
#ifdef VBOX_WITH_STATISTICS
if (pStats)
if (pRangeR3)
return VERR_IOM_MMIO_HANDLER_BOGUS_CALL;
cpu.mode = SELMIsSelector32Bit(pVM, pRegFrame->eflags, pRegFrame->cs, &pRegFrame->csHid) ? CPUMODE_32BIT : CPUMODE_16BIT;
int rc = SELMValidateAndConvertCSAddr(pVM, pRegFrame->eflags, pRegFrame->ss, pRegFrame->cs, &pRegFrame->csHid, (RTGCPTR)(cpu.mode == CPUMODE_32BIT ? pRegFrame->eip : pRegFrame->eip & 0xffff), &pvCode);
return VERR_IOM_MMIO_HANDLER_BOGUS_CALL;
unsigned cbOp;
case OP_MOV:
case OP_MOVZX:
case OP_MOVSX:
#ifdef IOMGC_MOVS_SUPPORT
case OP_MOVSB:
case OP_MOVSWD:
case OP_STOSB:
case OP_STOSWD:
case OP_LODSB:
case OP_LODSWD:
case OP_CMP:
case OP_AND:
case OP_TEST:
case OP_XCHG:
#ifdef VBOX_WITH_STATISTICS
switch (rc)
case VINF_IOM_HC_MMIO_READ:
case VINF_IOM_HC_MMIO_WRITE:
if (pStats)
return rc;
#ifdef VBOX_WITH_STATISTICS
# ifdef IN_RING3
return VINF_IOM_HC_MMIO_READ;
#ifdef IN_RING3
if (pRange)
#ifdef VBOX_WITH_STATISTICS
if (pStats)
#ifdef VBOX_WITH_STATISTICS
if (pStats)
switch (rc)
case VINF_SUCCESS:
return rc;
case VINF_IOM_MMIO_UNUSED_00:
switch (cbValue)
return VINF_SUCCESS;
case VINF_IOM_MMIO_UNUSED_FF:
switch (cbValue)
return VINF_SUCCESS;
#ifndef IN_RING3
if (pRangeR3)
return VINF_IOM_HC_MMIO_READ;
# ifdef VBOX_WITH_STATISTICS
if (pStats)
*pu32Value = 0;
Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", GCPhys, *pu32Value, cbValue));
return VINF_SUCCESS;
AssertMsgFailed(("Handlers and page tables are out of sync or something! GCPhys=%VGp cbValue=%d\n", GCPhys, cbValue));
return VERR_INTERNAL_ERROR;
#ifdef VBOX_WITH_STATISTICS
# ifdef IN_RING3
return VINF_IOM_HC_MMIO_WRITE;
#ifdef IN_RING3
if (pRange)
#ifdef VBOX_WITH_STATISTICS
if (pStats)
#ifdef VBOX_WITH_STATISTICS
if (pStats)
return rc;
#ifndef IN_RING3
if (pRangeR3)
return VINF_IOM_HC_MMIO_WRITE;
# ifdef VBOX_WITH_STATISTICS
if (pStats)
return VINF_SUCCESS;
AssertMsgFailed(("Handlers and page tables are out of sync or something! GCPhys=%VGp cbValue=%d\n", GCPhys, cbValue));
return VERR_INTERNAL_ERROR;
* @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)
IOMDECL(int) IOMInterpretINSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, uint32_t cbTransfer)
#ifdef VBOX_WITH_STATISTICS
return VINF_EM_RAW_EMULATE_INSTR;
if (!cTransfers)
return VINF_SUCCESS;
int rc = SELMToFlatEx(pVM, pRegFrame->eflags, pRegFrame->es, (RTGCPTR)pRegFrame->edi, &pRegFrame->esHid,
return VINF_EM_RAW_EMULATE_INSTR;
/* Access verification first; we can't recover from traps inside this instruction, as the port read cannot be repeated. */
return VINF_EM_RAW_EMULATE_INSTR;
#ifdef IN_GC
cTransfers--;
#ifdef IN_GC
AssertMsg(rc == VINF_SUCCESS || rc == VINF_IOM_HC_IOPORT_READ || (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST) || VBOX_FAILURE(rc), ("%Vrc\n", rc));
return rc;
* @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)
unsigned cbSize = 0;
AssertMsg(rc == VINF_EM_RAW_GUEST_TRAP || rc == VINF_TRPM_XCPT_DISPATCHED || rc == VINF_TRPM_XCPT_DISPATCHED || VBOX_FAILURE(rc), ("%Vrc\n", rc));
return rc;
* @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)
IOMDECL(int) IOMInterpretOUTSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, uint32_t cbTransfer)
#ifdef VBOX_WITH_STATISTICS
return VINF_EM_RAW_EMULATE_INSTR;
if (!cTransfers)
return VINF_SUCCESS;
int rc = SELMToFlatEx(pVM, pRegFrame->eflags, pRegFrame->ds, (RTGCPTR)pRegFrame->esi, &pRegFrame->dsHid,
return VINF_EM_RAW_EMULATE_INSTR;
/* Access verification first; we currently can't recover properly from traps inside this instruction */
return VINF_EM_RAW_EMULATE_INSTR;
#ifdef IN_GC
cTransfers--;
#ifdef IN_GC
AssertMsg(rc == VINF_SUCCESS || rc == VINF_IOM_HC_IOPORT_WRITE || (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST) || VBOX_FAILURE(rc), ("%Vrc\n", rc));
return rc;
* @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)
unsigned cbSize = 0;
AssertMsg(rc == VINF_EM_RAW_GUEST_TRAP || rc == VINF_TRPM_XCPT_DISPATCHED || rc == VINF_TRPM_XCPT_DISPATCHED || VBOX_FAILURE(rc), ("%Vrc\n", rc));
return rc;