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 70*25985edcSLucas 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 { 9858f07778SDavid Daney /* spinlock to control access to list */ 9958f07778SDavid Daney uint32_t lock; 10058f07778SDavid Daney /* flags for indicating various conditions */ 10158f07778SDavid Daney uint32_t flags; 10258f07778SDavid Daney uint64_t head_addr; 10358f07778SDavid Daney 10458f07778SDavid Daney /* Incremented when incompatible changes made */ 10558f07778SDavid Daney uint32_t major_version; 10658f07778SDavid Daney 10758f07778SDavid Daney /* 10858f07778SDavid Daney * Incremented changed when compatible changes made, reset to 10958f07778SDavid Daney * zero when major incremented. 11058f07778SDavid Daney */ 11158f07778SDavid Daney uint32_t minor_version; 11258f07778SDavid Daney 11358f07778SDavid Daney uint64_t app_data_addr; 11458f07778SDavid Daney uint64_t app_data_size; 11558f07778SDavid Daney 11658f07778SDavid Daney /* number of elements in named blocks array */ 11758f07778SDavid Daney uint32_t named_block_num_blocks; 11858f07778SDavid Daney 11958f07778SDavid Daney /* length of name array in bootmem blocks */ 12058f07778SDavid Daney uint32_t named_block_name_len; 12158f07778SDavid Daney /* address of named memory block descriptors */ 12258f07778SDavid Daney uint64_t named_block_array_addr; 12358f07778SDavid Daney 12458f07778SDavid Daney }; 12558f07778SDavid Daney 12658f07778SDavid Daney /** 12758f07778SDavid Daney * Initialize the boot alloc memory structures. This is 12858f07778SDavid Daney * normally called inside of cvmx_user_app_init() 12958f07778SDavid Daney * 13058f07778SDavid Daney * @mem_desc_ptr: Address of the free memory list 13158f07778SDavid Daney */ 13258f07778SDavid Daney extern int cvmx_bootmem_init(void *mem_desc_ptr); 13358f07778SDavid Daney 13458f07778SDavid Daney /** 13558f07778SDavid Daney * Allocate a block of memory from the free list that was passed 13658f07778SDavid Daney * to the application by the bootloader. 13758f07778SDavid Daney * This is an allocate-only algorithm, so freeing memory is not possible. 13858f07778SDavid Daney * 13958f07778SDavid Daney * @size: Size in bytes of block to allocate 14058f07778SDavid Daney * @alignment: Alignment required - must be power of 2 14158f07778SDavid Daney * 14258f07778SDavid Daney * Returns pointer to block of memory, NULL on error 14358f07778SDavid Daney */ 14458f07778SDavid Daney extern void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment); 14558f07778SDavid Daney 14658f07778SDavid Daney /** 14758f07778SDavid Daney * Allocate a block of memory from the free list that was 14858f07778SDavid Daney * passed to the application by the bootloader at a specific 14958f07778SDavid Daney * address. This is an allocate-only algorithm, so 15058f07778SDavid Daney * freeing memory is not possible. Allocation will fail if 15158f07778SDavid Daney * memory cannot be allocated at the specified address. 15258f07778SDavid Daney * 15358f07778SDavid Daney * @size: Size in bytes of block to allocate 15458f07778SDavid Daney * @address: Physical address to allocate memory at. If this memory is not 15558f07778SDavid Daney * available, the allocation fails. 15658f07778SDavid Daney * @alignment: Alignment required - must be power of 2 15758f07778SDavid Daney * Returns pointer to block of memory, NULL on error 15858f07778SDavid Daney */ 15958f07778SDavid Daney extern void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address, 16058f07778SDavid Daney uint64_t alignment); 16158f07778SDavid Daney 16258f07778SDavid Daney /** 16358f07778SDavid Daney * Allocate a block of memory from the free list that was 16458f07778SDavid Daney * passed to the application by the bootloader within a specified 16558f07778SDavid Daney * address range. This is an allocate-only algorithm, so 16658f07778SDavid Daney * freeing memory is not possible. Allocation will fail if 16758f07778SDavid Daney * memory cannot be allocated in the requested range. 16858f07778SDavid Daney * 16958f07778SDavid Daney * @size: Size in bytes of block to allocate 17058f07778SDavid Daney * @min_addr: defines the minimum address of the range 17158f07778SDavid Daney * @max_addr: defines the maximum address of the range 17258f07778SDavid Daney * @alignment: Alignment required - must be power of 2 17358f07778SDavid Daney * Returns pointer to block of memory, NULL on error 17458f07778SDavid Daney */ 17558f07778SDavid Daney extern void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment, 17658f07778SDavid Daney uint64_t min_addr, uint64_t max_addr); 17758f07778SDavid Daney 17858f07778SDavid Daney /** 17958f07778SDavid Daney * Frees a previously allocated named bootmem block. 18058f07778SDavid Daney * 18158f07778SDavid Daney * @name: name of block to free 18258f07778SDavid Daney * 18358f07778SDavid Daney * Returns 0 on failure, 18458f07778SDavid Daney * !0 on success 18558f07778SDavid Daney */ 1866fa044abSDavid Daney 1876fa044abSDavid Daney 1886fa044abSDavid Daney /** 1896fa044abSDavid Daney * Allocate a block of memory from the free list that was passed 1906fa044abSDavid Daney * to the application by the bootloader, and assign it a name in the 1916fa044abSDavid Daney * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 1926fa044abSDavid Daney * Named blocks can later be freed. 1936fa044abSDavid Daney * 1946fa044abSDavid Daney * @size: Size in bytes of block to allocate 1956fa044abSDavid Daney * @alignment: Alignment required - must be power of 2 1966fa044abSDavid Daney * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 1976fa044abSDavid Daney * 1986fa044abSDavid Daney * Returns a pointer to block of memory, NULL on error 1996fa044abSDavid Daney */ 2006fa044abSDavid Daney extern void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, 2016fa044abSDavid Daney char *name); 2026fa044abSDavid Daney 2036fa044abSDavid Daney 2046fa044abSDavid Daney 2056fa044abSDavid Daney /** 2066fa044abSDavid Daney * Allocate a block of memory from the free list that was passed 2076fa044abSDavid Daney * to the application by the bootloader, and assign it a name in the 2086fa044abSDavid Daney * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 2096fa044abSDavid Daney * Named blocks can later be freed. 2106fa044abSDavid Daney * 2116fa044abSDavid Daney * @size: Size in bytes of block to allocate 2126fa044abSDavid Daney * @address: Physical address to allocate memory at. If this 2136fa044abSDavid Daney * memory is not available, the allocation fails. 2146fa044abSDavid Daney * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN 2156fa044abSDavid Daney * bytes 2166fa044abSDavid Daney * 2176fa044abSDavid Daney * Returns a pointer to block of memory, NULL on error 2186fa044abSDavid Daney */ 2196fa044abSDavid Daney extern void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address, 2206fa044abSDavid Daney char *name); 2216fa044abSDavid Daney 2226fa044abSDavid Daney 2236fa044abSDavid Daney 2246fa044abSDavid Daney /** 2256fa044abSDavid Daney * Allocate a block of memory from a specific range of the free list 2266fa044abSDavid Daney * that was passed to the application by the bootloader, and assign it 2276fa044abSDavid Daney * a name in the global named block table. (part of the 2286fa044abSDavid Daney * cvmx_bootmem_descriptor_t structure) Named blocks can later be 2296fa044abSDavid Daney * freed. If request cannot be satisfied within the address range 2306fa044abSDavid Daney * specified, NULL is returned 2316fa044abSDavid Daney * 2326fa044abSDavid Daney * @size: Size in bytes of block to allocate 2336fa044abSDavid Daney * @min_addr: minimum address of range 2346fa044abSDavid Daney * @max_addr: maximum address of range 2356fa044abSDavid Daney * @align: Alignment of memory to be allocated. (must be a power of 2) 2366fa044abSDavid Daney * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 2376fa044abSDavid Daney * 2386fa044abSDavid Daney * Returns a pointer to block of memory, NULL on error 2396fa044abSDavid Daney */ 2406fa044abSDavid Daney extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, 2416fa044abSDavid Daney uint64_t max_addr, uint64_t align, 2426fa044abSDavid Daney char *name); 2436fa044abSDavid Daney 24458f07778SDavid Daney extern int cvmx_bootmem_free_named(char *name); 24558f07778SDavid Daney 24658f07778SDavid Daney /** 24758f07778SDavid Daney * Finds a named bootmem block by name. 24858f07778SDavid Daney * 24958f07778SDavid Daney * @name: name of block to free 25058f07778SDavid Daney * 25158f07778SDavid Daney * Returns pointer to named block descriptor on success 25258f07778SDavid Daney * 0 on failure 25358f07778SDavid Daney */ 25458f07778SDavid Daney struct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name); 25558f07778SDavid Daney 25658f07778SDavid Daney /** 25758f07778SDavid Daney * Allocates a block of physical memory from the free list, at 25858f07778SDavid Daney * (optional) requested address and alignment. 25958f07778SDavid Daney * 26058f07778SDavid Daney * @req_size: size of region to allocate. All requests are rounded up 26158f07778SDavid Daney * to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size 26258f07778SDavid Daney * 26358f07778SDavid Daney * @address_min: Minimum address that block can occupy. 26458f07778SDavid Daney * 26558f07778SDavid Daney * @address_max: Specifies the maximum address_min (inclusive) that 26658f07778SDavid Daney * the allocation can use. 26758f07778SDavid Daney * 26858f07778SDavid Daney * @alignment: Requested alignment of the block. If this alignment 26958f07778SDavid Daney * cannot be met, the allocation fails. This must be a 27058f07778SDavid Daney * power of 2. (Note: Alignment of 27158f07778SDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and 27258f07778SDavid Daney * internally enforced. Requested alignments of less than 27358f07778SDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE are set to 27458f07778SDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE.) 27558f07778SDavid Daney * 27658f07778SDavid Daney * @flags: Flags to control options for the allocation. 27758f07778SDavid Daney * 27858f07778SDavid Daney * Returns physical address of block allocated, or -1 on failure 27958f07778SDavid Daney */ 28058f07778SDavid Daney int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min, 28158f07778SDavid Daney uint64_t address_max, uint64_t alignment, 28258f07778SDavid Daney uint32_t flags); 28358f07778SDavid Daney 28458f07778SDavid Daney /** 2856fa044abSDavid Daney * Allocates a named block of physical memory from the free list, at 2866fa044abSDavid Daney * (optional) requested address and alignment. 2876fa044abSDavid Daney * 2886fa044abSDavid Daney * @param size size of region to allocate. All requests are rounded 2896fa044abSDavid Daney * up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE 2906fa044abSDavid Daney * bytes size 2916fa044abSDavid Daney * @param min_addr Minimum address that block can occupy. 2926fa044abSDavid Daney * @param max_addr Specifies the maximum address_min (inclusive) that 2936fa044abSDavid Daney * the allocation can use. 2946fa044abSDavid Daney * @param alignment Requested alignment of the block. If this 2956fa044abSDavid Daney * alignment cannot be met, the allocation fails. 2966fa044abSDavid Daney * This must be a power of 2. (Note: Alignment of 2976fa044abSDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and 2986fa044abSDavid Daney * internally enforced. Requested alignments of less 2996fa044abSDavid Daney * than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to 3006fa044abSDavid Daney * CVMX_BOOTMEM_ALIGNMENT_SIZE.) 3016fa044abSDavid Daney * @param name name to assign to named block 3026fa044abSDavid Daney * @param flags Flags to control options for the allocation. 3036fa044abSDavid Daney * 3046fa044abSDavid Daney * @return physical address of block allocated, or -1 on failure 3056fa044abSDavid Daney */ 3066fa044abSDavid Daney int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr, 3076fa044abSDavid Daney uint64_t max_addr, 3086fa044abSDavid Daney uint64_t alignment, 3096fa044abSDavid Daney char *name, uint32_t flags); 3106fa044abSDavid Daney 3116fa044abSDavid Daney /** 31258f07778SDavid Daney * Finds a named memory block by name. 31358f07778SDavid Daney * Also used for finding an unused entry in the named block table. 31458f07778SDavid Daney * 31558f07778SDavid Daney * @name: Name of memory block to find. If NULL pointer given, then 31658f07778SDavid Daney * finds unused descriptor, if available. 31758f07778SDavid Daney * 31858f07778SDavid Daney * @flags: Flags to control options for the allocation. 31958f07778SDavid Daney * 32058f07778SDavid Daney * Returns Pointer to memory block descriptor, NULL if not found. 32158f07778SDavid Daney * If NULL returned when name parameter is NULL, then no memory 32258f07778SDavid Daney * block descriptors are available. 32358f07778SDavid Daney */ 32458f07778SDavid Daney struct cvmx_bootmem_named_block_desc * 32558f07778SDavid Daney cvmx_bootmem_phy_named_block_find(char *name, uint32_t flags); 32658f07778SDavid Daney 32758f07778SDavid Daney /** 32858f07778SDavid Daney * Frees a named block. 32958f07778SDavid Daney * 33058f07778SDavid Daney * @name: name of block to free 33158f07778SDavid Daney * @flags: flags for passing options 33258f07778SDavid Daney * 33358f07778SDavid Daney * Returns 0 on failure 33458f07778SDavid Daney * 1 on success 33558f07778SDavid Daney */ 33658f07778SDavid Daney int cvmx_bootmem_phy_named_block_free(char *name, uint32_t flags); 33758f07778SDavid Daney 33858f07778SDavid Daney /** 33958f07778SDavid Daney * Frees a block to the bootmem allocator list. This must 34058f07778SDavid Daney * be used with care, as the size provided must match the size 34158f07778SDavid Daney * of the block that was allocated, or the list will become 34258f07778SDavid Daney * corrupted. 34358f07778SDavid Daney * 34458f07778SDavid Daney * IMPORTANT: This is only intended to be used as part of named block 34558f07778SDavid Daney * frees and initial population of the free memory list. 34658f07778SDavid Daney * * 34758f07778SDavid Daney * 34858f07778SDavid Daney * @phy_addr: physical address of block 34958f07778SDavid Daney * @size: size of block in bytes. 35058f07778SDavid Daney * @flags: flags for passing options 35158f07778SDavid Daney * 35258f07778SDavid Daney * Returns 1 on success, 35358f07778SDavid Daney * 0 on failure 35458f07778SDavid Daney */ 35558f07778SDavid Daney int __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags); 35658f07778SDavid Daney 35758f07778SDavid Daney /** 35858f07778SDavid Daney * Locks the bootmem allocator. This is useful in certain situations 35958f07778SDavid Daney * where multiple allocations must be made without being interrupted. 36058f07778SDavid Daney * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag. 36158f07778SDavid Daney * 36258f07778SDavid Daney */ 36358f07778SDavid Daney void cvmx_bootmem_lock(void); 36458f07778SDavid Daney 36558f07778SDavid Daney /** 36658f07778SDavid Daney * Unlocks the bootmem allocator. This is useful in certain situations 36758f07778SDavid Daney * where multiple allocations must be made without being interrupted. 36858f07778SDavid Daney * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag. 36958f07778SDavid Daney * 37058f07778SDavid Daney */ 37158f07778SDavid Daney void cvmx_bootmem_unlock(void); 37258f07778SDavid Daney 37358f07778SDavid Daney #endif /* __CVMX_BOOTMEM_H__ */ 374