cvmx-fpa.c revision 210284
1210284Sjmallett/***********************license start*************** 2210284Sjmallett * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights 3210284Sjmallett * reserved. 4210284Sjmallett * 5210284Sjmallett * 6210284Sjmallett * Redistribution and use in source and binary forms, with or without 7210284Sjmallett * modification, are permitted provided that the following conditions are 8210284Sjmallett * met: 9210284Sjmallett * 10210284Sjmallett * * Redistributions of source code must retain the above copyright 11210284Sjmallett * notice, this list of conditions and the following disclaimer. 12210284Sjmallett * 13210284Sjmallett * * Redistributions in binary form must reproduce the above 14210284Sjmallett * copyright notice, this list of conditions and the following 15210284Sjmallett * disclaimer in the documentation and/or other materials provided 16210284Sjmallett * with the distribution. 17210284Sjmallett * 18210284Sjmallett * * Neither the name of Cavium Networks nor the names of 19210284Sjmallett * its contributors may be used to endorse or promote products 20210284Sjmallett * derived from this software without specific prior written 21210284Sjmallett * permission. 22210284Sjmallett * 23210284Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 24210284Sjmallett * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS 25210284Sjmallett * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH 26210284Sjmallett * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY 27210284Sjmallett * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT 28210284Sjmallett * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES 29210284Sjmallett * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR 30210284Sjmallett * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET 31210284Sjmallett * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT 32210284Sjmallett * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 33210284Sjmallett * 34210284Sjmallett * 35210284Sjmallett * For any questions regarding licensing please contact marketing@caviumnetworks.com 36210284Sjmallett * 37210284Sjmallett ***********************license end**************************************/ 38210284Sjmallett 39210284Sjmallett 40210284Sjmallett 41210284Sjmallett 42210284Sjmallett 43210284Sjmallett 44210284Sjmallett/** 45210284Sjmallett * @file 46210284Sjmallett * 47210284Sjmallett * Support library for the hardware Free Pool Allocator. 48210284Sjmallett * 49210284Sjmallett * <hr>$Revision: 41586 $<hr> 50210284Sjmallett * 51210284Sjmallett */ 52210284Sjmallett 53210284Sjmallett#include "cvmx-config.h" 54210284Sjmallett#include "cvmx.h" 55210284Sjmallett#include "cvmx-fpa.h" 56210284Sjmallett#include "cvmx-ipd.h" 57210284Sjmallett 58210284Sjmallett/** 59210284Sjmallett * Current state of all the pools. Use access functions 60210284Sjmallett * instead of using it directly. 61210284Sjmallett */ 62210284SjmallettCVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS]; 63210284Sjmallett 64210284Sjmallett 65210284Sjmallett/** 66210284Sjmallett * Setup a FPA pool to control a new block of memory. The 67210284Sjmallett * buffer pointer must be a physical address. 68210284Sjmallett * 69210284Sjmallett * @param pool Pool to initialize 70210284Sjmallett * 0 <= pool < 8 71210284Sjmallett * @param name Constant character string to name this pool. 72210284Sjmallett * String is not copied. 73210284Sjmallett * @param buffer Pointer to the block of memory to use. This must be 74210284Sjmallett * accessable by all processors and external hardware. 75210284Sjmallett * @param block_size Size for each block controlled by the FPA 76210284Sjmallett * @param num_blocks Number of blocks 77210284Sjmallett * 78210284Sjmallett * @return 0 on Success, 79210284Sjmallett * -1 on failure 80210284Sjmallett */ 81210284Sjmallettint cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer, 82210284Sjmallett uint64_t block_size, uint64_t num_blocks) 83210284Sjmallett{ 84210284Sjmallett char *ptr; 85210284Sjmallett if (!buffer) 86210284Sjmallett { 87210284Sjmallett cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: NULL buffer pointer!\n"); 88210284Sjmallett return(-1); 89210284Sjmallett } 90210284Sjmallett if (pool >= CVMX_FPA_NUM_POOLS) 91210284Sjmallett { 92210284Sjmallett cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Illegal pool!\n"); 93210284Sjmallett return(-1); 94210284Sjmallett } 95210284Sjmallett 96210284Sjmallett if (block_size < CVMX_FPA_MIN_BLOCK_SIZE) 97210284Sjmallett { 98210284Sjmallett cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Block size too small.\n"); 99210284Sjmallett return(-1); 100210284Sjmallett } 101210284Sjmallett 102210284Sjmallett if (((unsigned long)buffer & (CVMX_FPA_ALIGNMENT-1)) != 0) 103210284Sjmallett { 104210284Sjmallett cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Buffer not aligned properly.\n"); 105210284Sjmallett return(-1); 106210284Sjmallett } 107210284Sjmallett 108210284Sjmallett cvmx_fpa_pool_info[pool].name = name; 109210284Sjmallett cvmx_fpa_pool_info[pool].size = block_size; 110210284Sjmallett cvmx_fpa_pool_info[pool].starting_element_count = num_blocks; 111210284Sjmallett cvmx_fpa_pool_info[pool].base = buffer; 112210284Sjmallett 113210284Sjmallett ptr = (char*)buffer; 114210284Sjmallett while (num_blocks--) 115210284Sjmallett { 116210284Sjmallett cvmx_fpa_free(ptr, pool, 0); 117210284Sjmallett ptr += block_size; 118210284Sjmallett } 119210284Sjmallett return(0); 120210284Sjmallett} 121210284Sjmallett 122210284Sjmallett/** 123210284Sjmallett * Shutdown a Memory pool and validate that it had all of 124210284Sjmallett * the buffers originally placed in it. 125210284Sjmallett * 126210284Sjmallett * @param pool Pool to shutdown 127210284Sjmallett * @return Zero on success 128210284Sjmallett * - Positive is count of missing buffers 129210284Sjmallett * - Negative is too many buffers or corrupted pointers 130210284Sjmallett */ 131210284Sjmallettuint64_t cvmx_fpa_shutdown_pool(uint64_t pool) 132210284Sjmallett{ 133210284Sjmallett uint64_t errors = 0; 134210284Sjmallett uint64_t count = 0; 135210284Sjmallett uint64_t base = cvmx_ptr_to_phys(cvmx_fpa_pool_info[pool].base); 136210284Sjmallett uint64_t finish = base + cvmx_fpa_pool_info[pool].size * cvmx_fpa_pool_info[pool].starting_element_count; 137210284Sjmallett void *ptr; 138210284Sjmallett uint64_t address; 139210284Sjmallett 140210284Sjmallett count = 0; 141210284Sjmallett do 142210284Sjmallett { 143210284Sjmallett ptr = cvmx_fpa_alloc(pool); 144210284Sjmallett if (ptr) 145210284Sjmallett address = cvmx_ptr_to_phys(ptr); 146210284Sjmallett else 147210284Sjmallett address = 0; 148210284Sjmallett if (address) 149210284Sjmallett { 150210284Sjmallett if ((address >= base) && (address < finish) && 151210284Sjmallett (((address - base) % cvmx_fpa_pool_info[pool].size) == 0)) 152210284Sjmallett { 153210284Sjmallett count++; 154210284Sjmallett } 155210284Sjmallett else 156210284Sjmallett { 157210284Sjmallett cvmx_dprintf("ERROR: cvmx_fpa_shutdown_pool: Illegal address 0x%llx in pool %s(%d)\n", 158210284Sjmallett (unsigned long long)address, cvmx_fpa_pool_info[pool].name, (int)pool); 159210284Sjmallett errors++; 160210284Sjmallett } 161210284Sjmallett } 162210284Sjmallett } while (address); 163210284Sjmallett 164210284Sjmallett#ifdef CVMX_ENABLE_PKO_FUNCTIONS 165210284Sjmallett if (pool == 0) 166210284Sjmallett cvmx_ipd_free_ptr(); 167210284Sjmallett#endif 168210284Sjmallett 169210284Sjmallett if (errors) 170210284Sjmallett { 171210284Sjmallett cvmx_dprintf("ERROR: cvmx_fpa_shutdown_pool: Pool %s(%d) started at 0x%llx, ended at 0x%llx, with a step of 0x%llx\n", 172210284Sjmallett cvmx_fpa_pool_info[pool].name, (int)pool, (unsigned long long)base, (unsigned long long)finish, (unsigned long long)cvmx_fpa_pool_info[pool].size); 173210284Sjmallett return -errors; 174210284Sjmallett } 175210284Sjmallett else 176210284Sjmallett return 0; 177210284Sjmallett} 178210284Sjmallett 179210284Sjmallettuint64_t cvmx_fpa_get_block_size(uint64_t pool) 180210284Sjmallett{ 181210284Sjmallett switch (pool) 182210284Sjmallett { 183210284Sjmallett case 0: return(CVMX_FPA_POOL_0_SIZE); 184210284Sjmallett case 1: return(CVMX_FPA_POOL_1_SIZE); 185210284Sjmallett case 2: return(CVMX_FPA_POOL_2_SIZE); 186210284Sjmallett case 3: return(CVMX_FPA_POOL_3_SIZE); 187210284Sjmallett case 4: return(CVMX_FPA_POOL_4_SIZE); 188210284Sjmallett case 5: return(CVMX_FPA_POOL_5_SIZE); 189210284Sjmallett case 6: return(CVMX_FPA_POOL_6_SIZE); 190210284Sjmallett case 7: return(CVMX_FPA_POOL_7_SIZE); 191210284Sjmallett default: return(0); 192210284Sjmallett } 193210284Sjmallett} 194