PGMAllPhys.cpp revision 6752e22c5aad40a438fc07dcbd9247cece5d9887
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * PGM - Page Manager and Monitor, Physical Memory Addressing.
304e26e9a9c1422dbc299ed139eceacca271a9ddvboxsync * Copyright (C) 2006-2007 innotek GmbH
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * available from http://www.virtualbox.org. This file is free software;
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * you can redistribute it and/or modify it under the terms of the GNU
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * General Public License as published by the Free Software Foundation,
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * If you received this file as part of a commercial VirtualBox
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * distribution, then only the terms of your commercial VirtualBox
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * license agreement apply instead of the previous paragraph.
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync/** @def PGM_IGNORE_RAM_FLAGS_RESERVED
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * Don't respect the MM_RAM_FLAGS_RESERVED flag when converting to HC addresses.
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * Since this flag is currently incorrectly kept set for ROM regions we will
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * have to ignore it for now so we don't break stuff.
1eda04de692c4c416332941e87bab4cc8fc45a18vboxsync/*******************************************************************************
1eda04de692c4c416332941e87bab4cc8fc45a18vboxsync* Header Files *
1eda04de692c4c416332941e87bab4cc8fc45a18vboxsync*******************************************************************************/
6f82db701c69ae6925eb7e8bf1dfe25c9f951bddvboxsync * Checks if Address Gate 20 is enabled or not.
6f82db701c69ae6925eb7e8bf1dfe25c9f951bddvboxsync * @returns true if enabled.
6f82db701c69ae6925eb7e8bf1dfe25c9f951bddvboxsync * @returns false if disabled.
6f82db701c69ae6925eb7e8bf1dfe25c9f951bddvboxsync * @param pVM VM handle.
6f82db701c69ae6925eb7e8bf1dfe25c9f951bddvboxsync LogFlow(("PGMPhysIsA20Enabled %d\n", pVM->pgm.s.fA20Enabled));
6f82db701c69ae6925eb7e8bf1dfe25c9f951bddvboxsync return !!pVM->pgm.s.fA20Enabled ; /* stupid MS compiler doesn't trust me. */
6f82db701c69ae6925eb7e8bf1dfe25c9f951bddvboxsync * Validates a GC physical address.
5bf0ee311caa414469f26237ff607cb1b3591508vboxsync * @returns true if valid.
pRam;
pRam;
return !(pRam->aHCPhys[off >> PAGE_SHIFT] & (MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO2));
pRam;
#ifdef IN_RING3
return rc;
#ifndef PGM_IGNORE_RAM_FLAGS_RESERVED
return VINF_SUCCESS;
return VERR_PGM_PHYS_PAGE_RESERVED;
#ifdef PGM_DYNAMIC_RAM_ALLOC
AssertMsgFailed(("PGMPhysGCPhys2HCPtr %VGp - %VGp crosses a chunk boundary!!\n", GCPhys, GCPhys+cbRange));
pRam;
#ifdef IN_RING3
return rc;
*pHCPtr = (RTHCPTR)((RTHCUINTPTR)CTXSUFF(pRam->pavHCChunk)[idx] + (off & PGM_DYNAMIC_CHUNK_OFFSET_MASK));
return VINF_SUCCESS;
#ifndef PGM_IGNORE_RAM_FLAGS_RESERVED
return VINF_SUCCESS;
return VERR_PGM_PHYS_PAGE_RESERVED;
pRam;
pRam;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_INVALID_POINTER;
pRam;
#ifndef PGM_IGNORE_RAM_FLAGS_RESERVED
return VINF_SUCCESS;
return VERR_PGM_PHYS_PAGE_RESERVED;
#ifndef PGM_IGNORE_RAM_FLAGS_RESERVED
return VINF_SUCCESS;
return VERR_PGM_PHYS_PAGE_RESERVED;
return VERR_INVALID_POINTER;
pRam;
while (iPage-- > 0)
#ifndef PGM_IGNORE_RAM_FLAGS_RESERVED
return VINF_SUCCESS;
return VERR_INVALID_POINTER;
pRam;
while (iPage-- > 0)
#ifndef PGM_IGNORE_RAM_FLAGS_RESERVED
*pHCPtr = (RTHCPTR)((RTHCUINTPTR)CTXSUFF(pRam->pavHCChunk)[idx] + ((iPage << PAGE_SHIFT) & PGM_DYNAMIC_CHUNK_OFFSET_MASK) + off);
return VINF_SUCCESS;
return VERR_INVALID_POINTER;
return rc;
rc = PGMPhysGCPhys2HCPtr(pVM, GCPhys | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK), 1 /* we always stay within one page */, pHCPtr);
return rc;
PGMDECL(int) PGMPhysGCPtr2HCPtrByGstCR3(PVM pVM, RTGCPTR GCPtr, uint32_t cr3, unsigned fFlags, PRTHCPTR pHCPtr)
int rc;
rc = PGMPhysGCPhys2HCPtr(pVM, (Pde.u & X86_PDE4M_PG_MASK) | ((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_PDE4M_PAE_PG_MASK) | ((RTGCUINTPTR)GCPtr & X86_PAGE_4M_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;
switch (HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_ROM))
case MM_RAM_FLAGS_ROM:
#ifdef IN_GC
goto end;
case MM_RAM_FLAGS_RESERVED:
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! */
#ifdef IN_GC
goto end;
goto end;
case MM_RAM_FLAGS_VIRTUAL_ALL:
unsigned iPage;
/** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
#ifdef IN_GC
goto end;
goto end;
goto end;
AssertReleaseMsgFailed(("Unknown read at %VGp size %d implement the complex physical reading case %x\n",
HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_ROM)));
if ( !pCur
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 pCur is still valid (paranoia) */
goto end;
switch (HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_VIRTUAL_WRITE | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_PHYSICAL_WRITE))
case MM_RAM_FLAGS_MMIO2:
#ifdef IN_GC
goto end;
case MM_RAM_FLAGS_RESERVED:
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! */
rc = pNode->pfnHandlerR3(pVM, GCPhys, pvDst, (void *)pvBuf, cb, PGMACCESSTYPE_WRITE, pNode->pvUserR3);
#ifdef IN_GC
goto end;
goto end;
case MM_RAM_FLAGS_VIRTUAL_ALL:
#ifdef IN_RING3
unsigned iPage;
/** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
#ifdef IN_GC
goto end;
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);
#ifdef IN_GC
goto end;
goto end;
goto end;
AssertReleaseMsgFailed(("Unknown write at %VGp size %d implement the complex physical writing case %x\n",
(HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_VIRTUAL_WRITE | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_PHYSICAL_WRITE))));
if ( !pCur
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;
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;
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;
PGMDECL(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;