cvmx-fpa.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /***********************license start***************
  2. * Author: Cavium Networks
  3. *
  4. * Contact: support@caviumnetworks.com
  5. * This file is part of the OCTEON SDK
  6. *
  7. * Copyright (c) 2003-2008 Cavium Networks
  8. *
  9. * This file is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License, Version 2, as
  11. * published by the Free Software Foundation.
  12. *
  13. * This file is distributed in the hope that it will be useful, but
  14. * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
  15. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
  16. * NONINFRINGEMENT. See the GNU General Public License for more
  17. * details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this file; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22. * or visit http://www.gnu.org/licenses/.
  23. *
  24. * This file may also be available under a different license from Cavium.
  25. * Contact Cavium Networks for more information
  26. ***********************license end**************************************/
  27. /**
  28. * @file
  29. *
  30. * Support library for the hardware Free Pool Allocator.
  31. *
  32. *
  33. */
  34. #include "cvmx-config.h"
  35. #include "cvmx.h"
  36. #include "cvmx-fpa.h"
  37. #include "cvmx-ipd.h"
  38. /**
  39. * Current state of all the pools. Use access functions
  40. * instead of using it directly.
  41. */
  42. CVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
  43. /**
  44. * Setup a FPA pool to control a new block of memory. The
  45. * buffer pointer must be a physical address.
  46. *
  47. * @pool: Pool to initialize
  48. * 0 <= pool < 8
  49. * @name: Constant character string to name this pool.
  50. * String is not copied.
  51. * @buffer: Pointer to the block of memory to use. This must be
  52. * accessible by all processors and external hardware.
  53. * @block_size: Size for each block controlled by the FPA
  54. * @num_blocks: Number of blocks
  55. *
  56. * Returns 0 on Success,
  57. * -1 on failure
  58. */
  59. int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
  60. uint64_t block_size, uint64_t num_blocks)
  61. {
  62. char *ptr;
  63. if (!buffer) {
  64. cvmx_dprintf
  65. ("ERROR: cvmx_fpa_setup_pool: NULL buffer pointer!\n");
  66. return -1;
  67. }
  68. if (pool >= CVMX_FPA_NUM_POOLS) {
  69. cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Illegal pool!\n");
  70. return -1;
  71. }
  72. if (block_size < CVMX_FPA_MIN_BLOCK_SIZE) {
  73. cvmx_dprintf
  74. ("ERROR: cvmx_fpa_setup_pool: Block size too small.\n");
  75. return -1;
  76. }
  77. if (((unsigned long)buffer & (CVMX_FPA_ALIGNMENT - 1)) != 0) {
  78. cvmx_dprintf
  79. ("ERROR: cvmx_fpa_setup_pool: Buffer not aligned properly.\n");
  80. return -1;
  81. }
  82. cvmx_fpa_pool_info[pool].name = name;
  83. cvmx_fpa_pool_info[pool].size = block_size;
  84. cvmx_fpa_pool_info[pool].starting_element_count = num_blocks;
  85. cvmx_fpa_pool_info[pool].base = buffer;
  86. ptr = (char *)buffer;
  87. while (num_blocks--) {
  88. cvmx_fpa_free(ptr, pool, 0);
  89. ptr += block_size;
  90. }
  91. return 0;
  92. }
  93. /**
  94. * Shutdown a Memory pool and validate that it had all of
  95. * the buffers originally placed in it.
  96. *
  97. * @pool: Pool to shutdown
  98. * Returns Zero on success
  99. * - Positive is count of missing buffers
  100. * - Negative is too many buffers or corrupted pointers
  101. */
  102. uint64_t cvmx_fpa_shutdown_pool(uint64_t pool)
  103. {
  104. uint64_t errors = 0;
  105. uint64_t count = 0;
  106. uint64_t base = cvmx_ptr_to_phys(cvmx_fpa_pool_info[pool].base);
  107. uint64_t finish =
  108. base +
  109. cvmx_fpa_pool_info[pool].size *
  110. cvmx_fpa_pool_info[pool].starting_element_count;
  111. void *ptr;
  112. uint64_t address;
  113. count = 0;
  114. do {
  115. ptr = cvmx_fpa_alloc(pool);
  116. if (ptr)
  117. address = cvmx_ptr_to_phys(ptr);
  118. else
  119. address = 0;
  120. if (address) {
  121. if ((address >= base) && (address < finish) &&
  122. (((address -
  123. base) % cvmx_fpa_pool_info[pool].size) == 0)) {
  124. count++;
  125. } else {
  126. cvmx_dprintf
  127. ("ERROR: cvmx_fpa_shutdown_pool: Illegal address 0x%llx in pool %s(%d)\n",
  128. (unsigned long long)address,
  129. cvmx_fpa_pool_info[pool].name, (int)pool);
  130. errors++;
  131. }
  132. }
  133. } while (address);
  134. #ifdef CVMX_ENABLE_PKO_FUNCTIONS
  135. if (pool == 0)
  136. cvmx_ipd_free_ptr();
  137. #endif
  138. if (errors) {
  139. cvmx_dprintf
  140. ("ERROR: cvmx_fpa_shutdown_pool: Pool %s(%d) started at 0x%llx, ended at 0x%llx, with a step of 0x%llx\n",
  141. cvmx_fpa_pool_info[pool].name, (int)pool,
  142. (unsigned long long)base, (unsigned long long)finish,
  143. (unsigned long long)cvmx_fpa_pool_info[pool].size);
  144. return -errors;
  145. } else
  146. return 0;
  147. }
  148. uint64_t cvmx_fpa_get_block_size(uint64_t pool)
  149. {
  150. switch (pool) {
  151. case 0:
  152. return CVMX_FPA_POOL_0_SIZE;
  153. case 1:
  154. return CVMX_FPA_POOL_1_SIZE;
  155. case 2:
  156. return CVMX_FPA_POOL_2_SIZE;
  157. case 3:
  158. return CVMX_FPA_POOL_3_SIZE;
  159. case 4:
  160. return CVMX_FPA_POOL_4_SIZE;
  161. case 5:
  162. return CVMX_FPA_POOL_5_SIZE;
  163. case 6:
  164. return CVMX_FPA_POOL_6_SIZE;
  165. case 7:
  166. return CVMX_FPA_POOL_7_SIZE;
  167. default:
  168. return 0;
  169. }
  170. }