158f07778SDavid Daney /***********************license start*************** 258f07778SDavid Daney * Author: Cavium Networks 358f07778SDavid Daney * 458f07778SDavid Daney * Contact: support@caviumnetworks.com 558f07778SDavid Daney * This file is part of the OCTEON SDK 658f07778SDavid Daney * 758f07778SDavid Daney * Copyright (c) 2003-2008 Cavium Networks 858f07778SDavid Daney * 958f07778SDavid Daney * This file is free software; you can redistribute it and/or modify 1058f07778SDavid Daney * it under the terms of the GNU General Public License, Version 2, as 1158f07778SDavid Daney * published by the Free Software Foundation. 1258f07778SDavid Daney * 1358f07778SDavid Daney * This file is distributed in the hope that it will be useful, but 1458f07778SDavid Daney * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty 1558f07778SDavid Daney * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 1658f07778SDavid Daney * NONINFRINGEMENT. See the GNU General Public License for more 1758f07778SDavid Daney * details. 1858f07778SDavid Daney * 1958f07778SDavid Daney * You should have received a copy of the GNU General Public License 2058f07778SDavid Daney * along with this file; if not, write to the Free Software 2158f07778SDavid Daney * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 2258f07778SDavid Daney * or visit http://www.gnu.org/licenses/. 2358f07778SDavid Daney * 2458f07778SDavid Daney * This file may also be available under a different license from Cavium. 2558f07778SDavid Daney * Contact Cavium Networks for more information 2658f07778SDavid Daney ***********************license end**************************************/ 2758f07778SDavid Daney 2858f07778SDavid Daney /* 2958f07778SDavid Daney * Simple allocate only memory allocator. Used to allocate memory at 3058f07778SDavid Daney * application start time. 3158f07778SDavid Daney */ 3258f07778SDavid Daney 3358f07778SDavid Daney #ifndef __CVMX_BOOTMEM_H__ 3458f07778SDavid Daney #define __CVMX_BOOTMEM_H__ 3558f07778SDavid Daney /* Must be multiple of 8, changing breaks ABI */ 3658f07778SDavid Daney #define CVMX_BOOTMEM_NAME_LEN 128 3758f07778SDavid Daney 3858f07778SDavid Daney /* Can change without breaking ABI */ 3958f07778SDavid Daney #define CVMX_BOOTMEM_NUM_NAMED_BLOCKS 64 4058f07778SDavid Daney 4158f07778SDavid Daney /* minimum alignment of bootmem alloced blocks */ 4258f07778SDavid Daney #define CVMX_BOOTMEM_ALIGNMENT_SIZE (16ull) 4358f07778SDavid Daney 4458f07778SDavid Daney /* Flags for cvmx_bootmem_phy_mem* functions */ 4558f07778SDavid Daney /* Allocate from end of block instead of beginning */ 4658f07778SDavid Daney #define CVMX_BOOTMEM_FLAG_END_ALLOC (1 << 0) 4758f07778SDavid Daney 4858f07778SDavid Daney /* Don't do any locking. */ 4958f07778SDavid Daney #define CVMX_BOOTMEM_FLAG_NO_LOCKING (1 << 1) 5058f07778SDavid Daney 5158f07778SDavid Daney /* First bytes of each free physical block of memory contain this structure, 5258f07778SDavid Daney * which is used to maintain the free memory list. Since the bootloader is 5358f07778SDavid Daney * only 32 bits, there is a union providing 64 and 32 bit versions. The 5458f07778SDavid Daney * application init code converts addresses to 64 bit addresses before the 5558f07778SDavid Daney * application starts. 5658f07778SDavid Daney */ 5758f07778SDavid Daney struct cvmx_bootmem_block_header { 5858f07778SDavid Daney /* 5958f07778SDavid Daney * Note: these are referenced from assembly routines in the 6058f07778SDavid Daney * bootloader, so this structure should not be changed 6158f07778SDavid Daney * without changing those routines as well. 6258f07778SDavid Daney */ 6358f07778SDavid Daney uint64_t next_block_addr; 6458f07778SDavid Daney uint64_t size; 6558f07778SDavid Daney 6658f07778SDavid Daney }; 6758f07778SDavid Daney 6858f07778SDavid Daney /* 6958f07778SDavid Daney * Structure for named memory blocks. Number of descriptors available 7025985edcSLucas De Marchi * can be changed without affecting compatibility, but name length 7158f07778SDavid Daney * changes require a bump in the bootmem descriptor version Note: This 7258f07778SDavid Daney * structure must be naturally 64 bit aligned, as a single memory 7358f07778SDavid Daney * image will be used by both 32 and 64 bit programs. 7458f07778SDavid Daney */ 7558f07778SDavid Daney struct cvmx_bootmem_named_block_desc { 7658f07778SDavid Daney /* Base address of named block */ 7758f07778SDavid Daney uint64_t base_addr; 7858f07778SDavid Daney /* 7958f07778SDavid Daney * Size actually allocated for named block (may differ from 8058f07778SDavid Daney * requested). 8158f07778SDavid Daney */ 8258f07778SDavid Daney uint64_t size; 8358f07778SDavid Daney /* name of named block */ 8458f07778SDavid Daney char name[CVMX_BOOTMEM_NAME_LEN]; 8558f07778SDavid Daney }; 8658f07778SDavid Daney 8758f07778SDavid Daney /* Current descriptor versions */ 8858f07778SDavid Daney /* CVMX bootmem descriptor major version */ 8958f07778SDavid Daney #define CVMX_BOOTMEM_DESC_MAJ_VER 3 9058f07778SDavid Daney 9158f07778SDavid Daney /* CVMX bootmem descriptor minor version */ 9258f07778SDavid Daney #define CVMX_BOOTMEM_DESC_MIN_VER 0 9358f07778SDavid Daney 9458f07778SDavid Daney /* First three members of cvmx_bootmem_desc_t are left in original 9558f07778SDavid Daney * positions for backwards compatibility. 9658f07778SDavid Daney */ 9758f07778SDavid Daney struct cvmx_bootmem_desc { 98*11db04c8SPaul Martin #if defined(__BIG_ENDIAN_BITFIELD) || defined(CVMX_BUILD_FOR_LINUX_HOST) 9958f07778SDavid Daney /* spinlock to control access to list */ 10058f07778SDavid Daney uint32_t lock; 10158f07778SDavid Daney /* flags for indicating various conditions */ 10258f07778SDavid Daney uint32_t flags; 10358f07778SDavid Daney uint64_t head_addr; 10458f07778SDavid Daney 10558f07778SDavid Daney /* Incremented when incompatible changes made */ 10658f07778SDavid Daney uint32_t major_version; 10758f07778SDavid Daney 10858f07778SDavid Daney /* 10958f07778SDavid Daney * Incremented changed when compatible changes made, reset to 11058f07778SDavid Daney * zero when major incremented. 11158f07778SDavid Daney */ 11258f07778SDavid Daney uint32_t minor_version; 11358f07778SDavid Daney 11458f07778SDavid Daney uint64_t app_data_addr; 11558f07778SDavid Daney uint64_t app_data_size; 11658f07778SDavid Daney 11758f07778SDavid Daney /* number of elements in named blocks array */ 11858f07778SDavid Daney uint32_t named_block_num_blocks; 11958f07778SDavid Daney 12058f07778SDavid Daney /* length of name array in bootmem blocks */ 12158f07778SDavid Daney uint32_t named_block_name_len; 12258f07778SDavid Daney /* address of named memory block descriptors */ 12358f07778SDavid Daney uint64_t named_block_array_addr; 124*11db04c8SPaul Martin #else /* __LITTLE_ENDIAN */ 125*11db04c8SPaul Martin uint32_t flags; 126*11db04c8SPaul Martin uint32_t lock; 127*11db04c8SPaul Martin uint64_t head_addr; 12858f07778SDavid Daney 129*11db04c8SPaul Martin uint32_t minor_version; 130*11db04c8SPaul Martin uint32_t major_version; 131*11db04c8SPaul Martin uint64_t app_data_addr; 132*11db04c8SPaul Martin uint64_t app_data_size; 133*11db04c8SPaul Martin 134*11db04c8SPaul Martin uint32_t named_block_name_len; 135*11db04c8SPaul Martin uint32_t named_block_num_blocks; 136*11db04c8SPaul Martin uint64_t named_block_array_addr; 137*11db04c8SPaul Martin #endif 13858f07778SDavid Daney }; 13958f07778SDavid Daney 14058f07778SDavid Daney /** 14158f07778SDavid Daney * Initialize the boot alloc memory structures. This is 14258f07778SDavid Daney * normally called inside of cvmx_user_app_init() 14358f07778SDavid Daney * 14458f07778SDavid Daney * @mem_desc_ptr: Address of the free memory list 14558f07778SDavid Daney */ 14658f07778SDavid Daney extern int cvmx_bootmem_init(void *mem_desc_ptr); 14758f07778SDavid Daney 14858f07778SDavid Daney /** 14958f07778SDavid Daney * Allocate a block of memory from the free list that was passed 15058f07778SDavid Daney * to the application by the bootloader. 15158f07778SDavid Daney * This is an allocate-only algorithm, so freeing memory is not possible. 15258f07778SDavid Daney * 15358f07778SDavid Daney * @size: Size in bytes of block to allocate 15458f07778SDavid Daney * @alignment: Alignment required - must be power of 2 15558f07778SDavid Daney * 15658f07778SDavid Daney * Returns pointer to block of memory, NULL on error 15758f07778SDavid Daney */ 15858f07778SDavid Daney extern void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment); 15958f07778SDavid Daney 16058f07778SDavid Daney /** 16158f07778SDavid Daney * Allocate a block of memory from the free list that was 16258f07778SDavid Daney * passed to the application by the bootloader at a specific 16358f07778SDavid Daney * address. This is an allocate-only algorithm, so 16458f07778SDavid Daney * freeing memory is not possible. Allocation will fail if 16558f07778SDavid Daney * memory cannot be allocated at the specified address. 16658f07778SDavid Daney * 16758f07778SDavid Daney * @size: Size in bytes of block to allocate 16858f07778SDavid Daney * @address: Physical address to allocate memory at. If this memory is not 16958f07778SDavid Daney * available, the allocation fails. 17058f07778SDavid Daney * @alignment: Alignment required - must be power of 2 17158f07778SDavid Daney * Returns pointer to block of memory, NULL on error 17258f07778SDavid Daney */ 17358f07778SDavid Daney extern void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address, 17458f07778SDavid Daney uint64_t alignment); 17558f07778SDavid Daney 17658f07778SDavid Daney /** 17758f07778SDavid Daney * Allocate a block of memory from the free list that was 17858f07778SDavid Daney * passed to the application by the bootloader within a specified 17958f07778SDavid Daney * address range. This is an allocate-only algorithm, so 18058f07778SDavid Daney * freeing memory is not possible. Allocation will fail if 18158f07778SDavid Daney * memory cannot be allocated in the requested range. 18258f07778SDavid Daney * 18358f07778SDavid Daney * @size: Size in bytes of block to allocate 18458f07778SDavid Daney * @min_addr: defines the minimum address of the range 18558f07778SDavid Daney * @max_addr: defines the maximum address of the range 18658f07778SDavid Daney * @alignment: Alignment required - must be power of 2 18758f07778SDavid Daney * Returns pointer to block of memory, NULL on error 18858f07778SDavid Daney */ 18958f07778SDavid Daney extern void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment, 19058f07778SDavid Daney uint64_t min_addr, uint64_t max_addr); 19158f07778SDavid Daney 19258f07778SDavid Daney /** 19358f07778SDavid Daney * Frees a previously allocated named bootmem block. 19458f07778SDavid Daney * 19558f07778SDavid Daney * @name: name of block to free 19658f07778SDavid Daney * 19758f07778SDavid Daney * Returns 0 on failure, 19858f07778SDavid Daney * !0 on success 19958f07778SDavid Daney */ 2006fa044abSDavid Daney 2016fa044abSDavid Daney 2026fa044abSDavid Daney /** 2036fa044abSDavid Daney * Allocate a block of memory from the free list that was passed 2046fa044abSDavid Daney * to the application by the bootloader, and assign it a name in the 2056fa044abSDavid Daney * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 2066fa044abSDavid Daney * Named blocks can later be freed. 2076fa044abSDavid Daney * 2086fa044abSDavid Daney * @size: Size in bytes of block to allocate 2096fa044abSDavid Daney * @alignment: Alignment required - must be power of 2 2106fa044abSDavid Daney * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 2116fa044abSDavid Daney * 2126fa044abSDavid Daney * Returns a pointer to block of memory, NULL on error 2136fa044abSDavid Daney */ 2146fa044abSDavid Daney extern void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, 2156fa044abSDavid Daney char *name); 2166fa044abSDavid Daney 2176fa044abSDavid Daney 2186fa044abSDavid Daney 2196fa044abSDavid Daney /** 2206fa044abSDavid Daney * Allocate a block of memory from the free list that was passed 2216fa044abSDavid Daney * to the application by the bootloader, and assign it a name in the 2226fa044abSDavid Daney * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 2236fa044abSDavid Daney * Named blocks can later be freed. 2246fa044abSDavid Daney * 2256fa044abSDavid Daney * @size: Size in bytes of block to allocate 2266fa044abSDavid Daney * @address: Physical address to allocate memory at. If this 2276fa044abSDavid Daney * memory is not available, the allocation fails. 2286fa044abSDavid Daney * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN 2296fa044abSDavid Daney * bytes 2306fa044abSDavid Daney * 2316fa044abSDavid Daney * Returns a pointer to block of memory, NULL on error 2326fa044abSDavid Daney */ 2336fa044abSDavid Daney extern void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address, 2346fa044abSDavid Daney char *name); 2356fa044abSDavid Daney 2366fa044abSDavid Daney 2376fa044abSDavid Daney 2386fa044abSDavid Daney /** 2396fa044abSDavid Daney * Allocate a block of memory from a specific range of the free list 2406fa044abSDavid Daney * that was passed to the application by the bootloader, and assign it 2416fa044abSDavid Daney * a name in the global named block table. (part of the 2426fa044abSDavid Daney * cvmx_bootmem_descriptor_t structure) Named blocks can later be 2436fa044abSDavid Daney * freed. If request cannot be satisfied within the address range 2446fa044abSDavid Daney * specified, NULL is returned 2456fa044abSDavid Daney * 2466fa044abSDavid Daney * @size: Size in bytes of block to allocate 2476fa044abSDavid Daney * @min_addr: minimum address of range 2486fa044abSDavid Daney * @max_addr: maximum address of range 2496fa044abSDavid Daney * @align: Alignment of memory to be allocated. (must be a power of 2) 2506fa044abSDavid Daney * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 2516fa044abSDavid Daney * 2526fa044abSDavid Daney * Returns a pointer to block of memory, NULL on error 2536fa044abSDavid Daney */ 2546fa044abSDavid Daney extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, 2556fa044abSDavid Daney uint64_t max_addr, uint64_t align, 2566fa044abSDavid Daney char *name); 2576fa044abSDavid Daney 25858f07778SDavid Daney extern int cvmx_bootmem_free_named(char *name); 25958f07778SDavid Daney 26058f07778SDavid Daney /** 26158f07778SDavid Daney * Finds a named bootmem block by name. 26258f07778SDavid Daney * 26358f07778SDavid Daney * @name: name of block to free 26458f07778SDavid Daney * 26558f07778SDavid Daney * Returns pointer to named block descriptor on success 26658f07778SDavid Daney * 0 on failure 26758f07778SDavid Daney */ 26858f07778SDavid Daney struct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name); 26958f07778SDavid Daney 27058f07778SDavid Daney /** 27158f07778SDavid Daney * Allocates a block of physical memory from the free list, at 27258f07778SDavid Daney * (optional) requested address and alignment. 27358f07778SDavid Daney * 27458f07778SDavid Daney * @req_size: size of region to allocate. All requests are rounded up 27558f07778SDavid Daney * to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size 27658f07778SDavid Daney * 27758f07778SDavid Daney * @address_min: Minimum address that block can occupy. 27858f07778SDavid Daney * 27958f07778SDavid Daney * @address_max: Specifies the maximum address_min (inclusive) that 28058f07778SDavid Daney * the allocation can use. 28158f07778SDavid Daney * 28258f07778SDavid Daney * @alignment: Requested alignment of the block. If this alignment 28358f07778SDavid Daney * cannot be met, the allocation fails. This must be a 28458f07778SDavid Daney * power of 2. (Note: Alignment of 28558f07778SDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and 28658f07778SDavid Daney * internally enforced. Requested alignments of less than 28758f07778SDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE are set to 28858f07778SDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE.) 28958f07778SDavid Daney * 29058f07778SDavid Daney * @flags: Flags to control options for the allocation. 29158f07778SDavid Daney * 29258f07778SDavid Daney * Returns physical address of block allocated, or -1 on failure 29358f07778SDavid Daney */ 29458f07778SDavid Daney int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min, 29558f07778SDavid Daney uint64_t address_max, uint64_t alignment, 29658f07778SDavid Daney uint32_t flags); 29758f07778SDavid Daney 29858f07778SDavid Daney /** 2996fa044abSDavid Daney * Allocates a named block of physical memory from the free list, at 3006fa044abSDavid Daney * (optional) requested address and alignment. 3016fa044abSDavid Daney * 3026fa044abSDavid Daney * @param size size of region to allocate. All requests are rounded 3036fa044abSDavid Daney * up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE 3046fa044abSDavid Daney * bytes size 3056fa044abSDavid Daney * @param min_addr Minimum address that block can occupy. 3066fa044abSDavid Daney * @param max_addr Specifies the maximum address_min (inclusive) that 3076fa044abSDavid Daney * the allocation can use. 3086fa044abSDavid Daney * @param alignment Requested alignment of the block. If this 3096fa044abSDavid Daney * alignment cannot be met, the allocation fails. 3106fa044abSDavid Daney * This must be a power of 2. (Note: Alignment of 3116fa044abSDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and 3126fa044abSDavid Daney * internally enforced. Requested alignments of less 3136fa044abSDavid Daney * than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to 3146fa044abSDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE.) 3156fa044abSDavid Daney * @param name name to assign to named block 3166fa044abSDavid Daney * @param flags Flags to control options for the allocation. 3176fa044abSDavid Daney * 3186fa044abSDavid Daney * @return physical address of block allocated, or -1 on failure 3196fa044abSDavid Daney */ 3206fa044abSDavid Daney int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr, 3216fa044abSDavid Daney uint64_t max_addr, 3226fa044abSDavid Daney uint64_t alignment, 3236fa044abSDavid Daney char *name, uint32_t flags); 3246fa044abSDavid Daney 3256fa044abSDavid Daney /** 32658f07778SDavid Daney * Finds a named memory block by name. 32758f07778SDavid Daney * Also used for finding an unused entry in the named block table. 32858f07778SDavid Daney * 32958f07778SDavid Daney * @name: Name of memory block to find. If NULL pointer given, then 33058f07778SDavid Daney * finds unused descriptor, if available. 33158f07778SDavid Daney * 33258f07778SDavid Daney * @flags: Flags to control options for the allocation. 33358f07778SDavid Daney * 33458f07778SDavid Daney * Returns Pointer to memory block descriptor, NULL if not found. 33558f07778SDavid Daney * If NULL returned when name parameter is NULL, then no memory 33658f07778SDavid Daney * block descriptors are available. 33758f07778SDavid Daney */ 33858f07778SDavid Daney struct cvmx_bootmem_named_block_desc * 33958f07778SDavid Daney cvmx_bootmem_phy_named_block_find(char *name, uint32_t flags); 34058f07778SDavid Daney 34158f07778SDavid Daney /** 34258f07778SDavid Daney * Frees a named block. 34358f07778SDavid Daney * 34458f07778SDavid Daney * @name: name of block to free 34558f07778SDavid Daney * @flags: flags for passing options 34658f07778SDavid Daney * 34758f07778SDavid Daney * Returns 0 on failure 34858f07778SDavid Daney * 1 on success 34958f07778SDavid Daney */ 35058f07778SDavid Daney int cvmx_bootmem_phy_named_block_free(char *name, uint32_t flags); 35158f07778SDavid Daney 35258f07778SDavid Daney /** 35358f07778SDavid Daney * Frees a block to the bootmem allocator list. This must 35458f07778SDavid Daney * be used with care, as the size provided must match the size 35558f07778SDavid Daney * of the block that was allocated, or the list will become 35658f07778SDavid Daney * corrupted. 35758f07778SDavid Daney * 35858f07778SDavid Daney * IMPORTANT: This is only intended to be used as part of named block 35958f07778SDavid Daney * frees and initial population of the free memory list. 36058f07778SDavid Daney * * 36158f07778SDavid Daney * 36258f07778SDavid Daney * @phy_addr: physical address of block 36358f07778SDavid Daney * @size: size of block in bytes. 36458f07778SDavid Daney * @flags: flags for passing options 36558f07778SDavid Daney * 36658f07778SDavid Daney * Returns 1 on success, 36758f07778SDavid Daney * 0 on failure 36858f07778SDavid Daney */ 36958f07778SDavid Daney int __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags); 37058f07778SDavid Daney 37158f07778SDavid Daney /** 37258f07778SDavid Daney * Locks the bootmem allocator. This is useful in certain situations 37358f07778SDavid Daney * where multiple allocations must be made without being interrupted. 37458f07778SDavid Daney * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag. 37558f07778SDavid Daney * 37658f07778SDavid Daney */ 37758f07778SDavid Daney void cvmx_bootmem_lock(void); 37858f07778SDavid Daney 37958f07778SDavid Daney /** 38058f07778SDavid Daney * Unlocks the bootmem allocator. This is useful in certain situations 38158f07778SDavid Daney * where multiple allocations must be made without being interrupted. 38258f07778SDavid Daney * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag. 38358f07778SDavid Daney * 38458f07778SDavid Daney */ 38558f07778SDavid Daney void cvmx_bootmem_unlock(void); 38658f07778SDavid Daney 387abe77f90SRalf Baechle extern struct cvmx_bootmem_desc *cvmx_bootmem_get_desc(void); 388abe77f90SRalf Baechle 38958f07778SDavid Daney #endif /* __CVMX_BOOTMEM_H__ */ 390