cvmx-bootmem.h revision 210284
190926Snectar/***********************license start*************** 290926Snectar * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights 390926Snectar * reserved. 490926Snectar * 590926Snectar * 690926Snectar * Redistribution and use in source and binary forms, with or without 790926Snectar * modification, are permitted provided that the following conditions are 890926Snectar * met: 990926Snectar * 1090926Snectar * * Redistributions of source code must retain the above copyright 1190926Snectar * notice, this list of conditions and the following disclaimer. 1290926Snectar * 1390926Snectar * * Redistributions in binary form must reproduce the above 1490926Snectar * copyright notice, this list of conditions and the following 1590926Snectar * disclaimer in the documentation and/or other materials provided 1690926Snectar * with the distribution. 1790926Snectar * 1890926Snectar * * Neither the name of Cavium Networks nor the names of 1990926Snectar * its contributors may be used to endorse or promote products 2090926Snectar * derived from this software without specific prior written 2190926Snectar * permission. 2290926Snectar * 2390926Snectar * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 2490926Snectar * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS 2590926Snectar * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH 2690926Snectar * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY 2790926Snectar * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT 2890926Snectar * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES 2990926Snectar * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR 3090926Snectar * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET 3190926Snectar * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT 3290926Snectar * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 3390926Snectar * 3490926Snectar * 3590926Snectar * For any questions regarding licensing please contact marketing@caviumnetworks.com 3690926Snectar * 3790926Snectar ***********************license end**************************************/ 3890926Snectar 3990926Snectar 4090926Snectar 4190926Snectar 4290926Snectar 4390926Snectar/** 4490926Snectar * @file 4590926Snectar * Simple allocate only memory allocator. Used to allocate memory at application 4690926Snectar * start time. 4790926Snectar * 4890926Snectar * <hr>$Revision: 41586 $<hr> 4990926Snectar * 5090926Snectar */ 5190926Snectar 5290926Snectar#ifndef __CVMX_BOOTMEM_H__ 5390926Snectar#define __CVMX_BOOTMEM_H__ 5490926Snectar 5590926Snectar#ifdef __cplusplus 5690926Snectarextern "C" { 5790926Snectar#endif 5890926Snectar 5990926Snectar#define CVMX_BOOTMEM_NAME_LEN 128 /* Must be multiple of 8, changing breaks ABI */ 6090926Snectar#define CVMX_BOOTMEM_NUM_NAMED_BLOCKS 64 /* Can change without breaking ABI */ 6190926Snectar#define CVMX_BOOTMEM_ALIGNMENT_SIZE (16ull) /* minimum alignment of bootmem alloced blocks */ 6290926Snectar 6390926Snectar/* Flags for cvmx_bootmem_phy_mem* functions */ 6490926Snectar#define CVMX_BOOTMEM_FLAG_END_ALLOC (1 << 0) /* Allocate from end of block instead of beginning */ 6590926Snectar#define CVMX_BOOTMEM_FLAG_NO_LOCKING (1 << 1) /* Don't do any locking. */ 6690926Snectar 6790926Snectar 6890926Snectar/* First bytes of each free physical block of memory contain this structure, 6990926Snectar * which is used to maintain the free memory list. Since the bootloader is 7090926Snectar * only 32 bits, there is a union providing 64 and 32 bit versions. The 7190926Snectar * application init code converts addresses to 64 bit addresses before the 7290926Snectar * application starts. 7390926Snectar */ 7490926Snectartypedef struct 7590926Snectar{ 7690926Snectar /* Note: these are referenced from assembly routines in the bootloader, so this structure 7790926Snectar ** should not be changed without changing those routines as well. */ 7890926Snectar uint64_t next_block_addr; 7990926Snectar uint64_t size; 8090926Snectar 8190926Snectar} cvmx_bootmem_block_header_t; 8290926Snectar 8390926Snectar 8490926Snectar/* Structure for named memory blocks 8590926Snectar** Number of descriptors 8690926Snectar** available can be changed without affecting compatiblity, 8790926Snectar** but name length changes require a bump in the bootmem 8890926Snectar** descriptor version 8990926Snectar** Note: This structure must be naturally 64 bit aligned, as a single 9090926Snectar** memory image will be used by both 32 and 64 bit programs. 9190926Snectar*/ 9290926Snectartypedef struct 9390926Snectar{ 9490926Snectar uint64_t base_addr; /**< Base address of named block */ 9590926Snectar uint64_t size; /**< Size actually allocated for named block (may differ from requested) */ 9690926Snectar char name[CVMX_BOOTMEM_NAME_LEN]; /**< name of named block */ 9790926Snectar} cvmx_bootmem_named_block_desc_t; 9890926Snectar 9990926Snectar 10090926Snectar 10190926Snectar/* Current descriptor versions */ 10290926Snectar#define CVMX_BOOTMEM_DESC_MAJ_VER 3 /* CVMX bootmem descriptor major version */ 10390926Snectar#define CVMX_BOOTMEM_DESC_MIN_VER 0 /* CVMX bootmem descriptor minor version */ 10490926Snectar 10590926Snectar/* First three members of cvmx_bootmem_desc_t are left in original 10690926Snectar** positions for backwards compatibility. 10790926Snectar*/ 10890926Snectartypedef struct 10990926Snectar{ 11090926Snectar uint32_t lock; /**< spinlock to control access to list */ 11190926Snectar uint32_t flags; /**< flags for indicating various conditions */ 11290926Snectar uint64_t head_addr; 11390926Snectar 11490926Snectar uint32_t major_version; /**< incremented changed when incompatible changes made */ 11590926Snectar uint32_t minor_version; /**< incremented changed when compatible changes made, reset to zero when major incremented */ 11690926Snectar uint64_t app_data_addr; 11790926Snectar uint64_t app_data_size; 11890926Snectar 11990926Snectar uint32_t named_block_num_blocks; /**< number of elements in named blocks array */ 12090926Snectar uint32_t named_block_name_len; /**< length of name array in bootmem blocks */ 12190926Snectar uint64_t named_block_array_addr; /**< address of named memory block descriptors */ 12290926Snectar 12390926Snectar} cvmx_bootmem_desc_t; 12490926Snectar 12590926Snectar 12690926Snectar/** 12790926Snectar * Initialize the boot alloc memory structures. This is 12890926Snectar * normally called inside of cvmx_user_app_init() 12990926Snectar * 13090926Snectar * @param mem_desc_ptr Address of the free memory list 13190926Snectar * @return 13290926Snectar */ 13390926Snectarextern int cvmx_bootmem_init(void *mem_desc_ptr); 13490926Snectar 13590926Snectar 13690926Snectar/** 13790926Snectar * Allocate a block of memory from the free list that was passed 13890926Snectar * to the application by the bootloader. 13990926Snectar * This is an allocate-only algorithm, so freeing memory is not possible. 14090926Snectar * 14190926Snectar * @param size Size in bytes of block to allocate 14290926Snectar * @param alignment Alignment required - must be power of 2 14390926Snectar * 14490926Snectar * @return pointer to block of memory, NULL on error 14590926Snectar */ 14690926Snectarextern void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment); 14790926Snectar 14890926Snectar/** 14990926Snectar * Allocate a block of memory from the free list that was 15090926Snectar * passed to the application by the bootloader at a specific 15190926Snectar * address. This is an allocate-only algorithm, so 15290926Snectar * freeing memory is not possible. Allocation will fail if 15390926Snectar * memory cannot be allocated at the specified address. 15490926Snectar * 15590926Snectar * @param size Size in bytes of block to allocate 15690926Snectar * @param address Physical address to allocate memory at. If this memory is not 15790926Snectar * available, the allocation fails. 15890926Snectar * @param alignment Alignment required - must be power of 2 15990926Snectar * @return pointer to block of memory, NULL on error 16090926Snectar */ 16190926Snectarextern void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address, uint64_t alignment); 16290926Snectar 16390926Snectar 16490926Snectar 16590926Snectar/** 16690926Snectar * Allocate a block of memory from the free list that was 16790926Snectar * passed to the application by the bootloader within a specified 16890926Snectar * address range. This is an allocate-only algorithm, so 16990926Snectar * freeing memory is not possible. Allocation will fail if 17090926Snectar * memory cannot be allocated in the requested range. 17190926Snectar * 17290926Snectar * @param size Size in bytes of block to allocate 17390926Snectar * @param min_addr defines the minimum address of the range 17490926Snectar * @param max_addr defines the maximum address of the range 17590926Snectar * @param alignment Alignment required - must be power of 2 17690926Snectar * @return pointer to block of memory, NULL on error 17790926Snectar */ 17890926Snectarextern void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment, uint64_t min_addr, uint64_t max_addr); 17990926Snectar 18090926Snectar 18190926Snectar/** 18290926Snectar * Allocate a block of memory from the free list that was passed 18390926Snectar * to the application by the bootloader, and assign it a name in the 18490926Snectar * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 18590926Snectar * Named blocks can later be freed. 18690926Snectar * 18790926Snectar * @param size Size in bytes of block to allocate 18890926Snectar * @param alignment Alignment required - must be power of 2 18990926Snectar * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 19090926Snectar * 19190926Snectar * @return pointer to block of memory, NULL on error 19290926Snectar */ 19390926Snectarextern void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, char *name); 19490926Snectar 19590926Snectar 19690926Snectar 19790926Snectar/** 19890926Snectar * Allocate a block of memory from the free list that was passed 19990926Snectar * to the application by the bootloader, and assign it a name in the 20090926Snectar * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 20190926Snectar * Named blocks can later be freed. 20290926Snectar * 20390926Snectar * @param size Size in bytes of block to allocate 20490926Snectar * @param address Physical address to allocate memory at. If this memory is not 20590926Snectar * available, the allocation fails. 20690926Snectar * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 20790926Snectar * 20890926Snectar * @return pointer to block of memory, NULL on error 20990926Snectar */ 21090926Snectarextern void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address, char *name); 21190926Snectar 21290926Snectar 21390926Snectar 21490926Snectar/** 21590926Snectar * Allocate a block of memory from a specific range of the free list that was passed 21690926Snectar * to the application by the bootloader, and assign it a name in the 21790926Snectar * global named block table. (part of the cvmx_bootmem_descriptor_t structure) 21890926Snectar * Named blocks can later be freed. 21990926Snectar * If request cannot be satisfied within the address range specified, NULL is returned 22090926Snectar * 22190926Snectar * @param size Size in bytes of block to allocate 22290926Snectar * @param min_addr minimum address of range 22390926Snectar * @param max_addr maximum address of range 22490926Snectar * @param align Alignment of memory to be allocated. (must be a power of 2) 22590926Snectar * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes 22690926Snectar * 22790926Snectar * @return pointer to block of memory, NULL on error 22890926Snectar */ 22990926Snectarextern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, uint64_t max_addr, uint64_t align, char *name); 23090926Snectar 23190926Snectar/** 23290926Snectar * Frees a previously allocated named bootmem block. 23390926Snectar * 23490926Snectar * @param name name of block to free 23590926Snectar * 23690926Snectar * @return 0 on failure, 23790926Snectar * !0 on success 23890926Snectar */ 23990926Snectarextern int cvmx_bootmem_free_named(char *name); 24090926Snectar 24190926Snectar 24290926Snectar/** 24390926Snectar * Finds a named bootmem block by name. 24490926Snectar * 24590926Snectar * @param name name of block to free 24690926Snectar * 24790926Snectar * @return pointer to named block descriptor on success 24890926Snectar * 0 on failure 24990926Snectar */ 25090926Snectarcvmx_bootmem_named_block_desc_t * cvmx_bootmem_find_named_block(char *name); 25190926Snectar 25290926Snectar 25390926Snectar 25490926Snectar/** 25590926Snectar * Returns the size of available memory in bytes, only 25690926Snectar * counting blocks that are at least as big as the minimum block 25790926Snectar * size. 25890926Snectar * 25990926Snectar * @param min_block_size 26090926Snectar * Minimum block size to count in total. 26190926Snectar * 26290926Snectar * @return Number of bytes available for allocation that meet the block size requirement 26390926Snectar */ 26490926Snectaruint64_t cvmx_bootmem_available_mem(uint64_t min_block_size); 26590926Snectar 26690926Snectar 26790926Snectar 26890926Snectar/** 26990926Snectar * Prints out the list of named blocks that have been allocated 27090926Snectar * along with their addresses and sizes. 27190926Snectar * This is primarily used for debugging purposes 27290926Snectar */ 27390926Snectarvoid cvmx_bootmem_print_named(void); 27490926Snectar 27590926Snectar 27690926Snectar/** 27790926Snectar * Allocates a block of physical memory from the free list, at (optional) requested address and alignment. 27890926Snectar * 27990926Snectar * @param req_size size of region to allocate. All requests are rounded up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size 28090926Snectar * @param address_min 28190926Snectar * Minimum address that block can occupy. 28290926Snectar * @param address_max 28390926Snectar * Specifies the maximum address_min (inclusive) that the allocation can use. 28490926Snectar * @param alignment Requested alignment of the block. If this alignment cannot be met, the allocation fails. 28590926Snectar * This must be a power of 2. 28690926Snectar * (Note: Alignment of CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and internally enforced. Requested alignments of 28790926Snectar * less than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to CVMX_BOOTMEM_ALIGNMENT_SIZE.) 28890926Snectar * @param flags Flags to control options for the allocation. 28990926Snectar * 29090926Snectar * @return physical address of block allocated, or -1 on failure 29190926Snectar */ 29290926Snectarint64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min, uint64_t address_max, uint64_t alignment, uint32_t flags); 29390926Snectar 29490926Snectar 29590926Snectar 29690926Snectar/** 29790926Snectar * Allocates a named block of physical memory from the free list, at (optional) requested address and alignment. 29890926Snectar * 29990926Snectar * @param size size of region to allocate. All requests are rounded up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size 30090926Snectar * @param min_addr 30190926Snectar * Minimum address that block can occupy. 30290926Snectar * @param max_addr 30390926Snectar * Specifies the maximum address_min (inclusive) that the allocation can use. 30490926Snectar * @param alignment Requested alignment of the block. If this alignment cannot be met, the allocation fails. 30590926Snectar * This must be a power of 2. 30690926Snectar * (Note: Alignment of CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and internally enforced. Requested alignments of 30790926Snectar * less than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to CVMX_BOOTMEM_ALIGNMENT_SIZE.) 30890926Snectar * @param name name to assign to named block 30990926Snectar * @param flags Flags to control options for the allocation. 31090926Snectar * 31190926Snectar * @return physical address of block allocated, or -1 on failure 31290926Snectar */ 31390926Snectarint64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr, uint64_t max_addr, uint64_t alignment, char *name, uint32_t flags); 31490926Snectar 31590926Snectar 31690926Snectar/** 31790926Snectar * Finds a named memory block by name. 31890926Snectar * Also used for finding an unused entry in the named block table. 31990926Snectar * 32090926Snectar * @param name Name of memory block to find. 32190926Snectar * If NULL pointer given, then finds unused descriptor, if available. 32290926Snectar * @param flags Flags to control options for the allocation. 32390926Snectar * 32490926Snectar * @return Pointer to memory block descriptor, NULL if not found. 32590926Snectar * If NULL returned when name parameter is NULL, then no memory 32690926Snectar * block descriptors are available. 32790926Snectar */ 32890926Snectarcvmx_bootmem_named_block_desc_t * cvmx_bootmem_phy_named_block_find(char *name, uint32_t flags); 32990926Snectar 33090926Snectar 33190926Snectar/** 33290926Snectar * Returns the size of available memory in bytes, only 33390926Snectar * counting blocks that are at least as big as the minimum block 33490926Snectar * size. 33590926Snectar * 33690926Snectar * @param min_block_size 33790926Snectar * Minimum block size to count in total. 33890926Snectar * 33990926Snectar * @return Number of bytes available for allocation that meet the block size requirement 34090926Snectar */ 34190926Snectaruint64_t cvmx_bootmem_phy_available_mem(uint64_t min_block_size); 34290926Snectar 34390926Snectar/** 34490926Snectar * Frees a named block. 34590926Snectar * 34690926Snectar * @param name name of block to free 34790926Snectar * @param flags flags for passing options 34890926Snectar * 34990926Snectar * @return 0 on failure 35090926Snectar * 1 on success 35190926Snectar */ 35290926Snectarint cvmx_bootmem_phy_named_block_free(char *name, uint32_t flags); 35390926Snectar 35490926Snectar/** 35590926Snectar * Frees a block to the bootmem allocator list. This must 35690926Snectar * be used with care, as the size provided must match the size 35790926Snectar * of the block that was allocated, or the list will become 35890926Snectar * corrupted. 35990926Snectar * 36090926Snectar * IMPORTANT: This is only intended to be used as part of named block 36190926Snectar * frees and initial population of the free memory list. 36290926Snectar * * 36390926Snectar * 36490926Snectar * @param phy_addr physical address of block 36590926Snectar * @param size size of block in bytes. 36690926Snectar * @param flags flags for passing options 36790926Snectar * 36890926Snectar * @return 1 on success, 36990926Snectar * 0 on failure 37090926Snectar */ 37190926Snectarint __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags); 37290926Snectar 37390926Snectar 37490926Snectar/** 37590926Snectar * Prints the list of currently allocated named blocks 37690926Snectar * 37790926Snectar */ 37890926Snectarvoid cvmx_bootmem_phy_named_block_print(void); 37990926Snectar 38090926Snectar 38190926Snectar/** 38290926Snectar * Prints the list of available memory. 38390926Snectar * 38490926Snectar */ 38590926Snectarvoid cvmx_bootmem_phy_list_print(void); 38690926Snectar 38790926Snectar 38890926Snectar 38990926Snectar/** 39090926Snectar * This function initializes the free memory list used by cvmx_bootmem. 39190926Snectar * This must be called before any allocations can be done. 39290926Snectar * 39390926Snectar * @param mem_size Total memory available, in bytes 39490926Snectar * @param low_reserved_bytes 39590926Snectar * Number of bytes to reserve (leave out of free list) at address 0x0. 39690926Snectar * @param desc_buffer 39790926Snectar * Buffer for the bootmem descriptor. This must be a 32 bit addressable 39890926Snectar * address. 39990926Snectar * 40090926Snectar * @return 1 on success 40190926Snectar * 0 on failure 40290926Snectar */ 40390926Snectarint64_t cvmx_bootmem_phy_mem_list_init(uint64_t mem_size, uint32_t low_reserved_bytes, cvmx_bootmem_desc_t *desc_buffer); 40490926Snectar 40590926Snectar/** 40690926Snectar * Locks the bootmem allocator. This is useful in certain situations 40790926Snectar * where multiple allocations must be made without being interrupted. 40890926Snectar * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag. 40990926Snectar * 41090926Snectar */ 41190926Snectarvoid cvmx_bootmem_lock(void); 41290926Snectar 41390926Snectar/** 41490926Snectar * Unlocks the bootmem allocator. This is useful in certain situations 41590926Snectar * where multiple allocations must be made without being interrupted. 41690926Snectar * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag. 41790926Snectar * 41890926Snectar */ 41990926Snectarvoid cvmx_bootmem_unlock(void); 42090926Snectar 42190926Snectar/** 42290926Snectar * Internal use function to get the current descriptor pointer */ 42390926Snectarvoid *__cvmx_bootmem_internal_get_desc_ptr(void); 42490926Snectar 42590926Snectar#ifdef __cplusplus 42690926Snectar} 42790926Snectar#endif 42890926Snectar 42990926Snectar#endif /* __CVMX_BOOTMEM_H__ */ 43090926Snectar