static int gralloc_alloc_buffer(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle) { ump_handle ump_mem_handle; void *cpu_ptr; ump_secure_id ump_id; ump_alloc_constraints constraints; size = round_up_to_page_size(size); if( (usage&GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN ) { constraints = UMP_REF_DRV_CONSTRAINT_USE_CACHE; } else { constraints = UMP_REF_DRV_CONSTRAINT_NONE; } ump_mem_handle = ump_ref_drv_allocate(size, constraints); if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle) { cpu_ptr = ump_mapped_pointer_get(ump_mem_handle); if (NULL != cpu_ptr) { ump_id = ump_secure_id_get(ump_mem_handle); if (UMP_INVALID_SECURE_ID != ump_id) { private_handle_t* hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_UMP, size, (int)cpu_ptr, private_handle_t::LOCK_STATE_MAPPED, ump_id, ump_mem_handle); if (NULL != hnd) { *pHandle = hnd; return 0; } else { LOGE("gralloc_alloc_buffer() failed to allocate handle"); } } else { LOGE("gralloc_alloc_buffer() failed to retrieve valid secure id"); } ump_mapped_pointer_release(ump_mem_handle); } else { LOGE("gralloc_alloc_buffer() failed to map UMP memory"); } ump_reference_release(ump_mem_handle); } else { LOGE("gralloc_alloc_buffer() failed to allcoate UMP memory"); } return -1; }
static void maliFinishAccess(PixmapPtr pPix, int index) { PrivPixmap *privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(pPix); mali_mem_info *mem_info; ScreenPtr pScreen = pPix->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; MaliPtr fPtr = MALIPTR(pScrn); IGNORE(index); if (!privPixmap) { return; } if (!pPix) { return; } mem_info = privPixmap->mem_info; if (!privPixmap->isFrameBuffer) { int secure_id = 0; _lock_item_s item; secure_id = ump_secure_id_get(mem_info->handle); if (secure_id) { item.secure_id = secure_id; item.usage = _LOCK_ACCESS_CPU_WRITE; if (fPtr->fd_umplock > 0) { ioctl(fPtr->fd_umplock, LOCK_IOCTL_RELEASE, &item); } } if (privPixmap->refs == 1) { if (NULL != mem_info) { ump_mapped_pointer_release(mem_info->handle); } } } pPix->devPrivate.ptr = NULL; privPixmap->refs--; }
static DRI2Buffer2Ptr MaliDRI2CreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format) { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; PixmapPtr pPixmap = NULL; DRI2Buffer2Ptr buffer = calloc(1, sizeof *buffer); MaliDRI2BufferPrivatePtr privates = calloc(1, sizeof *privates); ump_handle handle; size_t size; if (pDraw->type == DRAWABLE_WINDOW) { pPixmap = pScreen->GetWindowPixmap((WindowPtr)pDraw); } else { ErrorF("Unexpected pDraw->type (%d) in MaliDRI2CreateBuffer\n", pDraw->type); return NULL; } /* initialize buffer info to default values */ buffer->attachment = attachment; buffer->driverPrivate = privates; buffer->format = format; buffer->flags = 0; buffer->cpp = pPixmap->drawable.bitsPerPixel / 8; buffer->pitch = PixmapBytePad(pDraw->width, pDraw->depth); /* allocate UMP buffer */ size = pDraw->height * buffer->pitch; handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR | UMP_REF_DRV_CONSTRAINT_USE_CACHE); if (handle == UMP_INVALID_MEMORY_HANDLE) { ErrorF("invalid UMP handle, bufsize=%d\n", (int)size); } privates->size = size; privates->handle = handle; privates->addr = ump_mapped_pointer_get(handle); privates->width = pDraw->width; privates->height = pDraw->height; privates->depth = pDraw->depth; buffer->name = ump_secure_id_get(handle); buffer->flags = 0; /* offset */ // ErrorF("MaliDRI2CreateBuffer attachment=%d %p, format=%d, cpp=%d, depth=%d\n", // attachment, buffer, format, buffer->cpp, privates->depth); return buffer; }
static int gralloc_alloc_buffer(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle) { #if GRALLOC_ARM_DMA_BUF_MODULE { private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); ion_user_handle_t ion_hnd; unsigned char *cpu_ptr; int shared_fd; int ret; unsigned int ion_flags = 0; if( (usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN ) ion_flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC; if (usage & GRALLOC_USAGE_PRIVATE_1) { ret = ion_alloc(m->ion_client, size, 0, ION_HEAP_CARVEOUT_MASK, ion_flags, &ion_hnd); } else { ret = ion_alloc(m->ion_client, size, 0, ION_HEAP_SYSTEM_MASK, ion_flags, &ion_hnd); } if (ret != 0) { AERR("Failed to ion_alloc from ion_client:%d", m->ion_client); return -1; } ret = ion_share(m->ion_client, ion_hnd, &shared_fd); if (ret != 0) { AERR("ion_share( %d ) failed", m->ion_client); if (0 != ion_free(m->ion_client, ion_hnd)) { AERR("ion_free( %d ) failed", m->ion_client); } return -1; } cpu_ptr = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shared_fd, 0); if (MAP_FAILED == cpu_ptr) { AERR("ion_map( %d ) failed", m->ion_client); if (0 != ion_free(m->ion_client, ion_hnd)) { AERR("ion_free( %d ) failed", m->ion_client); } close(shared_fd); return -1; } private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_ION, usage, size, (int)cpu_ptr, private_handle_t::LOCK_STATE_MAPPED); if (NULL != hnd) { hnd->share_fd = shared_fd; hnd->ion_hnd = ion_hnd; *pHandle = hnd; return 0; } else { AERR("Gralloc out of mem for ion_client:%d", m->ion_client); } close(shared_fd); ret = munmap(cpu_ptr, size); if (0 != ret) { AERR("munmap failed for base:%p size: %d", cpu_ptr, size); } ret = ion_free(m->ion_client, ion_hnd); if (0 != ret) { AERR("ion_free( %d ) failed", m->ion_client); } return -1; } #endif #if GRALLOC_ARM_UMP_MODULE { ump_handle ump_mem_handle; void *cpu_ptr; ump_secure_id ump_id; ump_alloc_constraints constraints; size = round_up_to_page_size(size); if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN) { constraints = UMP_REF_DRV_CONSTRAINT_USE_CACHE; } else { constraints = UMP_REF_DRV_CONSTRAINT_NONE; } #ifdef GRALLOC_SIMULATE_FAILURES /* if the failure condition matches, fail this iteration */ if (__ump_alloc_should_fail()) { ump_mem_handle = UMP_INVALID_MEMORY_HANDLE; } else #endif { ump_mem_handle = ump_ref_drv_allocate(size, constraints); if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle) { cpu_ptr = ump_mapped_pointer_get(ump_mem_handle); if (NULL != cpu_ptr) { ump_id = ump_secure_id_get(ump_mem_handle); if (UMP_INVALID_SECURE_ID != ump_id) { private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_UMP, usage, size, (int)cpu_ptr, private_handle_t::LOCK_STATE_MAPPED, ump_id, ump_mem_handle); if (NULL != hnd) { *pHandle = hnd; return 0; } else { AERR("gralloc_alloc_buffer() failed to allocate handle. ump_handle = %p, ump_id = %d", ump_mem_handle, ump_id); } } else { AERR("gralloc_alloc_buffer() failed to retrieve valid secure id. ump_handle = %p", ump_mem_handle); } ump_mapped_pointer_release(ump_mem_handle); } else { AERR("gralloc_alloc_buffer() failed to map UMP memory. ump_handle = %p", ump_mem_handle); } ump_reference_release(ump_mem_handle); } else { AERR("gralloc_alloc_buffer() failed to allocate UMP memory. size:%d constraints: %d", size, constraints); } } return -1; } #endif }
static Bool maliPrepareAccess(PixmapPtr pPix, int index) { ScreenPtr pScreen = pPix->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; MaliPtr fPtr = MALIPTR(pScrn); PrivPixmap *privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(pPix); mali_mem_info *mem_info; IGNORE(index); if (!privPixmap) { ERROR_MSG("Failed to get private pixmap data"); return FALSE; } mem_info = privPixmap->mem_info; if (NULL != mem_info) { if (privPixmap->refs == 0) { if (privPixmap->isFrameBuffer) { privPixmap->addr = (unsigned long)fPtr->fbmem; } else { privPixmap->addr = (unsigned long)ump_mapped_pointer_get(mem_info->handle); } privPixmap->addr += mem_info->offset; } } else { ERROR_MSG("No mem_info on pixmap"); return FALSE; } pPix->devPrivate.ptr = (void *)(privPixmap->addr); if (NULL == pPix->devPrivate.ptr) { ERROR_MSG("cpu address not set"); return FALSE; } privPixmap->refs++; if (!privPixmap->isFrameBuffer) { int secure_id = 0; _lock_item_s item; secure_id = ump_secure_id_get(mem_info->handle); if (secure_id) { item.secure_id = secure_id; item.usage = _LOCK_ACCESS_CPU_WRITE; if (fPtr->fd_umplock > 0) { ioctl(fPtr->fd_umplock, LOCK_IOCTL_CREATE, &item); if (ioctl(fPtr->fd_umplock, LOCK_IOCTL_PROCESS, &item) < 0) { int max_retries = 5; ERROR_MSG("Unable to process lock item with ID 0x%x - throttling\n", item.secure_id); while ((ioctl(fPtr->fd_umplock, LOCK_IOCTL_PROCESS, &item) < 0) && max_retries) { usleep(2000); max_retries--; } if (max_retries == 0) { ERROR_MSG("Warning: Max retries == 0\n"); } } } if (fPtr->use_cached_ump) { ump_cache_operations_control(UMP_CACHE_OP_START); ump_switch_hw_usage_secure_id(item.secure_id, UMP_USED_BY_CPU); ump_cache_operations_control(UMP_CACHE_OP_FINISH); } } } return TRUE; }
static void maliCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height) { PrivPixmap *srcPrivPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(SrcPixmap); PrivPixmap *dstPrivPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(pDstPixmap); IGNORE(pDstPixmap); IGNORE(srcX); IGNORE(srcY); IGNORE(dstX); IGNORE(dstY); IGNORE(width); IGNORE(height); //ERROR_STR("%s: pDstPixmap=%p srcX=%d srcY=%d dstX=%d dstY=%d width=%d height=%d\n", // __FUNCTION__, pDstPixmap, srcX, srcY, dstX, dstY, width, height); ScreenPtr pScreen = SrcPixmap->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; MaliPtr fPtr = MALIPTR(pScrn); struct fb_var_screeninfo var_info; int ret = ioctl(fPtr->fb_lcd_fd, FBIOGET_VSCREENINFO, &var_info); if (ret < 0) { ERROR_STR("FBIOGET_VSCREENINFO failed.\n"); } unsigned char revX = 0; unsigned char revY = 0; if (dstY > srcY) { revY = 1; } if (dstX > srcX) { revX = 1; } //if (srcPrivPixmap->frameBufferNumber != 0) //{ // srcY += (var_info.yres * srcPrivPixmap->frameBufferNumber); //} //if (dstPrivPixmap->frameBufferNumber != 0) //{ // dstY += (var_info.yres * dstPrivPixmap->frameBufferNumber); //} ump_secure_id srcID = ump_secure_id_get(srcPrivPixmap->mem_info->handle); memclient_attach_dmabuf_param_t srcParam; srcParam.handle = srcID; ret = ioctl(memclient_fd, MEMCLIENT_ATTACH_UMP, &srcParam); if (ret < 0) { ERROR_STR("srcParam MEMCLIENT_ATTACH_UMP failed.\n"); } ump_secure_id dstID = ump_secure_id_get(dstPrivPixmap->mem_info->handle); memclient_attach_dmabuf_param_t dstParam; dstParam.handle = dstID; ret = ioctl(memclient_fd, MEMCLIENT_ATTACH_UMP, &dstParam); if (ret < 0) { ERROR_STR("dstParam MEMCLIENT_ATTACH_UMP failed.\n"); } // Configure GE2D struct config_para_ex_s configex; memset(&configex, 0x00, sizeof(configex)); configex.src_para.mem_type = CANVAS_ALLOC; //CANVAS_OSD0 configex.src_para.left = 0; configex.src_para.top = 0; configex.src_para.width = var_info.xres; configex.src_para.height = var_info.yres; configex.src_para.x_rev = revX; configex.src_para.y_rev = revY; configex.src_planes[0].addr = srcParam.physical_address; configex.src_planes[0].w = configex.src_para.width; configex.src_planes[0].h = configex.src_para.height; configex.src_para.format = GE2D_FORMAT_S32_ARGB; // GE2D_FORMAT_S32_BGRA; // GE2D_FMT_S32_RGBA; configex.src2_para.mem_type = CANVAS_TYPE_INVALID; configex.dst_para.mem_type = CANVAS_ALLOC; // CANVAS_OSD0; configex.dst_para.left = 0; configex.dst_para.top = 0; configex.dst_para.width = configex.src_para.width; configex.dst_para.height = configex.src_para.height; configex.dst_para.x_rev = configex.src_para.x_rev; configex.dst_para.y_rev = configex.src_para.y_rev; configex.dst_planes[0].addr = dstParam.physical_address; configex.dst_planes[0].w = configex.dst_para.width; configex.dst_planes[0].h = configex.dst_para.height; configex.dst_para.format = GE2D_FORMAT_S32_ARGB; ret = ioctl(ge2d_fd, GE2D_CONFIG_EX, &configex); if (ret < 0) { ERROR_STR("GE2D_CONFIG_EX failed.\n"); } // Perform the blit operation struct ge2d_para_s blitRect; memset(&blitRect, 0, sizeof(blitRect)); blitRect.src1_rect.x = srcX; blitRect.src1_rect.y = srcY; blitRect.src1_rect.w = width; blitRect.src1_rect.h = height; blitRect.dst_rect.x = dstX; blitRect.dst_rect.y = dstY; if (revY) // && height > 1 { blitRect.src1_rect.y -= 1; } ret = ioctl(ge2d_fd, GE2D_BLIT, &blitRect); if (ret < 0) { ERROR_STR("GE2D_BLIT failed.\n"); } ret = ioctl(memclient_fd, MEMCLIENT_RELEASE_UMP, dstID); if (ret < 0) { ERROR_STR("dstID MEMCLIENT_RELEASE_UMP failed.\n"); } ret = ioctl(memclient_fd, MEMCLIENT_RELEASE_UMP, srcID); if (ret < 0) { ERROR_STR("srcID MEMCLIENT_RELEASE_UMP failed.\n"); } }
static DRI2Buffer2Ptr MaliDRI2CreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format) { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; DRI2Buffer2Ptr buffer; MaliDRI2BufferPrivatePtr privates; ump_handle handle; FBDevPtr pMxv = FBDEVPTR(pScrn); Rk30MaliPtr rk_3d = pMxv->Rk30Mali; OvlHWPtr overlay = pMxv->OvlHW; Bool can_use_overlay = TRUE; PixmapPtr pWindowPixmap; if (pDraw->type == DRAWABLE_WINDOW && (pWindowPixmap = pScreen->GetWindowPixmap((WindowPtr)pDraw))) { DebugMsg("win=%p (w=%d, h=%d, x=%d, y=%d) has backing pix=%p (w=%d, h=%d, screen_x=%d, screen_y=%d)\n", pDraw, pDraw->width, pDraw->height, pDraw->x, pDraw->y, pWindowPixmap, pWindowPixmap->drawable.width, pWindowPixmap->drawable.height, pWindowPixmap->screen_x, pWindowPixmap->screen_y); } if(attachment != DRI2BufferBackLeft && rk_3d->buf_back != NULL){ DebugMsg("DRI2 return NullBuffer\n"); return rk_3d->buf_back; } if (!(buffer = calloc(1, sizeof *buffer))) { ErrorF("MaliDRI2CreateBuffer: calloc failed\n"); return NULL; } /* If it is a pixmap, just migrate this pixmap to UMP buffer */ if (pDraw->type == DRAWABLE_PIXMAP) { if (!(privates = MigratePixmapToUMP((PixmapPtr)pDraw))) { ErrorF("MaliDRI2CreateBuffer: MigratePixmapToUMP failed\n"); free(buffer); return NULL; } privates->refcount++; buffer->attachment = attachment; buffer->driverPrivate = privates; buffer->format = format; buffer->flags = 0; buffer->cpp = pDraw->bitsPerPixel / 8; buffer->pitch = ((PixmapPtr)pDraw)->devKind; buffer->name = ump_secure_id_get(privates->handle); DebugMsg("DRI2CreateBuffer pix=%p, buf=%p:%p, att=%d, ump=%d:%d, w=%d, h=%d, cpp=%d, depth=%d\n", pDraw, buffer, privates, attachment, buffer->name, buffer->flags, privates->width, privates->height, buffer->cpp, privates->depth); return buffer; } /* The drawable must be a window for using hardware overlays */ if (pDraw->type != DRAWABLE_WINDOW){ ErrorF("Unexpected pDraw->type (%d) in MaliDRI2CreateBuffer\n", pDraw->type); return NULL; } if (!(privates = calloc(1, sizeof *privates))) { ErrorF("MaliDRI2CreateBuffer: calloc failed\n"); free(buffer); return NULL; } /* We could not get framebuffer secure id */ if (rk_3d->ump_fb_secure_id1 == UMP_INVALID_SECURE_ID) can_use_overlay = FALSE; /* Overlay is already used by a different window */ if (rk_3d->pOverlayWin && rk_3d->pOverlayWin != (void *)pDraw) can_use_overlay = FALSE; /* TODO: try to support other color depths later */ if (pDraw->bitsPerPixel != 32) can_use_overlay = FALSE; /* The default common values */ buffer->attachment = attachment; buffer->driverPrivate = privates; buffer->format = format; buffer->flags = 0; buffer->cpp = pDraw->bitsPerPixel / 8; /* Stride must be 8 bytes aligned for Mali400 */ // buffer->pitch = ((buffer->cpp * pDraw->width + 7) / 8) * 8; buffer->pitch = ((buffer->cpp * overlay->cur_var.xres_virtual + 7) / 8) * 8; privates->size = pDraw->height * buffer->pitch; privates->width = pDraw->width; privates->height = pDraw->height; privates->depth = pDraw->depth; /* if (disp && disp->framebuffer_size - disp->gfx_layer_size < privates->size) { DebugMsg("Not enough space in the offscreen framebuffer (wanted %d for DRI2)\n", privates->size); can_use_overlay = FALSE; } */ /* if((pDraw->width+pDraw->x) > overlay->cur_var.xres || (pDraw->height+pDraw->y) > overlay->cur_var.yres) can_use_overlay = FALSE; */ if(pDraw->width < 2 || pDraw->height < 2){ can_use_overlay = FALSE; } if(attachment != DRI2BufferBackLeft){ // can_use_overlay = FALSE; free(privates); buffer->driverPrivate = NULL; buffer->name = UMP_INVALID_SECURE_ID; if(rk_3d->buf_back == NULL) rk_3d->buf_back = buffer; goto end; } if(rk_3d->OvlPg == ERRORL){ rk_3d->OvlPg = OvlAllocLay(pScrn, ANYL); if(rk_3d->OvlPg == ERRORL) can_use_overlay = FALSE; else{//init OvlSetupFb(pScrn, 0, 0, rk_3d->OvlPg); OvlEnable(pScrn, rk_3d->OvlPg, 1); } } rk_3d->bOverlayWinEnabled = can_use_overlay; if (can_use_overlay) rk_3d->pOverlayWin = (WindowPtr)pDraw; // buffer->pitch = ((buffer->cpp * overlay->OvlLay[rk_3d->OvlPg].var.xres_virtual + 7) / 8) * 8; // rk_3d->bOverlayWinEnabled = TRUE; // Stride must be 8 bytes aligned for Mali400 // privates->size = pDraw->height * buffer->pitch; // buffer->flags = 0; privates->handle = UMP_INVALID_MEMORY_HANDLE; privates->addr = NULL; buffer->name = rk_3d->ump_fb_secure_id1; privates->handle = ump_handle_create_from_secure_id(buffer->name); privates->addr = ump_mapped_pointer_get(privates->handle); // privates->addr = NULL;//(void*)0x94000000; /* } else { // rk_3d->bOverlayWinEnabled = FALSE; // Allocate UMP memory buffer #ifdef HAVE_LIBUMP_CACHE_CONTROL privates->handle = ump_ref_drv_allocate(privates->size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR | UMP_REF_DRV_CONSTRAINT_USE_CACHE); ump_cache_operations_control(UMP_CACHE_OP_START); ump_switch_hw_usage_secure_id(ump_secure_id_get(privates->handle), UMP_USED_BY_MALI); ump_cache_operations_control(UMP_CACHE_OP_FINISH); #else privates->handle = ump_ref_drv_allocate(privates->size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR); #endif if (privates->handle == UMP_INVALID_MEMORY_HANDLE) { ErrorF("Failed to allocate UMP buffer (size=%d)\n", (int)privates->size); } privates->addr = ump_mapped_pointer_get(privates->handle); buffer->name = ump_secure_id_get(privates->handle); buffer->flags = 0; } */ end: DebugMsg("DRI2CreateBuffer win=%p, buf=%p:%p, att=%d, ump=%d:%d, w=%d, h=%d, cpp=%d, depth=%d adr=%p\n", pDraw, buffer, privates, attachment, buffer->name, buffer->flags, privates->width, privates->height, buffer->cpp, privates->depth,privates->addr); return buffer; }
//static int gralloc_alloc_buffer(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle, bool reserve) static int gralloc_alloc_buffer(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle, int reserve) { #if GRALLOC_ARM_DMA_BUF_MODULE { private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); ion_user_handle_t ion_hnd; unsigned char *cpu_ptr; int shared_fd; int ret; unsigned int heap_mask; int Ion_type; bool Ishwc = false; int Ion_flag = 0; if(usage == (GRALLOC_USAGE_HW_COMPOSER|GRALLOC_USAGE_HW_RENDER)) Ishwc = true; //ret = ion_alloc(m->ion_client, size, 0, ION_HEAP_SYSTEM_MASK, 0, &ion_hnd); #ifdef USE_X86 if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) Ion_flag = (ION_FLAG_CACHED|ION_FLAG_CACHED_NEEDS_SYNC); if(is_out_log()) ALOGD("usage=%x,protect=%x,ion_flag=%x,mmu=%d",usage,GRALLOC_USAGE_PROTECTED,Ion_flag,g_MMU_stat); if (usage & GRALLOC_USAGE_PROTECTED) //secrue memery { unsigned long phys; ret = ion_secure_alloc(m->ion_client, size,&phys); //ALOGD("secure_alloc ret=%d,phys=%x",ret,(int)phys); if(ret != 0) { AERR("Failed to ion_alloc from ion_client:%d, size: %d", m->ion_client, size); return -1; } private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_ION, usage, size, 0, 0); if (NULL != hnd) { hnd->share_fd = 0; hnd->ion_hnd = 0; hnd->type = 0; hnd->phy_addr = (int)phys; *pHandle = hnd; if(is_out_log()) ALOGD("secure_alloc_ok phy=%x",usage,hnd->phy_addr); return 0; } else { AERR("Gralloc out of mem for ion_client:%d", m->ion_client); } close(shared_fd); return -1; } #endif //ret = ion_alloc(m->ion_client, size, 0, ION_HEAP_SYSTEM_MASK, 0, &ion_hnd); #ifdef USE_X86 if(g_MMU_stat && ((usage&GRALLOC_USAGE_HW_CAMERA_WRITE)==0) && !(usage & GRALLOC_USAGE_PRIVATE_2) && !Ishwc) #else if(g_MMU_stat) #endif { heap_mask = ION_HEAP(ION_VMALLOC_HEAP_ID); #ifdef USE_X86 if (usage & GRALLOC_USAGE_PRIVATE_2) { heap_mask |= ION_HEAP(ION_SECURE_HEAP_ID); } #endif ret = ion_alloc(m->ion_client, size, 0, heap_mask, Ion_flag, &ion_hnd); Ion_type = 1; } else { heap_mask = ION_HEAP(ION_CMA_HEAP_ID); #ifdef USE_X86 if (usage & GRALLOC_USAGE_PRIVATE_2) { heap_mask |= ION_HEAP(ION_SECURE_HEAP_ID); } #endif if (usage == (GRALLOC_USAGE_HW_CAMERA_WRITE|GRALLOC_USAGE_SW_READ_OFTEN)) { ret = ion_alloc(m->ion_client, size, 0,heap_mask, (ION_FLAG_CACHED|ION_FLAG_CACHED_NEEDS_SYNC), &ion_hnd); } else { ret = ion_alloc(m->ion_client, size, 0,heap_mask, Ion_flag, &ion_hnd); } #ifdef USE_X86 if(g_MMU_stat && Ishwc) { Ion_type = 1; } else #endif Ion_type = 0; } if (ret != 0) { if( (heap_mask & ION_HEAP(ION_CMA_HEAP_ID)) #ifdef USE_X86 && !Ishwc #endif ) { #ifdef BOARD_WITH_IOMMU heap_mask = ION_HEAP(ION_VMALLOC_HEAP_ID); #else heap_mask = ION_HEAP(ION_CARVEOUT_HEAP_ID); #endif ret = ion_alloc(m->ion_client, size, 0, heap_mask, 0, &ion_hnd ); { if( ret != 0) { AERR("Force to VMALLOC fail ion_client:%d", m->ion_client); return -1; } else { ALOGD("Force to VMALLOC sucess !"); Ion_type = 1; } } } else { AERR("Failed to ion_alloc from ion_client:%d, size: %d", m->ion_client, size); return -1; } } ret = ion_share(m->ion_client, ion_hnd, &shared_fd); if (ret != 0) { AERR("ion_share( %d ) failed", m->ion_client); if (0 != ion_free(m->ion_client, ion_hnd)) { AERR("ion_free( %d ) failed", m->ion_client); } return -1; } cpu_ptr = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shared_fd, 0); #ifdef USE_X86 //memset(cpu_ptr, 0, size); #endif if (MAP_FAILED == cpu_ptr) { AERR("ion_map( %d ) failed", m->ion_client); if (0 != ion_free(m->ion_client, ion_hnd)) { AERR("ion_free( %d ) failed", m->ion_client); } close(shared_fd); return -1; } private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_ION, usage, size, (int)cpu_ptr, private_handle_t::LOCK_STATE_MAPPED); if (NULL != hnd) { unsigned long cma_phys = 0; hnd->share_fd = shared_fd; hnd->ion_hnd = ion_hnd; hnd->type = Ion_type; if(!Ion_type) { int pret; pret = ion_get_phys(m->ion_client, ion_hnd, &cma_phys); //ALOGD("ion_get_phy ret=%d,cma_phys=%x",pret,cma_phys); } hnd->phy_addr = (int)cma_phys; *pHandle = hnd; if(is_out_log()) ALOGD("alloc_info fd[%d],type=%d,phy=%x",hnd->share_fd,hnd->type,hnd->phy_addr); return 0; } else { AERR("Gralloc out of mem for ion_client:%d", m->ion_client); } close(shared_fd); ret = munmap(cpu_ptr, size); if (0 != ret) { AERR("munmap failed for base:%p size: %d", cpu_ptr, size); } ret = ion_free(m->ion_client, ion_hnd); if (0 != ret) { AERR("ion_free( %d ) failed", m->ion_client); } return -1; } #endif #if GRALLOC_ARM_UMP_MODULE { ump_handle ump_mem_handle; void *cpu_ptr; ump_secure_id ump_id; int constraints; size = round_up_to_page_size(size); if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN) { constraints = UMP_REF_DRV_CONSTRAINT_USE_CACHE; } else { constraints = UMP_REF_DRV_CONSTRAINT_NONE; } if ( reserve & 0x01) { constraints |= UMP_REF_DRV_CONSTRAINT_PRE_RESERVE; } if( reserve & 0x02) { constraints |= UMP_REF_DRV_UK_CONSTRAINT_MEM_SWITCH; } #ifdef GRALLOC_SIMULATE_FAILURES /* if the failure condition matches, fail this iteration */ if (__ump_alloc_should_fail()) { ump_mem_handle = UMP_INVALID_MEMORY_HANDLE; } else #endif { ump_mem_handle = ump_ref_drv_allocate(size, (ump_alloc_constraints)constraints); if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle) { cpu_ptr = ump_mapped_pointer_get(ump_mem_handle); if (NULL != cpu_ptr) { ump_id = ump_secure_id_get(ump_mem_handle); if (UMP_INVALID_SECURE_ID != ump_id) { private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_UMP, usage, size, (int)cpu_ptr, private_handle_t::LOCK_STATE_MAPPED, ump_id, ump_mem_handle); if (NULL != hnd) { #ifdef USE_LCDC_COMPOSER if( reserve & 0x02) { hnd->phy_addr = 0; } else { hnd->phy_addr = ump_phy_addr_get(ump_mem_handle); } #endif *pHandle = hnd; return 0; } else { AERR("gralloc_alloc_buffer() failed to allocate handle. ump_handle = %p, ump_id = %d", ump_mem_handle, ump_id); } } else { AERR("gralloc_alloc_buffer() failed to retrieve valid secure id. ump_handle = %p", ump_mem_handle); } ump_mapped_pointer_release(ump_mem_handle); } else { AERR("gralloc_alloc_buffer() failed to map UMP memory. ump_handle = %p", ump_mem_handle); } ump_reference_release(ump_mem_handle); } else { AERR("gralloc_alloc_buffer() failed to allocate UMP memory. size:%d constraints: %d", size, constraints); } } return -1; } #endif
int main(int argc, char *argv[]) { int result = EXIT_FAILURE; if (UMP_OK == ump_open()) { const int SZ_4KB = 4096; const int alloc_size = 16 * SZ_4KB; const int resize_1 = 1 * SZ_4KB; const int resize_2 = -9 * SZ_4KB; #define NUM_ALLOCS 128 ump_handle h[NUM_ALLOCS]; int i; for (i = 0; i < NUM_ALLOCS; i++) { h[i] = UMP_INVALID_MEMORY_HANDLE; } for (i = 0; i < NUM_ALLOCS; i++) { u8 * p; h[i] = ump_allocate(alloc_size, UMP_PROT_CPU_RD | UMP_PROT_CPU_WR | UMP_HINT_CPU_RD | UMP_HINT_CPU_WR | UMP_PROT_W_RD | UMP_PROT_W_WR); if (UMP_INVALID_MEMORY_HANDLE == h[i]) { printf("Failed to allocate\n"); break; } p = ump_map(h[i], 0, alloc_size); if (NULL != p) { STDLIB_MEMSET(p, 0xFF, alloc_size); ump_cpu_msync_now(h[i], UMP_MSYNC_CLEAN, p, alloc_size); ump_unmap(h[i], p, alloc_size); } else { printf("Failed to map\n"); break; } } if (i == NUM_ALLOCS) { int resize_failure = 0; printf("%d allocations succeeded\n", NUM_ALLOCS); for (i = 0; i < NUM_ALLOCS; i++) { ump_secure_id check_id; check_id = ump_secure_id_get(h[i]); if (UMP_INVALID_SECURE_ID == check_id) { printf("Handle %d has an invalid secure id!\n", i); } else { int j; for (j = i + 1; j < NUM_ALLOCS; j++) { ump_secure_id id; id = ump_secure_id_get(h[j]); if (id == check_id) { printf("Duplicate IDs found for handles %d and %d, both have %u\n", i, j, id); } } } } printf("doing resize check\n"); for (i = 0; i < NUM_ALLOCS; i++) { u64 new_size; ump_resize_result res; res = ump_resize(h[i], resize_1, &new_size); if (UMP_RESIZE_OK != res) { printf("resize failed with error code 0x%08X\n", res); resize_failure++; } else { if (new_size != (alloc_size + resize_1)) { printf("Hmm, the new size isn't what I expected: %llu != %d\n", (unsigned long long)new_size, alloc_size + resize_1); resize_failure++; } else { int j; u8 * map; map = (u8*)ump_map(h[i], 0, new_size); if (NULL == map) { resize_failure++; /* record this as a resize failure */ break; } for (j = 0; j < alloc_size; j++) { if (map[j] != 0xFF) { printf("Expected 0xFF, have 0x%02X\n", map[j]); resize_failure++; } } for (j = alloc_size; j < new_size; j++) { if (map[j] != 0) { printf("Expected 0x00, have 0x%02X\n", map[j]); resize_failure++; } } ump_unmap(h[i], map, new_size); } res = ump_resize(h[i], resize_2, &new_size); if (UMP_RESIZE_OK != res) { printf("resize failed with error code 0x%08x\n", res); resize_failure++; } else { if (new_size != (alloc_size + resize_1 + resize_2)) { printf("Hmm, the new size isn't what I expected: %llu != %d\n", (unsigned long long)new_size, alloc_size + resize_1 + resize_2); resize_failure++; } else { int j; u8 * map; map = (u8*)ump_map(h[i], 0, new_size); if (NULL == map) { resize_failure++; break; } ump_cpu_msync_now(h[i], UMP_MSYNC_CLEAN_AND_INVALIDATE, map, new_size); for (j = 0; j < new_size; j++) { if (map[j] != 0xFF) { printf("expected 0xFF, have 0x%02X\n", map[j]); resize_failure++; } } ump_unmap(h[i], map, new_size); } } } } if (resize_failure) { printf("%d resize failures found\n", resize_failure); } else { printf("resize check OK\n"); result = EXIT_SUCCESS; } } for (i = 0; i < NUM_ALLOCS; i++) { ump_release(h[i]); } ump_close(); } return result; }