ump_kernel_descriptor_mapping.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. #include "mali_kernel_common.h"
  11. #include "mali_osk.h"
  12. #include "mali_osk_bitops.h"
  13. #include "ump_kernel_common.h"
  14. #include "ump_kernel_descriptor_mapping.h"
  15. #define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1))
  16. /**
  17. * Allocate a descriptor table capable of holding 'count' mappings
  18. * @param count Number of mappings in the table
  19. * @return Pointer to a new table, NULL on error
  20. */
  21. static ump_descriptor_table * descriptor_table_alloc(int count);
  22. /**
  23. * Free a descriptor table
  24. * @param table The table to free
  25. */
  26. static void descriptor_table_free(ump_descriptor_table * table);
  27. ump_descriptor_mapping * ump_descriptor_mapping_create(int init_entries, int max_entries)
  28. {
  29. ump_descriptor_mapping * map = _mali_osk_calloc(1, sizeof(ump_descriptor_mapping) );
  30. init_entries = MALI_PAD_INT(init_entries);
  31. max_entries = MALI_PAD_INT(max_entries);
  32. if (NULL != map)
  33. {
  34. map->table = descriptor_table_alloc(init_entries);
  35. if (NULL != map->table)
  36. {
  37. map->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_READERWRITER, 0 , 0);
  38. if ( NULL != map->lock )
  39. {
  40. _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */
  41. map->max_nr_mappings_allowed = max_entries;
  42. map->current_nr_mappings = init_entries;
  43. return map;
  44. }
  45. descriptor_table_free(map->table);
  46. }
  47. _mali_osk_free(map);
  48. }
  49. return NULL;
  50. }
  51. void ump_descriptor_mapping_destroy(ump_descriptor_mapping * map)
  52. {
  53. descriptor_table_free(map->table);
  54. _mali_osk_lock_term( map->lock );
  55. _mali_osk_free(map);
  56. }
  57. int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * target)
  58. {
  59. int descriptor = -1;/*-EFAULT;*/
  60. _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
  61. descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings);
  62. if (descriptor == map->current_nr_mappings)
  63. {
  64. int nr_mappings_new;
  65. /* no free descriptor, try to expand the table */
  66. ump_descriptor_table * new_table;
  67. ump_descriptor_table * old_table = map->table;
  68. nr_mappings_new= map->current_nr_mappings *2;
  69. if (map->current_nr_mappings >= map->max_nr_mappings_allowed)
  70. {
  71. descriptor = -1;
  72. goto unlock_and_exit;
  73. }
  74. new_table = descriptor_table_alloc(nr_mappings_new);
  75. if (NULL == new_table)
  76. {
  77. descriptor = -1;
  78. goto unlock_and_exit;
  79. }
  80. _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG);
  81. _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*));
  82. map->table = new_table;
  83. map->current_nr_mappings = nr_mappings_new;
  84. descriptor_table_free(old_table);
  85. }
  86. /* we have found a valid descriptor, set the value and usage bit */
  87. _mali_osk_set_nonatomic_bit(descriptor, map->table->usage);
  88. map->table->mappings[descriptor] = target;
  89. unlock_and_exit:
  90. _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
  91. return descriptor;
  92. }
  93. int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, void** target)
  94. {
  95. int result = -1;/*-EFAULT;*/
  96. DEBUG_ASSERT(map);
  97. _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
  98. if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
  99. {
  100. *target = map->table->mappings[descriptor];
  101. result = 0;
  102. }
  103. else *target = NULL;
  104. _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
  105. return result;
  106. }
  107. int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, void * target)
  108. {
  109. int result = -1;/*-EFAULT;*/
  110. _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
  111. if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
  112. {
  113. map->table->mappings[descriptor] = target;
  114. result = 0;
  115. }
  116. _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
  117. return result;
  118. }
  119. void ump_descriptor_mapping_free(ump_descriptor_mapping * map, int descriptor)
  120. {
  121. _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
  122. if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
  123. {
  124. map->table->mappings[descriptor] = NULL;
  125. _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage);
  126. }
  127. _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
  128. }
  129. static ump_descriptor_table * descriptor_table_alloc(int count)
  130. {
  131. ump_descriptor_table * table;
  132. table = _mali_osk_calloc(1, sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG) + (sizeof(void*) * count) );
  133. if (NULL != table)
  134. {
  135. table->usage = (u32*)((u8*)table + sizeof(ump_descriptor_table));
  136. table->mappings = (void**)((u8*)table + sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG));
  137. }
  138. return table;
  139. }
  140. static void descriptor_table_free(ump_descriptor_table * table)
  141. {
  142. _mali_osk_free(table);
  143. }