/******************************************************************************* ** ** gckKERNEL_MapVideoMemory ** ** Get the logical address for a hardware specific memory address for the ** current process. ** ** INPUT: ** ** gckKERNEL Kernel ** Pointer to an gckKERNEL object. ** ** gctBOOL InUserSpace ** gcvTRUE to map the memory into the user space. ** ** gctUINT32 Address ** Hardware specific memory address. ** ** OUTPUT: ** ** gctPOINTER * Logical ** Pointer to a variable that will hold the logical address of the ** specified memory address. */ gceSTATUS gckKERNEL_MapVideoMemoryEx( IN gckKERNEL Kernel, IN gceCORE Core, IN gctBOOL InUserSpace, IN gctUINT32 Address, OUT gctPOINTER * Logical ) { GCHAL * gchal; gcePOOL pool; gctUINT32 offset, base; gceSTATUS status; gctPOINTER logical; gcmkHEADER_ARG("Kernel=%p InUserSpace=%d Address=%08x", Kernel, InUserSpace, Address); gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_KERNEL, "[ENTER] gckKERNEL_MapVideoMemory"); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); gcmkVERIFY_ARGUMENT(Logical != gcvNULL); /* Extract the pointer to the GCHAL class. */ gchal = (GCHAL *) Kernel->context; do { #if gcdENABLE_VG if (Core == gcvCORE_VG) { /* Split the memory address into a pool type and offset. */ gcmkERR_BREAK(gckVGHARDWARE_SplitMemory(Kernel->vg->hardware, Address, &pool, &offset)); } else #endif { /* Split the memory address into a pool type and offset. */ gcmkERR_BREAK(gckHARDWARE_SplitMemory(Kernel->hardware, Address, &pool, &offset)); } /* Dispatch on pool. */ switch (pool) { case gcvPOOL_LOCAL_INTERNAL: /* Internal memory. */ logical = gchal->GetInternalLogical(); break; case gcvPOOL_LOCAL_EXTERNAL: /* External memory. */ logical = gchal->GetExternalLogical(); break; case gcvPOOL_SYSTEM: /* System memory. */ #if UNDER_CE >= 600 if (InUserSpace) { logical = gchal->GetProcessContiguousLogical(); } else { logical = gchal->GetContiguousLogical(); } #else logical = gchal->GetContiguousLogical(); #endif #if gcdENABLE_VG if (Core == gcvCORE_VG) { gcmkVERIFY_OK(gckVGHARDWARE_SplitMemory(Kernel->vg->hardware, gchal->GetContiguousHeap()->baseAddress, &pool, &base)); } else #endif { gcmkVERIFY_OK(gckHARDWARE_SplitMemory(Kernel->hardware, gchal->GetContiguousHeap()->baseAddress, &pool, &base)); } offset -= base; break; default: /* Invalid memory pool. */ gcmkFATAL("Unknown memory pool: %u", pool); return gcvSTATUS_INVALID_ARGUMENT; } /* Build logical address of specified address. */ *Logical = reinterpret_cast<gctPOINTER> (static_cast<gctUINT8 *>(logical) + offset); } while (gcvFALSE); if (gcmIS_SUCCESS(status)) { gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL, "gckKERNEL_MapVideoMemory: Address 0x%08X maps to %p", Address, *Logical); } gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_KERNEL, "[LEAVE] gckKERNEL_MapVideoMemory(%u)", status); /* Return the status. */ gcmkFOOTER(); return status; }
/******************************************************************************* ** ** gckKERNEL_MapVideoMemory ** ** Get the logical address for a hardware specific memory address for the ** current process. ** ** INPUT: ** ** gckKERNEL Kernel ** Pointer to an gckKERNEL object. ** ** gctBOOL InUserSpace ** gcvTRUE to map the memory into the user space. ** ** gctUINT32 Address ** Hardware specific memory address. ** ** OUTPUT: ** ** gctPOINTER * Logical ** Pointer to a variable that will hold the logical address of the ** specified memory address. */ gceSTATUS gckKERNEL_MapVideoMemoryEx( IN gckKERNEL Kernel, IN gceCORE Core, IN gctBOOL InUserSpace, IN gctUINT32 Address, OUT gctPOINTER * Logical ) { gckGALDEVICE device; PLINUX_MDL mdl; PLINUX_MDL_MAP mdlMap; gcePOOL pool; gctUINT32 offset, base; gceSTATUS status; gctPOINTER logical; gcmkHEADER_ARG("Kernel=%p InUserSpace=%d Address=%08x", Kernel, InUserSpace, Address); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); gcmkVERIFY_ARGUMENT(Logical != NULL); /* Extract the pointer to the gckGALDEVICE class. */ device = (gckGALDEVICE) Kernel->context; #if gcdENABLE_VG if (Core == gcvCORE_VG) { /* Split the memory address into a pool type and offset. */ gcmkONERROR( gckVGHARDWARE_SplitMemory(Kernel->vg->hardware, Address, &pool, &offset)); } else #endif { /* Split the memory address into a pool type and offset. */ gcmkONERROR( gckHARDWARE_SplitMemory(Kernel->hardware, Address, &pool, &offset)); } /* Dispatch on pool. */ switch (pool) { case gcvPOOL_LOCAL_INTERNAL: /* Internal memory. */ logical = device->internalLogical; break; case gcvPOOL_LOCAL_EXTERNAL: /* External memory. */ logical = device->externalLogical; break; case gcvPOOL_SYSTEM: /* System memory. */ if (device->contiguousMapped) { logical = device->contiguousBase; } else { gctINT processID; gckOS_GetProcessID(&processID); mdl = (PLINUX_MDL) device->contiguousPhysical; mdlMap = FindMdlMap(mdl, processID); gcmkASSERT(mdlMap); logical = (gctPOINTER) mdlMap->vmaAddr; } #if gcdENABLE_VG if (Core == gcvCORE_VG) { gcmkVERIFY_OK( gckVGHARDWARE_SplitMemory(Kernel->vg->hardware, device->contiguousVidMem->baseAddress, &pool, &base)); } else #endif { gctUINT32 baseAddress = 0; if (Kernel->hardware->mmuVersion == 0) { gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress)); } gcmkVERIFY_OK( gckHARDWARE_SplitMemory(Kernel->hardware, device->contiguousVidMem->baseAddress - baseAddress, &pool, &base)); } offset -= base; break; default: /* Invalid memory pool. */ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); } /* Build logical address of specified address. */ *Logical = (gctPOINTER) ((gctUINT8_PTR) logical + offset); /* Success. */ gcmkFOOTER_ARG("*Logical=%p", *Logical); return gcvSTATUS_OK; OnError: /* Retunn the status. */ gcmkFOOTER(); return status; }