PGMAllPhys.cpp revision 6a9b5d2a23485ebbd7b1063849d37bc5a8ef44d4
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * PGM - Page Manager and Monitor, Physical Memory Addressing.
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * available from http://www.virtualbox.org. This file is free software;
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * you can redistribute it and/or modify it under the terms of the GNU
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * General Public License (GPL) as published by the Free Software
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * additional information or have any questions.
851d14acf364667775d2b68c40987dbb2a1d64advboxsync/** @def PGM_IGNORE_RAM_FLAGS_RESERVED
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * Don't respect the MM_RAM_FLAGS_RESERVED flag when converting to HC addresses.
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * Since this flag is currently incorrectly kept set for ROM regions we will
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * have to ignore it for now so we don't break stuff.
851d14acf364667775d2b68c40987dbb2a1d64advboxsync * @todo this has been fixed now I believe, remove this hack.
#define PGM_IGNORE_RAM_FLAGS_RESERVED
#include "PGMInternal.h"
#ifdef IN_RING3
#ifndef IN_RING3
VMMDECL(int) pgmPhysRomWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, void *pvFault, RTGCPHYS GCPhysFault, void *pvUser)
int rc;
#ifdef VBOX_WITH_NEW_PHYS_CODE
case OP_MOV:
return VINF_SUCCESS;
return rc;
#ifdef VBOX_WITH_NEW_PHYS_CODE
return VINF_EM_RAW_EMULATE_INSTR;
return pPage
&& !(pPage->HCPhys & (MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO2));
return rc;
#ifndef PGM_IGNORE_RAM_FLAGS_RESERVED
return VERR_PGM_PHYS_PAGE_RESERVED;
return VINF_SUCCESS;
#ifdef IN_RING3
Log(("PGM: cHandyPages=%u out of %u -> allocate more\n", pVM->pgm.s.cHandyPages - 1 <= RT_ELEMENTS(pVM->pgm.s.aHandyPages)));
#ifdef IN_RING3
/** @todo call PGMR0PhysAllocateHandyPages directly - need to make sure we can call kernel code first and deal with the seeding fallback. */
return VERR_EM_NO_MEMORY;
#ifdef IN_RING3
#ifndef IN_RING3
Log(("PGM: VM_FF_TO_R3 - cHandyPages=%u out of %u\n", pVM->pgm.s.cHandyPages - 1 <= RT_ELEMENTS(pVM->pgm.s.aHandyPages)));
return VINF_SUCCESS;
return rc;
AssertMsg(PGM_PAGE_IS_ZERO(pPage) || PGM_PAGE_IS_SHARED(pPage), ("%d %RGp\n", PGM_PAGE_GET_STATE(pPage), GCPhys));
Log2(("PGM: Replaced zero page %RGp with %#x / %RHp\n", GCPhys, pVM->pgm.s.aHandyPages[iHandyPage].idPage, HCPhys));
return VINF_SUCCESS;
case PGM_PAGE_STATE_ALLOCATED:
return VINF_SUCCESS;
case PGM_PAGE_STATE_ZERO:
return VERR_PGM_PHYS_PAGE_RESERVED;
case PGM_PAGE_STATE_SHARED:
#ifdef IN_GC
if (!pMap)
#ifdef IN_RING0
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifndef IN_GC
if (!pRam)
void *pv;
return rc;
return VINF_SUCCESS;
#ifdef VBOX_WITH_NEW_PHYS_CODE
#ifdef IN_GC
return rc;
# ifdef IN_GC
VMMDECL(int) PGMPhysGCPhys2CCPtrReadOnly(PVM pVM, RTGCPHYS GCPhys, void const **ppv, PPGMPAGEMAPLOCK pLock)
return rc;
VMMDECL(int) PGMPhysGCPtr2CCPtrReadOnly(PVM pVM, RTGCPTR GCPtr, void const **ppv, PPGMPAGEMAPLOCK pLock)
return rc;
#ifdef VBOX_WITH_NEW_PHYS_CODE
#ifdef IN_GC
VMMDECL(int) PGMPhysGCPhys2HCPtr(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange, PRTHCPTR pHCPtr) /** @todo @bugref{1865}: HCPtr -> R3Ptr */
#ifdef VBOX_WITH_NEW_PHYS_CODE
return rc;
#ifndef PGM_IGNORE_RAM_FLAGS_RESERVED
return VERR_PGM_PHYS_PAGE_RESERVED;
#if defined(IN_GC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) /* ASSUMES this is a rare occurence */
return VERR_PGM_PHYS_PAGE_RESERVED;
return VINF_SUCCESS;
VMMDECL(RTHCPTR) PGMPhysGCPhys2HCPtrAssert(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange) /** @todo @bugref{1865}: HCPtr -> R3Ptr */
return HCPtr;
return NIL_RTHCPTR;
return rc;
return rc;
VMMDECL(int) PGMPhysGCPtr2HCPtr(PVM pVM, RTGCPTR GCPtr, PRTHCPTR pHCPtr) /** @todo @bugref{1865}: HCPtr -> R3Ptr */
#ifdef VBOX_WITH_NEW_PHYS_CODE
rc = PGMPhysGCPhys2HCPtr(pVM, GCPhys | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK), 1 /* we always stay within one page */, pHCPtr);
return rc;
VMMDECL(int) PGMPhysGCPtr2HCPtrByGstCR3(PVM pVM, RTGCPTR GCPtr, uint64_t cr3, unsigned fFlags, PRTHCPTR pHCPtr) /** @todo @bugref{1865}: HCPtr -> R3Ptr */
#ifdef VBOX_WITH_NEW_PHYS_CODE
int rc;
rc = PGMPhysGCPhys2HCPtr(pVM, pgmGstGet4MBPhysPage(&pVM->pgm.s, Pde) | ((RTGCUINTPTR)GCPtr & X86_PAGE_4M_OFFSET_MASK), 1 /* we always stay within one page */, pHCPtr);
return PGMPhysGCPhys2HCPtr(pVM, (Pte.u & X86_PTE_PG_MASK) | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK), 1 /* we always stay within one page */, pHCPtr);
rc = PGMPhysGCPhys2HCPtr(pVM, (Pde.u & X86_PDE2M_PAE_PG_MASK) | ((RTGCUINTPTR)GCPtr & X86_PAGE_2M_OFFSET_MASK), 1 /* we always stay within one page */, pHCPtr);
return PGMPhysGCPhys2HCPtr(pVM, (Pte.u & X86_PTE_PAE_PG_MASK) | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK), 1 /* we always stay within one page */, pHCPtr);
return rc;
#ifdef IN_RING3
#ifdef IN_RING3
bool fGrabbedLock = false;
if (cbRead == 0)
#ifdef IN_RING3
fGrabbedLock = true;
goto end;
PPGMPHYSHANDLER pNode = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.pTreesHC->PhysHandlers, GCPhys);
/** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
goto end;
goto end;
unsigned iPage;
/** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
goto end;
goto end;
switch (pPage->HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_ROM)) /** @todo PAGE FLAGS */
case MM_RAM_FLAGS_ROM:
goto end;
case MM_RAM_FLAGS_RESERVED:
goto end;
goto end;
AssertReleaseMsgFailed(("Unknown read at %VGp size %d implement the complex physical reading case %x\n",
pPage->HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_ROM))); /** @todo PAGE FLAGS */
if ( !pRam
goto end;
end:
#ifdef IN_RING3
if (fGrabbedLock)
#ifdef IN_RING3
bool fGrabbedLock = false;
if (cbWrite == 0)
#ifdef IN_RING3
fGrabbedLock = true;
int rc;
#ifdef IN_RING3
if (fGrabbedLock)
PGMPhysWrite(pVM, GCPhys, pvBuf, cbWrite); /* try again; can't assume pRam is still valid (paranoia) */
goto end;
PPGMPHYSHANDLER pPhysNode = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.pTreesHC->PhysHandlers, GCPhys);
/** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
rc = pPhysNode->pfnHandlerR3(pVM, GCPhys, pvDst, (void *)pvBuf, cb, PGMACCESSTYPE_WRITE, pPhysNode->pvUserR3);
unsigned iPage;
/** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
rc2 = pVirtNode->pfnHandlerHC(pVM, (RTGCPTR)GCPtr, pvDst, (void *)pvBuf, cb, PGMACCESSTYPE_WRITE, 0);
goto end;
goto end;
#ifdef IN_RING3
unsigned iPage;
/** @tode Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
goto end;
goto end;
PPGMPHYSHANDLER pNode = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.pTreesHC->PhysHandlers, GCPhys);
/** @todo Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
rc = pNode->pfnHandlerR3(pVM, GCPhys, pvDst, (void *)pvBuf, cb, PGMACCESSTYPE_WRITE, pNode->pvUserR3);
goto end;
goto end;
switch (pPage->HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_MMIO2)) /** @todo PAGE FLAGS */
case MM_RAM_FLAGS_MMIO2:
goto end;
case MM_RAM_FLAGS_RESERVED:
goto end;
goto end;
AssertReleaseMsgFailed(("Unknown write at %VGp size %d implement the complex physical writing case %x\n",
(pPage->HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_MMIO2)))); /** @todo PAGE FLAGS */
if ( !pRam
goto end;
end:
#ifdef IN_RING3
if (fGrabbedLock)
if (!cb)
return VINF_SUCCESS;
pRam;
void *pvSrc;
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_PGM_PHYS_PAGE_RESERVED;
if (!cb)
return VINF_SUCCESS;
pRam;
#ifdef VBOX_WITH_NEW_PHYS_CODE
void *pvDst;
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_PGM_PHYS_PAGE_RESERVED;
if (!cb)
return VINF_SUCCESS;
void *pvSrc;
return rc;
return VINF_SUCCESS;
void *pvSrc;
return rc;
return VINF_SUCCESS;
if (!cb)
return VINF_SUCCESS;
void *pvDst;
return rc;
return VINF_SUCCESS;
void *pvDst;
return rc;
return VINF_SUCCESS;
int rc;
if (!cb)
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
int rc;
if (!cb)
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
if (!cb)
return VINF_SUCCESS;
void *pvDst;
return rc;
rc = PGMGstModifyPage(pVM, GCPtrDst, cb, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D));
return VINF_SUCCESS;
void *pvDst;
return rc;
return VINF_SUCCESS;
VMMDECL(int) PGMPhysInterpretedRead(PVM pVM, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCUINTPTR GCPtrSrc, size_t cb)
int rc;
void *pvSrc;
switch (rc)
case VINF_SUCCESS:
Log(("PGMPhysInterpretedRead: pvDst=%p pvSrc=%p cb=%d\n", pvDst, (uint8_t *)pvSrc + (GCPtrSrc & PAGE_OFFSET_MASK), cb));
return rc;
return VINF_SUCCESS;
void *pvSrc1;
switch (rc)
case VINF_SUCCESS:
return rc;
void *pvSrc2;
switch (rc)
case VINF_SUCCESS:
return rc;
return VINF_SUCCESS;
switch (rc)
case VINF_SUCCESS:
case VERR_PAGE_NOT_PRESENT:
return rc;