/*! ****************************************************************************** @Function RMAN_CreateBucket ******************************************************************************/ IMG_RESULT RMAN_CreateBucket( IMG_HANDLE * phResBHandle ) { RMAN_sBucket * psBucket; IMG_UINT32 i; IMG_RESULT i32Result; IMG_ASSERT(gInitialised); /* Allocate a bucket structure...*/ psBucket = IMG_MALLOC(sizeof(*psBucket)); IMG_ASSERT(psBucket != IMG_NULL); if (psBucket == IMG_NULL) { return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psBucket, 0, sizeof(*psBucket)); /* Intialise the resource list...*/ DQ_init(&psBucket->sResList); /* The start allocating resource ids at the first...*/ i32Result = IDGEN_CreateContext(RMAN_MAX_ID, RMAN_ID_BLOCKSIZE, IMG_FALSE, &psBucket->hIdGenerator); if(i32Result != IMG_SUCCESS) { IMG_FREE(psBucket); IMG_ASSERT(!"failed to create IDGEN context"); return i32Result; } /* Locate free bucket index within the table...*/ SYSOSKM_DisableInt(); for (i=0; i<RMAN_CRESID_MAX_BUCKET_INDEX; i++) { if (gapsBucket[i] == IMG_NULL) { break; } } if (i >= RMAN_CRESID_MAX_BUCKET_INDEX) { SYSOSKM_EnableInt(); IDGEN_DestroyContext(psBucket->hIdGenerator); IMG_FREE(psBucket); IMG_ASSERT(!"No free buckets left"); return IMG_ERROR_GENERIC_FAILURE; } /* Allocate bucket index...*/ psBucket->ui32BucketIndex = i; gapsBucket[i] = psBucket; SYSOSKM_EnableInt(); /* Return the bucket handle...*/ *phResBHandle = psBucket; return IMG_SUCCESS; }
/*! ****************************************************************************** @Function SYSDEVKM_OpenDevice ******************************************************************************/ IMG_RESULT SYSDEVKM_OpenDevice( IMG_CHAR * pszDeviceName, IMG_HANDLE * phSysDevHandle ) { IMG_UINT32 ui32Result; SYSDEVKM_sDevice * psDevice; /* Allocate a device structure...*/ psDevice = IMG_MALLOC(sizeof(*psDevice)); IMG_ASSERT(psDevice != IMG_NULL); if (psDevice == IMG_NULL) { return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psDevice, 0, sizeof(*psDevice)); /* Get the device id...*/ ui32Result = SYSDEVU_GetDeviceId(pszDeviceName, &psDevice->ui32DeviceId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } /* Return the device handle...*/ *phSysDevHandle = psDevice; /* Update count...*/ SYSOSKM_DisableInt(); gsActiveOpenCnt++; SYSOSKM_EnableInt(); return IMG_SUCCESS; }
/*! ****************************************************************************** @Function POOL_Deinitialise ******************************************************************************/ IMG_VOID POOL_Deinitialise(IMG_VOID) { POOL_sResPool * psResPool; IMG_ASSERT(0); /* Disable interrupts. */ SYSOSKM_DisableInt(); /* If not initialised...*/ if (!gInitialised) { /* Destroy any active pools...*/ psResPool = (POOL_sResPool *)LST_first(&gsPoolList); while (psResPool != IMG_NULL) { POOL_PoolDestroy(psResPool); psResPool = (POOL_sResPool *)LST_first(&gsPoolList); } /* Set initialised flag...*/ gInitialised = IMG_FALSE; } /* Enable interrupts. */ SYSOSKM_EnableInt(); }
/*! ****************************************************************************** @Function POOL_PoolCreate ******************************************************************************/ IMG_RESULT POOL_PoolCreate( IMG_HANDLE * phPoolHandle ) { POOL_sResPool * psResPool; IMG_UINT32 ui32Result; IMG_ASSERT(gInitialised); /* Allocate a pool structure...*/ psResPool = IMG_MALLOC(sizeof(*psResPool)); IMG_ASSERT(psResPool != IMG_NULL); if (psResPool == IMG_NULL) { return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psResPool, 0, sizeof(*psResPool)); /* Initialise the pool info...*/ LST_init(&psResPool->sFreeResList); LST_init(&psResPool->sActResList); /* Create mutex...*/ ui32Result = SYSOSKM_CreateMutex(&psResPool->hMutexHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_create_mutex; } /* Create context for the Id generator...*/ ui32Result = IDGEN_CreateContext(POOL_IDGEN_MAX_ID, POOL_IDGEN_BLOCK_SIZE,IMG_FALSE, &psResPool->hIdGenHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_create_context; } /* Disable interrupts. */ SYSOSKM_DisableInt(); /* Add to list of pools...*/ LST_add(&gsPoolList, psResPool); /* Enable interrupts. */ SYSOSKM_EnableInt(); /* Return handle to pool...*/ *phPoolHandle = psResPool; return IMG_SUCCESS; /* Error handling. */ error_create_context: SYSOSKM_DestroyMutex(psResPool->hMutexHandle); error_create_mutex: IMG_FREE(psResPool); return ui32Result; }
/*! ****************************************************************************** @Function RMAN_Deinitialise ******************************************************************************/ IMG_VOID RMAN_Deinitialise(IMG_VOID) { IMG_UINT32 i; /* Make sure no other cpu is using the shared resources. */ SYSOSKM_DisableInt(); /* If initialised...*/ if (gInitialised) { /* Destroy the golbal resource bucket...*/ RMAN_DestroyBucket(gpsGlobalResBucket); /* Destroy the shared resource bucket...*/ RMAN_DestroyBucket(gpsSharedResBucket); /* Make sure we destroy the mutex after destroying the bucket. */ SYSOSKM_DestroyMutex(globalMutext); /* Destroy mutex...*/ SYSOSKM_DestroyMutex(ghSharedResMutexHandle); /* Check all buckets destroyed...*/ for (i=0; i<RMAN_CRESID_MAX_BUCKET_INDEX; i++) { IMG_ASSERT(gapsBucket[i] == IMG_NULL); } /* Reset initialised flag...*/ gInitialised = IMG_FALSE; } SYSOSKM_EnableInt(); }
/*! ****************************************************************************** @Function FreePages ******************************************************************************/ static IMG_VOID FreePages( SYSMEM_Heap * heap, IMG_HANDLE hPagesHandle ) { struct priv_params * prv = (struct priv_params *)heap->priv; SYSMEMU_sPages * psPages = hPagesHandle; IMG_UINT32 ui32NoPages; IMG_UINT32 ui32PageIndex; IMG_UINT32 i; IMG_UINT32 physAddrArrSize; /* Calculate required no. of pages...*/ ui32NoPages = (psPages->ui32Size + (HOST_MMU_PAGE_SIZE-1)) / HOST_MMU_PAGE_SIZE; /* If mapping then free on the copy of the page structure. */ if (psPages->bImported) { if(IMG_NULL != psPages->ppaPhysAddr) { IMG_BIGORSMALL_FREE(ui32NoPages * sizeof(psPages->ppaPhysAddr[0]), psPages->ppaPhysAddr); psPages->ppaPhysAddr = IMG_NULL; } return; } if (psPages->bDuplicated) return; /* Removed this from the list of mappable regions...*/ SYSBRGU_DestroyMappableRegion(psPages->hRegHandle); /* Free memory...*/ SYSOSKM_DisableInt(); IMG_ASSERT((IMG_UINTPTR)psPages->pvCpuKmAddr >= prv->vstart); IMG_ASSERT((IMG_UINTPTR)psPages->pvCpuKmAddr < (prv->vstart + prv->size)); /* Calculate page table size and index...*/ physAddrArrSize = sizeof(psPages->ppaPhysAddr[0]) * ui32NoPages; ui32PageIndex = (IMG_UINT32) ((((IMG_UINTPTR)psPages->pvCpuKmAddr) - prv->vstart) / HOST_MMU_PAGE_SIZE); /* Mark pages as unallocated...*/ for (i=0; i<ui32NoPages; i++) { IMG_ASSERT(prv->alloc_pool[ui32PageIndex+i]); prv->alloc_pool[ui32PageIndex+i] = IMG_FALSE; } prv->cur_index -= ui32NoPages; SYSOSKM_EnableInt(); IMG_BIGORSMALL_FREE(physAddrArrSize, psPages->ppaPhysAddr); }
/*! ****************************************************************************** @Function SYSDEVU_GetDeviceId ******************************************************************************/ IMG_RESULT SYSDEVU_GetDeviceId( IMG_CHAR * pszDeviceName, IMG_UINT32 * pui32DeviceId ) { SYSDEVU_sInfo *dev; if(!gSysDevInitialised) { IMG_ASSERT(gSysDevInitialised); return IMG_ERROR_NOT_INITIALISED; } dev = findDeviceByName(pszDeviceName); if (!dev) { IMG_ASSERT(dev); return IMG_ERROR_DEVICE_NOT_FOUND; } /* Return device Id...*/ *pui32DeviceId = dev->ui32DeviceId; /* If device not located...*/ SYSOSKM_DisableInt(); if (!dev->bDevLocated) { /* Device now located...*/ dev->bDevLocated = IMG_TRUE; SYSOSKM_EnableInt(); } else { SYSOSKM_EnableInt(); } /* Return success...*/ return IMG_SUCCESS; }
static irqreturn_t handle_interrupt(int irq, void *dev_id) { bool handled; if ( (gpsInfo != IMG_NULL) && (gpsInfo->pfnDevKmLisr != IMG_NULL) ) { SYSOSKM_DisableInt(); handled = gpsInfo->pfnDevKmLisr(gpsInfo->pvParam); SYSOSKM_EnableInt(); if (handled) { /* Signal this...*/ return IRQ_HANDLED; } } return IRQ_NONE; }
static irqreturn_t handle_interrupt(int irq, void *dev_id) { bool handled; if ( (gpsInfo != IMG_NULL) && (gpsInfo->pfnDevKmLisr != IMG_NULL) ) { SYSOSKM_DisableInt(); handled = gpsInfo->pfnDevKmLisr(gpsInfo->pvParam); SYSOSKM_EnableInt(); if (handled) { /* Clear the interrupt with QEMU */ *((char *)reg_base_addr + 0x10000) = 1; /* Signal this...*/ return IRQ_HANDLED; } } return IRQ_NONE; }
/*! ****************************************************************************** @Function SYSDEVKM_CloseDevice ******************************************************************************/ IMG_VOID SYSDEVKM_CloseDevice( IMG_HANDLE hSysDevHandle ) { SYSDEVKM_sDevice * psDevice = (SYSDEVKM_sDevice *)hSysDevHandle; IMG_ASSERT(hSysDevHandle != IMG_NULL); if (hSysDevHandle == IMG_NULL) { return; } IMG_FREE(psDevice); /* Update count...*/ SYSOSKM_DisableInt(); gsActiveOpenCnt--; SYSOSKM_EnableInt(); }
/*! ****************************************************************************** @Function IsrCb ******************************************************************************/ static irqreturn_t IsrCb(int irq, void *dev_id) { IMG_BOOL bHandled; if ( (psSysDev != IMG_NULL) && (psSysDev->pfnDevKmLisr != IMG_NULL) ) { //Call it SYSOSKM_DisableInt(); bHandled = psSysDev->pfnDevKmLisr(psSysDev->pvParam); SYSOSKM_EnableInt(); //If the LISR handled the interrupt if (bHandled) { //Signal this return IRQ_HANDLED; } } return IRQ_NONE; }
/*! ****************************************************************************** @Function POOL_Initialise ******************************************************************************/ IMG_RESULT POOL_Initialise(IMG_VOID) { /* Disable interrupts. */ SYSOSKM_DisableInt(); /* If not initialised...*/ if (!gInitialised) { /* Initialise the list of pools. */ LST_init(&gsPoolList); /* Set initialised flag...*/ gInitialised = IMG_TRUE; } /* Enable interrupts. */ SYSOSKM_EnableInt(); /* Return success...*/ return IMG_SUCCESS; }
/*! ****************************************************************************** @Function RMAN_DestroyBucket ******************************************************************************/ IMG_VOID RMAN_DestroyBucket( IMG_HANDLE hResBHandle ) { RMAN_sBucket * psBucket = (RMAN_sBucket *)hResBHandle; IMG_ASSERT(gInitialised); IMG_ASSERT(psBucket != IMG_NULL); if (psBucket== IMG_NULL) { return; } IMG_ASSERT(psBucket->ui32BucketIndex < RMAN_CRESID_MAX_BUCKET_INDEX); IMG_ASSERT(gapsBucket[psBucket->ui32BucketIndex] != IMG_NULL); /* Free all resources from the bucket...*/ RMAN_FreeResources(hResBHandle, RMAN_TYPE_P1); RMAN_FreeResources(hResBHandle, RMAN_TYPE_P2); RMAN_FreeResources(hResBHandle, RMAN_TYPE_P3); RMAN_FreeResources(hResBHandle, RMAN_ALL_TYPES); /* free sticky resources last: other resources are dependent on them */ RMAN_FreeResources(hResBHandle, RMAN_STICKY); /* Use proper locking around global buckets. */ SYSOSKM_DisableInt(); /* Free from array of bucket pointers...*/ gapsBucket[psBucket->ui32BucketIndex] = IMG_NULL; SYSOSKM_EnableInt(); /* Free the bucket itself...*/ IDGEN_DestroyContext(psBucket->hIdGenerator); IMG_FREE(psBucket); }
/*! ****************************************************************************** @Function DMANKM_RegisterDevice ******************************************************************************/ IMG_RESULT DMANKM_RegisterDevice(IMG_CHAR * pszDeviceName, DMANKM_pfnDevRegister pfnDevRegister) { DMANKM_sDevContext * psDevContext; IMG_UINT32 ui32Result; /* If the device context list is not initialised...*/ if (!gbDevListInitialised) { /* Initialise the device context list...*/ LST_init(&gsDevList); gbDevListInitialised = IMG_TRUE; } /* Locate the device - ensure it's not registered twice...*/ ui32Result = DMANKM_LocateDevice(pszDeviceName, (IMG_HANDLE *) &psDevContext); if (ui32Result != IMG_ERROR_DEVICE_NOT_FOUND) { IMG_ASSERT(ui32Result == IMG_ERROR_DEVICE_NOT_FOUND); return IMG_ERROR_GENERIC_FAILURE; } /* Allocate a device context structure...*/ psDevContext = IMG_MALLOC(sizeof(*psDevContext)); if (psDevContext == IMG_NULL ) { IMG_ASSERT(psDevContext != IMG_NULL); return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psDevContext, 0, sizeof(*psDevContext)); /* Setup the device context...*/ psDevContext->ui32DeviceId = gui32NextDeviceID; gui32NextDeviceID++; psDevContext->pszDeviceName = IMG_STRDUP(pszDeviceName); if (psDevContext->pszDeviceName == IMG_NULL ) { IMG_ASSERT(psDevContext->pszDeviceName != IMG_NULL); ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_dev_name; } psDevContext->pfnDevRegister = pfnDevRegister; psDevContext->ui8ApmPpmFlags = 0; ui32Result = SYSOSKM_CreateMutex(&psDevContext->hMutexHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_create_mutex; } LST_init(&psDevContext->sConnList); /* Disable interrupts...*/ SYSOSKM_DisableInt(); /* Add device to list...*/ LST_add(&gsDevList, psDevContext); /* Re-enable interrupts...*/ SYSOSKM_EnableInt(); /* If initialised...*/ if (gDmanKmInitialised) { /* Call device registration function...*/ ui32Result = psDevContext->pfnDevRegister(&psDevContext->sDevRegister); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_dev_register; } /* Set default if required...*/ if (psDevContext->sDevRegister.ui32ConnFlags == 0) { psDevContext->sDevRegister.ui32ConnFlags = DMAN_CFLAG_EXCLUSIVE; } } /* Return success...*/ return IMG_SUCCESS; /* Error handling. */ error_dev_register: SYSOSKM_DisableInt(); LST_remove(&gsDevList, psDevContext); SYSOSKM_EnableInt(); SYSOSKM_DestroyMutex(psDevContext->hMutexHandle); error_create_mutex: IMG_FREE(psDevContext->pszDeviceName); error_dev_name: IMG_FREE(psDevContext); return ui32Result; }
/*! ****************************************************************************** @Function POOL_PoolDestroy ******************************************************************************/ IMG_RESULT POOL_PoolDestroy( IMG_HANDLE hPoolHandle ) { POOL_sResPool * psResPool = hPoolHandle; POOL_sResource * psResource; POOL_sResource * psCloneResource; IMG_UINT32 ui32Result; IMG_ASSERT(gInitialised); IMG_ASSERT(psResPool != IMG_NULL); if (!gInitialised || psResPool == IMG_NULL) { ui32Result = IMG_ERROR_INVALID_PARAMETERS; goto error_nolock; } /* Lock the pool...*/ SYSOSKM_LockMutex(psResPool->hMutexHandle); /* Disable interrupts. */ SYSOSKM_DisableInt(); /* Remove the pool from the active list...*/ LST_remove(&gsPoolList, psResPool); /* Enable interrupts. */ SYSOSKM_EnableInt(); /* Destroy any resources in the free list...*/ psResource = (POOL_sResource *)LST_removeHead(&psResPool->sFreeResList); while (psResource != IMG_NULL) { psResource->pfnDestructor(psResource->pvParam); IMG_FREE(psResource); psResource = (POOL_sResource *)LST_removeHead(&psResPool->sFreeResList); } /* Destroy any resources in the active list...*/ psResource = (POOL_sResource *)LST_removeHead(&psResPool->sActResList); while (psResource != IMG_NULL) { psCloneResource = (POOL_sResource *)LST_removeHead(&psResource->sCloneResList); while (psCloneResource != IMG_NULL) { /* If we created a copy of the resources pvParam then free it...*/ if (psCloneResource->pvParam != IMG_NULL) { IMG_FREE(psCloneResource->pvParam ); } IMG_FREE(psCloneResource); psCloneResource = (POOL_sResource *)LST_removeHead(&psResource->sCloneResList); } /* Call the resource destructor...*/ psResource->pfnDestructor(psResource->pvParam); IMG_FREE(psResource); psResource = (POOL_sResource *)LST_removeHead(&psResPool->sActResList); } /* Destroy the context for the Id generator...*/ if (psResPool->hIdGenHandle != IMG_NULL) { ui32Result = IDGEN_DestroyContext(psResPool->hIdGenHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); } /* Unlock the pool...*/ SYSOSKM_UnlockMutex(psResPool->hMutexHandle); /* Destroy mutex...*/ SYSOSKM_DestroyMutex(psResPool->hMutexHandle); /* Free the pool structure */ IMG_FREE(psResPool); return IMG_SUCCESS; error_nolock: return ui32Result; }
/*! ****************************************************************************** @Function RMAN_RegisterResource ******************************************************************************/ IMG_RESULT RMAN_RegisterResource( IMG_HANDLE hResBHandle, IMG_UINT32 ui32TypeId, RMAN_pfnFree pfnFree, IMG_VOID * pvParam, IMG_HANDLE * phResHandle, IMG_UINT32 * pui32ResId ) { RMAN_sBucket * psBucket = (RMAN_sBucket *) hResBHandle; RMAN_sResource * psResource; IMG_RESULT i32Result; IMG_ASSERT(gInitialised); IMG_ASSERT(ui32TypeId != RMAN_ALL_TYPES); IMG_ASSERT(hResBHandle != IMG_NULL); if (hResBHandle == IMG_NULL) { return IMG_ERROR_GENERIC_FAILURE; } /* Allocate a resource structure...*/ psResource = IMG_MALLOC(sizeof(*psResource)); IMG_ASSERT(psResource != IMG_NULL); if (psResource == IMG_NULL) { return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psResource, 0, sizeof(*psResource)); /* Fill in the resource structure...*/ psResource->psBucket = psBucket; psResource->ui32TypeId = ui32TypeId; psResource->pfnFree = pfnFree; psResource->pvParam = pvParam; /* Allocate resource Id...*/ SYSOSKM_LockMutex(globalMutext); i32Result = IDGEN_AllocId(psBucket->hIdGenerator, psResource, &psResource->ui32ResId); SYSOSKM_UnlockMutex(globalMutext); if(i32Result != IMG_SUCCESS) { IMG_ASSERT(!"failed to allocate RMAN id"); return i32Result; } IMG_ASSERT(psResource->ui32ResId <= RMAN_CRESID_MAX_RES_ID); // add this resource to the bucket SYSOSKM_DisableInt(); DQ_addTail(&psBucket->sResList, psResource); /* Update count of resources...*/ psBucket->ui32ResCnt++; SYSOSKM_EnableInt(); /* If resource handle required...*/ if (phResHandle != IMG_NULL) { *phResHandle = psResource; } /* If resource id required...*/ if (pui32ResId != IMG_NULL) { *pui32ResId = RMAN_GetResourceId(psResource); } /* Return success...*/ return IMG_SUCCESS; }
static IMG_RESULT AllocPages( SYSMEM_Heap * heap, IMG_UINT32 ui32Size, SYSMEMU_sPages * psPages, SYS_eMemAttrib eMemAttrib ) { IMG_UINT32 ui32NoPages; IMG_UINT32 ui32ExamPages; IMG_UINT32 i; IMG_UINT64 ui64DeviceMemoryBase; IMG_PHYSADDR paCpuPhysAddr; IMG_UINT32 ui32Result; size_t physAddrArrSize; struct priv_params * prv = (struct priv_params *)heap->priv; /* If we don't know where the memory is...*/ SYSOSKM_DisableInt(); /* Calculate required no. of pages...*/ ui32NoPages = (ui32Size + (HOST_MMU_PAGE_SIZE-1)) / HOST_MMU_PAGE_SIZE; /* Loop over allocated pages until we find an unallocated slot big enough for this allocation...*/ ui32ExamPages = 0; while (ui32ExamPages < prv->npages) { /* If the current page is not allocated and we might have enough remaining to make this allocation...*/ if ( (!prv->alloc_pool[prv->cur_index]) && ((prv->cur_index + ui32NoPages) <= prv->npages) ) { /* Can we make this allocation...*/ for (i=0; i<ui32NoPages; i++) { if (prv->alloc_pool[prv->cur_index+i]) { break; } } if (i == ui32NoPages) { /* Yes, mark pages as allocated...*/ for (i=0; i<ui32NoPages; i++) { prv->alloc_pool[prv->cur_index+i] = IMG_TRUE; } /* Calculate the memory address of the start of the allocation...*/ //psPages->pvCpuKmAddr = (IMG_VOID *)((IMG_UINTPTR)prv->vstart + (prv->cur_index * HOST_MMU_PAGE_SIZE)); psPages->pvImplData = (IMG_VOID *)(prv->vstart + (prv->cur_index * HOST_MMU_PAGE_SIZE)); /* Update the current page index....*/ prv->cur_index += ui32NoPages; if (prv->cur_index >= prv->npages) { prv->cur_index = 0; } break; } } /* Update examined pages and page index...*/ ui32ExamPages++; prv->cur_index++; if (prv->cur_index >= prv->npages) { prv->cur_index = 0; } } SYSOSKM_EnableInt(); /* Check if allocation failed....*/ IMG_ASSERT(ui32ExamPages < prv->npages); if (ui32ExamPages >= prv->npages) { /* Failed...*/ /* dump some fragmentation information */ int i = 0; int nAllocated = 0; int n64kBlocks = 0; // number of blocks of <16 consecutive pages int n128kBlocks = 0; int n256kBlocks = 0; int nBigBlocks = 0; // number of blocks of >=64 consecutive pages int nMaxBlocks = 0; int nPages = 0; for(i = 0; i < (int)prv->npages; i++) { IMG_UINT8 isallocated = prv->alloc_pool[i]; nPages++; if(i == prv->npages-1 || isallocated != prv->alloc_pool[i+1]) { if(isallocated) nAllocated += nPages; else if(nPages < 16) n64kBlocks++; else if(nPages < 32) n128kBlocks++; else if(nPages < 64) n256kBlocks++; else nBigBlocks++; if(nMaxBlocks < nPages) nMaxBlocks = nPages; isallocated = prv->alloc_pool[i]; nPages = 0; } } #ifdef printk /* hopefully, this will give some idea of the fragmentation of the memory */ printk("AllocPages not able to allocate memory \n"); printk(" number available memory areas under 64k:%d\n", n64kBlocks); printk(" number available memory areas under 128k:%d\n", n128kBlocks); printk(" number available memory areas under 256k:%d\n", n256kBlocks); printk(" number available memory areas over 256k:%d\n", nBigBlocks); printk(" total allocated memory:%dk/%dk\n", nAllocated*4, prv->npages*4); #endif return IMG_ERROR_OUT_OF_MEMORY; } paCpuPhysAddr = CpuKmAddrToCpuPAddr(heap, psPages->pvImplData); IMG_ASSERT(paCpuPhysAddr != 0); if (paCpuPhysAddr == 0) { return IMG_ERROR_GENERIC_FAILURE; } #ifdef CONFIG_ARM /* This flushes the outer cache in ARM, so we avoid memory corruption by late flushes of memory previously marked as cached. */ if ((eMemAttrib & SYS_MEMATTRIB_CACHED) == 0) { mb(); /* the following two calls are somewhat expensive, but are there for defensive reasons */ flush_cache_all(); outer_flush_all(); } #endif { IMG_PHYSADDR * ppaCpuPhysAddrs; size_t numPages, pg_i, offset; // Memory for physical addresses numPages = (ui32Size + HOST_MMU_PAGE_SIZE - 1)/HOST_MMU_PAGE_SIZE; physAddrArrSize = sizeof(*ppaCpuPhysAddrs) * numPages; ppaCpuPhysAddrs = IMG_BIGORSMALL_ALLOC(physAddrArrSize); if (!ppaCpuPhysAddrs) { return IMG_ERROR_OUT_OF_MEMORY; } for (pg_i = 0, offset = 0; pg_i < numPages; offset += HOST_MMU_PAGE_SIZE, ++pg_i) { ppaCpuPhysAddrs[pg_i] = paCpuPhysAddr + offset; } // Set pointer to physical address in structure psPages->ppaPhysAddr = ppaCpuPhysAddrs; } /* Add this to the list of mappable regions...*/ ui32Result = SYSBRGU_CreateMappableRegion(paCpuPhysAddr, ui32Size, eMemAttrib, psPages, &psPages->hRegHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_mappable_region; } #if defined (CLEAR_PAGES) if (psPages->pvImplData) IMG_MEMSET( psPages->pvImplData, 0, ui32Size); #endif return IMG_SUCCESS; /* Error handling. */ error_mappable_region: IMG_BIGORSMALL_FREE(physAddrArrSize, psPages->ppaPhysAddr); psPages->ppaPhysAddr = IMG_NULL; return ui32Result; }