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 { 9811db04c8SPaul 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; 12411db04c8SPaul Martin #else /* __LITTLE_ENDIAN */ 12511db04c8SPaul Martin uint32_t flags; 12611db04c8SPaul Martin uint32_t lock; 12711db04c8SPaul Martin uint64_t head_addr; 12858f07778SDavid Daney 12911db04c8SPaul Martin uint32_t minor_version; 13011db04c8SPaul Martin uint32_t major_version; 13111db04c8SPaul Martin uint64_t app_data_addr; 13211db04c8SPaul Martin uint64_t app_data_size; 13311db04c8SPaul Martin 13411db04c8SPaul Martin uint32_t named_block_name_len; 13511db04c8SPaul Martin uint32_t named_block_num_blocks; 13611db04c8SPaul Martin uint64_t named_block_array_addr; 13711db04c8SPaul 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 15058f07778SDavid Daney * passed to the application by the bootloader at a specific 15158f07778SDavid Daney * address. This is an allocate-only algorithm, so 15258f07778SDavid Daney * freeing memory is not possible. Allocation will fail if 15358f07778SDavid Daney * memory cannot be allocated at the specified address. 15458f07778SDavid Daney * 15558f07778SDavid Daney * @size: Size in bytes of block to allocate 15658f07778SDavid Daney * @address: Physical address to allocate memory at. If this memory is not 15758f07778SDavid Daney * available, the allocation fails. 15858f07778SDavid Daney * @alignment: Alignment required - must be power of 2 15958f07778SDavid Daney * Returns pointer to block of memory, NULL on error 16058f07778SDavid Daney */ 16158f07778SDavid Daney extern void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address, 16258f07778SDavid Daney uint64_t alignment); 16358f07778SDavid Daney 16458f07778SDavid Daney /** 16558f07778SDavid Daney * Frees a previously allocated named bootmem block. 16658f07778SDavid Daney * 16758f07778SDavid Daney * @name: name of block to free 16858f07778SDavid Daney * 16958f07778SDavid Daney * Returns 0 on failure, 17058f07778SDavid Daney * !0 on success 17158f07778SDavid Daney */ 1726fa044abSDavid Daney 1736fa044abSDavid Daney 1746fa044abSDavid Daney /** 1756fa044abSDavid Daney * Allocate a block of memory from the free list that was passed 1766fa044abSDavid Daney * to the application by the bootloader, and assign it a name in the 1776fa044abSDavid Daney * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 1786fa044abSDavid Daney * Named blocks can later be freed. 1796fa044abSDavid Daney * 1806fa044abSDavid Daney * @size: Size in bytes of block to allocate 1816fa044abSDavid Daney * @alignment: Alignment required - must be power of 2 1826fa044abSDavid Daney * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 1836fa044abSDavid Daney * 1846fa044abSDavid Daney * Returns a pointer to block of memory, NULL on error 1856fa044abSDavid Daney */ 1866fa044abSDavid Daney extern void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, 1876fa044abSDavid Daney char *name); 1886fa044abSDavid Daney 1896fa044abSDavid Daney /** 1906fa044abSDavid Daney * Allocate a block of memory from a specific range of the free list 1916fa044abSDavid Daney * that was passed to the application by the bootloader, and assign it 1926fa044abSDavid Daney * a name in the global named block table. (part of the 1936fa044abSDavid Daney * cvmx_bootmem_descriptor_t structure) Named blocks can later be 1946fa044abSDavid Daney * freed. If request cannot be satisfied within the address range 1956fa044abSDavid Daney * specified, NULL is returned 1966fa044abSDavid Daney * 1976fa044abSDavid Daney * @size: Size in bytes of block to allocate 1986fa044abSDavid Daney * @min_addr: minimum address of range 1996fa044abSDavid Daney * @max_addr: maximum address of range 2006fa044abSDavid Daney * @align: Alignment of memory to be allocated. (must be a power of 2) 2016fa044abSDavid Daney * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 2026fa044abSDavid Daney * 2036fa044abSDavid Daney * Returns a pointer to block of memory, NULL on error 2046fa044abSDavid Daney */ 2056fa044abSDavid Daney extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, 2066fa044abSDavid Daney uint64_t max_addr, uint64_t align, 2076fa044abSDavid Daney char *name); 2086fa044abSDavid Daney 2099438a86aSSteven J. Hill /** 2109438a86aSSteven J. Hill * Allocate if needed a block of memory from a specific range of the 2119438a86aSSteven J. Hill * free list that was passed to the application by the bootloader, and 2129438a86aSSteven J. Hill * assign it a name in the global named block table. (part of the 2139438a86aSSteven J. Hill * cvmx_bootmem_descriptor_t structure) Named blocks can later be 2149438a86aSSteven J. Hill * freed. If the requested name block is already allocated, return 2159438a86aSSteven J. Hill * the pointer to block of memory. If request cannot be satisfied 2169438a86aSSteven J. Hill * within the address range specified, NULL is returned 2179438a86aSSteven J. Hill * 2189438a86aSSteven J. Hill * @param size Size in bytes of block to allocate 2199438a86aSSteven J. Hill * @param min_addr minimum address of range 2209438a86aSSteven J. Hill * @param max_addr maximum address of range 2219438a86aSSteven J. Hill * @param align Alignment of memory to be allocated. (must be a power of 2) 2229438a86aSSteven J. Hill * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 2239438a86aSSteven J. Hill * @param init Initialization function 2249438a86aSSteven J. Hill * 2259438a86aSSteven J. Hill * The initialization function is optional, if omitted the named block 2269438a86aSSteven J. Hill * is initialized to all zeros when it is created, i.e. once. 2279438a86aSSteven J. Hill * 2289438a86aSSteven J. Hill * @return pointer to block of memory, NULL on error 2299438a86aSSteven J. Hill */ 2309438a86aSSteven J. Hill void *cvmx_bootmem_alloc_named_range_once(uint64_t size, 2319438a86aSSteven J. Hill uint64_t min_addr, 2329438a86aSSteven J. Hill uint64_t max_addr, 2339438a86aSSteven J. Hill uint64_t align, 2349438a86aSSteven J. Hill char *name, 2359438a86aSSteven J. Hill void (*init) (void *)); 2369438a86aSSteven J. Hill 23758f07778SDavid Daney extern int cvmx_bootmem_free_named(char *name); 23858f07778SDavid Daney 23958f07778SDavid Daney /** 24058f07778SDavid Daney * Finds a named bootmem block by name. 24158f07778SDavid Daney * 24258f07778SDavid Daney * @name: name of block to free 24358f07778SDavid Daney * 24458f07778SDavid Daney * Returns pointer to named block descriptor on success 24558f07778SDavid Daney * 0 on failure 24658f07778SDavid Daney */ 24758f07778SDavid Daney struct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name); 24858f07778SDavid Daney 24958f07778SDavid Daney /** 25058f07778SDavid Daney * Allocates a block of physical memory from the free list, at 25158f07778SDavid Daney * (optional) requested address and alignment. 25258f07778SDavid Daney * 25358f07778SDavid Daney * @req_size: size of region to allocate. All requests are rounded up 25458f07778SDavid Daney * to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size 25558f07778SDavid Daney * 25658f07778SDavid Daney * @address_min: Minimum address that block can occupy. 25758f07778SDavid Daney * 25858f07778SDavid Daney * @address_max: Specifies the maximum address_min (inclusive) that 25958f07778SDavid Daney * the allocation can use. 26058f07778SDavid Daney * 26158f07778SDavid Daney * @alignment: Requested alignment of the block. If this alignment 26258f07778SDavid Daney * cannot be met, the allocation fails. This must be a 26358f07778SDavid Daney * power of 2. (Note: Alignment of 26458f07778SDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and 26558f07778SDavid Daney * internally enforced. Requested alignments of less than 26658f07778SDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE are set to 26758f07778SDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE.) 26858f07778SDavid Daney * 26958f07778SDavid Daney * @flags: Flags to control options for the allocation. 27058f07778SDavid Daney * 27158f07778SDavid Daney * Returns physical address of block allocated, or -1 on failure 27258f07778SDavid Daney */ 27358f07778SDavid Daney int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min, 27458f07778SDavid Daney uint64_t address_max, uint64_t alignment, 27558f07778SDavid Daney uint32_t flags); 27658f07778SDavid Daney 27758f07778SDavid Daney /** 2786fa044abSDavid Daney * Allocates a named block of physical memory from the free list, at 2796fa044abSDavid Daney * (optional) requested address and alignment. 2806fa044abSDavid Daney * 2816fa044abSDavid Daney * @param size size of region to allocate. All requests are rounded 2826fa044abSDavid Daney * up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE 2836fa044abSDavid Daney * bytes size 2846fa044abSDavid Daney * @param min_addr Minimum address that block can occupy. 2856fa044abSDavid Daney * @param max_addr Specifies the maximum address_min (inclusive) that 2866fa044abSDavid Daney * the allocation can use. 2876fa044abSDavid Daney * @param alignment Requested alignment of the block. If this 2886fa044abSDavid Daney * alignment cannot be met, the allocation fails. 2896fa044abSDavid Daney * This must be a power of 2. (Note: Alignment of 2906fa044abSDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and 2916fa044abSDavid Daney * internally enforced. Requested alignments of less 2926fa044abSDavid Daney * than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to 2936fa044abSDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE.) 2946fa044abSDavid Daney * @param name name to assign to named block 2956fa044abSDavid Daney * @param flags Flags to control options for the allocation. 2966fa044abSDavid Daney * 2976fa044abSDavid Daney * @return physical address of block allocated, or -1 on failure 2986fa044abSDavid Daney */ 2996fa044abSDavid Daney int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr, 3006fa044abSDavid Daney uint64_t max_addr, 3016fa044abSDavid Daney uint64_t alignment, 3026fa044abSDavid Daney char *name, uint32_t flags); 3036fa044abSDavid Daney 3046fa044abSDavid Daney /** 30558f07778SDavid Daney * Frees a block to the bootmem allocator list. This must 30658f07778SDavid Daney * be used with care, as the size provided must match the size 30758f07778SDavid Daney * of the block that was allocated, or the list will become 30858f07778SDavid Daney * corrupted. 30958f07778SDavid Daney * 31058f07778SDavid Daney * IMPORTANT: This is only intended to be used as part of named block 31158f07778SDavid Daney * frees and initial population of the free memory list. 31258f07778SDavid Daney * * 31358f07778SDavid Daney * 31458f07778SDavid Daney * @phy_addr: physical address of block 31558f07778SDavid Daney * @size: size of block in bytes. 31658f07778SDavid Daney * @flags: flags for passing options 31758f07778SDavid Daney * 31858f07778SDavid Daney * Returns 1 on success, 31958f07778SDavid Daney * 0 on failure 32058f07778SDavid Daney */ 32158f07778SDavid Daney int __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags); 32258f07778SDavid Daney 32358f07778SDavid Daney /** 32458f07778SDavid Daney * Locks the bootmem allocator. This is useful in certain situations 32558f07778SDavid Daney * where multiple allocations must be made without being interrupted. 32658f07778SDavid Daney * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag. 32758f07778SDavid Daney * 32858f07778SDavid Daney */ 32958f07778SDavid Daney void cvmx_bootmem_lock(void); 33058f07778SDavid Daney 33158f07778SDavid Daney /** 33258f07778SDavid Daney * Unlocks the bootmem allocator. This is useful in certain situations 33358f07778SDavid Daney * where multiple allocations must be made without being interrupted. 33458f07778SDavid Daney * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag. 33558f07778SDavid Daney * 33658f07778SDavid Daney */ 33758f07778SDavid Daney void cvmx_bootmem_unlock(void); 33858f07778SDavid Daney 339abe77f90SRalf Baechle extern struct cvmx_bootmem_desc *cvmx_bootmem_get_desc(void); 340abe77f90SRalf Baechle 34158f07778SDavid Daney #endif /* __CVMX_BOOTMEM_H__ */ 342