004-named_alloc_function.patch 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. The MGMT ethernet driver uses these new functions.
  2. Signed-off-by: David Daney <[email protected]>
  3. ---
  4. arch/mips/cavium-octeon/executive/cvmx-bootmem.c | 101 ++++++++++++++++++++++
  5. arch/mips/include/asm/octeon/cvmx-bootmem.h | 85 ++++++++++++++++++
  6. 2 files changed, 186 insertions(+), 0 deletions(-)
  7. --- a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
  8. +++ b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
  9. @@ -97,6 +97,32 @@ void *cvmx_bootmem_alloc(uint64_t size,
  10. return cvmx_bootmem_alloc_range(size, alignment, 0, 0);
  11. }
  12. +void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
  13. + uint64_t max_addr, uint64_t align,
  14. + char *name)
  15. +{
  16. + int64_t addr;
  17. +
  18. + addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr,
  19. + align, name, 0);
  20. + if (addr >= 0)
  21. + return cvmx_phys_to_ptr(addr);
  22. + else
  23. + return NULL;
  24. +}
  25. +
  26. +void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address,
  27. + char *name)
  28. +{
  29. + return cvmx_bootmem_alloc_named_range(size, address, address + size,
  30. + 0, name);
  31. +}
  32. +
  33. +void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, char *name)
  34. +{
  35. + return cvmx_bootmem_alloc_named_range(size, 0, 0, alignment, name);
  36. +}
  37. +
  38. int cvmx_bootmem_free_named(char *name)
  39. {
  40. return cvmx_bootmem_phy_named_block_free(name, 0);
  41. @@ -584,3 +610,78 @@ int cvmx_bootmem_phy_named_block_free(ch
  42. cvmx_bootmem_unlock();
  43. return named_block_ptr != NULL; /* 0 on failure, 1 on success */
  44. }
  45. +
  46. +int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr,
  47. + uint64_t max_addr,
  48. + uint64_t alignment,
  49. + char *name,
  50. + uint32_t flags)
  51. +{
  52. + int64_t addr_allocated;
  53. + struct cvmx_bootmem_named_block_desc *named_block_desc_ptr;
  54. +
  55. +#ifdef DEBUG
  56. + cvmx_dprintf("cvmx_bootmem_phy_named_block_alloc: size: 0x%llx, min: "
  57. + "0x%llx, max: 0x%llx, align: 0x%llx, name: %s\n",
  58. + (unsigned long long)size,
  59. + (unsigned long long)min_addr,
  60. + (unsigned long long)max_addr,
  61. + (unsigned long long)alignment,
  62. + name);
  63. +#endif
  64. + if (cvmx_bootmem_desc->major_version != 3) {
  65. + cvmx_dprintf("ERROR: Incompatible bootmem descriptor version: "
  66. + "%d.%d at addr: %p\n",
  67. + (int)cvmx_bootmem_desc->major_version,
  68. + (int)cvmx_bootmem_desc->minor_version,
  69. + cvmx_bootmem_desc);
  70. + return -1;
  71. + }
  72. +
  73. + /*
  74. + * Take lock here, as name lookup/block alloc/name add need to
  75. + * be atomic.
  76. + */
  77. + if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
  78. + cvmx_spinlock_lock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
  79. +
  80. + /* Get pointer to first available named block descriptor */
  81. + named_block_desc_ptr =
  82. + cvmx_bootmem_phy_named_block_find(NULL,
  83. + flags | CVMX_BOOTMEM_FLAG_NO_LOCKING);
  84. +
  85. + /*
  86. + * Check to see if name already in use, return error if name
  87. + * not available or no more room for blocks.
  88. + */
  89. + if (cvmx_bootmem_phy_named_block_find(name,
  90. + flags | CVMX_BOOTMEM_FLAG_NO_LOCKING) || !named_block_desc_ptr) {
  91. + if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
  92. + cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
  93. + return -1;
  94. + }
  95. +
  96. +
  97. + /*
  98. + * Round size up to mult of minimum alignment bytes We need
  99. + * the actual size allocated to allow for blocks to be
  100. + * coallesced when they are freed. The alloc routine does the
  101. + * same rounding up on all allocations.
  102. + */
  103. + size = __ALIGN_MASK(size, (CVMX_BOOTMEM_ALIGNMENT_SIZE - 1));
  104. +
  105. + addr_allocated = cvmx_bootmem_phy_alloc(size, min_addr, max_addr,
  106. + alignment,
  107. + flags | CVMX_BOOTMEM_FLAG_NO_LOCKING);
  108. + if (addr_allocated >= 0) {
  109. + named_block_desc_ptr->base_addr = addr_allocated;
  110. + named_block_desc_ptr->size = size;
  111. + strncpy(named_block_desc_ptr->name, name,
  112. + cvmx_bootmem_desc->named_block_name_len);
  113. + named_block_desc_ptr->name[cvmx_bootmem_desc->named_block_name_len - 1] = 0;
  114. + }
  115. +
  116. + if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
  117. + cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
  118. + return addr_allocated;
  119. +}
  120. --- a/arch/mips/include/asm/octeon/cvmx-bootmem.h
  121. +++ b/arch/mips/include/asm/octeon/cvmx-bootmem.h
  122. @@ -183,6 +183,64 @@ extern void *cvmx_bootmem_alloc_range(ui
  123. * Returns 0 on failure,
  124. * !0 on success
  125. */
  126. +
  127. +
  128. +/**
  129. + * Allocate a block of memory from the free list that was passed
  130. + * to the application by the bootloader, and assign it a name in the
  131. + * global named block table. (part of the cvmx_bootmem_descriptor_t structure)
  132. + * Named blocks can later be freed.
  133. + *
  134. + * @size: Size in bytes of block to allocate
  135. + * @alignment: Alignment required - must be power of 2
  136. + * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
  137. + *
  138. + * Returns a pointer to block of memory, NULL on error
  139. + */
  140. +extern void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment,
  141. + char *name);
  142. +
  143. +
  144. +
  145. +/**
  146. + * Allocate a block of memory from the free list that was passed
  147. + * to the application by the bootloader, and assign it a name in the
  148. + * global named block table. (part of the cvmx_bootmem_descriptor_t structure)
  149. + * Named blocks can later be freed.
  150. + *
  151. + * @size: Size in bytes of block to allocate
  152. + * @address: Physical address to allocate memory at. If this
  153. + * memory is not available, the allocation fails.
  154. + * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN
  155. + * bytes
  156. + *
  157. + * Returns a pointer to block of memory, NULL on error
  158. + */
  159. +extern void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address,
  160. + char *name);
  161. +
  162. +
  163. +
  164. +/**
  165. + * Allocate a block of memory from a specific range of the free list
  166. + * that was passed to the application by the bootloader, and assign it
  167. + * a name in the global named block table. (part of the
  168. + * cvmx_bootmem_descriptor_t structure) Named blocks can later be
  169. + * freed. If request cannot be satisfied within the address range
  170. + * specified, NULL is returned
  171. + *
  172. + * @size: Size in bytes of block to allocate
  173. + * @min_addr: minimum address of range
  174. + * @max_addr: maximum address of range
  175. + * @align: Alignment of memory to be allocated. (must be a power of 2)
  176. + * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
  177. + *
  178. + * Returns a pointer to block of memory, NULL on error
  179. + */
  180. +extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
  181. + uint64_t max_addr, uint64_t align,
  182. + char *name);
  183. +
  184. extern int cvmx_bootmem_free_named(char *name);
  185. /**
  186. @@ -224,6 +282,33 @@ int64_t cvmx_bootmem_phy_alloc(uint64_t
  187. uint32_t flags);
  188. /**
  189. + * Allocates a named block of physical memory from the free list, at
  190. + * (optional) requested address and alignment.
  191. + *
  192. + * @param size size of region to allocate. All requests are rounded
  193. + * up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE
  194. + * bytes size
  195. + * @param min_addr Minimum address that block can occupy.
  196. + * @param max_addr Specifies the maximum address_min (inclusive) that
  197. + * the allocation can use.
  198. + * @param alignment Requested alignment of the block. If this
  199. + * alignment cannot be met, the allocation fails.
  200. + * This must be a power of 2. (Note: Alignment of
  201. + * CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and
  202. + * internally enforced. Requested alignments of less
  203. + * than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to
  204. + * CVMX_BOOTMEM_ALIGNMENT_SIZE.)
  205. + * @param name name to assign to named block
  206. + * @param flags Flags to control options for the allocation.
  207. + *
  208. + * @return physical address of block allocated, or -1 on failure
  209. + */
  210. +int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr,
  211. + uint64_t max_addr,
  212. + uint64_t alignment,
  213. + char *name, uint32_t flags);
  214. +
  215. +/**
  216. * Finds a named memory block by name.
  217. * Also used for finding an unused entry in the named block table.
  218. *