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