2 * This confidential and proprietary software may be used only as
3 * authorised by a licensing agreement from ARM Limited
4 * (C) COPYRIGHT 2008-2011, 2013 ARM Limited
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.
11 #include "mali_kernel_common.h"
13 #include "mali_osk_bitops.h"
14 #include "ump_kernel_common.h"
15 #include "ump_kernel_descriptor_mapping.h"
17 #define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1))
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
24 static ump_descriptor_table
* descriptor_table_alloc(int count
);
27 * Free a descriptor table
28 * @param table The table to free
30 static void descriptor_table_free(ump_descriptor_table
* table
);
32 ump_descriptor_mapping
* ump_descriptor_mapping_create(int init_entries
, int max_entries
)
34 ump_descriptor_mapping
* map
= _mali_osk_calloc(1, sizeof(ump_descriptor_mapping
) );
36 init_entries
= MALI_PAD_INT(init_entries
);
37 max_entries
= MALI_PAD_INT(max_entries
);
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);
43 if ( NULL
!= map
->lock
) {
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
;
49 descriptor_table_free(map
->table
);
56 void ump_descriptor_mapping_destroy(ump_descriptor_mapping
* map
)
58 descriptor_table_free(map
->table
);
59 _mali_osk_mutex_rw_term(map
->lock
);
63 int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping
* map
, void * target
)
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
) {
70 /* no free descriptor, try to expand the table */
71 ump_descriptor_table
* new_table
;
72 ump_descriptor_table
* old_table
= map
->table
;
73 nr_mappings_new
= map
->current_nr_mappings
*2;
75 if (map
->current_nr_mappings
>= map
->max_nr_mappings_allowed
) {
80 new_table
= descriptor_table_alloc(nr_mappings_new
);
81 if (NULL
== new_table
) {
86 _mali_osk_memcpy(new_table
->usage
, old_table
->usage
, (sizeof(unsigned long)*map
->current_nr_mappings
) / BITS_PER_LONG
);
87 _mali_osk_memcpy(new_table
->mappings
, old_table
->mappings
, map
->current_nr_mappings
* sizeof(void*));
88 map
->table
= new_table
;
89 map
->current_nr_mappings
= nr_mappings_new
;
90 descriptor_table_free(old_table
);
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
;
98 _mali_osk_mutex_rw_signal(map
->lock
, _MALI_OSK_LOCKMODE_RW
);
102 int ump_descriptor_mapping_get(ump_descriptor_mapping
* map
, int descriptor
, void** target
)
104 int result
= -1;/*-EFAULT;*/
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
];
110 } else *target
= NULL
;
111 _mali_osk_mutex_rw_signal(map
->lock
, _MALI_OSK_LOCKMODE_RO
);
115 int ump_descriptor_mapping_set(ump_descriptor_mapping
* map
, int descriptor
, void * target
)
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
;
123 _mali_osk_mutex_rw_signal(map
->lock
, _MALI_OSK_LOCKMODE_RO
);
127 void ump_descriptor_mapping_free(ump_descriptor_mapping
* map
, int descriptor
)
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
);
134 _mali_osk_mutex_rw_signal(map
->lock
, _MALI_OSK_LOCKMODE_RW
);
137 static ump_descriptor_table
* descriptor_table_alloc(int count
)
139 ump_descriptor_table
* table
;
141 table
= _mali_osk_calloc(1, sizeof(ump_descriptor_table
) + ((sizeof(unsigned long) * count
)/BITS_PER_LONG
) + (sizeof(void*) * count
) );
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
));
151 static void descriptor_table_free(ump_descriptor_table
* table
)
153 _mali_osk_free(table
);