1/***********************license start*************** 2 * Author: Cavium Networks 3 * 4 * Contact: support@caviumnetworks.com 5 * This file is part of the OCTEON SDK 6 * 7 * Copyright (c) 2003-2008 Cavium Networks 8 * 9 * This file is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License, Version 2, as 11 * published by the Free Software Foundation. 12 * 13 * This file is distributed in the hope that it will be useful, but 14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty 15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 16 * NONINFRINGEMENT. See the GNU General Public License for more 17 * details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this file; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 * or visit http://www.gnu.org/licenses/. 23 * 24 * This file may also be available under a different license from Cavium. 25 * Contact Cavium Networks for more information 26 ***********************license end**************************************/ 27 28/** 29 * @file 30 * 31 * Support library for the hardware Free Pool Allocator. 32 * 33 * 34 */ 35 36#include "cvmx-config.h" 37#include "cvmx.h" 38#include "cvmx-fpa.h" 39#include "cvmx-ipd.h" 40 41/** 42 * Current state of all the pools. Use access functions 43 * instead of using it directly. 44 */ 45CVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS]; 46 47/** 48 * Setup a FPA pool to control a new block of memory. The 49 * buffer pointer must be a physical address. 50 * 51 * @pool: Pool to initialize 52 * 0 <= pool < 8 53 * @name: Constant character string to name this pool. 54 * String is not copied. 55 * @buffer: Pointer to the block of memory to use. This must be 56 * accessable by all processors and external hardware. 57 * @block_size: Size for each block controlled by the FPA 58 * @num_blocks: Number of blocks 59 * 60 * Returns 0 on Success, 61 * -1 on failure 62 */ 63int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer, 64 uint64_t block_size, uint64_t num_blocks) 65{ 66 char *ptr; 67 if (!buffer) { 68 cvmx_dprintf 69 ("ERROR: cvmx_fpa_setup_pool: NULL buffer pointer!\n"); 70 return -1; 71 } 72 if (pool >= CVMX_FPA_NUM_POOLS) { 73 cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Illegal pool!\n"); 74 return -1; 75 } 76 77 if (block_size < CVMX_FPA_MIN_BLOCK_SIZE) { 78 cvmx_dprintf 79 ("ERROR: cvmx_fpa_setup_pool: Block size too small.\n"); 80 return -1; 81 } 82 83 if (((unsigned long)buffer & (CVMX_FPA_ALIGNMENT - 1)) != 0) { 84 cvmx_dprintf 85 ("ERROR: cvmx_fpa_setup_pool: Buffer not aligned properly.\n"); 86 return -1; 87 } 88 89 cvmx_fpa_pool_info[pool].name = name; 90 cvmx_fpa_pool_info[pool].size = block_size; 91 cvmx_fpa_pool_info[pool].starting_element_count = num_blocks; 92 cvmx_fpa_pool_info[pool].base = buffer; 93 94 ptr = (char *)buffer; 95 while (num_blocks--) { 96 cvmx_fpa_free(ptr, pool, 0); 97 ptr += block_size; 98 } 99 return 0; 100} 101 102/** 103 * Shutdown a Memory pool and validate that it had all of 104 * the buffers originally placed in it. 105 * 106 * @pool: Pool to shutdown 107 * Returns Zero on success 108 * - Positive is count of missing buffers 109 * - Negative is too many buffers or corrupted pointers 110 */ 111uint64_t cvmx_fpa_shutdown_pool(uint64_t pool) 112{ 113 uint64_t errors = 0; 114 uint64_t count = 0; 115 uint64_t base = cvmx_ptr_to_phys(cvmx_fpa_pool_info[pool].base); 116 uint64_t finish = 117 base + 118 cvmx_fpa_pool_info[pool].size * 119 cvmx_fpa_pool_info[pool].starting_element_count; 120 void *ptr; 121 uint64_t address; 122 123 count = 0; 124 do { 125 ptr = cvmx_fpa_alloc(pool); 126 if (ptr) 127 address = cvmx_ptr_to_phys(ptr); 128 else 129 address = 0; 130 if (address) { 131 if ((address >= base) && (address < finish) && 132 (((address - 133 base) % cvmx_fpa_pool_info[pool].size) == 0)) { 134 count++; 135 } else { 136 cvmx_dprintf 137 ("ERROR: cvmx_fpa_shutdown_pool: Illegal address 0x%llx in pool %s(%d)\n", 138 (unsigned long long)address, 139 cvmx_fpa_pool_info[pool].name, (int)pool); 140 errors++; 141 } 142 } 143 } while (address); 144 145#ifdef CVMX_ENABLE_PKO_FUNCTIONS 146 if (pool == 0) 147 cvmx_ipd_free_ptr(); 148#endif 149 150 if (errors) { 151 cvmx_dprintf 152 ("ERROR: cvmx_fpa_shutdown_pool: Pool %s(%d) started at 0x%llx, ended at 0x%llx, with a step of 0x%llx\n", 153 cvmx_fpa_pool_info[pool].name, (int)pool, 154 (unsigned long long)base, (unsigned long long)finish, 155 (unsigned long long)cvmx_fpa_pool_info[pool].size); 156 return -errors; 157 } else 158 return 0; 159} 160 161uint64_t cvmx_fpa_get_block_size(uint64_t pool) 162{ 163 switch (pool) { 164 case 0: 165 return CVMX_FPA_POOL_0_SIZE; 166 case 1: 167 return CVMX_FPA_POOL_1_SIZE; 168 case 2: 169 return CVMX_FPA_POOL_2_SIZE; 170 case 3: 171 return CVMX_FPA_POOL_3_SIZE; 172 case 4: 173 return CVMX_FPA_POOL_4_SIZE; 174 case 5: 175 return CVMX_FPA_POOL_5_SIZE; 176 case 6: 177 return CVMX_FPA_POOL_6_SIZE; 178 case 7: 179 return CVMX_FPA_POOL_7_SIZE; 180 default: 181 return 0; 182 } 183} 184