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;
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
_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;
}
Exemplo n.º 4
0
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") );
}
Exemplo n.º 6
0
_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;
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 13
0
_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 );
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
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;
}
Exemplo n.º 18
0
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 );
		}
	}
Exemplo n.º 25
0
/*
 * 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);
}
Exemplo n.º 27
0
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);
}
Exemplo n.º 28
0
static void phys_blocks_release(void * ctx, struct ump_dd_mem * descriptor)
{
	_mali_osk_free(descriptor->block_array);
	descriptor->block_array = NULL;
}
Exemplo n.º 29
0
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;
}
Exemplo n.º 30
0
_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;
}