Commit | Line | Data |
---|---|---|
6fa3eb70 S |
1 | /* |
2 | * This confidential and proprietary software may be used only as | |
3 | * authorised by a licensing agreement from ARM Limited | |
bdc132d7 | 4 | * (C) COPYRIGHT 2008-2011, 2013-2015 ARM Limited |
6fa3eb70 S |
5 | * ALL RIGHTS RESERVED |
6 | * The entire notice above must be reproduced on all authorised | |
7 | * copies and copies may only be made to the extent permitted | |
8 | * by a licensing agreement from ARM Limited. | |
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 | */ | |
bdc132d7 | 24 | static ump_descriptor_table *descriptor_table_alloc(int count); |
6fa3eb70 S |
25 | |
26 | /** | |
27 | * Free a descriptor table | |
28 | * @param table The table to free | |
29 | */ | |
bdc132d7 | 30 | static void descriptor_table_free(ump_descriptor_table *table); |
6fa3eb70 | 31 | |
bdc132d7 | 32 | ump_descriptor_mapping *ump_descriptor_mapping_create(int init_entries, int max_entries) |
6fa3eb70 | 33 | { |
bdc132d7 | 34 | ump_descriptor_mapping *map = _mali_osk_calloc(1, sizeof(ump_descriptor_mapping)); |
6fa3eb70 S |
35 | |
36 | init_entries = MALI_PAD_INT(init_entries); | |
37 | max_entries = MALI_PAD_INT(max_entries); | |
38 | ||
39 | if (NULL != map) { | |
40 | map->table = descriptor_table_alloc(init_entries); | |
41 | if (NULL != map->table) { | |
42 | map->lock = _mali_osk_mutex_rw_init(_MALI_OSK_LOCKFLAG_UNORDERED, 0); | |
bdc132d7 | 43 | if (NULL != map->lock) { |
6fa3eb70 S |
44 | _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */ |
45 | map->max_nr_mappings_allowed = max_entries; | |
46 | map->current_nr_mappings = init_entries; | |
47 | return map; | |
48 | } | |
49 | descriptor_table_free(map->table); | |
50 | } | |
51 | _mali_osk_free(map); | |
52 | } | |
53 | return NULL; | |
54 | } | |
55 | ||
bdc132d7 | 56 | void ump_descriptor_mapping_destroy(ump_descriptor_mapping *map) |
6fa3eb70 S |
57 | { |
58 | descriptor_table_free(map->table); | |
59 | _mali_osk_mutex_rw_term(map->lock); | |
60 | _mali_osk_free(map); | |
61 | } | |
62 | ||
bdc132d7 | 63 | int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping *map, void *target) |
6fa3eb70 S |
64 | { |
65 | int descriptor = -1;/*-EFAULT;*/ | |
66 | _mali_osk_mutex_rw_wait(map->lock, _MALI_OSK_LOCKMODE_RW); | |
67 | descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings); | |
68 | if (descriptor == map->current_nr_mappings) { | |
69 | int nr_mappings_new; | |
70 | /* no free descriptor, try to expand the table */ | |
bdc132d7 S |
71 | ump_descriptor_table *new_table; |
72 | ump_descriptor_table *old_table = map->table; | |
73 | nr_mappings_new = map->current_nr_mappings * 2; | |
6fa3eb70 S |
74 | |
75 | if (map->current_nr_mappings >= map->max_nr_mappings_allowed) { | |
76 | descriptor = -1; | |
77 | goto unlock_and_exit; | |
78 | } | |
79 | ||
80 | new_table = descriptor_table_alloc(nr_mappings_new); | |
81 | if (NULL == new_table) { | |
82 | descriptor = -1; | |
83 | goto unlock_and_exit; | |
84 | } | |
85 | ||
86 | _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG); | |
bdc132d7 | 87 | _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void *)); |
6fa3eb70 S |
88 | map->table = new_table; |
89 | map->current_nr_mappings = nr_mappings_new; | |
90 | descriptor_table_free(old_table); | |
91 | } | |
92 | ||
93 | /* we have found a valid descriptor, set the value and usage bit */ | |
94 | _mali_osk_set_nonatomic_bit(descriptor, map->table->usage); | |
95 | map->table->mappings[descriptor] = target; | |
96 | ||
97 | unlock_and_exit: | |
98 | _mali_osk_mutex_rw_signal(map->lock, _MALI_OSK_LOCKMODE_RW); | |
99 | return descriptor; | |
100 | } | |
101 | ||
bdc132d7 | 102 | int ump_descriptor_mapping_get(ump_descriptor_mapping *map, int descriptor, void **target) |
6fa3eb70 S |
103 | { |
104 | int result = -1;/*-EFAULT;*/ | |
105 | DEBUG_ASSERT(map); | |
106 | _mali_osk_mutex_rw_wait(map->lock, _MALI_OSK_LOCKMODE_RO); | |
107 | if ((descriptor > 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage)) { | |
108 | *target = map->table->mappings[descriptor]; | |
109 | result = 0; | |
110 | } else *target = NULL; | |
111 | _mali_osk_mutex_rw_signal(map->lock, _MALI_OSK_LOCKMODE_RO); | |
112 | return result; | |
113 | } | |
114 | ||
bdc132d7 | 115 | int ump_descriptor_mapping_set(ump_descriptor_mapping *map, int descriptor, void *target) |
6fa3eb70 S |
116 | { |
117 | int result = -1;/*-EFAULT;*/ | |
118 | _mali_osk_mutex_rw_wait(map->lock, _MALI_OSK_LOCKMODE_RO); | |
119 | if ((descriptor > 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage)) { | |
120 | map->table->mappings[descriptor] = target; | |
121 | result = 0; | |
122 | } | |
123 | _mali_osk_mutex_rw_signal(map->lock, _MALI_OSK_LOCKMODE_RO); | |
124 | return result; | |
125 | } | |
126 | ||
bdc132d7 | 127 | void ump_descriptor_mapping_free(ump_descriptor_mapping *map, int descriptor) |
6fa3eb70 S |
128 | { |
129 | _mali_osk_mutex_rw_wait(map->lock, _MALI_OSK_LOCKMODE_RW); | |
130 | if ((descriptor > 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage)) { | |
131 | map->table->mappings[descriptor] = NULL; | |
132 | _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage); | |
133 | } | |
134 | _mali_osk_mutex_rw_signal(map->lock, _MALI_OSK_LOCKMODE_RW); | |
135 | } | |
136 | ||
bdc132d7 | 137 | static ump_descriptor_table *descriptor_table_alloc(int count) |
6fa3eb70 | 138 | { |
bdc132d7 | 139 | ump_descriptor_table *table; |
6fa3eb70 | 140 | |
bdc132d7 | 141 | table = _mali_osk_calloc(1, sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count) / BITS_PER_LONG) + (sizeof(void *) * count)); |
6fa3eb70 S |
142 | |
143 | if (NULL != table) { | |
bdc132d7 S |
144 | table->usage = (u32 *)((u8 *)table + sizeof(ump_descriptor_table)); |
145 | table->mappings = (void **)((u8 *)table + sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count) / BITS_PER_LONG)); | |
6fa3eb70 S |
146 | } |
147 | ||
148 | return table; | |
149 | } | |
150 | ||
bdc132d7 | 151 | static void descriptor_table_free(ump_descriptor_table *table) |
6fa3eb70 S |
152 | { |
153 | _mali_osk_free(table); | |
154 | } | |
155 |