mali_descriptor_mapping * mali_descriptor_mapping_create(int init_entries, int max_entries) { mali_descriptor_mapping * map = _mali_osk_calloc(1, sizeof(mali_descriptor_mapping)); init_entries = MALI_PAD_INT(init_entries); max_entries = MALI_PAD_INT(max_entries); if (NULL != map) { map->table = descriptor_table_alloc(init_entries); if (NULL != map->table) { map->lock = _mali_osk_mutex_rw_init(_MALI_OSK_LOCKFLAG_ORDERED, _MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP); if (NULL != map->lock) { _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */ map->max_nr_mappings_allowed = max_entries; map->current_nr_mappings = init_entries; return map; } descriptor_table_free(map->table); } _mali_osk_free(map); } return NULL; }
void mali_pp_delete(struct mali_pp_core *core) { u32 i; MALI_DEBUG_ASSERT_POINTER(core); _mali_osk_timer_term(core->timeout_timer); _mali_osk_irq_term(core->irq); mali_hw_core_delete(&core->hw_core); /* Remove core from global list */ for (i = 0; i < mali_global_num_pp_cores; i++) { if (mali_global_pp_cores[i] == core) { mali_global_pp_cores[i] = NULL; mali_global_num_pp_cores--; break; } } _mali_osk_free(core); }
_mali_osk_errcode_t mali_memory_session_begin(struct mali_session_data * session_data) { MALI_DEBUG_PRINT(5, ("Memory session begin\n")); /* Create descriptor mapping table */ session_data->descriptor_mapping = mali_descriptor_mapping_create(MALI_MEM_DESCRIPTORS_INIT, MALI_MEM_DESCRIPTORS_MAX); if (NULL == session_data->descriptor_mapping) { MALI_ERROR(_MALI_OSK_ERR_NOMEM); } session_data->memory_lock = _mali_osk_mutex_init(_MALI_OSK_LOCKFLAG_ORDERED, _MALI_OSK_LOCK_ORDER_MEM_SESSION); if (NULL == session_data->memory_lock) { mali_descriptor_mapping_destroy(session_data->descriptor_mapping); _mali_osk_free(session_data); MALI_ERROR(_MALI_OSK_ERR_FAULT); } MALI_DEBUG_PRINT(5, ("MMU session begin: success\n")); MALI_SUCCESS; }
void mali_l2_cache_delete(struct mali_l2_cache_core *cache) { u32 i; /* reset to defaults */ mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)mali_l2_max_reads); mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_DEFAULT); _mali_osk_lock_term(cache->counter_lock); _mali_osk_lock_term(cache->command_lock); mali_hw_core_delete(&cache->hw_core); for (i = 0; i < mali_global_num_l2_cache_cores; i++) { if (mali_global_l2_cache_cores[i] == cache) { mali_global_l2_cache_cores[i] = NULL; mali_global_num_l2_cache_cores--; } } _mali_osk_free(cache); }
void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id ) { /* Check this is the right system */ MALI_DEBUG_ASSERT( id == mali_subsystem_pmm_id ); MALI_DEBUG_ASSERT_POINTER(pmm_state); if( pmm_state ) { _mali_osk_resource_type_t t = PMU; #if PMM_OS_TEST power_test_end(); #endif /* Get the lock so we can shutdown */ MALI_PMM_LOCK(pmm_state); #if MALI_STATE_TRACKING pmm_state->mali_pmm_lock_acquired = 1; #endif /* MALI_STATE_TRACKING */ pmm_state->status = MALI_PMM_STATUS_OFF; #if MALI_STATE_TRACKING pmm_state->mali_pmm_lock_acquired = 0; #endif /* MALI_STATE_TRACKING */ MALI_PMM_UNLOCK(pmm_state); _mali_osk_pmm_ospmm_cleanup(); pmm_policy_term(pmm_state); _mali_osk_irq_term( pmm_state->irq ); _mali_osk_notification_queue_term( pmm_state->queue ); _mali_osk_notification_queue_term( pmm_state->iqueue ); if (pmm_state->cores_registered) mali_platform_powerdown(pmm_state->cores_registered); if( pmm_state->pmu_initialized ) mali_platform_deinit(&t); _mali_osk_atomic_term( &(pmm_state->messages_queued) ); MALI_PMM_LOCK_TERM(pmm_state); _mali_osk_free(pmm_state); pmm_state = NULL; } MALIPMM_DEBUG_PRINT( ("PMM: subsystem terminated\n") ); }
_mali_osk_errcode_t mali_pmm_pmu_deinit(_mali_osk_resource_type_t *type) { if (*type == PMU) { if( pmu_info ) { #ifndef MSTAR_RIU_ENABLED _mali_osk_mem_unmapioregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->reg_mapped); #endif _mali_osk_mem_unreqregion(pmu_info->reg_base_addr, pmu_info->reg_size); _mali_osk_free(pmu_info); pmu_info = NULL; MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Terminated PMU\n") ); } } else { /* Didn't expect a different resource */ MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } MALI_SUCCESS; }
struct mali_page_directory *mali_mmu_pagedir_alloc(void) { struct mali_page_directory *pagedir; _mali_osk_errcode_t err; mali_dma_addr phys; pagedir = _mali_osk_calloc(1, sizeof(struct mali_page_directory)); if (NULL == pagedir) { return NULL; } err = mali_mmu_get_table_page(&phys, &pagedir->page_directory_mapped); if (_MALI_OSK_ERR_OK != err) { _mali_osk_free(pagedir); return NULL; } pagedir->page_directory = (u32)phys; /* Zero page directory */ fill_page(pagedir->page_directory_mapped, 0); return pagedir; }
struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t *resource) { struct mali_dlbu_core *core = NULL; MALI_DEBUG_PRINT(2, ("Mali DLBU: Creating Mali dynamic load balancing unit: %s\n", resource->description)); core = _mali_osk_malloc(sizeof(struct mali_dlbu_core)); if (NULL != core) { if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI_DLBU_SIZE)) { core->pp_cores_mask = 0; if (_MALI_OSK_ERR_OK == mali_dlbu_reset(core)) { return core; } MALI_PRINT_ERROR(("Failed to reset DLBU %s\n", core->hw_core.description)); mali_hw_core_delete(&core->hw_core); } _mali_osk_free(core); } else { MALI_PRINT_ERROR(("Mali DLBU: Failed to allocate memory for DLBU core\n")); } return NULL; }
static int mali_ump_map(struct mali_session_data *session, mali_mem_allocation *descriptor) { ump_dd_handle ump_mem; u32 nr_blocks; u32 i; ump_dd_physical_block *ump_blocks; struct mali_page_directory *pagedir; u32 offset = 0; u32 prop; _mali_osk_errcode_t err; MALI_DEBUG_ASSERT_POINTER(session); MALI_DEBUG_ASSERT_POINTER(descriptor); MALI_DEBUG_ASSERT(MALI_MEM_UMP == descriptor->type); ump_mem = descriptor->ump_mem.handle; MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID != ump_mem); nr_blocks = ump_dd_phys_block_count_get(ump_mem); if (nr_blocks == 0) { MALI_DEBUG_PRINT(1, ("No block count\n")); return -EINVAL; } ump_blocks = _mali_osk_malloc(sizeof(*ump_blocks)*nr_blocks); if (NULL == ump_blocks) { return -ENOMEM; } if (UMP_DD_INVALID == ump_dd_phys_blocks_get(ump_mem, ump_blocks, nr_blocks)) { _mali_osk_free(ump_blocks); return -EFAULT; } pagedir = session->page_directory; prop = descriptor->mali_mapping.properties; err = mali_mem_mali_map_prepare(descriptor); if (_MALI_OSK_ERR_OK != err) { MALI_DEBUG_PRINT(1, ("Mapping of UMP memory failed\n")); _mali_osk_free(ump_blocks); return -ENOMEM; } for(i = 0; i < nr_blocks; ++i) { u32 virt = descriptor->mali_mapping.addr + offset; MALI_DEBUG_PRINT(7, ("Mapping in 0x%08x size %d\n", ump_blocks[i].addr , ump_blocks[i].size)); mali_mmu_pagedir_update(pagedir, virt, ump_blocks[i].addr, ump_blocks[i].size, prop); offset += ump_blocks[i].size; } if (descriptor->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) { u32 virt = descriptor->mali_mapping.addr + offset; /* Map in an extra virtual guard page at the end of the VMA */ MALI_DEBUG_PRINT(6, ("Mapping in extra guard page\n")); mali_mmu_pagedir_update(pagedir, virt, ump_blocks[0].addr, _MALI_OSK_MALI_PAGE_SIZE, prop); offset += _MALI_OSK_MALI_PAGE_SIZE; } _mali_osk_free(ump_blocks); return 0; }
void mali_mmu_delete(struct mali_mmu_core *mmu) { _mali_osk_irq_term(mmu->irq); mali_hw_core_delete(&mmu->hw_core); _mali_osk_free(mmu); }
mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size, const char *name) { mali_physical_memory_allocator * allocator; block_allocator * info; u32 usable_size; u32 num_blocks; usable_size = size & ~(MALI_BLOCK_SIZE - 1); MALI_DEBUG_PRINT(3, ("Mali block allocator create for region starting at 0x%08X length 0x%08X\n", base_address, size)); MALI_DEBUG_PRINT(4, ("%d usable bytes\n", usable_size)); num_blocks = usable_size / MALI_BLOCK_SIZE; MALI_DEBUG_PRINT(4, ("which becomes %d blocks\n", num_blocks)); if (usable_size == 0) { MALI_DEBUG_PRINT(1, ("Memory block of size %d is unusable\n", size)); return NULL; } allocator = _mali_osk_malloc(sizeof(mali_physical_memory_allocator)); if (NULL != allocator) { info = _mali_osk_malloc(sizeof(block_allocator)); if (NULL != info) { info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED, 0, 105); if (NULL != info->mutex) { info->all_blocks = _mali_osk_malloc(sizeof(block_info) * num_blocks); if (NULL != info->all_blocks) { u32 i; info->first_free = NULL; info->num_blocks = num_blocks; info->base = base_address; info->cpu_usage_adjust = cpu_usage_adjust; for ( i = 0; i < num_blocks; i++) { info->all_blocks[i].next = info->first_free; info->first_free = &info->all_blocks[i]; } allocator->allocate = block_allocator_allocate; allocator->allocate_page_table_block = block_allocator_allocate_page_table_block; allocator->destroy = block_allocator_destroy; allocator->stat = block_allocator_stat; allocator->ctx = info; allocator->name = name; return allocator; } _mali_osk_lock_term(info->mutex); } _mali_osk_free(info); } _mali_osk_free(allocator); } return NULL; }
static mali_physical_memory_allocation_result block_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) { block_allocator * info; u32 left; block_info * last_allocated = NULL; mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_NONE; block_allocator_allocation *ret_allocation; MALI_DEBUG_ASSERT_POINTER(ctx); MALI_DEBUG_ASSERT_POINTER(descriptor); MALI_DEBUG_ASSERT_POINTER(offset); MALI_DEBUG_ASSERT_POINTER(alloc_info); info = (block_allocator*)ctx; left = descriptor->size - *offset; MALI_DEBUG_ASSERT(0 != left); if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE; ret_allocation = _mali_osk_malloc( sizeof(block_allocator_allocation) ); if ( NULL == ret_allocation ) { /* Failure; try another allocator by returning MALI_MEM_ALLOC_NONE */ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); return result; } ret_allocation->start_offset = *offset; ret_allocation->mapping_length = 0; while ((left > 0) && (info->first_free)) { block_info * block; u32 phys_addr; u32 padding; u32 current_mapping_size; block = info->first_free; info->first_free = info->first_free->next; block->next = last_allocated; last_allocated = block; phys_addr = get_phys(info, block); padding = *offset & (MALI_BLOCK_SIZE-1); if (MALI_BLOCK_SIZE - padding < left) { current_mapping_size = MALI_BLOCK_SIZE - padding; } else { current_mapping_size = left; } if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, phys_addr + padding, info->cpu_usage_adjust, current_mapping_size)) { MALI_DEBUG_PRINT(1, ("Mapping of physical memory failed\n")); result = MALI_MEM_ALLOC_INTERNAL_FAILURE; mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->start_offset, ret_allocation->mapping_length, (_mali_osk_mem_mapregion_flags_t)0); /* release all memory back to the pool */ while (last_allocated) { /* This relinks every block we've just allocated back into the free-list */ block = last_allocated->next; last_allocated->next = info->first_free; info->first_free = last_allocated; last_allocated = block; } break; } *offset += current_mapping_size; left -= current_mapping_size; ret_allocation->mapping_length += current_mapping_size; } _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); if (last_allocated) { if (left) result = MALI_MEM_ALLOC_PARTIAL; else result = MALI_MEM_ALLOC_FINISHED; /* Record all the information about this allocation */ ret_allocation->last_allocated = last_allocated; ret_allocation->engine = engine; ret_allocation->descriptor = descriptor; alloc_info->ctx = info; alloc_info->handle = ret_allocation; alloc_info->release = block_allocator_release; } else { /* Free the allocation information - nothing to be passed back */ _mali_osk_free( ret_allocation ); } return result; }
_mali_osk_errcode_t malipmm_create(_mali_osk_resource_t *resource) { /* Create PMM state memory */ MALI_DEBUG_ASSERT( pmm_state == NULL ); pmm_state = (_mali_pmm_internal_state_t *) _mali_osk_malloc(sizeof(*pmm_state)); MALI_CHECK_NON_NULL( pmm_state, _MALI_OSK_ERR_NOMEM ); /* All values get 0 as default */ _mali_osk_memset(pmm_state, 0, sizeof(*pmm_state)); /* Set up the initial PMM state */ pmm_state->waiting = 0; pmm_state->status = MALI_PMM_STATUS_IDLE; pmm_state->state = MALI_PMM_STATE_UNAVAILABLE; /* Until a core registers */ /* Set up policy via compile time option for the moment */ #if MALI_PMM_ALWAYS_ON pmm_state->policy = MALI_PMM_POLICY_ALWAYS_ON; #else pmm_state->policy = MALI_PMM_POLICY_JOB_CONTROL; #endif #if MALI_PMM_TRACE _mali_pmm_trace_policy_change( MALI_PMM_POLICY_NONE, pmm_state->policy ); #endif /* Set up assumes all values are initialized to NULL or MALI_FALSE, so * we can exit halfway through set up and perform clean up */ #if !MALI_PMM_NO_PMU if( mali_platform_init(resource) != _MALI_OSK_ERR_OK ) goto pmm_fail_cleanup; pmm_state->pmu_initialized = MALI_TRUE; #endif pmm_state->queue = _mali_osk_notification_queue_init(); if( !pmm_state->queue ) goto pmm_fail_cleanup; pmm_state->iqueue = _mali_osk_notification_queue_init(); if( !pmm_state->iqueue ) goto pmm_fail_cleanup; /* We are creating an IRQ handler just for the worker thread it gives us */ pmm_state->irq = _mali_osk_irq_init( _MALI_OSK_IRQ_NUMBER_PMM, malipmm_irq_uhandler, malipmm_irq_bhandler, NULL, NULL, (void *)pmm_state, /* PMM state is passed to IRQ */ "PMM handler" ); if( !pmm_state->irq ) goto pmm_fail_cleanup; #ifdef CONFIG_SMP mali_pmm_lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)( _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 0); if( !mali_pmm_lock ) goto pmm_fail_cleanup; #endif /* CONFIG_SMP */ pmm_state->lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 75); if( !pmm_state->lock ) goto pmm_fail_cleanup; if( _mali_osk_atomic_init( &(pmm_state->messages_queued), 0 ) != _MALI_OSK_ERR_OK ) { goto pmm_fail_cleanup; } MALIPMM_DEBUG_PRINT( ("PMM: subsystem created, policy=%d\n", pmm_state->policy) ); MALI_SUCCESS; pmm_fail_cleanup: MALI_PRINT_ERROR( ("PMM: subsystem failed to be created\n") ); if( pmm_state ) { _mali_osk_resource_type_t t = PMU; if( pmm_state->lock ) _mali_osk_lock_term( pmm_state->lock ); if( pmm_state->irq ) _mali_osk_irq_term( pmm_state->irq ); if( pmm_state->queue ) _mali_osk_notification_queue_term( pmm_state->queue ); if( pmm_state->iqueue ) _mali_osk_notification_queue_term( pmm_state->iqueue ); if( pmm_state->pmu_initialized ) ( mali_platform_deinit(&t) ); _mali_osk_free(pmm_state); pmm_state = NULL; } MALI_ERROR( _MALI_OSK_ERR_FAULT ); }
UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks) { ump_dd_mem * mem; unsigned long size_total = 0; int map_id; u32 i; /* Go through the input blocks and verify that they are sane */ for (i=0; i < num_blocks; i++) { unsigned long addr = blocks[i].addr; unsigned long size = blocks[i].size; DBG_MSG(5, ("Adding physical memory to new handle. Address: 0x%08lx, size: %lu\n", addr, size)); size_total += blocks[i].size; if (0 != UMP_ADDR_ALIGN_OFFSET(addr)) { MSG_ERR(("Trying to create UMP memory from unaligned physical address. Address: 0x%08lx\n", addr)); return UMP_DD_HANDLE_INVALID; } if (0 != UMP_ADDR_ALIGN_OFFSET(size)) { MSG_ERR(("Trying to create UMP memory with unaligned size. Size: %lu\n", size)); return UMP_DD_HANDLE_INVALID; } } /* Allocate the ump_dd_mem struct for this allocation */ mem = _mali_osk_malloc(sizeof(*mem)); if (NULL == mem) { DBG_MSG(1, ("Could not allocate ump_dd_mem in ump_dd_handle_create_from_phys_blocks()\n")); return UMP_DD_HANDLE_INVALID; } /* Find a secure ID for this allocation */ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); map_id = ump_descriptor_mapping_allocate_mapping(device.secure_id_map, (void*) mem); if (map_id < 0) { _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); _mali_osk_free(mem); DBG_MSG(1, ("Failed to allocate secure ID in ump_dd_handle_create_from_phys_blocks()\n")); return UMP_DD_HANDLE_INVALID; } /* Now, make a copy of the block information supplied by the user */ mem->block_array = _mali_osk_malloc(sizeof(ump_dd_physical_block)* num_blocks); if (NULL == mem->block_array) { ump_descriptor_mapping_free(device.secure_id_map, map_id); _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); _mali_osk_free(mem); DBG_MSG(1, ("Could not allocate a mem handle for function ump_dd_handle_create_from_phys_blocks().\n")); return UMP_DD_HANDLE_INVALID; } _mali_osk_memcpy(mem->block_array, blocks, sizeof(ump_dd_physical_block) * num_blocks); /* And setup the rest of the ump_dd_mem struct */ _mali_osk_atomic_init(&mem->ref_count, 1); mem->secure_id = (ump_secure_id)map_id; mem->size_bytes = size_total; mem->nr_blocks = num_blocks; mem->backend_info = NULL; mem->ctx = NULL; mem->release_func = phys_blocks_release; /* For now UMP handles created by ump_dd_handle_create_from_phys_blocks() is forced to be Uncached */ mem->is_cached = 0; mem->hw_device = _UMP_UK_USED_BY_CPU; mem->lock_usage = UMP_NOT_LOCKED; _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); DBG_MSG(3, ("UMP memory created. ID: %u, size: %lu\n", mem->secure_id, mem->size_bytes)); return (ump_dd_handle)mem; }
struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *uargs, u32 id) { struct mali_pp_job *job; u32 perf_counter_flag; job = _mali_osk_malloc(sizeof(struct mali_pp_job)); if (NULL != job) { u32 i; if (0 != _mali_osk_copy_from_user(&job->uargs, uargs, sizeof(_mali_uk_pp_start_job_s))) { _mali_osk_free(job); return NULL; } if (job->uargs.num_cores > _MALI_PP_MAX_SUB_JOBS) { MALI_PRINT_ERROR(("Mali PP job: Too many sub jobs specified in job object\n")); _mali_osk_free(job); return NULL; } if (!mali_pp_job_use_no_notification(job)) { job->finished_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_PP_FINISHED, sizeof(_mali_uk_pp_job_finished_s)); if (NULL == job->finished_notification) { _mali_osk_free(job); return NULL; } } else { job->finished_notification = NULL; } perf_counter_flag = mali_pp_job_get_perf_counter_flag(job); /* case when no counters came from user space * so pass the debugfs / DS-5 provided global ones to the job object */ if (!((perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) || (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE))) { mali_pp_job_set_perf_counter_src0(job, mali_pp_job_get_pp_counter_src0()); mali_pp_job_set_perf_counter_src1(job, mali_pp_job_get_pp_counter_src1()); } _mali_osk_list_init(&job->list); job->session = session; _mali_osk_list_init(&job->session_list); job->id = id; for (i = 0; i < job->uargs.num_cores; i++) { job->perf_counter_value0[i] = 0; job->perf_counter_value1[i] = 0; } job->sub_jobs_num = job->uargs.num_cores ? job->uargs.num_cores : 1; job->sub_jobs_started = 0; job->sub_jobs_completed = 0; job->sub_job_errors = 0; job->pid = _mali_osk_get_pid(); job->tid = _mali_osk_get_tid(); #if defined(MTK_CONFIG_SYNC) job->sync_point = NULL; job->pre_fence = NULL; job->sync_work = NULL; #endif return job; } return NULL; }
struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t *resource, struct mali_group *group, mali_bool is_virtual, u32 bcast_id) { struct mali_pp_core *core = NULL; MALI_DEBUG_PRINT(2, ("Mali PP: Creating Mali PP core: %s\n", resource->description)); MALI_DEBUG_PRINT(2, ("Mali PP: Base address of PP core: 0x%x\n", resource->base)); if (mali_global_num_pp_cores >= MALI_MAX_NUMBER_OF_PP_CORES) { MALI_PRINT_ERROR(("Mali PP: Too many PP core objects created\n")); return NULL; } core = _mali_osk_calloc(1, sizeof(struct mali_pp_core)); if (NULL != core) { core->core_id = mali_global_num_pp_cores; core->bcast_id = bcast_id; if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI200_REG_SIZEOF_REGISTER_BANK)) { _mali_osk_errcode_t ret; if (!is_virtual) { ret = mali_pp_reset(core); } else { ret = _MALI_OSK_ERR_OK; } if (_MALI_OSK_ERR_OK == ret) { ret = mali_group_add_pp_core(group, core); if (_MALI_OSK_ERR_OK == ret) { /* Setup IRQ handlers (which will do IRQ probing if needed) */ MALI_DEBUG_ASSERT(!is_virtual || -1 != resource->irq); core->irq = _mali_osk_irq_init(resource->irq, mali_group_upper_half_pp, group, mali_pp_irq_probe_trigger, mali_pp_irq_probe_ack, core, resource->description); if (NULL != core->irq) { mali_global_pp_cores[mali_global_num_pp_cores] = core; mali_global_num_pp_cores++; return core; } else { MALI_PRINT_ERROR(("Mali PP: Failed to setup interrupt handlers for PP core %s\n", core->hw_core.description)); } mali_group_remove_pp_core(group); } else { MALI_PRINT_ERROR(("Mali PP: Failed to add core %s to group\n", core->hw_core.description)); } } mali_hw_core_delete(&core->hw_core); } _mali_osk_free(core); } else { MALI_PRINT_ERROR(("Mali PP: Failed to allocate memory for PP core\n")); } return NULL; }
struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t *resource) { struct mali_l2_cache_core *cache = NULL; _mali_osk_lock_flags_t lock_flags; #if defined(MALI_UPPER_HALF_SCHEDULING) lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE; #else lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE; #endif MALI_DEBUG_PRINT(2, ("Mali L2 cache: Creating Mali L2 cache: %s\n", resource->description)); if (mali_global_num_l2_cache_cores >= MALI_MAX_NUMBER_OF_L2_CACHE_CORES) { MALI_PRINT_ERROR(("Mali L2 cache: Too many L2 cache core objects created\n")); return NULL; } cache = _mali_osk_malloc(sizeof(struct mali_l2_cache_core)); if (NULL != cache) { cache->core_id = mali_global_num_l2_cache_cores; cache->counter_src0 = MALI_HW_CORE_NO_COUNTER; cache->counter_src1 = MALI_HW_CORE_NO_COUNTER; cache->pm_domain = NULL; cache->mali_l2_status = MALI_L2_NORMAL; if (_MALI_OSK_ERR_OK == mali_hw_core_create(&cache->hw_core, resource, MALI400_L2_CACHE_REGISTERS_SIZE)) { cache->command_lock = _mali_osk_lock_init(lock_flags, 0, _MALI_OSK_LOCK_ORDER_L2_COMMAND); if (NULL != cache->command_lock) { cache->counter_lock = _mali_osk_lock_init(lock_flags, 0, _MALI_OSK_LOCK_ORDER_L2_COUNTER); if (NULL != cache->counter_lock) { mali_l2_cache_reset(cache); cache->last_invalidated_id = 0; mali_global_l2_cache_cores[mali_global_num_l2_cache_cores] = cache; mali_global_num_l2_cache_cores++; return cache; } else { MALI_PRINT_ERROR(("Mali L2 cache: Failed to create counter lock for L2 cache core %s\n", cache->hw_core.description)); } _mali_osk_lock_term(cache->command_lock); } else { MALI_PRINT_ERROR(("Mali L2 cache: Failed to create command lock for L2 cache core %s\n", cache->hw_core.description)); } mali_hw_core_delete(&cache->hw_core); } _mali_osk_free(cache); } else { MALI_PRINT_ERROR(("Mali L2 cache: Failed to allocate memory for L2 cache core\n")); } return NULL; }
struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t *resource, struct mali_group *group) { struct mali_pp_core* core = NULL; MALI_DEBUG_PRINT(2, ("Mali PP: Creating Mali PP core: %s\n", resource->description)); MALI_DEBUG_PRINT(2, ("Mali PP: Base address of PP core: 0x%x\n", resource->base)); if (mali_global_num_pp_cores >= MALI_MAX_NUMBER_OF_PP_CORES) { MALI_PRINT_ERROR(("Mali PP: Too many PP core objects created\n")); return NULL; } core = _mali_osk_malloc(sizeof(struct mali_pp_core)); if (NULL != core) { core->group = group; core->core_id = mali_global_num_pp_cores; core->running_job = NULL; core->counter_src0 = MALI_HW_CORE_NO_COUNTER; core->counter_src1 = MALI_HW_CORE_NO_COUNTER; core->counter_src0_used = MALI_HW_CORE_NO_COUNTER; core->counter_src1_used = MALI_HW_CORE_NO_COUNTER; if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI200_REG_SIZEOF_REGISTER_BANK)) { _mali_osk_errcode_t ret; mali_group_lock(group); ret = mali_pp_reset(core); mali_group_unlock(group); if (_MALI_OSK_ERR_OK == ret) { /* Setup IRQ handlers (which will do IRQ probing if needed) */ core->irq = _mali_osk_irq_init(resource->irq, mali_pp_upper_half, mali_pp_bottom_half, mali_pp_irq_probe_trigger, mali_pp_irq_probe_ack, core, "mali_pp_irq_handlers"); if (NULL != core->irq) { /* Initialise the timeout timer */ core->timeout_timer = _mali_osk_timer_init(); if(NULL != core->timeout_timer) { _mali_osk_timer_setcallback(core->timeout_timer, mali_pp_timeout, (void *)core); mali_global_pp_cores[mali_global_num_pp_cores] = core; mali_global_num_pp_cores++; return core; } else { MALI_PRINT_ERROR(("Failed to setup timeout timer for PP core %s\n", core->hw_core.description)); /* Release IRQ handlers */ _mali_osk_irq_term(core->irq); } } else { MALI_PRINT_ERROR(("Mali PP: Failed to setup interrupt handlers for PP core %s\n", core->hw_core.description)); } } mali_hw_core_delete(&core->hw_core); } _mali_osk_free(core); } else { MALI_PRINT_ERROR(("Mali PP: Failed to allocate memory for PP core\n")); } return NULL; }
static _mali_osk_errcode_t mali200_renderunit_create(_mali_osk_resource_t * resource) { mali_core_renderunit *core; _mali_osk_errcode_t err; MALI_DEBUG_PRINT(3, ("Mali PP: mali200_renderunit_create\n") ) ; /* Checking that the resource settings are correct */ #if defined(USING_MALI200) if(MALI200 != resource->type) { MALI_PRINT_ERROR(("Can not register this resource as a " MALI_PP_SUBSYSTEM_NAME " core.")); MALI_ERROR(_MALI_OSK_ERR_FAULT); } #elif defined(USING_MALI400) if(MALI400PP != resource->type) { MALI_PRINT_ERROR(("Can not register this resource as a " MALI_PP_SUBSYSTEM_NAME " core.")); MALI_ERROR(_MALI_OSK_ERR_FAULT); } #endif if ( 0 != resource->size ) { MALI_PRINT_ERROR(("Memory size set to " MALI_PP_SUBSYSTEM_NAME " core should be zero.")); MALI_ERROR(_MALI_OSK_ERR_FAULT); } if ( NULL == resource->description ) { MALI_PRINT_ERROR(("A " MALI_PP_SUBSYSTEM_NAME " core needs a unique description field")); MALI_ERROR(_MALI_OSK_ERR_FAULT); } /* Create a new core object */ core = (mali_core_renderunit*) _mali_osk_malloc(sizeof(*core)); if ( NULL == core ) { MALI_ERROR(_MALI_OSK_ERR_NOMEM); } /* Variables set to be able to open and register the core */ core->subsystem = &subsystem_mali200 ; core->registers_base_addr = resource->base ; core->size = MALI200_REG_SIZEOF_REGISTER_BANK ; core->irq_nr = resource->irq ; core->description = resource->description; #if USING_MMU core->mmu_id = resource->mmu_id; core->mmu = NULL; #endif #if USING_MALI_PMM /* Set up core's PMM id */ switch( subsystem_mali200.number_of_cores ) { case 0: core->pmm_id = MALI_PMM_CORE_PP0; break; case 1: core->pmm_id = MALI_PMM_CORE_PP1; break; case 2: core->pmm_id = MALI_PMM_CORE_PP2; break; case 3: core->pmm_id = MALI_PMM_CORE_PP3; break; default: MALI_DEBUG_PRINT(1, ("Unknown supported core for PMM\n")); err = _MALI_OSK_ERR_FAULT; goto exit_on_error0; } #endif err = mali_core_renderunit_init( core ); if (_MALI_OSK_ERR_OK != err) { MALI_DEBUG_PRINT(1, ("Failed to initialize renderunit\n")); goto exit_on_error0; } /* Map the new core object, setting: core->registers_mapped */ err = mali_core_renderunit_map_registers(core); if (_MALI_OSK_ERR_OK != err) { MALI_DEBUG_PRINT(1, ("Failed to map register\n")); goto exit_on_error1; } /* Check that the register mapping of the core works. Return 0 if Mali PP core is present and accessible. */ if (mali_benchmark) { #if defined(USING_MALI200) core->core_version = (((u32)MALI_PP_PRODUCT_ID) << 16) | 5 /* Fake Mali200-r0p5 */; #elif defined(USING_MALI400) core->core_version = (((u32)MALI_PP_PRODUCT_ID) << 16) | 0x0101 /* Fake Mali400-r1p1 */; #else #error "No supported mali core defined" #endif } else { core->core_version = mali_core_renderunit_register_read( core, MALI200_REG_ADDR_MGMT_VERSION); } err = mali200_core_version_legal(core); if (_MALI_OSK_ERR_OK != err) { MALI_DEBUG_PRINT(1, ("Invalid core\n")); goto exit_on_error2; } /* Reset the core. Put the core into a state where it can start to render. */ mali200_reset(core); /* Registering IRQ, init the work_queue_irq_handle */ /* Adding this core as an available renderunit in the subsystem. */ err = mali_core_subsystem_register_renderunit(&subsystem_mali200, core); if (_MALI_OSK_ERR_OK != err) { MALI_DEBUG_PRINT(1, ("Failed to register with core\n")); goto exit_on_error2; } MALI_DEBUG_PRINT(6, ("Mali PP: mali200_renderunit_create\n") ) ; MALI_SUCCESS; exit_on_error2: mali_core_renderunit_unmap_registers(core); exit_on_error1: mali_core_renderunit_term(core); exit_on_error0: _mali_osk_free( core ) ; MALI_PRINT_ERROR(("Renderunit NOT created.")); MALI_ERROR(err); }
static int mali_mem_ump_map(mali_mem_backend *mem_backend) { ump_dd_handle ump_mem; mali_mem_allocation *alloc; struct mali_session_data *session; u32 nr_blocks; u32 i; ump_dd_physical_block *ump_blocks; struct mali_page_directory *pagedir; u32 offset = 0; _mali_osk_errcode_t err; MALI_DEBUG_ASSERT_POINTER(mem_backend); MALI_DEBUG_ASSERT(MALI_MEM_UMP == mem_backend->type); alloc = mem_backend->mali_allocation; MALI_DEBUG_ASSERT_POINTER(alloc); session = alloc->session; MALI_DEBUG_ASSERT_POINTER(session); ump_mem = mem_backend->ump_mem.handle; MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID != ump_mem); nr_blocks = ump_dd_phys_block_count_get(ump_mem); if (nr_blocks == 0) { MALI_DEBUG_PRINT(1, ("No block count\n")); return -EINVAL; } ump_blocks = _mali_osk_malloc(sizeof(*ump_blocks) * nr_blocks); if (NULL == ump_blocks) { return -ENOMEM; } if (UMP_DD_INVALID == ump_dd_phys_blocks_get(ump_mem, ump_blocks, nr_blocks)) { _mali_osk_free(ump_blocks); return -EFAULT; } pagedir = session->page_directory; mali_session_memory_lock(session); err = mali_mem_mali_map_prepare(alloc); if (_MALI_OSK_ERR_OK != err) { MALI_DEBUG_PRINT(1, ("Mapping of UMP memory failed\n")); _mali_osk_free(ump_blocks); mali_session_memory_unlock(session); return -ENOMEM; } for (i = 0; i < nr_blocks; ++i) { u32 virt = alloc->mali_vma_node.vm_node.start + offset; MALI_DEBUG_PRINT(7, ("Mapping in 0x%08x size %d\n", ump_blocks[i].addr , ump_blocks[i].size)); mali_mmu_pagedir_update(pagedir, virt, ump_blocks[i].addr, ump_blocks[i].size, MALI_MMU_FLAGS_DEFAULT); offset += ump_blocks[i].size; } if (alloc->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) { u32 virt = alloc->mali_vma_node.vm_node.start + offset; /* Map in an extra virtual guard page at the end of the VMA */ MALI_DEBUG_PRINT(6, ("Mapping in extra guard page\n")); mali_mmu_pagedir_update(pagedir, virt, ump_blocks[0].addr, _MALI_OSK_MALI_PAGE_SIZE, MALI_MMU_FLAGS_DEFAULT); offset += _MALI_OSK_MALI_PAGE_SIZE; } session->mali_mem_array[mem_backend->type] += mem_backend->size; mali_session_memory_unlock(session); _mali_osk_free(ump_blocks); return 0; }
void mali_dlbu_delete(struct mali_dlbu_core *dlbu) { mali_dlbu_reset(dlbu); mali_hw_core_delete(&dlbu->hw_core); _mali_osk_free(dlbu); }
_mali_osk_errcode_t mali_allocation_engine_allocate_memory(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, mali_physical_memory_allocator * physical_allocators, _mali_osk_list_t *tracking_list ) { memory_engine * engine = (memory_engine*)mem_engine; MALI_DEBUG_ASSERT_POINTER(engine); MALI_DEBUG_ASSERT_POINTER(descriptor); MALI_DEBUG_ASSERT_POINTER(physical_allocators); /* ASSERT that the list member has been initialized, even if it won't be * used for tracking. We need it to be initialized to see if we need to * delete it from a list in the release function. */ MALI_DEBUG_ASSERT( NULL != descriptor->list.next && NULL != descriptor->list.prev ); if (_MALI_OSK_ERR_OK == engine->mali_address->allocate(descriptor)) { _mali_osk_errcode_t res = _MALI_OSK_ERR_OK; if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) { res = engine->process_address->allocate(descriptor); } if ( _MALI_OSK_ERR_OK == res ) { /* address space setup OK, commit physical memory to the allocation */ mali_physical_memory_allocator * active_allocator = physical_allocators; struct mali_physical_memory_allocation * active_allocation_tracker = &descriptor->physical_allocation; u32 offset = 0; while ( NULL != active_allocator ) { switch (active_allocator->allocate(active_allocator->ctx, mem_engine, descriptor, &offset, active_allocation_tracker)) { case MALI_MEM_ALLOC_FINISHED: if ( NULL != tracking_list ) { /* Insert into the memory session list */ /* ASSERT that it is not already part of a list */ MALI_DEBUG_ASSERT( _mali_osk_list_empty( &descriptor->list ) ); _mali_osk_list_add( &descriptor->list, tracking_list ); } MALI_SUCCESS; /* all done */ case MALI_MEM_ALLOC_NONE: /* reuse current active_allocation_tracker */ MALI_DEBUG_PRINT( 4, ("Memory Engine Allocate: No allocation on %s, resorting to %s\n", ( active_allocator->name ) ? active_allocator->name : "UNNAMED", ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") ); active_allocator = active_allocator->next; break; case MALI_MEM_ALLOC_PARTIAL: if (NULL != active_allocator->next) { /* need a new allocation tracker */ active_allocation_tracker->next = _mali_osk_calloc(1, sizeof(mali_physical_memory_allocation)); if (NULL != active_allocation_tracker->next) { active_allocation_tracker = active_allocation_tracker->next; MALI_DEBUG_PRINT( 2, ("Memory Engine Allocate: Partial allocation on %s, resorting to %s\n", ( active_allocator->name ) ? active_allocator->name : "UNNAMED", ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") ); active_allocator = active_allocator->next; break; } } /* FALL THROUGH */ case MALI_MEM_ALLOC_INTERNAL_FAILURE: active_allocator = NULL; /* end the while loop */ break; } } MALI_PRINT(("Memory allocate failed, could not allocate size %d kB.\n", descriptor->size/1024)); /* allocation failure, start cleanup */ /* loop over any potential partial allocations */ active_allocation_tracker = &descriptor->physical_allocation; while (NULL != active_allocation_tracker) { /* handle blank trackers which will show up during failure */ if (NULL != active_allocation_tracker->release) { active_allocation_tracker->release(active_allocation_tracker->ctx, active_allocation_tracker->handle); } active_allocation_tracker = active_allocation_tracker->next; } /* free the allocation tracker objects themselves, skipping the tracker stored inside the descriptor itself */ for ( active_allocation_tracker = descriptor->physical_allocation.next; active_allocation_tracker != NULL; ) { void * buf = active_allocation_tracker; active_allocation_tracker = active_allocation_tracker->next; _mali_osk_free(buf); } /* release the address spaces */ if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) { engine->process_address->release(descriptor); } } engine->mali_address->release(descriptor); } MALI_ERROR(_MALI_OSK_ERR_FAULT); }
static void descriptor_table_free(ump_descriptor_table *table) { _mali_osk_free(table); }
static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) { mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_NONE; u32 left; os_allocator * info; os_allocation * allocation; int pages_allocated = 0; _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; MALI_DEBUG_ASSERT_POINTER(ctx); MALI_DEBUG_ASSERT_POINTER(engine); MALI_DEBUG_ASSERT_POINTER(descriptor); MALI_DEBUG_ASSERT_POINTER(offset); MALI_DEBUG_ASSERT_POINTER(alloc_info); info = (os_allocator*)ctx; left = descriptor->size - *offset; if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE; /** @note this code may not work on Linux, or may require a more complex Linux implementation */ allocation = _mali_osk_malloc(sizeof(os_allocation)); if (NULL != allocation) { /* MALI_SEC */ //u32 os_mem_max_usage = info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE; allocation->offset_start = *offset; allocation->num_pages = ((left + _MALI_OSK_CPU_PAGE_SIZE - 1) & ~(_MALI_OSK_CPU_PAGE_SIZE - 1)) >> _MALI_OSK_CPU_PAGE_ORDER; MALI_DEBUG_PRINT(6, ("Allocating page array of size %d bytes\n", allocation->num_pages * sizeof(struct page*))); /* MALI_SEC */ while (left > 0) { err = mali_allocation_engine_map_physical(engine, descriptor, *offset, MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, info->cpu_usage_adjust, _MALI_OSK_CPU_PAGE_SIZE); if ( _MALI_OSK_ERR_OK != err) { if ( _MALI_OSK_ERR_NOMEM == err) { /* 'Partial' allocation (or, out-of-memory on first page) */ break; } MALI_DEBUG_PRINT(1, ("Mapping of physical memory failed\n")); /* Fatal error, cleanup any previous pages allocated. */ if ( pages_allocated > 0 ) { mali_allocation_engine_unmap_physical( engine, descriptor, allocation->offset_start, _MALI_OSK_CPU_PAGE_SIZE*pages_allocated, _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR ); /* (*offset) doesn't need to be restored; it will not be used by the caller on failure */ } pages_allocated = 0; result = MALI_MEM_ALLOC_INTERNAL_FAILURE; break; } /* Loop iteration */ if (left < _MALI_OSK_CPU_PAGE_SIZE) left = 0; else left -= _MALI_OSK_CPU_PAGE_SIZE; pages_allocated++; *offset += _MALI_OSK_CPU_PAGE_SIZE; } if (left) MALI_PRINT(("Out of memory. Mali memory allocated: %d kB Configured maximum OS memory usage: %d kB\n", (info->num_pages_allocated * _MALI_OSK_CPU_PAGE_SIZE)/1024, (info->num_pages_max* _MALI_OSK_CPU_PAGE_SIZE)/1024)); /* Loop termination; decide on result */ if (pages_allocated) { MALI_DEBUG_PRINT(6, ("Allocated %d pages\n", pages_allocated)); if (left) result = MALI_MEM_ALLOC_PARTIAL; else result = MALI_MEM_ALLOC_FINISHED; /* Some OS do not perform a full cache flush (including all outer caches) for uncached mapped memory. * They zero the memory through a cached mapping, then flush the inner caches but not the outer caches. * This is required for MALI to have the correct view of the memory. */ _mali_osk_cache_ensure_uncached_range_flushed( (void *)descriptor, allocation->offset_start, pages_allocated *_MALI_OSK_CPU_PAGE_SIZE ); allocation->num_pages = pages_allocated; allocation->engine = engine; /* Necessary to make the engine's unmap call */ allocation->descriptor = descriptor; /* Necessary to make the engine's unmap call */ info->num_pages_allocated += pages_allocated; MALI_DEBUG_PRINT(6, ("%d out of %d pages now allocated\n", info->num_pages_allocated, info->num_pages_max)); alloc_info->ctx = info; alloc_info->handle = allocation; alloc_info->release = os_allocator_release; } else { MALI_DEBUG_PRINT(6, ("Releasing pages array due to no pages allocated\n")); _mali_osk_free( allocation ); } }
/* * IOCTL operation; Import fd to UMP memory */ int ump_ion_import_wrapper(u32 __user * argument, struct ump_session_data * session_data) { _ump_uk_ion_import_s user_interaction; ump_dd_handle *ump_handle; ump_dd_physical_block * blocks; unsigned long num_blocks; struct ion_handle *ion_hnd; struct scatterlist *sg; struct scatterlist *sg_ion; unsigned long i = 0; ump_session_memory_list_element * session_memory_element = NULL; if (ion_client_ump==NULL) ion_client_ump = ion_client_create(ion_exynos, -1, "ump"); /* Sanity check input parameters */ if (NULL == argument || NULL == session_data) { MSG_ERR(("NULL parameter in ump_ioctl_allocate()\n")); return -ENOTTY; } /* Copy the user space memory to kernel space (so we safely can read it) */ if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) { MSG_ERR(("copy_from_user() in ump_ioctl_allocate()\n")); return -EFAULT; } user_interaction.ctx = (void *) session_data; /* translate fd to secure ID*/ ion_hnd = ion_import_fd(ion_client_ump, user_interaction.ion_fd); sg_ion = ion_map_dma(ion_client_ump,ion_hnd); blocks = (ump_dd_physical_block*)_mali_osk_malloc(sizeof(ump_dd_physical_block)*1024); if (NULL == blocks) { MSG_ERR(("Failed to allocate blocks in ump_ioctl_allocate()\n")); return -ENOMEM; } sg = sg_ion; do { blocks[i].addr = sg_phys(sg); blocks[i].size = sg_dma_len(sg); i++; if (i>=1024) { _mali_osk_free(blocks); MSG_ERR(("ion_import fail() in ump_ioctl_allocate()\n")); return -EFAULT; } sg = sg_next(sg); } while(sg); num_blocks = i; /* Initialize the session_memory_element, and add it to the session object */ session_memory_element = _mali_osk_calloc( 1, sizeof(ump_session_memory_list_element)); if (NULL == session_memory_element) { _mali_osk_free(blocks); DBG_MSG(1, ("Failed to allocate ump_session_memory_list_element in ump_ioctl_allocate()\n")); return -EFAULT; } ump_handle = ump_dd_handle_create_from_phys_blocks(blocks, num_blocks); if (UMP_DD_HANDLE_INVALID == ump_handle) { _mali_osk_free(session_memory_element); _mali_osk_free(blocks); DBG_MSG(1, ("Failed to allocate ump_session_memory_list_element in ump_ioctl_allocate()\n")); return -EFAULT; } session_memory_element->mem = (ump_dd_mem*)ump_handle; _mali_osk_mutex_wait(session_data->lock); _mali_osk_list_add(&(session_memory_element->list), &(session_data->list_head_session_memory_list)); _mali_osk_mutex_signal(session_data->lock); ion_unmap_dma(ion_client_ump,ion_hnd); ion_free(ion_client_ump, ion_hnd); _mali_osk_free(blocks); user_interaction.secure_id = ump_dd_secure_id_get(ump_handle); user_interaction.size = ump_dd_size_get(ump_handle); user_interaction.ctx = NULL; if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) { /* If the copy fails then we should release the memory. We can use the IOCTL release to accomplish this */ MSG_ERR(("copy_to_user() failed in ump_ioctl_allocate()\n")); return -EFAULT; } return 0; /* success */ }
void ump_descriptor_mapping_destroy(ump_descriptor_mapping *map) { descriptor_table_free(map->table); _mali_osk_mutex_rw_term(map->lock); _mali_osk_free(map); }
void mali_dlbu_delete(struct mali_dlbu_core *dlbu) { MALI_DEBUG_ASSERT_POINTER(dlbu); mali_hw_core_delete(&dlbu->hw_core); _mali_osk_free(dlbu); }
static void phys_blocks_release(void * ctx, struct ump_dd_mem * descriptor) { _mali_osk_free(descriptor->block_array); descriptor->block_array = NULL; }
struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *uargs, u32 id, struct mali_timeline_tracker *pp_tracker) { struct mali_gp_job *job; u32 perf_counter_flag; job = _mali_osk_malloc(sizeof(struct mali_gp_job)); if (NULL != job) { job->finished_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_FINISHED, sizeof(_mali_uk_gp_job_finished_s)); if (NULL == job->finished_notification) { _mali_osk_free(job); return NULL; } job->oom_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s)); if (NULL == job->oom_notification) { _mali_osk_notification_delete(job->finished_notification); _mali_osk_free(job); return NULL; } if (0 != _mali_osk_copy_from_user(&job->uargs, uargs, sizeof(_mali_uk_gp_start_job_s))) { _mali_osk_notification_delete(job->finished_notification); _mali_osk_notification_delete(job->oom_notification); _mali_osk_free(job); return NULL; } perf_counter_flag = mali_gp_job_get_perf_counter_flag(job); /* case when no counters came from user space * so pass the debugfs / DS-5 provided global ones to the job object */ if (!((perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) || (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE))) { mali_gp_job_set_perf_counter_src0(job, mali_gp_job_get_gp_counter_src0()); mali_gp_job_set_perf_counter_src1(job, mali_gp_job_get_gp_counter_src1()); } _mali_osk_list_init(&job->list); job->session = session; job->id = id; job->heap_current_addr = job->uargs.frame_registers[4]; job->perf_counter_value0 = 0; job->perf_counter_value1 = 0; job->pid = _mali_osk_get_pid(); job->tid = _mali_osk_get_tid(); job->pp_tracker = pp_tracker; if (NULL != job->pp_tracker) { /* Take a reference on PP job's tracker that will be released when the GP job is done. */ mali_timeline_system_tracker_get(session->timeline_system, pp_tracker); } mali_timeline_tracker_init(&job->tracker, MALI_TIMELINE_TRACKER_GP, NULL, job); mali_timeline_fence_copy_uk_fence(&(job->tracker.fence), &(job->uargs.fence)); return job; } return NULL; }
_mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction ) { ump_session_data * session_data = NULL; ump_dd_mem *new_allocation = NULL; ump_session_memory_list_element * session_memory_element = NULL; int map_id; DEBUG_ASSERT_POINTER( user_interaction ); DEBUG_ASSERT_POINTER( user_interaction->ctx ); session_data = (ump_session_data *) user_interaction->ctx; session_memory_element = _mali_osk_calloc( 1, sizeof(ump_session_memory_list_element)); if (NULL == session_memory_element) { DBG_MSG(1, ("Failed to allocate ump_session_memory_list_element in ump_ioctl_allocate()\n")); return _MALI_OSK_ERR_NOMEM; } new_allocation = _mali_osk_calloc( 1, sizeof(ump_dd_mem)); if (NULL==new_allocation) { _mali_osk_free(session_memory_element); DBG_MSG(1, ("Failed to allocate ump_dd_mem in _ump_ukk_allocate()\n")); return _MALI_OSK_ERR_NOMEM; } /* Create a secure ID for this allocation */ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); map_id = ump_descriptor_mapping_allocate_mapping(device.secure_id_map, (void*)new_allocation); if (map_id < 0) { _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); _mali_osk_free(session_memory_element); _mali_osk_free(new_allocation); DBG_MSG(1, ("Failed to allocate secure ID in ump_ioctl_allocate()\n")); return - _MALI_OSK_ERR_INVALID_FUNC; } /* Initialize the part of the new_allocation that we know so for */ new_allocation->secure_id = (ump_secure_id)map_id; _mali_osk_atomic_init(&new_allocation->ref_count,1); if ( 0==(UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE & user_interaction->constraints) ) new_allocation->is_cached = 0; else new_allocation->is_cached = 1; /* special case a size of 0, we should try to emulate what malloc does in this case, which is to return a valid pointer that must be freed, but can't be dereferences */ if (0 == user_interaction->size) { user_interaction->size = 1; /* emulate by actually allocating the minimum block size */ } new_allocation->size_bytes = UMP_SIZE_ALIGN(user_interaction->size); /* Page align the size */ new_allocation->lock_usage = UMP_NOT_LOCKED; /* Now, ask the active memory backend to do the actual memory allocation */ if (!device.backend->allocate( device.backend->ctx, new_allocation ) ) { DBG_MSG(3, ("OOM: No more UMP memory left. Failed to allocate memory in ump_ioctl_allocate(). Size: %lu, requested size: %lu\n", new_allocation->size_bytes, (unsigned long)user_interaction->size)); ump_descriptor_mapping_free(device.secure_id_map, map_id); _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); _mali_osk_free(new_allocation); _mali_osk_free(session_memory_element); return _MALI_OSK_ERR_INVALID_FUNC; } new_allocation->hw_device = _UMP_UK_USED_BY_CPU; new_allocation->ctx = device.backend->ctx; new_allocation->release_func = device.backend->release; _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); /* Initialize the session_memory_element, and add it to the session object */ session_memory_element->mem = new_allocation; _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); _mali_osk_list_add(&(session_memory_element->list), &(session_data->list_head_session_memory_list)); _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); user_interaction->secure_id = new_allocation->secure_id; user_interaction->size = new_allocation->size_bytes; DBG_MSG(3, ("UMP memory allocated. ID: %u, size: %lu\n", new_allocation->secure_id, new_allocation->size_bytes)); return _MALI_OSK_ERR_OK; }