cvmx-bootmem.h revision 215990
1/***********************license start*************** 2 * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights 3 * reserved. 4 * 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 18 * * Neither the name of Cavium Networks nor the names of 19 * its contributors may be used to endorse or promote products 20 * derived from this software without specific prior written 21 * permission. 22 23 * This Software, including technical data, may be subject to U.S. export control 24 * laws, including the U.S. Export Administration Act and its associated 25 * regulations, and may be subject to export or import regulations in other 26 * countries. 27 28 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 29 * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR 30 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO 31 * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 32 * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 33 * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 34 * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 35 * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 36 * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 37 * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 38 ***********************license end**************************************/ 39 40 41 42 43 44 45/** 46 * @file 47 * Simple allocate only memory allocator. Used to allocate memory at application 48 * start time. 49 * 50 * <hr>$Revision: 49448 $<hr> 51 * 52 */ 53 54#ifndef __CVMX_BOOTMEM_H__ 55#define __CVMX_BOOTMEM_H__ 56 57#ifdef __cplusplus 58extern "C" { 59#endif 60 61#define CVMX_BOOTMEM_NAME_LEN 128 /* Must be multiple of 8, changing breaks ABI */ 62#define CVMX_BOOTMEM_NUM_NAMED_BLOCKS 64 /* Can change without breaking ABI */ 63#define CVMX_BOOTMEM_ALIGNMENT_SIZE (16ull) /* minimum alignment of bootmem alloced blocks */ 64 65/* Flags for cvmx_bootmem_phy_mem* functions */ 66#define CVMX_BOOTMEM_FLAG_END_ALLOC (1 << 0) /* Allocate from end of block instead of beginning */ 67#define CVMX_BOOTMEM_FLAG_NO_LOCKING (1 << 1) /* Don't do any locking. */ 68 69 70/* First bytes of each free physical block of memory contain this structure, 71 * which is used to maintain the free memory list. Since the bootloader is 72 * only 32 bits, there is a union providing 64 and 32 bit versions. The 73 * application init code converts addresses to 64 bit addresses before the 74 * application starts. 75 */ 76typedef struct 77{ 78 /* Note: these are referenced from assembly routines in the bootloader, so this structure 79 ** should not be changed without changing those routines as well. */ 80 uint64_t next_block_addr; 81 uint64_t size; 82 83} cvmx_bootmem_block_header_t; 84 85 86/* Structure for named memory blocks 87** Number of descriptors 88** available can be changed without affecting compatiblity, 89** but name length changes require a bump in the bootmem 90** descriptor version 91** Note: This structure must be naturally 64 bit aligned, as a single 92** memory image will be used by both 32 and 64 bit programs. 93*/ 94struct cvmx_bootmem_named_block_desc 95{ 96 uint64_t base_addr; /**< Base address of named block */ 97 uint64_t size; /**< Size actually allocated for named block (may differ from requested) */ 98 char name[CVMX_BOOTMEM_NAME_LEN]; /**< name of named block */ 99}; 100 101typedef struct cvmx_bootmem_named_block_desc cvmx_bootmem_named_block_desc_t; 102 103/* Current descriptor versions */ 104#define CVMX_BOOTMEM_DESC_MAJ_VER 3 /* CVMX bootmem descriptor major version */ 105#define CVMX_BOOTMEM_DESC_MIN_VER 0 /* CVMX bootmem descriptor minor version */ 106 107/* First three members of cvmx_bootmem_desc_t are left in original 108** positions for backwards compatibility. 109*/ 110typedef struct 111{ 112 uint32_t lock; /**< spinlock to control access to list */ 113 uint32_t flags; /**< flags for indicating various conditions */ 114 uint64_t head_addr; 115 116 uint32_t major_version; /**< incremented changed when incompatible changes made */ 117 uint32_t minor_version; /**< incremented changed when compatible changes made, reset to zero when major incremented */ 118 uint64_t app_data_addr; 119 uint64_t app_data_size; 120 121 uint32_t named_block_num_blocks; /**< number of elements in named blocks array */ 122 uint32_t named_block_name_len; /**< length of name array in bootmem blocks */ 123 uint64_t named_block_array_addr; /**< address of named memory block descriptors */ 124 125} cvmx_bootmem_desc_t; 126 127 128/** 129 * Initialize the boot alloc memory structures. This is 130 * normally called inside of cvmx_user_app_init() 131 * 132 * @param mem_desc_addr Address of the free memory list 133 * @return 134 */ 135extern int cvmx_bootmem_init(uint64_t mem_desc_addr); 136 137 138/** 139 * Allocate a block of memory from the free list that was passed 140 * to the application by the bootloader. 141 * This is an allocate-only algorithm, so freeing memory is not possible. 142 * 143 * @param size Size in bytes of block to allocate 144 * @param alignment Alignment required - must be power of 2 145 * 146 * @return pointer to block of memory, NULL on error 147 */ 148extern void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment); 149 150/** 151 * Allocate a block of memory from the free list that was 152 * passed to the application by the bootloader at a specific 153 * address. This is an allocate-only algorithm, so 154 * freeing memory is not possible. Allocation will fail if 155 * memory cannot be allocated at the specified address. 156 * 157 * @param size Size in bytes of block to allocate 158 * @param address Physical address to allocate memory at. If this memory is not 159 * available, the allocation fails. 160 * @param alignment Alignment required - must be power of 2 161 * @return pointer to block of memory, NULL on error 162 */ 163extern void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address, uint64_t alignment); 164 165 166 167/** 168 * Allocate a block of memory from the free list that was 169 * passed to the application by the bootloader within a specified 170 * address range. This is an allocate-only algorithm, so 171 * freeing memory is not possible. Allocation will fail if 172 * memory cannot be allocated in the requested range. 173 * 174 * @param size Size in bytes of block to allocate 175 * @param min_addr defines the minimum address of the range 176 * @param max_addr defines the maximum address of the range 177 * @param alignment Alignment required - must be power of 2 178 * @return pointer to block of memory, NULL on error 179 */ 180extern void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment, uint64_t min_addr, uint64_t max_addr); 181 182 183/** 184 * Allocate a block of memory from the free list that was passed 185 * to the application by the bootloader, and assign it a name in the 186 * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 187 * Named blocks can later be freed. 188 * 189 * @param size Size in bytes of block to allocate 190 * @param alignment Alignment required - must be power of 2 191 * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 192 * 193 * @return pointer to block of memory, NULL on error 194 */ 195extern void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, const char *name); 196 197 198 199/** 200 * Allocate a block of memory from the free list that was passed 201 * to the application by the bootloader, and assign it a name in the 202 * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 203 * Named blocks can later be freed. 204 * 205 * @param size Size in bytes of block to allocate 206 * @param address Physical address to allocate memory at. If this memory is not 207 * available, the allocation fails. 208 * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 209 * 210 * @return pointer to block of memory, NULL on error 211 */ 212extern void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address, const char *name); 213 214 215 216/** 217 * Allocate a block of memory from a specific range of the free list that was passed 218 * to the application by the bootloader, and assign it a name in the 219 * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 220 * Named blocks can later be freed. 221 * If request cannot be satisfied within the address range specified, NULL is returned 222 * 223 * @param size Size in bytes of block to allocate 224 * @param min_addr minimum address of range 225 * @param max_addr maximum address of range 226 * @param align Alignment of memory to be allocated. (must be a power of 2) 227 * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 228 * 229 * @return pointer to block of memory, NULL on error 230 */ 231extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, uint64_t max_addr, uint64_t align, const char *name); 232 233/** 234 * Frees a previously allocated named bootmem block. 235 * 236 * @param name name of block to free 237 * 238 * @return 0 on failure, 239 * !0 on success 240 */ 241extern int cvmx_bootmem_free_named(const char *name); 242 243 244/** 245 * Finds a named bootmem block by name. 246 * 247 * @param name name of block to free 248 * 249 * @return pointer to named block descriptor on success 250 * 0 on failure 251 */ 252const cvmx_bootmem_named_block_desc_t *cvmx_bootmem_find_named_block(const char *name); 253 254 255 256/** 257 * Returns the size of available memory in bytes, only 258 * counting blocks that are at least as big as the minimum block 259 * size. 260 * 261 * @param min_block_size 262 * Minimum block size to count in total. 263 * 264 * @return Number of bytes available for allocation that meet the block size requirement 265 */ 266uint64_t cvmx_bootmem_available_mem(uint64_t min_block_size); 267 268 269 270/** 271 * Prints out the list of named blocks that have been allocated 272 * along with their addresses and sizes. 273 * This is primarily used for debugging purposes 274 */ 275void cvmx_bootmem_print_named(void); 276 277 278/** 279 * Allocates a block of physical memory from the free list, at (optional) requested address and alignment. 280 * 281 * @param req_size size of region to allocate. All requests are rounded up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size 282 * @param address_min 283 * Minimum address that block can occupy. 284 * @param address_max 285 * Specifies the maximum address_min (inclusive) that the allocation can use. 286 * @param alignment Requested alignment of the block. If this alignment cannot be met, the allocation fails. 287 * This must be a power of 2. 288 * (Note: Alignment of CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and internally enforced. Requested alignments of 289 * less than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to CVMX_BOOTMEM_ALIGNMENT_SIZE.) 290 * @param flags Flags to control options for the allocation. 291 * 292 * @return physical address of block allocated, or -1 on failure 293 */ 294int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min, uint64_t address_max, uint64_t alignment, uint32_t flags); 295 296 297 298/** 299 * Allocates a named block of physical memory from the free list, at (optional) requested address and alignment. 300 * 301 * @param size size of region to allocate. All requests are rounded up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size 302 * @param min_addr 303 * Minimum address that block can occupy. 304 * @param max_addr 305 * Specifies the maximum address_min (inclusive) that the allocation can use. 306 * @param alignment Requested alignment of the block. If this alignment cannot be met, the allocation fails. 307 * This must be a power of 2. 308 * (Note: Alignment of CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and internally enforced. Requested alignments of 309 * less than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to CVMX_BOOTMEM_ALIGNMENT_SIZE.) 310 * @param name name to assign to named block 311 * @param flags Flags to control options for the allocation. 312 * 313 * @return physical address of block allocated, or -1 on failure 314 */ 315int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr, uint64_t max_addr, uint64_t alignment, const char *name, uint32_t flags); 316 317 318/** 319 * Finds a named memory block by name. 320 * Also used for finding an unused entry in the named block table. 321 * 322 * @param name Name of memory block to find. 323 * If NULL pointer given, then finds unused descriptor, if available. 324 * @param flags Flags to control options for the allocation. 325 * 326 * @return Physical address of the memory block descriptor, zero if not 327 * found. If zero returned when name parameter is NULL, then no 328 * memory block descriptors are available. 329 */ 330uint64_t cvmx_bootmem_phy_named_block_find(const char *name, uint32_t flags); 331 332 333/** 334 * Returns the size of available memory in bytes, only 335 * counting blocks that are at least as big as the minimum block 336 * size. 337 * 338 * @param min_block_size 339 * Minimum block size to count in total. 340 * 341 * @return Number of bytes available for allocation that meet the block size requirement 342 */ 343uint64_t cvmx_bootmem_phy_available_mem(uint64_t min_block_size); 344 345/** 346 * Frees a named block. 347 * 348 * @param name name of block to free 349 * @param flags flags for passing options 350 * 351 * @return 0 on failure 352 * 1 on success 353 */ 354int cvmx_bootmem_phy_named_block_free(const char *name, uint32_t flags); 355 356/** 357 * Frees a block to the bootmem allocator list. This must 358 * be used with care, as the size provided must match the size 359 * of the block that was allocated, or the list will become 360 * corrupted. 361 * 362 * IMPORTANT: This is only intended to be used as part of named block 363 * frees and initial population of the free memory list. 364 * * 365 * 366 * @param phy_addr physical address of block 367 * @param size size of block in bytes. 368 * @param flags flags for passing options 369 * 370 * @return 1 on success, 371 * 0 on failure 372 */ 373int __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags); 374 375 376/** 377 * Prints the list of currently allocated named blocks 378 * 379 */ 380void cvmx_bootmem_phy_named_block_print(void); 381 382 383/** 384 * Prints the list of available memory. 385 * 386 */ 387void cvmx_bootmem_phy_list_print(void); 388 389 390 391/** 392 * This function initializes the free memory list used by cvmx_bootmem. 393 * This must be called before any allocations can be done. 394 * 395 * @param mem_size Total memory available, in bytes 396 * @param low_reserved_bytes 397 * Number of bytes to reserve (leave out of free list) at address 0x0. 398 * @param desc_buffer 399 * Buffer for the bootmem descriptor. This must be a 32 bit addressable 400 * address. 401 * 402 * @return 1 on success 403 * 0 on failure 404 */ 405int64_t cvmx_bootmem_phy_mem_list_init(uint64_t mem_size, uint32_t low_reserved_bytes, cvmx_bootmem_desc_t *desc_buffer); 406 407/** 408 * Locks the bootmem allocator. This is useful in certain situations 409 * where multiple allocations must be made without being interrupted. 410 * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag. 411 * 412 */ 413void cvmx_bootmem_lock(void); 414 415/** 416 * Unlocks the bootmem allocator. This is useful in certain situations 417 * where multiple allocations must be made without being interrupted. 418 * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag. 419 * 420 */ 421void cvmx_bootmem_unlock(void); 422 423/** 424 * Internal use function to get the current descriptor pointer */ 425void *__cvmx_bootmem_internal_get_desc_ptr(void); 426 427#ifdef __cplusplus 428} 429#endif 430 431#endif /* __CVMX_BOOTMEM_H__ */ 432