/drivers/gpu/mali/ump/common/ump_kernel_descriptor_mapping.c
C | 166 lines | 123 code | 23 blank | 20 comment | 23 complexity | db49387a5d7423c9f2495cf2256cefeb MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
1/* 2 * Copyright (C) 2010-2011 ARM Limited. All rights reserved. 3 * 4 * This program is free software and is provided to you under the terms of the GNU General Public License version 2 5 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. 6 * 7 * A copy of the licence is included with the program, and can also be obtained from Free Software 8 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 9 */ 10 11#include "mali_kernel_common.h" 12#include "mali_osk.h" 13#include "mali_osk_bitops.h" 14#include "ump_kernel_common.h" 15#include "ump_kernel_descriptor_mapping.h" 16 17#define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1)) 18 19/** 20 * Allocate a descriptor table capable of holding 'count' mappings 21 * @param count Number of mappings in the table 22 * @return Pointer to a new table, NULL on error 23 */ 24static ump_descriptor_table * descriptor_table_alloc(int count); 25 26/** 27 * Free a descriptor table 28 * @param table The table to free 29 */ 30static void descriptor_table_free(ump_descriptor_table * table); 31 32ump_descriptor_mapping * ump_descriptor_mapping_create(int init_entries, int max_entries) 33{ 34 ump_descriptor_mapping * map = _mali_osk_calloc(1, sizeof(ump_descriptor_mapping) ); 35 36 init_entries = MALI_PAD_INT(init_entries); 37 max_entries = MALI_PAD_INT(max_entries); 38 39 if (NULL != map) 40 { 41 map->table = descriptor_table_alloc(init_entries); 42 if (NULL != map->table) 43 { 44 map->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_READERWRITER, 0 , 0); 45 if ( NULL != map->lock ) 46 { 47 _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */ 48 map->max_nr_mappings_allowed = max_entries; 49 map->current_nr_mappings = init_entries; 50 return map; 51 } 52 descriptor_table_free(map->table); 53 } 54 _mali_osk_free(map); 55 } 56 return NULL; 57} 58 59void ump_descriptor_mapping_destroy(ump_descriptor_mapping * map) 60{ 61 descriptor_table_free(map->table); 62 _mali_osk_lock_term( map->lock ); 63 _mali_osk_free(map); 64} 65 66int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * target) 67{ 68 int descriptor = -1;/*-EFAULT;*/ 69 _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); 70 descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings); 71 if (descriptor == map->current_nr_mappings) 72 { 73 int nr_mappings_new; 74 /* no free descriptor, try to expand the table */ 75 ump_descriptor_table * new_table; 76 ump_descriptor_table * old_table = map->table; 77 nr_mappings_new= map->current_nr_mappings *2; 78 79 if (map->current_nr_mappings >= map->max_nr_mappings_allowed) 80 { 81 descriptor = -1; 82 goto unlock_and_exit; 83 } 84 85 new_table = descriptor_table_alloc(nr_mappings_new); 86 if (NULL == new_table) 87 { 88 descriptor = -1; 89 goto unlock_and_exit; 90 } 91 92 _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG); 93 _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*)); 94 map->table = new_table; 95 map->current_nr_mappings = nr_mappings_new; 96 descriptor_table_free(old_table); 97 } 98 99 /* we have found a valid descriptor, set the value and usage bit */ 100 _mali_osk_set_nonatomic_bit(descriptor, map->table->usage); 101 map->table->mappings[descriptor] = target; 102 103unlock_and_exit: 104 _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW); 105 return descriptor; 106} 107 108int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, void** target) 109{ 110 int result = -1;/*-EFAULT;*/ 111 DEBUG_ASSERT(map); 112 _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); 113 if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) 114 { 115 *target = map->table->mappings[descriptor]; 116 result = 0; 117 } 118 else *target = NULL; 119 _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO); 120 return result; 121} 122 123int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, void * target) 124{ 125 int result = -1;/*-EFAULT;*/ 126 _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); 127 if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) 128 { 129 map->table->mappings[descriptor] = target; 130 result = 0; 131 } 132 _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO); 133 return result; 134} 135 136void ump_descriptor_mapping_free(ump_descriptor_mapping * map, int descriptor) 137{ 138 _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); 139 if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) 140 { 141 map->table->mappings[descriptor] = NULL; 142 _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage); 143 } 144 _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW); 145} 146 147static ump_descriptor_table * descriptor_table_alloc(int count) 148{ 149 ump_descriptor_table * table; 150 151 table = _mali_osk_calloc(1, sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG) + (sizeof(void*) * count) ); 152 153 if (NULL != table) 154 { 155 table->usage = (u32*)((u8*)table + sizeof(ump_descriptor_table)); 156 table->mappings = (void**)((u8*)table + sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG)); 157 } 158 159 return table; 160} 161 162static void descriptor_table_free(ump_descriptor_table * table) 163{ 164 _mali_osk_free(table); 165} 166