Back to home page

OSCL-LXR

 
 

    


0001 /***********************license start***************
0002  * Author: Cavium Networks
0003  *
0004  * Contact: support@caviumnetworks.com
0005  * This file is part of the OCTEON SDK
0006  *
0007  * Copyright (c) 2003-2008 Cavium Networks
0008  *
0009  * This file is free software; you can redistribute it and/or modify
0010  * it under the terms of the GNU General Public License, Version 2, as
0011  * published by the Free Software Foundation.
0012  *
0013  * This file is distributed in the hope that it will be useful, but
0014  * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
0015  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
0016  * NONINFRINGEMENT.  See the GNU General Public License for more
0017  * details.
0018  *
0019  * You should have received a copy of the GNU General Public License
0020  * along with this file; if not, write to the Free Software
0021  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
0022  * or visit http://www.gnu.org/licenses/.
0023  *
0024  * This file may also be available under a different license from Cavium.
0025  * Contact Cavium Networks for more information
0026  ***********************license end**************************************/
0027 
0028 /*
0029  * Simple allocate only memory allocator.  Used to allocate memory at
0030  * application start time.
0031  */
0032 
0033 #ifndef __CVMX_BOOTMEM_H__
0034 #define __CVMX_BOOTMEM_H__
0035 /* Must be multiple of 8, changing breaks ABI */
0036 #define CVMX_BOOTMEM_NAME_LEN 128
0037 
0038 /* Can change without breaking ABI */
0039 #define CVMX_BOOTMEM_NUM_NAMED_BLOCKS 64
0040 
0041 /* minimum alignment of bootmem alloced blocks */
0042 #define CVMX_BOOTMEM_ALIGNMENT_SIZE (16ull)
0043 
0044 /* Flags for cvmx_bootmem_phy_mem* functions */
0045 /* Allocate from end of block instead of beginning */
0046 #define CVMX_BOOTMEM_FLAG_END_ALLOC    (1 << 0)
0047 
0048 /* Don't do any locking. */
0049 #define CVMX_BOOTMEM_FLAG_NO_LOCKING   (1 << 1)
0050 
0051 /* First bytes of each free physical block of memory contain this structure,
0052  * which is used to maintain the free memory list.  Since the bootloader is
0053  * only 32 bits, there is a union providing 64 and 32 bit versions.  The
0054  * application init code converts addresses to 64 bit addresses before the
0055  * application starts.
0056  */
0057 struct cvmx_bootmem_block_header {
0058     /*
0059      * Note: these are referenced from assembly routines in the
0060      * bootloader, so this structure should not be changed
0061      * without changing those routines as well.
0062      */
0063     uint64_t next_block_addr;
0064     uint64_t size;
0065 
0066 };
0067 
0068 /*
0069  * Structure for named memory blocks.  Number of descriptors available
0070  * can be changed without affecting compatibility, but name length
0071  * changes require a bump in the bootmem descriptor version Note: This
0072  * structure must be naturally 64 bit aligned, as a single memory
0073  * image will be used by both 32 and 64 bit programs.
0074  */
0075 struct cvmx_bootmem_named_block_desc {
0076     /* Base address of named block */
0077     uint64_t base_addr;
0078     /*
0079      * Size actually allocated for named block (may differ from
0080      * requested).
0081      */
0082     uint64_t size;
0083     /* name of named block */
0084     char name[CVMX_BOOTMEM_NAME_LEN];
0085 };
0086 
0087 /* Current descriptor versions */
0088 /* CVMX bootmem descriptor major version */
0089 #define CVMX_BOOTMEM_DESC_MAJ_VER   3
0090 
0091 /* CVMX bootmem descriptor minor version */
0092 #define CVMX_BOOTMEM_DESC_MIN_VER   0
0093 
0094 /* First three members of cvmx_bootmem_desc_t are left in original
0095  * positions for backwards compatibility.
0096  */
0097 struct cvmx_bootmem_desc {
0098 #if defined(__BIG_ENDIAN_BITFIELD) || defined(CVMX_BUILD_FOR_LINUX_HOST)
0099     /* spinlock to control access to list */
0100     uint32_t lock;
0101     /* flags for indicating various conditions */
0102     uint32_t flags;
0103     uint64_t head_addr;
0104 
0105     /* Incremented when incompatible changes made */
0106     uint32_t major_version;
0107 
0108     /*
0109      * Incremented changed when compatible changes made, reset to
0110      * zero when major incremented.
0111      */
0112     uint32_t minor_version;
0113 
0114     uint64_t app_data_addr;
0115     uint64_t app_data_size;
0116 
0117     /* number of elements in named blocks array */
0118     uint32_t named_block_num_blocks;
0119 
0120     /* length of name array in bootmem blocks */
0121     uint32_t named_block_name_len;
0122     /* address of named memory block descriptors */
0123     uint64_t named_block_array_addr;
0124 #else                           /* __LITTLE_ENDIAN */
0125     uint32_t flags;
0126     uint32_t lock;
0127     uint64_t head_addr;
0128 
0129     uint32_t minor_version;
0130     uint32_t major_version;
0131     uint64_t app_data_addr;
0132     uint64_t app_data_size;
0133 
0134     uint32_t named_block_name_len;
0135     uint32_t named_block_num_blocks;
0136     uint64_t named_block_array_addr;
0137 #endif
0138 };
0139 
0140 /**
0141  * Initialize the boot alloc memory structures. This is
0142  * normally called inside of cvmx_user_app_init()
0143  *
0144  * @mem_desc_ptr:   Address of the free memory list
0145  */
0146 extern int cvmx_bootmem_init(void *mem_desc_ptr);
0147 
0148 /**
0149  * Allocate a block of memory from the free list that was
0150  * passed to the application by the bootloader at a specific
0151  * address. This is an allocate-only algorithm, so
0152  * freeing memory is not possible. Allocation will fail if
0153  * memory cannot be allocated at the specified address.
0154  *
0155  * @size:      Size in bytes of block to allocate
0156  * @address:   Physical address to allocate memory at.  If this memory is not
0157  *          available, the allocation fails.
0158  * @alignment: Alignment required - must be power of 2
0159  * Returns pointer to block of memory, NULL on error
0160  */
0161 extern void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address,
0162                     uint64_t alignment);
0163 
0164 /**
0165  * Frees a previously allocated named bootmem block.
0166  *
0167  * @name:   name of block to free
0168  *
0169  * Returns 0 on failure,
0170  *     !0 on success
0171  */
0172 
0173 
0174 /**
0175  * Allocate a block of memory from the free list that was passed
0176  * to the application by the bootloader, and assign it a name in the
0177  * global named block table.  (part of the cvmx_bootmem_descriptor_t structure)
0178  * Named blocks can later be freed.
0179  *
0180  * @size:      Size in bytes of block to allocate
0181  * @alignment: Alignment required - must be power of 2
0182  * @name:      name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
0183  *
0184  * Returns a pointer to block of memory, NULL on error
0185  */
0186 extern void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment,
0187                       char *name);
0188 
0189 /**
0190  * Allocate a block of memory from a specific range of the free list
0191  * that was passed to the application by the bootloader, and assign it
0192  * a name in the global named block table.  (part of the
0193  * cvmx_bootmem_descriptor_t structure) Named blocks can later be
0194  * freed.  If request cannot be satisfied within the address range
0195  * specified, NULL is returned
0196  *
0197  * @size:      Size in bytes of block to allocate
0198  * @min_addr:  minimum address of range
0199  * @max_addr:  maximum address of range
0200  * @align:     Alignment of memory to be allocated. (must be a power of 2)
0201  * @name:      name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
0202  *
0203  * Returns a pointer to block of memory, NULL on error
0204  */
0205 extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
0206                         uint64_t max_addr, uint64_t align,
0207                         char *name);
0208 
0209 /**
0210  * Allocate if needed a block of memory from a specific range of the
0211  * free list that was passed to the application by the bootloader, and
0212  * assign it a name in the global named block table.  (part of the
0213  * cvmx_bootmem_descriptor_t structure) Named blocks can later be
0214  * freed.  If the requested name block is already allocated, return
0215  * the pointer to block of memory.  If request cannot be satisfied
0216  * within the address range specified, NULL is returned
0217  *
0218  * @param size   Size in bytes of block to allocate
0219  * @param min_addr  minimum address of range
0220  * @param max_addr  maximum address of range
0221  * @param align  Alignment of memory to be allocated. (must be a power of 2)
0222  * @param name   name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
0223  * @param init   Initialization function
0224  *
0225  * The initialization function is optional, if omitted the named block
0226  * is initialized to all zeros when it is created, i.e. once.
0227  *
0228  * @return pointer to block of memory, NULL on error
0229  */
0230 void *cvmx_bootmem_alloc_named_range_once(uint64_t size,
0231                       uint64_t min_addr,
0232                       uint64_t max_addr,
0233                       uint64_t align,
0234                       char *name,
0235                       void (*init) (void *));
0236 
0237 extern int cvmx_bootmem_free_named(char *name);
0238 
0239 /**
0240  * Finds a named bootmem block by name.
0241  *
0242  * @name:   name of block to free
0243  *
0244  * Returns pointer to named block descriptor on success
0245  *     0 on failure
0246  */
0247 struct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name);
0248 
0249 /**
0250  * Allocates a block of physical memory from the free list, at
0251  * (optional) requested address and alignment.
0252  *
0253  * @req_size: size of region to allocate.  All requests are rounded up
0254  *        to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size
0255  *
0256  * @address_min: Minimum address that block can occupy.
0257  *
0258  * @address_max: Specifies the maximum address_min (inclusive) that
0259  *       the allocation can use.
0260  *
0261  * @alignment: Requested alignment of the block.  If this alignment
0262  *         cannot be met, the allocation fails.  This must be a
0263  *         power of 2.  (Note: Alignment of
0264  *         CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and
0265  *         internally enforced.  Requested alignments of less than
0266  *         CVMX_BOOTMEM_ALIGNMENT_SIZE are set to
0267  *         CVMX_BOOTMEM_ALIGNMENT_SIZE.)
0268  *
0269  * @flags:     Flags to control options for the allocation.
0270  *
0271  * Returns physical address of block allocated, or -1 on failure
0272  */
0273 int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min,
0274                    uint64_t address_max, uint64_t alignment,
0275                    uint32_t flags);
0276 
0277 /**
0278  * Allocates a named block of physical memory from the free list, at
0279  * (optional) requested address and alignment.
0280  *
0281  * @param size      size of region to allocate.  All requests are rounded
0282  *          up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE
0283  *          bytes size
0284  * @param min_addr Minimum address that block can occupy.
0285  * @param max_addr  Specifies the maximum address_min (inclusive) that
0286  *          the allocation can use.
0287  * @param alignment Requested alignment of the block.  If this
0288  *          alignment cannot be met, the allocation fails.
0289  *          This must be a power of 2.  (Note: Alignment of
0290  *          CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and
0291  *          internally enforced.  Requested alignments of less
0292  *          than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to
0293  *          CVMX_BOOTMEM_ALIGNMENT_SIZE.)
0294  * @param name      name to assign to named block
0295  * @param flags     Flags to control options for the allocation.
0296  *
0297  * @return physical address of block allocated, or -1 on failure
0298  */
0299 int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr,
0300                        uint64_t max_addr,
0301                        uint64_t alignment,
0302                        char *name, uint32_t flags);
0303 
0304 /**
0305  * Frees a block to the bootmem allocator list.  This must
0306  * be used with care, as the size provided must match the size
0307  * of the block that was allocated, or the list will become
0308  * corrupted.
0309  *
0310  * IMPORTANT:  This is only intended to be used as part of named block
0311  * frees and initial population of the free memory list.
0312  *                          *
0313  *
0314  * @phy_addr: physical address of block
0315  * @size:     size of block in bytes.
0316  * @flags:    flags for passing options
0317  *
0318  * Returns 1 on success,
0319  *     0 on failure
0320  */
0321 int __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags);
0322 
0323 /**
0324  * Locks the bootmem allocator.  This is useful in certain situations
0325  * where multiple allocations must be made without being interrupted.
0326  * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag.
0327  *
0328  */
0329 void cvmx_bootmem_lock(void);
0330 
0331 /**
0332  * Unlocks the bootmem allocator.  This is useful in certain situations
0333  * where multiple allocations must be made without being interrupted.
0334  * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag.
0335  *
0336  */
0337 void cvmx_bootmem_unlock(void);
0338 
0339 extern struct cvmx_bootmem_desc *cvmx_bootmem_get_desc(void);
0340 
0341 #endif /*   __CVMX_BOOTMEM_H__ */