BS3_DECL(void) Bs3SlabInit(PBS3SLABCTL pSlabCtl, size_t cbSlabCtl, uint32_t uFlatSlabPtr, uint32_t cbSlab, uint16_t cbChunk) { uint16_t cBits; BS3_ASSERT(RT_IS_POWER_OF_TWO(cbChunk)); BS3_ASSERT(cbSlab >= cbChunk * 4); BS3_ASSERT(!(uFlatSlabPtr & (cbChunk - 1))); BS3_XPTR_SET_FLAT(BS3SLABCTL, pSlabCtl->pNext, 0); BS3_XPTR_SET_FLAT(BS3SLABCTL, pSlabCtl->pHead, 0); BS3_XPTR_SET_FLAT(BS3SLABCTL, pSlabCtl->pbStart, uFlatSlabPtr); pSlabCtl->cbChunk = cbChunk; pSlabCtl->cChunkShift = ASMBitFirstSetU16(cbChunk) - 1; pSlabCtl->cChunks = cbSlab >> pSlabCtl->cChunkShift; pSlabCtl->cFreeChunks = pSlabCtl->cChunks; cBits = RT_ALIGN_T(pSlabCtl->cChunks, 32, uint16_t); BS3_ASSERT(cbSlabCtl >= RT_OFFSETOF(BS3SLABCTL, bmAllocated[cBits >> 3])); Bs3MemZero(&pSlabCtl->bmAllocated, cBits >> 3); /* Mark excess bitmap padding bits as allocated. */ if (cBits != pSlabCtl->cChunks) { uint16_t iBit; for (iBit = pSlabCtl->cChunks; iBit < cBits; iBit++) ASMBitSet(pSlabCtl->bmAllocated, iBit); } }
/** * Maps a range of physical pages at a given virtual address * in the guest context. * * The GC virtual address range must be within an existing mapping. * * @returns VBox status code. * @param pVM The virtual machine. * @param GCPtr Where to map the page(s). Must be page aligned. * @param HCPhys Start of the range of physical pages. Must be page aligned. * @param cbPages Number of bytes to map. Must be page aligned. * @param fFlags Page flags (X86_PTE_*). */ VMMDECL(int) PGMMap(PVM pVM, RTGCUINTPTR GCPtr, RTHCPHYS HCPhys, uint32_t cbPages, unsigned fFlags) { AssertMsg(pVM->pgm.s.offVM, ("Bad init order\n")); /* * Validate input. */ AssertMsg(RT_ALIGN_T(GCPtr, PAGE_SIZE, RTGCUINTPTR) == GCPtr, ("Invalid alignment GCPtr=%#x\n", GCPtr)); AssertMsg(cbPages > 0 && RT_ALIGN_32(cbPages, PAGE_SIZE) == cbPages, ("Invalid cbPages=%#x\n", cbPages)); AssertMsg(!(fFlags & X86_PDE_PG_MASK), ("Invalid flags %#x\n", fFlags)); /* hypervisor defaults */ if (!fFlags) fFlags = X86_PTE_P | X86_PTE_A | X86_PTE_D; /* * Find the mapping. */ PPGMMAPPING pCur = pVM->pgm.s.CTX_SUFF(pMappings); while (pCur) { if (GCPtr - pCur->GCPtr < pCur->cb) { if (GCPtr + cbPages - 1 > pCur->GCPtrLast) { AssertMsgFailed(("Invalid range!!\n")); return VERR_INVALID_PARAMETER; } /* * Setup PTE. */ X86PTEPAE Pte; Pte.u = fFlags | (HCPhys & X86_PTE_PAE_PG_MASK); /* * Update the page tables. */ for (;;) { RTGCUINTPTR off = GCPtr - pCur->GCPtr; const unsigned iPT = off >> X86_PD_SHIFT; const unsigned iPageNo = (off >> PAGE_SHIFT) & X86_PT_MASK; /* 32-bit */ pCur->aPTs[iPT].CTX_SUFF(pPT)->a[iPageNo].u = (uint32_t)Pte.u; /* ASSUMES HCPhys < 4GB and/or that we're never gonna do 32-bit on a PAE host! */ /* pae */ PGMSHWPTEPAE_SET(pCur->aPTs[iPT].CTX_SUFF(paPaePTs)[iPageNo / 512].a[iPageNo % 512], Pte.u); /* next */ cbPages -= PAGE_SIZE; if (!cbPages) break; GCPtr += PAGE_SIZE; Pte.u += PAGE_SIZE; } return VINF_SUCCESS; } /* next */ pCur = pCur->CTX_SUFF(pNext); } AssertMsgFailed(("GCPtr=%#x was not found in any mapping ranges!\n", GCPtr)); return VERR_INVALID_PARAMETER; }
/* Called to create DirectDraw surface. * Note: we always return DDHAL_DRIVER_NOTHANDLED, which asks DirectDraw memory manager * to perform actual memory allocation in our DDraw heap. */ DWORD APIENTRY VBoxDispDDCreateSurface(PDD_CREATESURFACEDATA lpCreateSurface) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpCreateSurface->lpDD->dhpdev; LOGF_ENTER(); PDD_SURFACE_LOCAL pSurf = lpCreateSurface->lplpSList[0]; if (pSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { LOG(("primary surface")); pSurf->lpGbl->fpVidMem = 0; } else { LOG(("non primary surface")); pSurf->lpGbl->fpVidMem = DDHAL_PLEASEALLOC_BLOCKSIZE; } pSurf->lpGbl->dwReserved1 = 0; #ifdef VBOX_WITH_VIDEOHWACCEL if(pDev->vhwa.bEnabled) { VBOXVHWACMD* pCmd; pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_CREATE, sizeof(VBOXVHWACMD_SURF_CREATE)); if (pCmd) { VBOXVHWACMD_SURF_CREATE *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE); PVBOXVHWASURFDESC pDesc; int rc; memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CREATE)); rc = VBoxDispVHWAFromDDSURFACEDESC(&pBody->SurfInfo, lpCreateSurface->lpDDSurfaceDesc); VBOX_WARNRC(rc); pBody->SurfInfo.surfCaps = VBoxDispVHWAFromDDSCAPS(pSurf->ddsCaps.dwCaps); pBody->SurfInfo.flags |= DDSD_CAPS; pBody->SurfInfo.height = pSurf->lpGbl->wHeight; pBody->SurfInfo.width = pSurf->lpGbl->wWidth; pBody->SurfInfo.flags |= DDSD_HEIGHT | DDSD_WIDTH; VBoxDispVHWAFromDDPIXELFORMAT(&pBody->SurfInfo.PixelFormat, &pSurf->lpGbl->ddpfSurface); pBody->SurfInfo.flags |= VBOXVHWA_SD_PIXELFORMAT; if (pSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { pBody->SurfInfo.offSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, 0); } else { pBody->SurfInfo.offSurface = VBOXVHWA_OFFSET64_VOID; } pDesc = VBoxDispVHWASurfDescAlloc(); if (pDesc) { VBoxDispVHWACommandSubmit(pDev, pCmd); if (RT_SUCCESS(pCmd->rc)) { uint32_t surfSizeX = pBody->SurfInfo.sizeX; uint32_t surfSizeY = pBody->SurfInfo.sizeY; pDesc->hHostHandle = pBody->SurfInfo.hSurf; if(!!(pSurf->ddsCaps.dwCaps & DDSCAPS_OVERLAY) && !!(pSurf->ddsCaps.dwCaps & DDSCAPS_VISIBLE)) { pDesc->bVisible = true; } pSurf->lpGbl->dwBlockSizeX = pBody->SurfInfo.sizeX; pSurf->lpGbl->dwBlockSizeY = pBody->SurfInfo.sizeY; pSurf->lpGbl->lPitch = pBody->SurfInfo.pitch; lpCreateSurface->lpDDSurfaceDesc->lPitch = pSurf->lpGbl->lPitch; lpCreateSurface->lpDDSurfaceDesc->dwFlags |= DDSD_PITCH; /*@todo: it's probably a memory leak, because DDDestroySurface wouldn't be called for * primary surfaces. */ pSurf->lpGbl->dwReserved1 = (ULONG_PTR)pDesc; } else { WARN(("VBoxDispVHWACommandSubmit failed with rc=%#x", rc)); VBoxDispVHWASurfDescFree(pDesc); } } else { WARN(("VBoxDispVHWASurfDescAlloc failed")); } VBoxDispVHWACommandRelease(pDev, pCmd); } else { WARN(("VBoxDispVHWACommandCreate failed")); } return DDHAL_DRIVER_NOTHANDLED; } #endif /*VBOX_WITH_VIDEOHWACCEL*/ LPDDSURFACEDESC pDesc = lpCreateSurface->lpDDSurfaceDesc; if (pDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4) { pSurf->lpGbl->lPitch = RT_ALIGN_T(pSurf->lpGbl->wWidth/2, 32, LONG); } else if (pDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { pSurf->lpGbl->lPitch = RT_ALIGN_T(pSurf->lpGbl->wWidth, 32, LONG); } else { pSurf->lpGbl->lPitch = pSurf->lpGbl->wWidth*(pDesc->ddpfPixelFormat.dwRGBBitCount/8); } pSurf->lpGbl->dwBlockSizeX = pSurf->lpGbl->lPitch; pSurf->lpGbl->dwBlockSizeY = pSurf->lpGbl->wHeight; pDesc->lPitch = pSurf->lpGbl->lPitch; pDesc->dwFlags |= DDSD_PITCH; LOGF_LEAVE(); return DDHAL_DRIVER_NOTHANDLED; }