_mali_osk_errcode_t mali_create_fault_flush_pages(mali_dma_addr *page_directory,
		mali_io_address *page_directory_mapping,
		mali_dma_addr *page_table, mali_io_address *page_table_mapping,
		mali_dma_addr *data_page, mali_io_address *data_page_mapping)
{
	_mali_osk_errcode_t err;

	err = mali_mmu_get_table_page(data_page, data_page_mapping);
	if (_MALI_OSK_ERR_OK == err) {
		err = mali_mmu_get_table_page(page_table, page_table_mapping);
		if (_MALI_OSK_ERR_OK == err) {
			err = mali_mmu_get_table_page(page_directory, page_directory_mapping);
			if (_MALI_OSK_ERR_OK == err) {
				fill_page(*data_page_mapping, 0);
				fill_page(*page_table_mapping, *data_page | MALI_MMU_FLAGS_DEFAULT);
				fill_page(*page_directory_mapping, *page_table | MALI_MMU_FLAGS_PRESENT);
				MALI_SUCCESS;
			}
			mali_mmu_release_table_page(*page_table, *page_table_mapping);
			*page_table = MALI_INVALID_PAGE;
		}
		mali_mmu_release_table_page(*data_page, *data_page_mapping);
		*data_page = MALI_INVALID_PAGE;
	}
	return err;
}
_mali_osk_errcode_t mali_create_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page)
{
	_mali_osk_errcode_t err;
	mali_io_address page_directory_mapping;
	mali_io_address page_table_mapping;
	mali_io_address data_page_mapping;

	err = mali_mmu_get_table_page(data_page, &data_page_mapping);
	if (_MALI_OSK_ERR_OK == err)
	{
		err = mali_mmu_get_table_page(page_table, &page_table_mapping);
		if (_MALI_OSK_ERR_OK == err)
		{
			err = mali_mmu_get_table_page(page_directory, &page_directory_mapping);
			if (_MALI_OSK_ERR_OK == err)
			{
				fill_page(data_page_mapping, 0);
				fill_page(page_table_mapping, *data_page | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT);
				fill_page(page_directory_mapping, *page_table | MALI_MMU_FLAGS_PRESENT);
				MALI_SUCCESS;
			}
			mali_mmu_release_table_page(*page_table);
			*page_table = MALI_INVALID_PAGE;
		}
		mali_mmu_release_table_page(*data_page);
		*data_page = MALI_INVALID_PAGE;
	}
	return err;
}
Пример #3
0
_mali_osk_errcode_t mali_dlbu_initialize(void)
{
	MALI_DEBUG_PRINT(2, ("Mali DLBU: Initializing\n"));

	if (_MALI_OSK_ERR_OK ==
	    mali_mmu_get_table_page(&mali_dlbu_phys_addr,
				    &mali_dlbu_cpu_addr)) {
		return _MALI_OSK_ERR_OK;
	}

	return _MALI_OSK_ERR_FAULT;
}
_mali_osk_errcode_t mali_dlbu_initialize(void)
{

	MALI_DEBUG_PRINT(2, ("Dynamic Load Balancing Unit initializing\n"));

	if (_MALI_OSK_ERR_OK == mali_mmu_get_table_page(&mali_dlbu_phys_addr, &mali_dlbu_cpu_addr))
	{
		MALI_SUCCESS;
	}

	return _MALI_OSK_ERR_FAULT;
}
struct mali_page_directory *mali_mmu_pagedir_alloc(void)
{
	struct mali_page_directory *pagedir;

	pagedir = _mali_osk_calloc(1, sizeof(struct mali_page_directory));
	if(NULL == pagedir) {
		return NULL;
	}

	if(_MALI_OSK_ERR_OK != mali_mmu_get_table_page(&pagedir->page_directory, &pagedir->page_directory_mapped)) {
		_mali_osk_free(pagedir);
		return NULL;
	}

	/* Zero page directory */
	fill_page(pagedir->page_directory_mapped, 0);

	return pagedir;
}
_mali_osk_errcode_t mali_mmu_pagedir_map(struct mali_page_directory *pagedir, u32 mali_address, u32 size)
{
	const int first_pde = MALI_MMU_PDE_ENTRY(mali_address);
	const int last_pde = MALI_MMU_PDE_ENTRY(mali_address + size - 1);
	_mali_osk_errcode_t err;
	mali_io_address pde_mapping;
	u32 pde_phys;
	int i;

	for(i = first_pde; i <= last_pde; i++)
	{
		if(0 == (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32)) & MALI_MMU_FLAGS_PRESENT))
		{
			/* Page table not present */
			MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]);
			MALI_DEBUG_ASSERT(NULL == pagedir->page_entries_mapped[i]);

			err = mali_mmu_get_table_page(&pde_phys, &pde_mapping);
			if(_MALI_OSK_ERR_OK != err)
			{
				MALI_PRINT_ERROR(("Failed to allocate page table page.\n"));
				return err;
			}
			pagedir->page_entries_mapped[i] = pde_mapping;

			/* Update PDE, mark as present */
			_mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i*sizeof(u32),
			                pde_phys | MALI_MMU_FLAGS_PRESENT);

			MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]);
			pagedir->page_entries_usage_count[i] = 1;
		}
		else
		{
			pagedir->page_entries_usage_count[i]++;
		}
	}
	_mali_osk_write_mem_barrier();

	MALI_SUCCESS;
}
u32 mali_allocate_empty_page(void)
{
	_mali_osk_errcode_t err;
	mali_io_address mapping;
	u32 address;

	if(_MALI_OSK_ERR_OK != mali_mmu_get_table_page(&address, &mapping))
	{
		/* Allocation failed */
		return 0;
	}

	MALI_DEBUG_ASSERT_POINTER( mapping );

	err = fill_page(mapping, 0);
	if (_MALI_OSK_ERR_OK != err)
	{
		mali_mmu_release_table_page(address);
	}
	return address;
}
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;
}
u32 mali_allocate_empty_page(mali_io_address *virt_addr)
{
	_mali_osk_errcode_t err;
	mali_io_address mapping;
	mali_dma_addr address;

	if (_MALI_OSK_ERR_OK != mali_mmu_get_table_page(&address, &mapping)) {
		/* Allocation failed */
		MALI_DEBUG_PRINT(2, ("Mali MMU: Failed to get table page for empty pgdir\n"));
		return 0;
	}

	MALI_DEBUG_ASSERT_POINTER(mapping);

	err = fill_page(mapping, 0);
	if (_MALI_OSK_ERR_OK != err) {
		mali_mmu_release_table_page(address, mapping);
		MALI_DEBUG_PRINT(2, ("Mali MMU: Failed to zero page\n"));
		return 0;
	}

	*virt_addr = mapping;
	return address;
}