blob: cda74c30e85b74ac8bb3776052635c88f6bddc74 [file] [log] [blame]
/*
* Copyright (C) 2010-2012 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
*
* A copy of the licence is included with the program, and can also be obtained from Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __MALI_KERNEL_MEMORY_ENGINE_H__
#define __MALI_KERNEL_MEMORY_ENGINE_H__
typedef void * mali_allocation_engine;
typedef enum { MALI_MEM_ALLOC_FINISHED, MALI_MEM_ALLOC_PARTIAL, MALI_MEM_ALLOC_NONE, MALI_MEM_ALLOC_INTERNAL_FAILURE } mali_physical_memory_allocation_result;
typedef struct mali_physical_memory_allocation
{
void (*release)(void * ctx, void * handle); /**< Function to call on to release the physical memory */
void * ctx;
void * handle;
struct mali_physical_memory_allocation * next;
} mali_physical_memory_allocation;
struct mali_page_table_block;
typedef struct mali_page_table_block
{
void (*release)(struct mali_page_table_block *page_table_block);
void * ctx;
void * handle;
u32 size; /**< In bytes, should be a multiple of MALI_MMU_PAGE_SIZE to avoid internal fragementation */
u32 phys_base; /**< Mali physical address */
mali_io_address mapping;
} mali_page_table_block;
/** @addtogroup _mali_osk_low_level_memory
* @{ */
typedef enum
{
MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE = 0x1,
MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE = 0x2,
} mali_memory_allocation_flag;
/**
* Supplying this 'magic' physical address requests that the OS allocate the
* physical address at page commit time, rather than committing a specific page
*/
#define MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC ((u32)(-1))
typedef struct mali_memory_allocation
{
/* Information about the allocation */
void * mapping; /**< CPU virtual address where the memory is mapped at */
u32 mali_address; /**< The Mali seen address of the memory allocation */
u32 size; /**< Size of the allocation */
u32 permission; /**< Permission settings */
mali_memory_allocation_flag flags;
_mali_osk_lock_t * lock;
/* Manager specific information pointers */
void * mali_addr_mapping_info; /**< Mali address allocation specific info */
void * process_addr_mapping_info; /**< Mapping manager specific info */
mali_physical_memory_allocation physical_allocation;
_mali_osk_list_t list; /**< List for linking together memory allocations into the session's memory head */
} mali_memory_allocation;
/** @} */ /* end group _mali_osk_low_level_memory */
typedef struct mali_physical_memory_allocator
{
mali_physical_memory_allocation_result (*allocate)(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
mali_physical_memory_allocation_result (*allocate_page_table_block)(void * ctx, mali_page_table_block * block); /* MALI_MEM_ALLOC_PARTIAL not allowed */
void (*destroy)(struct mali_physical_memory_allocator * allocator);
u32 (*stat)(struct mali_physical_memory_allocator * allocator);
void * ctx;
const char * name; /**< Descriptive name for use in mali_allocation_engine_report_allocators, or NULL */
u32 alloc_order; /**< Order in which the allocations should happen */
struct mali_physical_memory_allocator * next;
} mali_physical_memory_allocator;
typedef struct mali_kernel_mem_address_manager
{
_mali_osk_errcode_t (*allocate)(mali_memory_allocation *); /**< Function to call to reserve an address */
void (*release)(mali_memory_allocation *); /**< Function to call to free the address allocated */
/**
* Function called for each physical sub allocation.
* Called for each physical block allocated by the physical memory manager.
* @param[in] descriptor The memory descriptor in question
* @param[in] off Offset from the start of range
* @param[in,out] phys_addr A pointer to the physical address of the start of the
* physical block. When *phys_addr == MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC
* is used, this requests the function to allocate the physical page
* itself, and return it through the pointer provided.
* @param[in] size Length in bytes of the physical block
* @return _MALI_OSK_ERR_OK on success.
* A value of type _mali_osk_errcode_t other than _MALI_OSK_ERR_OK indicates failure.
* Specifically, _MALI_OSK_ERR_UNSUPPORTED indicates that the function
* does not support allocating physical pages itself.
*/
_mali_osk_errcode_t (*map_physical)(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size);
/**
* Function called to remove a physical sub allocation.
* Called on error paths where one of the address managers fails.
*
* @note this is optional. For address managers where this is not
* implemented, the value of this member is NULL. The memory engine
* currently does not require the mali address manager to be able to
* unmap individual pages, but the process address manager must have this
* capability.
*
* @param[in] descriptor The memory descriptor in question
* @param[in] off Offset from the start of range
* @param[in] size Length in bytes of the physical block
* @param[in] flags flags to use on a per-page basis. For OS-allocated
* physical pages, this must include _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR.
* @return _MALI_OSK_ERR_OK on success.
* A value of type _mali_osk_errcode_t other than _MALI_OSK_ERR_OK indicates failure.
*/
void (*unmap_physical)(mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags);
} mali_kernel_mem_address_manager;
mali_allocation_engine mali_allocation_engine_create(mali_kernel_mem_address_manager * mali_address_manager, mali_kernel_mem_address_manager * process_address_manager);
void mali_allocation_engine_destroy(mali_allocation_engine engine);
int mali_allocation_engine_allocate_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor, mali_physical_memory_allocator * physical_provider, _mali_osk_list_t *tracking_list );
void mali_allocation_engine_release_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor);
void mali_allocation_engine_release_pt1_mali_pagetables_unmap(mali_allocation_engine engine, mali_memory_allocation * descriptor);
void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine engine, mali_memory_allocation * descriptor);
int mali_allocation_engine_map_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 phys, u32 cpu_usage_adjust, u32 size);
void mali_allocation_engine_unmap_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t unmap_flags);
int mali_allocation_engine_allocate_page_tables(mali_allocation_engine, mali_page_table_block * descriptor, mali_physical_memory_allocator * physical_provider);
void mali_allocation_engine_report_allocators(mali_physical_memory_allocator * physical_provider);
u32 mali_allocation_engine_memory_usage(mali_physical_memory_allocator *allocator);
#endif /* __MALI_KERNEL_MEMORY_ENGINE_H__ */