VirtualBox

Changeset 18143 in vbox for trunk/src/VBox/VMM/PGMPhys.cpp


Ignore:
Timestamp:
Mar 23, 2009 3:10:24 PM (16 years ago)
Author:
vboxsync
Message:

VMM,Devices: Changed ROM registration and fixed some shadowed ROM issues in the new phys code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PGMPhys.cpp

    r18101 r18143  
    347347
    348348#ifdef VBOX_WITH_NEW_PHYS_CODE
    349 /** 
     349/**
    350350 * VMR3ReqCall worker for PGMR3PhysGCPhys2CCPtrExternal to make pages writable.
    351  * 
     351 *
    352352 * @returns see PGMR3PhysGCPhys2CCPtrExternal
    353353 * @param   pVM         The VM handle.
     
    355355 * @param   ppv         Where to store the mapping address.
    356356 * @param   pLock       Where to store the lock.
    357  */ 
     357 */
    358358static DECLCALLBACK(int) pgmR3PhysGCPhys2CCPtrDelegated(PVM pVM, PRTGCPHYS pGCPhys, void **ppv, PPGMPAGEMAPLOCK pLock)
    359359{
    360360    /*
    361      * Just hand it to PGMPhysGCPhys2CCPtr and check that it's not a page with 
     361     * Just hand it to PGMPhysGCPhys2CCPtr and check that it's not a page with
    362362     * an access handler after it succeeds.
    363363     */
     
    392392 * Requests the mapping of a guest page into ring-3, external threads.
    393393 *
    394  * When you're done with the page, call PGMPhysReleasePageMappingLock() ASAP to 
    395  * release it. 
    396  *
    397  * This API will assume your intention is to write to the page, and will 
    398  * therefore replace shared and zero pages. If you do not intend to modify the 
    399  * page, use the PGMR3PhysGCPhys2CCPtrReadOnlyExternal() API. 
     394 * When you're done with the page, call PGMPhysReleasePageMappingLock() ASAP to
     395 * release it.
     396 *
     397 * This API will assume your intention is to write to the page, and will
     398 * therefore replace shared and zero pages. If you do not intend to modify the
     399 * page, use the PGMR3PhysGCPhys2CCPtrReadOnlyExternal() API.
    400400 *
    401401 * @returns VBox status code.
    402402 * @retval  VINF_SUCCESS on success.
    403  * @retval  VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical 
     403 * @retval  VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
    404404 *          backing or if the page has any active access handlers. The caller
    405405 *          must fall back on using PGMR3PhysWriteExternal.
     
    445445            /*
    446446             * If the page is shared, the zero page, or being write monitored
    447              * it must be converted to an page that's writable if possible. 
     447             * it must be converted to an page that's writable if possible.
    448448             * This has to be done on an EMT.
    449449             */
     
    451451            {
    452452                pgmUnlock(pVM);
    453    
     453
    454454                PVMREQ pReq = NULL;
    455455                rc = VMR3ReqCall(pVM, VMREQDEST_ANY, &pReq, RT_INDEFINITE_WAIT,
     
    496496/**
    497497 * Requests the mapping of a guest page into ring-3, external threads.
    498  * 
     498 *
    499499 * When you're done with the page, call PGMPhysReleasePageMappingLock() ASAP to
    500500 * release it.
     
    502502 * @returns VBox status code.
    503503 * @retval  VINF_SUCCESS on success.
    504  * @retval  VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical 
     504 * @retval  VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
    505505 *          backing or if the page as an active ALL access handler. The caller
    506506 *          must fall back on using PGMPhysRead.
     
    538538            rc = VERR_PGM_PHYS_PAGE_RESERVED;
    539539#endif
    540         else 
     540        else
    541541        {
    542542            /*
     
    16961696 * @param   pvBinary            Pointer to the binary data backing the ROM image.
    16971697 *                              This must be exactly \a cbRange in size.
    1698  * @param   fFlags              Mask of flags. PGMPHYS_ROM_FLAG_SHADOWED
    1699  *                              and/or PGMPHYS_ROM_FLAG_PERMANENT_BINARY.
     1698 * @param   fFlags              Mask of flags. PGMPHYS_ROM_FLAGS_SHADOWED
     1699 *                              and/or PGMPHYS_ROM_FLAGS_PERMANENT_BINARY.
    17001700 * @param   pszDesc             Pointer to description string. This must not be freed.
    17011701 *
     
    17201720    AssertPtrReturn(pvBinary, VERR_INVALID_PARAMETER);
    17211721    AssertPtrReturn(pszDesc, VERR_INVALID_POINTER);
    1722     AssertReturn(!(fFlags & ~(PGMPHYS_ROM_FLAG_SHADOWED | PGMPHYS_ROM_FLAG_PERMANENT_BINARY)), VERR_INVALID_PARAMETER);
     1722    AssertReturn(!(fFlags & ~(PGMPHYS_ROM_FLAGS_SHADOWED | PGMPHYS_ROM_FLAGS_PERMANENT_BINARY)), VERR_INVALID_PARAMETER);
    17231723    VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE);
    17241724
     
    17941794     */
    17951795    uint32_t cExtraBaseCost = fRamExists ? cPages : 0;
    1796     if (fFlags & PGMPHYS_ROM_FLAG_SHADOWED)
     1796    if (fFlags & PGMPHYS_ROM_FLAGS_SHADOWED)
    17971797        cExtraBaseCost += cPages;
    17981798    if (cExtraBaseCost)
     
    18991899             * to PGM atm).
    19001900             */
    1901             if (fFlags & PGMPHYS_ROM_FLAG_SHADOWED)
     1901            if (fFlags & PGMPHYS_ROM_FLAGS_SHADOWED)
    19021902            {
    19031903                REMR3NotifyPhysRomRegister(pVM, GCPhys, cb, NULL, true /* fShadowed */);
    19041904                rc = PGMR3HandlerPhysicalRegister(pVM,
    1905                                                   fFlags & PGMPHYS_ROM_FLAG_SHADOWED
     1905                                                  fFlags & PGMPHYS_ROM_FLAGS_SHADOWED
    19061906                                                  ? PGMPHYSHANDLERTYPE_PHYSICAL_ALL
    19071907                                                  : PGMPHYSHANDLERTYPE_PHYSICAL_WRITE,
     
    19141914            {
    19151915                rc = PGMR3HandlerPhysicalRegister(pVM,
    1916                                                   fFlags & PGMPHYS_ROM_FLAG_SHADOWED
     1916                                                  fFlags & PGMPHYS_ROM_FLAGS_SHADOWED
    19171917                                                  ? PGMPHYSHANDLERTYPE_PHYSICAL_ALL
    19181918                                                  : PGMPHYSHANDLERTYPE_PHYSICAL_WRITE,
     
    19541954                    pRomNew->cb = cb;
    19551955                    pRomNew->fFlags = fFlags;
    1956                     pRomNew->pvOriginal = fFlags & PGMPHYS_ROM_FLAG_PERMANENT_BINARY ? pvBinary : NULL;
     1956                    pRomNew->pvOriginal = fFlags & PGMPHYS_ROM_FLAGS_PERMANENT_BINARY ? pvBinary : NULL;
    19571957                    pRomNew->pszDesc = pszDesc;
    19581958
     
    20372037    Assert(iPage < (pRom->cb >> PAGE_SHIFT));
    20382038    PPGMROMPAGE     pRomPage = &pRom->aPages[iPage];
    2039     switch (pRomPage->enmProt)
    2040     {
    2041         /*
    2042          * Ignore.
    2043          */
    2044         case PGMROMPROT_READ_ROM_WRITE_IGNORE:
    2045         case PGMROMPROT_READ_RAM_WRITE_IGNORE:
    2046             return VINF_SUCCESS;
    2047 
    2048         /*
    2049          * Write to the ram page.
    2050          */
    2051         case PGMROMPROT_READ_ROM_WRITE_RAM:
    2052         case PGMROMPROT_READ_RAM_WRITE_RAM: /* yes this will get here too, it's *way* simpler that way. */
    2053         {
    2054             /* This should be impossible now, pvPhys doesn't work cross page anylonger. */
    2055             Assert(((GCPhys - pRom->GCPhys + cbBuf - 1) >> PAGE_SHIFT) == iPage);
    2056 
     2039    Log5(("pgmR3PhysRomWriteHandler: %d %c %#08RGp %#04zx\n", pRomPage->enmProt, enmAccessType == PGMACCESSTYPE_READ ? 'R' : 'W', GCPhys, cbBuf));
     2040
     2041    if (enmAccessType == PGMACCESSTYPE_READ)
     2042    {
     2043        switch (pRomPage->enmProt)
     2044        {
    20572045            /*
    2058              * Take the lock, do lazy allocation, map the page and copy the data.
    2059              *
    2060              * Note that we have to bypass the mapping TLB since it works on
    2061              * guest physical addresses and entering the shadow page would
    2062              * kind of screw things up...
     2046             * Take the default action.
    20632047             */
    2064             int rc = pgmLock(pVM);
    2065             AssertRC(rc);
    2066 
    2067             if (RT_UNLIKELY(PGM_PAGE_GET_STATE(&pRomPage->Shadow) != PGM_PAGE_STATE_ALLOCATED))
     2048            case PGMROMPROT_READ_ROM_WRITE_IGNORE:
     2049            case PGMROMPROT_READ_RAM_WRITE_IGNORE:
     2050            case PGMROMPROT_READ_ROM_WRITE_RAM:
     2051            case PGMROMPROT_READ_RAM_WRITE_RAM:
     2052                return VINF_PGM_HANDLER_DO_DEFAULT;
     2053
     2054            default:
     2055                AssertMsgFailedReturn(("enmProt=%d iPage=%d GCPhys=%RGp\n",
     2056                                       pRom->aPages[iPage].enmProt, iPage, GCPhys),
     2057                                      VERR_INTERNAL_ERROR);
     2058        }
     2059    }
     2060    else
     2061    {
     2062        Assert(enmAccessType == PGMACCESSTYPE_WRITE);
     2063        switch (pRomPage->enmProt)
     2064        {
     2065            /*
     2066             * Ignore writes.
     2067             */
     2068            case PGMROMPROT_READ_ROM_WRITE_IGNORE:
     2069            case PGMROMPROT_READ_RAM_WRITE_IGNORE:
     2070                return VINF_SUCCESS;
     2071
     2072            /*
     2073             * Write to the ram page.
     2074             */
     2075            case PGMROMPROT_READ_ROM_WRITE_RAM:
     2076            case PGMROMPROT_READ_RAM_WRITE_RAM: /* yes this will get here too, it's *way* simpler that way. */
    20682077            {
    2069                 rc = pgmPhysPageMakeWritable(pVM, &pRomPage->Shadow, GCPhys);
    2070                 if (RT_FAILURE(rc))
     2078                /* This should be impossible now, pvPhys doesn't work cross page anylonger. */
     2079                Assert(((GCPhys - pRom->GCPhys + cbBuf - 1) >> PAGE_SHIFT) == iPage);
     2080
     2081                /*
     2082                 * Take the lock, do lazy allocation, map the page and copy the data.
     2083                 *
     2084                 * Note that we have to bypass the mapping TLB since it works on
     2085                 * guest physical addresses and entering the shadow page would
     2086                 * kind of screw things up...
     2087                 */
     2088                int rc = pgmLock(pVM);
     2089                AssertRC(rc);
     2090                PPGMPAGE pShadowPage = &pRomPage->Shadow;
     2091                if (!PGMROMPROT_IS_ROM(pRomPage->enmProt))
    20712092                {
    2072                     pgmUnlock(pVM);
    2073                     return rc;
     2093                    pShadowPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
     2094                    AssertLogRelReturn(pShadowPage, VERR_INTERNAL_ERROR);
    20742095                }
    2075                 AssertMsg(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3 /* returned */, ("%Rrc\n", rc));
     2096
     2097                if (RT_UNLIKELY(PGM_PAGE_GET_STATE(pShadowPage) != PGM_PAGE_STATE_ALLOCATED))
     2098                {
     2099                    rc = pgmPhysPageMakeWritable(pVM, pShadowPage, GCPhys);
     2100                    if (RT_FAILURE(rc))
     2101                    {
     2102                        pgmUnlock(pVM);
     2103                        return rc;
     2104                    }
     2105                    AssertMsg(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3 /* returned */, ("%Rrc\n", rc));
     2106                }
     2107
     2108                void       *pvDstPage;
     2109                PPGMPAGEMAP pMapIgnored;
     2110                int rc2 = pgmPhysPageMap(pVM, pShadowPage, GCPhys & X86_PTE_PG_MASK, &pMapIgnored, &pvDstPage);
     2111                if (RT_SUCCESS(rc2))
     2112                    memcpy((uint8_t *)pvDstPage + (GCPhys & PAGE_OFFSET_MASK), pvBuf, cbBuf);
     2113                else
     2114                    rc = rc2;
     2115
     2116                pgmUnlock(pVM);
     2117                return rc;
    20762118            }
    20772119
    2078             void *pvDstPage;
    2079             PPGMPAGEMAP pMapIgnored;
    2080             int rc2 = pgmPhysPageMap(pVM, &pRomPage->Shadow, GCPhys & X86_PTE_PG_MASK, &pMapIgnored, &pvDstPage);
    2081             if (RT_SUCCESS(rc2))
    2082                 memcpy((uint8_t *)pvDstPage + (GCPhys & PAGE_OFFSET_MASK), pvBuf, cbBuf);
    2083             else
    2084                 rc = rc2;
    2085 
    2086             pgmUnlock(pVM);
    2087             return rc;
    2088         }
    2089 
    2090         default:
    2091             AssertMsgFailedReturn(("enmProt=%d iPage=%d GCPhys=%RGp\n",
    2092                                    pRom->aPages[iPage].enmProt, iPage, GCPhys),
    2093                                   VERR_INTERNAL_ERROR);
     2120            default:
     2121                AssertMsgFailedReturn(("enmProt=%d iPage=%d GCPhys=%RGp\n",
     2122                                       pRom->aPages[iPage].enmProt, iPage, GCPhys),
     2123                                      VERR_INTERNAL_ERROR);
     2124        }
    20942125    }
    20952126}
     
    21122143        const uint32_t cPages = pRom->cb >> PAGE_SHIFT;
    21132144
    2114         if (pRom->fFlags & PGMPHYS_ROM_FLAG_SHADOWED)
     2145        if (pRom->fFlags & PGMPHYS_ROM_FLAGS_SHADOWED)
    21152146        {
    21162147            /*
     
    22462277        if (    GCPhys     <= pRom->GCPhysLast
    22472278            &&  GCPhysLast >= pRom->GCPhys
    2248             &&  (pRom->fFlags & PGMPHYS_ROM_FLAG_SHADOWED))
     2279            &&  (pRom->fFlags & PGMPHYS_ROM_FLAGS_SHADOWED))
    22492280        {
    22502281            /*
     
    22542285            uint32_t const cPages = pRom->GCPhysLast <= GCPhysLast
    22552286                                  ? pRom->cb >> PAGE_SHIFT
    2256                                   : (GCPhysLast - pRom->GCPhys) >> PAGE_SHIFT;
     2287                                  : (GCPhysLast - pRom->GCPhys + 1) >> PAGE_SHIFT;
    22572288            for (uint32_t iPage = (GCPhys - pRom->GCPhys) >> PAGE_SHIFT;
    22582289                 iPage < cPages;
     
    22792310                    /** @todo preserve the volatile flags (handlers) when these have been moved out of HCPhys! */
    22802311                }
     2312                pRomPage->enmProt = enmProt;
    22812313            }
    22822314
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette