]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/contrib/octeon-sdk/cvmx-fpa.c
Copy stable/8 to releng/8.2 in preparation for FreeBSD-8.2 release.
[FreeBSD/releng/8.2.git] / sys / contrib / octeon-sdk / cvmx-fpa.c
1 /***********************license start***************
2  *  Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights
3  *  reserved.
4  *
5  *
6  *  Redistribution and use in source and binary forms, with or without
7  *  modification, are permitted provided that the following conditions are
8  *  met:
9  *
10  *      * Redistributions of source code must retain the above copyright
11  *        notice, this list of conditions and the following disclaimer.
12  *
13  *      * Redistributions in binary form must reproduce the above
14  *        copyright notice, this list of conditions and the following
15  *        disclaimer in the documentation and/or other materials provided
16  *        with the distribution.
17  *
18  *      * Neither the name of Cavium Networks nor the names of
19  *        its contributors may be used to endorse or promote products
20  *        derived from this software without specific prior written
21  *        permission.
22  *
23  *  TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
24  *  AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
25  *  OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
26  *  RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
27  *  REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
28  *  DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
29  *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
30  *  PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
31  *  POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
32  *  OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
33  *
34  *
35  *  For any questions regarding licensing please contact marketing@caviumnetworks.com
36  *
37  ***********************license end**************************************/
38
39
40
41
42
43
44 /**
45  * @file
46  *
47  * Support library for the hardware Free Pool Allocator.
48  *
49  * <hr>$Revision: 41586 $<hr>
50  *
51  */
52
53 #include "cvmx.h"
54 #include "cvmx-fpa.h"
55 #include "cvmx-ipd.h"
56
57 /**
58  * Current state of all the pools. Use access functions
59  * instead of using it directly.
60  */
61 CVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
62
63
64 /**
65  * Setup a FPA pool to control a new block of memory. The
66  * buffer pointer must be a physical address.
67  *
68  * @param pool       Pool to initialize
69  *                   0 <= pool < 8
70  * @param name       Constant character string to name this pool.
71  *                   String is not copied.
72  * @param buffer     Pointer to the block of memory to use. This must be
73  *                   accessable by all processors and external hardware.
74  * @param block_size Size for each block controlled by the FPA
75  * @param num_blocks Number of blocks
76  *
77  * @return 0 on Success,
78  *         -1 on failure
79  */
80 int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
81                          uint64_t block_size, uint64_t num_blocks)
82 {
83     char *ptr;
84     if (!buffer)
85     {
86         cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: NULL buffer pointer!\n");
87         return(-1);
88     }
89     if (pool >= CVMX_FPA_NUM_POOLS)
90     {
91         cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Illegal pool!\n");
92         return(-1);
93     }
94
95     if (block_size < CVMX_FPA_MIN_BLOCK_SIZE)
96     {
97         cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Block size too small.\n");
98         return(-1);
99     }
100
101     if (((unsigned long)buffer & (CVMX_FPA_ALIGNMENT-1)) != 0)
102     {
103         cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Buffer not aligned properly.\n");
104         return(-1);
105     }
106
107     cvmx_fpa_pool_info[pool].name = name;
108     cvmx_fpa_pool_info[pool].size = block_size;
109     cvmx_fpa_pool_info[pool].starting_element_count = num_blocks;
110     cvmx_fpa_pool_info[pool].base = buffer;
111
112     ptr = (char*)buffer;
113     while (num_blocks--)
114     {
115         cvmx_fpa_free(ptr, pool, 0);
116         ptr += block_size;
117     }
118     return(0);
119 }
120
121 /**
122  * Shutdown a Memory pool and validate that it had all of
123  * the buffers originally placed in it.
124  *
125  * @param pool   Pool to shutdown
126  * @return Zero on success
127  *         - Positive is count of missing buffers
128  *         - Negative is too many buffers or corrupted pointers
129  */
130 uint64_t cvmx_fpa_shutdown_pool(uint64_t pool)
131 {
132     uint64_t errors = 0;
133     uint64_t count  = 0;
134     uint64_t base   = cvmx_ptr_to_phys(cvmx_fpa_pool_info[pool].base);
135     uint64_t finish = base + cvmx_fpa_pool_info[pool].size * cvmx_fpa_pool_info[pool].starting_element_count;
136     void *ptr;
137     uint64_t address;
138
139     count = 0;
140     do
141     {
142         ptr = cvmx_fpa_alloc(pool);
143         if (ptr)
144             address = cvmx_ptr_to_phys(ptr);
145         else
146             address = 0;
147         if (address)
148         {
149             if ((address >= base) && (address < finish) &&
150                 (((address - base) % cvmx_fpa_pool_info[pool].size) == 0))
151             {
152                 count++;
153             }
154             else
155             {
156                 cvmx_dprintf("ERROR: cvmx_fpa_shutdown_pool: Illegal address 0x%llx in pool %s(%d)\n",
157                        (unsigned long long)address, cvmx_fpa_pool_info[pool].name, (int)pool);
158                 errors++;
159             }
160         }
161     } while (address);
162
163 #ifdef CVMX_ENABLE_PKO_FUNCTIONS
164     if (pool == 0)
165         cvmx_ipd_free_ptr();
166 #endif
167
168     if (errors)
169     {
170         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",
171                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);
172         return -errors;
173     }
174     else
175         return 0;
176 }
177
178 uint64_t cvmx_fpa_get_block_size(uint64_t pool)
179 {
180     switch (pool)
181     {
182         case 0: return(CVMX_FPA_POOL_0_SIZE);
183         case 1: return(CVMX_FPA_POOL_1_SIZE);
184         case 2: return(CVMX_FPA_POOL_2_SIZE);
185         case 3: return(CVMX_FPA_POOL_3_SIZE);
186         case 4: return(CVMX_FPA_POOL_4_SIZE);
187         case 5: return(CVMX_FPA_POOL_5_SIZE);
188         case 6: return(CVMX_FPA_POOL_6_SIZE);
189         case 7: return(CVMX_FPA_POOL_7_SIZE);
190         default: return(0);
191     }
192 }