cvmx-bootmem.h revision 302408
1/***********************license start*************** 2 * Copyright (c) 2003-2010 Cavium Inc. (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 Inc. 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 INC. 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: 70030 $<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/* Real physical addresses of memory regions */ 70#define OCTEON_DDR0_BASE (0x0ULL) 71#define OCTEON_DDR0_SIZE (0x010000000ULL) 72#define OCTEON_DDR1_BASE ((OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF7XXX)) ? 0x20000000ULL : 0x410000000ULL) 73#define OCTEON_DDR1_SIZE (0x010000000ULL) 74#define OCTEON_DDR2_BASE ((OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF7XXX)) ? 0x30000000ULL : 0x20000000ULL) 75#define OCTEON_DDR2_SIZE ((OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF7XXX)) ? 0x7d0000000ULL : 0x3e0000000ULL) 76#define OCTEON_MAX_PHY_MEM_SIZE ((OCTEON_IS_MODEL(OCTEON_CN68XX)) ? 128*1024*1024*1024ULL : (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF7XXX)) ? 32*1024*1024*1024ull : 16*1024*1024*1024ULL) 77 78/* First bytes of each free physical block of memory contain this structure, 79 * which is used to maintain the free memory list. Since the bootloader is 80 * only 32 bits, there is a union providing 64 and 32 bit versions. The 81 * application init code converts addresses to 64 bit addresses before the 82 * application starts. 83 */ 84typedef struct 85{ 86 /* Note: these are referenced from assembly routines in the bootloader, so this structure 87 ** should not be changed without changing those routines as well. */ 88 uint64_t next_block_addr; 89 uint64_t size; 90 91} cvmx_bootmem_block_header_t; 92 93 94/* Structure for named memory blocks 95** Number of descriptors 96** available can be changed without affecting compatiblity, 97** but name length changes require a bump in the bootmem 98** descriptor version 99** Note: This structure must be naturally 64 bit aligned, as a single 100** memory image will be used by both 32 and 64 bit programs. 101*/ 102struct cvmx_bootmem_named_block_desc 103{ 104 uint64_t base_addr; /**< Base address of named block */ 105 uint64_t size; /**< Size actually allocated for named block (may differ from requested) */ 106 char name[CVMX_BOOTMEM_NAME_LEN]; /**< name of named block */ 107}; 108 109typedef struct cvmx_bootmem_named_block_desc cvmx_bootmem_named_block_desc_t; 110 111/* Current descriptor versions */ 112#define CVMX_BOOTMEM_DESC_MAJ_VER 3 /* CVMX bootmem descriptor major version */ 113#define CVMX_BOOTMEM_DESC_MIN_VER 0 /* CVMX bootmem descriptor minor version */ 114 115/* First three members of cvmx_bootmem_desc_t are left in original 116** positions for backwards compatibility. 117*/ 118typedef struct 119{ 120 uint32_t lock; /**< spinlock to control access to list */ 121 uint32_t flags; /**< flags for indicating various conditions */ 122 uint64_t head_addr; 123 124 uint32_t major_version; /**< incremented changed when incompatible changes made */ 125 uint32_t minor_version; /**< incremented changed when compatible changes made, reset to zero when major incremented */ 126 uint64_t app_data_addr; 127 uint64_t app_data_size; 128 129 uint32_t named_block_num_blocks; /**< number of elements in named blocks array */ 130 uint32_t named_block_name_len; /**< length of name array in bootmem blocks */ 131 uint64_t named_block_array_addr; /**< address of named memory block descriptors */ 132 133} cvmx_bootmem_desc_t; 134 135 136/** 137 * Initialize the boot alloc memory structures. This is 138 * normally called inside of cvmx_user_app_init() 139 * 140 * @param mem_desc_addr Address of the free memory list 141 * @return 142 */ 143extern int cvmx_bootmem_init(uint64_t mem_desc_addr); 144 145 146/** 147 * Allocate a block of memory from the free list that was passed 148 * to the application by the bootloader. 149 * This is an allocate-only algorithm, so freeing memory is not possible. 150 * 151 * @param size Size in bytes of block to allocate 152 * @param alignment Alignment required - must be power of 2 153 * 154 * @return pointer to block of memory, NULL on error 155 */ 156extern void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment); 157 158/** 159 * Allocate a block of memory from the free list that was 160 * passed to the application by the bootloader at a specific 161 * address. This is an allocate-only algorithm, so 162 * freeing memory is not possible. Allocation will fail if 163 * memory cannot be allocated at the specified address. 164 * 165 * @param size Size in bytes of block to allocate 166 * @param address Physical address to allocate memory at. If this memory is not 167 * available, the allocation fails. 168 * @param alignment Alignment required - must be power of 2 169 * @return pointer to block of memory, NULL on error 170 */ 171extern void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address, uint64_t alignment); 172 173/** 174 * Allocate a block of memory from the free list that was 175 * passed to the application by the bootloader within a specified 176 * address range. This is an allocate-only algorithm, so 177 * freeing memory is not possible. Allocation will fail if 178 * memory cannot be allocated in the requested range. 179 * 180 * @param size Size in bytes of block to allocate 181 * @param min_addr defines the minimum address of the range 182 * @param max_addr defines the maximum address of the range 183 * @param alignment Alignment required - must be power of 2 184 * @param flags Flags to control options for the allocation. 185 * @return pointer to block of memory, NULL on error 186 */ 187extern void *cvmx_bootmem_alloc_range_flags(uint64_t size, uint64_t alignment, uint64_t min_addr, uint64_t max_addr, uint32_t flags); 188 189 190/** 191 * Allocate a block of memory from the free list that was 192 * passed to the application by the bootloader within a specified 193 * address range. This is an allocate-only algorithm, so 194 * freeing memory is not possible. Allocation will fail if 195 * memory cannot be allocated in the requested range. 196 * 197 * @param size Size in bytes of block to allocate 198 * @param min_addr defines the minimum address of the range 199 * @param max_addr defines the maximum address of the range 200 * @param alignment Alignment required - must be power of 2 201 * @return pointer to block of memory, NULL on error 202 */ 203extern void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment, uint64_t min_addr, uint64_t max_addr); 204 205 206/** 207 * Allocate a block of memory from the free list that was passed 208 * to the application by the bootloader, and assign it a name in the 209 * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 210 * Named blocks can later be freed. 211 * 212 * @param size Size in bytes of block to allocate 213 * @param alignment Alignment required - must be power of 2 214 * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 215 * 216 * @return pointer to block of memory, NULL on error 217 */ 218extern void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, const char *name); 219 220/** 221 * Allocate a block of memory from the free list that was passed 222 * to the application by the bootloader, and assign it a name in the 223 * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 224 * Named blocks can later be freed. 225 * 226 * @param size Size in bytes of block to allocate 227 * @param alignment Alignment required - must be power of 2 228 * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 229 * @param flags Flags to control options for the allocation. 230 * 231 * @return pointer to block of memory, NULL on error 232 */ 233extern void *cvmx_bootmem_alloc_named_flags(uint64_t size, uint64_t alignment, const char *name, uint32_t flags); 234 235 236 237/** 238 * Allocate a block of memory from the free list that was passed 239 * to the application by the bootloader, and assign it a name in the 240 * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 241 * Named blocks can later be freed. 242 * 243 * @param size Size in bytes of block to allocate 244 * @param address Physical address to allocate memory at. If this memory is not 245 * available, the allocation fails. 246 * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 247 * 248 * @return pointer to block of memory, NULL on error 249 */ 250extern void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address, const char *name); 251 252 253 254/** 255 * Allocate a block of memory from a specific range of the free list that was passed 256 * to the application by the bootloader, and assign it a name in the 257 * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 258 * Named blocks can later be freed. 259 * If request cannot be satisfied within the address range specified, NULL is returned 260 * 261 * @param size Size in bytes of block to allocate 262 * @param min_addr minimum address of range 263 * @param max_addr maximum address of range 264 * @param align Alignment of memory to be allocated. (must be a power of 2) 265 * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 266 * 267 * @return pointer to block of memory, NULL on error 268 */ 269extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, uint64_t max_addr, uint64_t align, const char *name); 270 271/** 272 * Allocate if needed a block of memory from a specific range of the free list that was passed 273 * to the application by the bootloader, and assign it a name in the 274 * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 275 * Named blocks can later be freed. 276 * If the requested name block is already allocated, return the pointer to block of memory. 277 * If request cannot be satisfied within the address range specified, NULL is returned 278 * 279 * @param size Size in bytes of block to allocate 280 * @param min_addr minimum address of range 281 * @param max_addr maximum address of range 282 * @param align Alignment of memory to be allocated. (must be a power of 2) 283 * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 284 * @param init Initialization function 285 * 286 * @return pointer to block of memory, NULL on error 287 */ 288extern void *cvmx_bootmem_alloc_named_range_once(uint64_t size, uint64_t min_addr, uint64_t max_addr, uint64_t align, const char *name, void (*init)(void*)); 289 290/** 291 * Frees a previously allocated named bootmem block. 292 * 293 * @param name name of block to free 294 * 295 * @return 0 on failure, 296 * !0 on success 297 */ 298extern int cvmx_bootmem_free_named(const char *name); 299 300 301/** 302 * Finds a named bootmem block by name. 303 * 304 * @param name name of block to free 305 * 306 * @return pointer to named block descriptor on success 307 * 0 on failure 308 */ 309const cvmx_bootmem_named_block_desc_t *cvmx_bootmem_find_named_block(const char *name); 310 311 312 313/** 314 * Returns the size of available memory in bytes, only 315 * counting blocks that are at least as big as the minimum block 316 * size. 317 * 318 * @param min_block_size 319 * Minimum block size to count in total. 320 * 321 * @return Number of bytes available for allocation that meet the block size requirement 322 */ 323uint64_t cvmx_bootmem_available_mem(uint64_t min_block_size); 324 325 326 327/** 328 * Prints out the list of named blocks that have been allocated 329 * along with their addresses and sizes. 330 * This is primarily used for debugging purposes 331 */ 332void cvmx_bootmem_print_named(void); 333 334 335/** 336 * Allocates a block of physical memory from the free list, at (optional) requested address and alignment. 337 * 338 * @param req_size size of region to allocate. All requests are rounded up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size 339 * @param address_min 340 * Minimum address that block can occupy. 341 * @param address_max 342 * Specifies the maximum address_min (inclusive) that the allocation can use. 343 * @param alignment Requested alignment of the block. If this alignment cannot be met, the allocation fails. 344 * This must be a power of 2. 345 * (Note: Alignment of CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and internally enforced. Requested alignments of 346 * less than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to CVMX_BOOTMEM_ALIGNMENT_SIZE.) 347 * @param flags Flags to control options for the allocation. 348 * 349 * @return physical address of block allocated, or -1 on failure 350 */ 351int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min, uint64_t address_max, uint64_t alignment, uint32_t flags); 352 353 354 355/** 356 * Allocates a named block of physical memory from the free list, at (optional) requested address and alignment. 357 * 358 * @param size size of region to allocate. All requests are rounded up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size 359 * @param min_addr 360 * Minimum address that block can occupy. 361 * @param max_addr 362 * Specifies the maximum address_min (inclusive) that the allocation can use. 363 * @param alignment Requested alignment of the block. If this alignment cannot be met, the allocation fails. 364 * This must be a power of 2. 365 * (Note: Alignment of CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and internally enforced. Requested alignments of 366 * less than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to CVMX_BOOTMEM_ALIGNMENT_SIZE.) 367 * @param name name to assign to named block 368 * @param flags Flags to control options for the allocation. 369 * 370 * @return physical address of block allocated, or -1 on failure 371 */ 372int64_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); 373 374 375/** 376 * Finds a named memory block by name. 377 * Also used for finding an unused entry in the named block table. 378 * 379 * @param name Name of memory block to find. 380 * If NULL pointer given, then finds unused descriptor, if available. 381 * @param flags Flags to control options for the allocation. 382 * 383 * @return Physical address of the memory block descriptor, zero if not 384 * found. If zero returned when name parameter is NULL, then no 385 * memory block descriptors are available. 386 */ 387uint64_t cvmx_bootmem_phy_named_block_find(const char *name, uint32_t flags); 388 389 390/** 391 * Returns the size of available memory in bytes, only 392 * counting blocks that are at least as big as the minimum block 393 * size. 394 * 395 * @param min_block_size 396 * Minimum block size to count in total. 397 * 398 * @return Number of bytes available for allocation that meet the block size requirement 399 */ 400uint64_t cvmx_bootmem_phy_available_mem(uint64_t min_block_size); 401 402/** 403 * Frees a named block. 404 * 405 * @param name name of block to free 406 * @param flags flags for passing options 407 * 408 * @return 0 on failure 409 * 1 on success 410 */ 411int cvmx_bootmem_phy_named_block_free(const char *name, uint32_t flags); 412 413/** 414 * Frees a block to the bootmem allocator list. This must 415 * be used with care, as the size provided must match the size 416 * of the block that was allocated, or the list will become 417 * corrupted. 418 * 419 * IMPORTANT: This is only intended to be used as part of named block 420 * frees and initial population of the free memory list. 421 * * 422 * 423 * @param phy_addr physical address of block 424 * @param size size of block in bytes. 425 * @param flags flags for passing options 426 * 427 * @return 1 on success, 428 * 0 on failure 429 */ 430int __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags); 431 432 433/** 434 * Prints the list of currently allocated named blocks 435 * 436 */ 437void cvmx_bootmem_phy_named_block_print(void); 438 439 440/** 441 * Prints the list of available memory. 442 * 443 */ 444void cvmx_bootmem_phy_list_print(void); 445 446 447 448/** 449 * This function initializes the free memory list used by cvmx_bootmem. 450 * This must be called before any allocations can be done. 451 * 452 * @param mem_size Total memory available, in bytes 453 * @param low_reserved_bytes 454 * Number of bytes to reserve (leave out of free list) at address 0x0. 455 * @param desc_buffer 456 * Buffer for the bootmem descriptor. This must be a 32 bit addressable 457 * address. 458 * 459 * @return 1 on success 460 * 0 on failure 461 */ 462int64_t cvmx_bootmem_phy_mem_list_init(uint64_t mem_size, uint32_t low_reserved_bytes, cvmx_bootmem_desc_t *desc_buffer); 463 464/** 465 * Locks the bootmem allocator. This is useful in certain situations 466 * where multiple allocations must be made without being interrupted. 467 * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag. 468 * 469 */ 470void cvmx_bootmem_lock(void); 471 472/** 473 * Unlocks the bootmem allocator. This is useful in certain situations 474 * where multiple allocations must be made without being interrupted. 475 * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag. 476 * 477 */ 478void cvmx_bootmem_unlock(void); 479 480/** 481 * Internal use function to get the current descriptor pointer */ 482void *__cvmx_bootmem_internal_get_desc_ptr(void); 483 484#ifdef __cplusplus 485} 486#endif 487 488#endif /* __CVMX_BOOTMEM_H__ */ 489