162306a36Sopenharmony_ci/***********************license start*************** 262306a36Sopenharmony_ci * Author: Cavium Networks 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Contact: support@caviumnetworks.com 562306a36Sopenharmony_ci * This file is part of the OCTEON SDK 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (c) 2003-2008 Cavium Networks 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * This file is free software; you can redistribute it and/or modify 1062306a36Sopenharmony_ci * it under the terms of the GNU General Public License, Version 2, as 1162306a36Sopenharmony_ci * published by the Free Software Foundation. 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci * This file is distributed in the hope that it will be useful, but 1462306a36Sopenharmony_ci * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty 1562306a36Sopenharmony_ci * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 1662306a36Sopenharmony_ci * NONINFRINGEMENT. See the GNU General Public License for more 1762306a36Sopenharmony_ci * details. 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * You should have received a copy of the GNU General Public License 2062306a36Sopenharmony_ci * along with this file; if not, write to the Free Software 2162306a36Sopenharmony_ci * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 2262306a36Sopenharmony_ci * or visit http://www.gnu.org/licenses/. 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * This file may also be available under a different license from Cavium. 2562306a36Sopenharmony_ci * Contact Cavium Networks for more information 2662306a36Sopenharmony_ci ***********************license end**************************************/ 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci/* 2962306a36Sopenharmony_ci * Simple allocate only memory allocator. Used to allocate memory at 3062306a36Sopenharmony_ci * application start time. 3162306a36Sopenharmony_ci */ 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#ifndef __CVMX_BOOTMEM_H__ 3462306a36Sopenharmony_ci#define __CVMX_BOOTMEM_H__ 3562306a36Sopenharmony_ci/* Must be multiple of 8, changing breaks ABI */ 3662306a36Sopenharmony_ci#define CVMX_BOOTMEM_NAME_LEN 128 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci/* Can change without breaking ABI */ 3962306a36Sopenharmony_ci#define CVMX_BOOTMEM_NUM_NAMED_BLOCKS 64 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci/* minimum alignment of bootmem alloced blocks */ 4262306a36Sopenharmony_ci#define CVMX_BOOTMEM_ALIGNMENT_SIZE (16ull) 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* Flags for cvmx_bootmem_phy_mem* functions */ 4562306a36Sopenharmony_ci/* Allocate from end of block instead of beginning */ 4662306a36Sopenharmony_ci#define CVMX_BOOTMEM_FLAG_END_ALLOC (1 << 0) 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci/* Don't do any locking. */ 4962306a36Sopenharmony_ci#define CVMX_BOOTMEM_FLAG_NO_LOCKING (1 << 1) 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci/* First bytes of each free physical block of memory contain this structure, 5262306a36Sopenharmony_ci * which is used to maintain the free memory list. Since the bootloader is 5362306a36Sopenharmony_ci * only 32 bits, there is a union providing 64 and 32 bit versions. The 5462306a36Sopenharmony_ci * application init code converts addresses to 64 bit addresses before the 5562306a36Sopenharmony_ci * application starts. 5662306a36Sopenharmony_ci */ 5762306a36Sopenharmony_cistruct cvmx_bootmem_block_header { 5862306a36Sopenharmony_ci /* 5962306a36Sopenharmony_ci * Note: these are referenced from assembly routines in the 6062306a36Sopenharmony_ci * bootloader, so this structure should not be changed 6162306a36Sopenharmony_ci * without changing those routines as well. 6262306a36Sopenharmony_ci */ 6362306a36Sopenharmony_ci uint64_t next_block_addr; 6462306a36Sopenharmony_ci uint64_t size; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci}; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci/* 6962306a36Sopenharmony_ci * Structure for named memory blocks. Number of descriptors available 7062306a36Sopenharmony_ci * can be changed without affecting compatibility, but name length 7162306a36Sopenharmony_ci * changes require a bump in the bootmem descriptor version Note: This 7262306a36Sopenharmony_ci * structure must be naturally 64 bit aligned, as a single memory 7362306a36Sopenharmony_ci * image will be used by both 32 and 64 bit programs. 7462306a36Sopenharmony_ci */ 7562306a36Sopenharmony_cistruct cvmx_bootmem_named_block_desc { 7662306a36Sopenharmony_ci /* Base address of named block */ 7762306a36Sopenharmony_ci uint64_t base_addr; 7862306a36Sopenharmony_ci /* 7962306a36Sopenharmony_ci * Size actually allocated for named block (may differ from 8062306a36Sopenharmony_ci * requested). 8162306a36Sopenharmony_ci */ 8262306a36Sopenharmony_ci uint64_t size; 8362306a36Sopenharmony_ci /* name of named block */ 8462306a36Sopenharmony_ci char name[CVMX_BOOTMEM_NAME_LEN]; 8562306a36Sopenharmony_ci}; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/* Current descriptor versions */ 8862306a36Sopenharmony_ci/* CVMX bootmem descriptor major version */ 8962306a36Sopenharmony_ci#define CVMX_BOOTMEM_DESC_MAJ_VER 3 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci/* CVMX bootmem descriptor minor version */ 9262306a36Sopenharmony_ci#define CVMX_BOOTMEM_DESC_MIN_VER 0 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci/* First three members of cvmx_bootmem_desc_t are left in original 9562306a36Sopenharmony_ci * positions for backwards compatibility. 9662306a36Sopenharmony_ci */ 9762306a36Sopenharmony_cistruct cvmx_bootmem_desc { 9862306a36Sopenharmony_ci#if defined(__BIG_ENDIAN_BITFIELD) || defined(CVMX_BUILD_FOR_LINUX_HOST) 9962306a36Sopenharmony_ci /* spinlock to control access to list */ 10062306a36Sopenharmony_ci uint32_t lock; 10162306a36Sopenharmony_ci /* flags for indicating various conditions */ 10262306a36Sopenharmony_ci uint32_t flags; 10362306a36Sopenharmony_ci uint64_t head_addr; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci /* Incremented when incompatible changes made */ 10662306a36Sopenharmony_ci uint32_t major_version; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci /* 10962306a36Sopenharmony_ci * Incremented changed when compatible changes made, reset to 11062306a36Sopenharmony_ci * zero when major incremented. 11162306a36Sopenharmony_ci */ 11262306a36Sopenharmony_ci uint32_t minor_version; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci uint64_t app_data_addr; 11562306a36Sopenharmony_ci uint64_t app_data_size; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci /* number of elements in named blocks array */ 11862306a36Sopenharmony_ci uint32_t named_block_num_blocks; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci /* length of name array in bootmem blocks */ 12162306a36Sopenharmony_ci uint32_t named_block_name_len; 12262306a36Sopenharmony_ci /* address of named memory block descriptors */ 12362306a36Sopenharmony_ci uint64_t named_block_array_addr; 12462306a36Sopenharmony_ci#else /* __LITTLE_ENDIAN */ 12562306a36Sopenharmony_ci uint32_t flags; 12662306a36Sopenharmony_ci uint32_t lock; 12762306a36Sopenharmony_ci uint64_t head_addr; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci uint32_t minor_version; 13062306a36Sopenharmony_ci uint32_t major_version; 13162306a36Sopenharmony_ci uint64_t app_data_addr; 13262306a36Sopenharmony_ci uint64_t app_data_size; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci uint32_t named_block_name_len; 13562306a36Sopenharmony_ci uint32_t named_block_num_blocks; 13662306a36Sopenharmony_ci uint64_t named_block_array_addr; 13762306a36Sopenharmony_ci#endif 13862306a36Sopenharmony_ci}; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci/** 14162306a36Sopenharmony_ci * Initialize the boot alloc memory structures. This is 14262306a36Sopenharmony_ci * normally called inside of cvmx_user_app_init() 14362306a36Sopenharmony_ci * 14462306a36Sopenharmony_ci * @mem_desc_ptr: Address of the free memory list 14562306a36Sopenharmony_ci */ 14662306a36Sopenharmony_ciextern int cvmx_bootmem_init(void *mem_desc_ptr); 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci/** 14962306a36Sopenharmony_ci * Allocate a block of memory from the free list that was 15062306a36Sopenharmony_ci * passed to the application by the bootloader at a specific 15162306a36Sopenharmony_ci * address. This is an allocate-only algorithm, so 15262306a36Sopenharmony_ci * freeing memory is not possible. Allocation will fail if 15362306a36Sopenharmony_ci * memory cannot be allocated at the specified address. 15462306a36Sopenharmony_ci * 15562306a36Sopenharmony_ci * @size: Size in bytes of block to allocate 15662306a36Sopenharmony_ci * @address: Physical address to allocate memory at. If this memory is not 15762306a36Sopenharmony_ci * available, the allocation fails. 15862306a36Sopenharmony_ci * @alignment: Alignment required - must be power of 2 15962306a36Sopenharmony_ci * Returns pointer to block of memory, NULL on error 16062306a36Sopenharmony_ci */ 16162306a36Sopenharmony_ciextern void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address, 16262306a36Sopenharmony_ci uint64_t alignment); 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci/** 16562306a36Sopenharmony_ci * Frees a previously allocated named bootmem block. 16662306a36Sopenharmony_ci * 16762306a36Sopenharmony_ci * @name: name of block to free 16862306a36Sopenharmony_ci * 16962306a36Sopenharmony_ci * Returns 0 on failure, 17062306a36Sopenharmony_ci * !0 on success 17162306a36Sopenharmony_ci */ 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci/** 17562306a36Sopenharmony_ci * Allocate a block of memory from the free list that was passed 17662306a36Sopenharmony_ci * to the application by the bootloader, and assign it a name in the 17762306a36Sopenharmony_ci * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 17862306a36Sopenharmony_ci * Named blocks can later be freed. 17962306a36Sopenharmony_ci * 18062306a36Sopenharmony_ci * @size: Size in bytes of block to allocate 18162306a36Sopenharmony_ci * @alignment: Alignment required - must be power of 2 18262306a36Sopenharmony_ci * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 18362306a36Sopenharmony_ci * 18462306a36Sopenharmony_ci * Returns a pointer to block of memory, NULL on error 18562306a36Sopenharmony_ci */ 18662306a36Sopenharmony_ciextern void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, 18762306a36Sopenharmony_ci char *name); 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci/** 19062306a36Sopenharmony_ci * Allocate a block of memory from a specific range of the free list 19162306a36Sopenharmony_ci * that was passed to the application by the bootloader, and assign it 19262306a36Sopenharmony_ci * a name in the global named block table. (part of the 19362306a36Sopenharmony_ci * cvmx_bootmem_descriptor_t structure) Named blocks can later be 19462306a36Sopenharmony_ci * freed. If request cannot be satisfied within the address range 19562306a36Sopenharmony_ci * specified, NULL is returned 19662306a36Sopenharmony_ci * 19762306a36Sopenharmony_ci * @size: Size in bytes of block to allocate 19862306a36Sopenharmony_ci * @min_addr: minimum address of range 19962306a36Sopenharmony_ci * @max_addr: maximum address of range 20062306a36Sopenharmony_ci * @align: Alignment of memory to be allocated. (must be a power of 2) 20162306a36Sopenharmony_ci * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 20262306a36Sopenharmony_ci * 20362306a36Sopenharmony_ci * Returns a pointer to block of memory, NULL on error 20462306a36Sopenharmony_ci */ 20562306a36Sopenharmony_ciextern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, 20662306a36Sopenharmony_ci uint64_t max_addr, uint64_t align, 20762306a36Sopenharmony_ci char *name); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci/** 21062306a36Sopenharmony_ci * Allocate if needed a block of memory from a specific range of the 21162306a36Sopenharmony_ci * free list that was passed to the application by the bootloader, and 21262306a36Sopenharmony_ci * assign it a name in the global named block table. (part of the 21362306a36Sopenharmony_ci * cvmx_bootmem_descriptor_t structure) Named blocks can later be 21462306a36Sopenharmony_ci * freed. If the requested name block is already allocated, return 21562306a36Sopenharmony_ci * the pointer to block of memory. If request cannot be satisfied 21662306a36Sopenharmony_ci * within the address range specified, NULL is returned 21762306a36Sopenharmony_ci * 21862306a36Sopenharmony_ci * @param size Size in bytes of block to allocate 21962306a36Sopenharmony_ci * @param min_addr minimum address of range 22062306a36Sopenharmony_ci * @param max_addr maximum address of range 22162306a36Sopenharmony_ci * @param align Alignment of memory to be allocated. (must be a power of 2) 22262306a36Sopenharmony_ci * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 22362306a36Sopenharmony_ci * @param init Initialization function 22462306a36Sopenharmony_ci * 22562306a36Sopenharmony_ci * The initialization function is optional, if omitted the named block 22662306a36Sopenharmony_ci * is initialized to all zeros when it is created, i.e. once. 22762306a36Sopenharmony_ci * 22862306a36Sopenharmony_ci * @return pointer to block of memory, NULL on error 22962306a36Sopenharmony_ci */ 23062306a36Sopenharmony_civoid *cvmx_bootmem_alloc_named_range_once(uint64_t size, 23162306a36Sopenharmony_ci uint64_t min_addr, 23262306a36Sopenharmony_ci uint64_t max_addr, 23362306a36Sopenharmony_ci uint64_t align, 23462306a36Sopenharmony_ci char *name, 23562306a36Sopenharmony_ci void (*init) (void *)); 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ciextern int cvmx_bootmem_free_named(char *name); 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci/** 24062306a36Sopenharmony_ci * Finds a named bootmem block by name. 24162306a36Sopenharmony_ci * 24262306a36Sopenharmony_ci * @name: name of block to free 24362306a36Sopenharmony_ci * 24462306a36Sopenharmony_ci * Returns pointer to named block descriptor on success 24562306a36Sopenharmony_ci * 0 on failure 24662306a36Sopenharmony_ci */ 24762306a36Sopenharmony_cistruct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name); 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci/** 25062306a36Sopenharmony_ci * Allocates a block of physical memory from the free list, at 25162306a36Sopenharmony_ci * (optional) requested address and alignment. 25262306a36Sopenharmony_ci * 25362306a36Sopenharmony_ci * @req_size: size of region to allocate. All requests are rounded up 25462306a36Sopenharmony_ci * to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size 25562306a36Sopenharmony_ci * 25662306a36Sopenharmony_ci * @address_min: Minimum address that block can occupy. 25762306a36Sopenharmony_ci * 25862306a36Sopenharmony_ci * @address_max: Specifies the maximum address_min (inclusive) that 25962306a36Sopenharmony_ci * the allocation can use. 26062306a36Sopenharmony_ci * 26162306a36Sopenharmony_ci * @alignment: Requested alignment of the block. If this alignment 26262306a36Sopenharmony_ci * cannot be met, the allocation fails. This must be a 26362306a36Sopenharmony_ci * power of 2. (Note: Alignment of 26462306a36Sopenharmony_ci * CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and 26562306a36Sopenharmony_ci * internally enforced. Requested alignments of less than 26662306a36Sopenharmony_ci * CVMX_BOOTMEM_ALIGNMENT_SIZE are set to 26762306a36Sopenharmony_ci * CVMX_BOOTMEM_ALIGNMENT_SIZE.) 26862306a36Sopenharmony_ci * 26962306a36Sopenharmony_ci * @flags: Flags to control options for the allocation. 27062306a36Sopenharmony_ci * 27162306a36Sopenharmony_ci * Returns physical address of block allocated, or -1 on failure 27262306a36Sopenharmony_ci */ 27362306a36Sopenharmony_ciint64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min, 27462306a36Sopenharmony_ci uint64_t address_max, uint64_t alignment, 27562306a36Sopenharmony_ci uint32_t flags); 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci/** 27862306a36Sopenharmony_ci * Allocates a named block of physical memory from the free list, at 27962306a36Sopenharmony_ci * (optional) requested address and alignment. 28062306a36Sopenharmony_ci * 28162306a36Sopenharmony_ci * @param size size of region to allocate. All requests are rounded 28262306a36Sopenharmony_ci * up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE 28362306a36Sopenharmony_ci * bytes size 28462306a36Sopenharmony_ci * @param min_addr Minimum address that block can occupy. 28562306a36Sopenharmony_ci * @param max_addr Specifies the maximum address_min (inclusive) that 28662306a36Sopenharmony_ci * the allocation can use. 28762306a36Sopenharmony_ci * @param alignment Requested alignment of the block. If this 28862306a36Sopenharmony_ci * alignment cannot be met, the allocation fails. 28962306a36Sopenharmony_ci * This must be a power of 2. (Note: Alignment of 29062306a36Sopenharmony_ci * CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and 29162306a36Sopenharmony_ci * internally enforced. Requested alignments of less 29262306a36Sopenharmony_ci * than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to 29362306a36Sopenharmony_ci * CVMX_BOOTMEM_ALIGNMENT_SIZE.) 29462306a36Sopenharmony_ci * @param name name to assign to named block 29562306a36Sopenharmony_ci * @param flags Flags to control options for the allocation. 29662306a36Sopenharmony_ci * 29762306a36Sopenharmony_ci * @return physical address of block allocated, or -1 on failure 29862306a36Sopenharmony_ci */ 29962306a36Sopenharmony_ciint64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr, 30062306a36Sopenharmony_ci uint64_t max_addr, 30162306a36Sopenharmony_ci uint64_t alignment, 30262306a36Sopenharmony_ci char *name, uint32_t flags); 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci/** 30562306a36Sopenharmony_ci * Frees a block to the bootmem allocator list. This must 30662306a36Sopenharmony_ci * be used with care, as the size provided must match the size 30762306a36Sopenharmony_ci * of the block that was allocated, or the list will become 30862306a36Sopenharmony_ci * corrupted. 30962306a36Sopenharmony_ci * 31062306a36Sopenharmony_ci * IMPORTANT: This is only intended to be used as part of named block 31162306a36Sopenharmony_ci * frees and initial population of the free memory list. 31262306a36Sopenharmony_ci * * 31362306a36Sopenharmony_ci * 31462306a36Sopenharmony_ci * @phy_addr: physical address of block 31562306a36Sopenharmony_ci * @size: size of block in bytes. 31662306a36Sopenharmony_ci * @flags: flags for passing options 31762306a36Sopenharmony_ci * 31862306a36Sopenharmony_ci * Returns 1 on success, 31962306a36Sopenharmony_ci * 0 on failure 32062306a36Sopenharmony_ci */ 32162306a36Sopenharmony_ciint __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags); 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci/** 32462306a36Sopenharmony_ci * Locks the bootmem allocator. This is useful in certain situations 32562306a36Sopenharmony_ci * where multiple allocations must be made without being interrupted. 32662306a36Sopenharmony_ci * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag. 32762306a36Sopenharmony_ci * 32862306a36Sopenharmony_ci */ 32962306a36Sopenharmony_civoid cvmx_bootmem_lock(void); 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci/** 33262306a36Sopenharmony_ci * Unlocks the bootmem allocator. This is useful in certain situations 33362306a36Sopenharmony_ci * where multiple allocations must be made without being interrupted. 33462306a36Sopenharmony_ci * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag. 33562306a36Sopenharmony_ci * 33662306a36Sopenharmony_ci */ 33762306a36Sopenharmony_civoid cvmx_bootmem_unlock(void); 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ciextern struct cvmx_bootmem_desc *cvmx_bootmem_get_desc(void); 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci#endif /* __CVMX_BOOTMEM_H__ */ 342